Author Topic: Sprite Library Revisited  (Read 38126 times)

0 Members and 1 Guest are viewing this topic.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #45 on: September 28, 2018, 04:56:57 pm »
I have a 3 dimension array that needs saved/loaded:

TYPE SL_ANGLE
    x1 AS INTEGER '                     collision box upper left x
    x2 AS INTEGER '                     collision box lower right x
    y1 AS INTEGER '                     collision box upper left y
    y2 AS INTEGER '                     collision box lower right y
    cwidth AS INTEGER '                 collision box width
    cheight AS INTEGER '                collision box height
    radius AS INTEGER '                 collision circle radius
    rwidth AS INTEGER '                 rotated sprite width
    rheight AS INTEGER '                rotated sprite height
    px0 AS INTEGER '                    rectangular rotation coordinates
    px1 AS INTEGER
    px2 AS INTEGER
    px3 AS INTEGER
    py0 AS INTEGER
    py1 AS INTEGER
    py2 AS INTEGER
    py3 AS INTEGER
END TYPE

SL_angle(x, y, 359) AS SL_ANGLE  (x = sheet#, y = cell#, rotational angle from 0 to 359

I tried saving the entire array with a single PUT command, but when I bring it back with a single GET for some reason all the data contained in the even numbered entries is set to zero.

Here is what I'm using to save the file:

Code: QB64: [Select]
  1.     IF NOT _FILEEXISTS(rotfile) THEN '                                                                  does it exist?
  2.         OPEN rotfile FOR BINARY AS #1 '                                                                 no, open it for writing
  3.         FOR x = 1 TO cells '                                                                            cycle through all sprite cells
  4.             FOR y = 0 TO 359 '                                                                          and their rotational angles
  5.                 PUT #1, , SL_angle(handle, x, y) '                                                      put the data
  6.             NEXT y
  7.         NEXT x
  8.         CLOSE #1 '                                                                                      close the file
  9.     END IF
  10.  

and here is what I am using to load the file:

Code: QB64: [Select]
  1.     rotfile = LEFT$(filename, INSTR(filename, ".") - 1) + ".rot" '                                      the name of the rotational data file
  2.     IF _FILEEXISTS(rotfile) THEN '                                                                      does it exist?
  3.         preloaded = -1 '                                                                                yes, remember that data has been preloaded
  4.         OPEN rotfile FOR BINARY AS #1 '                                                                 open it for reading
  5.         FOR x = 1 TO cells '                                                                            cycle through all animation cells
  6.             FOR y = 0 TO 359 '                                                                          and their associated rotational data
  7.                 GET #1, , SL_angle(handle, x, y) '                                                      get the data
  8.             NEXT y
  9.         NEXT x
  10.         CLOSE #1 '                                                                                      close the file
  11.     END IF
  12.  

In order to understand recursion, one must first understand recursion.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Sprite Library Revisited
« Reply #46 on: September 28, 2018, 06:03:38 pm »
Dim a memblock, point it to your array:


DIM m AS _MEM
M = _MEM(SL_Angle())

Set a temp variable to hold it all, and put that to the file in one go.

t$ = SPACE(M.SIZE)
_MEMGET M, M.OFFSET, t$
PUT #1, , t$
......

Reverse the process to restore it in one go.

t$ = SPACE$(M.SIZE)
GET #1, , t$
_MEMPUT M, M.OFFSET, t$

****************************

I'm thinking the end result should save you some disk access time.  (And if M can be static/shared, you won't need to _MEMFREE or assign it more than once, saving some initialization time there as well.)


*****************
*****************

EDIT:   And, I see potential issues with the shared code:  Change #1 to a FREEFILE handle.  You can't be certain that a library user isn't going to already have file #1 opened for some other purpose (such as a save game file).
« Last Edit: September 28, 2018, 06:07:31 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #47 on: September 28, 2018, 07:23:16 pm »
Thank you for helping me make this better/faster.

Yes! You are correct, FREEFILE should always be used in library. I'm glad you caught that.
In order to understand recursion, one must first understand recursion.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Sprite Library Revisited
« Reply #48 on: September 29, 2018, 02:14:36 pm »
Hi Terry
you have started to go on the moon and now your astroship is acrossing the rings of Saturn. Wonderful!!! Hard but great work!

about your issue about PUT#FileNumberFree, , array() and GET#FileNumberFree, , array()
using your model of code I have tried and it seems to work well saving and loading in one shot the array from/to the file.
Here my lazy mod:
Code: QB64: [Select]
  1. TYPE SL_ANGLE
  2.     x1 AS INTEGER '                     collision box upper left x
  3.     x2 AS INTEGER '                     collision box lower right x
  4.     y1 AS INTEGER '                     collision box upper left y
  5.     y2 AS INTEGER '                     collision box lower right y
  6.     cwidth AS INTEGER '                 collision box width
  7.     cheight AS INTEGER '                collision box height
  8.     radius AS INTEGER '                 collision circle radius
  9.     rwidth AS INTEGER '                 rotated sprite width
  10.     rheight AS INTEGER '                rotated sprite height
  11.     px0 AS INTEGER '                    rectangular rotation coordinates
  12.     px1 AS INTEGER
  13.     px2 AS INTEGER
  14.     px3 AS INTEGER
  15.     py0 AS INTEGER
  16.     py1 AS INTEGER
  17.     py2 AS INTEGER
  18.     py3 AS INTEGER
  19.  
  20. REDIM SL_angle(1 TO 2, 1 TO 5, 0 TO 359) AS SL_ANGLE '(x = sheet#, y = cell#, rotational angle from 0 to 359
  21.  
  22. 'IF NOT _FILEEXISTS("rotfile") THEN '                                                                  does it exist?
  23. handle = 1: cells = 5: numfile = FREEFILE
  24. OPEN "rotfile" FOR BINARY AS #numfile '                                                                 no, open it for writing
  25. FOR x = 1 TO cells '                                                                            cycle through all sprite cells
  26.     FOR y = 0 TO 359 '                                                                          and their rotational angles
  27.         SL_angle(handle, x, y).x1 = x
  28.         SL_angle(handle, x, y).y1 = y
  29.         SL_angle(handle, x, y).radius = y
  30.         PRINT SL_angle(handle, x, y).x1; " "; SL_angle(handle, x, y).y1; " "; SL_angle(handle, x, y).radius
  31.  
  32.     NEXT y
  33. PUT #numfile, , SL_angle() '                                                      put the data
  34. CLOSE #numfile '                                                                                      close the file
  35. 'END IF
  36.  
  37. '   rotfile = LEFT$(filename, INSTR(filename, ".") - 1) + ".rot" '                                      the name of the rotational data file
  38. VIEW PRINT 14 TO 24
  39. IF _FILEEXISTS("rotfile") THEN '                                                                      does it exist?
  40.     preloaded = -1 '                                                                                yes, remember that data has been preloaded
  41.     OPEN "rotfile" FOR BINARY AS #numfile '                                                                 open it for reading
  42.     GET #numfile, , SL_angle() '                                                      get the data
  43.     FOR x = 1 TO cells '                                                                            cycle through all animation cells
  44.         FOR y = 0 TO 359 '                                                                          and their associated rotational data
  45.             PRINT SL_angle(handle, x, y).x1; " "; SL_angle(handle, x, y).y1; " "; SL_angle(handle, x, y).radius
  46.         NEXT y
  47.     NEXT x
  48.     CLOSE #numfile '                                                                                      close the file
  49.  
  50.  

I hope this can be useful for your coding.
PS here I add Steve's suggestion to use FREEFILE to be safe from conflict about number of file used to open a file.
Programming isn't difficult, only it's  consuming time and coffee

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #49 on: September 29, 2018, 04:30:02 pm »
Thanks for code Tempo, I'll investigate it in a little bit.

Right now I'm tracking down some layer issues I have. I needed to have a working program to track the issues down so I created this quick Roman numeral clock using some cheesy clock graphics I found on the net. It's a good example showing how powerful this little library is already becoming. You'll need the two graphic files below if you wish to run the demo.

Code: QB64: [Select]
  1. '** NOTES **
  2.  
  3.  
  4.  
  5. ' Ideas to add
  6. '
  7. ' if SL_EVENT_TRIGGER then 'check for event that was sent (add event triggers)
  8. ' - possible link sounds to events
  9. ' add gravity, attraction, repulsion  SL_SET_PHYSICS
  10. ' add mass, elasticity (bounciness?)   ^  ^  ^
  11. ' add arc calculator for things like a swinging vine or radar scope
  12. ' ability to link sprites, when one moves the other moves, break apart when collision happens SL_LINK_SPRITE
  13. ' give sprites path-following ability (bezier curves?) SL_FOLLOW_PATH
  14. ' divide work space into cells and detect when sprites enter/leave a cell
  15. ' stand-alone program to develop sprite sheets (inform)        \
  16. ' stand-alone program to develop celled work spaces (inform)   /  combine these into one program?
  17. ' when sprite interact their mass, elascticity, etc. govern the way the move and fall
  18. ' - I will need help from a math major for this
  19.  
  20. ' Planned additions
  21. '
  22. ' get sprite width and height (both actual and collision box) SL_GET_ACTUAL_WIDTH, SL_GET_ACTUAL_HEIGHT, SL_GET_COLLISION_WIDTH, SL_GET_COLLISION_HEIGHT
  23. ' set Z depth of sprite for different planes/layers (possibly incorporate this into zoom?)
  24. ' - need to figure out how to rotate collision box along with sprites, not too hard
  25. ' - this will require line segment intersection algorithms for collision detection, yikes! hard, probably need help
  26. ' - possibly link sounds to collisions SL_LINK_COLLIDE_SOUND
  27. ' Parallaxing layers  SL_CREATE_PARALLAX, SL_UPDATE_PARALLAX
  28. ' Game font printing
  29. ' Sprite tiling, square for sure, isometric?
  30.  
  31. ' Things to improve
  32. '
  33. ' Naming convention of constants and their values
  34. ' Use integers wherever possible
  35. ' allow SINGLE value rotation angles for accuracy but convert to integer before sprite rotation
  36. ' - using only integer now, may not be precise enough for future improvements
  37.  
  38. ' Investigate
  39. '
  40. ' Use of _MAPTRIANGLE for 3D rotation   SL_ROTATE_3D
  41. ' _HARDWARE vs _HARDWARE1
  42.  
  43. ' Remember
  44. '
  45. ' Any code added that is OS dependant needs to detect the OS running first
  46. ' - try to create routines that are OS dependant for all OS'
  47.  
  48.  
  49.  
  50. OPTION _EXPLICIT ' need to remove before publishing library!!
  51.  
  52. '*
  53. '* constant declarations
  54. '*
  55.  
  56. '      CONSTANT NAME                   DESCRIPTION                                                       FUNCTIONS / SUBROUTINES THAT MAY USE THIS CONSTANT
  57. ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  58. CONST SL_RESET = -32767 '   reset a function or subroutine              SL_ROTATE_SPRITE, SL_FLIP_SPRITE, SL_ZOOM_SPRITE, SL_SET_ZOOM, SL_CHANGE_AUTOROTATION, SL_CHANGE_AUTOMOTION, SL_CHANGE_ROTATION_SPEED, SL_SET_COLLISION
  59. CONST SL_NOFLIP = 0 '       sprite will use no flipping                 SL_FLIP_SPRITE
  60. CONST SL_HORIZONTAL = 1 '   sprite will be flipped horizontally         SL_FLIP_SPRITE
  61. CONST SL_VERTICAL = 2 '     sprite will be flipped vertically           SL_FLIP_SPRITE
  62. CONST SL_FLIPBOTH = 3 '     sprite will be flipped both direction       SL_FLIP_SPRITE
  63. CONST SL_USESHEET = -1 '    use sheet's transparency info (.PNG)        SL_NEW_SHEET
  64. CONST SL_SET = 0 '          manually set transparency                   SL_NEW_SHEET
  65. CONST SL_NONE = 1 '         don't use transparency with sheet           SL_NEW_SHEET
  66. CONST SL_NOSAVE = 0 '       sprite will not save background             SL_NEW_SPRITE, SL_SET_SOFTWARE
  67. CONST SL_SAVE = -1 '        sprite will save background                 SL_NEW_SPRITE, SL_SET_SOFTWARE
  68. CONST SL_HARDWARE = 0 '     sprite in hardware mode                     SL_NEW_SPRITE, SL_update_auto_sprites
  69. CONST SL_SOFTWARE = -1 '    sprite in software mode                     SL_NEW_SPRITE, SL_update_auto_sprites
  70. CONST SL_START = -1 '       enable auto motion / rotation               SL_CHANGE_AUTOMOTION, SL_CHANGE_AUTOROTATION, SL_SET_AUTOANIMATION, SL_SET_ANIMATION, SL_SET_MOTION, SL_SET_ROTATION
  71. CONST SL_STOP = 0 '         disable auto motion / rotation              SL_CHANGE_AUTOMOTION, SL_CHANGE_AUTOROTATION, SL_SET_AUTOANIMATION, SL_SET_ANIMATION, SL_SET_MOTION, SL_SET_ROTATION, SL_CHANGE_ROTATION_SPEED
  72. CONST SL_FORWARD = 0 '      animation cells proceed forward             SL_SET_ANIMATION
  73. CONST SL_BACKWARD = 1 '     animation cells proceed backwards           SL_SET_ANIMATION
  74. CONST SL_BACKFORTH = 2 '    animation cells toggle forward/backward     SL_SET_ANIMATION
  75. CONST SL_CURRENTCELL = -1 ' use current cell as starting cell           SL_SET_ANIMATION, SL_CHANGE_ANIMATION_CELLS
  76. CONST SL_SHOW = -1 '        sprite will be shown on screen              SL_SET_SPRITE_VISIBLE, SL_SET_LAYER_VISIBLE
  77. CONST SL_HIDE = 0 '         sprite will not be shown on screen          SL_SET_SPRITE_VISIBLE, SL_SET_LAYER_VISIBLE
  78. CONST SL_NODETECT = 0 '     sprite uses no collision detection          SL_SET_COLLISION
  79. CONST SL_BOXDETECT = 1 '    sprite uses box collision detect            SL_SET_COLLISION
  80. CONST SL_ROUNDDETECT = 2 '  sprite uses round collision detect '        SL_SET_COLLISION
  81. CONST SL_PIXELDETECT = 3 '  sprite uses pixel perfect collision detect  SL_SET_COLLISION
  82. CONST SL_ALL = -1 '         check for all sprites                       SL_GET_COLLISION, SL_GET_MOUSE, SL_CLEAR_LAYER
  83. CONST SL_NOMOUSE = 0 '      no mouse interaction with sprite            SL_GET_MOUSE
  84. CONST SL_HOVER = 1 '        mouse pointer hovering over sprite          SL_GET_MOUSE
  85. CONST SL_LEFTCLICK = 2 '    left mouse button clicked on sprite         SL_GET_MOUSE
  86. CONST SL_RIGHTCLICK = 3 '   right mouse button clicked on sprite        SL_GET_MOUSE
  87. CONST SL_CENTERCLICK = 4 '  center mouse button clicked on sprite       SL_GET_MOUSE
  88.  
  89. '*
  90. '* type declarations
  91. '*
  92.  
  93. TYPE SL_SHEET ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SPRITE SHEET DATABASE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  94.     software AS LONG '                  software sprite image
  95.     mask AS LONG '                      software mask image
  96.     swidth AS INTEGER '                 width of sprite
  97.     sheight AS INTEGER '                height of sprite
  98.     transparency AS INTEGER '           -1 (TRUE) if sheet uses transparency
  99.     clearcolor AS _UNSIGNED LONG '      transparent color of image
  100. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  101.  
  102. TYPE SL_XY ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ X,Y LOCATIONS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  103.     real AS SINGLE '                    single values of sprite x,y center point
  104.     int AS INTEGER '                    integer values of sprite x,y center point
  105.     actual AS INTEGER '                 integer values of sprite upper left x,y location
  106.     back AS INTEGER '                   integer values of sprite's background image x,y location
  107.     dir AS SINGLE '                     single values of sprite x,y motion vectors
  108. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  109.  
  110. TYPE SL_IMAGE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IMAGES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  111.     hardware AS LONG '                  hardware sprite image
  112.     software AS LONG '                  software sprite image
  113.     mask AS LONG '                      software sprite mask image
  114.     back AS LONG '                      software sprite saved background image
  115. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  116.  
  117. TYPE SL_ANIM ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ANIMATION SETTINGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  118.     cell AS INTEGER '                   current animation cell
  119.     cellfrom AS INTEGER '               starting animation cell
  120.     cellto AS INTEGER '                 ending animation cell
  121.     dir AS INTEGER '                    animation direction
  122.     mode AS INTEGER '                   animation mode (forward, backward, back/forth)
  123.     framerate AS INTEGER '              sprite animation frame rate
  124.     frame AS INTEGER '                  animation frame counter
  125.     skip AS INTEGER '                   how often to skip a frame to achieve framerate
  126.     auto AS INTEGER '                   auto-animation on/off
  127. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  128.  
  129. TYPE SL_MOTION ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MOTION SETTINGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  130.     auto AS INTEGER '                   -1 (TRUE) if auto-motion turned on
  131.     speed AS SINGLE '                   speed of sprite during motion
  132.     angle AS INTEGER '                  direction of sprite during motion (0 - 359)
  133. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  134.  
  135. TYPE SL_ROTATION ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ROTATION SETTINGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  136.     auto AS INTEGER '                   -1 (TRUE) if auto-rotation turned on
  137.     speed AS INTEGER '                  spin rate in degrees of sprite (0 - 359)
  138.     angle AS INTEGER '                  current rotation angle of sprite
  139. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  140.  
  141. TYPE SL_COLLISION ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ COLLISION SETTINGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  142.     detect AS INTEGER '                 type of detection this sprite uses (box, round, ellipse, pixel)
  143.     box AS INTEGER '                    -1 (TRUE) if a box collision detected
  144.     round AS INTEGER '                  -1 (TRUE) if a round collision detected
  145.     pixel AS INTEGER '                  -1 (TRUE) if a pixel perfect collision detected
  146.     with AS INTEGER '                   the sprite collision happened with
  147.     radius AS INTEGER '                 radius of round collision area
  148.     x1 AS INTEGER '                     collision box upper left x
  149.     x2 AS INTEGER '                     collision box lower right x
  150.     y1 AS INTEGER '                     collision box upper left y
  151.     y2 AS INTEGER '                     collision box lower right y
  152.     cwidth AS INTEGER '                 width of collision box
  153.     cheight AS INTEGER '                height of collision box
  154.     xpoint AS INTEGER '                 x location of collision
  155.     ypoint AS INTEGER '                 y location of collision
  156. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  157.  
  158. TYPE SL_MOUSE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MOUSE SETTINGS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  159.     event AS INTEGER '                  last event on sprite (hover, click, etc)
  160.     x AS INTEGER '                      x location of mouse on sprite
  161.     y AS INTEGER '                      y location of mouse on sprite
  162.     xa AS INTEGER '                     x location of mouse on screen
  163.     ya AS INTEGER '                     y location of mouse on screen
  164. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  165.  
  166. TYPE SL_SPRITE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ SPRITE DATABASE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  167.     inuse AS INTEGER '                  this array index in use
  168.     x AS SL_XY '                        x coordinate locations
  169.     y AS SL_XY '                        y coordinate locations
  170.     gfx AS SL_IMAGE '                   image graphics
  171.     animation AS SL_ANIM '              animation settings
  172.     motion AS SL_MOTION '               motion settings
  173.     rotation AS SL_ROTATION '           rotation settings
  174.     collision AS SL_COLLISION '         collision settings
  175.     mouse AS SL_MOUSE '                 mouse interaction settings
  176.     sheet AS INTEGER '                  sheet sprite belongs to
  177.     cell AS INTEGER '                   current sprite cell
  178.     swidth AS INTEGER '                 width of sprite
  179.     sheight AS INTEGER '                height of sprite
  180.     restore AS INTEGER '                -1 (TRUE) if sprite restores background
  181.     flip AS INTEGER '                   flip horizontally, vertically, or both
  182.     transparency AS INTEGER '           -1 (TRUE) if sprite uses transparency
  183.     zoom AS INTEGER '                   zoom level of sprite (1% - x%)
  184.     software AS INTEGER '               -1 (TRUE) if sprite is to be treated as software image
  185.     score AS INTEGER '                  point score of sprite
  186.     visible AS INTEGER '                -1 (TRUE) if sprite visible
  187.     layer AS INTEGER '                  the layer the sprite belongs to
  188. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  189.  
  190. TYPE SL_ANGLE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ROTATION ANGLE & COLLISION BOX DATABASE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  191.     x1 AS INTEGER '                     collision box upper left x
  192.     x2 AS INTEGER '                     collision box lower right x
  193.     y1 AS INTEGER '                     collision box upper left y
  194.     y2 AS INTEGER '                     collision box lower right y
  195.     cwidth AS INTEGER '                 collision box width
  196.     cheight AS INTEGER '                collision box height
  197.     radius AS INTEGER '                 collision circle radius
  198.     rwidth AS INTEGER '                 rotated sprite width
  199.     rheight AS INTEGER '                rotated sprite height
  200.     px0 AS INTEGER '                    rectangular rotation coordinates
  201.     px1 AS INTEGER
  202.     px2 AS INTEGER
  203.     px3 AS INTEGER
  204.     py0 AS INTEGER
  205.     py1 AS INTEGER
  206.     py2 AS INTEGER
  207.     py3 AS INTEGER
  208. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  209.  
  210. TYPE SL_LAYERS ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ LAYER DATABASE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  211.     image AS LONG '                     software image of screen layer
  212.     visible AS INTEGER '                -1 (TRUE) if layer is visible
  213. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  214.  
  215. TYPE SL_GLOBAL ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ GLOBALS DATABASE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  216.     layer AS INTEGER '                  active layer
  217.     swidth AS INTEGER '                 screen width
  218.     sheight AS INTEGER '                screen height
  219.     framerate AS INTEGER '              global frame rate
  220.     source AS INTEGER '                 current source layer
  221.     destination AS INTEGER '            current destination layer
  222. END TYPE ' ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  223.  
  224. '*
  225. '* global dynamic array declarations
  226. '*
  227.  
  228. REDIM SL_sheet(1, 1) AS SL_SHEET '      sheet#, cell# - master sheet array
  229. REDIM SL_angle(1, 1, 359) AS SL_ANGLE ' sheet#, cell#, angle# - master sheet precalculated angle array
  230. REDIM SL_sprite(1) AS SL_SPRITE '       master working sprite array
  231. REDIM SL_layer(1) AS SL_LAYERS '        image layer array
  232.  
  233. '
  234. '*
  235. '* global variable declarations
  236. '*
  237.  
  238. DIM SL_global AS SL_GLOBAL
  239.  
  240. '*
  241. '* main code (for testing)
  242. '*
  243.  
  244. DIM handsheet AS INTEGER '      clock hand sprite sheet
  245. DIM hour AS INTEGER '           hour hand sprite
  246. DIM minute AS INTEGER '         minute hand sprite
  247. DIM second AS INTEGER '         second hand sprite
  248. DIM h AS INTEGER '              current hour value
  249. DIM m AS INTEGER '              current minute value
  250. DIM s AS INTEGER '              current second value
  251.  
  252. SL_SCREEN 551, 551, 1 '                                                                                 set window size and layers
  253. _TITLE "Clock Demo" '                                                                                   give window a title
  254. handsheet = SL_NEW_SHEET("hands73x533.png", 73, 533, SL_SET, _RGB32(255, 0, 255)) '                     load the clock hands
  255. hour = SL_NEW_SPRITE(1, handsheet, 2, SL_HARDWARE, SL_NOSAVE) '                                         get the hour hand
  256. minute = SL_NEW_SPRITE(1, handsheet, 1, SL_HARDWARE, SL_NOSAVE) '                                       get the minute hand
  257. second = SL_NEW_SPRITE(1, handsheet, 3, SL_HARDWARE, SL_NOSAVE) '                                       get the second hand
  258. _PUTIMAGE , _LOADIMAGE("face.png", 32) '                                                                display the clock face
  259. SL_SET_FRAMERATE 5 '                                                                                    set the global frame rate
  260.     _LIMIT SL_GET_FRAMERATE '                                                                           maintain global frame rate
  261.     h = VAL(TIME$) '                                                                                    get current hour value
  262.     IF h > 11 THEN h = h - 12 '                                                                         keep a 12 hour clock
  263.     m = VAL(MID$(TIME$, 4, 2)) '                                                                        get current minute value
  264.     s = VAL(MID$(TIME$, 7, 2)) '                                                                        get current second value
  265.     SL_ROTATE_SPRITE hour, 30 * h + m \ 2 '                                                             rotate hour hand into position
  266.     SL_ROTATE_SPRITE minute, 6 * m + s \ 10 '                                                           rotate minute hand into position
  267.     SL_ROTATE_SPRITE second, 6 * s '                                                                    rotate second hand into position
  268.     SL_PUT_SPRITE 276, 276, hour '                                                                      display the hour hand
  269.     SL_PUT_SPRITE 276, 276, minute '                                                                    display the minute hand
  270.     SL_PUT_SPRITE 276, 276, second '                                                                    display the second hand
  271.     SL_DISPLAY '                                                                                        merge layers and display
  272. LOOP UNTIL _KEYHIT '                                                                                    leave when key hit
  273. SL_FREE_SPRITE hour '                                                                                   free sprites from memory
  274. SL_FREE_SPRITE minute
  275. SL_FREE_SPRITE second
  276.  
  277.  
  278.  
  279. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  280. '                                                                       ----------==========                ==========----------
  281. '                                                                       ----------========== LAYER ROUTINES ==========----------
  282. '                                                                       ----------==========                ==========----------
  283. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  284.  
  285. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  286. SUB SL_SCREEN (swidth AS INTEGER, sheight AS INTEGER, layers AS INTEGER) '                                                                                                                    SL_SCREEN
  287.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  288.  
  289.     ' declare global variables
  290.  
  291.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  292.     SHARED SL_global AS SL_GLOBAL '     common globals array
  293.  
  294.     ' declare local variables
  295.  
  296.     DIM layer AS INTEGER '              layer counter
  297.  
  298.     ' perform error checks
  299.  
  300.     IF layers < 1 THEN '                                                                                creating at least one layer?
  301.         SL_error "SL_SCREEN", 26, "" '                                                                  no, report error to programmer
  302.     END IF
  303.  
  304.     REDIM SL_layer(layers) AS SL_LAYERS '                                                               increase layer array to match requested number of layers
  305.     SL_global.swidth = swidth '                                                                         set screen width
  306.     SL_global.sheight = sheight '                                                                       set screen height
  307.     layer = 0 '                                                                                         reset layer counter
  308.  
  309.     DO '                                                                                                cycle through layers
  310.         SL_layer(layer).image = _NEWIMAGE(swidth, sheight, 32) '                                        create layer software image
  311.         SL_layer(layer).visible = -1 '                                                          (TRUE)  layer is visible
  312.         layer = layer + 1 '                                                                             increment layer counter
  313.     LOOP UNTIL layer = UBOUND(SL_layer) + 1 '                                                           leave when all layers created
  314.  
  315.     SL_SET_DESTINATION_LAYER 1 '                                                                        set destination layer
  316.     SL_SET_SOURCE_LAYER 1 '                                                                             set source layer
  317.     SCREEN SL_layer(0).image '                                                                          initialize layer 0 working screen
  318.  
  319.  
  320. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  321. SUB SL_DISPLAY () '                                                                                                                                                                          SL_DISPLAY
  322.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  323.  
  324.     ' declare global variables
  325.  
  326.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  327.     SHARED SL_global AS SL_GLOBAL '     common globals array
  328.  
  329.     ' declare local variables
  330.  
  331.     DIM layer AS INTEGER '              layer counter
  332.     DIM odest AS INTEGER '              original destination
  333.     DIM merge AS LONG '                 software image to merge all layers onto
  334.     DIM hardware AS LONG '              hardware image of merged layers to place on working screen
  335.  
  336.     SL_update_auto_sprites -1 '                                                          (SL_SOFTWARE)  update all software automatic sprites
  337.     odest = _DEST '                                                                                     save original destination
  338.     _DEST SL_layer(0).image '                                                                           working screen is destination
  339.     merge = _NEWIMAGE(SL_global.swidth, SL_global.sheight, 32) '                                        create screen to merge layers
  340.     layer = UBOUND(SL_layer) '                                                                          reset layer counter
  341.  
  342.     DO '                                                                                                cycle through layers backwards (high to low)
  343.         IF SL_layer(layer).visible THEN '                                                               is this layer visible?
  344.             _PUTIMAGE , SL_layer(layer).image, merge '                                                  merge this layer
  345.         END IF
  346.         layer = layer - 1 '                                                                             decrement layer counter
  347.     LOOP UNTIL layer = 0 '                                                                              leave when all layers merged
  348.  
  349.     hardware = _COPYIMAGE(merge, 33) '                                                                  create hardware image of merged layers
  350.     _PUTIMAGE , hardware '                                                                              place hardware image on working screen
  351.     _FREEIMAGE merge '                                                                                  merged software image no longer needed
  352.     _FREEIMAGE hardware '                                                                               merged hardware image no longer needed
  353.     SL_update_auto_sprites 0 '                                                           (SL_HARDWARE)  update all hardware automatic sprites
  354.     _DEST odest '                                                                                       restore original destination
  355.     _DISPLAY '                                                                                          update display screen with changes
  356.  
  357.  
  358. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  359. SUB SL_SET_DESTINATION_LAYER (layer AS INTEGER) '                                                                                                                              SL_SET_DESTINATION_LAYER
  360.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  361.  
  362.     ' declare global variables
  363.  
  364.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  365.     SHARED SL_global AS SL_GLOBAL '     common globals array
  366.  
  367.     ' perform error checks
  368.  
  369.     IF layer <> -32767 THEN '                                                               (SL_RESET)  reset to working image?
  370.         IF NOT SL_VALID_LAYER(layer) THEN '                                                             no, valid layer?
  371.             SL_error "SL_SET_DESTINATION_LAYER", 25, "" '                                               no, report error to programmer
  372.         ELSE '                                                                                          yes, valid layer
  373.             _DEST SL_layer(layer).image '                                                               set destination as layer software image
  374.             SL_global.destination = layer '                                                             save new destination layer
  375.         END IF
  376.     ELSE '                                                                                              yes, reset layer
  377.         _DEST SL_layer(1).image '                                                                       set destination as layer 1 software image
  378.         SL_global.destination = 1 '                                                                     save new destination layer
  379.     END IF
  380.  
  381.  
  382. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  383. SUB SL_SET_SOURCE_LAYER (layer AS INTEGER) '                                                                                                                                        SL_SET_SOURCE_LAYER
  384.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  385.  
  386.     ' declare global variables
  387.  
  388.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  389.     SHARED SL_global AS SL_GLOBAL '     common globals array
  390.  
  391.     ' perform error checks
  392.  
  393.     IF layer <> -32767 THEN '                                                               (SL_RESET)  reset to working image?
  394.         IF NOT SL_VALID_LAYER(layer) THEN '                                                             no, valid layer?
  395.             SL_error "SL_SET_SOURCE_LAYER", 25, "" '                                                    no, report error to programmer
  396.         ELSE '                                                                                          yes, valid layer
  397.             _SOURCE SL_layer(layer).image '                                                             set source as layer software image
  398.             SL_global.source = layer '                                                                  save new source layer
  399.         END IF
  400.     ELSE '                                                                                              yes, reset layer
  401.         _SOURCE SL_layer(1).image '                                                                     set source as layer 1 software image
  402.         SL_global.source = 1 '                                                                          save new source layer
  403.     END IF
  404.  
  405.  
  406. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  407. FUNCTION SL_GET_DESTINATION_LAYER () '                                                                                                                                         SL_GET_DESTINATION_LAYER
  408.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  409.  
  410.     ' declare global variables
  411.  
  412.     SHARED SL_global AS SL_GLOBAL '     common globals array
  413.  
  414.     SL_GET_DESTINATION_LAYER = SL_global.destination '                                                  return current destination layer
  415.  
  416.  
  417. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  418. FUNCTION SL_GET_SOURCE_LAYER () '                                                                                                                                                   SL_GET_SOURCE_LAYER
  419.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  420.  
  421.     ' declare global variables
  422.  
  423.     SHARED SL_global AS SL_GLOBAL '     common globals array
  424.  
  425.     SL_GET_SOURCE_LAYER = SL_global.source '                                                            return current source layer
  426.  
  427.  
  428. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  429. SUB SL_CLEAR_LAYER (layer AS INTEGER) '                                                                                                                                                  SL_CLEAR_LAYER
  430.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  431.  
  432.     ' declare global variables
  433.  
  434.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  435.     SHARED SL_global AS SL_GLOBAL '     common globals array
  436.  
  437.     ' declare local variables
  438.  
  439.     DIM layers AS INTEGER '             layer counter
  440.  
  441.     ' perform error checks
  442.  
  443.     IF layer <> -1 THEN '                                                                     (SL_ALL)  clear all layers?
  444.         IF NOT SL_VALID_LAYER(layer) THEN '                                                             no, valid layer?
  445.             SL_error "SL_CLEAR_LAYER", 25, "" '                                                         no, report error to programmer
  446.         END IF
  447.         _FREEIMAGE SL_layer(layer).image '                                                              free the layer's software image from memory
  448.         SL_layer(layer).image = _NEWIMAGE(SL_global.swidth, SL_global.sheight, 32) '                    create a new software layer
  449.     ELSE '                                                                                              yes, clear all layers
  450.         layers = 0 '                                                                                    reset layer counter
  451.         DO
  452.             layers = layers + 1 '                                                                       increment layer counter
  453.             _FREEIMAGE SL_layer(layers).image '                                                         free the layer's software image from memory
  454.             SL_layer(layers).image = _NEWIMAGE(SL_global.swidth, SL_global.sheight, 32) '               create a new software layer
  455.         LOOP UNTIL layers = UBOUND(SL_layer) '                                                          leave when all layers cleared
  456.     END IF
  457.  
  458.  
  459. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  460. FUNCTION SL_VALID_LAYER (layer AS INTEGER) '                                                                                                                                             SL_VALID_LAYER
  461.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  462.  
  463.     ' declare global variables
  464.  
  465.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  466.  
  467.     IF layer < 1 OR layer > UBOUND(SL_layer) THEN '                                                     valid layer?
  468.         SL_VALID_LAYER = 0 '                                                                   (FALSE)  no, return invalid
  469.     ELSE '                                                                                              yes
  470.         SL_VALID_LAYER = -1 '                                                                   (TRUE)  return valid
  471.     END IF
  472.  
  473.  
  474. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  475. FUNCTION SL_SCREEN_WIDTH () '                                                                                                                                                           SL_SCREEN_WIDTH
  476.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  477.  
  478.     ' declare global variables
  479.  
  480.     SHARED SL_global AS SL_GLOBAL '     common globals array
  481.  
  482.     SL_SCREEN_WIDTH = SL_global.swidth '                                                                return screen width
  483.  
  484.  
  485. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  486. FUNCTION SL_SCREEN_HEIGHT () '                                                                                                                                                         SL_SCREEN_HEIGHT
  487.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  488.  
  489.     ' declare global variables
  490.  
  491.     SHARED SL_global AS SL_GLOBAL '     common globals array
  492.  
  493.     SL_SCREEN_HEIGHT = SL_global.sheight '                                                              return screen height
  494.  
  495.  
  496. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  497. SUB SL_SET_LAYER_VISBILE (layer AS INTEGER, visible AS INTEGER) '                                                                                                                  SL_SET_LAYER_VISIBLE
  498.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  499.  
  500.     ' declare global variables
  501.  
  502.     SHARED SL_layer() AS SL_LAYERS '    master layer array
  503.  
  504.     ' perform error checks
  505.  
  506.     IF NOT SL_VALID_LAYER(layer) THEN '                                                                 no, valid layer?
  507.         SL_error "SL_SET_LAYER_VISIBLE", 25, "" '                                                       no, report error to programmer
  508.     END IF
  509.     IF (visible < -1) OR (visible > 0) THEN '                                      (SL_SHOW & SL_HIDE)  valid visible behavior requested?
  510.         SL_error "SL_SET_LAYER_VISIBLE", 20, "" '                                                       no, report error to programmer
  511.     END IF
  512.  
  513.     SL_layer(layer).visible = visible '                                                                 set layer visibility
  514.  
  515.  
  516. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  517. '                                                                       ----------==========                ==========----------
  518. '                                                                       ----------========== MOUSE ROUTINES ==========----------
  519. '                                                                       ----------==========                ==========----------
  520. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  521.  
  522. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  523. FUNCTION SL_GET_MOUSE (handle AS INTEGER) '                                                                                                                                                SL_GET_MOUSE
  524.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  525.  
  526.     ' declare global variables
  527.  
  528.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  529.  
  530.     ' declare local variables
  531.  
  532.     DIM sprite AS INTEGER '             sprite counter to cycle through array
  533.     DIM event AS INTEGER '              -1 (TRUE) if an event was recorded
  534.  
  535.     ' perform error checks
  536.  
  537.     IF handle <> -1 THEN '                                                                    (SL_ALL)  check all sprites for mouse interaction?
  538.         IF NOT SL_VALID_SPRITE(handle) THEN '                                                           no, is this a valid sprite?
  539.             SL_error "SL_GET_MOUSE", 1, "" '                                                            no, report error to programmer
  540.         END IF
  541.         IF NOT SL_sprite(handle).visible THEN '                                                         is sprite visible?
  542.             EXIT FUNCTION '                                                                             no, leave function
  543.         END IF
  544.     END IF
  545.     IF handle = -1 THEN '                                                                     (SL_ALL)  check all sprites?
  546.         sprite = 1 '                                                                                    yes, start with first index
  547.     ELSE '                                                                                              no, check a single sprite
  548.         sprite = handle '                                                                               start with that sprite
  549.     END IF
  550.  
  551.     DO '                                                                                                cycle through sprite array
  552.         IF SL_sprite(handle).inuse AND SL_sprite(handle).visible THEN '                                 is sprite in use and visible?
  553.             SL_sprite(handle).mouse.event = 0 '                                                         yes, reset mouse settings
  554.             SL_sprite(handle).mouse.x = 0
  555.             SL_sprite(handle).mouse.y = 0
  556.             SL_sprite(handle).mouse.xa = 0
  557.             SL_sprite(handle).mouse.ya = 0
  558.             WHILE _MOUSEINPUT: WEND '                                                                   get latest mouse information
  559.             IF _MOUSEX >= SL_sprite(sprite).collision.x1 THEN '                                         is mouse pointer on sprite?
  560.                 IF _MOUSEX <= SL_sprite(sprite).collision.x2 THEN
  561.                     IF _MOUSEY >= SL_sprite(sprite).collision.y1 THEN
  562.                         IF _MOUSEY <= SL_sprite(sprite).collision.y2 THEN
  563.                             event = -1 '                                                                yes, remember that an event occurred
  564.                             SL_sprite(sprite).mouse.xa = _MOUSEX '                                      screen location of mouse x
  565.                             SL_sprite(sprite).mouse.ya = _MOUSEY '                                      screen location of mouse y
  566.                             SL_sprite(sprite).mouse.x = _MOUSEX - SL_sprite(sprite).x.actual '          sprite location of mouse x
  567.                             SL_sprite(sprite).mouse.y = _MOUSEY - SL_sprite(sprite).y.actual '          sprite location of mouse y
  568.                             IF _MOUSEBUTTON(1) THEN '                                                   is left button clicked?
  569.                                 SL_GET_MOUSE = 2 '                                      (SL_LEFTCLICK)  yes, return value
  570.                                 SL_sprite(sprite).mouse.event = 2 '                     (SL_LEFTCLICK)  record mouse event
  571.                             ELSEIF _MOUSEBUTTON(2) THEN '                                               no, is right button clicked?
  572.                                 SL_GET_MOUSE = 3 '                                     (SL_RIGHTCLICK)  yes, return value
  573.                                 SL_sprite(sprite).mouse.event = 3 '                    (SL_RIGHTCLICK)  record mouse event
  574.                             ELSEIF _MOUSEBUTTON(3) THEN '                                               no, is center button clicked?
  575.                                 SL_GET_MOUSE = 4 '                                    (SL_CENTERCLICK)  yes, return value
  576.                                 SL_sprite(sprite).mouse.event = 4 '                   (SL_CENTERCLICK)  record mouse event
  577.                             ELSE '                                                                      no, mouse is just hovering
  578.                                 SL_GET_MOUSE = 1 '                                          (SL_HOVER)  return value
  579.                                 SL_sprite(sprite).mouse.event = 1 '                         (SL_HOVER)  record mouse event
  580.                             END IF
  581.                         END IF
  582.                     END IF
  583.                 END IF
  584.             END IF
  585.         END IF
  586.         sprite = sprite + 1 '                                                                           increment sprite counter
  587.     LOOP UNTIL sprite = (UBOUND(SL_sprite) + 1) OR (handle = -1) '                                      leave when full array or single sprite checked
  588.  
  589.     IF handle = -1 THEN '                                                                     (SL_ALL)  were all sprites checked?
  590.         IF event THEN '                                                                                 yes, was there an event with any of them?
  591.             SL_GET_MOUSE = -1 '                                                                 (TRUE)  return that an event occurred
  592.         ELSE '                                                                                          no events recorded
  593.             SL_GET_MOUSE = 0 '                                                                 (FALSE)  return that no events occurred
  594.         END IF
  595.     END IF
  596.  
  597.  
  598. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  599. FUNCTION SL_GET_MOUSE_EVENT (handle AS INTEGER) '                                                                                                                                    SL_GET_MOUSE_EVENT
  600.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  601.  
  602.     ' declare global variables
  603.  
  604.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  605.  
  606.     ' perform error checks
  607.  
  608.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  609.         SL_error "SL_GET_MOUSE_EVENT", 1, "" '                                                          no, report error to programmer
  610.     END IF
  611.  
  612.     SL_GET_MOUSE_EVENT = SL_sprite(handle).mouse.event '                                                return mouse event
  613.     SL_sprite(handle).mouse.event = 0 '                                                                 reset now that value retrieved
  614.  
  615.  
  616. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  617. FUNCTION SL_GET_MOUSE_SPRITEX (handle AS INTEGER) '                                                                                                                                SL_GET_MOUSE_SPRITEX
  618.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  619.  
  620.     ' declare global variables
  621.  
  622.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  623.  
  624.     ' perform error checks
  625.  
  626.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  627.         SL_error "SL_GET_MOUSE_SPRITEX", 1, "" '                                                        no, report error to programmer
  628.     END IF
  629.  
  630.     SL_GET_MOUSE_SPRITEX = SL_sprite(handle).mouse.x '                                                  return x value of mouse on sprite
  631.     SL_sprite(handle).mouse.x = 0 '                                                                     reset now that value retrieved
  632.  
  633.  
  634. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  635. FUNCTION SL_GET_MOUSE_SPRITEY (handle AS INTEGER) '                                                                                                                                SL_GET_MOUSE_SPRITEY
  636.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  637.  
  638.     ' declare global variables
  639.  
  640.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  641.  
  642.     ' perform error checks
  643.  
  644.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  645.         SL_error "SL_GET_MOUSE_SPRITEY", 1, "" '                                                        no, report error to programmer
  646.     END IF
  647.  
  648.     SL_GET_MOUSE_SPRITEY = SL_sprite(handle).mouse.y '                                                  return y value of mouse on sprite
  649.     SL_sprite(handle).mouse.y = 0 '                                                                     reset now that value retrieved
  650.  
  651.  
  652. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  653. FUNCTION SL_GET_MOUSE_ACTUALX (handle AS INTEGER) '                                                                                                                                SL_GET_MOUSE_ACTUALX
  654.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  655.  
  656.     ' declare global variables
  657.  
  658.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  659.  
  660.     ' perform error checks
  661.  
  662.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  663.         SL_error "SL_GET_MOUSE_ACTUALX", 1, "" '                                                        no, report error to programmer
  664.     END IF
  665.  
  666.     SL_GET_MOUSE_ACTUALX = SL_sprite(handle).mouse.xa '                                                 return x value of mouse on screen
  667.     SL_sprite(handle).mouse.xa = 0 '                                                                    reset now that value retrieved
  668.  
  669.  
  670. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  671. FUNCTION SL_GET_MOUSE_ACTUALY (handle AS INTEGER) '                                                                                                                                SL_GET_MOUSE_ACTUALY
  672.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  673.  
  674.     ' declare global variables
  675.  
  676.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  677.  
  678.     ' perform error checks
  679.  
  680.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  681.         SL_error "SL_GET_MOUSE_ACTUALY", 1, "" '                                                        no, report error to programmer
  682.     END IF
  683.  
  684.     SL_GET_MOUSE_ACTUALY = SL_sprite(handle).mouse.ya '                                                 return y value of mouse on screen
  685.     SL_sprite(handle).mouse.ya = 0 '                                                                    reset now that value retrieved
  686.  
  687.  
  688. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  689. '                                                                     ----------==========                    ==========----------
  690. '                                                                     ----------========== COLLISION ROUTINES ==========----------
  691. '                                                                     ----------==========                    ==========----------
  692. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  693.  
  694. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  695. FUNCTION SL_GET_COLLISION (handle1 AS INTEGER, handle2 AS INTEGER) '                                                                                                                   SL_GET_COLLISION
  696.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  697.  
  698.     ' declare global variables
  699.  
  700.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  701.  
  702.     ' declare local variables
  703.  
  704.     DIM sprite AS INTEGER '             sprite counter in loop
  705.  
  706.     ' perform error checks
  707.  
  708.     IF NOT SL_VALID_SPRITE(handle1) THEN '                                                              is this a valid sprite?
  709.         SL_error "SL_GET_COLLISION", 1, "" '                                                            no, report error to programmer
  710.     END IF
  711.     IF handle2 <> -1 THEN '                                                                   (SL_ALL)  check for collision with all sprites?
  712.         IF NOT SL_VALID_SPRITE(handle2) THEN '                                                          no, is this a valid sprite?
  713.             SL_error "SL_GET_COLLISION", 1, "" '                                                        no, report error to programmer
  714.         END IF
  715.         IF SL_sprite(handle2).collision.detect = 0 THEN '                                               collision detection turned on?
  716.             SL_error "SL_GET_COLLISION", 22, "" '                                                       no, report error to programmer
  717.         END IF
  718.         'IF SL_sprite(handle1).collision.detect <> SL_sprite(handle2).collision.detect THEN '            both sprites use same detection method?
  719.         '    SL_error "SL_GET_COLLISION", 23, "" '                                                       no, report error to programmer
  720.         'END IF
  721.     END IF
  722.     IF SL_sprite(handle1).collision.detect = 0 THEN '                                                   collision detection turned on?
  723.         SL_error "SL_GET_COLLISION", 21, "" '                                                           no, report error to programmer
  724.     END IF
  725.  
  726.     SELECT CASE SL_sprite(handle1).collision.detect
  727.         CASE 1 '                                                                              (SL_BOX)  box detection
  728.             IF handle2 <> -1 THEN '                                                           (SL_ALL)  check all sprites for collision?
  729.                 SL_sprite(handle1).collision.box = SL_box_collision(SL_sprite(handle1).collision.x1,_
  730.                                                                     SL_sprite(handle1).collision.y1,_
  731.                                                                     SL_sprite(handle1).collision.cwidth,_
  732.                                                                     SL_sprite(handle1).collision.cheight,_
  733.                                                                     SL_sprite(handle2).collision.x2,_
  734.                                                                     SL_sprite(handle2).collision.y2,_
  735.                                                                     SL_sprite(handle2).collision.cwidth,_
  736.                                                                     SL_sprite(handle2).collision.cheight) ' no, check for a box collision of two sprites
  737.                 IF SL_sprite(handle1).collision.box THEN '                                              was there a collision?
  738.                     SL_sprite(handle1).collision.with = handle2 '                                       yes, record sprite that was collided with
  739.                     SL_sprite(handle2).collision.with = handle1 '                                       tell the other sprite who it collided with
  740.                     SL_GET_COLLISION = handle2 '                                                (TRUE)  return that a collision happened
  741.                 END IF
  742.             ELSE '                                                                                      yes, check all sprites
  743.                 sprite = 0 '                                                                            reset sprite counter
  744.                 DO '                                                                                    cycle through sprite array
  745.                     sprite = sprite + 1 '                                                               increment sprite counter
  746.                     IF SL_sprite(sprite).inuse AND SL_sprite(sprite).collision.detect THEN '            is sprite in use and using collision detection?
  747.                         SL_sprite(handle1).collision.box = SL_box_collision(SL_sprite(handle1).collision.x1,_
  748.                                                                             SL_sprite(handle1).collision.y1,_
  749.                                                                             SL_sprite(handle1).collision.cwidth,_
  750.                                                                             SL_sprite(handle1).collision.cheight,_
  751.                                                                             SL_sprite(sprite).collision.x2,_
  752.                                                                             SL_sprite(sprite).collision.y2,_
  753.                                                                             SL_sprite(sprite).collision.cwidth,_
  754.                                                                             SL_sprite(sprite).collision.cheight) ' yes, check for a box collision of two sprites
  755.                         IF SL_sprite(handle1).collision.box THEN '                                      box collision detected?
  756.                             SL_sprite(handle1).collision.with = sprite '                                yes, record sprite that was collided with
  757.                             SL_sprite(sprite).collision.with = handle1 '                                tell the other sprite who it collided with
  758.                             SL_GET_COLLISION = sprite '                                         (TRUE)  return that collision happened
  759.                             sprite = UBOUND(SL_sprite) '                                                no need to check further
  760.                         END IF
  761.                     END IF
  762.                 LOOP UNTIL sprite = UBOUND(SL_sprite) '                                                 leave when end of array reached
  763.             END IF
  764.         CASE 2 '                                                                            (SL_ROUND)  round collision
  765.             IF handle2 <> -1 THEN '                                                           (SL_ALL)  check all sprites for collision?
  766.                 SL_sprite(handle1).collision.round = sl_round_collision(SL_sprite(handle1).x.int,_
  767.                                                                         SL_sprite(handle1).y.int,_
  768.                                                                         SL_sprite(handle1).collision.radius,_
  769.                                                                         SL_SPRITE(handle2).x.int,_
  770.                                                                         SL_sprite(handle2).y.int,_
  771.                                                                         SL_sprite(handle2).collision.radius) ' no, check for a round collision of two sprites
  772.                 IF SL_sprite(handle1).collision.round THEN '                                            was there a collision?
  773.                     SL_sprite(handle1).collision.with = handle2 '                                       yes, record sprite that was collided with
  774.                     SL_sprite(handle2).collision.with = handle1 '                                       tell the other sprite who it collided with
  775.                     SL_GET_COLLISION = handle2 '                                                (TRUE)  return that a collision happened
  776.                 END IF
  777.             ELSE '                                                                                      yes, check all sprites
  778.                 sprite = 0 '                                                                            reset sprite counter
  779.                 DO '                                                                                    cycle through sprite array
  780.                     sprite = sprite + 1 '                                                               increment sprite counter
  781.                     IF SL_sprite(sprite).inuse AND SL_sprite(sprite).collision.detect THEN '            is sprite in use and using collision detection?
  782.                         SL_sprite(handle1).collision.round = sl_round_collision(SL_sprite(handle1).x.int,_
  783.                                                                                 SL_sprite(handle1).y.int,_
  784.                                                                                 SL_sprite(handle1).collision.radius,_
  785.                                                                                 SL_sprite(sprite).x.int,_
  786.                                                                                 SL_sprite(sprite).y.int,_
  787.                                                                                 SL_sprite(sprite).collision.radius) ' yes, check for a round collision of two sprites
  788.                         IF SL_sprite(handle1).collision.round THEN '                                    round collision detected?
  789.                             SL_sprite(handle1).collision.with = sprite '                                yes, record sprite that was collided with
  790.                             SL_sprite(sprite).collision.with = handle1 '                                tell the other sprite who it collided with
  791.                             SL_GET_COLLISION = sprite '                                         (TRUE)  return that collision happened
  792.                             sprite = UBOUND(SL_sprite) '                                                no need to check further
  793.                         END IF
  794.                     END IF
  795.                 LOOP UNTIL sprite = UBOUND(SL_sprite) '                                                 leave when end of array reached
  796.             END IF
  797.         CASE 3 '                                                                            (SL_PIXEL)  pixel perfect collision
  798.             IF handle2 <> -1 THEN '                                                           (SL_ALL)  check all sprites for collision?
  799.                 SL_sprite(handle1).collision.pixel = SL_PIXEL_COLLISION(handle1, handle2) '             yes, check for a pixel collision of two sprites
  800.                 IF SL_sprite(handle1).collision.pixel THEN '                                            pixel collision detected?
  801.                     SL_sprite(handle1).collision.with = handle2 '                                       yes, record sprite that was collided with
  802.                     SL_sprite(handle2).collision.with = handle1 '                                       tell the other sprite who it collided with
  803.                     SL_GET_COLLISION = handle2 '                                                (TRUE)  return that collision happened
  804.                 END IF
  805.             ELSE '                                                                                      yes, check all sprites
  806.                 sprite = 0 '                                                                            reset sprite counter
  807.                 DO '                                                                                    cycle through sprite array
  808.                     sprite = sprite + 1 '                                                               increment sprite counter
  809.                     IF SL_sprite(sprite).inuse AND SL_sprite(sprite).collision.detect THEN '            is sprite in use and using collision detection? (may need to see if mask available too) <--------------- LOOK
  810.                         SL_sprite(handle1).collision.pixel = SL_PIXEL_COLLISION(handle1, sprite) '      yes, check for a pixel collision of two sprites
  811.                         IF SL_sprite(handle1).collision.pixel THEN '                                    pixel collision detected?
  812.                             SL_sprite(handle1).collision.with = sprite '                                yes, record sprite that was collided with
  813.                             SL_sprite(sprite).collision.with = handle1 '                                tell the other sprite who it collided with
  814.                             SL_GET_COLLISION = sprite '                                         (TRUE)  return that collision happened
  815.                             sprite = UBOUND(SL_sprite) '                                                no need to check further
  816.                         END IF
  817.                     END IF
  818.                 LOOP UNTIL sprite = UBOUND(SL_sprite) '                                                 leave when end of array reached
  819.             END IF
  820.     END SELECT
  821.  
  822.  
  823. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  824. FUNCTION SL_ROUND_COLLISION (x1 AS INTEGER, y1 AS INTEGER, r1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, r2 AS INTEGER) '                                                             SL_ROUND_COLLISION
  825.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  826.  
  827.     IF SL_GET_DISTANCE_POINT_TO_POINT(x1, y1, x2, y2) < r1 + r2 THEN '                                  is distance less than both radii added together?
  828.         SL_ROUND_COLLISION = -1 '                                                               (TRUE)  yes, return a collision
  829.     END IF
  830.  
  831.  
  832. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  833. FUNCTION SL_BOX_COLLISION (x1 AS INTEGER, y1 AS INTEGER, w1 AS INTEGER, h1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER, w2 AS INTEGER, h2 AS INTEGER) '                                   SL_BOX_COLLISION
  834.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  835.  
  836.     IF x1 <= x2 + w2 THEN '                                                                             is x1 within box 2's width?
  837.         IF x1 + w1 >= x2 THEN '                                                                         yes, is x2 within box 1's width?
  838.             IF y1 <= y2 + h2 THEN '                                                                     yes, is y1 within box 2's height?
  839.                 IF y1 + h1 >= y2 THEN '                                                                 yes, is y2 within box 1's height?
  840.                     SL_BOX_COLLISION = -1 '                                                     (TRUE)  yes, return a collision
  841.                 END IF
  842.             END IF
  843.         END IF
  844.     END IF
  845.  
  846.  
  847. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  848. FUNCTION SL_PIXEL_COLLISION (handle1 AS INTEGER, handle2 AS INTEGER) '                                                                                                               SL_PIXEL_COLLISION
  849.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  850.  
  851.     ' declare global variables
  852.  
  853.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  854.  
  855.     ' declare local variables
  856.  
  857.     DIM leftx AS INTEGER '              upper left x location of box collision area
  858.     DIM rightx AS INTEGER '             lower right x location of box collision area
  859.     DIM topy AS INTEGER '               upper left y location of box collision area
  860.     DIM bottomy AS INTEGER '            lower right y location of box collision area
  861.     DIM masks AS LONG '                 box collision area image to place masks
  862.     DIM h1x AS INTEGER '                center point x offset for first sprite mask image
  863.     DIM h2x AS INTEGER '                center point x offset for second sprite mask image
  864.     DIM h1y AS INTEGER '                center point y offset for first sprite mask image
  865.     DIM h2y AS INTEGER '                center point y offset for second sprite mask image
  866.     DIM odest AS LONG '                 original destination
  867.     DIM osource AS LONG '               original source
  868.     DIM x AS INTEGER '                  counter to cycle through width of mask image
  869.     DIM y AS INTEGER '                  counter to cycle throuogh height of mask image
  870.  
  871.     ' perform error checks
  872.  
  873.     IF (NOT SL_VALID_SPRITE(handle1)) OR (NOT SL_VALID_SPRITE(handle2)) THEN '                          are these valid sprites?
  874.         SL_error "SL_PIXEL_COLLISION", 1, "" '                                                          no, report error to programmer
  875.     END IF
  876.  
  877.     ' if there is no box collision then no need to check for pixel collision
  878.  
  879.     IF  SL_box_collision(SL_sprite(handle1).collision.x1, SL_sprite(handle1).collision.y1,_
  880.                            SL_sprite(handle1).collision.cwidth, SL_sprite(handle1).collision.cheight,_
  881.                            SL_sprite(handle2).collision.x2, SL_sprite(handle2).collision.y2,_
  882.                            SL_sprite(handle2).collision.cwidth, SL_sprite(handle2).collision.cheight) THEN 'is there a box collision?
  883.         leftx = SL_max(SL_sprite(handle1).collision.x1, SL_sprite(handle2).collision.x1) '              yes, get collision area coordinates
  884.         rightx = SL_min(SL_sprite(handle1).collision.x1 + SL_sprite(handle1).collision.cwidth,_
  885.                         SL_sprite(handle2).collision.x1 + SL_sprite(handle2).collision.cwidth)
  886.         topy = SL_max(SL_sprite(handle1).collision.y1, SL_sprite(handle2).collision.y1)
  887.         bottomy = SL_min(SL_sprite(handle1).collision.y1 + SL_sprite(handle1).collision.cheight,_
  888.                          SL_sprite(handle2).collision.y1 + SL_sprite(handle2).collision.cheight)
  889.  
  890.         odest = _DEST '                                                                                 save original destination
  891.         osource = _SOURCE '                                                                             save original source
  892.         masks = _NEWIMAGE(rightx - leftx, bottomy - topy, 32) '                                         create image of same size to hold image masks
  893.         h1x = SL_sprite(handle1).x.int - leftx '                                                        get image mask center point offsets from collision area upper left x,y
  894.         h1y = SL_sprite(handle1).y.int - topy
  895.         h2x = SL_sprite(handle2).x.int - leftx
  896.         h2y = SL_sprite(handle2).y.int - topy
  897.         _DEST masks '                                                                                   masks are to be drawn on new image
  898.         _SOURCE masks '                                                                                 pixels are to be examined on new image
  899.         _PUTIMAGE (-h1x, -h1y), SL_sprite(handle1).gfx.mask '                                           draw first sprite mask onto image
  900.         _PUTIMAGE (-h2x, -h2y), SL_sprite(handle2).gfx.mask '                                           draw second sprite mask onto image
  901.         x = 0 '                                                                                         reset width couonter
  902.  
  903.         DO '                                                                                            cycle through width of image
  904.             y = 0 '                                                                                     reset height counter
  905.             DO '                                                                                        cycle through height of image
  906.                 IF POINT(x, y) = _RGBA32(0, 0, 0, 0) THEN '                                             is this a black pixel? <----------------------------------- used saved clearcolor instead?  LOOK
  907.                     SL_sprite(handle1).collision.with = handle2 '                                       yes, record sprite that was collided with
  908.                     SL_sprite(handle2).collision.with = handle1 '                                       tell the other sprite who it collided with
  909.                     SL_PIXEL_COLLISION = handle2 '                                              (TRUE)  return that collision happened
  910.                     y = _HEIGHT(masks) - 1 '                                                            no need to continue loop
  911.                     x = _WIDTH(masks) - 1 '                                                             no need to continue loop
  912.                 END IF
  913.                 y = y + 1 '                                                                             increment height counter
  914.             LOOP UNTIL y = _HEIGHT(masks) '                                                             leave when full height cycled
  915.             x = x + 1 '                                                                                 increment width counter
  916.         LOOP UNTIL x = _WIDTH(masks) '                                                                  leave when full width cycled
  917.  
  918.         _SOURCE osource '                                                                               restore original source
  919.         _DEST odest '                                                                                   restore original destination
  920.         _FREEIMAGE masks '                                                                              mask image no longer needed
  921.     END IF
  922.  
  923.  
  924. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  925. SUB SL_SET_COLLISION (handle AS INTEGER, method AS INTEGER) '                                                                                                                          SL_SET_COLLISION
  926.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  927.  
  928.     ' declare global variables
  929.  
  930.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  931.  
  932.     ' perform error checks
  933.  
  934.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  935.         SL_error "SL_SET_COLLISION", 1, "" '                                                            no, report error to programmer
  936.     END IF
  937.     IF method = -32767 THEN '                                                               (SL_RESET)  reset collision detection?
  938.         SL_sprite(handle).collision.detect = 0 '                                         (SL_NODETECT)  yes, reset detection
  939.     ELSEIF method < 0 OR method > 3 THEN ' (SL_NODETECT, SL_BOXDETECT, SL_ROUNDDETECT, SL_PIXELDETECT)  invalid mode?
  940.         SL_error "SL_SET_COLLISION", 24, "" '                                                           yes, report error to programmer
  941.     ELSE '                                                                                              no
  942.         SL_sprite(handle).collision.detect = method '                                                   set collision detection mode
  943.     END IF
  944.  
  945.  
  946. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  947. '                                                                     ----------==========                    ==========----------
  948. '                                                                     ----------========== ANIMATION ROUTINES ==========----------
  949. '                                                                     ----------==========                    ==========----------
  950. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  951.  
  952. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  953. SUB SL_SET_FRAMERATE (framerate AS INTEGER) '                                                                                                                                          SL_SET_FRAMERATE
  954.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  955.  
  956.     ' declare global variables
  957.  
  958.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  959.     SHARED SL_global AS SL_GLOBAL
  960.  
  961.     ' declare local variables
  962.  
  963.     DIM handle AS INTEGER '             counter to cycle through sprite handles
  964.  
  965.     ' perform error checks
  966.  
  967.     IF framerate < 1 THEN '                                                                             valid frame rate?
  968.         SL_error "SL_SET_FRAMERATE", 10, "" '                                                           no, report error to programmer
  969.     END IF
  970.  
  971.     ' set local variables
  972.  
  973.     SL_global.framerate = framerate '                                                                   set global frame rate
  974.     handle = 0 '                                                                                        reset handle counter
  975.  
  976.     DO '                                                                                                update all available sprites
  977.         handle = handle + 1 '                                                                           increment sprite pointer
  978.         IF SL_sprite(handle).inuse THEN '                                                               is this sprite in use?
  979.             IF SL_sprite(handle).animation.framerate THEN '                                             yes, does it contain an animation frame rate?
  980.                 IF framerate < SL_sprite(handle).animation.framerate THEN '                             is new global frame rate less than sprite's frame rate?
  981.                     SL_sprite(handle).animation.framerate = framerate '                                 yes, set sprite's frame rate to global frame rate
  982.                 END IF
  983.                 IF framerate = SL_sprite(handle).animation.framerate THEN '                             animation and global frame rates the same?
  984.                     SL_sprite(handle).animation.skip = 0 '                                              yes, nothing needs to be done with frames
  985.                 ELSEIF SL_sprite(handle).animation.framerate >= framerate \ 2 THEN '                    no, sprite frame rate 1/2 or less of master frame rate?
  986.                     SL_sprite(handle).animation.skip = framerate \ (framerate - SL_sprite(handle).animation.framerate) ' yes, calculate every frame to skip
  987.                 ELSE '                                                                                  no, sprite frame rate is greater than 1/2 of master frame rate
  988.                     SL_sprite(handle).animation.skip = framerate \ SL_sprite(handle).animation.framerate ' calculate every frame to draw
  989.                 END IF
  990.             END IF
  991.         END IF
  992.     LOOP UNTIL handle = UBOUND(SL_sprite) '                                                             leave when all sprites updated
  993.  
  994.  
  995. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  996. FUNCTION SL_GET_FRAMERATE () '                                                                                                                                                         SL_GET_FRAMERATE
  997.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  998.  
  999.     ' declare global variables
  1000.  
  1001.     SHARED SL_global AS SL_GLOBAL
  1002.  
  1003.     SL_GET_FRAMERATE = SL_global.framerate '                                                            return global frame rate
  1004.  
  1005.  
  1006. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1007. SUB SL_NEXT_ANIMATION_CELL (handle AS INTEGER) '                                                                                                                                 SL_NEXT_ANIMATION_CELL
  1008.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1009.  
  1010.     ' declare global variables
  1011.  
  1012.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1013.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  1014.  
  1015.     ' perform error checks
  1016.  
  1017.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1018.         SL_error "SL_NEXT_ANIMATION_CELL", 1, "" '                                                      no, report error to programmer
  1019.     END IF
  1020.     IF NOT SL_sprite(handle).animation.cellfrom THEN '                                                  has animation been assigned to this sprite?
  1021.         SL_error "SL_NEXT_ANIMATION_CELL", 15, "" '                                                     no, report error to programmer
  1022.     END IF
  1023.     IF SL_sprite(handle).animation.auto THEN '                                                          is this sprite under auto animation control?
  1024.         SL_error "SL_NEXT_ANIMATION_CELL", 18, "" '                                                     yes, report error to programmer
  1025.     END IF
  1026.  
  1027.     SELECT CASE SL_sprite(handle).animation.mode '                                                      which animation mode is this sprite using?
  1028.         CASE 0 '                                                                          (SL_FORWARD)  move forward through the cells
  1029.             SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell + 1 '                   increment animation cell
  1030.             IF SL_sprite(handle).animation.cell > SL_sprite(handle).animation.cellto THEN '             passed the last cell?
  1031.                 SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellfrom '               yes, go back to first cell
  1032.             END IF
  1033.         CASE 1 '                                                                         (SL_BACKWARD)  move backward through the cells
  1034.             SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell - 1 '                   decrement animation cell
  1035.             IF SL_sprite(handle).animation.cell < SL_sprite(handle).animation.cellfrom THEN '           passed the first cell?
  1036.                 SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellto '                 yes, go back to last cell
  1037.             END IF
  1038.         CASE 2 '                                                                        (SL_BACKFORTH)  ping-pong back and forth through the cells
  1039.             SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell + SL_sprite(handle).animation.dir ' increment/decrement animation cell
  1040.             IF SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellto OR _
  1041.                SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellfrom THEN '           is this the first or last cell?
  1042.                 SL_sprite(handle).animation.dir = -SL_sprite(handle).animation.dir '                    yes, reverse animation direction
  1043.             END IF
  1044.     END SELECT
  1045.     SL_sprite(handle).cell = SL_sprite(handle).animation.cell '                                         update current sprite cell
  1046.     IF SL_sprite(handle).rotation.angle AND (NOT SL_sprite(handle).rotation.auto) THEN '                is this animation currently rotated but not automatic?
  1047.         SL_ROTATE_SPRITE handle, SL_sprite(handle).rotation.angle '                                     yes, this new cell will need manually rotated as well
  1048.     ELSE '                                                                                              no rotation, but still needs image updated
  1049.         _FREEIMAGE SL_sprite(handle).gfx.software '                                                     remove current software image from memory
  1050.         SL_sprite(handle).gfx.software = _COPYIMAGE(SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).software, 32) ' get new software image
  1051.         IF SL_sprite(handle).gfx.mask THEN '                                                            is there a mask with this image?
  1052.             _FREEIMAGE SL_sprite(handle).gfx.mask '                                                     yes, remove the software mask image from memory
  1053.             SL_sprite(handle).gfx.mask = _COPYIMAGE(SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).mask, 32) ' get new software mask image
  1054.         END IF
  1055.     END IF
  1056.  
  1057.  
  1058. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1059. SUB SL_CHANGE_ANIMATION_CELLS (handle AS INTEGER, cellfrom AS INTEGER, cellto AS INTEGER) '                                                                                   SL_CHANGE_ANIMATION_CELLS
  1060.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1061.  
  1062.     ' declare global variables
  1063.  
  1064.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1065.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  1066.  
  1067.     ' perform error checks
  1068.  
  1069.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1070.         SL_error "SL_CHANGE_ANIMATION_CELLS", 1, "" '                                                   no, report error to programmer
  1071.     END IF
  1072.     IF NOT SL_sprite(handle).animation.cellfrom THEN '                                                  has animation been assigned to this sprite?
  1073.         SL_error "SL_CHANGE_ANIMATION_CELLS", 15, "" '                                                  no, report error to programmer
  1074.     END IF
  1075.     IF NOT SL_VALID_CELL(SL_sprite(handle).sheet, cellfrom) THEN '                                      no, is this a valid cell request?
  1076.         SL_error "SL_CHANGE_ANIMATION_CELLS", 13, "" '                                                  no, report error to rpogrammer
  1077.     END IF
  1078.     IF NOT SL_VALID_CELL(SL_sprite(handle).sheet, cellto) THEN '                                        is this valid cell request?
  1079.         SL_error "SL_CHANGE_ANIMATION_CELLS", 13, "" '                                                  no, report error to programmer
  1080.     END IF
  1081.  
  1082.     SL_sprite(handle).animation.cellfrom = cellfrom '                                                   set first cell in animation
  1083.     SL_sprite(handle).animation.cellto = cellto '                                                       set last cell in animation
  1084.     SL_sprite(handle).animation.cell = cellfrom '                                                       set current animation cell to first cell
  1085.     SL_sprite(handle).cell = cellfrom '                                                                 set current sprite cell to first cell
  1086.  
  1087.     IF SL_sprite(handle).animation.cellto < SL_sprite(handle).animation.cellfrom THEN '                 is cellto greater than cellfrom?
  1088.         SL_error "SL_CHANGE_ANIMATION_CELLS", 19, "" '                                                  no, report error to programmer
  1089.     END IF
  1090.  
  1091.     IF SL_sprite(handle).rotation.angle AND (NOT SL_sprite(handle).rotation.auto) THEN '                is this animation currently rotated but not automatic?
  1092.         SL_ROTATE_SPRITE handle, SL_sprite(handle).rotation.angle '                                     yes, this new cell will need manually rotated as well
  1093.     ELSE '                                                                                              no rotation, but still needs image updated
  1094.         _FREEIMAGE SL_sprite(handle).gfx.software '                                                     remove current software image from memory
  1095.         SL_sprite(handle).gfx.software = _COPYIMAGE(SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).software, 32) ' get new software image
  1096.         IF SL_sprite(handle).gfx.mask THEN '                                                            is there a mask with this image?
  1097.             _FREEIMAGE SL_sprite(handle).gfx.mask '                                                     yes, remove the software mask image from memory
  1098.             SL_sprite(handle).gfx.mask = _COPYIMAGE(SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).mask, 32) ' get new software mask image
  1099.         END IF
  1100.     END IF
  1101.  
  1102.  
  1103. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1104. SUB SL_CHANGE_ANIMATION_FRAMERATE (handle AS INTEGER, framerate AS INTEGER) '                                                                                             SL_CHANGE_ANIMATION_FRAMERATE
  1105.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1106.     ' declare global variables
  1107.  
  1108.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1109.     SHARED SL_global AS SL_GLOBAL '     common globals array
  1110.  
  1111.     ' perform error checks
  1112.  
  1113.     IF framerate < 1 OR framerate > SL_global.framerate THEN '                                          valid frame rate supplied?
  1114.         SL_error "SL_CHANGE_ANIMATION_FRAMERATE", 11, "" '                                              no, report error to programmer
  1115.     END IF
  1116.  
  1117.     SL_sprite(handle).animation.framerate = framerate '                                                 save sprite frame rate
  1118.     IF SL_global.framerate = framerate THEN '                                                           animation and global frame rates the same?
  1119.         SL_sprite(handle).animation.skip = 0 '                                                          yes, nothing needs to be done with frames
  1120.     ELSEIF framerate >= SL_global.framerate \ 2 THEN '                                                  no, sprite frame rate 1/2 or less of master frame rate?
  1121.         SL_sprite(handle).animation.skip = SL_global.framerate \ (SL_global.framerate - framerate) '    yes, calculate every frame to skip
  1122.     ELSE '                                                                                              no, sprite frame rate is greater than 1/2 of master frame rate
  1123.         SL_sprite(handle).animation.skip = SL_global.framerate \ framerate '                            calculate every frame to draw
  1124.     END IF
  1125.  
  1126.  
  1127. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1128. SUB SL_CHANGE_AUTOANIMATION (handle AS INTEGER, auto AS INTEGER) '                                                                                                              SL_CHANGE_AUTOANIMATION
  1129.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1130.  
  1131.     ' declare global variables
  1132.  
  1133.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1134.  
  1135.     ' perform error checks
  1136.  
  1137.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1138.         SL_error "SL_CHANGE_AUTOANIMATION", 1, "" '                                                     no, report error to programmer
  1139.     END IF
  1140.     IF auto < -1 OR auto > 0 THEN '                                                                     valid auto animation value?
  1141.         SL_error "SL_CHANGE_ANIMATION", 14, "" '                                                        no, report error to programmer
  1142.     END IF
  1143.  
  1144.     SL_sprite(handle).animation.auto = auto '                                     (SL_START & SL_STOP)  set auto-animation
  1145.  
  1146.  
  1147. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1148. SUB SL_SET_ANIMATION (handle AS INTEGER, cellfrom AS INTEGER, cellto AS INTEGER, mode AS INTEGER, framerate AS INTEGER, auto AS INTEGER) '                                             SL_SET_ANIMATION
  1149.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1150.  
  1151.     ' declare global variables
  1152.  
  1153.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1154.     SHARED SL_global AS SL_GLOBAL '     common globals array
  1155.  
  1156.     ' perform error checks
  1157.  
  1158.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1159.         SL_error "SL_SET_ANIMATION", 1, "" '                                                            no, report error to programmer
  1160.     END IF
  1161.     IF framerate < 1 OR framerate > SL_global.framerate THEN '                                          valid frame rate supplied?
  1162.         SL_error "SL_SET_ANIMATION", 11, "" '                                                           no, report error to programmer
  1163.     END IF
  1164.     IF mode < 0 OR mode > 2 THEN '                                                                      valid animation mode supplied?
  1165.         SL_error "SL_SET_ANIMATION", 12, "" '                                                           no, report error to programmer
  1166.     END IF
  1167.     IF cellfrom <> -1 THEN '                                                          (SL_CURRENTCELL)  is the current cell being requested for cellfrom?
  1168.         IF cellfrom < 1 OR (NOT SL_VALID_CELL(SL_sprite(handle).sheet, cellfrom)) THEN '                no, is this a valid cell request? <----------------------------- line need modified?   LOOK
  1169.             SL_error "SL_SET_ANIMATION", 13, "" '                                                       no, report error to rpogrammer
  1170.         END IF
  1171.     END IF
  1172.     IF cellto < 1 OR (NOT SL_VALID_CELL(SL_sprite(handle).sheet, cellto)) THEN '                        is this valid cell request?
  1173.         SL_error "SL_SET_ANIMATION", 13, "" '                                                           no, report error to programmer
  1174.     END IF
  1175.     IF auto < -1 OR auto > 0 THEN '                                                                     valid auto animation value?
  1176.         SL_error "SL_SET_ANIMATION", 14, "" '                                                           no, report error to programmer
  1177.     END IF
  1178.  
  1179.     IF cellfrom = -1 THEN '                                                           (SL_CURRENTCELL)  use current cell as start cell?
  1180.         SL_sprite(handle).animation.cellfrom = SL_sprite(handle).animation.cell '                       yes, set first cell as current cell
  1181.     ELSE '                                                                                              no
  1182.         SL_sprite(handle).animation.cell = cellfrom '                                                   set starting cell
  1183.         SL_sprite(handle).animation.cellfrom = cellfrom '                                               set first cell in animation
  1184.     END IF
  1185.     SL_sprite(handle).animation.cellto = cellto '                                                       set last cell in animation
  1186.  
  1187.     IF cellto <= cellfrom THEN '                                                                        is cellto greater than cellfrom?
  1188.         SL_error "SL_SET_ANIMATION", 19, "" '                                                           no, report error to programmer
  1189.     END IF
  1190.  
  1191.     SL_sprite(handle).animation.framerate = framerate '                                                 save sprite frame rate
  1192.     IF SL_global.framerate = framerate THEN '                                                           animation and global frame rates the same?
  1193.         SL_sprite(handle).animation.skip = 0 '                                                          yes, nothing needs to be done with frames
  1194.     ELSEIF framerate >= SL_global.framerate \ 2 THEN '                                                  no, sprite frame rate 1/2 or less of master frame rate?
  1195.         SL_sprite(handle).animation.skip = SL_global.framerate \ (SL_global.framerate - framerate) '    yes, calculate every frame to skip
  1196.     ELSE '                                                                                              no, sprite frame rate is greater than 1/2 of master frame rate
  1197.         SL_sprite(handle).animation.skip = SL_global.framerate \ framerate '                            calculate every frame to draw
  1198.     END IF
  1199.     SL_sprite(handle).animation.frame = 0 '                                                             reset skip frame counter
  1200.     SL_sprite(handle).animation.mode = mode '                (SL_FORWARD & SL_BACKWARD & SL_BACKFORTH)  set animation mode
  1201.     IF mode = 0 OR mode = 2 THEN '                                        (SL_FORWARD or SL_BACKFORTH)  forward or back and forth?
  1202.         SL_sprite(handle).animation.dir = 1 '                                                           yes, set animation direction forward
  1203.     ELSE '                                                                               (SL_BACKWARD)  no, backward
  1204.         SL_sprite(handle).animation.dir = -1 '                                                          set animation direction backward
  1205.     END IF
  1206.     SL_sprite(handle).animation.auto = auto '                                     (SL_START & SL_STOP)  set auto-animation
  1207.  
  1208.  
  1209. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1210. FUNCTION SL_GET_CELL (handle AS INTEGER) '                                                                                                                                                  SL_GET_CELL
  1211.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1212.  
  1213.     ' declare global variables
  1214.  
  1215.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1216.  
  1217.     ' perform error checks
  1218.  
  1219.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1220.         SL_error "SL_GET_CELL", 1, "" '                                                                 no, report error to programmer
  1221.     END IF
  1222.  
  1223.     SL_GET_CELL = SL_sprite(handle).animation.cell '                                                    return animation cell of this sprite < --------------------- animation or sprite cell?   LOOK
  1224.  
  1225.  
  1226. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1227. FUNCTION SL_VALID_CELL (sheet AS INTEGER, cell AS INTEGER) '                                                                                                                              SL_VALID_CELL
  1228.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1229.  
  1230.     ' declare global variables
  1231.  
  1232.     SHARED SL_sheet() AS SL_SHEET '    master sprite sheet array
  1233.  
  1234.     IF NOT SL_VALID_SHEET(sheet) THEN '                                                                 is this a valid sheet?
  1235.         SL_error "SL_VALID_CELL", 5, "" '                                                               no, report error to programmer
  1236.     END IF
  1237.  
  1238.     IF (cell < 1) OR (cell > UBOUND(SL_sheet, 2)) THEN '                                                is cell withing range of cells on sheet?
  1239.         SL_VALID_CELL = 0 '                                                                    (FALSE)  no, return false for invalid cell
  1240.     ELSE '                                                                                              yes, within total cells
  1241.         SL_VALID_CELL = -1 '                                                                    (TRUE)  return true for valid cell
  1242.     END IF
  1243.  
  1244.  
  1245. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1246. '                                                                       ----------==========                 ==========----------
  1247. '                                                                       ----------========== MOTION ROUTINES ==========----------
  1248. '                                                                       ----------==========                 ==========----------
  1249. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1250.  
  1251. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1252. SUB SL_REVERSE_MOTIONX (handle AS INTEGER) '                                                                                                                                         SL_REVERSE_MOTIONX
  1253.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1254.  
  1255.     ' declare global variables
  1256.  
  1257.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1258.  
  1259.     ' perform error checks
  1260.  
  1261.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1262.         SL_error "SL_REVERSE_MOTIONX", 1, "" '                                                          no, report error to programmer
  1263.     END IF
  1264.  
  1265.     SL_sprite(handle).x.dir = -SL_sprite(handle).x.dir '                                                reverse x motion direction
  1266.  
  1267.  
  1268. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1269. SUB SL_REVERSE_MOTIONY (handle AS INTEGER) '                                                                                                                                         SL_REVERSE_MOTIONY
  1270.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1271.  
  1272.     ' declare global variables
  1273.  
  1274.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1275.  
  1276.     ' perform error checks
  1277.  
  1278.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1279.         SL_error "SL_REVERSE_MOTIONY", 1, "" '                                                          no, report error to programmer
  1280.     END IF
  1281.  
  1282.     SL_sprite(handle).y.dir = -SL_sprite(handle).y.dir '                                                reverse y motion direction
  1283.  
  1284.  
  1285. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1286. FUNCTION SL_GET_MOTIONX (handle AS INTEGER) '                                                                                                                                            SL_GET_MOTIONX
  1287.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1288.  
  1289.     ' declare global variables
  1290.  
  1291.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1292.  
  1293.     ' perform error checks
  1294.  
  1295.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1296.         SL_error "SL_GET_MOTIONX", 1, "" '                                                              no, report error to programmer
  1297.     END IF
  1298.  
  1299.     SL_GET_MOTIONX = SL_sprite(handle).x.dir '                                                          return x motion direction
  1300.  
  1301.  
  1302. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1303. FUNCTION SL_GET_MOTIONY (handle AS INTEGER) '                                                                                                                                            SL_GET_MOTIONY
  1304.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1305.  
  1306.     ' declare global variables
  1307.  
  1308.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1309.  
  1310.     ' perform error checks
  1311.  
  1312.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1313.         SL_error "SL_GET_MOTIONY", 1, "" '                                                              no, report error to programmer
  1314.     END IF
  1315.  
  1316.     SL_GET_MOTIONY = SL_sprite(handle).y.dir '                                                          return y motion direction
  1317.  
  1318.  
  1319. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1320. SUB SL_SET_MOTIONX (handle AS INTEGER, xdir AS SINGLE) '                                                                                                                                 SL_SET_MOTIONX
  1321.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1322.     ' declare global variables
  1323.  
  1324.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1325.  
  1326.     ' perform error checks
  1327.  
  1328.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1329.         SL_error "SL_SET_MOTIONX", 1, "" '                                                              no, report error to programmer
  1330.     END IF
  1331.  
  1332.     SL_sprite(handle).x.dir = xdir '                                                                    set x motion direction
  1333.  
  1334.  
  1335. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1336. SUB SL_SET_MOTIONY (handle AS INTEGER, ydir AS SINGLE) '                                                                                                                                 SL_SET_MOTIONY
  1337.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1338.  
  1339.     ' declare global variables
  1340.  
  1341.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1342.  
  1343.     ' perform error checks
  1344.  
  1345.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1346.         SL_error "SL_SET_MOTIONY", 1, "" '                                                              no, report error to programmer
  1347.     END IF
  1348.  
  1349.     SL_sprite(handle).y.dir = ydir '                                                                    set y motion direction
  1350.  
  1351.  
  1352. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1353. SUB SL_UPDATE_MOTION (handle AS INTEGER) '                                                                                                                                             SL_UPDATE_MOTION
  1354.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1355.  
  1356.     ' declare global variables
  1357.  
  1358.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1359.  
  1360.     ' perform error checks
  1361.  
  1362.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1363.         SL_error "SL_UPDATE_MOTION", 1, "" '                                                            no, report error to programmer
  1364.     END IF
  1365.     IF SL_sprite(handle).motion.auto THEN '                                                             attempt to move sprite under automatic control?
  1366.         SL_error "SL_UPDATE_MOTION", 16, "" '                                                           yes, report error to programmer
  1367.     END IF
  1368.  
  1369.     SL_sprite(handle).x.real = SL_sprite(handle).x.real + SL_sprite(handle).x.dir '                     update x location
  1370.     SL_sprite(handle).y.real = SL_sprite(handle).y.real + SL_sprite(handle).y.dir '                     update y location
  1371.     SL_PUT_SPRITE SL_sprite(handle).x.real, SL_sprite(handle).y.real, handle '                          update sprite location
  1372.  
  1373.  
  1374. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1375. SUB SL_SET_MOTION (handle AS INTEGER, degrees AS INTEGER, speed AS SINGLE, auto AS INTEGER) '                                                                                            SL_SET_MOTION
  1376.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1377.  
  1378.     ' declare global variables
  1379.  
  1380.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1381.  
  1382.     ' perform error checks
  1383.  
  1384.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1385.         SL_error "SL_SET_MOTION", 1, "" '                                                               no, report error to programmer
  1386.     END IF
  1387.     IF auto < -1 OR auto > 0 THEN '                                               (SL_START & SL_STOP)  valid on/off switch supplied?
  1388.         SL_error "SL_SET_MOTION", 7, "" '                                                               no, report error to programmer
  1389.     END IF
  1390.  
  1391.     SL_sprite(handle).motion.speed = speed '                                                            set motion speed of sprite
  1392.     SL_CHANGE_MOTION_DIRECTION handle, SL_FIX_DEGREES(degrees) '                                        set motion angle of sprite
  1393.     SL_sprite(handle).motion.auto = auto '                                        (SL_START & SL_STOP)  set auto-motion of sprite
  1394.  
  1395.  
  1396. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1397. SUB SL_CHANGE_MOTION_DIRECTION (handle AS INTEGER, degrees AS INTEGER) '                                                                                                     SL_CHANGE_MOTION_DIRECTION
  1398.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1399.  
  1400.     ' declare global variables
  1401.  
  1402.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1403.  
  1404.     ' delcare local variables
  1405.  
  1406.     DIM degree AS INTEGER '             degree angle passed in
  1407.  
  1408.     ' perform error checks
  1409.  
  1410.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1411.         SL_error "SL_CHANGE_MOTION_DIRECTION", 1, "" '                                                  no, report error to programmer
  1412.     END IF
  1413.  
  1414.     degree = SL_FIX_DEGREES(degrees) '                                                                  get degree angle passed in
  1415.     SL_sprite(handle).motion.angle = degree '                                                           set motion degree angle
  1416.     SL_sprite(handle).x.dir = SIN(degree * .017453292) * SL_sprite(handle).motion.speed '               calculate x vector
  1417.     SL_sprite(handle).y.dir = -COS(degree * .017453292) * SL_sprite(handle).motion.speed '              calculate y vector
  1418.  
  1419.  
  1420. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1421. FUNCTION SL_GET_MOTION_DIRECTION (handle AS INTEGER) '                                                                                                                          SL_GET_MOTION_DIRECTION
  1422.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1423.  
  1424.     ' declare global variables
  1425.  
  1426.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1427.  
  1428.     ' perform error checks
  1429.  
  1430.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1431.         SL_error "SL_GET_MOTION_DIRECTION", 1, "" '                                                     no, report error to programmer
  1432.     END IF
  1433.  
  1434.     SL_GET_MOTION_DIRECTION = SL_sprite(handle).motion.angle '                                          return direction sprite currently set to
  1435.  
  1436.  
  1437. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1438. SUB SL_CHANGE_MOTION_SPEED (handle AS INTEGER, speed AS SINGLE) '                                                                                                                SL_CHANGE_MOTION_SPEED
  1439.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1440.  
  1441.     ' declare global variables
  1442.  
  1443.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1444.  
  1445.     ' perform error checks
  1446.  
  1447.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1448.         SL_error "SL_CHANGE_MOTION_SPEED", 1, "" '                                                      no, report error to programmer
  1449.     END IF
  1450.  
  1451.     SL_sprite(handle).motion.speed = speed '                                                            set sprite motion speed
  1452.     SL_sprite(handle).x.dir = SIN(SL_sprite(handle).motion.angle * .017453292) * speed '                calculate x vector
  1453.     SL_sprite(handle).y.dir = -COS(SL_sprite(handle).motion.angle * .017453292) * speed '               calculate y vector
  1454.  
  1455.  
  1456. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1457. FUNCTION SL_GET_MOTION_SPEED (handle AS INTEGER) '                                                                                                                                  SL_GET_MOTION_SPEED
  1458.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1459.  
  1460.     ' declare global variables
  1461.  
  1462.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1463.  
  1464.     ' perform error checks
  1465.  
  1466.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1467.         SL_error "SL_GET_MOTION_SPEED", 1, "" '                                                         no, report error to programmer
  1468.     END IF
  1469.  
  1470.     SL_GET_MOTION_SPEED = SL_sprite(handle).motion.speed '                                              return current sprite motion speed
  1471.  
  1472.  
  1473. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1474. SUB SL_CHANGE_AUTOMOTION (handle AS INTEGER, auto AS INTEGER) '                                                                                                                    SL_CHANGE_AUTOMOTION
  1475.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1476.  
  1477.     ' declare global variables
  1478.  
  1479.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1480.  
  1481.     ' perform error checks
  1482.  
  1483.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1484.         SL_error "SL_CHANGE_AUTOMOTION", 1, "" '                                                        no, report error to programmer
  1485.     END IF
  1486.     IF auto = -32767 THEN '                                                                 (SL_RESET)  reset auto motion?
  1487.         SL_sprite(handle).motion.auto = 0 '                                                  (SL_STOP)  yes, turn auto motion off
  1488.     ELSEIF auto < -1 OR auto > 0 THEN '                                           (SL_START & SL_STOP)  valid on/off switch supplied?
  1489.         SL_error "SL_CHANGE_AUTOMOTION", 7, "" '                                                        no, report error to programmer
  1490.     ELSE '                                                                                              yes
  1491.         SL_sprite(handle).motion.auto = auto '                                          (TRUE & FALSE)  set auto motion status
  1492.     END IF
  1493.  
  1494.  
  1495. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1496. FUNCTION SL_GET_AUTOMOTION (handle AS INTEGER) '                                                                                                                                      SL_GET_AUTOMOTION
  1497.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1498.  
  1499.     ' declare global variables
  1500.  
  1501.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1502.  
  1503.     ' perform error checks
  1504.  
  1505.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1506.         SL_error "SL_GET_AUTOMOTION", 1, "" '                                                           no, report error to programmer
  1507.     END IF
  1508.  
  1509.     SL_GET_AUTOMOTION = SL_sprite(handle).motion.auto '                                 (TRUE & FALSE)  return auto motion status
  1510.  
  1511.  
  1512. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1513. '                                                                      ----------==========                   ==========----------
  1514. '                                                                      ----------========== ROTATION ROUTINES ==========----------
  1515. '                                                                      ----------==========                   ==========----------
  1516. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1517.  
  1518. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1519. SUB SL_UPDATE_ROTATION (handle AS INTEGER) '                                                                                                                                         SL_UPDATE_ROTATION
  1520.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1521.  
  1522.     ' declare global variables
  1523.  
  1524.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1525.  
  1526.     ' perform error checks
  1527.  
  1528.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1529.         SL_error "SL_UPDATE_ROTATION", 1, "" '                                                          no, report error to programmer
  1530.     END IF
  1531.     IF SL_sprite(handle).rotation.auto THEN '                                                           attempt to rotate sprite under automatic control?
  1532.         SL_error "SL_UPDATE_ROTATION", 17, "" '                                                         yes, report error to programmer
  1533.     END IF
  1534.  
  1535.     SL_ROTATE_SPRITE handle, SL_sprite(handle).rotation.angle + SL_sprite(handle).rotation.speed '      rotate sprite to next degree angle
  1536.     SL_PUT_SPRITE SL_sprite(handle).x.real, SL_sprite(handle).y.real, handle '                          update sprite rotation
  1537.  
  1538.  
  1539.  
  1540. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1541. SUB SL_SET_ROTATION (handle AS INTEGER, degrees AS INTEGER, speed AS INTEGER, auto AS INTEGER) '                                                                                        SL_SET_ROTATION
  1542.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1543.  
  1544.     ' declare global variables
  1545.  
  1546.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1547.  
  1548.     ' perform error checks
  1549.  
  1550.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1551.         SL_error "SL_SET_ROTATION", 1, "" '                                                             no, report error to programmer
  1552.     END IF
  1553.     IF auto < -1 OR auto > 0 THEN '                                               (SL_START & SL_STOP)  valid on/off switch supplied?
  1554.         SL_error "SL_SET_ROTATION", 8, "" '                                                             no, report error to programmer
  1555.     END IF
  1556.     IF ABS(degrees) > 359 THEN '                                                                        degree requested between -359 and 359?
  1557.         SL_error "SL_SET_ROTATION", 9, "" '                                                             no, report error to programmer
  1558.     END IF
  1559.  
  1560.     SL_sprite(handle).rotation.speed = speed '                                                          set rotation speed
  1561.     SL_ROTATE_SPRITE handle, degrees '                                                                  set start angle
  1562.     SL_sprite(handle).rotation.auto = auto '                                                            set auto-rotation
  1563.  
  1564.  
  1565. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1566. SUB SL_CHANGE_AUTOROTATION (handle AS INTEGER, auto AS INTEGER) '                                                                                                                SL_CHANGE_AUTOROTATION
  1567.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1568.  
  1569.     ' declare global variables
  1570.  
  1571.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1572.  
  1573.     ' perform error checks
  1574.  
  1575.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1576.         SL_error "SL_CHANGE_AUTOROTATION", 1, "" '                                                      no, report error to programmer
  1577.     END IF
  1578.     IF auto = -32767 THEN '                                                                 (SL_RESET)  reset auto rotate?
  1579.         SL_sprite(handle).rotation.auto = 0 '                                                  (FALSE)  yes, turn auto rotation off
  1580.     ELSEIF auto < -1 OR auto > 0 THEN '                                           (SL_START & SL_STOP)  valid on/off switch supplied?
  1581.         SL_error "SL_CHANGE_AUTOROTATION", 8, "" '                                                      no, report error to programmer
  1582.     ELSE '                                                                                              yes
  1583.         SL_sprite(handle).rotation.auto = auto '                                        (TRUE & FALSE)  set auto rotation status
  1584.     END IF
  1585.  
  1586.  
  1587. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1588. FUNCTION SL_GET_AUTOROTATION (handle AS INTEGER) '                                                                                                                                  SL_GET_AUTOROTATION
  1589.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1590.  
  1591.     ' declare global variables
  1592.  
  1593.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1594.  
  1595.     ' perform error checks
  1596.  
  1597.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1598.         SL_error "SL_GET_AUTOROTATION", 1, "" '                                                         no, report error to programmer
  1599.     END IF
  1600.  
  1601.     SL_GET_AUTOROTATION = SL_sprite(handle).rotation.auto '                             (TRUE & FALSE)  return auto rotation status
  1602.  
  1603.  
  1604. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1605. SUB SL_CHANGE_ROTATION_SPEED (handle AS INTEGER, degrees AS INTEGER) '                                                                                                         SL_CHANGE_ROTATION_SPEED
  1606.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1607.  
  1608.     ' declare global variables
  1609.  
  1610.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1611.  
  1612.     ' perform error checks
  1613.  
  1614.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1615.         SL_error "SL_CHANGE_ROTATION_SPEED", 1, "" '                                                    no, report error to programmer
  1616.     END IF
  1617.     IF degrees = -32767 THEN '                                                              (SL_RESET)  reset requested?
  1618.         SL_sprite(handle).rotation.speed = 0 '                                               (SL_STOP)  turn auto spin off
  1619.     ELSEIF ABS(degrees) > 359 THEN '                                                                    degree requested between -359 and 359?
  1620.         SL_error "SL_CHANGE_ROTATION_SPEED", 9, "" '                                                    no, report error to programmer
  1621.     ELSE '                                                                                              yes
  1622.         SL_sprite(handle).rotation.speed = degrees '                                                    set sprite spin rate
  1623.     END IF
  1624.  
  1625.  
  1626. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1627. FUNCTION SL_GET_ROTATION_SPEED (handle AS INTEGER) '                                                                                                                              SL_GET_ROTATION_SPEED
  1628.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1629.  
  1630.     ' declare global variables
  1631.  
  1632.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1633.  
  1634.     ' perform error checks
  1635.  
  1636.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1637.         SL_error "SL_GET_ROTATION_SPEED", 1, "" '                                                       no, report error to programmer
  1638.     END IF
  1639.  
  1640.     SL_GET_ROTATION_SPEED = SL_sprite(handle).rotation.speed '                                          return current sprite spin rate
  1641.  
  1642.  
  1643. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1644. SUB SL_ROTATE_SPRITE (handle AS INTEGER, degrees AS INTEGER) '                                                                                                                         SL_ROTATE_SPRITE
  1645.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1646.  
  1647.     ' declare global variables
  1648.  
  1649.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  1650.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1651.     SHARED SL_angle() AS SL_ANGLE '     master rotation array
  1652.  
  1653.     ' declare local variables
  1654.  
  1655.     DIM sw AS INTEGER '                 width of sprite to be drawn
  1656.     DIM sh AS INTEGER '                 height of sprite to be drawn
  1657.     DIM rw AS INTEGER '                 precalculated rotated sprite width
  1658.     DIM rh AS INTEGER '                 precalculated rotated sprite height
  1659.     DIM px0 AS INTEGER '                precalculated triangular coordinates
  1660.     DIM px1 AS INTEGER
  1661.     DIM px2 AS INTEGER
  1662.     DIM px3 AS INTEGER
  1663.     DIM py0 AS INTEGER
  1664.     DIM py1 AS INTEGER
  1665.     DIM py2 AS INTEGER
  1666.     DIM py3 AS INTEGER
  1667.     DIM image AS LONG '                 software sprite image
  1668.     DIM mask AS LONG '                  software sprite image mask
  1669.     DIM degree AS INTEGER '             angle of rotation
  1670.  
  1671.     ' perform error checks
  1672.  
  1673.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1674.         SL_error "SL_ROTATE_SPRITE", 1, "" '                                                            no, report error to programmer
  1675.     END IF
  1676.  
  1677.     ' check if rotation necessary
  1678.  
  1679.     degree = SL_FIX_DEGREES(degrees) '                                                                  correct degree angle if needed
  1680.  
  1681.     ' get default images and dimensions from sprite sheet
  1682.  
  1683.     image = SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).software '                        get image from sprite sheet
  1684.     mask = SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).mask '                             get mask from sprite sheet
  1685.     sw = SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).swidth '                             get default sprite width from sprite sheet
  1686.     sh = SL_sheet(SL_sprite(handle).sheet, SL_sprite(handle).cell).sheight '                            get default sprite height from sprite sheet
  1687.  
  1688.     ' free existing images from memory
  1689.  
  1690.     _FREEIMAGE SL_sprite(handle).gfx.software '                                                         free software sprite image
  1691.     IF SL_sprite(handle).gfx.mask THEN _FREEIMAGE SL_sprite(handle).gfx.mask '                          free software mask image
  1692.  
  1693.     ' remove rotation (reset) if requested
  1694.  
  1695.     IF degrees = -32767 OR degree = 0 THEN '                                                (SL_RESET)  reset sprite rotation?
  1696.         SL_sprite(handle).rotation.angle = 0 '                                                          yes, reset rotation angle
  1697.         SL_sprite(handle).swidth = sw '                                                                 save sprite's width
  1698.         SL_sprite(handle).sheight = sh '                                                                save prite's height
  1699.         SL_sprite(handle).gfx.software = _COPYIMAGE(image, 32) '                                        copy software image from sprite sheet
  1700.         IF SL_sprite(handle).transparency THEN '                                                        does this sprite have a mask?
  1701.             SL_sprite(handle).gfx.mask = _COPYIMAGE(mask, 32) '                                         yes, copy software mask from sprite sheet
  1702.         END IF
  1703.         EXIT SUB '                                                                                      no rotation needed, leave subroutine
  1704.     END IF
  1705.  
  1706.     ' rotate sprite
  1707.  
  1708.     rw = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).rwidth '                     get precalculated rotated sprite width
  1709.     rh = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).rheight '                    get precalculated rotated sprite height
  1710.     px0 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).px0 '                       get precalculated triangular coordinates
  1711.     px1 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).px1
  1712.     px2 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).px2
  1713.     px3 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).px3
  1714.     py0 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).py0
  1715.     py1 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).py1
  1716.     py2 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).py2
  1717.     py3 = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, degree).py3
  1718.  
  1719.     SL_sprite(handle).gfx.software = _NEWIMAGE(rw, rh, 32) '                                            create new software sprite image
  1720.     _MAPTRIANGLE (0, 0)-(0, sh - 1)-(sw - 1, sh - 1), image TO(px0, py0)-(px1, py1)-(px2, py2), SL_sprite(handle).gfx.software ' map rotated sprite onto image
  1721.     _MAPTRIANGLE (0, 0)-(sw - 1, 0)-(sw - 1, sh - 1), image TO(px0, py0)-(px3, py3)-(px2, py2), SL_sprite(handle).gfx.software
  1722.     IF SL_sprite(handle).transparency THEN '                                                            does this sprite have a mask?
  1723.         SL_sprite(handle).gfx.mask = _NEWIMAGE(rw, rh, 32) '                                            yes, create new software mask image
  1724.         _MAPTRIANGLE (0, 0)-(0, sh - 1)-(sw - 1, sh - 1), mask TO(px0, py0)-(px1, py1)-(px2, py2), SL_sprite(handle).gfx.mask '  map rotated mask onto image
  1725.         _MAPTRIANGLE (0, 0)-(sw - 1, 0)-(sw - 1, sh - 1), mask TO(px0, py0)-(px3, py3)-(px2, py2), SL_sprite(handle).gfx.mask
  1726.     END IF
  1727.     SL_sprite(handle).swidth = rw '                                                                     save sprite's rotated width
  1728.     SL_sprite(handle).sheight = rh '                                                                    save sprite's rotated height
  1729.     SL_sprite(handle).rotation.angle = degree '                                                         save sprite's degree of rotation
  1730.  
  1731.  
  1732.  
  1733. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1734. FUNCTION SL_GET_ROTATION_ANGLE (handle AS INTEGER) '                                                                                                                              SL_GET_ROTATION_ANGLE
  1735.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1736.  
  1737.     ' declare global variables
  1738.  
  1739.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1740.  
  1741.     ' perform error checks
  1742.  
  1743.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1744.         SL_error "SL_GET_ROTATION_ANGLE", 1, "" '                                                       no, report error to programmer
  1745.     END IF
  1746.  
  1747.     SL_GET_ROTATION_ANGLE = SL_sprite(handle).rotation.angle '                                          return current angle of rotation
  1748.  
  1749.  
  1750. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1751. FUNCTION SL_FIX_DEGREES (degrees AS INTEGER) '                                                                                                                                           SL_FIX_DEGREES
  1752.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1753.  
  1754.     ' Credits: this function uses code contriibuted by codeguy
  1755.     '          https://www.qb64.org/forum/index.php?topic=537.15
  1756.  
  1757.     'declare local variables
  1758.  
  1759.     DIM degree AS INTEGER '             degree angle passed in
  1760.  
  1761.     ' set local variables
  1762.  
  1763.     degree = degrees MOD 360 '                                                                          get -359 to 359
  1764.     IF degree < 0 THEN '                                                                                need to make positive?
  1765.         SL_FIX_DEGREES = degree + 360 '                                                                 yes, correct value and return degree angle
  1766.     ELSE
  1767.         SL_FIX_DEGREES = degree '                                                                       no correction needed, return degree angle
  1768.     END IF
  1769.  
  1770.  
  1771.  
  1772. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1773. '                                                                      ----------==========                   ==========----------
  1774. '                                                                      ----------========== LOCATION ROUTINES ==========----------
  1775. '                                                                      ----------==========                   ==========----------
  1776. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  1777.  
  1778.  
  1779. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1780. FUNCTION SL_GET_REALX (handle AS INTEGER) '                                                                                                                                                SL_GET_REALX
  1781.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1782.  
  1783.     ' declare global variables
  1784.  
  1785.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1786.  
  1787.     ' perform error checks
  1788.  
  1789.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1790.         SL_error "SL_GET_REALX", 1, "" '                                                                no, report error to programmer
  1791.     END IF
  1792.  
  1793.     SL_GET_REALX = SL_sprite(handle).x.real '                                                           return real number center point x
  1794.  
  1795.  
  1796. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1797. FUNCTION SL_GET_REALY (handle AS INTEGER) '                                                                                                                                                SL_GET_REALY
  1798.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1799.  
  1800.     ' declare global variables
  1801.  
  1802.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1803.  
  1804.     ' perform error checks
  1805.  
  1806.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1807.         SL_error "SL_GET_REALY", 1, "" '                                                                no, report error to programmer
  1808.     END IF
  1809.  
  1810.     SL_GET_REALY = SL_sprite(handle).y.real '                                                           return real number center point y
  1811.  
  1812.  
  1813. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1814. FUNCTION SL_GET_INTX (handle AS INTEGER) '                                                                                                                                                  SL_GET_INTX
  1815.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1816.  
  1817.     ' declare global variables
  1818.  
  1819.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1820.  
  1821.     ' perform error checks
  1822.  
  1823.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1824.         SL_error "SL_GET_INTX", 1, "" '                                                                 no, report error to programmer
  1825.     END IF
  1826.  
  1827.     SL_GET_INTX = SL_sprite(handle).x.int '                                                             return integer number center point x
  1828.  
  1829.  
  1830. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1831. FUNCTION SL_GET_INTY (handle AS INTEGER) '                                                                                                                                                  SL_GET_INTY
  1832.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1833.  
  1834.     ' declare global variables
  1835.  
  1836.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1837.  
  1838.     ' perform error checks
  1839.  
  1840.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1841.         SL_error "SL_GET_INTY", 1, "" '                                                                 no, report error to programmer
  1842.     END IF
  1843.  
  1844.     SL_GET_INTY = SL_sprite(handle).y.int '                                                             return integer number center point x
  1845.  
  1846.  
  1847. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1848. FUNCTION SL_GET_ACTUALX (handle AS INTEGER) '                                                                                                                                            SL_GET_ACTUALX
  1849.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1850.  
  1851.     ' declare global variables
  1852.  
  1853.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1854.  
  1855.     ' perform error checks
  1856.  
  1857.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1858.         SL_error "SL_GET_ACTUALX", 1, "" '                                                              no, report error to programmer
  1859.     END IF
  1860.  
  1861.     SL_GET_ACTUALX = SL_sprite(handle).x.actual '                                                       return integer number upper left point x
  1862.  
  1863.  
  1864. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1865. FUNCTION SL_GET_ACTUALY (handle AS INTEGER) '                                                                                                                                            SL_GET_ACTUALY
  1866.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1867.  
  1868.     ' declare global variables
  1869.  
  1870.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1871.  
  1872.     ' perform error checks
  1873.  
  1874.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1875.         SL_error "SL_GET_ACTUALY", 1, "" '                                                              no, report error to programmer
  1876.     END IF
  1877.  
  1878.     SL_GET_ACTUALY = SL_sprite(handle).y.actual '                                                       return integer number upper left point y
  1879.  
  1880.  
  1881. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1882. FUNCTION SL_GET_DISTANCE_POINT_TO_POINT (x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER) '                                                                   SL_GET_DISTANCE_POINT_TO_POINT
  1883.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1884.  
  1885.     'declare local variables
  1886.  
  1887.     DIM a AS INTEGER '                  side a of triangle
  1888.     DIM b AS INTEGER '                  side b of triangle
  1889.  
  1890.     'solve for c (hypotenuse)
  1891.  
  1892.     a = x1 - x2 '                                                                                       get length of side a
  1893.     b = y1 = y2 '                                                                                       get length of side b
  1894.  
  1895.     SL_GET_DISTANCE_POINT_TO_POINT = INT(SQR(a * a + b * b)) '                                          return length of side c
  1896.  
  1897.  
  1898. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1899. FUNCTION SL_GET_DISTANCE_TO_SPRITE (handle1 AS INTEGER, handle2 AS INTEGER) '                                                                                                 SL_GET_DISTANCE_TO_SPRITE
  1900.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1901.  
  1902.     ' declare global variables
  1903.  
  1904.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1905.  
  1906.     'perform error checks
  1907.  
  1908.     IF (NOT SL_VALID_SPRITE(handle1)) OR (NOT SL_VALID_SPRITE(handle2)) THEN '                          are these valid sprites?
  1909.         SL_error "SL_GET_DISTANCE_TO_SPRITE", 1, "" '                                                   no, report error to programmer
  1910.     END IF
  1911.  
  1912.     SL_GET_DISTANCE_TO_SPRITE = SL_GET_DISTANCE_POINT_TO_POINT(SL_sprite(handle1).x.int, SL_sprite(handle1).y.int, _
  1913.                                                                SL_sprite(handle2).x.int, SL_sprite(handle2).y.int) '  return distance to sprite 2
  1914.  
  1915.  
  1916. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1917. FUNCTION SL_GET_DISTANCE_TO_POINT (handle AS INTEGER, x AS INTEGER, y AS INTEGER) '                                                                                            SL_GET_DISTANCE_TO_POINT
  1918.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1919.  
  1920.     ' declare global variables
  1921.  
  1922.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1923.  
  1924.     'perform error checks
  1925.  
  1926.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  1927.         SL_error "SL_GET_DISTANCE_TO_POINT", 1, "" '                                                    no, report error to programmer
  1928.     END IF
  1929.  
  1930.     SL_GET_DISTANCE_TO_POINT = SL_GET_DISTANCE_POINT_TO_POINT(SL_sprite(handle).x.int, SL_sprite(handle).y.int, x, y) ' return distance to point
  1931.  
  1932.  
  1933. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1934. FUNCTION SL_GET_ANGLE_POINT_TO_POINT (x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER) '                                                                         SL_GET_ANGLE_POINT_TO_POINT
  1935.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1936.  
  1937.     'declare local variables
  1938.  
  1939.     DIM angle AS INTEGER '              angle from first x,y location to second x,y location
  1940.  
  1941.     IF y1 = y2 THEN '                                                                                   both y values same?
  1942.         IF x1 = x2 THEN '                                                                               yes, both x values same?
  1943.             EXIT FUNCTION '                                                                             yes, there is no angle (0), leave
  1944.         END IF
  1945.         IF x2 > x1 THEN '                                                                               is second x to the right of first x?
  1946.             SL_GET_ANGLE_POINT_TO_POINT = 90 '                                                          yes, the angle must be 90 degrees
  1947.         ELSE '                                                                                          no, second x is to the left of first x
  1948.             SL_GET_ANGLE_POINT_TO_POINT = 270 '                                                         the angle must be 270 degrees
  1949.         END IF
  1950.         EXIT FUNCTION '                                                                                 leave function, angle computed
  1951.     END IF
  1952.     IF x1 = x2 THEN '                                                                                   both x values same?
  1953.         IF y2 > y1 THEN '                                                                               yes, is second y lower than first y?
  1954.             SL_GET_ANGLE_POINT_TO_POINT = 180 '                                                         yes, the angle must be 180
  1955.         END IF
  1956.         EXIT FUNCTION '                                                                                 leave function, angle computed (angle is 0 if no calculation done)
  1957.     END IF
  1958.     angle = ATN((x2 - x1) / (y2 - y1)) * -57.2957795131 '                                               calculate initial angle
  1959.     IF y2 < y1 THEN '                                                                                   is second y higher than first y?
  1960.         IF x2 > x1 THEN '                                                                               yes, is second x to right of first x?
  1961.             SL_GET_ANGLE_POINT_TO_POINT = angle '                                                       yes, angle needs no adjustment
  1962.         ELSE '                                                                                          no, second x is to left of first x
  1963.             SL_GET_ANGLE_POINT_TO_POINT = angle + 360 '                                                 adjust angle accordingly
  1964.         END IF
  1965.     ELSE '                                                                                              no, second y is lower than first y
  1966.         SL_GET_ANGLE_POINT_TO_POINT = angle + 180 '                                                     adjust angle accordingly
  1967.     END IF
  1968.  
  1969.  
  1970. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1971. FUNCTION SL_GET_ANGLE_TO_SPRITE (handle1 AS INTEGER, handle2 AS INTEGER) '                                                                                                       SL_GET_ANGLE_TO_SPRITE
  1972.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1973.  
  1974.     ' declare global variables
  1975.  
  1976.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1977.  
  1978.     'perform error checks
  1979.  
  1980.     IF (NOT SL_VALID_SPRITE(handle1)) OR (NOT SL_VALID_SPRITE(handle2)) THEN '                          are these valid sprites?
  1981.         SL_error "SL_GET_ANGLE_TO_SPRITE", 1, "" '                                                      no, report error to programmer
  1982.     END IF
  1983.  
  1984.     SL_GET_ANGLE_TO_SPRITE = SL_GET_ANGLE_POINT_TO_POINT(SL_sprite(handle1).x.int, SL_sprite(handle1).y.int, _
  1985.                                                          SL_sprite(handle2).x.int, SL_sprite(handle2).y.int) ' return angle to sprite 2
  1986.  
  1987.  
  1988. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1989. FUNCTION SL_GET_ANGLE_FROM_SPRITE (handle1 AS INTEGER, handle2 AS INTEGER) '                                                                                                   SL_GET_ANGLE_FROM_SPRITE
  1990.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  1991.  
  1992.     ' declare global variables
  1993.  
  1994.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  1995.  
  1996.     'perform error checks
  1997.  
  1998.     IF (NOT SL_VALID_SPRITE(handle1)) OR (NOT SL_VALID_SPRITE(handle2)) THEN '                          are these valid sprites?
  1999.         SL_error "SL_GET_ANGLE_FROM_SPRITE", 1, "" '                                                    no, report error to programmer
  2000.     END IF
  2001.  
  2002.     SL_GET_ANGLE_FROM_SPRITE = SL_GET_ANGLE_POINT_TO_POINT(SL_sprite(handle2).x.int, SL_sprite(handle2).y.int, _
  2003.                                                            SL_sprite(handle1).x.int, SL_sprite(handle1).y.int) '  return angle from sprite 2
  2004.  
  2005.  
  2006. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2007. FUNCTION SL_GET_ANGLE_TO_POINT (handle AS INTEGER, x AS INTEGER, y AS INTEGER) '                                                                                                  SL_GET_ANGLE_TO_POINT
  2008.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2009.  
  2010.     ' declare global variables
  2011.  
  2012.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2013.  
  2014.     'perform error checks
  2015.  
  2016.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2017.         SL_error "SL_GET_ANGLE_TO_POINT", 1, "" '                                                       no, report error to programmer
  2018.     END IF
  2019.  
  2020.     SL_GET_ANGLE_TO_POINT = SL_GET_ANGLE_POINT_TO_POINT(SL_sprite(handle).x.int, SL_sprite(handle).y.int, x, y) ' return angle to point x,y
  2021.  
  2022.  
  2023. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2024. FUNCTION SL_GET_ANGLE_FROM_POINT (handle AS INTEGER, x AS INTEGER, y AS INTEGER) '                                                                                              SL_GET_ANGLE_FROM_POINT
  2025.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2026.  
  2027.     ' declare global variables
  2028.  
  2029.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2030.  
  2031.     'perform error checks
  2032.  
  2033.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2034.         SL_error "SL_GET_ANGLE_FROM_POINT", 1, "" '                                                     no, report error to programmer
  2035.     END IF
  2036.  
  2037.     SL_GET_ANGLE_FROM_POINT = SL_GET_ANGLE_POINT_TO_POINT(x, y, SL_sprite(handle).x.int, SL_sprite(handle).y.int) 'return angle from point x,y
  2038.  
  2039.  
  2040. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2041. '                                                                       ----------==========                 ==========----------
  2042. '                                                                       ----------========== SPRITE ROUTINES ==========----------
  2043. '                                                                       ----------==========                 ==========----------
  2044. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2045.  
  2046. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2047. SUB SL_SET_SPRITE_VISIBLE (handle AS INTEGER, visible AS INTEGER) '                                                                                                               SL_SET_SPRITE_VISIBLE
  2048.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2049.  
  2050.     ' declare global variables
  2051.  
  2052.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2053.  
  2054.     ' perform error checks
  2055.  
  2056.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2057.         SL_error "SL_SET_SPRITE_VISIBLE", 1, "" '                                                       no, report error to programmer
  2058.     END IF
  2059.     IF (visible < -1) OR (visible > 0) THEN '                                      (SL_SHOW & SL_HIDE)  valid visible behavior requested?
  2060.         SL_error "SL_SET_SPRITE_VISIBLE", 20, "" '                                                      no, report error to programmer
  2061.     END IF
  2062.  
  2063.     SL_sprite(handle).visible = visible '                                          (SL_SHOW & SL_HIDE)  set visible mode
  2064.  
  2065.  
  2066. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2067. FUNCTION SL_COPY_SPRITE (handle AS INTEGER) '                                                                                                                                            SL_COPY_SPRITE
  2068.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2069.  
  2070.     ' declare global variables
  2071.  
  2072.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2073.  
  2074.     ' declare local variables
  2075.  
  2076.     DIM newhandle AS INTEGER '          handle of copied sprite
  2077.  
  2078.     ' perform error checks
  2079.  
  2080.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2081.         SL_error "SL_COPY_SPRITE", 1, "" '                                                              no, report error to programmer
  2082.     END IF
  2083.  
  2084.     newhandle = 0 '                                                                                     initialize new handle counter
  2085.  
  2086.     ' increase sprite array's size if needed
  2087.  
  2088.     DO '                                                                                                look for next available handle
  2089.         newhandle = newhandle + 1 '                                                                     increment to next handle value
  2090.     LOOP UNTIL (NOT SL_sprite(newhandle).inuse) OR newhandle = UBOUND(SL_sprite) '                      stop looking when valid handle found
  2091.     IF SL_sprite(newhandle).inuse THEN '                                                                is the last array element in use?
  2092.         newhandle = newhandle + 1 '                                                                     yes, increment to next handle value
  2093.         REDIM _PRESERVE SL_sprite(newhandle) AS SL_SPRITE '                                             increase the size of the sprite array
  2094.     END IF
  2095.  
  2096.     ' copy new sprite
  2097.  
  2098.     SL_sprite(newhandle) = SL_sprite(handle) '                                                          copy entire sprite contents
  2099.     SL_sprite(newhandle).gfx.hardware = _COPYIMAGE(SL_sprite(handle).gfx.hardware, 33) '                create an actual copy of the hardware sprite
  2100.     SL_sprite(newhandle).gfx.software = _COPYIMAGE(SL_sprite(handle).gfx.software, 32) '                create an actual copy of the software image
  2101.     IF SL_sprite(handle).gfx.mask THEN '                                                                does the original contain a mask image?
  2102.         SL_sprite(newhandle).gfx.mask = _COPYIMAGE(SL_sprite(handle).gfx.mask, 32) '                    yes, create an actual copy of the software mask image
  2103.     END IF
  2104.  
  2105.     SL_COPY_SPRITE = newhandle '                                                                        return new sprite's handle pointer
  2106.  
  2107.  
  2108. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2109. SUB SL_STAMP_SPRITE (layer AS INTEGER, x AS INTEGER, y AS INTEGER, sheet AS INTEGER, cell AS INTEGER, degrees AS INTEGER, flip AS INTEGER, zoom AS INTEGER) '                           SL_STAMP_SPRITE
  2110.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2111.  
  2112.     ' declare global variables
  2113.  
  2114.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  2115.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2116.  
  2117.     ' declare local variables
  2118.  
  2119.     DIM tempsprite AS LONG '            temporary sprite to stamp
  2120.  
  2121.     ' perform error checks
  2122.  
  2123.     IF NOT SL_VALID_SHEET(sheet) THEN '                                                                 is this a valid sheet?
  2124.         SL_error "SL_STAMP_SPRITE", 5, "" '                                                             no, report error to programmer
  2125.     END IF
  2126.     IF NOT SL_VALID_CELL(sheet, cell) THEN '                                                            valid cell?
  2127.         SL_error "SL_STAMP_SPRITE", 13, "" '                                                            no, report error to programmer
  2128.     END IF
  2129.     IF flip < 0 OR flip > 3 THEN '                                                                      valid flip behavior requested?
  2130.         SL_error "SL_STAMP_SPRITE", 3, "" '                                                             no, report error to programmer
  2131.     END IF
  2132.     IF zoom < 1 THEN '                                                                                  valid zoom level requested?
  2133.         SL_error "SL_STAMP_SPRITE", 4, "" '                                                             no, report error to programmer
  2134.     END IF
  2135.     IF NOT SL_VALID_LAYER(layer) THEN '                                                                 valid layer?
  2136.         SL_error "SL_STAMP_SPRITE", 25, "" '                                                            no, report error to programmer
  2137.     END IF
  2138.  
  2139.     tempsprite = SL_NEW_SPRITE(layer, sheet, cell, 0, 0) '                                              create new temporary software sprite
  2140.     SL_sprite(tempsprite).rotation.speed = SL_FIX_DEGREES(degrees) '                                    set speed of rotation
  2141.     SL_sprite(tempsprite).flip = flip '                                                                 set flipping behavior
  2142.     SL_sprite(tempsprite).zoom = zoom '                                                                 set zoom level
  2143.     SL_PUT_SPRITE x, y, tempsprite '                                                                    place sprite on current destination
  2144.     SL_FREE_SPRITE tempsprite '                                                                         temporary sprite no longer needed
  2145.  
  2146.  
  2147.  
  2148. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2149. SUB SL_SET_SOFTWARE (handle AS INTEGER, restores AS INTEGER) '                                                                                                                          SL_SET_SOFTWARE
  2150.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2151.  
  2152.     ' declare global variables
  2153.  
  2154.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2155.  
  2156.     'perform error checks
  2157.  
  2158.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2159.         SL_error "SL_SET_SOFTWARE", 1, "" '                                                             no, report error to programmer
  2160.     END IF
  2161.     IF restores < -1 OR restores > 0 THEN '                                                             valid background restoration behavior requested?
  2162.         SL_error "SL_SET_SOFTWARE", 2, "" '                                                             no, report error to programmer
  2163.     END IF
  2164.  
  2165.     SL_sprite(handle).software = -1 '                                                    (SL_SOFTWARE)  set sprite to software mode
  2166.     SL_sprite(handle).restore = restores '                                       (SL_SAVE & SL_NOSAVE)  set background saving behavior
  2167.  
  2168.  
  2169. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2170. SUB SL_SET_HARDWARE (handle AS INTEGER) '                                                                                                                                               SL_SET_HARDWARE
  2171.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2172.  
  2173.     ' declare global variables
  2174.  
  2175.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2176.  
  2177.     'perform error checks
  2178.  
  2179.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2180.         SL_error "SL_SET_HARDWARE", 1, "" '                                                             no, report error to programmer
  2181.     END IF
  2182.  
  2183.     SL_sprite(handle).software = 0 '                                                     (SL_HARDWARE)  set sprite to hardware mode
  2184.  
  2185.  
  2186. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2187. SUB SL_SET_ZOOM (handle AS INTEGER, zoom AS INTEGER) '                                                                                                                                      SL_SET_ZOOM
  2188.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2189.  
  2190.     ' declare global variables
  2191.  
  2192.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2193.  
  2194.     ' perform error checks
  2195.  
  2196.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2197.         SL_error "SL_SET_ZOOM", 1, "" '                                                                 no, report error to programmer
  2198.     END IF
  2199.     IF zoom = -32767 THEN '                                                                 (SL_RESET)  reset zoom level?
  2200.         SL_sprite(handle).zoom = 100 '                                                                  yes, reset level to normal
  2201.     ELSEIF zoom < 1 THEN '                                                                              valid zoom level requested?
  2202.         SL_error "SL_SET_ZOOM", 4, "" '                                                                 no, report error to programmer
  2203.     ELSE '                                                                                              yes
  2204.         SL_sprite(handle).zoom = zoom '                                                                 set zoom level
  2205.     END IF
  2206.  
  2207.  
  2208. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2209. SUB SL_FLIP_SPRITE (handle AS INTEGER, flip AS INTEGER) '                                                                                                                                SL_FLIP_SPRITE
  2210.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2211.  
  2212.     ' declare global variables
  2213.  
  2214.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2215.  
  2216.     ' perform error checks
  2217.  
  2218.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2219.         SL_error "SL_FLIP_SPRITE", 1, "" '                                                              no, report error to programmer
  2220.     END IF
  2221.     IF flip = -32767 THEN '                                                                 (SL_RESET)  reset flipping behavior?
  2222.         SL_sprite(handle).flip = 0 '                                                       (SL_NOFLIP)  yes, reset flip value
  2223.     ELSEIF flip < 0 OR flip > 3 THEN '                                                                  valid flip behavior requested?
  2224.         SL_error "SL_FLIP_SPRITE", 3, "" '                                                              no, report error to programmer
  2225.     ELSE '                                                                                              yes
  2226.         SL_sprite(handle).flip = flip '           (SL_NOFLIP, SL_HORIZONTAL, SL_VERTICAL, SL_FLIPBOTH)  set flipping behavior
  2227.     END IF
  2228.  
  2229.  
  2230. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2231. SUB SL_PUT_SPRITE (x AS SINGLE, y AS SINGLE, handle AS INTEGER) '                                                                                                                         SL_PUT_SPRITE
  2232.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2233.  
  2234.     ' declare global variables
  2235.  
  2236.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2237.     SHARED SL_angle() AS SL_ANGLE '     master rotation array
  2238.  
  2239.     ' declare local variables
  2240.  
  2241.     DIM xa AS INTEGER '                 actual x location of sprite on screen
  2242.     DIM ya AS INTEGER '                 actual y location of sprite on screen
  2243.     DIM sw AS INTEGER '                 width of sprite to be drawn
  2244.     DIM sh AS INTEGER '                 height of sprite to be drawn
  2245.     DIM rw AS INTEGER '                 precalculated rotated sprite width
  2246.     DIM rh AS INTEGER '                 precalculated rotated sprite height
  2247.     DIM px0 AS INTEGER '                precalculated triangular coordinates
  2248.     DIM px1 AS INTEGER
  2249.     DIM px2 AS INTEGER
  2250.     DIM px3 AS INTEGER
  2251.     DIM py0 AS INTEGER
  2252.     DIM py1 AS INTEGER
  2253.     DIM py2 AS INTEGER
  2254.     DIM py3 AS INTEGER
  2255.     DIM image AS LONG '                 software sprite image
  2256.     DIM mask AS LONG '                  software sprite image mask
  2257.     DIM sprite AS LONG '                hardware sprite image
  2258.     DIM odest AS LONG '                 original destination layer
  2259.     DIM osource AS LONG '               original source layer
  2260.     DIM zoomfactor AS SINGLE '          zoom multiplication factor
  2261.     ' perform error checks
  2262.  
  2263.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2264.         SL_error "SL_PUT_SPRITE", 1, "" '                                                               no, report error to programmer
  2265.     END IF
  2266.  
  2267.     'local variable setup
  2268.  
  2269.     'odest = _DEST '                                                                                     save original destination
  2270.     'osource = _SOURCE '                                                                                 save original source
  2271.     odest = SL_GET_DESTINATION_LAYER
  2272.     osource = SL_GET_SOURCE_LAYER
  2273.  
  2274.     SL_sprite(handle).x.real = x '                                                            (SINGLE)  save requested x center location
  2275.     SL_sprite(handle).y.real = y '                                                            (SINGLE)  save requested y center location
  2276.     SL_sprite(handle).x.int = INT(x) '                                                       (INTEGER)  save screen x center location
  2277.     SL_sprite(handle).y.int = INT(y) '                                                       (INTEGER)  save screen y center location
  2278.     sw = SL_sprite(handle).swidth '                                                                     get current sprite width
  2279.     sh = SL_sprite(handle).sheight '                                                                    get current sprite height
  2280.  
  2281.     'update hardware image
  2282.  
  2283.     _FREEIMAGE SL_sprite(handle).gfx.hardware '                                                         free previous hardware sprite image
  2284.     SL_sprite(handle).gfx.hardware = _COPYIMAGE(SL_sprite(handle).gfx.software, 33) '                   create new hardware sprite of image
  2285.  
  2286.     IF SL_sprite(handle).restore THEN '                                                                 is sprite holding a background image?
  2287.         IF SL_sprite(handle).gfx.back THEN '                                                            yes, has a background image been saved yet?
  2288.             SL_SET_DESTINATION_LAYER SL_sprite(handle).layer '                                          yes, set destination layer
  2289.             _PUTIMAGE (SL_sprite(handle).x.back, SL_sprite(handle).y.back), SL_sprite(handle).gfx.back 'replace background with image
  2290.             _FREEIMAGE SL_sprite(handle).gfx.back '                                                     free hardware background image
  2291.         END IF
  2292.         IF NOT SL_sprite(handle).software THEN '                                                        was the sprite type changed?
  2293.             SL_sprite(handle).restore = 0 '                                                (SL_NOSAVE)  yes, stop saving background
  2294.         END IF
  2295.     END IF
  2296.  
  2297.     'adjust zoom level if needed
  2298.  
  2299.     IF SL_sprite(handle).zoom <> 100 THEN '                                                             zoom sprite in/out?
  2300.         zoomfactor = SL_sprite(handle).zoom / 100
  2301.         'sw = sw * SL_sprite(handle).zoom * .01 '\ 100 '                                                        yes, calculate new zoom width
  2302.         'sh = sh * SL_sprite(handle).zoom * .01 '\ 100 '                                                        calculate new zoom height
  2303.         sw = sw * zoomfactor '                                                                          yes, calculate new zoom width
  2304.         sh = sh * zoomfactor '                                                                          calculate new zoom height
  2305.     ELSE
  2306.         zoomfactor = 1
  2307.     END IF
  2308.  
  2309.     'calculate actual sprite screen coordinates
  2310.  
  2311.     xa = SL_sprite(handle).x.int - sw \ 2 '                                                             calculate actual screen x location from center
  2312.     ya = SL_sprite(handle).y.int - sh \ 2 '                                                             calculate actual screen y location from center
  2313.     SL_sprite(handle).x.actual = xa '                                                        (INTEGER)  save actual screen x location
  2314.     SL_sprite(handle).y.actual = ya '                                                        (INTEGER)  save actual screen y location
  2315.  
  2316.     ' update collision box location based on actual x,y location, radius, and zoom factor
  2317.  
  2318.     SL_sprite(handle).collision.x1 = xa + SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, SL_sprite(handle).rotation.angle).x1 * zoomfactor
  2319.     SL_sprite(handle).collision.x2 = xa + SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, SL_sprite(handle).rotation.angle).x2 * zoomfactor
  2320.     SL_sprite(handle).collision.y1 = ya + SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, SL_sprite(handle).rotation.angle).y1 * zoomfactor
  2321.     SL_sprite(handle).collision.y2 = ya + SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, SL_sprite(handle).rotation.angle).y2 * zoomfactor
  2322.     SL_sprite(handle).collision.radius = SL_angle(SL_sprite(handle).sheet, SL_sprite(handle).cell, SL_sprite(handle).rotation.angle).radius * zoomfactor
  2323.  
  2324.     'get background image before placing sprite if necessary
  2325.  
  2326.     IF SL_sprite(handle).restore THEN '                                                                 is this sprite storing background images?
  2327.         SL_sprite(handle).gfx.back = _NEWIMAGE(sw, sh, 32) '                                            yes, create background image
  2328.         SL_SET_SOURCE_LAYER SL_sprite(handle).layer '                                                   set the source layer
  2329.         _PUTIMAGE , _SOURCE, SL_sprite(handle).gfx.back, (xa, ya)-(xa + sw - 1, ya + sh - 1) '          get background area from current source layer
  2330.         SL_sprite(handle).x.back = xa '                                                                 record background x location
  2331.         SL_sprite(handle).y.back = ya '                                                                 record background y location
  2332.     END IF
  2333.  
  2334.     'use hardware or software image
  2335.  
  2336.     IF SL_sprite(handle).software THEN '                                                                is this a software sprite?
  2337.         sprite = SL_sprite(handle).gfx.software '                                                       yes, use the software image
  2338.         SL_SET_DESTINATION_LAYER SL_sprite(handle).layer '                                              set the destination layer
  2339.     ELSE '                                                                                              no
  2340.         sprite = SL_sprite(handle).gfx.hardware '                                                       use the hardware image
  2341.         SL_SET_DESTINATION_LAYER 1 '                                                                    set the destination layer to first as default
  2342.     END IF
  2343.  
  2344.     ' place sprite on the current destination with desired flip method
  2345.  
  2346.     IF SL_sprite(handle).visible THEN '                                            (SL_SHOW & SL_HIDE)  show this sprite?
  2347.         SELECT CASE SL_sprite(handle).flip '                                                            yes, which flipping style is selected?
  2348.             CASE 0 '                                                                       (SL_NOFLIP)  normal, no flipping
  2349.                 _PUTIMAGE (xa, ya)-(xa + sw - 1, ya + sh - 1), sprite '                                 draw normal sprite
  2350.             CASE 1 '                                                                   (SL_HORIZONTAL)  flip horizontally
  2351.                 _PUTIMAGE (xa + sw - 1, ya)-(xa, ya + sh - 1), sprite '                                 draw horizontally flipped sprite
  2352.             CASE 2 '                                                                     (SL_VERTICAL)  flip vertically
  2353.                 _PUTIMAGE (xa, ya + sh - 1)-(xa + sw - 1, ya), sprite '                                 draw vertically flipped sprite
  2354.             CASE 3 '                                                                     (SL_FLIPBOTH)  flip vertically and horizontally
  2355.                 _PUTIMAGE (xa + sw - 1, ya + sh - 1)-(xa, ya), sprite '                                 draw horizontally and vertically flipped sprite
  2356.         END SELECT
  2357.     END IF
  2358.  
  2359.     '_SOURCE osource '                                                                                   restore original source
  2360.     '_DEST odest '                                                                                       restore original destination
  2361.     SL_SET_SOURCE_LAYER osource
  2362.     SL_SET_DESTINATION_LAYER odest
  2363.  
  2364.  
  2365. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2366. FUNCTION SL_NEW_SPRITE (layer AS INTEGER, sheet AS INTEGER, cell AS INTEGER, software AS INTEGER, restores AS INTEGER) '                                                                  SL_NEW_SPRITE
  2367.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2368.  
  2369.     ' declare global variables
  2370.  
  2371.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  2372.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2373.  
  2374.     ' declare local variables
  2375.  
  2376.     DIM handle AS INTEGER '             handle (pointer) number of new sprite
  2377.  
  2378.     ' perform error checks
  2379.  
  2380.     IF NOT SL_VALID_SHEET(sheet) THEN '                                                                 is this a valid sprite sheet?
  2381.         SL_error "SL_NEW_SPRITE", 5, "" '                                                               no, report error to programmer
  2382.     END IF
  2383.     IF NOT SL_VALID_CELL(sheet, cell) THEN '                                                            valid cell?
  2384.         SL_error "SL_NEW_SPRITE", 13, "" '                                                              no, report error to programmer
  2385.     END IF
  2386.     IF NOT SL_VALID_LAYER(layer) THEN '                                                                 valid layer?
  2387.         SL_error "SL_NEW_SPRITE", 25, "" '                                                              no, report error to programmer
  2388.     END IF
  2389.     IF restores < -1 OR restores > 0 THEN '                                                             valid background restoration behavior requested?
  2390.         SL_error "SL_NEW_SPRITE", 2, "" '                                                               no, report error to programmer
  2391.     END IF
  2392.     IF software < -1 OR software > 0 THEN '                                                             valid hardware / software setting requested?
  2393.         SL_error "SL_NEW_SPRITE", 112, "" '                                                             no, report error to programmer
  2394.     END IF
  2395.     IF (NOT software) AND restores THEN '                                                               hardware image that restores background?
  2396.         SL_error "SL_NEW_SPRITE", 113, "" '                                                             yes, report error to programmer
  2397.     END IF
  2398.  
  2399.     ' local variable setup
  2400.  
  2401.     handle = 0 '                                                                                        initialize handle value
  2402.  
  2403.     ' increase sprite array's size if needed
  2404.  
  2405.     DO '                                                                                                look for next available handle
  2406.         handle = handle + 1 '                                                                           increment to next handle value
  2407.     LOOP UNTIL (NOT SL_sprite(handle).inuse) OR handle = UBOUND(SL_sprite) '                            stop looking when valid handle found
  2408.     IF SL_sprite(handle).inuse THEN '                                                                   is the last array element in use?
  2409.         handle = handle + 1 '                                                                           yes, increment to next handle value
  2410.         REDIM _PRESERVE SL_sprite(handle) AS SL_SPRITE '                                                increase the size of the sprite array
  2411.     END IF
  2412.  
  2413.     ' populate sprite array, general settings
  2414.  
  2415.     SL_sprite(handle).inuse = -1 '                                                              (TRUE)  mark array index as in use
  2416.     SL_sprite(handle).sheet = sheet '                                                                   point to sheet where sprite resides
  2417.     SL_sprite(handle).cell = cell '                                                                     cell sprite is located in on sheet
  2418.     SL_sprite(handle).software = software '                                (SL_SOFTWARE & SL_HARDWARE)  sprite treated as software or hardware image
  2419.     SL_sprite(handle).restore = restores '                                       (SL_SAVE & SL_NOSAVE)  background restore behavior of sprite
  2420.     SL_sprite(handle).swidth = SL_sheet(sheet, cell).swidth '                                           get width of sprite
  2421.     SL_sprite(handle).sheight = SL_sheet(sheet, cell).sheight '                                         get height of sprite
  2422.     SL_sprite(handle).flip = 0 '                                                                        no sprite flipping
  2423.     SL_sprite(handle).zoom = 100 '                                                                      zoom normal at 100%
  2424.     SL_sprite(handle).score = 0 '                                                                       no point score
  2425.     SL_sprite(handle).visible = -1 '                                                            (TRUE)  sprite visible on screen
  2426.     SL_sprite(handle).layer = layer '                                                                   set sprite's layer
  2427.  
  2428.  
  2429.     ' mouse settings
  2430.  
  2431.     SL_sprite(handle).mouse.event = 0 '(SL_NOMOUSE, SL_HOVER, SL_LEFTCLICK, SL_RIGHTCLICK, SL_CENTERCLICK) reset mouse interaction
  2432.     SL_sprite(handle).mouse.x = 0 '                                                                     reset mouse pointer locations
  2433.     SL_sprite(handle).mouse.y = 0
  2434.     SL_sprite(handle).mouse.xa = 0
  2435.     SL_sprite(handle).mouse.ya = 0
  2436.  
  2437.     ' collision settings
  2438.  
  2439.     SL_sprite(handle).collision.detect = 0 '                                                            reset collision detection method selected
  2440.     SL_sprite(handle).collision.box = 0 '                                                      (FALSE)  reset box collision detected
  2441.     SL_sprite(handle).collision.round = 0 '                                                    (FALSE)  reset round collision detected
  2442.     SL_sprite(handle).collision.pixel = 0 '                                                    (FALSE)  reset pixel perfect collision detected
  2443.     SL_sprite(handle).collision.with = 0 '                                                              reset collision detected
  2444.     SL_sprite(handle).collision.xpoint = 0 '                                                            reset collision x point
  2445.     SL_sprite(handle).collision.ypoint = 0 '                                                            reset collision y point
  2446.     SL_sprite(handle).collision.radius = 0 '                                                            reset round collision radius
  2447.     SL_sprite(handle).collision.x1 = 0 '                                                                reset sprite's collision box boundaries
  2448.     SL_sprite(handle).collision.y1 = 0
  2449.     SL_sprite(handle).collision.x2 = 0
  2450.     SL_sprite(handle).collision.y2 = 0
  2451.     SL_sprite(handle).collision.cwidth = 0 '                                                            reset collision box width
  2452.     SL_sprite(handle).collision.cheight = 0 '                                                           reset collision box height
  2453.  
  2454.     ' animation settings
  2455.  
  2456.     SL_sprite(handle).animation.cell = cell '                                                           the animation cell this sprite is in
  2457.     SL_sprite(handle).animation.cellfrom = 0 '                                                          reset sprite beginning animation cell
  2458.     SL_sprite(handle).animation.cellto = 0 '                                                            reset sprite ending animation cell
  2459.     SL_sprite(handle).animation.dir = 0 '                      (SL_FORWARD, SL_BACKWARD & SLBACKFORTH)  reset sprite animation direction
  2460.     SL_sprite(handle).animation.mode = 0 '                                                              reset sprite animation mode
  2461.     SL_sprite(handle).animation.frame = 0 '                                                             reset sprite animation frame counter
  2462.     SL_sprite(handle).animation.skip = 0 '                                                              reset sprite animation skip rate
  2463.     SL_sprite(handle).animation.auto = 0 '                                                     (FALSE)  sprite has no auto animation
  2464.  
  2465.     ' x,y location settings
  2466.  
  2467.     SL_sprite(handle).x.real = 0 '                                                                      reset x location of sprite (center x)
  2468.     SL_sprite(handle).y.real = 0 '                                                                      reset y location of sprite (center y)
  2469.     SL_sprite(handle).x.int = 0 '                                                                       reset x location of sprite on screen INT(xreal) (center x)
  2470.     SL_sprite(handle).y.int = 0 '                                                                       reset y location of sprite on screen INT(yreal) (center y)
  2471.     SL_sprite(handle).x.actual = 0 '                                                                    reset x location of sprite on screen (upper left x)
  2472.     SL_sprite(handle).y.actual = 0 '                                                                    reset y location of sprite on screen (upper left y)
  2473.     SL_sprite(handle).x.dir = 0 '                                                                       x direction during motion
  2474.     SL_sprite(handle).y.dir = 0 '                                                                       y direction during motion
  2475.  
  2476.     ' graphics image settings
  2477.  
  2478.     SL_sprite(handle).gfx.back = 0 '                                                                    no background image saved yet
  2479.     SL_sprite(handle).gfx.hardware = _COPYIMAGE(SL_sheet(sheet, cell).software, 33) '                   create hardware sprite image
  2480.     SL_sprite(handle).gfx.software = _COPYIMAGE(SL_sheet(sheet, cell).software, 32) '                   copy software sprite image from sheet
  2481.     IF SL_sheet(sheet, cell).transparency THEN '                                                        does this sprite use transparency?
  2482.         SL_sprite(handle).gfx.mask = _COPYIMAGE(SL_sheet(sheet, cell).mask, 32) '                       yes, copy software sprite mask image from sheet
  2483.         SL_sprite(handle).transparency = -1 '                                                   (TRUE)  remember this sprite has a transparency layer
  2484.     ELSE '                                                                                              no transparency
  2485.         SL_sprite(handle).gfx.mask = 0 '                                                                no mask will be brought in
  2486.         SL_sprite(handle).transparency = 0 '                                                   (FALSE)  remember this sprite has no transparency layer
  2487.     END IF
  2488.  
  2489.     ' rotation settings
  2490.  
  2491.     SL_sprite(handle).rotation.angle = 0 '                                                              no sprite rotation angle
  2492.     SL_sprite(handle).rotation.speed = 0 '                                                              no spin rate
  2493.     SL_sprite(handle).rotation.auto = 0 '                                                      (FALSE)  auto rotation disabled
  2494.  
  2495.     ' motion settings
  2496.  
  2497.     SL_sprite(handle).motion.speed = 0 '                                                                speed during motion
  2498.     SL_sprite(handle).motion.angle = 0 '                                                                direction during motion (0 - 359)
  2499.     SL_sprite(handle).motion.auto = 0 '                                                        (FALSE)  auto motion disabled
  2500.  
  2501.     SL_NEW_SPRITE = handle '                                                                            return pointer value of new sprite
  2502.  
  2503.  
  2504. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2505. SUB SL_FREE_SPRITE (handle AS INTEGER) '                                                                                                                                                 SL_FREE_SPRITE
  2506.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2507.  
  2508.     ' declare global variables
  2509.  
  2510.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2511.  
  2512.     ' check for errors
  2513.  
  2514.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2515.         SL_error "SL_FREE_SPRITE", 1, "" '                                                              no, report error to programmer
  2516.     END IF
  2517.  
  2518.     ' restore background if this sprite saving background
  2519.  
  2520.     IF SL_sprite(handle).restore THEN '                                                                 is there a background image to restore?
  2521.         _PUTIMAGE (SL_sprite(handle).x.back, SL_sprite(handle).y.back), SL_sprite(handle).gfx.back '    yes, restore the image
  2522.         _FREEIMAGE SL_sprite(handle).gfx.back '                                                         free background image
  2523.     END IF
  2524.  
  2525.     ' free all image data associated with sprite
  2526.  
  2527.     IF SL_sprite(handle).gfx.back THEN _FREEIMAGE SL_sprite(handle).gfx.back '                          free background image if present
  2528.     IF SL_sprite(handle).gfx.mask THEN _FREEIMAGE SL_sprite(handle).gfx.mask '                          free sprite mask image if present
  2529.     _FREEIMAGE SL_sprite(handle).gfx.hardware '                                                         free hardware sprite image
  2530.     _FREEIMAGE SL_sprite(handle).gfx.software '                                                         free software sprite image
  2531.  
  2532.     IF (handle = UBOUND(sl_sprite)) AND (handle <> 1) THEN '                                            is handle the last element in array?
  2533.         REDIM _PRESERVE SL_sprite(handle - 1) AS SL_SPRITE '                                            yes, remove index and resize array
  2534.     ELSE '                                                                                              no, index somewhere else
  2535.         SL_sprite(handle).inuse = 0 '                                                          (FALSE)  mark index as usable later
  2536.     END IF
  2537.  
  2538.  
  2539. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2540. FUNCTION SL_VALID_SPRITE (handle AS INTEGER) '                                                                                                                                         SL_VALID_SPRITE
  2541.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2542.  
  2543.     ' declare global variables
  2544.  
  2545.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2546.  
  2547.     IF (handle > UBOUND(SL_SPRITE)) OR (NOT SL_sprite(handle).inuse) OR (handle < 1) THEN '              is this a valid sprite handle?
  2548.         SL_VALID_SPRITE = 0 '                                                                   (FALSE)  no, return 0
  2549.     ELSE '                                                                                               yes, it is valid
  2550.         SL_VALID_SPRITE = -1 '                                                                   (TRUE)  return -1
  2551.     END IF
  2552.  
  2553.  
  2554. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2555. SUB SL_SET_SCORE (handle AS INTEGER, score AS INTEGER) '                                                                                                                                   SL_SET_SCORE
  2556.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2557.  
  2558.     ' declare global variables
  2559.  
  2560.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2561.  
  2562.     ' perform error checks
  2563.  
  2564.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2565.         SL_error "SL_SET_SCORE", 1, "" '                                                                no, report error to programmer
  2566.     END IF
  2567.  
  2568.     SL_sprite(handle).score = score '                                                                   set sprite score
  2569.  
  2570.  
  2571. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2572. FUNCTION SL_GET_SCORE (handle AS INTEGER) '                                                                                                                                                SL_GET_SCORE
  2573.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2574.  
  2575.     ' declare global variables
  2576.  
  2577.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2578.  
  2579.     ' perform error checks
  2580.  
  2581.     IF NOT SL_VALID_SPRITE(handle) THEN '                                                               is this a valid sprite?
  2582.         SL_error "SL_GET_SCORE", 1, "" '                                                                no, report error to programmer
  2583.     END IF
  2584.  
  2585.     SL_GET_SCORE = SL_sprite(handle).score '                                                            return sprite score
  2586.  
  2587.  
  2588.  
  2589. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2590. '                                                                       ----------==========                ==========----------
  2591. '                                                                       ----------========== SHEET ROUTINES ==========----------
  2592. '                                                                       ----------==========                ==========----------
  2593. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2594.  
  2595.  
  2596. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2597. FUNCTION SL_NEW_SHEET (filename AS STRING, swidth AS INTEGER, sheight AS INTEGER, transparency AS INTEGER, transcolor AS _UNSIGNED LONG) '                                                 SL_NEW_SHEET
  2598.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2599.  
  2600.     ' The saving/loading of rotational data file added from an idea by Bplus
  2601.     ' https://www.qb64.org/forum/index.php?topic=537.30
  2602.  
  2603.     ' declare global variables
  2604.  
  2605.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  2606.     SHARED SL_angle() AS SL_ANGLE '     precalculated rotation table
  2607.  
  2608.     ' declare local variables
  2609.  
  2610.     DIM handle AS INTEGER '             handle (pointer) number of new sprite sheet
  2611.     DIM x AS INTEGER '                  generic counter to cycle through sheet sprite columns
  2612.     DIM y AS INTEGER '                  generic counter to cycle through sheet sprite rows
  2613.     DIM osource AS LONG '               original source image before this function was called
  2614.     DIM odest AS LONG '                 original destination image before this function was called
  2615.     DIM pixel AS _UNSIGNED LONG '       pixel color at each coordinate in sprite sheet
  2616.     DIM alpha AS _UNSIGNED LONG '       alpha level of current pixel
  2617.     DIM top AS INTEGER '                upper boundary of sprite image
  2618.     DIM bottom AS INTEGER '             lower boundary of sprite image
  2619.     DIM left AS INTEGER '               left boundary of sprite image
  2620.     DIM right AS INTEGER '              right boundary of sprite image
  2621.     DIM sheetimage AS LONG '            sprite sheet image
  2622.     DIM sheetwidth AS INTEGER '         width of sprite sheet in pixels
  2623.     DIM sheetheight AS INTEGER '        height of sprite sheet in pixels
  2624.     DIM rows AS INTEGER '               number of sprite rows contained on sheet
  2625.     DIM columns AS INTEGER '            number of sprite columns contained on sheet
  2626.     DIM clearcolor AS _UNSIGNED LONG '  transcolor passed in will be modified
  2627.     DIM tempsprite AS LONG '            temporary sprite image
  2628.     DIM px(3) AS SINGLE '               polar x coordinates of maptriangle
  2629.     DIM py(3) AS SINGLE '               polar y coordinates of maptriangle
  2630.     DIM sinr AS SINGLE '                sin rotation calculation
  2631.     DIM cosr AS SINGLE '                cosine rotation calculation
  2632.     DIM bx1 AS SINGLE '                 boundaries of collision box
  2633.     DIM bx2 AS SINGLE
  2634.     DIM by1 AS SINGLE
  2635.     DIM by2 AS SINGLE
  2636.     DIM x2 AS SINGLE '                  new computed polar coordinates
  2637.     DIM y2 AS SINGLE
  2638.     DIM cells AS INTEGER '              total number of cells on sheet
  2639.     DIM cell AS INTEGER '               cell counter
  2640.     DIM degree AS INTEGER '             degree counter
  2641.     DIM polar AS INTEGER '              polar coordinate counter
  2642.     DIM xoffset AS INTEGER '            x offset to rotated center
  2643.     DIM yoffset AS INTEGER '            y offset to rotated center
  2644.     DIM xwidth AS INTEGER '             sprite width counter
  2645.     DIM yheight AS INTEGER '            sprite height counter
  2646.     DIM rotfile AS STRING '             name of rotation data file
  2647.     DIM preloaded AS INTEGER '          -1 (TRUE) if rotation data preloaded
  2648.     DIM filenum AS INTEGER '            FREEFILE number
  2649.  
  2650.     ' perform error checks
  2651.  
  2652.     IF NOT _FILEEXISTS(filename) THEN '                                                                 does the sprite sheet exist?
  2653.         SL_error "SL_NEW_SHEET", 100, filename '                                                        no, report error to programmer
  2654.     END IF
  2655.     IF ABS(transparency) > 1 THEN '                                                                     valid transparency setting?
  2656.         SL_error "SL_NEW_SHEET", 101, "" '                                                              no, report error to programmer
  2657.     END IF
  2658.     IF swidth < 1 OR sheight < 1 THEN '                                                                 valid sprite width/height supplied?
  2659.         SL_error "SL_NEW_SHEET", 102, "" '                                                              no, report error to programmer
  2660.     END IF
  2661.     IF transparency = -1 AND UCASE$(RIGHT$(filename, 4)) <> ".PNG" THEN '                               wrong file type for transparency?
  2662.         SL_error "SL_NEW_SHEET", 103, UCASE$(RIGHT$(filename, 4)) '                                     yes, report error to programmer
  2663.     END IF
  2664.  
  2665.     ' local variable setup
  2666.  
  2667.     sheetimage = _LOADIMAGE(filename, 32) '                                                             load sprite sheet file
  2668.     sheetwidth = _WIDTH(sheetimage) '                                                                   get width of sheet
  2669.     sheetheight = _HEIGHT(sheetimage) '                                                                 get height of sheet
  2670.     columns = sheetwidth \ swidth '                                                                     get number of whole columns of sprites
  2671.     rows = sheetheight \ sheight '                                                                      get number of whole rows of sprites
  2672.     cells = rows * columns '                                                                            calculate total number of cells on sheet
  2673.  
  2674.     IF columns < 1 OR rows < 1 THEN '                                                                   at least one sprite column and row on sheet?
  2675.         SL_error "SL_NEW_SHEET", 104, "" '                                                              no, report error to programmer
  2676.     END IF
  2677.  
  2678.     osource = _SOURCE '                                                                                 remember current source image
  2679.     odest = _DEST '                                                                                     remember current destination image
  2680.     handle = 0 '                                                                                        initialize handle value
  2681.     clearcolor = transcolor '                                                                           get background/transparent color passed in
  2682.  
  2683.     ' increase sheet array's 1st dimension if needed to create a new sprite sheet
  2684.  
  2685.     DO '                                                                                                look for the next available handle
  2686.         handle = handle + 1 '                                                                           increment the handle value
  2687.     LOOP UNTIL (NOT SL_sheet(handle, 0).software) OR handle = UBOUND(SL_sheet) '                        stop looking when valid handle value found
  2688.     IF SL_sheet(handle, 0).software = -1 THEN '                                                 (TRUE)  is the last array element in use?
  2689.         handle = handle + 1 '                                                                           yes, increment the handle value
  2690.         REDIM _PRESERVE SL_sheet(handle, UBOUND(SL_sheet, 2)) AS SL_SHEET '                             create new sheet in sprite array
  2691.         REDIM _PRESERVE SL_angle(handle, UBOUND(SL_angle, 2), 359) AS SL_ANGLE '                        increase rotation array to match
  2692.     END IF
  2693.  
  2694.     ' increase sheet array's 2nd dimension if needed to match number of cells
  2695.  
  2696.     IF cells > UBOUND(SL_sheet, 2) THEN '                                                               more cells in this sheet than others?
  2697.         REDIM _PRESERVE SL_sheet(handle, cells) AS SL_SHEET '                                           yes, increase the array's 2nd dimension to match
  2698.         REDIM _PRESERVE SL_angle(handle, cells, 359) AS SL_ANGLE '                                      increase rotation array to match
  2699.     END IF
  2700.  
  2701.     ' the variables in SL_sheet(x, 0) will serve a dual purpose
  2702.     ' SL_sheet(x, 0).image will contain either -1 (true) or 0 (false) to indicate the first dimension of the array is in use.
  2703.  
  2704.     SL_sheet(handle, 0).software = -1 '                                                         (TRUE)  mark as in use
  2705.  
  2706.     ' identify transparency of sprite sheet if requested
  2707.  
  2708.     IF transparency = -1 THEN '                                                          (SL_USESHEET)  sheet have alpha channel?
  2709.         x = 0 '                                                                                         yes, start at upper left x of sheet
  2710.         y = 0 '                                                                                         start at upper left y of sheet
  2711.         alpha = 255 '                                                                                   assume no alpha channel
  2712.         _SOURCE sheetimage '                                                                            set sprite sheet image as source image
  2713.         DO '                                                                                            start looping through the sheet's pixels
  2714.             pixel = POINT(x, y) '                                                                       get the pixel's color attributes
  2715.             alpha = _ALPHA32(pixel) '                                                                   get the alpha level (0 - 255)
  2716.             IF alpha = 0 THEN EXIT DO '                                                                 if it is transparent then leave the loop
  2717.             x = x + 1 '                                                                                 move right one pixel
  2718.             IF x > sheetwidth THEN '                                                                    have we gone off the sheet?
  2719.                 x = 0 '                                                                                 yes, reset back to the left beginning
  2720.                 y = y + 1 '                                                                             move down one pixel
  2721.             END IF
  2722.         LOOP UNTIL y > sheetheight '                                                                    don't stop until the entire sheet has been checked
  2723.         IF alpha = 0 THEN '                                                                             did we find a transparent pixel?
  2724.             tempsprite = _NEWIMAGE(1, 1, 32) '                                                          yes, create a temporary image         * why did I have to do
  2725.             _CLEARCOLOR pixel, tempsprite '                                                             set pixel found as transparent        * this hack to get
  2726.             clearcolor = _CLEARCOLOR(tempsprite) '                                                      get the transparent color from image  * clearcolor to come out
  2727.             _FREEIMAGE tempsprite '                                                                     temporary image no longer needed      * to the right value?
  2728.         ELSE '                                                                                          no transparency found within sheet
  2729.             transparency = 1 '                                                                          set sheet to having no alpha channel
  2730.         END IF
  2731.     ELSEIF transparency = 0 THEN '                                                            (SL_SET)  manually set alpha channel?
  2732.         _CLEARCOLOR clearcolor, sheetimage '                                                            yes, set color as transparent
  2733.         clearcolor = _CLEARCOLOR(sheetimage) '                                                          get the transparent color ************* again, why this hack?
  2734.     END IF
  2735.  
  2736.     ' preload rotational data if it exists
  2737.  
  2738.     rotfile = LEFT$(filename, INSTR(filename, ".") - 1) + ".rot" '                                      the name of the rotational data file
  2739.     IF _FILEEXISTS(rotfile) THEN '                                                                      does it exist?
  2740.         preloaded = -1 '                                                                                yes, remember that data has been preloaded
  2741.         filenum = FREEFILE
  2742.         OPEN rotfile FOR BINARY AS filenum '                                                            open it for reading
  2743.         FOR x = 1 TO cells '                                                                            cycle through all animation cells
  2744.             FOR y = 0 TO 359 '                                                                          and their associated rotational data
  2745.                 GET #1, , SL_angle(handle, x, y) '                                                      get the data
  2746.             NEXT y
  2747.         NEXT x
  2748.         CLOSE filenum '                                                                                 close the file
  2749.     END IF
  2750.  
  2751.     ' load sprites from sheet and place into sprite array
  2752.  
  2753.     x = 0 '                                                                                             reset column counter
  2754.     DO '                                                                                                cycle through sheet's columns
  2755.         x = x + 1 '                                                                                     increment column counter
  2756.         y = 0 '                                                                                         reset row counter
  2757.         DO '                                                                                            cycle through sheet's rows
  2758.             y = y + 1 '                                                                                 increment row counter
  2759.             cell = (y - 1) * columns + x '                                                              calculate current cell number
  2760.             SL_sheet(handle, cell).software = _NEWIMAGE(swidth, sheight, 32) '                          create software sprite image
  2761.  
  2762.             SL_sheet(handle, cell).swidth = swidth
  2763.             SL_sheet(handle, cell).sheight = sheight
  2764.  
  2765.  
  2766.             IF transparency < 1 THEN '                                                                  should a mask be created?
  2767.                 SL_sheet(handle, cell).mask = _NEWIMAGE(swidth, sheight, 32) '                          yes, create software sprite mask image
  2768.                 _DEST SL_sheet(handle, cell).mask '                                                     write to the mask image
  2769.             ELSE '                                                                                      no software mask image
  2770.                 SL_sheet(handle, cell).transparency = 0 '                                      (FALSE)  set sprite as having no transparency
  2771.             END IF
  2772.             _PUTIMAGE , sheetimage, SL_sheet(handle, cell).software,_
  2773.                 ((x - 1) * swidth, (y - 1) * sheight)-_
  2774.                 ((x - 1) * swidth + swidth - 1, (y - 1) * sheight + sheight - 1) '                      copy sprite from sheet and place in sprite image
  2775.  
  2776.             ' precalculate collision boundaries and update sprite mask if needed
  2777.  
  2778.             _SOURCE SL_sheet(handle, cell).software '                                                   work from the software sprite image
  2779.             top = sheight - 1 '                                                                         set initial collision boundary markers
  2780.             left = swidth - 1
  2781.             bottom = 0
  2782.             right = 0
  2783.  
  2784.             xwidth = 0 '                                                                                reset width counter
  2785.             DO '                                                                                        cycle through width of sprite
  2786.                 yheight = 0 '                                                                           reset height counter
  2787.                 DO '                                                                                    cycle through height of sprite
  2788.                     IF POINT(xwidth, yheight) <> clearcolor THEN '                                      is this pixel a transparent/background color?
  2789.                         IF xwidth < left THEN left = xwidth '                                           no, save position if left-most pixel
  2790.                         IF yheight < top THEN top = yheight '                                           save position if top-most pixel
  2791.                         IF xwidth > right THEN right = xwidth '                                         save position if right-most pixel
  2792.                         IF yheight > bottom THEN bottom = yheight '                                     save position if bbottom-most pixel
  2793.                     END IF
  2794.                     IF transparency < 1 THEN '                                                          update software sprite mask?
  2795.                         IF POINT(xwidth, yheight) = clearcolor THEN '                                   yes, is this pixel a transparent/background color?
  2796.                             PSET (xwidth, yheight), _RGB32(255, 255, 255) '                             yes, set as white on the mask image
  2797.                         END IF
  2798.                     END IF
  2799.                     yheight = yheight + 1 '                                                             increment height counter
  2800.                 LOOP UNTIL yheight = sheight '                                                          leave when height of sprite reached (-1)
  2801.                 xwidth = xwidth + 1 '                                                                   increment width counter
  2802.             LOOP UNTIL xwidth = swidth '                                                                leave when width of sprite reached (-1)
  2803.  
  2804.             SL_angle(handle, cell, 0).x1 = left '                                                       collision box top left x
  2805.             SL_angle(handle, cell, 0).y1 = top '                                                        collision box top left y
  2806.             SL_angle(handle, cell, 0).x2 = right '                                                      collision box bottom right x
  2807.             SL_angle(handle, cell, 0).y2 = bottom '                                                     collision box bottom right y
  2808.             SL_angle(handle, cell, 0).cwidth = right - left '                                           remember collision box width
  2809.             SL_angle(handle, cell, 0).cheight = bottom - top '                                          remember collision box height
  2810.             SL_angle(handle, cell, 0).radius = (SL_angle(handle, cell, 0).cwidth + SL_angle(handle, cell, 0).cheight) \ 4 ' calculate round collision radius
  2811.  
  2812.             IF NOT preloaded THEN
  2813.  
  2814.                 degree = 0 '                                                                            reset degree counter
  2815.                 DO '                                                                                    cycle from 1 to 359 degrees
  2816.                     degree = degree + 1 '                                                               increment degree counter
  2817.                     'px(0) = (-swidth + 1) / 2 '                                                         upper left  x polar coordinate of sprite
  2818.                     'py(0) = (-sheight + 1) / 2 '                                                        upper left  y polar coordinate of sprite
  2819.                     px(0) = -swidth / 2 '                                                               upper left  x polar coordinate of sprite
  2820.                     py(0) = -sheight / 2 '                                                              upper left  y polar coordinate of sprite
  2821.                     px(1) = px(0) '                                                                     lower left  x polar coordinate of sprite
  2822.                     'py(1) = (sheight -1) / 2 '                                                          lower left  y polar coordinate of sprite
  2823.                     'px(2) = (swidth - 1) / 2 '                                                          lower right x polar coordinate of sprite
  2824.                     py(1) = sheight / 2 '                                                               lower left  y polar coordinate of sprite
  2825.                     px(2) = swidth / 2 '                                                                lower right x polar coordinate of sprite
  2826.                     py(2) = py(1) '                                                                     lower right y polar coordinate of sprite
  2827.                     px(3) = px(2) '                                                                     upper right x polar coordinate of sprite
  2828.                     py(3) = py(0) '                                                                     upper right y polar coordinate of sprite
  2829.                     sinr = SIN(-degree / 57.2957795131) '                                               calculate the sin of rotation
  2830.                     cosr = COS(-degree / 57.2957795131) '                                               calculate the cosine of rotation
  2831.                     bx1 = 0 '                                                                           upper left x boundary of sprite
  2832.                     by1 = 0 '                                                                           upper left y boundary of sprite
  2833.                     bx2 = 0 '                                                                           lower right x boundary of sprite
  2834.                     by2 = 0 '                                                                           lower right y boundary of sprite
  2835.  
  2836.                     polar = 0 '                                                                         reset counter
  2837.                     DO '                                                                                cycle through all four polar coordinates (0 to 3)
  2838.                         x2 = (px(polar) * cosr + sinr * py(polar)) '                                    compute new polar coordinate location
  2839.                         y2 = (py(polar) * cosr - px(polar) * sinr) '                                    compute new polar coordinate location
  2840.                         px(polar) = x2 '                                                                save the new polar coordinate
  2841.                         py(polar) = y2 '                                                                save the new polar coordinate
  2842.                         IF px(polar) < bx1 THEN bx1 = px(polar) '                                       save lowest  x value seen \  NOTE: use for
  2843.                         IF px(polar) > bx2 THEN bx2 = px(polar) '                                       save highest x value seen  \ background image         <--------------------- LOOK
  2844.                         IF py(polar) < by1 THEN by1 = py(polar) '                                       save lowest  y value seen  / rectangle coordinates
  2845.                         IF py(polar) > by2 THEN by2 = py(polar) '                                       save highest y value seen /
  2846.                         polar = polar + 1 '                                                             increment counter
  2847.                     LOOP UNTIL polar = 4 '                                                              leave when all coordinates calculated
  2848.  
  2849.                     SL_angle(handle, cell, degree).rwidth = bx2 - bx1 + 1 '                             calculate width of rotated sprite
  2850.                     SL_angle(handle, cell, degree).rheight = by2 - by1 + 1 '                            calculate height of rotated sprite
  2851.                     xoffset = SL_angle(handle, cell, degree).rwidth \ 2 '                               calculate x offset
  2852.                     yoffset = SL_angle(handle, cell, degree).rheight \ 2 '                              calculate y offset
  2853.                     SL_angle(handle, cell, degree).px0 = px(0) + xoffset '                              add offsets to coordinates
  2854.                     SL_angle(handle, cell, degree).px1 = px(1) + xoffset
  2855.                     SL_angle(handle, cell, degree).px2 = px(2) + xoffset
  2856.                     SL_angle(handle, cell, degree).px3 = px(3) + xoffset
  2857.                     SL_angle(handle, cell, degree).py0 = py(0) + yoffset
  2858.                     SL_angle(handle, cell, degree).py1 = py(1) + yoffset
  2859.                     SL_angle(handle, cell, degree).py2 = py(2) + yoffset
  2860.                     SL_angle(handle, cell, degree).py3 = py(3) + yoffset
  2861.  
  2862.                     ' rotate image here to get rotated collision box info
  2863.  
  2864.                     tempsprite = _NEWIMAGE(SL_angle(handle, cell, degree).rwidth, SL_angle(handle, cell, degree).rheight, 32) ' create temp image using precalculated width/height
  2865.                 _MAPTRIANGLE (0, 0)-(0, sheight - 1)-(swidth - 1, sheight - 1), SL_sheet(handle, cell).software TO _
  2866.                              (SL_angle(handle, cell, degree).px0, SL_angle(handle, cell, degree).py0)-(SL_angle(handle, cell, degree).px1,_
  2867.                               SL_angle(handle, cell, degree).py1)-(SL_angle(handle, cell, degree).px2, SL_angle(handle, cell, degree).py2), tempsprite ' map rotated sprite onto temp image
  2868.                 _MAPTRIANGLE (0, 0)-(swidth - 1, 0)-(swidth - 1, sheight - 1), SL_sheet(handle, cell).software TO _
  2869.                              (SL_angle(handle, cell, degree).px0, SL_angle(handle, cell, degree).py0)-(SL_angle(handle, cell, degree).px3,_
  2870.                               SL_angle(handle, cell, degree).py3)-(SL_angle(handle, cell, degree).px2, SL_angle(handle, cell, degree).py2), tempsprite
  2871.  
  2872.                     ' precalculate rotated collision boundaries
  2873.  
  2874.                     _SOURCE tempsprite '                                                                work from the temp image
  2875.                     top = SL_angle(handle, cell, degree).rheight - 1 '                                  set initial collision boundary markers
  2876.                     left = SL_angle(handle, cell, degree).rwidth - 1
  2877.                     bottom = 0
  2878.                     right = 0
  2879.  
  2880.                     xwidth = 0 '                                                                        reset width counter
  2881.                     DO '                                                                                cycle through width of rotated sprite
  2882.                         yheight = 0 '                                                                   reset height counter
  2883.                         DO '                                                                            cycle through height of rotated sprite
  2884.                             IF POINT(xwidth, yheight) <> clearcolor THEN '                              is this pixel a transparent/background color?
  2885.                                 IF xwidth < left THEN left = xwidth '                                   no, save position if left-most pixel
  2886.                                 IF yheight < top THEN top = yheight '                                   save position if top-most pixel
  2887.                                 IF xwidth > right THEN right = xwidth '                                 save position if right-most pixel
  2888.                                 IF yheight > bottom THEN bottom = yheight '                             save position if bbottom-most pixel
  2889.                             END IF
  2890.                             yheight = yheight + 1 '                                                     increment height counter
  2891.                         LOOP UNTIL yheight = SL_angle(handle, cell, degree).rheight '                   leave when height of rotated sprite reached (-1)
  2892.                         xwidth = xwidth + 1 '                                                           increment width counter
  2893.                     LOOP UNTIL xwidth = SL_angle(handle, cell, degree).rwidth '                         leave when width of rotated sprite reached (-1)
  2894.  
  2895.                     _FREEIMAGE tempsprite '                                                             temp image no longer needed
  2896.                     SL_angle(handle, cell, degree).x1 = left '                                          collision box top left x
  2897.                     SL_angle(handle, cell, degree).y1 = top '                                           collision box top left y
  2898.                     SL_angle(handle, cell, degree).x2 = right '                                         collision box bottom right x
  2899.                     SL_angle(handle, cell, degree).y2 = bottom '                                        collision box bottom right y
  2900.                     SL_angle(handle, cell, degree).cwidth = right - left '                              remember collision box width
  2901.                     SL_angle(handle, cell, degree).cheight = bottom - top '                             remember collision box height
  2902.                     SL_angle(handle, cell, degree).radius = (SL_angle(handle, cell, degree).cwidth + SL_angle(handle, cell, degree).cheight) \ 4 ' calculate round collision radius
  2903.                 LOOP UNTIL degree = 359 '                                                               leave when all degree angles calculated
  2904.  
  2905.             END IF ' preloaded
  2906.  
  2907.         LOOP UNTIL y = rows '                                                                           leave when all rows processed
  2908.     LOOP UNTIL x = columns '                                                                            leave when all columns processed
  2909.  
  2910.     _FREEIMAGE sheetimage '                                                                             sprite sheet image no longer needed
  2911.  
  2912.     _SOURCE osource '                                                                                   return source to current
  2913.     _DEST odest '                                                                                       return destination to current
  2914.  
  2915.     IF NOT _FILEEXISTS(rotfile) THEN '                                                                  does it exist?
  2916.         filenum = FREEFILE
  2917.         OPEN rotfile FOR BINARY AS filenum '                                                            no, open it for writing
  2918.         FOR x = 1 TO cells '                                                                            cycle through all sprite cells
  2919.             FOR y = 0 TO 359 '                                                                          and their rotational angles
  2920.                 PUT #1, , SL_angle(handle, x, y) '                                                      put the data
  2921.             NEXT y
  2922.         NEXT x
  2923.         CLOSE filenum '                                                                                 close the file
  2924.     END IF
  2925.  
  2926.     SL_NEW_SHEET = handle '                                                                             return the handle number pointing to this sheet
  2927.  
  2928.  
  2929. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2930. FUNCTION SL_VALID_SHEET (sheet AS INTEGER) '                                                                                                                                             SL_VALID_SHEET
  2931.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2932.  
  2933.     ' declare global variables
  2934.  
  2935.     SHARED SL_sheet() AS SL_SHEET '    master sprite sheet array
  2936.  
  2937.     IF (sheet > UBOUND(SL_sheet)) OR (sheet < 1) THEN '                                                 is this a valid sheet?
  2938.         SL_VALID_SHEET = 0 '                                                                   (FALSE)  no, return false
  2939.     ELSEIF NOT SL_sheet(sheet, 0).software THEN '                                                       is sprite sheet in use?
  2940.         SL_VALID_SHEET = 0 '                                                                   (FALSE)  no, return false
  2941.     ELSE '                                                                                              everything checks out
  2942.         SL_VALID_SHEET = -1 '                                                                   (TRUE)  return true
  2943.     END IF
  2944.  
  2945.  
  2946.  
  2947. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2948. '                                                                      ----------==========                   ==========----------
  2949. '                                                                      ----------========== INTERNAL USE ONLY ==========----------
  2950. '                                                                      ----------==========                   ==========----------
  2951. 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
  2952.  
  2953.  
  2954. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2955. SUB SL_update_auto_sprites (software AS INTEGER) '                                                                                                                               SL_update_auto_sprites
  2956.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  2957.  
  2958.     ' declare global variables
  2959.  
  2960.     SHARED SL_sprite() AS SL_SPRITE '   master working sprite array
  2961.     SHARED SL_global AS SL_GLOBAL '     common globals array
  2962.  
  2963.     ' declare local variables
  2964.  
  2965.     DIM handle AS INTEGER '             handle of sprite
  2966.     DIM nextcell AS SINGLE '            draw (-1 TRUE) or skip (0 FALSE) next animation cell
  2967.  
  2968.     ' local variable setup
  2969.  
  2970.     handle = 0 '                                                                                        initialize handle counter
  2971.  
  2972.     DO '                                                                                                cycle through all sprite indexes
  2973.         handle = handle + 1 '                                                                           increment to next sprite handle
  2974.         IF SL_sprite(handle).software = software THEN '                                                 hardware or software type equal to requested type?
  2975.             IF SL_sprite(handle).inuse AND (SL_sprite(handle).motion.auto OR _
  2976.                                             SL_sprite(handle).rotation.auto OR _
  2977.                                             SL_sprite(handle).animation.auto) THEN '                    yes, is this sprite being used and automagically controlled?
  2978.  
  2979.                 ' auto motion
  2980.  
  2981.                 IF SL_sprite(handle).motion.auto THEN '                                                 yes, is auto motion enabled?
  2982.                     SL_sprite(handle).x.real = SL_sprite(handle).x.real + SL_sprite(handle).x.dir '     yes, update x location
  2983.                     SL_sprite(handle).y.real = SL_sprite(handle).y.real + SL_sprite(handle).y.dir '     update y location
  2984.                 END IF
  2985.  
  2986.  
  2987.                 ' auto animation
  2988.  
  2989.                 IF SL_sprite(handle).animation.auto THEN '                                              is auto animation enabled?
  2990.                     IF SL_sprite(handle).animation.skip = 0 THEN '                                      yes, always go to next cell?
  2991.                         nextcell = -1 '                                                         (TRUE)  yes, draw next cell
  2992.                     ELSE '                                                                              no
  2993.  
  2994.                         ' decide to draw or skip next cell
  2995.  
  2996.                         SL_sprite(handle).animation.frame = SL_sprite(handle).animation.frame + 1 '     increment frame counter
  2997.                         IF SL_sprite(handle).animation.skip = SL_sprite(handle).animation.frame THEN '  time to skip or go to next cell?
  2998.                             SL_sprite(handle).animation.frame = 0 '                                     yes, reset the frame counter
  2999.                             IF SL_sprite(handle).animation.framerate >= SL_global.framerate \ 2 THEN '  should this cell be skipped?
  3000.                                 nextcell = 0 '                                                 (FALSE)  yes, skip next cell
  3001.                             ELSE '                                                                      no
  3002.                                 nextcell = -1 '                                                 (TRUE)  go to next cell
  3003.                             END IF
  3004.                         ELSEIF SL_sprite(handle).animation.framerate >= SL_global.framerate \ 2 THEN '  no, is sprite frame rate equal or greater than half global frame rate?
  3005.                             nextcell = -1 '                                                             yes, go to next cell
  3006.                         END IF
  3007.                     END IF
  3008.  
  3009.                     ' draw next cell
  3010.  
  3011.                     IF nextcell THEN '                                                                  update animation cell?
  3012.                         SELECT CASE SL_sprite(handle).animation.mode '                                  which animation mode is this sprite using?
  3013.                             CASE 0 '                                                      (SL_FORWARD)  move forward through the cells
  3014.                                 SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell + 1 ' increment animation cell
  3015.                                 IF SL_sprite(handle).animation.cell > SL_sprite(handle).animation.cellto THEN ' passed the last cell?
  3016.                                     SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellfrom ' yes, go back to first cell
  3017.                                 END IF
  3018.                             CASE 1 '                                                     (SL_BACKWARD)  move backward through the cells
  3019.                                 SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell - 1 ' decrement animation cell
  3020.                                 IF SL_sprite(handle).animation.cell < SL_sprite(handle).animation.cellfrom THEN ' passed the first cell?
  3021.                                     SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellto ' yes, go back to last cell
  3022.                                 END IF
  3023.                             CASE 2 '                                                    (SL_BACKFORTH)  ping-pong back and forth through the cells
  3024.                                 SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cell + SL_sprite(handle).animation.dir ' increment/decrement animation cell
  3025.                                 IF SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellto OR _
  3026.                                     SL_sprite(handle).animation.cell = SL_sprite(handle).animation.cellfrom THEN ' is this the first or last cell?
  3027.                                     SL_sprite(handle).animation.dir = -SL_sprite(handle).animation.dir 'yes, reverse animation direction
  3028.                                 END IF
  3029.                         END SELECT
  3030.                         SL_sprite(handle).cell = SL_sprite(handle).animation.cell '                     update current sprite cell
  3031.                         IF SL_sprite(handle).rotation.angle AND (NOT SL_sprite(handle).rotation.auto) THEN ' is this animation currently rotated but not automatic?
  3032.                             SL_ROTATE_SPRITE handle, SL_sprite(handle).rotation.angle '                 yes, this new cell will need manually rotated as well
  3033.                         END IF
  3034.                     END IF
  3035.                 END IF
  3036.  
  3037.                 ' auto rotation
  3038.  
  3039.                 IF SL_sprite(handle).rotation.auto THEN '                                               is auto rotation enabled?
  3040.                     SL_ROTATE_SPRITE handle, SL_sprite(handle).rotation.angle + SL_sprite(handle).rotation.speed ' yes, rotate sprite to next degree angle
  3041.                 END IF
  3042.  
  3043.                 SL_PUT_SPRITE SL_sprite(handle).x.real, SL_sprite(handle).y.real, handle '              update sprite motion location, rotation, and animation
  3044.             END IF
  3045.         END IF
  3046.     LOOP UNTIL handle = UBOUND(SL_sprite) '                                                             leave when all indexes checked
  3047.  
  3048.  
  3049. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3050. FUNCTION SL_min (a AS INTEGER, b AS INTEGER) '                                                                                                                                                   SL_min
  3051.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3052.  
  3053.     IF a < b THEN '                                                                                     is a the smaller number?
  3054.         SL_min = a '                                                                                    yes, return a
  3055.     ELSE '                                                                                              no, b is smaller number
  3056.         SL_min = b '                                                                                    return b (or a = b)
  3057.     END IF
  3058.  
  3059.  
  3060. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3061. FUNCTION SL_max (a AS INTEGER, b AS INTEGER) '                                                                                                                                                   SL_max
  3062.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3063.  
  3064.     IF a > b THEN '                                                                                     is a the larger number?
  3065.         SL_max = a '                                                                                    yes, return a
  3066.     ELSE '                                                                                              no, b is the larger number
  3067.         SL_max = b '                                                                                    return b (or a = b)
  3068.     END IF
  3069.  
  3070.  
  3071. '    ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3072. SUB SL_error (routine AS STRING, errno AS INTEGER, info AS STRING) '                                                                                                                           SL_error
  3073.     'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
  3074.  
  3075.     SCREEN 0, 0, 0, 0 '                                                                                 go to a pure text screen
  3076.     _FONT 16 '                                                                                          set the standard screen 0 font
  3077.     IF _FULLSCREEN THEN _FULLSCREEN _OFF '                                                              turn off full screen if on
  3078.     _AUTODISPLAY '                                                                                      auto update the display
  3079.     CLS '                                                                                               clear the screen
  3080.     COLOR 10, 0
  3081.     PRINT "                   **************************************" '                                 print error header
  3082.     PRINT "                   ** Sprite Library Error Encountered **"
  3083.     PRINT "                   **************************************"
  3084.     PRINT
  3085.     COLOR 15, 0
  3086.     PRINT " "; routine;
  3087.     COLOR 7, 0
  3088.     PRINT " has reported error";
  3089.     COLOR 30, 0
  3090.     PRINT STR$(errno)
  3091.     COLOR 7, 0
  3092.     PRINT
  3093.     SELECT CASE errno '                                                                                 which error number is being reported?
  3094.  
  3095.         ' general purpose errors for all subs/functions
  3096.  
  3097.         CASE 1
  3098.             PRINT "- the requested sprite does not exist"
  3099.         CASE 2
  3100.             PRINT "- invalid background restore setting supplied - valid settings are"
  3101.             PRINT "- : -1 (constant SL_SAVE)"
  3102.             PRINT "- :  0 (constant SL_NOSAVE)"
  3103.         CASE 3
  3104.             PRINT "- invalid flip setting supplied - valid settings are"
  3105.             PRINT "- : 0 (constant SL_NOFLIP or SL_RESET)"
  3106.             PRINT "- : 1 (constant SL_HORIZONTAL)"
  3107.             PRINT "- : 2 (constant SL_VERTICAL)"
  3108.             PRINT "- : 3 (constant SL_FLIPBOTH)"
  3109.         CASE 4
  3110.             PRINT "- invalid zoom level setting supplied"
  3111.             PRINT "- zoom level must be greater than zero (0)"
  3112.         CASE 5
  3113.             PRINT "- the specified sprite sheet is not in use or does not exist"
  3114.         CASE 6
  3115.             PRINT "- invalid row or column selected for specified sprite sheet"
  3116.         CASE 7
  3117.             PRINT "- invalid auto motion behavior requested - valid settings are"
  3118.             PRINT "- : -1 (constant SL_START)"
  3119.             PRINT "- :  0 (constant SL_STOP)"
  3120.         CASE 8
  3121.             PRINT "- invalid auto rotation behavior requested - valid settings are"
  3122.             PRINT "- : -1 (constant SL_START)"
  3123.             PRINT "- :  0 (constant SL_STOP)"
  3124.         CASE 9
  3125.             PRINT "- rotation speed must be between -359 and 359 degrees"
  3126.         CASE 10
  3127.             PRINT "- frame rate must be greater than zero (0)"
  3128.         CASE 11
  3129.             PRINT "- frame rate must be greater than zero (0) and less than or equal"
  3130.             PRINT "- to the global frame rate"
  3131.         CASE 12
  3132.             PRINT "- incorrect animation direction mode setting - valid settings are"
  3133.             PRINT "- : 0 (constant SL_FORWARD)"
  3134.             PRINT "- : 1 (constant SL_BACKWARD)"
  3135.             PRINT "- : 2 (constant CL_BACKFORTH"
  3136.         CASE 13
  3137.             PRINT "- invalid cell value given - it must be greater than 0 and less"
  3138.             PRINT "- than or equal to the total number of animation cells on a sheet"
  3139.         CASE 14
  3140.             PRINT "- invalid auto animation behavior requested - valid settings are"
  3141.             PRINT "- : -1 (constant SL_START)"
  3142.             PRINT "- :  0 (constant SL_STOP)"
  3143.         CASE 15
  3144.             PRINT "- animation has not been assigned to this sprite - use"
  3145.             PRINT "- SL_SET_ANIMATION to assign animation to this sprite"
  3146.         CASE 16
  3147.             PRINT "- this srpite is already under auto motion control"
  3148.             PRINT "- use SL_CHANGE_AUTOMOTION to disable auto motion control"
  3149.         CASE 17
  3150.             PRINT "- this sprite is already under auto rotation control"
  3151.             PRINT "- use SL_CHANGE_AUTOROTATION to disable auto rotation control"
  3152.         CASE 18
  3153.             PRINT "- this sprite is already under auto animation control"
  3154.             PRINT "- use SL_CHNAGE_AUTOANIMATION to disable auto animation control"
  3155.         CASE 19
  3156.             PRINT "- the destination cell must be greater than the starting cell"
  3157.         CASE 20
  3158.             PRINT "- invalid visible setting reguested - valid setting are"
  3159.             PRINT "- : -1 (constant SL_SHOW)"
  3160.             PRINT "- :  0 (constant SL_HIDE)"
  3161.         CASE 21
  3162.             PRINT "- the sprite being checked for collisions has no collision detection"
  3163.             PRINT "- enabled - use SL_XXXXXXXXXX to turn on collision detection for"
  3164.             PRINT "- the sprite"
  3165.         CASE 22
  3166.             PRINT "- the sprite being checked for a collision with has no collision"
  3167.             PRINT "- detection enabled - use SL_XXXXXXX to turn on collision detection"
  3168.             PRINT "- for the sprite"
  3169.         CASE 23
  3170.             PRINT "- both sprites must have the same collision detection method"
  3171.         CASE 24
  3172.             PRINT "- invalid collision detection mode requested - valid settings are"
  3173.             PRINT "- : 0 (constant SL_NODETECT or SL_RESET)"
  3174.             PRINT "- : 1 (constant SL_BOXDETECT)"
  3175.             PRINT "- : 2 (constant SL_ROUNDDETECT)"
  3176.             PRINT "- : 3 (constant SL_PIXELDETECT)"
  3177.         CASE 25
  3178.             PRINT "- invalid layer requested - the layer does not exist"
  3179.         CASE 26
  3180.             PRINT "- you must create at least one (1) layer"
  3181.  
  3182.             ' errors belonging to SL_NEW_SHEET (100 - 109)
  3183.  
  3184.         CASE 100
  3185.             PRINT "- "; CHR$(34); info; CHR$(34); " sprite sheet does not exist"
  3186.             PRINT "- check path or spelling"
  3187.         CASE 101
  3188.             PRINT "- invalid transparency setting supplied - valid settings are"
  3189.             PRINT "- : -1 (constant SL_USESHEET)"
  3190.             PRINT "- :  0 (constant SL_SET)"
  3191.             PRINT "- :  1 (constant SL_NONE)"
  3192.         CASE 102
  3193.             PRINT "- sprite width and/or height must be greater than zero"
  3194.         CASE 103
  3195.             PRINT "- selecting to use a sheet's transparency only works with .PNG files"
  3196.             PRINT "- the function was passed a "; info; " file."
  3197.         CASE 104
  3198.             PRINT "- there must be at least one column and one row of sprites on sheet"
  3199.             PRINT "- the sheet being loaded does not meet these minimums"
  3200.  
  3201.             'errors belonging to SL_NEW_SPRITE (110 - 119)
  3202.  
  3203.             'CASE 110
  3204.             '    PRINT "- the specified sprite sheet is not in use or does not exist"
  3205.             'CASE 111
  3206.             '    PRINT "- invalid row or column selected for specified sprite sheet"
  3207.         CASE 112
  3208.             PRINT "- invalid hardware / software setting supplied - valid settings are"
  3209.             PRINT "- : -1 (constant SL_SOFTWARE)"
  3210.             PRINT "- :  0 (constant SL_HARDWARE)"
  3211.         CASE 113
  3212.             PRINT "- there is no need to restore the background with hardware sprites"
  3213.             PRINT "- change background restore setting to zero (0) (constant SL_NOSAVE)"
  3214.  
  3215.     END SELECT
  3216.     COLOR 12, 0
  3217.     PRINT
  3218.     PRINT " See sprite library doumentation for further explanation."
  3219.     COLOR 7, 0
  3220.     DO: LOOP UNTIL INKEY$ = "" '                                                                        clear the keyboard buffer
  3221.     END '                                                                                               end the program
  3222.  
  3223.  
  3224.  
hands73x533.png
* hands73x533.png (Filesize: 3.47 KB, Dimensions: 219x533, Views: 194)
face.png
* face.png (Filesize: 54.83 KB, Dimensions: 551x551, Views: 191)
« Last Edit: September 29, 2018, 05:07:36 pm by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #50 on: September 29, 2018, 11:28:15 pm »
I've taken the clock demo code from above and added screen resizing to show how sprite zooming works in conjunction with it. If you resize the screen it will stay square and the clock continues to operate like nothing happens, only bigger or smaller depending on the resize.

Update: I smoothed the second hand out as well. It now uses all 360 degrees when spinning.

Code: QB64: [Select]
  1.  
  2. DIM handsheet AS INTEGER '      clock hand sprite sheet
  3. DIM hour AS INTEGER '           hour hand sprite
  4. DIM minute AS INTEGER '         minute hand sprite
  5. DIM second AS INTEGER '         second hand sprite
  6. DIM h AS INTEGER '              current hour value
  7. DIM m AS INTEGER '              current minute value
  8. DIM s AS INTEGER '              current second value
  9. DIM currentscreen AS LONG '     current SL_SCREEN
  10. DIM tempscreen AS LONG '        a temporary screen needed for resizing
  11. DIM swidth AS INTEGER '         original width of screen
  12. DIM sheight AS INTEGER '        original height of screen
  13. DIM center AS INTEGER '         x and y center point of screen
  14. DIM frame AS INTEGER '          frame counter
  15. DIM olds AS INTEGER '           the previous second
  16.  
  17. swidth = 551 '                                                                                          set screen variables
  18. sheight = 551
  19. center = 276
  20. SL_SCREEN swidth, sheight, 1 '                                                                          set window size and layers
  21. _DELAY .1 '                                                                                             need to wait for _RESIZE below
  22. tempscreen = _RESIZE '                                                                                  clear resize flag
  23.  
  24. _TITLE "Clock Demo" '                                                                                   give window a title
  25. handsheet = SL_NEW_SHEET("hands73x533.png", 73, 533, SL_SET, _RGB32(255, 0, 255)) '                     load the clock hands
  26. hour = SL_NEW_SPRITE(1, handsheet, 2, SL_HARDWARE, SL_NOSAVE) '                                         get the hour hand
  27. minute = SL_NEW_SPRITE(1, handsheet, 1, SL_HARDWARE, SL_NOSAVE) '                                       get the minute hand
  28. second = SL_NEW_SPRITE(1, handsheet, 3, SL_HARDWARE, SL_NOSAVE) '                                       get the second hand
  29. _PUTIMAGE , _LOADIMAGE("face.png", 32) '                                                                display the clock face
  30. SL_SET_FRAMERATE 6 '                                                                                    set the global frame rate
  31.     _LIMIT SL_GET_FRAMERATE '                                                                           maintain global frame rate
  32.     h = VAL(TIME$) '                                                                                    get current hour value
  33.     IF h > 11 THEN h = h - 12 '                                                                         keep a 12 hour clock
  34.     m = VAL(MID$(TIME$, 4, 2)) '                                                                        get current minute value
  35.     s = VAL(MID$(TIME$, 7, 2)) '                                                                        get current second value
  36.     frame = frame + 1 '                                                                                 increment frame counter
  37.     IF s <> olds THEN '                                                                                 new second?
  38.         frame = 0 '                                                                                     yes, reset frame counter
  39.         olds = s '                                                                                      remember this second value
  40.     END IF
  41.     SL_ROTATE_SPRITE hour, 30 * h + m \ 2 '                                                             rotate hour hand into position
  42.     SL_ROTATE_SPRITE minute, 6 * m + s \ 10 '                                                           rotate minute hand into position
  43.     SL_ROTATE_SPRITE second, 6 * s + frame '                                                                    rotate second hand into position
  44.     SL_PUT_SPRITE center, center, hour '                                                                display the hour hand
  45.     SL_PUT_SPRITE center, center, minute '                                                              display the minute hand
  46.     SL_PUT_SPRITE center, center, second '                                                              display the second hand
  47.     IF _RESIZE THEN '                                                                                   did user resize screen?
  48.         currentscreen = _SOURCE '                                                                       yes, get the current screen pointer
  49.         tempscreen = _COPYIMAGE(_SOURCE, 32) '                                                          make a copy of the current screen
  50.         SCREEN tempscreen '                                                                             make the copy active
  51.         _FREEIMAGE currentscreen '                                                                      free the old current screen
  52.         SL_SCREEN _RESIZEWIDTH, _RESIZEWIDTH, 1 '                                                       create the new current screen (square _RESIZEWIDTH)
  53.         _PUTIMAGE (0, 0)-(_WIDTH(_SOURCE) - 1, _HEIGHT(_SOURCE) - 1), _LOADIMAGE("face.png", 32) '      stretch the clock face onto it
  54.         _FREEIMAGE tempscreen '                                                                         no longer need copy of old current screen
  55.         SL_SET_ZOOM hour, _WIDTH(_SOURCE) / swidth * 100 '                                              zoom the sprites to match new dimensions
  56.         SL_SET_ZOOM minute, _WIDTH(_SOURCE) / swidth * 100
  57.         SL_SET_ZOOM second, _WIDTH(_SOURCE) / swidth * 100
  58.         center = _WIDTH(_SOURCE) \ 2 '                                                                  new center point for clock hands
  59.     END IF
  60.     SL_DISPLAY '                                                                                        merge layers and display
  61. LOOP UNTIL _KEYHIT '                                                                                    leave when key hit
  62. SL_FREE_SPRITE hour '                                                                                   free sprites from memory
  63. SL_FREE_SPRITE minute
  64. SL_FREE_SPRITE second
« Last Edit: September 30, 2018, 12:15:31 am by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Sprite Library Revisited
« Reply #51 on: September 30, 2018, 09:39:44 am »
Hi Terry
your clock demo is very fine
like you can see from the attachment file image...

it remember me the old fashion clock of the ancient time :-)

Waiting the evolution of your creature Sprite Library I'll take open eyes
demo clock.jpg
* demo clock.jpg (Filesize: 237.17 KB, Dimensions: 1366x713, Views: 138)
Programming isn't difficult, only it's  consuming time and coffee

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #52 on: October 18, 2018, 03:28:49 am »
It's been a while since I posted an update. I am still working on the new library. I have most of the pieces I want in place, it's now time to go through those pieces and optimize the code. I purchased a wide carriage dot matrix printer because the code is getting LONG. At last count I was over 4000 lines. To this end during the optimization I am keeping code to 132 characters per line to match the printer.

Some additions I made since the last update:
- SIN and COSINE tables are now precalculated and used to speed up math routines.
- Sprite rotation table saving/loading is now done with one GET and PUT statement speeding it up drastically.
- Took a page from Python and designed data types to use RECT (rectangular) structures for easier manipulation (TOP, LEFT, RIGHT, BOTTOM).
- The programmer now has the option to have the sprite rotation file built during a sprite sheet load or have sprites done individually as needed.
- Saving of _SOURCE and _DEST throughout the code is now performed using a FILO stack structure.

Here is the newly designed code I have completed so far. Much leaner and cleaner. Much, much more to come.

Code: QB64: [Select]
  1.  
  2. CONST SL_NOTRANSPARENCY = _RGB32(2, 4, 6) ' the chance of a sheet using this as a transparent color are 16 million to 1
  3. CONST SL_WHITE = _RGB32(255, 255, 255)
  4.  
  5. CONST SL_FALSE = 0 '                    boolean truth test
  6. CONST SL_TRUE = -1 '                    boolean truth test
  7. CONST SL_PUSH = -1 '                    push _DEST and _SOURCE into stack
  8. CONST SL_POP = 0 '                      pop _DEST and _SOURCE out of stack
  9.  
  10.  
  11. TYPE SL_RECTANGLE '---------------- A RECTANGULAR STRUCTURE -----------------------------------------------------------------------
  12.     left AS INTEGER '               the left x coordinate       *  This structure should ALWAYS be used to describe any           *
  13.     right AS INTEGER '              the right x coordinate      *  rectangular object contained within the library. The screen,   *
  14.     top AS INTEGER '                the top y coordinate        *  layers, sprites, and objects are examples of rectangular       *
  15.     bottom AS INTEGER '             the bottom y coordinate     *  structures.                                                    *
  16.     centerx AS INTEGER '            the center x coordinate     *                                                                 *
  17.     centery AS INTEGER '            the center y coordinate     *                                                                 *
  18.     width AS INTEGER '              the width of rectangle      *                                                                 *
  19.     height AS INTEGER '             the height of rectangle     *                                                                 *
  20. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  21.  
  22. TYPE SL_COLLISION '---------------- COLLISION BOX STRUCTURE -----------------------------------------------------------------------
  23.     collision AS SL_RECTANGLE '     collision box offsets
  24. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  25.  
  26. TYPE SL_RECT '--------------------- RECTANGULAR STRUCTURES ------------------------------------------------------------------------
  27.     '                                                           *  -------------------------------------------------------------  *
  28.     offset AS SL_RECTANGLE '        rectangular offset values   *  These should be considered STATIC values. Once they have been  *
  29.     '                                                           *  set they should not be changed. These are used as offsets to   *
  30.     '                                                           *  rectangular objects placed on the screen. TOP and LEFT will    *
  31.     '                                                           *  ALWAYS be zero (0). RIGHT and BOTTOM will ALWAYS equal         *
  32.     '                                                           *  WIDTH - 1 and HEIGHT - 1 respectively.                         *
  33.     '                                                           *  WIDTH and HEIGHT respectively.                                 *
  34.     '                                                           *  -------------------------------------------------------------  *
  35.     '                                                           *  -------------------------------------------------------------  *
  36.     screen AS SL_RECTANGLE '        rectangular screen values   *  These should be considered as DYNAMIC values. The values       *
  37.     '                                                           *  contained here will be computed from the offsets above to      *
  38.     '                                                           *  obtain screen coordinates. These will change every time an     *
  39.     '                                                           *  object is moved based on the CENTERX and CENTERY values        *
  40.     '                                                           *  passed in.                                                     *
  41.     '                                                           *  -------------------------------------------------------------  *
  42.     '                                                           *  -------------------------------------------------------------  *
  43.     collision AS SL_RECTANGLE '     collision box offsets       *  These should be considered STATIC values. Once they have been  *
  44.     '                                                           *  set they should not be changed. These are used as offsets to   *
  45.     '                                                           *  rectangular object collision boxes within the sprite itself.   *
  46.     '                                                           *  Add these offsets to 'screen' above to identify the collision  *
  47.     '                                                           *  rectangular area within the sprite.                            *
  48.     '                                                           *  -------------------------------------------------------------  *
  49. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  50.  
  51. TYPE SL_ANGLE '-------------------- PRECALCULATED SPRITE ROTATION ANGLE DATABASE --------------------------------------------------
  52.     inuse AS _BYTE '                -1 if array index in use
  53.     rect AS SL_COLLISION '          collision box offsets
  54.     px0 AS INTEGER '                rotation coordinates
  55.     px1 AS INTEGER '                (used by _MAPTRIANGLE)
  56.     px2 AS INTEGER
  57.     px3 AS INTEGER
  58.     py0 AS INTEGER
  59.     py1 AS INTEGER
  60.     py2 AS INTEGER
  61.     py3 AS INTEGER
  62. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  63.  
  64. TYPE SL_DEGREE '------------------- PRECALCULATED ROTATION DEGREE TABLE -----------------------------------------------------------
  65.     sin AS SINGLE '                 rotating sprites
  66.     cos AS SINGLE '                 rotating sprites
  67.     sinmap AS SINGLE '              maptriangle rotation
  68.     cosmap AS SINGLE '              maptriangle rotation
  69. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  70.  
  71. TYPE SL_SHEET '-------------------- SPRITE SHEET DATABASE -------------------------------------------------------------------------
  72.     rect AS SL_COLLISION '          collision box offsets
  73.     image AS LONG '                 default sprite image
  74.     mask AS LONG '                  default sprite mask
  75.     anglekey AS INTEGER '           pointer to SL_angle
  76. END TYPE '-------------------------------------------------------------------------------------------------------------------------
  77.  
  78. TYPE SL_SPRITE
  79.     rect AS SL_RECT '               rectangular structures
  80.     zoom AS INTEGER
  81.  
  82. ' define arrays
  83.  
  84. REDIM SL_sheet(0, 0) AS SL_SHEET '      sprite sheet sprite database
  85. REDIM SL_angle(1, 359) AS SL_ANGLE '    precalculated rotation table
  86. DIM SL_degree(359) AS SL_DEGREE '       precalculated SIN/COS table
  87.  
  88.  
  89. ' main code (for testing)
  90.  
  91. DIM sprite AS SL_SPRITE
  92. DIM rect AS SL_RECTANGLE
  93. DIM dkong AS INTEGER
  94.  
  95. SL_START '                                                                  initialize library
  96. dkong = SL_LOAD_SHEET("dkong.png", 64, 64, _RGB32(255, 0, 255), SL_TRUE) '  load a sprite sheet
  97. SCREEN _NEWIMAGE(640, 480, 32) '                                            set up a screen
  98. _PUTIMAGE (100, 100), SL_sheet(dkong, 1).image '                            make sure SL_SHEET is getting images
  99. LINE (SL_sheet(dkong, 1).rect.collision.left + 100, SL_sheet(dkong, 1).rect.collision.top + 100)-_
  100.      (SL_sheet(dkong, 1).rect.collision.right + 100, SL_sheet(dkong, 1).rect.collision.bottom + 100),_
  101.      _RGB32(255, 255, 255), B '                                             draw the collision box
  102.  
  103.  
  104. '----------------------------------------------------------------------------------------------------------------------------------
  105. SUB SL_START ()
  106.     '------------------------------------------------------------------------------------------------------------------------------
  107.  
  108.     SHARED SL_degree() AS SL_DEGREE '   precalculated SIN/COS table
  109.     DIM degree AS INTEGER '             degree counter
  110.  
  111.     ' precalculate SIN/COS values and place in table
  112.  
  113.     DO '                                                                                    cycle 0 to 359 degrees
  114.         SL_degree(degree).sin = SIN(degree * .017453292) '                                  SIN of angle
  115.         SL_degree(degree).cos = -COS(degree * .017453292) '                                 COS of angle
  116.         'SL_degree(degree).sinmap = SIN(-degree / 57.2957795131) '                           MAPTRIANGLE SIN of angle
  117.         'SL_degree(degree).cosmap = COS(-degree / 57.2957795131) '                           MAPTRIANGLE COS of angle
  118.         SL_degree(degree).sinmap = SIN(-degree * .017453292) '                              MAPTRIANGLE SIN of angle
  119.         SL_degree(degree).cosmap = COS(-degree * .017453292) '                              MAPTRIANGLE COS of angle
  120.         degree = degree + 1 '                                                               increment degree counter
  121.     LOOP UNTIL degree = 360 '                                                               leave when all degrees calculated
  122.  
  123.  
  124. '----------------------------------------------------------------------------------------------------------------------------------
  125. FUNCTION SL_LOAD_SHEET (filename AS STRING, swidth AS INTEGER, sheight AS INTEGER, colour AS _UNSIGNED LONG, rotate AS INTEGER)
  126.     '------------------------------------------------------------------------------------------------------------------------------
  127.  
  128.     SHARED SL_sheet() AS SL_SHEET '     master sheet array
  129.     SHARED SL_angle() AS SL_ANGLE '     precalculated rotation angle array
  130.     REDIM SL_temp(0, 0) AS SL_ANGLE '   temporary rotation angle array
  131.     DIM clearcolor AS _UNSIGNED LONG '  transparency color of sprite sheet
  132.     DIM bounds AS SL_RECTANGLE '        rectangle boundaries
  133.     DIM transparent AS INTEGER '        -1 (TRUE) if sprite sheet contains transparency
  134.     DIM celltotal AS INTEGER '          total number of cells on sheet
  135.     DIM colcount AS INTEGER '           column counter
  136.     DIM rowcount AS INTEGER '           row counter
  137.     DIM anglekey AS INTEGER '           key index pointer to angle array
  138.     DIM filenum AS INTEGER '            the next free file handle
  139.     DIM preload AS INTEGER '            -1 (SL_TRUE) if rotation data file was loaded
  140.     DIM columns AS INTEGER '            number of columns on sheet
  141.     DIM rows AS INTEGER '               number of rows on sheet
  142.     DIM handle AS INTEGER '             next available sheet handle pointer
  143.     DIM rotfile AS STRING '             rotation data file name
  144.     DIM degree AS INTEGER '             degree counter
  145.     DIM cell AS INTEGER '               number of cells currently assigned in SL_sheet, and a cell counter
  146.     DIM sheet AS LONG '                 sheet image
  147.  
  148.     ' load sheet, determine rows / columns / cells, create an index in sheet array
  149.  
  150.     sheet = _LOADIMAGE(filename, 32) '                                                      load sprite sheet
  151.     columns = _WIDTH(sheet) \ swidth: rows = _HEIGHT(sheet) \ sheight '                     calculate number of columns and rows
  152.     celltotal = rows * columns '                                                            calculate number of cells
  153.     cell = UBOUND(SL_sheet, 2) '                                                            current number of cells in sheet array
  154.     IF celltotal > cell THEN cell = celltotal '                                             increase cells in sheet array
  155.     handle = UBOUND(SL_sheet) + 1 '                                                         get new sheet's handle pointer value
  156.     REDIM _PRESERVE SL_sheet(handle, cell) AS SL_SHEET '                                    create a new sheet entry in array
  157.  
  158.     ' load rotation data file if it exists
  159.  
  160.     IF rotate THEN '                                                                        precalculate rotations?
  161.         rotfile = LEFT$(filename, INSTR(filename, ".")) + "rot" '                           yes, create name of rotation file
  162.         filenum = FREEFILE '                                                                get next free file handle
  163.         REDIM SL_temp(celltotal, 359) AS SL_ANGLE '                                         increase array size to match sheet size
  164.         IF _FILEEXISTS(rotfile) THEN '                                                      does the rotation file exist?
  165.             OPEN rotfile FOR BINARY AS #filenum '                                           open the rotation file
  166.             GET #filenum, , SL_temp() '                                                     get the rotation data
  167.             CLOSE #filenum '                                                                close the file
  168.             anglekey = UBOUND(SL_angle) + 1 '                                               beginning index in array
  169.             REDIM _PRESERVE SL_angle(UBOUND(SL_angle) + UBOUND(sl_temp), 359) AS SL_ANGLE ' increase angle array to hold ne data
  170.             preload = SL_TRUE '                                                             remember that is has been loaded
  171.         END IF
  172.     END IF
  173.  
  174.     ' get or apply transparency to the sprite sheet
  175.  
  176.     IF colour <> SL_NOTRANSPARENCY THEN '                                                   use transparency?
  177.         transparent = SL_GetTransparentColor(sheet, clearcolor) '                           yes, get transparent layer of image
  178.         IF NOT transparent THEN '                                                           was a transparent color found?
  179.             _CLEARCOLOR colour, sheet '                                                     no, apply the supplied color
  180.             clearcolor = _CLEARCOLOR(sheet) '                                               get the transparent value from sheet
  181.             transparent = SL_TRUE '                                                         sheet now contains transparency
  182.         END IF
  183.     END IF
  184.  
  185.     ' cycle through the sheet and create related data
  186.  
  187.     DO '                                                                                    cycle through sheet's columns
  188.         colcount = colcount + 1 '                                                           increment column counter
  189.         rowcount = 0 '                                                                      reset row counter
  190.         DO '                                                                                cycle through sheet's rows
  191.  
  192.             ' get image from sheet and place in array
  193.  
  194.             rowcount = rowcount + 1 '                                                       increment row counter
  195.             cell = (rowcount - 1) * columns + colcount '                                    calculate current sprite's cell number
  196.             SL_sheet(handle, cell).image = _NEWIMAGE(swidth, sheight, 32) '                 create sprite image holder
  197.             bounds.left = (colcount - 1) * swidth '                                         calculate left x sprite location
  198.             bounds.top = (rowcount - 1) * sheight '                                         calculate top y sprite location
  199.             bounds.right = bounds.left + swidth - 1 '                                       calculate right x sprite location
  200.             bounds.bottom = bounds.top + sheight - 1 '                                      calculate bottom y sprite location
  201.             _PUTIMAGE , sheet, SL_sheet(handle, cell).image, (bounds.left, bounds.top)-_
  202.                                                              (bounds.right, bounds.bottom) 'get image from sheet
  203.  
  204.             ' create image mask and determine collision boundaries if necessary
  205.  
  206.             IF transparent THEN '                                                           sprite contain transparent color?
  207.                 SL_sheet(handle, cell).mask = _NEWIMAGE(swidth, sheight, 32) '              yes, create sprite mask image
  208.                 bounds.left = swidth - 1
  209.                 bounds.top = sheight - 1
  210.                 bounds.right = 0
  211.                 bounds.left = 0
  212.                 bounds.width = swidth
  213.                 bounds.height = sheight
  214.                 SL_GetBounds SL_sheet(handle, cell).image, SL_sheet(handle, cell).mask, clearcolor, bounds ' get collision bounds
  215.                 '                                                                           collide with boundaries only
  216.                 SL_sheet(handle, cell).rect.collision.left = bounds.left '                  * ----------------------------
  217.                 SL_sheet(handle, cell).rect.collision.top = bounds.top '                    *
  218.                 SL_sheet(handle, cell).rect.collision.right = bounds.right '                *
  219.                 SL_sheet(handle, cell).rect.collision.bottom = bounds.bottom '              * NOTE: These are OFFSETS
  220.                 SL_sheet(handle, cell).rect.collision.width = bounds.right - bounds.left '  *       NOT actual coordinates
  221.                 SL_sheet(handle, cell).rect.collision.height = bounds.bottom - bounds.top ' *
  222.                 SL_sheet(handle, cell).rect.collision.centerx = bounds.left + (bounds.right - bounds.left) / 2 '*
  223.                 SL_sheet(handle, cell).rect.collision.centery = bounds.top + (bounds.bottom - bounds.top) / 2 ' * --------
  224.             ELSE '                                                                          collide with entire sprite
  225.                 SL_sheet(handle, cell).rect.collision.left = 0 '                            * ----------------------------
  226.                 SL_sheet(handle, cell).rect.collision.top = 0 '                             *
  227.                 SL_sheet(handle, cell).rect.collision.right = swidth - 1 '                  *
  228.                 SL_sheet(handle, cell).rect.collision.bottom = sheight - 1 '                * NOTE: These are OFFSETS
  229.                 SL_sheet(handle, cell).rect.collision.width = swidth '                      *       NOT actual coordinates
  230.                 SL_sheet(handle, cell).rect.collision.height = sheight '                    *
  231.                 SL_sheet(handle, cell).rect.collision.centerx = bounds.left + swidth / 2 '  *
  232.                 SL_sheet(handle, cell).rect.collision.centery = bounds.top + sheight / 2 '  * ----------------------------
  233.             END IF
  234.  
  235.             ' create / insert precalculated rotation data
  236.  
  237.             IF rotate THEN '                                                                precalculate rotation data?
  238.                 IF preload THEN '                                                           yes, has it already been loaded?
  239.                     degree = 0 '                                                            reset degree counter
  240.                     DO '                                                                    cycle through 360 degrees
  241.                         SL_angle(anglekey, degree) = SL_temp(cell, degree) '                insert loaded information into array
  242.                         degree = degree + 1 '                                               increment degree counter
  243.                     LOOP UNTIL degree = 360 '                                               leave when all degrees processed
  244.                     SL_sheet(handle, cell).anglekey = anglekey '                            record the array index key
  245.                     anglekey = anglekey + 1 '                                               increment array index key
  246.                 ELSE '                                                                      no file was preloaded
  247.                     SL_sheet(handle, cell).anglekey = SL_RotationPrecalc(handle, cell, clearcolor) 'calculate rotation information
  248.                     degree = 0 '                                                            reset degree counter
  249.                     DO '                                                                    cycle through 360 degrees
  250.                         SL_temp(cell, degree) = SL_angle(anglekey, degree) '                save the rotation data to temp array
  251.                         degree = degree + 1 '                                               increment degree counter
  252.                     LOOP UNTIL degree = 360 '                                               leave when all degrees processed
  253.                 END IF
  254.             END IF
  255.         LOOP UNTIL rowcount = rows '                                                        leave when all rows checked
  256.     LOOP UNTIL colcount = columns '                                                         leave when all columns checked
  257.  
  258.     ' save precalculated rotation data to a file
  259.  
  260.     IF rotate AND (NOT preload) THEN '                                                      rotation data need saved?
  261.         OPEN rotfile FOR BINARY AS #filenum '                                               yes, open the file
  262.         PUT #filenum, , SL_temp() '                                                         write the rotation data
  263.         CLOSE #filenum '                                                                    close the file
  264.         REDIM SL_temp(0, 0) AS SL_ANGLE '                                                   clear temporary array
  265.     END IF
  266.     _FREEIMAGE sheet '                                                                      remove sprite sheet image from memory
  267.     SL_LOAD_SHEET = handle '                                                                return handle pointing to this sheet
  268.  
  269.  
  270. '----------------------------------------------------------------------------------------------------------------------------------
  271. FUNCTION SL_RotationPrecalc (sheet AS INTEGER, cell AS INTEGER, clearcolor AS _UNSIGNED LONG)
  272.     '------------------------------------------------------------------------------------------------------------------------------
  273.  
  274.     SHARED SL_sheet() AS SL_SHEET '     master sprite sheet array
  275.     SHARED SL_angle() AS SL_ANGLE '     master sprite angle array
  276.     SHARED SL_degree() AS SL_DEGREE '   precalculated SIN/COS table
  277.     DIM bounds AS SL_RECTANGLE '        rectangle boundries
  278.     DIM rotatedsprite AS LONG '         rotated sprite image
  279.     DIM anglekey AS INTEGER '           angle array index pointer
  280.     DIM swidth AS INTEGER '             width of sprite
  281.     DIM sheight AS INTEGER '            height of sprite
  282.     DIM xoffset AS INTEGER '            used to center sprite on rotated image
  283.     DIM yoffset AS INTEGER
  284.     DIM degree AS INTEGER '             degree counter
  285.     DIM polar AS INTEGER '              polar coordinate counter
  286.     DIM px(3) AS SINGLE '               _MAPTRIANGLE coordinates
  287.     DIM py(3) AS SINGLE
  288.     DIM sinr AS SINGLE, cosr AS SINGLE 'coordinate rotation calculations
  289.     DIM x2 AS SINGLE, y2 AS SINGLE '    rotated polar coordinate positions
  290.     DIM px0 AS SINGLE, px1 AS SINGLE '  polar coordinates
  291.     DIM px2 AS SINGLE, px3 AS SINGLE
  292.     DIM py0 AS SINGLE, py1 AS SINGLE
  293.     DIM py2 AS SINGLE, py3 AS SINGLE
  294.  
  295.     DO '                                                                                    cycle through angle array
  296.         anglekey = anglekey + 1 '                                                           increment index key pointer
  297.     LOOP UNTIL (SL_angle(anglekey, 0).inuse = SL_FALSE) OR (anglekey = UBOUND(SL_angle)) '  leave when available index found
  298.     IF SL_angle(anglekey, 0).inuse = SL_TRUE THEN '                                         is there no available index?
  299.         anglekey = anglekey + 1 '                                                           yes, increment index key pointer
  300.         REDIM _PRESERVE SL_angle(anglekey, 359) AS SL_ANGLE '                               increase size of angle array by one
  301.     END IF
  302.     SL_angle(anglekey, 0).inuse = SL_TRUE '                                                 mark this array index as in use
  303.     swidth = _WIDTH(SL_sheet(sheet, cell).image) '                                          get width of sprite image
  304.     sheight = _HEIGHT(SL_sheet(sheet, cell).image) '                                        get height of sprite image
  305.  
  306.     ' calculate _MAPTRIANGLE rotated coordinates
  307.  
  308.     DO
  309.         px(0) = -swidth / 2: py(0) = -sheight / 2: px(1) = px(0): py(1) = sheight / 2 '     specifiy _MAPTRIANGLE coordinates
  310.         px(2) = swidth / 2: py(2) = py(1): px(3) = px(2): py(3) = py(0)
  311.         sinr = SL_degree(degree).sinmap '                                                   get coordinate rotation angles
  312.         cosr = SL_degree(degree).cosmap '                                                   from precalculated COS/SIN table
  313.         bounds.left = 0: bounds.top = 0: bounds.right = 0: bounds.bottom = 0: polar = 0 '   set initial boundary markers
  314.         DO '                                                                                cycle through polar coordinates
  315.             x2 = (px(polar) * cosr + sinr * py(polar)) '                                    compute new polar coordinate location
  316.             y2 = (py(polar) * cosr - px(polar) * sinr) '                                    compute new polar coordinate location
  317.             px(polar) = x2 '                                                                save the new polar coordinate
  318.             py(polar) = y2 '                                                                save the new polar coordinate
  319.             IF px(polar) < bounds.left THEN bounds.left = px(polar) '                       get left x value
  320.             IF px(polar) > bounds.right THEN bounds.right = px(polar) '                     get right x value
  321.             IF py(polar) < bounds.top THEN bounds.top = py(polar) '                         get top y value
  322.             IF py(polar) > bounds.bottom THEN bounds.bottom = py(polar) '                   get bottom y value
  323.             polar = polar + 1 '                                                             increment counter
  324.         LOOP UNTIL polar = 4 '                                                              leave when all coordinates calculated
  325.         bounds.width = bounds.right - bounds.left + 1 '                                     calculate rotated width
  326.         bounds.height = bounds.bottom - bounds.top + 1 '                                    calculate rotated height
  327.         xoffset = bounds.width \ 2 '                                                        calculate x offset
  328.         yoffset = bounds.height \ 2 '                                                       calculate y offset
  329.         px0 = px(0) + xoffset: px1 = px(1) + xoffset '                                      add offsets to rotated sprite
  330.         px2 = px(2) + xoffset: px3 = px(3) + xoffset '                                      to center sprite onto the rotated
  331.         py0 = py(0) + yoffset: py1 = py(1) + yoffset '                                      image
  332.         py2 = py(2) + yoffset: py3 = py(3) + yoffset
  333.         rotatedsprite = _NEWIMAGE(bounds.width, bounds.height, 32) '                        create rotated sprite image holder
  334.  
  335.         ' map image onto rotated sprite
  336.  
  337.         _MAPTRIANGLE (0, 0)-(0, sheight - 1)-(swidth - 1, sheight - 1), SL_sheet(sheet, cell).image_
  338.                      TO(px0, py0)-(px1, py1)-(px2, py2), rotatedsprite
  339.         _MAPTRIANGLE (0, 0)-(swidth - 1, 0)-(swidth - 1, sheight - 1), SL_sheet(sheet, cell).image_
  340.                      TO(px0, py0)-(px3, py3)-(px2, py2), rotatedsprite
  341.  
  342.         ' get rotated collision boundaries
  343.  
  344.         bounds.left = bounds.width - 1: bounds.top = bounds.height - 1 '                    set intitial boundary markers
  345.         bounds.right = 0: bounds.bottom = 0
  346.         SL_GetBounds rotatedsprite, 0, clearcolor, bounds '                                 get collision boundaries
  347.         SL_angle(anglekey, degree).rect.collision.left = bounds.left '                      * ----------------------------
  348.         SL_angle(anglekey, degree).rect.collision.top = bounds.top '                        *
  349.         SL_angle(anglekey, degree).rect.collision.right = bounds.right '                    *
  350.         SL_angle(anglekey, degree).rect.collision.bottom = bounds.bottom '                  * NOTE: These are OFFSETS
  351.         SL_angle(anglekey, degree).rect.collision.width = bounds.right - bounds.left '      *       NOT actual coordinates
  352.         SL_angle(anglekey, degree).rect.collision.height = bounds.bottom - bounds.top '     *
  353.         SL_angle(anglekey, degree).rect.collision.centerx = bounds.left + (bounds.right - bounds.left) / 2 '*
  354.         SL_angle(anglekey, degree).rect.collision.centery = bounds.top + (bounds.bottom - bounds.top) / 2 ' * -------------
  355.         SL_angle(anglekey, degree).px0 = px0 '                                              save _MAPTRIANGLE coordinates
  356.         SL_angle(anglekey, degree).px1 = px1
  357.         SL_angle(anglekey, degree).px2 = px2
  358.         SL_angle(anglekey, degree).px3 = px3
  359.         SL_angle(anglekey, degree).py0 = py0
  360.         SL_angle(anglekey, degree).py1 = py1
  361.         SL_angle(anglekey, degree).py2 = py2
  362.         SL_angle(anglekey, degree).py3 = py3
  363.         degree = degree + 1 '                                                               increment degree counter
  364.     LOOP UNTIL degree = 360 '                                                               leave when all degrees processed
  365.     SL_RotationPrecalc = anglekey '                                                         return array index pointer
  366.  
  367.  
  368. '----------------------------------------------------------------------------------------------------------------------------------
  369. FUNCTION SL_GetTransparentColor (image AS LONG, clearcolor AS _UNSIGNED LONG)
  370.     '------------------------------------------------------------------------------------------------------------------------------
  371.  
  372.     ' usage  : exists = SL_GetTransparentColor(image, clearcolor)
  373.     '
  374.     ' returns: exists     =  0 (SL_FALSE) if no transparent color found, -1 (SL_TRUE) if a transparent color found
  375.     '          clearcolor =  unchanged if no transparent color found or the transparent color if one is found
  376.  
  377.     DIM pixel AS _UNSIGNED LONG '       color of pixel
  378.     DIM x AS INTEGER, y AS INTEGER '    column and row counters
  379.     DIM tempimage AS LONG '             temporary image used to identify transparent color
  380.  
  381.     SL_DestSource SL_PUSH '                                                                 save current _DEST and _SOURCE
  382.     _SOURCE image '                                                                         read from image
  383.     DO '                                                                                    cycle through image
  384.         pixel = POINT(x, y) '                                                               get the next pixel
  385.         IF _ALPHA32(pixel) = 0 THEN '                                                       is it transparent?
  386.             tempimage = _NEWIMAGE(1, 1, 32) '                                               yes, create a temp image
  387.             _CLEARCOLOR pixel, tempimage '                                                  apply the transparent value to it
  388.             clearcolor = _CLEARCOLOR(tempimage) '                                           get transparent value from temp image
  389.             _FREEIMAGE tempimage '                                                          remove temp image from memory
  390.             EXIT DO '                                                                       leave the loop, no reason to continue
  391.         END IF
  392.         x = x + 1 '                                                                         move to the next column
  393.         IF x > _WIDTH(image) THEN x = 0: y = y + 1 '                                        move to the next row if necessary
  394.     LOOP UNTIL y > _HEIGHT(image) '                                                         leave when entire sheet checked
  395.     IF _ALPHA32(pixel) = 0 THEN SL_GetTransparentColor = SL_TRUE '                          return -1 if transparent color found
  396.     SL_DestSource SL_POP '                                                                  restore previous _DEST and _SOURCE
  397.  
  398.  
  399. '----------------------------------------------------------------------------------------------------------------------------------
  400. SUB SL_GetBounds (image AS LONG, mask AS LONG, clearcolor AS _UNSIGNED LONG, bounds AS SL_RECTANGLE)
  401.     '------------------------------------------------------------------------------------------------------------------------------
  402.  
  403.     ' NOTE: bounds will be modified with new boundary coordinates
  404.  
  405.     DIM x AS INTEGER, y AS INTEGER '    column and row counters
  406.  
  407.     SL_DestSource SL_PUSH '                                                                 save current _DEST and _SOURCE
  408.     _SOURCE image '                                                                         read from image
  409.     IF mask THEN _DEST mask '                                                               write to mask if present
  410.     DO '                                                                                    cycle through columns
  411.         y = 0 '                                                                             reset row counter
  412.         DO '                                                                                cycle through rows
  413.             IF POINT(x, y) <> clearcolor THEN '                                             is this pixel transparent?
  414.                 IF x < bounds.left THEN bounds.left = x '                                   no, set left-most image pixel seen
  415.                 IF y < bounds.top THEN bounds.top = y '                                     set top-most image pixel seen
  416.                 IF x > bounds.right THEN bounds.right = x '                                 set right-most image pixel seen
  417.                 IF y > bounds.bottom THEN bounds.bottom = y '                               set bottom-most image pixel seen
  418.             ELSE '                                                                          yes, this is a transparent pixel
  419.                 IF mask THEN PSET (x, y), SL_WHITE '                                        draw as white on the image mask
  420.             END IF
  421.             y = y + 1 '                                                                     increment row counter
  422.         LOOP UNTIL y = bounds.height '                                                      leave when all rows scanned
  423.         x = x + 1 '                                                                         increment column counter
  424.     LOOP UNTIL x = bounds.width '                                                           leave when all columns scanned
  425.     SL_DestSource SL_POP '                                                                  restore previous _DEST and _SOURCE
  426.  
  427.  
  428. '----------------------------------------------------------------------------------------------------------------------------------
  429. SUB SL_DestSource (action AS INTEGER)
  430.     '------------------------------------------------------------------------------------------------------------------------------
  431.  
  432.     ' creates a FILO (First In Last Out) stack for storing source and destination values
  433.  
  434.     STATIC stack(0) AS LONG '           FILO stack (values retained between calls)
  435.  
  436.     SELECT CASE action '                                                                    push or pop stack?
  437.         CASE SL_PUSH '                                                                      pushing
  438.             REDIM _PRESERVE stack(UBOUND(stack) + 2) AS LONG '                              increase stack size
  439.             stack(UBOUND(stack) - 1) = _SOURCE '                                            save current source
  440.             stack(UBOUND(stack)) = _DEST '                                                  save current destination
  441.         CASE SL_POP '                                                                       popping in reverse order
  442.             _DEST stack(UBOUND(stack)) '                                                    restore destination
  443.             _SOURCE stack(UBOUND(stack) - 1) '                                              restore source
  444.             REDIM _PRESERVE stack(UBOUND(stack) - 2) AS LONG '                              decrease stack size
  445.     END SELECT
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455. ' subs and functions below ideas for now
  456.  
  457.  
  458. SUB SL_ComputeRectScreen (rect AS SL_RECT, centerx AS INTEGER, centery AS INTEGER)
  459.  
  460.     ' Calculates a RECT structures onscreen values using offset values
  461.     ' CENTERX and CENTERY always assumed to be the only values used
  462.     ' Any RECT structure supplied will be MODIFIED and sent back
  463.  
  464.     rect.screen.left = centerx - rect.offset.centerx
  465.     rect.screen.right = rect.screen.left + rect.offset.width
  466.     rect.screen.top = centery - rect.offset.centery
  467.     rect.screen.bottom = rect.screen.top + rect.offset.height
  468.     rect.screen.width = rect.screen.right - rect.screen.left
  469.     rect.screen.height = rect.screen.bottom - rect.screen.top
  470.     rect.screen.centerx = centerx
  471.     rect.screen.centery = centery
  472.  
  473.  
  474.  
  475. SUB SL_ComputeRectOffset (rect AS SL_RECTANGLE)
  476.  
  477.     ' Calculates a RECT structure's offset values
  478.     ' LEFT and TOP always assumed to be zero (0)
  479.     ' Any RECT structure supplied will be MODIFIED and sent back
  480.  
  481.     IF rect.left + rect.top THEN BEEP: END '                        left and top must be zero
  482.  
  483.     IF rect.width THEN '                                            if width is supplied
  484.         rect.right = rect.width '                                   then calculate right
  485.         rect.centerx = rect.width / 2 '                             and center x
  486.     ELSEIF rect.centerx THEN '                                      if center x is supplied
  487.         rect.right = rect.centerx * 2 '                             then calculate right
  488.         rect.width = rect.right '                                   and width
  489.     ELSE '                                                          if right and left supplied
  490.         rect.width = rect.right '                                   then calculate width
  491.         rect.centerx = rect.width / 2 '                             and center x
  492.     END IF
  493.  
  494.     IF rect.height THEN '                                           if height is supplied
  495.         rect.bottom = rect.height '                                 then calculate bottom
  496.         rect.centery = rect.height / 2 '                            and center y
  497.     ELSEIF rect.centery THEN '                                      if center y is suplied
  498.         rect.bottom = rect.centery * 2 '                            then calculate bottom
  499.         rect.height = rect.bottom '                                 and height
  500.     ELSE '                                                          if top and bottom supplied
  501.         rect.height = rect.bottom '                                 then calculate height
  502.         rect.centery = rect.height / 2 '                            and center y
  503.     END IF
  504.  
  505.  
« Last Edit: October 18, 2018, 03:40:17 am by TerryRitchie »
In order to understand recursion, one must first understand recursion.

Offline TerryRitchie

  • Seasoned Forum Regular
  • Posts: 495
  • Semper Fidelis
    • View Profile
Re: Sprite Library Revisited
« Reply #53 on: November 03, 2018, 02:07:04 pm »
Just an update to state I'm still working on the library. Here is the current state of the code:

Code: QB64: [Select]
  1. '
  2. ' Sprite Library v2.0
  3. ' Terry Ritchie
  4. ' QuickBASIC64@gmail.com
  5. '
  6.  
  7. OPTION _EXPLICIT '                  NOTE: Remove before publishing library
  8.  
  9. '                                                                                            _____________________________________
  10. CONST SLFALSE = 0 '                 logical false (0)                                       | Constants are used throughout the   |
  11. CONST SLTRUE = NOT SLFALSE '        logical true (-1)                                       | library code. Changing, deleting,   |
  12. CONST SLNONE = 0 '                  used to null a setting                                  | or altering CONSTant values will    |
  13. CONST SLFORWARD = 1 '               used for animation cell direction                       | result in errors.                   |
  14. CONST SLBACKWARD = 2 '              used for animation cell direction                       |                                     |
  15. CONST SLBACKFORTH = 3 '             used for animation cell direction                       |                                     |
  16. CONST SLRECTANGLE = 1 '             used for collision detection method                     |                                     |
  17. CONST SLCIRCLE = 2 '                used for collision detection method                     |                                     |
  18. CONST SLPIXEL = 3 '                 used for collision detection method                     |                                     |
  19. CONST SLHORIZONTAL = 1 '            used for object flipping                                |                                     |
  20. CONST SLVERTICAL = 2 '              used for object flipping                                |                                     |
  21. CONST SLBOTH = 3 '                  used for object flipping                                |                                     |
  22. CONST SLNOTRANSPARENCY = 1 '        used to disable sheet/sprite transparency               |                                     |
  23. CONST SLLEFTCLICK = 1
  24. CONST SLRIGHTCLICK = 2
  25. CONST SLMIDDLECLICK = 3
  26. CONST SLHOVER = 4
  27. CONST SLWHEELUP = 5
  28. CONST SLWHEELDOWN = 6
  29. CONST SLZOOM = -32767
  30. CONST SLFLIP = -32766
  31. CONST SLVISIBLE = -32765
  32. CONST SLLAYER = -32764
  33. CONST SLSCORE = -32763
  34. CONST SLAUTOANIMATE = -32762
  35. CONST SLFROMCELL = -32761
  36. CONST SLTOCELL = -32760
  37. CONST SLANIMATEDIR = -32759
  38. CONST SLFRAMERATE = -32758
  39. CONST SLAUTOMOTION = -32757
  40. CONST SLMOTIONANGLE = -32756
  41. CONST SLXDIR = -32755
  42. CONST SLYDIR = -32754
  43. CONST SLAUTOROTATE = -32753
  44. CONST SLROTATEANGLE = -32752
  45. CONST SLROTATESPEED = -32751
  46. CONST SLDETECTION = -32750
  47. CONST SLLEFT = -32749
  48. CONST SLTOP = -32748
  49. CONST SLRIGHT = -32747
  50. CONST SLBOTTOM = -32746
  51. CONST SLWIDTH = -32745
  52. CONST SLHEIGHT = -32744
  53. CONST SLCENTERX = -32743
  54. CONST SLCENTERY = -32742
  55. CONST SLCOLLISION = -32741
  56. CONST SLCOLLIDEWITH = -32740
  57. CONST SLCOLLIDEX = -32739
  58. CONST SLCOLLIDEY = -32738
  59. CONST SLMOUSE = -32737
  60. CONST SLMOUSEX = -32736
  61. CONST SLMOUSEY = -32735
  62. CONST SLSPRITEMOUSEX = -32734
  63. CONST SLSPRITEMOUSEY = -32733
  64. '                                                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  65.  
  66. TYPE SLRECT '---------------------- RECTANGULAR STRUCTURE ---------------------------------  _____________________________________
  67.     Width AS INTEGER '              width  of rectangular object                            | This structure should ALWAYS be     |
  68.     Height AS INTEGER '             height of rectangular object                            | used to describe any rectangular    |
  69.     Left AS INTEGER '               left x coordinate   (or offset) of rectangular object   | object used within the library.     |
  70.     Top AS INTEGER '                top y coordinate    (or offset) of rectangular object   | Items such as layers, main screen,  |
  71.     Right AS INTEGER '              right x coordinate  (or offset) of rectangular object   | sprites, and collision areas are    |
  72.     Bottom AS INTEGER '             bottom y coordinate (or offset) of rectangular object   | examples of rectangular structures. |
  73. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  74.  
  75. TYPE SLANIMATION '----------------- OBJECT ANIMATION SETTINGS -----------------------------  _____________________________________
  76.     Auto AS _BYTE '                 auto animation (SLTRUE / SLFALSE)                       | Notes                               |
  77.     Cell AS INTEGER '               current animation cell                                  |                                     |
  78.     FromCell AS INTEGER '           animation start cell number                             |                                     |
  79.     ToCell AS INTEGER '             animation end cell number                               |                                     |
  80.     FrameRate AS INTEGER '          animation independent frame rate                        |                                     |
  81.     Direction AS _BYTE '            animation direction (1 to 3)                            |                                     |
  82. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83.  
  84. TYPE SLMOTION '-------------------- OBJECT MOTION SETTINGS --------------------------------  _____________________________________
  85.     Auto AS _BYTE '                 auto motion (SLTRUE / SLFALSE)                          | Notes                               |
  86.     Degree AS INTEGER '             angle direction of motion (-359 to 359)                 |                                     |
  87.     Xdir AS INTEGER '               x motion vector                                         |                                     |
  88.     Ydir AS INTEGER '               y motion vector                                         |                                     |
  89. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  90.  
  91. TYPE SLROTATION '------------------ OBJECT ROTATION SETTINGS ------------------------------  _____________________________________
  92.     Auto AS _BYTE '                 auto rotation (SLTRUE / SLFALSE)                        | Notes                               |
  93.     Rotates AS _BYTE '              rotation enabled/disabled for sprite (SLTRUE / SLFALSE) |                                     |
  94.     Degree AS INTEGER '             angle of rotation (0 to 359)                            |                                     |
  95.     Rate AS INTEGER '               rotation spin rate (speed)                              |                                     |
  96.     key AS INTEGER '                index key to map and rotation arrays                    |                                     |
  97. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  98.  
  99. TYPE SLCOLLISIONS '---------------- OBJECT COLLISION SETTINGS -----------------------------  _____________________________________
  100.     Detect AS _BYTE '               collision detection method (0 to 3)                     | Notes                               |
  101.     Event AS _BYTE '                collision occurance (SLTRUE / SLFALSE)                  |                                     |
  102.     With AS INTEGER '               the object collision happend with                       |                                     |
  103.     Xloc AS INTEGER '               x location of collision (pixel)                         |                                     |
  104.     Yloc AS INTEGER '               y location of collision (pixel)                         |                                     |
  105.     Mask AS LONG '                  sprite mask image for pixel detection                   |                                     |
  106. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107.  
  108. TYPE SLMOUSES '-------------------- MOUSE INTERACTION SETTINGS ----------------------------  _____________________________________
  109.     Event AS _BYTE '                most recent mouse event                                 | Notes                               |
  110.     Xloc AS INTEGER '               x coordinate location of mouse on object                |                                     |
  111.     Yloc AS INTEGER '               y coordinate location of mouse on object                |                                     |
  112.     SXloc AS INTEGER '              x coordinate of mouse on screen in relation to object   |                                     |
  113.     SYloc AS INTEGER '              y coordinate of mouse on screen in relation to object   |                                     |
  114. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  115.  
  116. TYPE SLSHEET '--------------------- SPRITE SHEET SETTINGS ---------------------------------  _____________________________________
  117.     InUse AS _BYTE '                array index in use (SLTRUE / SLFASLE)                   | Notes                               |
  118.     Image AS LONG '                 sprite sheet image                                      |                                     |
  119.     ClearColor AS _UNSIGNED LONG '  transparent color of sheet                              |                                     |
  120.     CellWidth AS INTEGER '          width of each sprite cell                               |                                     |
  121.     CellHeight AS INTEGER '         height of each sprite cell                              |                                     |
  122.     Columns AS INTEGER '            number of cell columns                                  |                                     |
  123.     Rows AS INTEGER '               number of cell rows                                     |                                     |
  124.     TotalCells AS INTEGER '         total number of cells on sheet                          |                                     |
  125. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  126.  
  127. TYPE SLSPRITE '-------------------- SPRITE SETTINGS ---------------------------------------
  128.     '                                                                                        _____________________________________
  129.     OrigSheet AS INTEGER '          original sprite sheet location                          | These values are to be considered   |
  130.     OrigCell AS INTEGER '           original sprite sheet cell location                     | STATIC in nature. Once they are set |
  131.     OrigImage AS LONG '             original sprite image                                   | they should never be changed.       |
  132.     OrigMask AS LONG '              original sprite mask image                              |                                     |
  133.     OrigWidth AS INTEGER '          original sprite width                                   |                                     |
  134.     OrigHeight AS INTEGER '         original sprite height                                  |                                     |
  135.     '                                                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  136.     OrigColl AS SLRECT '            original NON_ROTATED sprite collision area coordinates
  137.     '  _________________________________________________________________________________     _____________________________________
  138.     ' | .Width  - original collision area width                                         |   | These values are to be considered   |
  139.     ' | .Height - original collision area height                                        |   | STATIC in nature. Once they are set |
  140.     ' | .Left   - original collision area left   x offset (from screen left x)          |   | they should never be changed. These |
  141.     ' | .Top    - original collision area top    y offset (from screen top  y)          |   | values are used to calculate the    |
  142.     ' | .Right  - original collision area right  x offset (from screen left x)          |   | on-screen sprite collision area     |
  143.     ' | .Bottom - original collision area bottom y offset (from screen top  y)          |   | coordinates.                        |
  144.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  145.     ScrnImage AS LONG '             on-screen sprite software image
  146.     ScrnHardware AS LONG '          on-screen sprite hardware image
  147.     ScrnMask AS LONG '              on-screen sprite mask image
  148.  
  149.     Scrn AS SLRECT '                on-screen sprite location coordinates
  150.     '  _________________________________________________________________________________     _____________________________________
  151.     ' | .Width  - on-screen sprite width                                                |   | These values are to be considered   |
  152.     ' | .Height - on-screen sprite height                                               |   | DYNAMIC in nature. These values     |
  153.     ' | .Left   - on-screen sprite left   x location                                    |   | will be calculated every time a     |
  154.     ' | .Top    - on-screen sprite top    y location                                    |   | sprite is to be drawn on-screen     |
  155.     ' | .Right  - on-screen sprite right  x location                                    |   | taking into account rotation,       |
  156.     ' | .Bottom - on-screen sprite bottom y location                                    |   | animation, motion, etc..            |
  157.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  158.  
  159.     ScrnColl AS SLRECT '            on-screen sprite collision area coordinates
  160.     '  _________________________________________________________________________________     _____________________________________
  161.     ' | .Width  - on-screen sprite collision area width                                 |   | These values are to be considered   |
  162.     ' | .Height - on-screen sprite collision area height                                |   | DYNAMIC in nature. These values     |
  163.     ' | .Left   - on-screen sprite collision area left   x location                     |   | will be calculated by adding the    |
  164.     ' | .Top    - on-screen sprite collision area top    y location                     |   | original collision offsets to the   |
  165.     ' | .Right  - on-screen sprite collision area right  x location                     |   | on-screen sprite location           |
  166.     ' | .Bottom - on-screen sprite collision area bottom y location                     |   | coordinates.                        |
  167.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  168.  
  169.     Anim AS SLANIMATION '           sprite animation settings
  170.     '  _________________________________________________________________________________     _____________________________________
  171.     ' | .Auto      - enable or disable sprite auto-animation (SLTRUE / SLFALSE)         |   | Notes                               |
  172.     ' | .Cell      - the current cell in the animation sequence                         |   |                                     |
  173.     ' | .FromCell  - the beginning cell number of the animation sequence                |   |                                     |
  174.     ' | .ToCell    - the ending cell number of the animation sequence                   |   |                                     |
  175.     ' | .FrameRate - the independent animation frame rate                               |   |                                     |
  176.     ' | .Direction - the animation cell direction (1 forward, 2 backward, 3 back/forth) |   |                                     |
  177.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  178.  
  179.     Move AS SLMOTION '              sprite motion settings
  180.     '  _________________________________________________________________________________     _____________________________________
  181.     ' | .Auto   - enable or disable sprite auto-motion (SLTRUE / SLFALSE)               |   | Notes                               |
  182.     ' | .Degree - direction of motion movement in degrees (0 to 359)                    |   |                                     |
  183.     ' | .Xdir   - x direction vector of sprite motion                                   |   |                                     |
  184.     ' | .Ydir   - y direction vector of sprite motion                                   |   |                                     |
  185.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  186.  
  187.     Spin AS SLROTATION '            sprite rotation settings
  188.     '  _________________________________________________________________________________     _____________________________________
  189.     ' | .Auto    - enable or disable sprite auto-rotation (SLTRUE / SLFALSE)            |   | Notes                               |
  190.     ' | .Rotates - sprite has been configured for rotation (SLTRUE / SLFALSE)           |   |                                     |
  191.     ' | .Degree  - sprite degree of rotation (0 to 359)                                 |   |                                     |
  192.     ' | .Rate    - spin rate (speed) of rotation (-359 to 359)                          |   |                                     |
  193.     ' | .Key     - index pointer to map and rotation arrays                             |   |                                     |
  194.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  195.  
  196.     Mouse AS SLMOUSES '             sprite/mouse interaction settings
  197.     '  _________________________________________________________________________________     _____________________________________
  198.     ' | .Event - the most recent mouse/sprite interaction event that occurred           |   | Notes                               |
  199.     ' | .Xloc  - the x coordinate location of the mouse pointer on the sprite           |   |                                     |
  200.     ' | .Yloc  - the y coordinate location of the mouse pointer on the sprite           |   |                                     |
  201.     ' | .SXloc - the x coordinate of the mouse pointer on the screen                    |   |                                     |
  202.     ' | .SYloc - the y coordinate of the mouse pointer on the screen                    |   |                                     |
  203.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  204.  
  205.     Coll AS SLCOLLISIONS '          sprite collision settings
  206.     '  _________________________________________________________________________________     _____________________________________
  207.     ' | .Detect - collision detection method (0 none, 1 rectangle, 2 circle, 3 pixel)   |   | These collision settings have       |
  208.     ' | .Event  - set when a collision event occurs (SLTRUE / SLFALSE)                  |   | nothing to do with collision area   |
  209.     ' | .With   - the object handle the sprite has collided with                        |   | structures used for collision       |
  210.     ' | .Xloc   - x coordinate location of where the collision occurred (pixel)         |   | detection itself. Theese values are |
  211.     ' | .Yloc   - y coordinate location of where the collision occurred (pixel)         |   | created in direct result of a       |
  212.     ' | .Mask   - sprite mask image for use in pixel detection                          |   | collision happening between objects.|
  213.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  214.  
  215.     InUse AS _BYTE '                array index in use (SLTRUE / SLFALSE)
  216.     Flipped AS _BYTE '              sprite flipping method (0 None, 1 Horiz, 2 Vert, 3 Both)
  217.     Zoom AS INTEGER '               sprite zoom level (100 = 100%)
  218.     Visible AS _BYTE '              sprite is currently visible (SLTRUE / SLFALSE)
  219.     Layer AS INTEGER '              the layer a sprite belongs to
  220.     Score AS SINGLE '               the score value associated with a sprite
  221.     ClearColor AS _UNSIGNED LONG '  transparent color of sprite
  222.     Centerx AS INTEGER
  223.     Centery AS INTEGER
  224. END TYPE '---------------------------------------------------------------------------------
  225.  
  226. TYPE SLLAYERS '-------------------- LAYER DATABASE ----------------------------------------  _____________________________________
  227.     image AS LONG '                 the layer surface software image                        | Notes                               |
  228.     Hardware AS LONG '              the layer surface hardware image                        |                                     |
  229.     visible AS _BYTE '              layer visibility (SLTRUE / SLFALSE)                     |                                     |
  230. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  231.  
  232. TYPE SLMAP '----------------------- _MAPTRIANGLE COORDINATES ------------------------------  _____________________________________
  233.     width AS INTEGER '              width of  _MAPTRIANGLE rotated sprite                   | Notes                               |
  234.     height AS INTEGER '             height of _MAPTRIANGLE rotated sprite                   |                                     |
  235.     px0 AS INTEGER '                upper left  x _MAPTRIANGLE coordinate                   |                                     |
  236.     py0 AS INTEGER '                upper left  y _MAPTRIANGLE coordinate                   |                                     |
  237.     px1 AS INTEGER '                lower left  x _MAPTRIANGLE coordinate                   |                                     |
  238.     py1 AS INTEGER '                lower left  y _MAPTRIANGLE coordinate                   |                                     |
  239.     px2 AS INTEGER '                lower right x _MAPTRIANGLE coordinate                   |                                     |
  240.     py2 AS INTEGER '                lower right y _MAPTRIANGLE coordinate                   |                                     |
  241.     px3 AS INTEGER '                upper right x _MAPTRIANGLE coordinate                   |                                     |
  242.     py3 AS INTEGER '                upper right y _MAPTRIANGLE coordinate                   |                                     |
  243. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  244.  
  245. TYPE SLROT '----------------------- ROTATED COLLISION AREA COORDINATES --------------------
  246.     InUse AS _BYTE '                array index in use (SLTRUE / SLFALSE)
  247.     Coll AS SLRECT '                ROTATED collision area coordinates
  248.     '  _________________________________________________________________________________     _____________________________________
  249.     ' | .Width  - rotated collision area width                                          |   | These values are to be considered   |
  250.     ' | .Height - rotated collision area height                                         |   | STATIC in nature. Once they are set |
  251.     ' | .Left   - rotated collision area left   x offset (from screen left x)           |   | they should never be changed. These |
  252.     ' | .Top    - rotated collision area top    y offset (from screen top  y)           |   | values are used to calculate the    |
  253.     ' | .Right  - rotated collision area right  x offset (from screen left x)           |   | on-screen ROTATED sprite collision  |
  254.     ' | .Bottom - rotated collision area bottom y offset (from screen top  y)           |   | area coordinates.                   |
  255.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  256. END TYPE '---------------------------------------------------------------------------------
  257.  
  258. TYPE SLDEGREE '-------------------- PRECALCULATED SIN/COS TABLE ---------------------------  _____________________________________
  259.     SIN AS SINGLE '                 SIN of rotation                                         | The file degrees.deg will be        |
  260.     COS AS SINGLE '                 COS of rotation                                         | created to hold this table.         |
  261. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  262.  
  263. TYPE SLGLOBAL '-------------------- GLOBAL SETTINGS ---------------------------------------  _____________________________________
  264.     Scrn AS SLRECT '                main screen coordinate values                           | Any single variables that need to   |
  265.     Start AS _BYTE '                SLStart initialization trigger (SLTRUE / SLFALSE)       | be shared globally throughout the   |
  266.     FrameRate AS INTEGER '          global library frame rate                               | library should be placed in this    |
  267.     Layers AS INTEGER '             number of layers requested by programmer                | data type.                          |
  268.     Subroutine AS STRING * 15 '     current subroutine for error processing                 |                                     |
  269. END TYPE '---------------------------------------------------------------------------------  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  270.  
  271.  
  272. REDIM SLSheet(0) AS SLSHEET '       master sprite sheet array
  273. REDIM SLSprite(0) AS SLSPRITE '     master sprite array
  274. REDIM SLMap(0, 359) AS SLMAP '      master sprite sheet _MAPTRIANGLE coordinate array
  275. REDIM SLRot(0, 359) AS SLROT '      master sprite rotated collision area array
  276. REDIM SLLayers(0) AS SLLAYERS '      master layer array
  277. DIM SLDegree(359) AS SLDEGREE '     precalculated SIN/COS table
  278. DIM SLGlobal AS SLGLOBAL '          global variables
  279.  
  280.  
  281. DIM dkong AS INTEGER
  282. DIM rect AS SLRECT
  283. DIM mario AS INTEGER
  284.  
  285. SL_Start
  286. SL_Window 640, 480, 5
  287. dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  288. mario = SL_MakeSprite(0, dkong, 6, SLTRUE)
  289. 'SL_SpriteSet mario, SLZOOM, 500
  290. SL_PutSprite mario, 200, 200
  291. _PUTIMAGE (SLSprite(mario).Scrn.Left, SLSprite(mario).Scrn.Top)-(SLSprite(mario).Scrn.Right, SLSprite(mario).Scrn.Bottom), SLSprite(mario).OrigImage
  292. CIRCLE (100, 100), 50, _RGB32(255, 255, 255)
  293. LINE (SLSprite(mario).ScrnColl.Left, SLSprite(mario).ScrnColl.Top)-(SLSprite(mario).ScrnColl.Right, SLSprite(mario).ScrnColl.Bottom), _RGB32(255, 255, 255), B
  294. SL_FreeSprite mario
  295.  
  296.  
  297. ' Verified SLRot() is being created correctly
  298. '--------------------------------------------
  299. 'SCREEN _NEWIMAGE(640, 480, 32)
  300. 'dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  301. 'mario = SL_MakeSprite(0, dkong, 1, SLTRUE)
  302. 'FOR i = 0 TO 359
  303. '    PRINT SLRot(0, i).Coll.Width; SLRot(0, i).Coll.Height
  304. '    PRINT SLRot(0, i).Coll.Left; SLRot(0, i).Coll.Top; SLRot(0, i).Coll.Right; SLRot(0, i).Coll.Bottom
  305. 'NEXT i
  306.  
  307.  
  308. ' Verified SL_MakeSprite is working properly
  309. '-------------------------------------------
  310. 'SCREEN _NEWIMAGE(640, 480, 32)
  311. 'dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  312. 'mario = SL_MakeSprite(0, dkong, 1, SLTRUE)
  313. '_PUTIMAGE (0, 0), SLSprite(dkong).OrigImage
  314. 'LINE (SLSprite(mario).OrigColl.Left, SLSprite(mario).OrigColl.Top)-(SLSprite(mario).OrigColl.Right, SLSprite(mario).OrigColl.Bottom), _RGB32(255, 255, 255), B
  315.  
  316.  
  317. ' Verified SL_GetCellCoordinates is working properly
  318. '---------------------------------------------------
  319. 'SCREEN _NEWIMAGE(640, 480, 32)
  320. 'dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  321. 'SL_GetCellCoordinates dkong, 1, rect
  322. 'PRINT rect.left, rect.top
  323. 'PRINT rect.right, rect.bottom
  324. 'PRINT rect.width, rect.height
  325.  
  326.  
  327. ' Verified sheet is loading and clearcolor being applied
  328. '-------------------------------------------------------
  329. 'SCREEN _NEWIMAGE(640, 480, 32)
  330. 'dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  331. '_PUTIMAGE (100, 100), SLSheet(dkong).Image
  332.  
  333.  
  334. ' Verified SLMAP() is being created and reloaded properly
  335. '--------------------------------------------------------
  336. 'SCREEN _NEWIMAGE(640, 480, 32)
  337. 'dkong = SL_LoadSheet("dkong.png", 64, 64, _RGB32(255, 0, 255))
  338. 'FOR i = 0 TO 359
  339. '    PRINT i; SLMap(dkong, i).width; SLMap(dkong, i).height
  340. '    DO: LOOP UNTIL _KEYHIT
  341. 'NEXT i
  342.  
  343.  
  344.  
  345. '----------------------------------------------------------------------------------------------------------------------------------
  346. SUB SL_Start () '                                                                                                          SL_Start
  347.     '  ___________________________________________________________________________________________________________________________
  348.     ' | Initializes the sprite library                                                                                            |
  349.     ' |---------------------------------------------------------------------------------------------------------------------------|
  350.     ' | Usage : SL_Start                                                                                                          |
  351.     ' |                                                                                                                           |
  352.     ' | Output: A file named 'degrees.deg' will be created after executing this subroutine.                                       |
  353.     ' | Note  : This MUST be the first command issued before using the sprite library. Any setup procedures that need to be       |
  354.     ' |         performed in support of functions and subroutines should be placed in this subroutine.                            |
  355.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  356.     SHARED SLDegree() AS SLDEGREE ' precalculated SIN/COS table
  357.     SHARED SLGlobal AS SLGLOBAL '   global variables
  358.     DIM Degree AS INTEGER '         degree counter
  359.     DIM FileNumber AS INTEGER '     next available file handle
  360.     '  ________________________________________________________________________________
  361.     ' | Load or create precalculated degree rotation array                             |
  362.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  363.     FileNumber = FREEFILE '                                                                 get the next free file handle
  364.     IF _FILEEXISTS("degrees.deg") THEN '                                                    does the degree file exist?
  365.         '  ____________________________________________________________________________
  366.         ' | Load the array since the file already exists                               |
  367.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  368.         OPEN "degrees.deg" FOR BINARY AS #FileNumber '                                      yes, open the file for reading
  369.         GET #FileNumber, , SLDegree() '                                                     get the rotational degree data
  370.         CLOSE #FileNumber '                                                                 close the file
  371.     ELSE '                                                                                  no, the file does not exist
  372.         '  ____________________________________________________________________________
  373.         ' | Create the precalculated degree rotation array                             |
  374.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  375.         DO '                                                                                cycle through 360 degrees
  376.             SLDegree(Degree).SIN = SIN(Degree * .017453292) '                               calculate the SIN of angle
  377.             SLDegree(Degree).COS = -COS(Degree * .017453292) '                              calculate the COSINE of angle
  378.             Degree = Degree + 1 '                                                           increment degree counter
  379.         LOOP UNTIL Degree = 360 '                                                           leave when all degrees cycled
  380.         '  ____________________________________________________________________________
  381.         ' | The file must be created since it did not exist                            |
  382.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  383.         OPEN "degrees.deg" FOR BINARY AS #FileNumber '                                      open the file for writing
  384.         PUT #FileNumber, , SLDegree() '                                                     write the rotational degree data
  385.         CLOSE #FileNumber '                                                                 close the file
  386.     END IF
  387.     SLGlobal.Start = SLTRUE '                                                               record that library was initialized
  388.  
  389.  
  390. '----------------------------------------------------------------------------------------------------------------------------------
  391. SUB SL_Window (ScreenWidth AS INTEGER, ScreenHeight AS INTEGER, Layers AS INTEGER) '                                      SL_Window
  392.     '  ___________________________________________________________________________________________________________________________
  393.     ' | Creates the main working screen and number of requested layers.                                                           |
  394.     ' |---------------------------------------------------------------------------------------------------------------------------|
  395.     ' | Usage : SL_Window 640, 480, 4                                                                                             |
  396.     ' |                                                                                                                           |
  397.     ' | Input : ScreenWidth  = the width of the main working screen and requested layers                                          |
  398.     ' |         ScreenHeight = the height of the main working screen and requested layers                                         |
  399.     ' |         Layers       = the requested number fo layers to create (zero (0) for no layers)                                  |
  400.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  401.     SHARED SLLayers() AS SLLAYERS ' master layer array
  402.     SHARED SLGlobal AS SLGLOBAL '   global variables
  403.     DIM layer AS INTEGER
  404.  
  405.     SLGlobal.Scrn.Width = ScreenWidth '                                                     set screen/layer rectangular values
  406.     SLGlobal.Scrn.Height = ScreenHeight
  407.     SLGlobal.Scrn.Left = 0
  408.     SLGlobal.Scrn.Top = 0
  409.     SLGlobal.Scrn.Right = ScreenWidth - 1
  410.     SLGlobal.Scrn.Bottom = ScreenHeight - 1
  411.     '  _________________________________________________________________________________
  412.     ' | Create the number of requested layers                                           |
  413.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  414.     IF Layers > SLNONE THEN '                                                               have layers been requested?
  415.         SLGlobal.Layers = Layers '                                                          yes, record number of layers requested
  416.         REDIM SLLayers(Layers) AS SLLAYERS '                                                increase size of layer array
  417.         DO '                                                                                cycle through requested layers
  418.             layer = layer + 1 '                                                             increment layer counter
  419.             SLLayers(layer).image = _NEWIMAGE(ScreenWidth, ScreenHeight, 32) '              create software layer image
  420.             SLLayers(Layers).visible = SLTRUE '                                             layers are visible by default
  421.         LOOP UNTIL layer = UBOUND(SLLayers) '                                               leave when all layers created
  422.     END IF
  423.     '  _________________________________________________________________________________
  424.     ' | Create the main working screen (_DEST 0)                                        |
  425.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  426.     SCREEN _NEWIMAGE(ScreenWidth, ScreenHeight, 32) '                                       initialize main screen
  427.  
  428.  
  429. '----------------------------------------------------------------------------------------------------------------------------------
  430. SUB SL_PutSprite (Handle AS INTEGER, Centerx AS INTEGER, Centery AS INTEGER) '                                         SL_PutSprite
  431.     '  ___________________________________________________________________________________________________________________________
  432.     ' | Calculates the actual screen and collision area coordinates for sprite screen placement.                                  |
  433.     ' |---------------------------------------------------------------------------------------------------------------------------|
  434.     ' | Usage : SL_PutSprite Mysprite, 100, 100                                                                                   |
  435.     ' |                                                                                                                           |
  436.     ' | Input : Handle  = the handle pointer name of the sprite to have screen placement calculated                               |
  437.     ' |         Centerx = the x coordinate location to horizontally center the sprite                                             |
  438.     ' |         Centery = the y coordinate location to vertically center the sprite                                               |
  439.     ' | Note  : The sprite will be centered on the supplied Centerx and Centery coordinate pair.                                  |
  440.     ' |         The sprite zoom level will be taken into account to adjust the screen and collision coordinates accordingly.      |
  441.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  442.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  443.     SHARED SLMap() AS SLMAP '       master sprite sheet _MAPTRIANGLE coordinate array
  444.     SHARED SLRot() AS SLROT '       master sprite rotated collision area array
  445.     DIM Zoom AS INTEGER '           zoom level of sprite
  446.     DIM Sheet AS INTEGER '          the sprite sheet the sprite belongs to
  447.     DIM Degree AS INTEGER '         the sprite's dgree of rotation
  448.     DIM RotKey AS INTEGER '         the sprite's key index pointer to the SLRot array
  449.  
  450.     Zoom = SLSprite(Handle).Zoom \ 100 '                                                    get and calculate the zoom level
  451.     Sheet = SLSprite(Handle).OrigSheet '                                                    get the sheet that owns this sprite
  452.     Degree = SLSprite(Handle).Spin.Degree '                                                 get the sprite's degree of rotation
  453.     RotKey = SLSprite(Handle).Spin.key '                                                    get the sprite's SLRot index pointer
  454.     SLSprite(Handle).Centerx = Centerx '                                                    record current x coordinate of sprite
  455.     SLSprite(Handle).Centery = Centery '                                                    record current y coordinate of sprite
  456.     '  _________________________________________________________________________________
  457.     ' |                                                                                 |
  458.     ' | Calculate the sprite's on-screen rectangular structure coordinate values        |
  459.     ' |                                                                                 |
  460.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  461.     IF SLSprite(Handle).Spin.Rotates THEN '                                                 has sprite been configured to rotate?
  462.         '  _____________________________________________________________________________
  463.         ' | Use SLMap width and height values since the sprite uses ROTATION            |
  464.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  465.         SLSprite(Handle).Scrn.Width = SLMap(Sheet, Degree).width '                          yes, get the rotated width of sprite
  466.         SLSprite(Handle).Scrn.Height = SLMap(Sheet, Degree).height '                        get the rotated height of sprite
  467.     ELSE '                                                                                  no, this sprite does not rotate
  468.         '  _____________________________________________________________________________
  469.         ' | Use original width and height values since the sprite uses NO ROTATION      |
  470.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  471.         SLSprite(Handle).Scrn.Width = SLSprite(Handle).OrigWidth '                          get the original width of sprite
  472.         SLSprite(Handle).Scrn.Height = SLSprite(Handle).OrigHeight '                        get the original height of sprite
  473.     END IF
  474.     '  _________________________________________________________________________________
  475.     ' | Complete the calculations for the on-screen sprite rectangular structure        |
  476.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  477.     SLSprite(Handle).Scrn.Left = Centerx - (SLSprite(Handle).Scrn.Width \ 2) * Zoom '       calculate sprite's left x coordinate
  478.     SLSprite(Handle).Scrn.Top = Centery - (SLSprite(Handle).Scrn.Height \ 2) * Zoom '       calculate sprite's top y coordinate
  479.     SLSprite(Handle).Scrn.Right = SLSprite(Handle).Scrn.Left +_
  480.                                   (SLSprite(Handle).Scrn.Width - 1) * Zoom '                calculate sprite's right x coordinate
  481.     SLSprite(Handle).Scrn.Bottom = SLSprite(Handle).Scrn.Top +_
  482.                                   (SLSprite(Handle).Scrn.Height - 1) * Zoom '               calculate sprite's bottom y coordinate
  483.     '  _________________________________________________________________________________
  484.     ' |                                                                                 |
  485.     ' | Calculate the sprite's on-screen collision area rectangular coordinate values   |
  486.     ' |                                                                                 |
  487.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  488.     IF SLSprite(Handle).ClearColor = SLNOTRANSPARENCY THEN '                                does sprite have transparent color?
  489.         '  _____________________________________________________________________________
  490.         ' | Since sprite is not transparent the collision area will be the entire sprite|
  491.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  492.         SLSprite(Handle).ScrnColl = SLSprite(Handle).Scrn '                                 no, use entire sprite as collision
  493.     ELSE '                                                                                  yes, this sprite uses transparency
  494.         IF SLSprite(Handle).Spin.Rotates THEN '                                             has sprite been configured to rotate?
  495.             '  _________________________________________________________________________
  496.             ' | Since the sprite is transparent and it rotates the collision area       |
  497.             ' | coordinates must come from the SLRot array.                             |
  498.             ' |-------------------------------------------------------------------------|
  499.             ' |                                Sprite Top Y                             |
  500.             ' |          +--------------------------------------------------------+     |
  501.             ' |          |TRANSPARENT          SLRot        ^   ^        SLRot    |     |
  502.             ' |          |   SPRITE          Collision      |   |      Collision  |     |
  503.             ' |          |                   Area Top Y --->|   |<--- Area Bottom |     |
  504.             ' |          |                    (offset)      |   |     Y (offset)  |     |
  505.             ' |          |                                  |   |                 |     |
  506.             ' |          |  SLRot ~~~~~~~~~~\               V   |                 |     |
  507.             ' |  Sprite  |  Collision Area   |    +-------------+--------+        |     |
  508.             ' |  Left X  |  Lext X (offset)  V    |COLLISION    |        |        |     |
  509.             ' |          |<---------------------->|   AREA      |        |        |     |
  510.             ' |          |                        |             |        |        |     |
  511.             ' |          |<-----------------------+-------------+------->|        |     |
  512.             ' |          |   Collision Area  ^    |             |        |        |     |
  513.             ' |          |  Right X (offset) |    |             V        |        |     |
  514.             ' |          |  SLRot __________/     +----------------------+        |     |
  515.             ' |          |                                                        |     |
  516.             ' |          +--------------------------------------------------------+     |
  517.             ' | The collsion area for a transparent sprite comes from taking the left x |
  518.             ' | and top y offset values from SLRot and adding them to the left x and    |
  519.             ' | top y sprite coordinate values as shown above. The collision area can   |
  520.             ' | wildy vary in size depending on the actual non-transparent image        |
  521.             ' | contained within the sprite. Note as well that the collision does not   |
  522.             ' | necessarily need to be centered within the sprite, again depending on   |
  523.             ' | the actual non-transparent image contained within the sprite.           |
  524.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  525.             SLSprite(Handle).ScrnColl.Width = SLRot(RotKey, Degree).Coll.Width '            get the sprite's rotated width
  526.             SLSprite(Handle).ScrnColl.Height = SLRot(RotKey, Degree).Coll.Height '          get the sprite's rotated height
  527.             SLSprite(Handle).ScrnColl.Left = SLSprite(Handle).Scrn.Left +_
  528.                                              SLRot(RotKey, Degree).Coll.Left * Zoom '       calculate sprite's left x coordinate
  529.             SLSprite(Handle).ScrnColl.Top = SLSprite(Handle).Scrn.Top +_
  530.                                             SLRot(RotKey, Degree).Coll.Top * Zoom '         calculate sprite's top y coordinate
  531.             SLSprite(Handle).ScrnColl.Right = SLSprite(Handle).Scrn.Left +_
  532.                                               SLRot(RotKey, Degree).Coll.Right * Zoom '     calculate sprite's right x coordinate
  533.             SLSprite(Handle).ScrnColl.Bottom = SLSprite(Handle).Scrn.Top +_
  534.                                                SLRot(RotKey, Degree).Coll.Bottom * Zoom '   calculate sprite's bottom y coordinate
  535.         ELSE '                                                                              no, this sprite does not rotate
  536.             '  _________________________________________________________________________
  537.             ' | The sprite does not rotate so use the original collision area instead   |
  538.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  539.             SLSprite(Handle).ScrnColl.Width = SLSprite(Handle).OrigColl.Width '             get sprite's original collision width
  540.             SLSprite(Handle).ScrnColl.Height = SLSprite(Handle).OrigColl.Height '           get sprite's original collision height
  541.             SLSprite(Handle).ScrnColl.Left = SLSprite(Handle).Scrn.Left +_
  542.                                              SLSprite(Handle).OrigColl.Left * Zoom '        calculate sprite's left x coordinate
  543.             SLSprite(Handle).ScrnColl.Top = SLSprite(Handle).Scrn.Top +_
  544.                                             SLSprite(Handle).OrigColl.Top * Zoom '          calculate sprite's top y coordinate
  545.             SLSprite(Handle).ScrnColl.Right = SLSprite(Handle).Scrn.Left +_
  546.                                               SLSprite(Handle).OrigColl.Right * Zoom '      calculate sprite's right x coordinate
  547.             SLSprite(Handle).ScrnColl.Bottom = SLSprite(Handle).Scrn.Top +_
  548.                                                SLSprite(Handle).OrigColl.Bottom * Zoom '    calculate sprite's bottom y coordinate
  549.         END IF
  550.     END IF
  551.  
  552.  
  553. '----------------------------------------------------------------------------------------------------------------------------------
  554. FUNCTION SL_MakeSprite (Layer AS INTEGER, Sheet AS INTEGER, Cell AS INTEGER, Rotates AS INTEGER) '                    SL_MakeSprite
  555.     '  ___________________________________________________________________________________________________________________________
  556.     ' | Create a new sprite from a previously loaded sprite sheet.                                                                |
  557.     ' |---------------------------------------------------------------------------------------------------------------------------|
  558.     ' | Usage : Sprite = SL_MakeSprite(LayerNumber, MySheet, CellNumber, SLTRUE)                                                  |
  559.     ' |                                                                                                                           |
  560.     ' | Input : Layer   = the layer this sprite resides on (use zero (0) for a pure hardware sprite)                              |
  561.     ' |         Sheet   = the previously loaded sheet where the sprite is located                                                 |
  562.     ' |         Cell    = the cell number on the previously loaded sheet where the sprite resides                                 |
  563.     ' |         Rotates = sprite rotation characteristics (SLTRUE = the sprite will rotate, SLFALSE = the sprite will not rotate) |
  564.     ' | Output: An array index that acts as a handle pointer to the newly created sprite                                          |
  565.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  566.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  567.     SHARED SLSheet() AS SLSHEET '   master sprite sheet array
  568.     SHARED SLMap() AS SLMAP '       master sprite sheet _MAPTRIANGLE coordinate array
  569.     SHARED SLRot() AS SLROT '       master sprite rotated collision area array
  570.     DIM Handle AS INTEGER '         sprite array index pointer
  571.     DIM Rect AS SLRECT '            general use rectangular structure
  572.     DIM odest AS LONG '             current _DEST
  573.     DIM osource AS LONG '           current _SOURCE
  574.     DIM x AS INTEGER '              x axis (width) counter
  575.     DIM y AS INTEGER '              y axis (height) counter
  576.     DIM RotKey AS INTEGER '         rotated collsion array index key used by sprite
  577.     DIM rotatedsprite AS LONG '     each sprite rotated 360 degrees
  578.     DIM degree AS INTEGER '         degree counter
  579.     '  _________________________________________________________________________________
  580.     ' | Create a new or use existing unused index in sprite array to hold sprite.       |
  581.     ' |---------------------------------------------------------------------------------|
  582.     ' | When a sprite is removed (SL_RemoveSprite) the array index is marked as unused  |
  583.     ' | and can be later reused by another sprite being created. If no unused array     |
  584.     ' | positions exist then a new array index will be created to hold the new sprite's |
  585.     ' | information.                                                                    |
  586.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  587.     Handle = -1 '                                                                           reset handle array index pointer
  588.     DO '                                                                                    cycle through sprite array
  589.         Handle = Handle + 1 '                                                               increment handle array index pointer
  590.     LOOP UNTIL SLSprite(Handle).InUse = SLFALSE OR Handle = UBOUND(SLSprite) '              leave when suitable array index found
  591.     IF SLSprite(Handle).InUse THEN '                                                        is this array index currently in use?
  592.         Handle = Handle + 1 '                                                               yes, increase the array index size
  593.         REDIM _PRESERVE SLSprite(Handle) AS SLSPRITE '                                      create new index in sprite array
  594.     END IF
  595.     '  _________________________________________________________________________________
  596.     ' | Record basic information about the sprite                                       |
  597.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  598.     SLSprite(Handle).InUse = SLTRUE '                                                       mark this array index as in use
  599.     SLSprite(Handle).OrigSheet = Sheet '                                                    get the sheet sprite belongs to
  600.     SLSprite(Handle).OrigCell = Cell '                                                      get the cell sprite resides in on sheet
  601.     SLSprite(Handle).OrigWidth = SLSheet(Sheet).CellWidth '                                 get original width of sprite
  602.     SLSprite(Handle).OrigHeight = SLSheet(Sheet).CellHeight '                               get original height of sprite
  603.     SLSprite(Handle).OrigImage = _NEWIMAGE(SLSprite(Handle).OrigWidth,_
  604.                                            SLSprite(Handle).OrigHeight, 32) '               create original image surface
  605.     SLSprite(Handle).OrigMask = _COPYIMAGE(SLSprite(Handle).OrigImage, 32) '                create original image mask surface
  606.     SL_GetCellCoordinates Sheet, Cell, Rect '                                               get original image sheet coordinates
  607.     _PUTIMAGE , SLSheet(Sheet).Image, SLSprite(Handle).OrigImage,_
  608.                 (Rect.Left, Rect.Top)-(Rect.Right, Rect.Bottom) '                           get original copy of image from sheet
  609.     SLSprite(Handle).Flipped = SLNONE '                                                     reset sprite flipping behavior
  610.     SLSprite(Handle).Zoom = 100 '                                                           reset zoom to normal (100%)
  611.     SLSprite(Handle).Visible = SLTRUE '                                                     all new sprites visible by default
  612.     SLSprite(Handle).Layer = Layer '                                                        the layer that sprite belongs to
  613.     SLSprite(Handle).Score = 0 '                                                            reset sprite's score
  614.     SLSprite(Handle).ClearColor = SLSheet(Sheet).ClearColor '                               get sprite's transparenct color
  615.     '  _________________________________________________________________________________
  616.     ' | Create original collision area information and original sprite mask image       |
  617.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  618.     odest = _DEST '                                                                         save current destination surface
  619.     osource = _SOURCE '                                                                     save current source surface
  620.     _SOURCE SLSprite(Handle).OrigImage '                                                    set original image as source surface
  621.     _DEST SLSprite(Handle).OrigMask '                                                       set original image mask as destination
  622.     Rect.Width = SLSprite(Handle).OrigWidth '                                               use original width in rect structure
  623.     Rect.Height = SLSprite(Handle).OrigHeight '                                             use original height in rect structure
  624.     Rect.Left = Rect.Width '                                                                start at opposite side of left
  625.     Rect.Top = Rect.Height '                                                                start at opposite side of top
  626.     Rect.Right = 0 '                                                                        start at opposite side of right
  627.     Rect.Bottom = 0 '                                                                       start at opposite side of bottom
  628.     '  _________________________________________________________________________________
  629.     ' | Scan every pixel of the image to obtain collision area characteristics          |
  630.     ' |---------------------------------------------------------------------------------|
  631.     ' | If a pixel location within the image is not a transparent color then test to    |
  632.     ' | see if that pixel is one of the outer boundaries of the collision area. The     |
  633.     ' | collison area will encompass any pixel that is not a transparent one. If the    |
  634.     ' | pixel is transparent however draw a pixel on the sprite mask image in the same  |
  635.     ' | spot as white. This will create a negative mask, white being where a tranparent |
  636.     ' | pixel is and black being where the image is located.                            |
  637.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  638.     DO '                                                                                    cycle through the width of the image
  639.         y = 0 '                                                                             reset height counter
  640.         DO '                                                                                cycle through the height of the image
  641.             IF POINT(x, y) <> SLSprite(Handle).ClearColor THEN '                            is this pixel transparent?
  642.                 '  _____________________________________________________________________
  643.                 ' | pixel is part of image so look for outer boundary                   |
  644.                 '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  645.                 IF x < Rect.Left THEN Rect.Left = x '                                       no, if left-most so far record it
  646.                 IF y < Rect.Top THEN Rect.Top = y '                                         if top-most so far record it
  647.                 IF x > Rect.Right THEN Rect.Right = x '                                     if right-most so far record it
  648.                 IF y > Rect.Bottom THEN Rect.Bottom = y '                                   if bottom-most so far record it
  649.             ELSE '                                                                          yes, the pixel is transparent
  650.                 '  _____________________________________________________________________
  651.                 ' | pixel is part of the transparent area so create mask instead        |
  652.                 '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  653.                 PSET (x, y), _RGB32(255, 255, 255) '                                        draw white pixel on mask in same spot
  654.             END IF
  655.             y = y + 1 '                                                                     increment height counter
  656.         LOOP UNTIL y = Rect.Height '                                                        leave when height of image reached
  657.         x = x + 1 '                                                                         increment width counter
  658.     LOOP UNTIL x = Rect.Width '                                                             leave when width of image reached
  659.     _DEST odest '                                                                           restore current destination surface
  660.     _SOURCE osource '                                                                       restore current source surface
  661.     SLSprite(Handle).OrigColl = Rect '                                                      record original collision area values
  662.     '  _________________________________________________________________________________
  663.     ' | Reset on-screen sprite and collision area coordinates                           |
  664.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  665.     Rect.Width = 0 '                                                                        create empty rectangular structure
  666.     Rect.Height = 0
  667.     Rect.Left = 0
  668.     Rect.Top = 0
  669.     Rect.Right = 0
  670.     Rect.Bottom = 0
  671.     SLSprite(Handle).Scrn = Rect '                                                          reset on-screen location coordinates
  672.     SLSprite(Handle).ScrnColl = Rect '                                                      reset on-screen collision area coords
  673.     '  _________________________________________________________________________________
  674.     ' | Reset sprite animation settings                                                 |
  675.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  676.     SLSprite(Handle).Anim.Auto = SLFALSE
  677.     SLSprite(Handle).Anim.Cell = 0
  678.     SLSprite(Handle).Anim.FromCell = 0
  679.     SLSprite(Handle).Anim.ToCell = 0
  680.     SLSprite(Handle).Anim.FrameRate = 0
  681.     SLSprite(Handle).Anim.Direction = 0
  682.     '  _________________________________________________________________________________
  683.     ' | Reset sprite motion settings                                                    |
  684.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  685.     SLSprite(Handle).Move.Auto = SLFALSE
  686.     SLSprite(Handle).Move.Degree = 0
  687.     SLSprite(Handle).Move.Xdir = 0
  688.     SLSprite(Handle).Move.Ydir = 0
  689.     '  _________________________________________________________________________________
  690.     ' | Reset sprite rotation settings                                                  |
  691.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  692.     IF Rotates THEN '                                                                       will this sprite be able to rotate?
  693.         '  _____________________________________________________________________________
  694.         ' | Create a new or use existing unused index in collision rotation array       |
  695.         ' |-----------------------------------------------------------------------------|
  696.         ' | When a sprite is set as being allowed to rotate its image is rotated 360    |
  697.         ' | degrees to obtain collision area coordinates for every angle. This          |
  698.         ' | information is stored in the collision rotation array at either a new index |
  699.         ' | created to hold the information or an unused one freed up by a sprite being |
  700.         ' | removed. A key is used as an index pointer by the sprite to find its        |
  701.         ' | information in the collision rotation array.                                |
  702.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  703.         RotKey = -1 '                                                                       yes, reset handle array index pointer
  704.         DO '                                                                                cycle through rotated collision array
  705.             RotKey = RotKey + 1 '                                                           increment handle array index pointer
  706.         LOOP UNTIL SLRot(RotKey, 0).InUse = SLFALSE OR RotKey = UBOUND(SLrot, 1) '          leave when suitable array index found
  707.         IF SLRot(RotKey, 0).InUse THEN '                                                    is this array index currently in use?
  708.             RotKey = RotKey + 1 '                                                           yes, increase the array index size
  709.             REDIM _PRESERVE SLRot(RotKey, 359) AS SLROT '                                   create new index in rotated coll array
  710.         END IF
  711.         SLSprite(Handle).Spin.key = RotKey '                                                mark this array index as in use
  712.         DO '                                                                                cycle through 360 degrees
  713.             IF SLSprite(Handle).ClearColor = SLNOTRANSPARENCY THEN '                        does this sprite contain transparency?
  714.                 '  _____________________________________________________________________
  715.                 ' | The sprite not transparent so use the full rotated width and height |
  716.                 '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  717.                 SLRot(RotKey, degree).Coll.Width = SLMap(Sheet, degree).width '             no, record rotated collision area width
  718.                 SLRot(RotKey, degree).Coll.Height = SLMap(Sheet, degree).height '           record rotated collision area height
  719.                 SLRot(RotKey, degree).Coll.Left = 0 '                                       record rotated collision left offset
  720.                 SLRot(RotKey, degree).Coll.Top = 0 '                                        record rotated collision top offset
  721.                 SLRot(RotKey, degree).Coll.Right = SLMap(Sheet, degree).width - 1 '         record rotated collision right offset
  722.                 SLRot(RotKey, degree).Coll.Bottom = SLMap(Sheet, degree).height - 1 '       record rotated collision bottom offset
  723.             ELSE '                                                                          yes, this sprite contains transparency
  724.                 '  _____________________________________________________________________     _____________________________________
  725.                 ' | Map original sprite onto rotated image using SLMap data made before |   | These rotated sprite images could   |
  726.                 ' |---------------------------------------------------------------------|   | be saved into an array in a later   |
  727.                 ' | The precalculated values        px(0),py(0)           px(3),py(3)   |   | version of the sprite library       |
  728.                 ' | created when the sheet was           +---------------------+        |   | eleviating the need to once again   |
  729.                 ' | loaded and placed in SLMap       ,>  |~\_     _MAPTRIANGLE |  >,    |   | rotate them in SLPutSprite later.   |
  730.                 ' | are now used by _MAPTRIANGLE    /    |   ~\_       #2      |    \   |   | This would take a considerable      |
  731.                 ' | to rotate the image onto       |     |      ~\_            |     |  |   | amount of memory to store however   |
  732.                 ' | the rotated sprite image      |      |         ~\_         |      | |   | depending on the number of sprites  |
  733.                 ' | surface. SLMap also contains   |     |            ~\_      |     |  |   | that require rotating in a given    |
  734.                 ' | the rotated width and height    \    | _MAPTRIANGLE  ~\_   |    /   |   | game/program. This will need to be  |
  735.                 ' | needed to create the rotated     `<  |      #1          ~\_|  <'    |   | investigated at a later date.       |
  736.                 ' | sprite image surface.                +---------------------+        |   |                                     |
  737.                 ' |                                 px(1),py(1)           px(2),py(2)   |   |                       tr 10/30/18   |
  738.                 '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  739.                 rotatedsprite = _NEWIMAGE(SLMap(Sheet, degree).width,_
  740.                                           SLMap(Sheet, degree).height, 32) '                create rotated sprite image surface
  741.  
  742.                 _MAPTRIANGLE (0, 0)-(0, SLSprite(Handle).OrigHeight - 1)-_
  743.                     (SLSprite(Handle).OrigWidth - 1, SLSprite(Handle).OrigHeight - 1),_
  744.                     SLSprite(Handle).OrigImage TO _
  745.                     (SLMap(Sheet, degree).px0, SLMap(Sheet, degree).py0)-_
  746.                     (SLMap(Sheet, degree).px1, SLMap(Sheet, degree).py1)-_
  747.                     (SLMap(Sheet, degree).px2, SLMap(Sheet, degree).py2), rotatedsprite '   map triangle #1 to rotated sprite image
  748.                 _MAPTRIANGLE (0, 0)-(SLSprite(Handle).OrigWidth - 1, 0)-_
  749.                     (SLSprite(Handle).OrigWidth - 1, SLSprite(Handle).OrigHeight - 1),_
  750.                     SLSprite(Handle).OrigImage TO _
  751.                     (SLMap(Sheet, degree).px0, SLMap(Sheet, degree).py0)-_
  752.                     (SLMap(Sheet, degree).px3, SLMap(Sheet, degree).py3)-_
  753.                     (SLMap(Sheet, degree).px2, SLMap(Sheet, degree).py2), rotatedsprite '   map triangle #2 to rotated sprite image
  754.                 '  _____________________________________________________________________
  755.                 ' | The sprite is transparent so the rotated image will need scanned    |
  756.                 ' |---------------------------------------------------------------------|
  757.                 ' | If a pixel location within the image is not a transparent color     |
  758.                 ' | then test to see if that pixel is one of the outer boundaries of    |
  759.                 ' | the collision area. The collision area will encompass any pixel     |
  760.                 ' | that is not a transparent one.                                      |
  761.                 '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  762.                 Rect.Width = SLMap(Sheet, degree).width '                                   use rotated width in rect structure
  763.                 Rect.Height = SLMap(Sheet, degree).height '                                 use rotated height in rect structure
  764.                 Rect.Left = Rect.Width '                                                    start at opposite side of left
  765.                 Rect.Top = Rect.Height '                                                    start at opposite side of top
  766.                 Rect.Right = 0 '                                                            start at opposite side of right
  767.                 Rect.Bottom = 0 '                                                           start at opposite side of bottom
  768.                 osource = _SOURCE '                                                         save current source surface
  769.                 _SOURCE rotatedsprite '                                                     set rotated image as source surface
  770.                 x = 0 '                                                                     reset width counter
  771.                 DO '                                                                        cycle through the width of the image
  772.                     y = 0 '                                                                 reset height counter
  773.                     DO '                                                                    cycle through the height of the image
  774.                         IF POINT(x, y) <> SLSprite(Handle).ClearColor THEN '                is this pixel transparent?
  775.                             '  _________________________________________________________
  776.                             ' | pixel is part of image so look for outer boundary       |
  777.                             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  778.                             IF x < Rect.Left THEN Rect.Left = x '                           no, if left-most so far record it
  779.                             IF y < Rect.Top THEN Rect.Top = y '                             if top-most so far record it
  780.                             IF x > Rect.Right THEN Rect.Right = x '                         if right-most so far record it
  781.                             IF y > Rect.Bottom THEN Rect.Bottom = y '                       if bottom-most so far record it
  782.                         END IF
  783.                         y = y + 1 '                                                         increment height counter
  784.                     LOOP UNTIL y = Rect.Height '                                            leave when height of image reached
  785.                     x = x + 1 '                                                             increment width counter
  786.                 LOOP UNTIL x = Rect.Width '                                                 leave when width of image reached
  787.                 _SOURCE osource '                                                           restore current source surface
  788.                 Rect.Width = Rect.Right - Rect.Left '                                       record width of rotated collision area
  789.                 Rect.Height = Rect.Bottom - Rect.Top '                                      record height of rotated collision area
  790.                 SLRot(RotKey, degree).Coll = Rect '                                         record rotated collision area values
  791.                 _FREEIMAGE rotatedsprite '                                                  remove rotated image from memory
  792.             END IF
  793.             degree = degree + 1 '                                                           increment degree counter
  794.         LOOP UNTIL degree = 360 '                                                           leave when 360 degrees processed
  795.     ELSE '                                                                                  no, this sprite will not rotate
  796.         SLSprite(Handle).Spin.key = 0 '                                                     reset rotation file index pointer
  797.     END IF
  798.     SLSprite(Handle).Spin.Auto = SLFALSE '                                                  disable auto rotation
  799.     SLSprite(Handle).Spin.Rotates = Rotates '                                               enable/disable sprite rotation status
  800.     SLSprite(Handle).Spin.Degree = 0 '                                                      reset rotation degree angle
  801.     SLSprite(Handle).Spin.Rate = 0 '                                                        reset rotation spin rate (speed)
  802.     '  _________________________________________________________________________________
  803.     ' | Reset sprite/mouse interaction settings                                         |
  804.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  805.     SLSprite(Handle).Mouse.Event = SLNONE '                                                 reset most recent mouse interaction
  806.     SLSprite(Handle).Mouse.Xloc = 0 '                                                       reset mouse x coordinate location
  807.     SLSprite(Handle).Mouse.Yloc = 0 '                                                       reset mouse y coordinate location
  808.     SLSprite(Handle).Mouse.SXloc = 0 '                                                      reset mouse on screen x coordinate
  809.     SLSprite(Handle).Mouse.SYloc = 0 '                                                      reset mouse on screen y coordinate
  810.     '  _________________________________________________________________________________
  811.     ' | Reset sprite collision settings                                                 |
  812.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  813.     SLSprite(Handle).Coll.Detect = SLNONE '                                                 reset sprite collision detection method
  814.     SLSprite(Handle).Coll.Event = 0 '                                                       reset collision event trigger
  815.     SLSprite(Handle).Coll.With = 0 '                                                        reset collision with object identifier
  816.     SLSprite(Handle).Coll.Xloc = 0 '                                                        reset collision x coordinate location
  817.     SLSprite(Handle).Coll.Yloc = 0 '                                                        reset collision y coordinate location
  818.     SLSprite(Handle).Coll.Mask = 0 '                                                        reset mask image surface
  819.     SL_MakeSprite = Handle '                                                                return the sprite handle index pointer
  820.  
  821.  
  822. '----------------------------------------------------------------------------------------------------------------------------------
  823. FUNCTION SL_CopySprite (Handle AS INTEGER) '                                                                          SL_CopySprite
  824.     '  ___________________________________________________________________________________________________________________________
  825.     ' | Creates an identical copy of a sprite and assigns a new handle pointer value.                                             |
  826.     ' |---------------------------------------------------------------------------------------------------------------------------|
  827.     ' | Usage : NewSprite = SL_CopySPrite(MySPrite)                                                                               |
  828.     ' |                                                                                                                           |
  829.     ' | Input : Handle = the handle pointer of the sprite being copied                                                            |
  830.     ' | Output: a handle pointer value of the new sprite created                                                                  |
  831.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  832.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  833.     DIM CopyHandle AS INTEGER
  834.  
  835.     CopyHandle = -1 '                                                                       reset handle array index pointer
  836.     DO '                                                                                    cycle through sprite array
  837.         CopyHandle = CopyHandle + 1 '                                                       increment handle array index pointer
  838.     LOOP UNTIL SLSprite(CopyHandle).InUse = SLFALSE OR CopyHandle = UBOUND(SLSprite) '      leave when suitable array index found
  839.     IF SLSprite(CopyHandle).InUse THEN '                                                    is this array index currently in use?
  840.         CopyHandle = CopyHandle + 1 '                                                       yes, increase the array index size
  841.         REDIM _PRESERVE SLSprite(CopyHandle) AS SLSPRITE '                                  create new index in sprite array
  842.     END IF
  843.     SLSprite(CopyHandle) = SLSprite(Handle) '                                               copy the entire contents of sprite
  844.     SLSprite(CopyHandle).OrigImage = _COPYIMAGE(SLSprite(Handle).OrigImage, 32) '           copy the sprite's original image
  845.     IF SLSprite(Handle).OrigMask THEN '                                                     does the sprite being copied have mask?
  846.         SLSprite(CopyHandle).OrigMask = _COPYIMAGE(SLSprite(Handle).OrigMask, 32) '         yes, copy sprite's original image mask
  847.     END IF
  848.     SL_CopySprite = CopyHandle '                                                            return the new sprite's handle pointer
  849.  
  850.  
  851. '----------------------------------------------------------------------------------------------------------------------------------
  852. SUB SL_FreeSprite (Handle AS INTEGER)
  853.     '  ___________________________________________________________________________________________________________________________
  854.     ' | Removes a sprite from the sprite array and all associated images from memory.                                             |
  855.     ' |---------------------------------------------------------------------------------------------------------------------------|
  856.     ' | Usage : SL_FreeSprite(MySprite)                                                                                           |
  857.     ' |                                                                                                                           |
  858.     ' | Input : Handle = the handle pointer of the sprite being removed                                                           |
  859.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  860.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  861.  
  862.     IF SL_ValidSprite(Handle) = SLFALSE THEN SL_Error 1, "SL_FreeSprite" '                  report error if invalid sprite
  863.     IF SLSprite(Handle).OrigMask THEN _FREEIMAGE SLSprite(Handle).OrigMask '                free mask image if present
  864.     IF SLSprite(Handle).ScrnHardware THEN _FREEIMAGE SLSprite(Handle).ScrnHardware '        free screen hardware image if present
  865.     IF SLSprite(Handle).ScrnImage THEN _FREEIMAGE SLSprite(Handle).ScrnImage '              free screen software image if present
  866.     _FREEIMAGE SLSprite(Handle).OrigImage '                                                 free original sprite image
  867.     IF (Handle = UBOUND(slsprite)) AND (Handle <> 0) THEN '                                 is this the last sprite in array?
  868.         REDIM _PRESERVE SLSprite(Handle - 1) AS SLSPRITE '                                  yes, remove last element in array
  869.     ELSE '                                                                                  no, this sprite resides somewhere else
  870.         SLSprite(Handle).InUse = SLFALSE '                                                  mark the index in array as reusable
  871.     END IF
  872.  
  873.  
  874. '----------------------------------------------------------------------------------------------------------------------------------
  875. FUNCTION SL_LoadSheet (Filename AS STRING, CellWidth AS INTEGER, CellHeight AS INTEGER, ClearColor AS _UNSIGNED LONG) 'SL_LoadSheet
  876.     '  ___________________________________________________________________________________________________________________________
  877.     ' | Load a sprite sheet image and create a _MAPTRIANGLE rotation array to be used for sprite rotation.                        |
  878.     ' |---------------------------------------------------------------------------------------------------------------------------|
  879.     ' | Usage : SheetName = ("spritesheet.png", 32, 48, _RGB32(255, 0, 255))                                                      |
  880.     ' |                                                                                                                           |
  881.     ' | Input : filename   = the name of the image file to load as a sprite sheet                                                 |
  882.     ' |         CellWidth  = the width of each sprite on the sheet                                                                |
  883.     ' |         CellHeight = the height of each sprite on the sheet                                                               |
  884.     ' |         ClearColor = the color to use as the transparent layer of the sprite sheet                                        |
  885.     ' | Output: An array index that acts as a handle pointer to the newly loaded sprite sheet                                     |
  886.     ' |                                                                                                                           |
  887.     ' | A .map file will be created with the same name as the image filename provided, "filename.map", that holds precalculated   |
  888.     ' | coordinates that _MAPTRIANGLE will use for sprite rotation.                                                               |
  889.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  890.     SHARED SLSheet() AS SLSHEET '   master sprite sheet array
  891.     SHARED SLMap() AS SLMAP '       master sprite sheet _MAPTRIANGLE coordinate array
  892.     DIM Handle AS INTEGER '         index pointer to new sheet
  893.     DIM MapFileName AS STRING '     name of .map file where _MAPTRIANGLE coordinates are stored
  894.     DIM Degree AS INTEGER '         0 through 359 degree counter
  895.     DIM FileNumber AS INTEGER '     next free file handle
  896.     DIM Polar AS INTEGER '          counter used for calculating _MAPTRIANGLE x,y coordinate pairs
  897.     DIM px(3) AS SINGLE '           _MAPTRIANGLE x coordinates
  898.     DIM py(3) AS SINGLE '           _MAPTRIANGLE y coordinates
  899.     DIM Xoffset AS INTEGER '        _MAPTRIANGLE x coordinate offset to center image
  900.     DIM Yoffset AS INTEGER '        _MAPTRIANGLE y coordinate offset to center image
  901.     DIM x AS SINGLE '               rotated x location of a image corner
  902.     DIM y AS SINGLE '               rotated y location of a image corner
  903.     DIM SINr AS SINGLE '            SIN of image corner rotation
  904.     DIM COSr AS SINGLE '            COSINE of image corner rotation
  905.     DIM Left AS INTEGER '           new left x coordinate of rotated cell image
  906.     DIM Top AS INTEGER '            new top y coordinate of rotated cell image
  907.     DIM Right AS INTEGER '          new right x coordinate of rotated cell image
  908.     DIM Bottom AS INTEGER '         new bottom y coordinate of rotated cell image
  909.     '  _________________________________________________________________________________
  910.     ' | Create a new or use existing unused index in sprite sheet array to hold sheet.  |
  911.     ' |---------------------------------------------------------------------------------|
  912.     ' | When a sprite sheet is removed (SL_RemoveSheet) the array index is marked as    |
  913.     ' | unused and can be later reused by another sprite sheet being loaded. If no      |
  914.     ' | unused array positions exist then a new array index will be created to hold the |
  915.     ' | new sprite sheet's information.                                                 |
  916.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  917.     Handle = -1 '                                                                           reset handle array index pointer
  918.     DO '                                                                                    cycle through sprite sheet array
  919.         Handle = Handle + 1 '                                                               increment handle array index pointer
  920.     LOOP UNTIL SLSheet(Handle).InUse = SLFALSE OR Handle = UBOUND(SLSheet) '                leave when suitable array index found
  921.     IF SLSheet(Handle).InUse THEN '                                                         is this array index currently in use?
  922.         Handle = Handle + 1 '                                                               yes, increase the array index size
  923.         REDIM _PRESERVE SLSheet(Handle) AS SLSHEET '                                        create new index in sprite sheet array
  924.         REDIM _PRESERVE SLMap(Handle, 359) AS SLMAP '                                       create new index in coordinate array
  925.     END IF
  926.     '  _________________________________________________________________________________
  927.     ' | Load sprite sheet and record basic information about the sheet                  |
  928.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  929.     SLSheet(Handle).InUse = SLTRUE '                                                        mark this array index as being used
  930.     SLSheet(Handle).Image = _LOADIMAGE(Filename, 32) '                                      load the sprite sheet image
  931.     SLSheet(Handle).CellWidth = CellWidth '                                                 record each cell's width
  932.     SLSheet(Handle).CellHeight = CellHeight '                                               record each cell's height
  933.     IF ClearColor = SLNOTRANSPARENCY THEN '                                                 has sheet transparency been disabled?
  934.         SLSheet(Handle).ClearColor = SLNOTRANSPARENCY '                                     yes, record this setting
  935.     ELSE '                                                                                  no, set the transparent color of sheet
  936.         _CLEARCOLOR ClearColor, SLSheet(Handle).Image '                                     set the sheet's transparent color
  937.         SLSheet(Handle).ClearColor = _CLEARCOLOR(SLSheet(Handle).Image) '                   record the sheet's transparent color
  938.     END IF
  939.     SLSheet(Handle).Columns = _WIDTH(SLSheet(Handle).Image) \ CellWidth '                   record number of cell columns on sheet
  940.     SLSheet(Handle).Rows = _HEIGHT(SLSheet(Handle).Image) \ CellHeight '                    record number of cell rows on sheet
  941.     SLSheet(Handle).TotalCells = SLSheet(Handle).Columns * SLSheet(Handle).Rows '           record total number of cells on sheet
  942.     '  _________________________________________________________________________________
  943.     ' | Create or retrieve the _MAPTRIANGLE rotational map file for sprite rotation     |
  944.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  945.     MapFileName = LEFT$(Filename, INSTR(Filename, ".")) + "map" '                           create the map file's file name
  946.     FileNumber = FREEFILE '                                                                 get the next free file handle
  947.     IF _FILEEXISTS(MapFileName) THEN '                                                      does the map file already exist?
  948.         '  _____________________________________________________________________________
  949.         ' | The file has been previously created. Open it and load its contents.        |
  950.         ' |-----------------------------------------------------------------------------|
  951.         ' | This is done for speed. Calculations will only need to be performed once    |
  952.         ' | per sprite sheet. However, if the sprite sheet's characteristics are ever   |
  953.         ' | changed the .map file will need to be deleted to have the new coordinate    |
  954.         ' | information calculated and saved. This will be in the documentation.        |
  955.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  956.         OPEN MapFileName FOR BINARY AS #FileNumber '                                        yes, open the map file for reading
  957.         DO '                                                                                cycle through 360 degrees
  958.             GET #FileNumber, , SLMap(Handle, Degree) '                                      get the rotational data for this degree
  959.             Degree = Degree + 1 '                                                           increment degree counter
  960.         LOOP UNTIL Degree = 360 '                                                           leave when 360 degrees cycled through
  961.         CLOSE #FileNumber '                                                                 close the map file
  962.     ELSE '                                                                                  no, the map file does not exist
  963.         '  _____________________________________________________________________________     _____________________________________
  964.         ' | The file must be created. This is the first time the sheet has been loaded. |   | If the .map file were to somehow    |
  965.         ' |-----------------------------------------------------------------------------|   | get deleted from the user's drive   |
  966.         ' | The original cell width and height        px(0),py(0)           px(3),py(3) |   | it will simply get recreated the    |
  967.         ' | are used to calculate the four         ....... +---------------------+      |   | next time the program is executed.  |
  968.         ' | corners of the image. These four          ^    |~\_     _MAPTRIANGLE |      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  969.         ' | corners are then rotated through 360      |    |   ~\_       #2      |      |
  970.         ' | degrees to the new corner locations      cell  |      ~\_            |      |
  971.         ' | for _MAPTRIANGLE, and also to           height |         ~\_         |      |
  972.         ' | calculate the new width and height        |    |            ~\_      |      |
  973.         ' | of the rotated image. These values        |    | _MAPTRIANGLE  ~\_   |      |
  974.         ' | are then saved to a .map file for         V    |      #1          ~\_|      |
  975.         ' | later retrieval to speed up the        ....... +---------------------+      |
  976.         ' | process of _MAPTRIANGLE coordinate        px(1),py(1)           px(2),py(2) |
  977.         ' | calculations. This process will only           :                     :      |
  978.         ' | need to be performed once per sprite           :<--- cell width ---->:      |
  979.         ' | sheet unless the physical character-           :                     :      |
  980.         ' | istics of the sprite sheet change.                                          |
  981.         '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  982.         OPEN MapFileName FOR BINARY AS #FileNumber '                                        open the map file for writing
  983.         Degree = 0 '                                                                        reset the degree counter
  984.         DO '                                                                                cycle through 360 degrees
  985.             px(0) = -CellWidth / 2 '                                                        reset image corner coordinates
  986.             py(0) = -CellHeight / 2
  987.             px(1) = px(0)
  988.             py(1) = CellHeight / 2
  989.             px(2) = CellWidth / 2
  990.             py(2) = py(1)
  991.             px(3) = px(2)
  992.             py(3) = py(0)
  993.             SINr = SIN(-Degree / 57.2957795131) '                                           calculate the SIN of rotation
  994.             COSr = COS(-Degree / 57.2957795131) '                                           calculate the COSINE of rotation
  995.             Left = 0 '                                                                      reset rotated image boundaries
  996.             Top = 0
  997.             Right = 0
  998.             Bottom = 0
  999.             Polar = 0 '                                                                     reset polar coordinate counter
  1000.             DO '                                                                            cycle through the 4 polar coordinates
  1001.                 x = (px(Polar) * COSr + SINr * py(Polar)) '                                 calculate rotated image x corner
  1002.                 y = (py(Polar) * COSr - px(Polar) * SINr) '                                 calculate rotated image y corner
  1003.                 px(Polar) = x '                                                             record new corner x location
  1004.                 py(Polar) = y '                                                             record new corner y location
  1005.                 IF px(Polar) < Left THEN Left = px(Polar) '                                 get smallest left x value seen so far
  1006.                 IF px(Polar) > Right THEN Right = px(Polar) '                               get greatest right x value seen so far
  1007.                 IF py(Polar) < Top THEN Top = py(Polar) '                                   get smallest top y value seen so far
  1008.                 IF py(Polar) > Bottom THEN Bottom = py(Polar) '                             get greatest bottom y value seen so far
  1009.                 Polar = Polar + 1 '                                                         increment to next polar coordinate pair
  1010.             LOOP UNTIL Polar = 4 '                                                          leave when all four corners processed
  1011.             SLMap(Handle, Degree).width = Right - Left + 1 '                                record the width of the rotated image
  1012.             SLMap(Handle, Degree).height = Bottom - Top + 1 '                               record the height of the rotated image
  1013.             Xoffset = SLMap(Handle, Degree).width \ 2 '                                     calculate x offset to center image
  1014.             Yoffset = SLMap(Handle, Degree).height \ 2 '                                    calculate y offset to center image
  1015.             SLMap(Handle, Degree).px0 = INT(px(0)) + Xoffset '                              record all 4 centered coordinate pairs
  1016.             SLMap(Handle, Degree).px1 = INT(px(1)) + Xoffset
  1017.             SLMap(Handle, Degree).px2 = INT(px(2)) + Xoffset
  1018.             SLMap(Handle, Degree).px3 = INT(px(3)) + Xoffset
  1019.             SLMap(Handle, Degree).py0 = INT(py(0)) + Yoffset
  1020.             SLMap(Handle, Degree).py1 = INT(py(1)) + Yoffset
  1021.             SLMap(Handle, Degree).py2 = INT(py(2)) + Yoffset
  1022.             SLMap(Handle, Degree).py3 = INT(py(3)) + Yoffset
  1023.             PUT #1, , SLMap(Handle, Degree) '                                               save the rotational data for the degree
  1024.             Degree = Degree + 1 '                                                           increment the degree counter
  1025.         LOOP UNTIL Degree = 360 '                                                           leave when 360 degrees cycled through
  1026.         CLOSE #FileNumber '                                                                 close the map file
  1027.     END IF
  1028.     '  _________________________________________________________________________________
  1029.     ' | Return the array index as a pointer to this new sprite sheet                    |
  1030.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1031.     SL_LoadSheet = Handle '                                                                 return array index pointer to new sheet
  1032.  
  1033.  
  1034. '----------------------------------------------------------------------------------------------------------------------------------
  1035. SUB SL_GetCellCoordinates (Sheet AS INTEGER, Cell AS INTEGER, Rect AS SLRECT) '                               SL_GetCellCoordinates
  1036.     '  ___________________________________________________________________________________________________________________________
  1037.     ' | Returns the rectangular coordinates of a cell given the sprite sheet that it belongs to.                                  |
  1038.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1039.     ' | Usage : SL_GetCellCoordinates MySheet, CellNumber, RectStructure                                                          |
  1040.     ' |                                                                                                                           |
  1041.     ' | Input : Sheet = the handle pointer of the sheet the cell resides in                                                       |
  1042.     ' |         Cell  = the cell number to return the coordinates of                                                              |
  1043.     ' |         Rect  = the rectangular structure (SLRECT) that the resuls are returned in                                        |
  1044.     ' |                                                                                                                           |
  1045.     ' | Output: the values in Rect will be modified with the coordinate information:                                              |
  1046.     ' |         Rect.left   = left   x coordinate of cell                                                                         |
  1047.     ' |         Rect.top    = top    y coordinate of cell                                                                         |
  1048.     ' |         Rect.right  = right  x coordinate of cell                                                                         |
  1049.     ' |         Rect.bottom = bottom y coordinate of cell                                                                         |
  1050.     ' |         Rect.width  = width of cell                                                                                       |
  1051.     ' |         Rect.height = height of cell                                                                                      |
  1052.     ' |          _________________________________________________________                                                        |
  1053.     ' | Note  : | ** INTERNAL USE ONLY ** not to be used by programmer ** |                                                       |
  1054.     ' |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                        |
  1055.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1056.     SHARED SLSheet() AS SLSHEET '   master sprite sheet array
  1057.     DIM Column AS INTEGER '         the column the cell resides in
  1058.     DIM Row AS INTEGER '            the row the cell resides in
  1059.     '  _________________________________________________________________________________
  1060.     ' | Calculate the row and column the sheet's cell reside in                         |
  1061.     ' |---------------------------------------------------------------------------------|
  1062.     ' | Sprite images within a sprite sheet are seen as cells with equal widths and     |
  1063.     ' | heights. The cells are numbered beginning at the top left corner and counting   |
  1064.     ' | to the right, beginning again at the next row down when the end of the current  |
  1065.     ' | row has been reached.                                                           |
  1066.     ' |                              <----- COLUMNS ----->                              |
  1067.     ' |                    1         2         3         4         5 ....               |
  1068.     ' |               +-------------------------------------------------+               |
  1069.     ' |               |         |         |         |         |         |               |
  1070.     ' |        ^    1 | cell 01 | cell 02 | cell 03 | cell 04 | cell 05 |               |
  1071.     ' |        |      |         |         |         |         |         |               |
  1072.     ' |        |      +-------------------------------------------------+               |
  1073.     ' |        |      |         |         |         |         |         |               |
  1074.     ' |      ROWS   2 | cell 06 | cell 07 | cell 08 | cell 09 | cell 10 |               |
  1075.     ' |        |      |         |         |         |         |         |               |
  1076.     ' |        |      +-------------------------------------------------+               |
  1077.     ' |        |      |         |         |         |         |         |               |
  1078.     ' |        V    3 | cell 11 | cell 12 | cell 13 | cell 14 | cell 15 |               |
  1079.     ' |             : |         |         |         |         |         |               |
  1080.     ' |             : +-------------------------------------------------+               |
  1081.     ' |                                                                                 |
  1082.     ' | Modulus division using the cell number will yield the current column a cell     |
  1083.     ' | resides in, execpt for the far right column. The result of a modulus division   |
  1084.     ' | with a cell in the far right column will produce 0 (zero). A result of zero can |
  1085.     ' | then be interpreted as the cell being in the column farthest to the right.      |
  1086.     ' |                                                                                 |
  1087.     ' | Once you have the column a cell resides in you can then subract that value from |
  1088.     ' | the cell, divide that result by the total number of columns and add 1 to get    |
  1089.     ' | the row a cell resides in.                                                      |
  1090.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1091.     Column = Cell MOD SLSheet(Sheet).Columns '                                              MOD remainder equals the column number
  1092.     IF Column = 0 THEN Column = SLSheet(Sheet).Columns '                                    unless it's 0, then column is greatest
  1093.     Row = (Cell - Column) / SLSheet(Sheet).Columns + 1 '                                    calculate the row number from column
  1094.     '  _________________________________________________________________________________
  1095.     ' | Calculate and return the rectangular coordinates of the sheet's cell            |
  1096.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1097.     Rect.Left = (Column - 1) * SLSheet(Sheet).CellWidth '                                   calculate left x coordinate of cell
  1098.     Rect.Top = (Row - 1) * SLSheet(Sheet).CellHeight '                                      calculate top y coordinate of cell
  1099.     Rect.Right = Rect.Left + SLSheet(Sheet).CellWidth - 1 '                                 calculate right x coordinate of cell
  1100.     Rect.Bottom = Rect.Top + SLSheet(Sheet).CellHeight - 1 '                                calculate bottom y coordinate of cell
  1101.     Rect.Width = SLSheet(Sheet).CellWidth '                                                 report cell width
  1102.     Rect.Height = SLSheet(Sheet).CellHeight '                                               report cell height
  1103.  
  1104.  
  1105. '----------------------------------------------------------------------------------------------------------------------------------
  1106. FUNCTION SL_FixDegree (Degree AS INTEGER) '                                                                            SL_FixDegree
  1107.     '  ___________________________________________________________________________________________________________________________
  1108.     ' | Returns a corrected degree value of 0 to 359 given the value passed in.                                                   |
  1109.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1110.     ' | Usage : ValidDegree = SL_FixDegree(720)                                                                                   |
  1111.     ' |                                                                                                                           |
  1112.     ' | Input : Degree = the degree value to correct                                                                              |
  1113.     ' | Output: the corrected degree value between 0 and 359 degrees                                                              |
  1114.     ' | Credit: This function uses code contributed by CodeGuy - https://www.qb64.org/forum/index.php?topic=537.15                |
  1115.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1116.     DIM Deg AS INTEGER '            degree value supplied
  1117.  
  1118.     Deg = Degree MOD 360 '                                                                  get -359 to 359
  1119.     IF Deg < 0 THEN '                                                                       need to make positive?
  1120.         SL_FixDegree = Deg + 360 '                                                          yes, correct value and return degree
  1121.     ELSE '                                                                                  no correction needed
  1122.         SL_FixDegree = Deg '                                                                return degree
  1123.     END IF
  1124.  
  1125.  
  1126. '----------------------------------------------------------------------------------------------------------------------------------
  1127. FUNCTION SL_PPDistance (x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER) '                                 SL_PPDistance
  1128.     '  ___________________________________________________________________________________________________________________________
  1129.     ' | Calculates the distance in pixels between any two coordinate pair points.                                                 |
  1130.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1131.     ' | Usage : Distance = SL_PPDistance(100, 100, 200, 200)                                                                      |
  1132.     ' |                                                                                                                           |
  1133.     ' | Input : x1 = x coordinate location of first point                                                                         |
  1134.     ' |         y1 = y coordinate location of first point                                                                         |
  1135.     ' |         x2 = x coordinate location of second point                                                                        |
  1136.     ' |         y2 = y coordinate location of second point                                                                        |
  1137.     ' | Output: the distance in pixels between the two coordinate pair points                                                     |
  1138.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1139.     DIM SideA AS INTEGER '          side A of right triangle
  1140.     DIM SideB AS INTEGER '          side B of right triangle
  1141.     '  _________________________________________________________________________________
  1142.     ' | Use Pythagoras to calculate the distance between the two points.                |
  1143.     ' |---------------------------------------------------------------------------------|
  1144.     ' | By using the Pythagorean Theorum                               x1,y1            |
  1145.     ' | Aý + Bý = Cý the distance between any                           /|              |
  1146.     ' | two points can be calculated by                               /  |              |
  1147.     ' | creating a right triangle between the                       /    |              |
  1148.     ' | two points, solving for sides A and B,        hypotenuse  /      |              |
  1149.     ' | and then solving for side C, the                SIDE C  /        | SIDE B       |
  1150.     ' | hypotenuse. The following formula can                 /          |              |
  1151.     ' | be utilized:                                        /            |              |
  1152.     ' |       _________                                   /              |              |
  1153.     ' |  C = û Aý + Bý                                  /               _|              |
  1154.     ' |                                               /________________I_|              |
  1155.     ' |                                            x2,y2     SIDE A                     |
  1156.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1157.     SideA = x1 - x2 '                                                                       calculate length of side A
  1158.     SideB = y1 - y2 '                                                                       calculate length of side B
  1159.     SL_PPDistance = INT(SQR(SideA * SideA + SideB * SideB)) '                               return length of side C (hypotenuse)
  1160.  
  1161.  
  1162. '----------------------------------------------------------------------------------------------------------------------------------
  1163. FUNCTION SL_SSDistance (Handle1 AS INTEGER, Handle2 AS INTEGER) '                                                     SL_SSDistance
  1164.     '  ___________________________________________________________________________________________________________________________
  1165.     ' | Calculates the distance in pixels between any two supplied sprites.                                                       |
  1166.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1167.     ' | Usage : Distance = SL_SSDistance(Sprite1, Sprite2)                                                                        |
  1168.     ' |                                                                                                                           |
  1169.     ' | Input : Handle1 = the handle pointer name of first sprite                                                                 |
  1170.     ' |         Handle2 = the handle pointer name of second sprite                                                                |
  1171.     ' | Output: the distance in pixels between the two supplied sprites                                                           |
  1172.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1173.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1174.     '  _________________________________________________________________________________
  1175.     ' | Pass the sprite coordinates to SL_PPDistance to use Pythagoras to calculate.    |
  1176.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1177.     SL_SSDistance = SL_PPDistance(SLSprite(Handle1).Centerx, SLSprite(Handle1).Centery,_
  1178.                                   SLSprite(Handle2).Centerx, SLSprite(Handle2).Centery) '   return distance between the sprites
  1179.  
  1180.  
  1181. '----------------------------------------------------------------------------------------------------------------------------------
  1182. FUNCTION SL_SPDistance (Handle AS INTEGER, x AS INTEGER, y AS INTEGER) '                                              SL_SPDistance
  1183.     '  ___________________________________________________________________________________________________________________________
  1184.     ' | Calculates the distance in pixels between a sprite and a coordinate point.                                                |
  1185.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1186.     ' | Usage : Distance = SL_SPDistance(Sprite, 100, 100)                                                                        |
  1187.     ' |                                                                                                                           |
  1188.     ' | Input : Handle = the handle pointer name of the sprite                                                                    |
  1189.     ' |         x      = the x coordinate value of the point                                                                      |
  1190.     ' |         y      = the y coordinate value of the point                                                                      |
  1191.     ' | Output: the distance in pixels between the sprite and the supplied coordinate point                                       |
  1192.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1193.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1194.     '  _________________________________________________________________________________
  1195.     ' | Pass the sprite coordinates and supplied coordinate to SL_PPDistance to use     |
  1196.     ' | Pythagoras to calculate.                                                        |
  1197.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1198.     SL_SPDistance = SL_PPDistance(SLSprite(Handle).Centerx, SLSprite(Handle).Centery, x, y) 'return distance to point from sprite
  1199.  
  1200.  
  1201. '----------------------------------------------------------------------------------------------------------------------------------
  1202. FUNCTION SL_PPAngle (x1 AS INTEGER, y1 AS INTEGER, x2 AS INTEGER, y2 AS INTEGER) '                                       SL_PPAngle
  1203.     '  ___________________________________________________________________________________________________________________________
  1204.     ' | Calculates the angle (0 to 359) between two coordinate pairs.                                                             |
  1205.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1206.     ' | Usage : Angle = SL_PPAngle(100, 100, 200, 200)                                                                            |
  1207.     ' |                                                                                                                           |
  1208.     ' | Input : x1 = x coordinate location of first point                                                                         |
  1209.     ' |         y1 = y coordinate location of first point                                                                         |
  1210.     ' |         x2 = x coordinate location of second point                                                                        |
  1211.     ' |         y2 = y coordinate location of second point                                                                        |
  1212.     ' | Output: the angle from x1,y1 to x2,y2.                                                                                    |
  1213.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1214.     DIM angle AS INTEGER '          angle from x1,y1 to x2,y2
  1215.  
  1216.     IF y1 = y2 THEN '                                                                       both y values same?
  1217.         IF x1 = x2 THEN '                                                                   yes, both x values same?
  1218.             EXIT FUNCTION '                                                                 yes, there is no angle (0), leave
  1219.         END IF
  1220.         IF x2 > x1 THEN '                                                                   is second x to the right of first x?
  1221.             SL_PPAngle = 90 '                                                               yes, the angle must be 90 degrees
  1222.         ELSE '                                                                              no, second x is to the left of first x
  1223.             SL_PPAngle = 270 '                                                              the angle must be 270 degrees
  1224.         END IF
  1225.         EXIT FUNCTION '                                                                     leave function, angle computed
  1226.     END IF
  1227.     IF x1 = x2 THEN '                                                                       both x values same?
  1228.         IF y2 > y1 THEN '                                                                   yes, is second y lower than first y?
  1229.             SL_PPAngle = 180 '                                                              yes, the angle must be 180
  1230.         END IF
  1231.         EXIT FUNCTION '                                                                     leave function, angle computed
  1232.     END IF
  1233.     angle = ATN((x2 - x1) / (y2 - y1)) * -57.2957795131 '                                   calculate initial angle
  1234.     IF y2 < y1 THEN '                                                                       is second y higher than first y?
  1235.         IF x2 > x1 THEN '                                                                   yes, is second x to right of first x?
  1236.             SL_PPAngle = angle '                                                            yes, angle needs no adjustment
  1237.         ELSE '                                                                              no, second x is to left of first x
  1238.             SL_PPAngle = angle + 360 '                                                      adjust angle accordingly
  1239.         END IF
  1240.     ELSE '                                                                                  no, second y is lower than first y
  1241.         SL_PPAngle = angle + 180 '                                                          adjust angle accordingly
  1242.     END IF
  1243.  
  1244.  
  1245. '----------------------------------------------------------------------------------------------------------------------------------
  1246. FUNCTION SL_SSAngle (Handle1 AS INTEGER, Handle2 AS INTEGER) '                                                           SL_SSAngle
  1247.     '  ___________________________________________________________________________________________________________________________
  1248.     ' | Calculates the angle between any two supplied sprites.                                                                    |
  1249.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1250.     ' | Usage : Angle = SL_SSAngle(Sprite1, Sprite2)                                                                              |
  1251.     ' |                                                                                                                           |
  1252.     ' | Input : Handle1 = the handle pointer name of first sprite                                                                 |
  1253.     ' |         Handle2 = the handle pointer name of second sprite                                                                |
  1254.     ' | Output: the angle from sprite1 to sprite2                                                                                 |
  1255.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1256.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1257.     '  _________________________________________________________________________________
  1258.     ' | Pass the sprite coordinates to SL_PPAngle to calculate the angle.               |
  1259.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1260.     SL_SSAngle = SL_PPAngle(SLSprite(Handle1).Centerx, SLSprite(Handle1).Centery,_
  1261.                             SLSprite(Handle2).Centerx, SLSprite(Handle2).Centery) '         return the angle between the sprites
  1262.  
  1263.  
  1264. '----------------------------------------------------------------------------------------------------------------------------------
  1265. FUNCTION SL_SPAngle (Handle AS INTEGER, x AS INTEGER, y AS INTEGER) '                                                    SL_SPAngle
  1266.     '  ___________________________________________________________________________________________________________________________
  1267.     ' | Calculates the angle between a sprite an a supplied coordinate pair.                                                      |
  1268.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1269.     ' | Usage : Angle = SL_SPAngle(Sprite, 100, 100)                                                                              |
  1270.     ' |                                                                                                                           |
  1271.     ' | Input : Handle = the handle pointer name of the sprite                                                                    |
  1272.     ' |         x      = the x coordinate value of the point                                                                      |
  1273.     ' |         y      = the y coordinate value of the point                                                                      |
  1274.     ' | Output: the angle from the sprite to the supplied coordinate pair.                                                        |
  1275.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1276.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1277.     '  _________________________________________________________________________________
  1278.     ' | Pass the sprite coordinates to SL_PPAngle to calculate the angle.               |
  1279.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1280.     SL_SPAngle = SL_PPAngle(SLSprite(Handle).Centerx, SLSprite(Handle).Centery, x, y) '     return the angle from sprite to point
  1281.  
  1282.  
  1283. '----------------------------------------------------------------------------------------------------------------------------------
  1284. SUB SL_SpriteSet (Handle AS INTEGER, Action AS INTEGER, Value AS LONG) ' (MULTI-FUNCTION COMMAND)                      SL_SpriteSet
  1285.     '  ___________________________________________________________________________________________________________________________
  1286.     ' | Sets various aspects of sprite depending on action and value provided.                                                    |
  1287.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1288.     ' | Usage : SL_SpriteSet MySPrite, SLZOOM, 150                                                                                |
  1289.     ' |                                                                                                                           |
  1290.     ' | Input : Handle = the handle pointer name of the sprite                                                                    |
  1291.     ' |         Action = the setting to be acted upon                                                                             |
  1292.     ' |         Value  = the new setting value                                                                                    |
  1293.     ' |                                                                                                                           |
  1294.     ' | Valid Action and Value combinations:                                                                                      |
  1295.     ' |                                                                                                                           |
  1296.     ' |     Action           Value(s)                                   Description                                               |
  1297.     ' | --------------  ------------------  ------------------------------------------------------------------------------------- |
  1298.     ' | SLZOOM          1 - 32767           Sets the zoom level for a sprite (100 = 100%, 200 = 200%, etc..)                      |
  1299.     ' | SLFLIP          SLNONE              reset sprite's orientation to normal (no flipping)                                    |
  1300.     ' |                 SLVERTICAL          flips a sprite vertically                                                             |
  1301.     ' |                 SLHORIZONTAL        flips a sprite horizontally                                                           |
  1302.     ' |                 SLBOTH              flips a sprite both horizontally and vertically                                       |
  1303.     ' | SLVISIBLE       SLTRUE              sets the sprite as visible on screen                                                  |
  1304.     ' |                 SLFALSE             sets the sprite as invisible (will not be shown on screen)                            |
  1305.     ' | SLLAYER         0 - max layers      sets the layer associated with the sprite                                             |
  1306.     ' | SLSCORE         any LONG INT        sets the score associated with a sprite                                               |
  1307.     ' | SLAUTOANIMATE   SLTRUE              enables sprite auto-animation                                                         |
  1308.     ' |                 SLFALSE             disables sprite auto-animation                                                        |
  1309.     ' | SLFROMCELL      1 - max cells       sets the sprite's animation sequence starting cell number (must be less than ending)  |
  1310.     ' | SLTOCELL        1 - max cells       sets the sprite's animation sequence ending cell number (must be greater than start)  |
  1311.     ' | SLANIMATEDIR    SLFORWARD           animation sequence will proceed from start to end then recylce back to start          |
  1312.     ' |                 SLBACKWARD          animation sequence will proceed from end to start then recycle back to end            |
  1313.     ' |                 SLBACKFORTH         animation sequence will proceed SLFORWARD, then SLBACKWARD, then recyle to SLFORWARD  |
  1314.     ' | SLFRAMERATE     1 - global rate     sets the local independent frame rate of the sprite                                   |
  1315.     ' | SLAUTOMOTION    SLTRUE              enables sprite auto-motion                                                            |
  1316.     ' |                 SLFALSE             disables sprite auto-motion                                                           |
  1317.     ' | SLMOTIONANGLE   -359 to 359         sets the sprite's direction of motion (SLXDIR and SLYDIR computed from this)          |
  1318.     ' | SLXDIR          -32768 - 32767      sets the sprite's x motion vextor (used to over-ride SLMOTIONANGLE if desired)        |
  1319.     ' | SLYDIR          -32768 - 32767      sets the sprite's y motion vector (used to over-ride SLMOTIONANGLE if desired)        |
  1320.     ' | SLAUTOROTATE    SLTRUE              enables sprite auto-rotation                                                          |
  1321.     ' |                 SLFALSE             disables sprite auto-rotation                                                         |
  1322.     ' | SLROTATEANGLE   -359 to 359         set rotation angle of sprite                                                          |
  1323.     ' | SLROTATESPEED   -359 to 359         set the rotation rate (or spin) of a sprite                                           |
  1324.     ' | SLDETECTION     SLNONE              disable sprite collision detection                                                    |
  1325.     ' |                 SLRECTANGLE         enable rectangular sprite collision detection                                         |
  1326.     ' |                 SLCIRCLE            enable circular sprite collision detection                                            |
  1327.     ' |                 SLPIXEL             enable pixel-perfect sprite collision detection                                       |
  1328.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1329.     SHARED SLSheet() AS SLSHEET '   master sprite sheet array
  1330.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1331.     SHARED SLGlobal AS SLGLOBAL '   global variables
  1332.  
  1333.     IF SL_ValidSprite(Handle) = SLFALSE THEN SL_Error 1, "SL_SpriteSet" '                   report error if invalid sprite
  1334.     SELECT CASE Action '                                                                    which value will be set?
  1335.         CASE SLZOOM '                                                                       set sprite zoom level
  1336.             '  _________________________________________________________________________
  1337.             ' | Valid values: 1 through 32767                                           |
  1338.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1339.             IF (Value < 1) OR (Value > 32767) THEN SL_Error 2, "SL_SpriteSet" '             report error if invalid zoom level
  1340.             SLSprite(Handle).Zoom = Value '                                                 set sprite's zoom level
  1341.         CASE SLFLIP '                                                                       set sprite flipping behavior
  1342.             '  _________________________________________________________________________
  1343.             ' | Valid values: SLNONE, SLVERTICAL, SLHORIZONTAL, SLBOTH                  |
  1344.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1345.             IF (Value < SLNONE) OR (Value > SLBOTH) THEN SL_Error 3, "SL_SpriteSet" '       report error if invalid flip setting
  1346.             SLSprite(Handle).Flipped = Value '                                              set sprite's flipping behavior
  1347.         CASE SLVISIBLE '                                                                    set sprite visibility
  1348.             '  _________________________________________________________________________
  1349.             ' | Valid values: SLTRUE, SLFALSE                                           |
  1350.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1351.             IF (Value <> SLFALSE) AND (Value <> SLTRUE) THEN SL_Error 4, "SL_SpriteSet" '   reprt error if invalid visible setting
  1352.             SLSprite(Handle).Visible = Value '                                              set sprite's visibility
  1353.         CASE SLLAYER '                                                                      set layer sprite belongs to
  1354.             '  _________________________________________________________________________
  1355.             ' | Valid values: 0 through UBOUND(SLLayers)                                |
  1356.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1357.             IF (Value < 0) OR (Value > SLGlobal.Layers) THEN SL_Error 5, "SL_SpriteSet" '   report error if invalid layer requested
  1358.             SLSprite(Handle).Layer = Value '                                                set sprite's layer
  1359.         CASE SLSCORE '                                                                      set score value of sprite
  1360.             '  _________________________________________________________________________
  1361.             ' | Valid values: any number in LONG integer range                          |
  1362.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1363.             SLSprite(Handle).Score = Value '                                                set sprite's score
  1364.         CASE SLAUTOANIMATE '                                                                enable or disable auto animation
  1365.             '  _________________________________________________________________________
  1366.             ' | Valid values: SLTRUE, SLFALSE                                           |
  1367.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1368.             IF (Value <> SLFALSE) AND (Value <> SLTRUE) THEN SL_Error 6, "SL_SpriteSet" '   report error if invalid auto-motion
  1369.             SLSprite(Handle).Anim.Auto = Value '                                            set sprite's auto-motion
  1370.         CASE SLFROMCELL '                                                                   set animation starting cell
  1371.             '  _________________________________________________________________________
  1372.             ' | Valid values: 1 through total number of cells on sheet                  |
  1373.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1374.             IF (Value < 1) OR (Value > SLSheet(SLSprite(Handle).OrigSheet).TotalCells) THEN 'invalid cell requested?
  1375.                 SL_Error 7, "SL_SpriteSet" '                                                yes, report error
  1376.             END IF
  1377.             SLSprite(Handle).Anim.FromCell = Value '                                        set sprite's animation start cell
  1378.         CASE SLTOCELL '                                                                     set animation ending cell
  1379.             '  _________________________________________________________________________
  1380.             ' | Valid values: 1 through total number of cells on sheet                  |
  1381.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1382.             IF (Value < 1) OR (Value > SLSheet(SLSprite(Handle).OrigSheet).TotalCells) OR _
  1383.                (Value <= SLSprite(Handle).Anim.FromCell) THEN '                             invalid cell requested?
  1384.                 SL_Error 7, "SL_SpriteSet" '                                                yes, report error
  1385.             END IF
  1386.             SLSprite(Handle).Anim.ToCell = Value '                                          set sprite's animation end cell
  1387.         CASE SLANIMATEDIR '                                                                 set direction of animation sequence
  1388.             '  _________________________________________________________________________
  1389.             ' | Valid values: SLFORWARD, SLBACKWARD, SLBACKFORTH                        |
  1390.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1391.             IF (Value < SLFORWARD) OR (Value > SLBACKFORTH) THEN SL_Error 8, "SL_SpriteSet" 'report error if invalid direction
  1392.             SLSprite(Handle).Anim.Direction = Value '                                       set sprite's animation direction
  1393.         CASE SLFRAMERATE '                                                                  set local animation frame rate
  1394.             '  _________________________________________________________________________
  1395.             ' | Valid values: 1 through global frame rate                               |
  1396.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1397.             IF (Value < 1) OR (Value > SLGlobal.FrameRate) THEN SL_Error 9, "SL_SpriteSet" 'report error if invalid frame rate
  1398.             SLSprite(Handle).Anim.FrameRate = Value '                                       set sprite's local frame rate
  1399.         CASE SLAUTOMOTION '                                                                 enable or disable auto motion
  1400.             '  _________________________________________________________________________
  1401.             ' | Valid values: SLTRUE, SLFALSE                                           |
  1402.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1403.             IF (Value <> SLFALSE) AND (Value <> SLTRUE) THEN SL_Error 10, "SL_SpriteSet" '  report error if invalid auto motion
  1404.             SLSprite(Handle).Move.Auto = Value '                                            set sprite's auto motion
  1405.         CASE SLMOTIONANGLE '                                                                set angle in degrees of motion
  1406.             '  _________________________________________________________________________
  1407.             ' | Valid values: -359 through 359                                          |
  1408.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1409.             SLSprite(Handle).Move.Degree = SL_FixDegree(Value) '                            set sprite's angle of motion
  1410.         CASE SLXDIR '                                                                       set x motion direction vector
  1411.             '  _________________________________________________________________________
  1412.             ' | Valid values: -32768 through 32767                                      |
  1413.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1414.             IF (Value < -32768) OR (Value > 32767) THEN SL_Error 11, "SL_SpriteSet" '       report error if invalid x vector value
  1415.             SLSprite(Handle).Move.Xdir = Value '                                            set sprite's x vector
  1416.         CASE SLYDIR '                                                                       set y motion direction vector
  1417.             '  _________________________________________________________________________
  1418.             ' | Valid values: -32768 through 32767                                      |
  1419.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1420.             IF (Value < -32768) OR (Value > 32767) THEN SL_Error 12, "SL_SpriteSet" '       report error if invalid y vector value
  1421.             SLSprite(Handle).Move.Ydir = Value '                                            set sprite's y vector
  1422.         CASE SLAUTOROTATE '                                                                 enable or disable auto rotation
  1423.             '  _________________________________________________________________________
  1424.             ' | Valid values: SLTRUE, SLFALSE                                           |
  1425.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1426.             IF (Value <> SLFALSE) AND (Value <> SLTRUE) THEN SL_Error 13, "SL_SpriteSet" '  report error if invalid auto rotation
  1427.             SLSprite(Handle).Spin.Auto = Value '                                            set sprite's auto rotation
  1428.         CASE SLROTATEANGLE '                                                                set angle in degrees of rotation
  1429.             '  _________________________________________________________________________
  1430.             ' | Valid values: -359 through 359                                          |
  1431.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1432.             SLSprite(Handle).Spin.Degree = SL_FixDegree(Value) '                            set sprite's angle of rotation
  1433.         CASE SLROTATESPEED '                                                                set spin speed of rotation
  1434.             '  _________________________________________________________________________
  1435.             ' | Valid values: -359 through 359                                          |
  1436.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1437.             IF ABS(Value) > 359 THEN SL_Error 14, "SL_SpriteSet" '                          report error if invalid rotate speed
  1438.             SLSprite(Handle).Spin.Rate = Value '                                            set sprite's spin rate
  1439.         CASE SLDETECTION '                                                                  set sprite collision detection method
  1440.             '  _________________________________________________________________________
  1441.             ' | Valid values: SLNONE, SLRECTANGLE, SLCIRCLE, SLPIXEL                    |
  1442.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1443.             IF (Value < SLNONE) OR (Value > SLPIXEL) THEN SL_Error 15, "SL_SpriteSet" '     report error if invalid detection
  1444.             SLSprite(Handle).Coll.Detect = Value '                                          set sprite's collision detection method
  1445.         CASE ELSE
  1446.             SL_Error 16, "SL_SpriteSet" '                                                   report invalid use of command
  1447.     END SELECT
  1448.  
  1449.  
  1450. '----------------------------------------------------------------------------------------------------------------------------------
  1451. FUNCTION SL_SpriteGet (Handle AS INTEGER, Action AS INTEGER) ' (MULTI-FUNCTION COMMAND)                                SL_SpriteGet
  1452.     '  ___________________________________________________________________________________________________________________________
  1453.     ' | Gets various aspects of a sprite depending on the action provided.                                                        |
  1454.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1455.     ' | Usage : Setting = SL_SpriteGet(MySprite, SLZOOM)                                                                          |
  1456.     ' |                                                                                                                           |
  1457.     ' | Input : Handle = the handle pointer name of the sprite                                                                    |
  1458.     ' |         Action = the setting to be acted upon                                                                             |
  1459.     ' | Output: A return value based on the setting to obtain a value from                                                        |
  1460.     ' |                                                                                                                           |
  1461.     ' | Valid Actions and their return value(s):                                                                                  |
  1462.     ' |                                                                                                                           |
  1463.     ' |     Action       Return Value(s)                                Description                                               |
  1464.     ' | --------------  ------------------  ------------------------------------------------------------------------------------- |
  1465.     ' | SLZOOM          1 - 32767           retrieve the current zoom level of the sprite (100 = 100%, 200 = 200%, etc..)         |
  1466.     ' | SLFLIP          SLNONE              sprite flipping disabled                                                              |
  1467.     ' |                 SLVERTICAL          sprite set to flip vertically                                                         |
  1468.     ' |                 SLHORIZONTAL        sprite set to flip horizontally                                                       |
  1469.     ' |                 SLBOTH              sprite set to flip vertically and horizontally                                        |
  1470.     ' | SLVISIBLE       SLTRUE              sprite is set to be visible on screen                                                 |
  1471.     ' |                 SLFALSE             sprite is set to be invisible                                                         |
  1472.     ' | SLLAYER         1 to max layers     the layer a sprite belongs to                                                         |
  1473.     ' | SLSCORE         Any LONG integer    the score associated with the sprite                                                  |
  1474.     ' | SLLEFT          -32768 to 32767     the left x coordinate of the sprite                                                   |
  1475.     ' | SLTOP           -32768 to 32767     the top y coordinate of the sprite                                                    |
  1476.     ' | SLRIGHT         -32768 to 32767     the right x coordinate of the sprite                                                  |
  1477.     ' | SLBOTTOM        -32768 to 32767     the bottom y coordinate of the sprite                                                 |
  1478.     ' | SLWIDTH         1 to 32767          the width of the sprite                                                               |
  1479.     ' | SLHEIGHT        1 to 32767          the height of the sprite                                                              |
  1480.     ' | SLCENTERX       1 to 16382          the center x coordinate of the sprite                                                 |
  1481.     ' | SLCENTERY       1 to 16382          the center y coordinate of the sprite                                                 |
  1482.     ' | SLFRAMERATE     1 to global rate    the current independent animation frame rate of the sprite                            |
  1483.     ' | SLAUTOANIMATE   SLTRUE              auto-animation is enabled for the sprite                                              |
  1484.     ' |                 SLFALSE             auto-animation is disabled for the sprite                                             |
  1485.     ' | SLFROMCELL      1 to max cells      the sprite's animation start cell (must be less than SLTOCELL)                        |
  1486.     ' | SLTOCELL        1 to max cells      the sprite's animation end cell (must be greater than SLFROMCELL)                     |
  1487.     ' | SLANIMATEDIR    SLFORWARD           the sprite's animation will proceed from start to end cell then back to start         |
  1488.     ' |                 SLBACKWARD          the sprite's animation will proceed from end to start cell then back to end           |
  1489.     ' |                 SLBACKFORTH         the sprite's animation will proceed from start to end then end to start               |
  1490.     ' | SLAUTOMOTION    SLTRUE              auto-motion is enabled for the sprite                                                 |
  1491.     ' |                 SLFALSE             auto-motion is disabled for the sprite                                                |
  1492.     ' | SLMOTIONANGLE   0 to 359            the sprite's current angle of motion                                                  |
  1493.     ' | SLXDIR          -32768 to 32767     the sprite's current x motion vector                                                  |
  1494.     ' | SLYDIR          -32768 to 32767     the sprite's current y motion vector                                                  |
  1495.     ' | SLAUTOROTATE    SLTRUE              auto-rotation is enabled for the sprite                                               |
  1496.     ' |                 SLFALSE             auto-rotation is disabled for the sprite                                              |
  1497.     ' | SLROTATEANGLE   0 to 359            the sprite's current rotation angle                                                   |
  1498.     ' | SLROTATESPEED   0 to 359            the sprite's current spin rate                                                        |
  1499.     ' | SLDETECTION     SLNONE              collision detection for the sprite is disabled                                        |
  1500.     ' |                 SLRECTANGLE         collision detection is set to rectangle collsiion                                     |
  1501.     ' |                 SLCIRCLE            collision detection is set for circular collision                                     |
  1502.     ' |                 SLPIXEL             collsiion detection is set for pixel-perfect collision                                |
  1503.     ' | SLCOLLISION     SLTRUE              this sprite has collided with another object                                          |
  1504.     ' |                 SLFALSE             no collisions have been detected with this sprite                                     |
  1505.     ' | SLCOLLIDEWITH   1 to max sprites    the sprite has collided with this sprite                                              |
  1506.     ' |                 SLNONE              no other sprite has been collided with                                                |
  1507.     ' | SLCOLLIDEX      -32768 to 32767     the x coordinate location of sprite collision                                         |
  1508.     ' | SLCOLLIDEY      -32768 to 32767     the y coordinate location of sprite collision                                         |
  1509.     ' | SLMOUSE         SLNONE              no interaction with the mouse pointer has been recorded                               |
  1510.     ' |                 SLLEFTCLICK         the left mouse button was clicked while on the sprite                                 |
  1511.     ' |                 SLRIGHTCLICK        the right mouse button was clicked while on the sprite                                |
  1512.     ' |                 SLMIDDLECLICK       the middle mouse button was clicked while on the sprite                               |
  1513.     ' |                 SLHOVER             the mouse pointer is currently hovering over the sprite                               |
  1514.     ' | SLMOUSEX        0 - screen width-1  the current mouse x location on the screen in relation to the sprite                  |
  1515.     ' | SLMOUSEY        0 - screen height-1 the current mouse y location on the screen in relation to the sprite                  |
  1516.     ' | SLSPRITEMOUSEX  sprite left - right the current mouse x location on the sprite                                            |
  1517.     ' | SLSPRITEMOUSEY  sprite top - bottom the current mouse y location on the sprite                                            |
  1518.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1519.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1520.  
  1521.     IF SL_ValidSprite(Handle) = SLFALSE THEN SL_Error 1, "SL_SpriteGet" '                   report error if invalid sprite
  1522.     SELECT CASE Action
  1523.         CASE SLZOOM
  1524.             '  _________________________________________________________________________
  1525.             ' | Valid returns: 1 - 32767                                                |
  1526.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1527.             SL_SpriteGet = SLSprite(Handle).Zoom
  1528.         CASE SLFLIP
  1529.             '  _________________________________________________________________________
  1530.             ' | Valid returns: SLNONE, SLVERTICAL, SLHORIZONTAL, SLBOTH                 |
  1531.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1532.             SL_SpriteGet = SLSprite(Handle).Flipped
  1533.         CASE SLVISIBLE
  1534.             '  _________________________________________________________________________
  1535.             ' | Valid returns: SLTRUE, SLFALSE                                          |
  1536.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1537.             SL_SpriteGet = SLSprite(Handle).Visible
  1538.         CASE SLLAYER
  1539.             '  _________________________________________________________________________
  1540.             ' | Valid returns: 0 - UBOUND(SLLayers)                                     |
  1541.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1542.             SL_SpriteGet = SLSprite(Handle).Layer
  1543.         CASE SLSCORE
  1544.             '  _________________________________________________________________________
  1545.             ' | Valid returns: any number in LONG integer range                         |
  1546.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1547.             SL_SpriteGet = SLSprite(Handle).Score
  1548.         CASE SLLEFT
  1549.             '  _________________________________________________________________________
  1550.             ' | Valid returns: -32768 through 32767                                     |
  1551.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1552.             SL_SpriteGet = SLSprite(Handle).Scrn.Left
  1553.         CASE SLTOP
  1554.             '  _________________________________________________________________________
  1555.             ' | Valid returns: -32768 through 32767                                     |
  1556.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1557.             SL_SpriteGet = SLSprite(Handle).Scrn.Top
  1558.         CASE SLRIGHT
  1559.             '  _________________________________________________________________________
  1560.             ' | Valid returns: -32768 through 32767                                     |
  1561.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1562.             SL_SpriteGet = SLSprite(Handle).Scrn.Right
  1563.         CASE SLBOTTOM
  1564.             '  _________________________________________________________________________
  1565.             ' | Valid returns: -32768 through 32767                                     |
  1566.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1567.             SL_SpriteGet = SLSprite(Handle).Scrn.Bottom
  1568.         CASE SLWIDTH
  1569.             '  _________________________________________________________________________
  1570.             ' | Valid returns: -32768 through 32767                                     |
  1571.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1572.             SL_SpriteGet = SLSprite(Handle).Scrn.Width
  1573.         CASE SLHEIGHT
  1574.             '  _________________________________________________________________________
  1575.             ' | Valid returns: -32768 through 32767                                     |
  1576.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1577.             SL_SpriteGet = SLSprite(Handle).Scrn.Height
  1578.         CASE SLCENTERX
  1579.             '  _________________________________________________________________________
  1580.             ' | Valid returns: -32768 through 32767                                     |
  1581.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1582.             SL_SpriteGet = SLSprite(Handle).Centerx
  1583.         CASE SLCENTERY
  1584.             '  _________________________________________________________________________
  1585.             ' | Valid returns: -32768 through 32767                                     |
  1586.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1587.             SL_SpriteGet = SLSprite(Handle).Centery
  1588.         CASE SLFRAMERATE
  1589.             '  _________________________________________________________________________
  1590.             ' | Valid returns: 1 through global frame rate                              |
  1591.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1592.             SL_SpriteGet = SLSprite(Handle).Anim.FrameRate
  1593.         CASE SLAUTOANIMATE
  1594.             '  _________________________________________________________________________
  1595.             ' | Valid returns: SLTRUE, SLFALSE                                          |
  1596.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1597.             SL_SpriteGet = SLSprite(Handle).Anim.Auto
  1598.         CASE SLFROMCELL
  1599.             '  _________________________________________________________________________
  1600.             ' | Valid returns: 1 through total number of cells on sheet                 |
  1601.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1602.             SL_SpriteGet = SLSprite(Handle).Anim.FromCell
  1603.         CASE SLTOCELL
  1604.             '  _________________________________________________________________________
  1605.             ' | Valid returns: 1 through total number of cells on sheet                 |
  1606.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1607.             SL_SpriteGet = SLSprite(Handle).Anim.ToCell
  1608.         CASE SLANIMATEDIR
  1609.             '  _________________________________________________________________________
  1610.             ' | Valid returns: SLFORWARD, SLBACKWARD, SLBACKFORTH                       |
  1611.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1612.             SL_SpriteGet = SLSprite(Handle).Anim.Direction
  1613.         CASE SLAUTOMOTION
  1614.             '  _________________________________________________________________________
  1615.             ' | Valid returns: SLTRUE, SLFALSE                                          |
  1616.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1617.             SL_SpriteGet = SLSprite(Handle).Move.Auto
  1618.         CASE SLMOTIONANGLE
  1619.             '  _________________________________________________________________________
  1620.             ' | Valid returns: 0 through 359                                            |
  1621.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1622.             SL_SpriteGet = SLSprite(Handle).Move.Degree
  1623.         CASE SLXDIR
  1624.             '  _________________________________________________________________________
  1625.             ' | Valid returns: -32768 through 32767                                     |
  1626.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1627.             SL_SpriteGet = SLSprite(Handle).Move.Xdir
  1628.         CASE SLYDIR
  1629.             '  _________________________________________________________________________
  1630.             ' | Valid returns: -32768 through 32767                                     |
  1631.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1632.             SL_SpriteGet = SLSprite(Handle).Move.Ydir
  1633.         CASE SLAUTOROTATE
  1634.             '  _________________________________________________________________________
  1635.             ' | Valid returns: SLTRUE, SLFALSE                                          |
  1636.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1637.             SL_SpriteGet = SLSprite(Handle).Spin.Auto
  1638.         CASE SLROTATEANGLE
  1639.             '  _________________________________________________________________________
  1640.             ' | Valid returns: 0 through 359                                            |
  1641.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1642.             SL_SpriteGet = SLSprite(Handle).Spin.Degree
  1643.         CASE SLROTATESPEED
  1644.             '  _________________________________________________________________________
  1645.             ' | Valid returns: -359 through 359                                         |
  1646.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1647.             SL_SpriteGet = SLSprite(Handle).Spin.Rate
  1648.         CASE SLDETECTION
  1649.             '  _________________________________________________________________________
  1650.             ' | Valid returns: SLNONE, SLRECTANGLE, SLCIRCLE, SLPIXEL                   |
  1651.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1652.             SL_SpriteGet = SLSprite(Handle).Coll.Detect
  1653.         CASE SLCOLLISION
  1654.             '  _________________________________________________________________________
  1655.             ' | Valid returns: SLTRUE, SLFALSE                                          |
  1656.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1657.             SL_SpriteGet = SLSprite(Handle).Coll.Event
  1658.         CASE SLCOLLIDEWITH
  1659.             '  _________________________________________________________________________
  1660.             ' | Valid returns: 1 through maximum number of sprite handles               |
  1661.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1662.             SL_SpriteGet = SLSprite(Handle).Coll.With
  1663.         CASE SLCOLLIDEX
  1664.             '  _________________________________________________________________________
  1665.             ' | Valid returns: -32768 through 32767                                     |
  1666.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1667.             SL_SpriteGet = SLSprite(Handle).Coll.Xloc
  1668.         CASE SLCOLLIDEY
  1669.             '  _________________________________________________________________________
  1670.             ' | Valid returns: -32768 through 32767                                     |
  1671.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1672.             SL_SpriteGet = SLSprite(Handle).Coll.Yloc
  1673.         CASE SLMOUSE
  1674.             '  _________________________________________________________________________
  1675.             ' | Valid returns: SLNONE, SLLEFTCLICK, SLRIGHTCLICK, SLMIDDLECLICK, SLHOVER|
  1676.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1677.             SL_SpriteGet = SLSprite(Handle).Mouse.Event
  1678.         CASE SLMOUSEX
  1679.             '  _________________________________________________________________________
  1680.             ' | Valid returns: 0 through screen width - 1                               |
  1681.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1682.             SL_SpriteGet = SLSprite(Handle).Mouse.SXloc
  1683.         CASE SLMOUSEY
  1684.             '  _________________________________________________________________________
  1685.             ' | Valid returns: 0 through screen height - 1                              |
  1686.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1687.             SL_SpriteGet = SLSprite(Handle).Mouse.SYloc
  1688.         CASE SLSPRITEMOUSEX
  1689.             '  _________________________________________________________________________
  1690.             ' | Valid returns: sprite.left through sprite.right                         |
  1691.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1692.             SL_SpriteGet = SLSprite(Handle).Mouse.Xloc
  1693.         CASE SLSPRITEMOUSEY
  1694.             '  _________________________________________________________________________
  1695.             ' | Valid returns: sprite.top through sprite.bottom                         |
  1696.             '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1697.             SL_SpriteGet = SLSprite(Handle).Mouse.Yloc
  1698.         CASE ELSE
  1699.             SL_Error 17, "SL_SpriteGet" '                                                   report invalid use of command
  1700.     END SELECT
  1701.  
  1702.  
  1703. '----------------------------------------------------------------------------------------------------------------------------------
  1704. FUNCTION SL_ValidSprite (Handle AS INTEGER) '                                                                        SL_ValidSprite
  1705.     '  ___________________________________________________________________________________________________________________________
  1706.     ' | Checks that the supplied sprite handle points to a valid sprite.                                                          |
  1707.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1708.     ' | Usage : Valid = SL_ValidSprite(MySprite)                                                                                  |
  1709.     ' |                                                                                                                           |
  1710.     ' | Input : Handle = the handle pointer name of the sprite                                                                    |
  1711.     ' | Output: SLTRUE if the sprite handle is valid, SLFALSE otherwise.                                                          |
  1712.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1713.     SHARED SLSprite() AS SLSPRITE ' master sprite array
  1714.  
  1715.     IF Handle > UBOUND(SLSprite) OR Handle < 0 THEN '                                       is this a valid handle pointer?
  1716.         SL_ValidSprite = SLFALSE '                                                          no, return SLFALSE
  1717.     ELSEIF SLSprite(Handle).InUse THEN '                                                    yes, is the sprite currently in use?
  1718.         SL_ValidSprite = SLTRUE '                                                           yes, return SLTRUE
  1719.     END IF
  1720.     '  _________________________________________________________________________________
  1721.     ' | If the handle was not in use the function will return 0 (SLFALSE)               |
  1722.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1723.  
  1724. '----------------------------------------------------------------------------------------------------------------------------------
  1725. FUNCTION SL_Min (Num1 AS INTEGER, Num2 AS INTEGER) '                                                                         SL_Min
  1726.     '  ___________________________________________________________________________________________________________________________
  1727.     ' | Returns the smaller of the two numbers supplied.                                                                          |
  1728.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1729.     ' | Usage : Smallest = SL_Min(Number1, Number2)                                                                               |
  1730.     ' |                                                                                                                           |
  1731.     ' | Input : Num1, Num2 = the two numbers to be compared                                                                       |
  1732.     ' | Output: The smaller of the two numbers (if equal then Num2 will always be returned)                                       |
  1733.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1734.     IF Num1 < Num2 THEN SL_Min = Num1 ELSE SL_Min = Num2 '                                  return the smallest of the two numbers
  1735.  
  1736.  
  1737. '----------------------------------------------------------------------------------------------------------------------------------
  1738. FUNCTION SL_Max (Num1 AS INTEGER, Num2 AS INTEGER) '                                                                         SL_Max
  1739.     '  ___________________________________________________________________________________________________________________________
  1740.     ' | Returns the larger of the two numbers supplied.                                                                           |
  1741.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1742.     ' | Usage : Largest = SL_Max(Number1, Number2)                                                                                |
  1743.     ' |                                                                                                                           |
  1744.     ' | Input : Num1, Num2 = the two numbers to be compared                                                                       |
  1745.     ' | Output: The larger of the two numbers (if equal then Num2 will always be returned)                                        |
  1746.     '  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1747.     IF Num1 > Num2 THEN SL_Max = Num1 ELSE SL_Max = Num2 '                                  return the largest of the two numbers
  1748.  
  1749.  
  1750. '----------------------------------------------------------------------------------------------------------------------------------
  1751. SUB SL_Error (ErrNo AS INTEGER, Routine AS STRING)
  1752.     '  ___________________________________________________________________________________________________________________________
  1753.     ' |                                                                                                                           |
  1754.     ' |---------------------------------------------------------------------------------------------------------------------------|
  1755.     ' | Usage :                                                                                                                   |
  1756.     ' |                                                                                                                           |
  1757.     ' | Input :                                                                                                                   |
  1758.     ' |                                                                                                                           |
  1759.     ' | Output:                                                                                                                   |
  1760.  
  1761.     BEEP
  1762.  
  1763.     SCREEN 0, 0, 0, 0
  1764.     PRINT ErrNo, Routine
  1765.  
  1766.     SELECT CASE ErrNo
  1767.         CASE 1 ' invalid sprite
  1768.         CASE 2 ' invalid sprite zoom level
  1769.         CASE 3 ' invalid sprite flpping behavior
  1770.         CASE 4 ' invalid sprite visibility setting
  1771.         CASE 5 ' invalid layer requested
  1772.         CASE 6 ' invalid auto-animation setting
  1773.         CASE 7 ' invalid cell requested
  1774.         CASE 8 ' invalid animation direction requested
  1775.         CASE 9 ' invalid sprite frame rate requested
  1776.         CASE 10 ' invalid auto-motion setting
  1777.         CASE 11 ' invalid x direction vector
  1778.         CASE 12 ' invalid y direction vector
  1779.         CASE 13 ' invalid auto-rotation setting
  1780.         CASE 14 ' invalid rotation speed
  1781.         CASE 15 ' invalid colllsion detection method
  1782.         CASE 16 ' invalid use of SL_SpriteSet
  1783.         CASE 17 ' invalid use of SL_SpriteGet
  1784.  
  1785.     END SELECT
  1786.  
  1787.     END
  1788.  
  1789.  
  1790.  
In order to understand recursion, one must first understand recursion.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Sprite Library Revisited
« Reply #54 on: November 04, 2018, 07:00:07 am »
Hi Terry

while you are working in progress with your library
you raccomande us to use old library or the new in progress because only news are in evolution and the rest part is done and it will not change?
Programming isn't difficult, only it's  consuming time and coffee

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: Sprite Library Revisited
« Reply #55 on: December 04, 2020, 11:00:41 am »
Just an update to state I'm still working on the library. Here is the current state of the code:

I'm new to QB64 and just learning by making some simple games.
This library seems really useful - have you updated it since this post?
Does this have a home on git hub?
A tutorial and especially example programs (such as simple basic games) that illustrate how to utilize it would be very helpful.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sprite Library Revisited
« Reply #56 on: December 04, 2020, 12:22:13 pm »
I'm new to QB64 and just learning by making some simple games.
This library seems really useful - have you updated it since this post?
Does this have a home on git hub?
A tutorial and especially example programs (such as simple basic games) that illustrate how to utilize it would be very helpful.


Welcome madscijr!  Mad Scientist Jr?

Terry hasn't been around for awhile at least with public posts here but you can find links to his wonderful tutorial from this .org Home page or the Wiki for QB64 or maybe it's in his signature or maybe someone can paste one up here directly, I can't find mine at moment.

Here is Wiki which you might bookmark anyway on your browser (if you hadn't already), very handy!
https://www.qb64.org/wiki/Main_Page
« Last Edit: December 04, 2020, 12:24:59 pm by bplus »

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Sprite Library Revisited
« Reply #57 on: December 04, 2020, 08:40:56 pm »
Hi Madscijr
welcome to the forum
here a link to the tutorial for game programming of Terry
https://www.qb64.org/forum/index.php?topic=3204.0
here one of the last post of Terry
https://www.qb64.org/forum/index.php?topic=2264.msg114989#msg114989
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sprite Library Revisited
« Reply #58 on: December 04, 2020, 09:12:19 pm »
Found it! Terry's Tutorial: https://www.qb64sourcecode.com

? I thought it was on Home page and at Wiki but couldn't find at either.
« Last Edit: December 04, 2020, 09:15:40 pm by bplus »

FellippeHeitor

  • Guest
Re: Sprite Library Revisited
« Reply #59 on: December 04, 2020, 09:20:40 pm »
Found it! Terry's Tutorial: https://www.qb64sourcecode.com

? I thought it was on Home page and at Wiki but couldn't find at either.

Link to Terry's tutorial is in the wiki's landing page.