Author Topic: WIP: Isometric Demo re-revisited v3.01, showing animation  (Read 3503 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
WIP: Isometric Demo re-revisited v3.01, showing animation
« on: December 29, 2021, 06:21:52 pm »
And a little holiday message, @bplus !
Kinda late for Christmas so Happy New Year.

I wanted to get some 2.5D sheer rotation working, but translating it from 2D polar coordinates to a 3D 1-based array is tricky. Maybe later!

Enjoy and Happy Holidays.

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' #TOP
  3.  
  4. ' Isomatric mapping demo re-revisited
  5. ' Version 3.00 by madscijr
  6.  
  7. ' Based on Isometric Mapping Demo
  8. ' by SMcNeill, bplus, and others at
  9. ' https://www.qb64.org/forum/index.php?topic=1903.30
  10.  
  11. ' This crude version uses a 3-dimensional array (32x32x32)
  12. ' to store cubes of different colors,
  13. ' and draws them to the screen in 2.5D "isometric".
  14.  
  15. ' -----------------------------------------------------------------------------
  16. ' DONE
  17. ' -----------------------------------------------------------------------------
  18. ' * Render cubes that block the view of the player as transparent.
  19. ' * 2-D top down "map" view of the player's current Z slice.
  20. ' * variable grid size
  21. ' * change arrMap to global shared variable (for simpler code) & rename m_arrMap
  22. ' * allow player to rotate their view
  23. ' * preliminary multiplayer changes
  24. '   - move player info into array (upto 4 players)
  25. '   - key mapping variables
  26. ' * fixed some keyboard input (repeating keys, continuous motion)
  27. ' * fixed right point of view bug where x & y coordinates were reversed
  28. ' * preliminary multiplayer changes
  29. '   - split screen display (4, 6, or 8?)
  30. '     + for now display player 1's world rotated in each window (for editor)
  31. '       * x4: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  32. '       * x6: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  33. '       * x8: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, (none), (none)
  34. '     + will eventually be one per player
  35. ' * 2D minimap background = cKhaki
  36. ' * , and . change minimap size
  37. ' * editor v1 = simple drawing program
  38. '   - change lowest z level to draw full blocks instead of flat tiles (leftover from early version)
  39. '   - add type RecordType to hold recording steps
  40. '   - add array m_arrRecord of RecordType to hold recording
  41. '   - display palette of available colors on screen
  42. '     + 26 colors including empty
  43. '     + 2 tiles (empty, wall)
  44. '   - cursor places tiles (ENTER = add/delete at current space)
  45. '   - 0-9 keys change colors/etc.
  46. '   - simple 1-level UNDO & REDO
  47. '   - save screens to file (stored as editable text)
  48. '     + FORMAT: tile={t},color={c},x={x},y={y},z={z}
  49. '   - load screens line by line (split was too slow)
  50. '     + PARSER:
  51. '       1. remove whitespace
  52. '       2. split by "," into 1D array of name/value pairs
  53. '       3. each element is either tile, color, x, y, z
  54. '       4. parse each into array to playback recording
  55. '   - run commands in m_arrRecord to plot tiles and display
  56. ' * 2-D front/back "map" view of the player's current Y slice.
  57. ' * 2-D right/left "map" view of the player's current X slice.
  58. ' SOME 3D SHAPE ROUTINES
  59. ' - 3D rectangle (cuboid)
  60. ' - 3D circle (simple, not a sphere, not filled)
  61.  
  62. ' -----------------------------------------------------------------------------
  63. ' TO DO (HOLIDAY)
  64. ' -----------------------------------------------------------------------------
  65.  
  66. ' * snow
  67. ' * ornaments
  68. ' * wind lights
  69. ' * blinking
  70. ' * tree star
  71. ' * rotate it all
  72. ' * stars (all 4 sides + top?)
  73. ' * northstar
  74. ' * text message
  75. ' * music
  76.  
  77. ' * smaller tiles
  78. ' * one big map
  79. ' * - free rotate? 3D 3-shear rotation v1 (x/y)
  80. ' * mouse control (mouse moves x/y, wheel moves z)
  81.  
  82. ' * MORE 3D SHAPE ROUTINES
  83. '   - improved circle
  84. '     * circle fill
  85. '     * circle wall thickness
  86. '     * option for origin at top left
  87. '   - step pyramid
  88. '   - sphere
  89. '   - simple line in one plane (x/y, x/z, y/z)
  90. '   - 3D line (x1,y1,z1) to (x2,y2,z2)
  91.  
  92. ' * 3D select
  93. '   - copy/cut/paste
  94. '   - rotate (x/y, x/z, y/z)
  95. '   - flip (x/y, x/z, y/z)
  96. '   - invert
  97. '   - substitute colors
  98. '   - save contents as reusable shape
  99.  
  100. ' christmas trees
  101. ' * stack of pyramids (grow, reset, grow)
  102. ' * stack of circle cones (circles grow)
  103. ' * 4-sided pyramid polygons with wavering bottom points
  104. ' * stack of circle cones (lines from bottom to tip)
  105. ' * 3-sided pyramid polygons with 3-d lines
  106. '
  107. ' north star
  108. ' * shimmering north star
  109. ' * growing glowing circles along 3 axes
  110. '
  111. ' ornaments
  112. ' * ornaments fly in from 4 directions
  113. ' * circles
  114. ' * striped
  115. '
  116. ' lights
  117. ' * string of transparent lights follows around outside, winds its way up
  118. ' * colors = red, green, blue, yellow, orange, purple
  119. ' * save lights in array
  120. ' * shimmer each with its color pattern
  121. '
  122. ' snowfall
  123. ' * wavering snowflakes
  124. ' * stick n deep
  125. ' * fall down if n spaces under
  126. '
  127. ' stars in sky
  128. ' * at back edges
  129. ' * twinkling
  130. '
  131. ' snowman
  132. ' * 3 spheres
  133. ' * cone nose
  134. ' * eyes
  135. ' * mouth
  136. ' * hat
  137. ' * stick arms
  138. ' * pipe
  139. ' * scarf
  140. '
  141. ' presents
  142. ' stockings
  143. ' reindeer/slay
  144.  
  145. ' -----------------------------------------------------------------------------
  146. ' TO DO (GENERAL)
  147. ' -----------------------------------------------------------------------------
  148. ' * screen size
  149. '   - grow screen to 64x64 (only 1 window)
  150. '   - shrink grid size
  151. ' * layers
  152.  
  153. ' -----------------------------------------------------------------------------
  154. ' TO DO (DRAWING)
  155. ' -----------------------------------------------------------------------------
  156. ' * mouse control
  157. ' * change mouse axis
  158. ' * first person view
  159. ' * x/y/z view (total not slice)
  160. ' * line/brush size
  161. ' * line/bresenham
  162. ' * cube (height/length, width, isHollow?)
  163. ' * pyramid from top (height, color scheme, isHollow)
  164. ' * pyramid from base (length, width, isHollow)
  165. ' * polygon (draw n points, fills inbetween)
  166. ' * fill
  167. ' * YET MORE SHAPES
  168. '   - ellipse
  169. '   - n-sided polygon
  170.  
  171. ' -----------------------------------------------------------------------------
  172. ' TO DO (MORE DETAILS)
  173. ' -----------------------------------------------------------------------------
  174. ' * get _BUTTON or some method working to detect keydown/keyup events for CTRL+Z, CTRL+Y for UNDO & REDO
  175.  
  176. ' * save unlinited levels of undo/redo, using history of actions
  177.  
  178. ' * rotating view changes orientation of keys (get it working)
  179.  
  180. ' * add parameters to tiles
  181. '   - color scheme (for cycle colors)
  182.  
  183. ' * add tiles
  184. '   - transparent lights (blinking / cycle colors)
  185.  
  186. ' * editor v2 = simple animation program
  187. '   - records cursor movements and adding/deleting tiles
  188. '   - press key to record a "frame"
  189. '     + flash screen + play a sound
  190. '   - can change animation speed
  191. '   - realtime=on command enables redrawing screen every step (until realtime=off command encountered)
  192. '   - playback mode recreates editing actions
  193. '   - playback updates screen every "update"
  194. '   - tweak save format (still editable text)
  195. '     + FORMAT: TBD
  196. '     + PARSER:
  197. '       1. Commands:
  198. '          - cls
  199. '          - rotate perspective (up, down, left, right, back, forward), FORMAT: rotate={d}
  200. '          - enable/disable screen update every step, FORMAT: realtime{on/off}
  201. '          - set speed, FORAT: speed={s}
  202. '          - update screen, FORMAT: update
  203. '          - clear screen "cls"
  204. '          - select tile
  205. '          - change color
  206. '          - movement? (speed / direction)
  207. '   - effects of gravity (from bottom up, ie z=0 to z=max)
  208.  
  209. ' -----------------------------------------------------------------------------
  210. ' * expand world to bigger than screen (2.5d scrolling view)
  211.  
  212. ' * editor v3 = mouse
  213. '   - mouse movement controls cursor x,y position
  214. '   - mouse wheel controls z position
  215. '   - left click draws a tile
  216. '   - right click erases a tile
  217. '   - ENTER records a frame
  218. '   - Add animation playback command:
  219. '          [n][0] = command
  220. '                   -8 = enable user to rotate image in realtime with mouse? "mouse=on"
  221.  
  222. ' -----------------------------------------------------------------------------
  223. ' TO DO (LATER)
  224. ' -----------------------------------------------------------------------------
  225. ' * local multiplayer (2-4 players)
  226. '   - split screen (x2 or x4)
  227.  
  228. ' * fix/control screen placement/rendering/scroll boundaries for grid sizes
  229. '   (to not overwrite other players, go off screen, etc., when grid size changes)
  230.  
  231. ' * auto-rotate view depending on direction player is facing
  232.  
  233. ' * control the x/y/z slice axis, for a cutaway view
  234.  
  235. ' * gravity (players stay on ground, can fall)
  236. ' * player can climb up to next level if it is 1 tile higher
  237. ' * add ability to jump over 1 space
  238.  
  239. ' * option to remap keys
  240. ' * support game controllers
  241. ' * game controller calibration/mapping function
  242.  
  243. ' * option to hide objects out of player's line-of-sight
  244.  
  245. ' * show player as a stick figure (like "Realm of Impossibility")
  246. ' * walking movement
  247.  
  248. ' * add tiles (water, ladders, steps, ropes, windows, doors, etc.)
  249. ' * add toggle tiles - door "opens" when triggered
  250. ' * triggers
  251. ' * add tiles
  252. '   - Water = transparent blue)
  253. '   - Window = more transparent cyan)
  254.  
  255. ' * add directional tiles (can be rotated?)
  256. '   - ladder
  257. '   - bridge
  258. '   - hand-over-hand bars?
  259. '   - Slope45 = 45° slope <- 4 or 6 directions?
  260. '   - InvSlope45 = 45° inverted slope <- 4 or 6 directions?
  261. '   - Pyramid45 = 45° pyramid "cap stone" <- 4 or 6 directions?
  262. '   - ramp (player can walk up/down slope45)
  263.  
  264. ' * add ability to climb ladders + climbing animation
  265. ' * add ability to walk up ramps with smooth z-movement inbetween tiles
  266. ' * add ability to climb monkey bars (animation like lode runner)
  267.  
  268. ' * simultaneously show additional 1st person view
  269. ' * add ability for tilting head up/down in first person
  270.  
  271. ' * simple open world (players can add/remove tiles, build in real time)
  272. ' * make simple games (maze craze, capture the flag, snake, surround, 2.5d pong)
  273. ' * make more complex games (berzerk, lode runner, atari combat / tank)
  274. ' * make awesome complex games (2.5d lunar lander, atari adventure, asteroids, gravitar, Zaxxon meets Atari 2600 Superman, Isometric Atari 2600 Raiders of the Lost Ark, etc.)
  275. ' * text adventure features (to create graphic Infocom or Scott Adams style games)
  276.  
  277. ' * for 2.5D animation program: independent animated objects?
  278. '   - 2.5D sprites?
  279. '     + animation sequence
  280. '     + motion path / algorithm
  281. '     + storage / library
  282. '     + multiple instances?
  283. '   - gravity? (tile falls if no tiles underneath)
  284.  
  285. ' ################################################################################################################################################################
  286.  
  287. ' =============================================================================
  288. ' SOME USEFUL STUFF FOR REFERENCE:
  289.  
  290. ' Type Name               Type suffix symbol   Minimum value                  Maximum value                Size in Bytes
  291. ' ---------------------   ------------------   ----------------------------   --------------------------   -------------
  292. ' _BIT                    `                    -1                             0                            1/8
  293. ' _BIT * n                `n                   -128                           127                          n/8
  294. ' _UNSIGNED _BIT          ~`                   0                              1                            1/8
  295. ' _BYTE                   %%                   -128                           127                          1
  296. ' _UNSIGNED _BYTE         ~%%                  0                              255                          1
  297. ' INTEGER                 %                    -32,768                        32,767                       2
  298. ' _UNSIGNED INTEGER       ~%                   0                              65,535                       2
  299. ' LONG                    &                    -2,147,483,648                 2,147,483,647                4
  300. ' _UNSIGNED LONG          ~&                   0                              4,294,967,295                4
  301. ' _INTEGER64              &&                   -9,223,372,036,854,775,808     9,223,372,036,854,775,807    8
  302. ' _UNSIGNED _INTEGER64    ~&&                  0                              18,446,744,073,709,551,615   8
  303. ' SINGLE                  ! or none            -2.802597E-45                  +3.402823E+38                4
  304. ' DOUBLE                  #                    -4.490656458412465E-324        +1.797693134862310E+308      8
  305. ' _FLOAT                  ##                   -1.18E-4932                    +1.18E+4932                  32(10 used)
  306. ' _OFFSET                 %&                   -9,223,372,036,854,775,808     9,223,372,036,854,775,807    Use LEN
  307. ' _UNSIGNED _OFFSET       ~%&                  0                              18,446,744,073,709,551,615   Use LEN
  308. ' _MEM                    none                 combined memory variable type  N/A                          Use LEN
  309.  
  310. ' div: int1% = num1% \ den1%
  311. ' mod: rem1% = num1% MOD den1%
  312.  
  313. ' =============================================================================
  314. ' GLOBAL DECLARATIONS
  315.  
  316. ' -----------------------------------------------------------------------------
  317. ' boolean constants
  318. ' -----------------------------------------------------------------------------
  319. Const FALSE = 0
  320. Const TRUE = Not FALSE
  321.  
  322. ' -----------------------------------------------------------------------------
  323. ' KeyDownConstants
  324. ' -----------------------------------------------------------------------------
  325. Const c_iKeyDown_Esc = 27
  326. Const c_iKeyDown_F1 = 15104
  327. Const c_iKeyDown_F2 = 15360
  328. Const c_iKeyDown_F3 = 15616
  329. Const c_iKeyDown_F4 = 15872
  330. Const c_iKeyDown_F5 = 16128
  331. Const c_iKeyDown_F6 = 16384
  332. Const c_iKeyDown_F7 = 16640
  333. Const c_iKeyDown_F8 = 16896
  334. Const c_iKeyDown_F9 = 17152
  335. Const c_iKeyDown_F10 = 17408
  336. Const c_iKeyDown_Tilde = 96
  337. Const c_iKeyDown_1 = 49
  338. Const c_iKeyDown_2 = 50
  339. Const c_iKeyDown_3 = 51
  340. Const c_iKeyDown_4 = 52
  341. Const c_iKeyDown_5 = 53
  342. Const c_iKeyDown_6 = 54
  343. Const c_iKeyDown_7 = 55
  344. Const c_iKeyDown_8 = 56
  345. Const c_iKeyDown_9 = 57
  346. Const c_iKeyDown_0 = 48
  347. Const c_iKeyDown_Minus = 45
  348. Const c_iKeyDown_EqualPlus = 61
  349. Const c_iKeyDown_BkSp = 8
  350. Const c_iKeyDown_Ins = 20992
  351. Const c_iKeyDown_Home = 18176
  352. Const c_iKeyDown_PgUp = 18688
  353. Const c_iKeyDown_Del = 21248
  354. Const c_iKeyDown_End = 20224
  355. Const c_iKeyDown_PgDn = 20736
  356. Const c_iKeyDown_KEYPAD_7_Home = 18176
  357. Const c_iKeyDown_KEYPAD_8_Up = 18432
  358. Const c_iKeyDown_KEYPAD_9_PgUp = 18688
  359. Const c_iKeyDown_KEYPAD_4_Left = 19200
  360. Const c_iKeyDown_KEYPAD_6_Right = 19712
  361. Const c_iKeyDown_KEYPAD_1_End = 20224
  362. Const c_iKeyDown_KEYPAD_2_Down = 20480
  363. Const c_iKeyDown_KEYPAD_3_PgDn = 20736
  364. Const c_iKeyDown_KEYPAD_0_Ins = 20992
  365. Const c_iKeyDown_KEYPAD_Period_Del = 21248
  366. Const c_iKeyDown_Tab = 9
  367. Const c_iKeyDown_Q = 113
  368. Const c_iKeyDown_W = 119
  369. Const c_iKeyDown_E = 101
  370. Const c_iKeyDown_R = 114
  371. Const c_iKeyDown_T = 116
  372. Const c_iKeyDown_Y = 121
  373. Const c_iKeyDown_U = 117
  374. Const c_iKeyDown_Pipe = 105
  375. Const c_iKeyDown_O = 111
  376. Const c_iKeyDown_P = 112
  377. Const c_iKeyDown_BracketLeft = 91
  378. Const c_iKeyDown_BracketRight = 93
  379. Const c_iKeyDown_Backslash = 92
  380. Const c_iKeyDown_A = 97
  381. Const c_iKeyDown_S = 115
  382. Const c_iKeyDown_D = 100
  383. Const c_iKeyDown_F = 102
  384. Const c_iKeyDown_G = 103
  385. Const c_iKeyDown_H = 104
  386. Const c_iKeyDown_J = 106
  387. Const c_iKeyDown_K = 107
  388. Const c_iKeyDown_L = 108
  389. Const c_iKeyDown_SemiColon = 59
  390. Const c_iKeyDown_Apostrophe = 39
  391. Const c_iKeyDown_Enter = 13
  392. Const c_iKeyDown_Z = 22
  393. Const c_iKeyDown_X = 120
  394. Const c_iKeyDown_C = 99
  395. Const c_iKeyDown_V = 118
  396. Const c_iKeyDown_B = 98
  397. Const c_iKeyDown_N = 110
  398. Const c_iKeyDown_M = 109
  399. Const c_iKeyDown_Comma = 44
  400. Const c_iKeyDown_Period = 46
  401. Const c_iKeyDown_Slash = 47
  402. Const c_iKeyDown_Up = 18432
  403. Const c_iKeyDown_Left = 19200
  404. Const c_iKeyDown_Down = 20480
  405. Const c_iKeyDown_Right = 19712
  406. Const c_iKeyDown_Spacebar = 32
  407.  
  408. ' -----------------------------------------------------------------------------
  409. ' Constants for layers
  410. ' -----------------------------------------------------------------------------
  411. Const cTerrainType = 1
  412. Const cObjectsType = 2
  413. Const cPlayersType = 3
  414.  
  415. ' -----------------------------------------------------------------------------
  416. ' Tile value constants for map (MapTileType.Typ)
  417. ' -----------------------------------------------------------------------------
  418. Const c_iTile_Empty = 0
  419. Const c_iTile_Floor = 1
  420. Const c_iTile_Wall = 2
  421. Const c_iTile_Water = 3
  422. Const c_iTile_Window = 4
  423. Const c_iTile_Player1 = 5
  424. Const c_iTile_Player2 = 6
  425. Const c_iTile_Player3 = 7
  426. Const c_iTile_Player4 = 8
  427. Const c_iTile_Blinking = 9
  428. Const c_iTile_Snow = 10
  429. Const c_iTile_Slope45 = 11
  430. Const c_iTile_InvSlope45 = 12
  431.  
  432. ' -----------------------------------------------------------------------------
  433. ' constants for 2.5D movement
  434. ' -----------------------------------------------------------------------------
  435. Const c_iDir_Down = 1
  436. Const c_iDir_Up = 2
  437. Const c_iDir_Left = 3
  438. Const c_iDir_Right = 4
  439. Const c_iDir_Back = 5
  440. Const c_iDir_Forward = 6
  441. Const c_iDir_Min = 1
  442. Const c_iDir_Max = 6
  443.  
  444. ' -----------------------------------------------------------------------------
  445. ' constants for drawing the 2.5D screen
  446. ' -----------------------------------------------------------------------------
  447. Const cGridOffsetX = 300
  448. Const cGridOffsetY = 50
  449. Const cGridOffsetZ = 0
  450. Const cScreenOffsetX = 500
  451. Const cScreenOffsetY = 300
  452. Const cScreenOffsetZ = 0
  453.  
  454. ' -----------------------------------------------------------------------------
  455. ' constants for 3D coordinates
  456. ' -----------------------------------------------------------------------------
  457. Const cPlaneXY = 1
  458. Const cPlaneYZ = 2
  459. Const cPlaneZX = 3
  460.  
  461. ' =============================================================================
  462. ' USER DEFINED TYPES
  463. ' =============================================================================
  464. Type MapTileType
  465.     Typ As Integer ' c_iTile_Empty, c_iTile_Floor, c_iTile_Wall, etc.
  466.     'Vis As Integer ' TRUE = visible, FALSE = don't render
  467.     'Lit As Long ' light offset
  468.     Color1 As _Unsigned Long ' main color
  469.     Color2 As _Unsigned Long ' secondary color if needed
  470.     Color3 As _Unsigned Long ' third color if needed
  471.     Alpha1 As Integer ' transparency of tile Color1
  472.     Alpha2 As Integer ' transparency of tile Color2
  473.     Alpha3 As Integer ' transparency of tile Color3
  474.     AlphaOverride As Integer ' can be used to override alpha (255 treated as opaque)
  475.        
  476.     origx As Integer ' used for shear rotation
  477.     origy As Integer ' used for shear rotation
  478.     origz As Integer ' used for shear rotation (added for 3D)
  479.     zone as integer ' used for shear rotation, which zone screen is in, 1 = top right, 2 = bottom right, 3 = bottom left, 4 = top left
  480. End Type ' MapTileType
  481.  
  482. Type MapUndoType
  483.     x As Integer
  484.     y As Integer
  485.     z As Integer
  486.     Typ As Integer ' c_iTile_Empty, c_iTile_Floor, c_iTile_Wall, etc.
  487.     Color1 As _Unsigned Long ' main color
  488.     Alpha1 As Integer ' transparency of tile Color1
  489. End Type ' MapUndoType
  490.  
  491. Type RecordType
  492.     Command As String ' "draw"
  493.     intParam1 As Integer ' x
  494.     intParam2 As Integer ' y
  495.     intParam3 As Integer ' z
  496.     intParam4 As Integer ' tile #
  497.     ulngParam1 As _Unsigned Long ' color1
  498. End Type ' RecordType
  499.  
  500. ' UDT TO HOLD THE INFO FOR A PLAYER
  501. Type PlayerType
  502.     IsEnabled As Integer ' TRUE or FALSE
  503.     x As Integer ' player x position
  504.     y As Integer ' player y position
  505.     z As Integer ' player z position
  506.     Direction As Integer ' direction player is moving: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward; not used: c_iDir_Down, c_iDir_Up
  507.     View As Integer ' player's viewing orientation (direction screen is being looked at from), can be: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  508.     Tile1 As Long ' later we will instead use directional animation sequences
  509.  
  510.     Color1 As _Unsigned Long ' main color
  511.     'Color2 As _Unsigned Long ' secondary color if needed
  512.     'Color3 As _Unsigned Long ' third color if needed
  513.  
  514.     Alpha1 As Integer ' transparency of player Color1
  515.     'Alpha2 As Integer ' transparency of player Color2
  516.     'Alpha3 As Integer ' transparency of player Color3
  517.  
  518.     ColorScheme1 As Long ' for cycling colors
  519.     ColorSchemeSpeed1 As Long
  520.     ColorSchemeCount1 As Long
  521.  
  522.     'ColorScheme2 As Long ' for cycling colors
  523.     'ColorSchemeSpeed2 As Long
  524.     'ColorSchemeCount2 As Long
  525.  
  526.     'ColorScheme3 As Long ' for cycling colors
  527.     'ColorSchemeSpeed3 As Long
  528.     'ColorSchemeCount3 As Long
  529.  
  530.     AlphaOverride As Integer ' can be used to override alpha (0 treated as opaque)
  531.  
  532.     IsMoving As Integer ' TRUE/FALSE
  533.     IsMoved As Integer ' TRUE/FALSE
  534.  
  535.     GridSize As Integer
  536.     MapSize As Integer
  537.  
  538.     'hx AS Integer ' home base x position
  539.     'hy AS Integer ' home base y position
  540.     'ex AS Integer ' exit x position
  541.     'ey AS Integer ' exit y position
  542.     'wins AS Integer ' count # of wins
  543.     'points AS Long ' count points (more points for harder)
  544.     'difficulty AS Integer ' 1-5, from 1 (easiest, maze width 5) to 5 (hardest, maze width 1). Each win awards {difficulty} # of points.
  545.     'speed AS Integer ' the higher the faster
  546.     'delay AS Integer ' counter, player can move based on speed
  547.     'bit AS Integer ' bit value for masking player in map
  548.     'rows AS Integer ' # of rows in player's maze
  549.     'cols AS Integer ' # of columns in player's maze
  550. End Type ' PlayerType
  551.  
  552. ' HOLDS SNOWFLAKES
  553. ' TODO: generalize this for more complex objects
  554. Type SnowflakeType
  555.     IsEnabled As Integer ' TRUE or FALSE
  556.     x As Integer ' player x position
  557.     y As Integer ' player y position
  558.     z As Integer ' player z position
  559.     Direction As Integer ' direction object is moving: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  560.         Tile1 As Long ' tile to draw it with
  561.     Color1 As _Unsigned Long ' main color
  562.     Alpha1 As Integer ' transparency of Color1
  563.     Color2 As _Unsigned Long ' secondary color if needed
  564.     Alpha2 As Integer ' transparency of Color2
  565.     Color3 As _Unsigned Long ' third color if needed
  566.     Alpha3 As Integer ' transparency of Color3
  567.        
  568.         ' used to track last time snowflake moved in the wind?
  569.         xCount As Integer
  570.         xMax As Integer
  571.         yCount As Integer
  572.         yMax As Integer
  573.        
  574.         ' used to regulate snowflake's vertical speed
  575.         zCount As Integer
  576.         zMax As Integer
  577. End Type ' SnowflakeType
  578.  
  579. ' KEY MAPPING v1
  580. ' UDT TO HOLD THE KEY MAPPINGS
  581. Type DirKeyMapType
  582.     KeyBack As Long
  583.     KeyForward As Long
  584.     KeyLeft As Long
  585.     KeyRight As Long
  586.     KeyUp As Long
  587.     KeyDown As Long
  588. End Type ' DirKeyMapType
  589.  
  590. ' SPLIT SCREEN OFFSETS
  591. Type SplitScreenType
  592.     ' WHERE TO SHOW THE SPLIT SCREENS
  593.     GridOffsetX As Integer
  594.     GridOffsetY As Integer
  595.     GridOffsetZ As Integer
  596.     ScreenOffsetX As Integer
  597.     ScreenOffsetY As Integer
  598.     ScreenOffsetZ As Integer
  599.  
  600.     ' WHERE TO DRAW THE PLAYER'S MINI MAPS
  601.     MiniMapFirstPersonX As Integer
  602.     MiniMapFirstPersonY As Integer
  603.     MiniMapTopDownX As Integer
  604.     MiniMapTopDownY As Integer
  605.     MiniMapFrontBackX As Integer
  606.     MiniMapFrontBackY As Integer
  607.     MiniMapRightLeftX As Integer
  608.     MiniMapRightLeftY As Integer
  609.  
  610.     ' WHERE TO LOCATE(Y,X) THE PLAYER'S MINI MAP TEXT LABELS
  611.     ' TODO: later this will probably be bitmap text
  612.     MiniMapFirstPersonTextX As Integer
  613.     MiniMapFirstPersonTextY As Integer
  614.     MiniMapTopDownTextX As Integer
  615.     MiniMapTopDownTextY As Integer
  616.     MiniMapFrontBackTextX As Integer
  617.     MiniMapFrontBackTextY As Integer
  618.     MiniMapRightLeftTextX As Integer
  619.     MiniMapRightLeftTextY As Integer
  620. End Type ' SplitScreenType
  621.  
  622. Type RotationType
  623.     origx As Integer
  624.     origy As Integer
  625.     origz As Integer ' added for 3D
  626.     'c As Integer
  627.     zone as integer ' which zone screen is in, 1 = top right, 2 = bottom right, 3 = bottom left, 4 = top left
  628.        
  629.     Typ As Integer ' c_iTile_Empty, c_iTile_Floor, c_iTile_Wall, etc.
  630.     Color1 As _Unsigned Long ' main color
  631.     'Color2 As _Unsigned Long ' secondary color if needed
  632.     'Color3 As _Unsigned Long ' third color if needed
  633.     Alpha1 As Integer ' transparency of tile Color1
  634.     'Alpha2 As Integer ' transparency of tile Color2
  635.     'Alpha3 As Integer ' transparency of tile Color3
  636.     'AlphaOverride As Integer ' can be used to override alpha (255 treated as opaque)
  637. End Type ' RotationType
  638.  
  639. ' =============================================================================
  640. ' GLOBAL VARIABLES
  641. ' =============================================================================
  642. Dim Shared m_ProgramPath$: m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  643. Dim Shared m_ProgramName$: m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  644. Dim Shared m_SaveFileName$: m_SaveFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "txt"
  645.  
  646. Dim Shared m_iGridSize As Integer: m_iGridSize = 6 ' BEFORE, < 10 wass causing problems with PAINT, but new method doesn't use PAINT, so nyah!
  647. Dim Shared m_iGridSizeMin As Integer: m_iGridSizeMin = 1
  648. Dim Shared m_iGridSizeMax As Integer: m_iGridSizeMax = 128
  649.  
  650. Dim Shared m_iMapMinX As Integer: m_iMapMinX = 0
  651. Dim Shared m_iMapMaxX As Integer: m_iMapMaxX = 64
  652. Dim Shared m_iMapMidX As Integer: m_iMapMidX = (m_iMapMaxX - m_iMapMinX) \ 2
  653. Dim Shared m_iMapMinY As Integer: m_iMapMinY = 0
  654. Dim Shared m_iMapMaxY As Integer: m_iMapMaxY = 64
  655. Dim Shared m_iMapMidY As Integer: m_iMapMidY = (m_iMapMaxY - m_iMapMinY) \ 2
  656. Dim Shared m_iMapMinZ As Integer: m_iMapMinZ = 0
  657. Dim Shared m_iMapMaxZ As Integer: m_iMapMaxZ = 64
  658. Dim Shared m_iMapMidZ As Integer: m_iMapMidZ = (m_iMapMaxZ - m_iMapMinZ) \ 2
  659.  
  660. Dim Shared m_iPlayerMin As Integer: m_iPlayerMin = 1
  661. Dim Shared m_iPlayerMax As Integer: m_iPlayerMax = 4
  662. Dim Shared m_iPlayerCount As Integer: m_iPlayerCount = 0
  663. Dim Shared m_iObjectCount As Integer: m_iObjectCount = 0 ' <- TO BE USED WHEN WE HAVE OBJECTS
  664.  
  665. Dim Shared m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  666. Dim Shared m_arrRender0(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  667. Dim Shared m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  668. Dim Shared m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  669. Dim Shared m_arrPlayer(m_iPlayerMin To m_iPlayerMax) As PlayerType
  670. Dim Shared m_arrSnow(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As Integer
  671.  
  672. ' PLACE TEXT INSTRUCTIONS ON SCREEN
  673. Dim Shared m_iInstrStartRow As Integer : m_iInstrStartRow = 3
  674. Dim Shared m_iInstrStartCol As Integer : m_iInstrStartCol = 2
  675. Dim Shared m_iPaletteTextRow As Integer : m_iPaletteTextRow = 17
  676. Dim Shared m_iPaletteTextCol As Integer : m_iPaletteTextCol = 10
  677.  
  678. ' PLACE MINI MAPS ON SCREEN
  679. Dim Shared m_iMiniMapStartRow As Integer : m_iMiniMapStartRow = 800
  680. Dim Shared m_iMiniMapStartCol As Integer : m_iMiniMapStartCol = 300
  681. Dim Shared m_iMiniMapSize As Integer : m_iMiniMapSize = 150
  682.  
  683. ' PLACE MINI MAP TEXT ON SCREEN (150 pixels = 19 text characters)
  684. Dim Shared m_iMiniMapTextStartRow As Integer : m_iMiniMapTextStartRow = 60
  685. Dim Shared m_iMiniMapTextStartCol As Integer : m_iMiniMapTextStartCol = 39
  686. Dim Shared m_iMiniMapTextSize As Integer : m_iMiniMapTextSize = 19
  687.  
  688. ' TODO: ADD UNLIMITED UNDO, FOR NOW ONE LEVEL IS BETTER THAN NONE!
  689. Dim Shared m_MapTileUndo As MapUndoType
  690.  
  691. ' This array is used to hold user's drawing actions,
  692. ' to save drawings and for playback, and later for Undo/Redo.
  693. ' How big will the recording get?
  694. ' Max # tiles in (32x32x32) world = 32,768
  695. ' Max # tiles for 16 (32x32x32) worlds = 524,288
  696. ' Max # tiles for 256 (32x32x32) worlds = 8,388,608
  697. ReDim Shared m_arrRecord(-1) As RecordType
  698.  
  699. ' For each player, map the 6 directional keys differently for each of the 6 directional orientations!
  700. Dim Shared m_arrDirKeyMap(m_iPlayerMin To m_iPlayerMax, c_iDir_Min To c_iDir_Max) As DirKeyMapType
  701.  
  702. ' Store offsets for splitscreen
  703. Dim Shared m_arrSplitScreen(m_iPlayerMin To m_iPlayerMax) As SplitScreenType
  704.  
  705. ' Store colors in an array
  706. Dim Shared m_arrColors(0 To 25) As Long
  707.  
  708. ' ENABLE / DISABLE DEBUG CONSOLE
  709. Dim Shared m_bTesting As Integer : m_bTesting = TRUE
  710.  
  711. ' ENABLE / DISABLE DEBUG GRID
  712. Dim Shared m_bDebugGrid As Integer : m_bDebugGrid = FALSE
  713.  
  714. ' TODO: REPLACE THIS HACK WAY OF TRACKING KEY UP/DOWN
  715. Dim Shared m_bButton_LeftCtrl As Integer: m_bButton_LeftCtrl = FALSE
  716. Dim Shared m_bButton_RightCtrl As Integer: m_bButton_RightCtrl = FALSE
  717. Dim Shared m_bButton_Y As Integer: m_bButton_Y = FALSE
  718. Dim Shared m_bButton_Z As Integer: m_bButton_Z = FALSE
  719.  
  720. ReDim m_arrGreenTreeColors(-1) As _Unsigned Long
  721.  
  722. ' =============================================================================
  723. ' LOCAL VARIABLES
  724. Dim in$
  725.  
  726. ' ****************************************************************************************************************************************************************
  727. ' ACTIVATE DEBUGGING WINDOW
  728. IF m_bTesting = TRUE THEN
  729.         $Console
  730.         _Delay 4
  731.         _Console On
  732.         _Echo "Started " + m_ProgramName$
  733.         _Echo "Debugging on..."
  734. ' ****************************************************************************************************************************************************************
  735.  
  736. ' =============================================================================
  737. ' START THE MAIN ROUTINE
  738. main
  739.  
  740. ' =============================================================================
  741. ' FINISH
  742. Print m_ProgramName$ + " finished."
  743. Input "Press <ENTER> to continue", in$
  744.  
  745. ' ****************************************************************************************************************************************************************
  746. ' DEACTIVATE DEBUGGING WINDOW
  747. IF m_bTesting = TRUE THEN
  748.         _Console Off
  749. ' ****************************************************************************************************************************************************************
  750.  
  751. System ' return control to the operating system
  752.  
  753. ' /////////////////////////////////////////////////////////////////////////////
  754.  
  755. Sub main
  756.     Dim RoutineName As String: RoutineName = "main"
  757.     Dim in$
  758.     Dim result$
  759.  
  760.     Screen 0
  761.  
  762.     Do
  763.         Cls
  764.         Print m_ProgramName$
  765.         Print
  766.         Print "Isomatric Mapping Demo Re-visited"
  767.         Print "v3.01, by Softintheheadware (Dec, 2021)"
  768.         Print
  769.         'PRINT "CONTROLS: PRESS <ESC> TO RETURN TO MENU"
  770.         'PRINT "PLAYER  LEFT       RIGHT       UP        DOWN       "
  771.         'PRINT "1       CRSR LEFT  CRSR RIGHT  CRSR UP   CRSR DOWN  "
  772.         'PRINT "2       KEYPAD 4   KEYPAD 6    KEYPAD 8  KEYPAD 2   "
  773.         'PRINT "3       A          S           W         Z          "
  774.         'PRINT "4       J          K           I         M          "
  775.         'PRINT
  776.  
  777.         Print "1. A little holiday message + primitive drawing in 2.5D woohoo!"
  778.         'Print "2. BoxDrawTest1$"
  779.         'Print "3. (TBD)"
  780.         'Print "4. (TBD)"
  781.         Print
  782.         Print "What to do? ('q' to exit)"
  783.                
  784.         Input in$: in$ = LCase$(Left$(in$, 1))
  785.  
  786.         If in$ = "1" Then
  787.             result$ = IsometricDraw1$
  788.         ElseIf in$ = "2" Then
  789.             'result$ = BoxDrawTest1$
  790.         ElseIf in$ = "3" Then
  791.             'result$ = IsometricDemo1$
  792.         ElseIf in$ = "4" Then
  793.             'result$ = IsometricDemo2$
  794.         ElseIf in$ = "5" Then
  795.             'result$ = IsometricDemo3$
  796.         End If
  797.  
  798.         If Len(result$) > 0 Then
  799.             Print result$
  800.         End If
  801.  
  802.     Loop Until in$ = "q"
  803. End Sub ' main
  804.  
  805. ' /////////////////////////////////////////////////////////////////////////////
  806.  
  807. Function IsometricDemo1$
  808.     IsometricDemo1$ = "(TBD)"
  809. End Function ' IsometricDemo1
  810.  
  811. ' /////////////////////////////////////////////////////////////////////////////
  812.  
  813. Function IsometricDemo2$
  814.     IsometricDemo2$ = "(TBD)"
  815. End Function ' IsometricDemo2
  816.  
  817. ' /////////////////////////////////////////////////////////////////////////////
  818.  
  819. Function IsometricDemo3$
  820.     IsometricDemo3$ = "(TBD)"
  821. End Function ' IsometricDemo3
  822.  
  823. ' /////////////////////////////////////////////////////////////////////////////
  824. ' Test all the values 0-255 for style
  825. ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  826.  
  827. Function BoxDrawTest1$
  828.     Dim in$
  829.     Dim iSize%
  830.     Dim iDrawX%
  831.     Dim iDrawY%
  832.     Dim iFromX%
  833.     Dim iFromY%
  834.     Dim iToX%
  835.     Dim iToY%
  836.     Dim iNextColor~&
  837.     Dim iLoop As Integer
  838.     Dim iSpace%
  839.     Dim sError As String: sError = ""
  840.  
  841.     iSize% = 48 ' {n}x{n} pixels square
  842.     iDrawX% = 10
  843.     iDrawY% = 10
  844.     iNextColor~& = cWhite
  845.     iSpace% = 8
  846.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  847.     For iLoop = 0 To 255
  848.         DrawStyledOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor~&, iLoop
  849.         'DrawOutlineBox iDrawX%+1, iDrawY%+1, iSize%-2, iNextColor~&, iLoop
  850.  
  851.         iDrawX% = iDrawX% + iSize% + iSpace%
  852.         If iDrawX% > (1280 - (iSize% * 2)) Then
  853.             iDrawX% = 10
  854.             iDrawY% = iDrawY% + iSize% + iSpace%
  855.  
  856.             If iDrawY% > (1024 - (iSize% * 2)) Then
  857.                 sError = "Ran out of Y space."
  858.                 Exit For
  859.             End If
  860.         End If
  861.     Next iLoop
  862.  
  863.     If Len(sError) = 0 Then
  864.         For iLoop = 1 To (iSize% \ 2)
  865.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor~&, iLoop
  866.             iDrawX% = iDrawX% + iSize% + iSpace%
  867.             If iDrawX% > (1280 - (iSize% * 2)) Then
  868.                 iDrawX% = 10
  869.                 iDrawY% = iDrawY% + iSize% + iSpace%
  870.                 If iDrawY% > (1024 - (iSize% * 2)) Then
  871.                     sError = "Ran out of Y space."
  872.                     Exit For
  873.                 End If
  874.             End If
  875.         Next iLoop
  876.     End If
  877.  
  878.     Locate 58, 1
  879.     If Len(sError) > 0 Then
  880.         Print sError
  881.     End If
  882.     Input "PRESS <ENTER> TO CONTINUE"; in$
  883.  
  884.     _KeyClear
  885.     Screen 0
  886.  
  887.     BoxDrawTest1$ = ""
  888. End Function ' BoxDrawTest1$
  889.  
  890. ' /////////////////////////////////////////////////////////////////////////////
  891. ' receives x,y,z coordinates of the back, bottom, left corner
  892. ' and width, length, height for the size
  893. ' where
  894. ' X1 is the x dimension, the size of which is W1 width
  895. ' Y1 is the y dimension, the size of which is L1 length
  896. ' Z1 is the z dimension, the size of which is H1 height
  897. ' and draws a tile iTile in the color iColor
  898. ' using PlotTile
  899.  
  900. ' usage:
  901. ' PlotCuboid startX, widthX, startY, lengthY, startZ, heightZ, iTile, iColor
  902.  
  903. ' TODO: add parameter to specify array to plot to
  904.  
  905. Sub PlotCuboid (X1 As Integer, W1 As Integer, Y1 As Integer, L1 As Integer, Z1 As Integer, H1 As Integer, iTile As Integer, iColor As _Unsigned Long)
  906.     Dim iX As Integer
  907.     Dim X2 As Integer
  908.     Dim iY As Integer
  909.     Dim Y2 As Integer
  910.     Dim iZ As Integer
  911.     Dim Z2 As Integer
  912.    
  913.     if W1 > 0 then
  914.         if L1 > 0 then
  915.             if H1 > 0 then
  916.                 X2 = (X1 + W1) - 1
  917.                 Y2 = (Y1 + L1) - 1
  918.                 Z2 = (Z1 + H1) - 1
  919.                 For iX = X1 To X2
  920.                     For iY = Y1 To Y2
  921.                         For iZ = Z1 To Z2
  922.                             PlotTile iX, iY, iZ, iTile, iColor
  923.                         Next iZ
  924.                     Next iY
  925.                 Next iX
  926.             end if
  927.         end if
  928.     end if
  929. End Sub ' PlotCuboid
  930.  
  931. ' /////////////////////////////////////////////////////////////////////////////
  932. ' Fast circle drawing in pure Atari BASIC#
  933. ' https://atariwiki.org/wiki/Wiki.jsp?page=Super%20fast%20circle%20routine
  934.  
  935. ' * Magazine: Moj Mikro, 1989/3
  936. ' * Author : Zlatko Bleha
  937. ' * Page : 27 - 31
  938. ' * Atari BASIC listing on disk (tokenized): M8903282.BAS
  939. ' * Atari BASIC listing (listed): M8903282.LST
  940.  
  941. ' Next example is demonstration of implementing mentioned circle algorithm
  942. ' in pure Atari BASIC. This program shows how much faster it is compared to
  943. ' classic program using sine and cosine functions from Atari BASIC
  944. ' (shown in last example).
  945.  
  946. ' Basic Listing M8903282.LST#
  947. '1 REM *******************************
  948. '2 REM PROGRAM  : FAST CIRCLE DRAWING
  949. '3 REM AUTHOR   : ZLATKO BLEHA
  950. '4 REM PUBLISHER: MOJ MIKRO MAGAZINE
  951. '5 REM ISSUE NO.: 1989, NO.3, PAGE 29
  952. '6 REM *******************************
  953. '7 REM
  954. '10 GRAPHICS 8:SETCOLOR 2,0,0:COLOR 3
  955. '20 PRINT "ENTER X, Y AND R"
  956. '30 INPUT X,Y,R
  957. '40 IF R=0 THEN PLOT X,Y:END
  958. '50 B=R:C=0:A=R-1
  959. '60 PLOT X+C,Y+B
  960. '70 PLOT X+C,Y-B
  961. '80 PLOT X-C,Y-B
  962. '90 PLOT X-C,Y+B
  963. '100 PLOT X+B,Y+C
  964. '110 PLOT X+B,Y-C
  965. '120 PLOT X-B,Y-C
  966. '130 PLOT X-B,Y+C
  967. '140 C=C+1
  968. '150 A=A+1-C-C
  969. '160 IF A>=0 THEN 190
  970. '170 B=B-1
  971. '180 A=A+B+B
  972. '190 IF B>=C THEN 60
  973.  
  974. ' Use some valid values for coordinates and radius, for example:
  975. ' X=40, Y=40, R=30
  976. ' X=130, Y=90, R=60
  977. ' Slow circle drawing in Atari BASIC#
  978. ' * Magazine: Moj Mikro, 1989/3
  979. ' * Author : Zlatko Bleha
  980. ' * Page : 27 - 31
  981. ' * Atari BASIC listing on disk (tokenized): M8903281.BAS
  982. ' * Atari BASIC listing (listed): M8903281.LST
  983.  
  984. ' This is classic example for drawing circles from Atari BASIC
  985. ' using sine and cosine functions. Unfortunatelly, this is very slow
  986. ' way of doing it and not recommended.
  987. ' Just use routine shown above and everybody will be happy
  988.  
  989. ' Basic Listing M8903281.LST#
  990. '1 REM *******************************
  991. '2 REM PROGRAM  : SLOW CIRCLE DRAWING
  992. '3 REM AUTHOR   : ZLATKO BLEHA
  993. '4 REM PUBLISHER: MOJ MIKRO MAGAZINE
  994. '5 REM ISSUE NO.: 1989, NO.3, PAGE 29
  995. '6 REM *******************************
  996. '7 REM
  997. '10 GRAPHICS 8:SETCOLOR 2,0,0:COLOR 3
  998. '20 FOR A=0 TO 6.28 STEP 0.02
  999. '30 X=SIN(A)*50+150
  1000. '40 Y=COS(A)*50+80
  1001. '50 PLOT X,Y
  1002. '60 NEXT A
  1003.  
  1004. ' Conclusion#
  1005. ' Returning back to first program with the fastest way of drawing circles...
  1006. ' There is one more thing to note. In case you want to use PLOT subroutine,
  1007. ' which is part of the main circle routine, then read following explanation.
  1008. ' PLOT routine is written so it can be used easily from Atari BASIC program
  1009. ' independently from main circle routine, by using like this:
  1010. ' A=USR(30179,POK,X,Y)
  1011. '
  1012. ' POK   1 (drawing a pixel), 0 (erasing a pixel)
  1013. ' X     X coordinate of the pixel
  1014. ' Y     Y coordinate of the pixel
  1015. '
  1016. ' The routine alone is not any faster than normal PLOT command
  1017. ' from Atari BASIC, because USR command takes approximately 75%
  1018. ' of whole execution. But, used as part of the main circle routine
  1019. ' it does not matter anymore, because it is integrated in one larger
  1020. ' entity. There the execution is very fast, with no overhead.
  1021. ' PLOT routine is here for you to examine anyway.
  1022. ' You never know if you will maybe need it in the future.
  1023.  
  1024. ' More on plotting circles:
  1025. '     Drawing a circle in BASIC - fast
  1026. '     https://www.cpcwiki.eu/forum/programming/drawing-a-circle-in-basic-fast/
  1027.  
  1028. ' -----------------------------------------------------------------------------
  1029. ' Modified to work with 3 dimensional array
  1030. ' -----------------------------------------------------------------------------
  1031. ' Dependencies:
  1032. ' Needs the following constants defined: cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1033.  
  1034. ' Receives:
  1035. ' iAxis   = which plane to draw it on, where cPlaneXY=X,Y cPlaneYZ=Y,Z cPlaneZX=X,Z
  1036. ' X,Y,Z   = center point of circle
  1037. ' R       = radius
  1038. ' iTile   = tile to plot with using PlotTile
  1039. ' iColor  = color to make the tile
  1040.  
  1041. ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1042. ' PlotCircle iAxis, startX, startY, startZ, radius, iTile, iColor
  1043.  
  1044. ' TODO: add parameter to specify array to plot to
  1045.  
  1046. Sub PlotCircle (iAxis As Integer, X As Integer, Y As Integer, Z As Integer, R As Integer, iTile As Integer, iColor As _Unsigned Long)
  1047.     Dim A As Integer
  1048.     Dim B As Integer
  1049.     Dim C As Integer
  1050.  
  1051.     If R > 0 Then
  1052.         B = R
  1053.         C = 0
  1054.         A = R - 1
  1055.         Do
  1056.             Select Case iAxis
  1057.                 Case cPlaneXY:
  1058.                     ' X, Y
  1059.                     PlotTile X + C, Y + B, Z, iTile, iColor
  1060.                     PlotTile X + C, Y - B, Z, iTile, iColor
  1061.                     PlotTile X - C, Y - B, Z, iTile, iColor
  1062.                     PlotTile X - C, Y + B, Z, iTile, iColor
  1063.                     PlotTile X + B, Y + C, Z, iTile, iColor
  1064.                     PlotTile X + B, Y - C, Z, iTile, iColor
  1065.                     PlotTile X - B, Y - C, Z, iTile, iColor
  1066.                     PlotTile X - B, Y + C, Z, iTile, iColor
  1067.                    
  1068.                 Case cPlaneYZ:
  1069.                     ' Y, Z
  1070.                     PlotTile X, Y + B, Z + C, iTile, iColor
  1071.                     PlotTile X, Y - B, Z + C, iTile, iColor
  1072.                     PlotTile X, Y - B, Z - C, iTile, iColor
  1073.                     PlotTile X, Y + B, Z - C, iTile, iColor
  1074.                     PlotTile X, Y + C, Z + B, iTile, iColor
  1075.                     PlotTile X, Y - C, Z + B, iTile, iColor
  1076.                     PlotTile X, Y - C, Z - B, iTile, iColor
  1077.                     PlotTile X, Y + C, Z - B, iTile, iColor
  1078.                    
  1079.                 Case cPlaneZX:
  1080.                     ' X, Z
  1081.                     PlotTile X + C, Y, Z + B, iTile, iColor
  1082.                     PlotTile X + C, Y, Z - B, iTile, iColor
  1083.                     PlotTile X - C, Y, Z - B, iTile, iColor
  1084.                     PlotTile X - C, Y, Z + B, iTile, iColor
  1085.                     PlotTile X + B, Y, Z + C, iTile, iColor
  1086.                     PlotTile X + B, Y, Z - C, iTile, iColor
  1087.                     PlotTile X - B, Y, Z - C, iTile, iColor
  1088.                     PlotTile X - B, Y, Z + C, iTile, iColor
  1089.                    
  1090.                 Case Else:
  1091.                     ' DO NOTHING
  1092.             End Select
  1093.             C = C + 1
  1094.             A = A + 1 - C - C
  1095.             If A < 0 Then ' IF A>=0 THEN 190
  1096.                 B = B - 1
  1097.                 A = A + B + B
  1098.             End If
  1099.             If B < C Then Exit Do ' 190 IF B>=C THEN 60
  1100.         Loop
  1101.     End If
  1102. End Sub ' PlotCircle
  1103.  
  1104. ' /////////////////////////////////////////////////////////////////////////////
  1105. ' Temporary variable version
  1106. ' later we will update PlotCircle and all will use that
  1107. ' for now bSaveToRecording is disabled
  1108. ' later we will use a global variable for that
  1109.  
  1110. ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1111. ' PlotCircle2 arrMap(), iAxis, X, Y, Z, R, iTile, iColor
  1112.  
  1113. Sub PlotCircle2 (arrMap() As MapTileType, iAxis As Integer, X As Integer, Y As Integer, Z As Integer, R As Integer, iTile As Integer, iColor As _Unsigned Long)
  1114.     Dim A As Integer
  1115.     Dim B As Integer
  1116.     Dim C As Integer
  1117.  
  1118.     If R > 0 Then
  1119.         B = R
  1120.         C = 0
  1121.         A = R - 1
  1122.         Do
  1123.             Select Case iAxis
  1124.                 Case cPlaneXY:
  1125.                     ' X, Y
  1126.                     PlotTile2 arrMap(), X + C, Y + B, Z, iTile, iColor
  1127.                     PlotTile2 arrMap(), X + C, Y - B, Z, iTile, iColor
  1128.                     PlotTile2 arrMap(), X - C, Y - B, Z, iTile, iColor
  1129.                     PlotTile2 arrMap(), X - C, Y + B, Z, iTile, iColor
  1130.                     PlotTile2 arrMap(), X + B, Y + C, Z, iTile, iColor
  1131.                     PlotTile2 arrMap(), X + B, Y - C, Z, iTile, iColor
  1132.                     PlotTile2 arrMap(), X - B, Y - C, Z, iTile, iColor
  1133.                     PlotTile2 arrMap(), X - B, Y + C, Z, iTile, iColor
  1134.                    
  1135.                 Case cPlaneYZ:
  1136.                     ' Y, Z
  1137.                     PlotTile2 arrMap(), X, Y + B, Z + C, iTile, iColor
  1138.                     PlotTile2 arrMap(), X, Y - B, Z + C, iTile, iColor
  1139.                     PlotTile2 arrMap(), X, Y - B, Z - C, iTile, iColor
  1140.                     PlotTile2 arrMap(), X, Y + B, Z - C, iTile, iColor
  1141.                     PlotTile2 arrMap(), X, Y + C, Z + B, iTile, iColor
  1142.                     PlotTile2 arrMap(), X, Y - C, Z + B, iTile, iColor
  1143.                     PlotTile2 arrMap(), X, Y - C, Z - B, iTile, iColor
  1144.                     PlotTile2 arrMap(), X, Y + C, Z - B, iTile, iColor
  1145.                    
  1146.                 Case cPlaneZX:
  1147.                     ' X, Z
  1148.                     PlotTile2 arrMap(), X + C, Y, Z + B, iTile, iColor
  1149.                     PlotTile2 arrMap(), X + C, Y, Z - B, iTile, iColor
  1150.                     PlotTile2 arrMap(), X - C, Y, Z - B, iTile, iColor
  1151.                     PlotTile2 arrMap(), X - C, Y, Z + B, iTile, iColor
  1152.                     PlotTile2 arrMap(), X + B, Y, Z + C, iTile, iColor
  1153.                     PlotTile2 arrMap(), X + B, Y, Z - C, iTile, iColor
  1154.                     PlotTile2 arrMap(), X - B, Y, Z - C, iTile, iColor
  1155.                     PlotTile2 arrMap(), X - B, Y, Z + C, iTile, iColor
  1156.                    
  1157.                 Case Else:
  1158.                     ' DO NOTHING
  1159.             End Select
  1160.             C = C + 1
  1161.             A = A + 1 - C - C
  1162.             If A < 0 Then ' IF A>=0 THEN 190
  1163.                 B = B - 1
  1164.                 A = A + B + B
  1165.             End If
  1166.             If B < C Then Exit Do ' 190 IF B>=C THEN 60
  1167.         Loop
  1168.     End If
  1169. End Sub ' PlotCircle2
  1170.  
  1171. ' /////////////////////////////////////////////////////////////////////////////
  1172. ' Re: Is this fast enough as general circle fill?
  1173. ' https://qb64forum.alephc.xyz/index.php?topic=298.msg1913#msg1913
  1174.  
  1175. ' From: SMcNeill
  1176. ' Date: « Reply #30 on: June 26, 2018, 03:34:18 pm »
  1177. '
  1178. ' Sometimes, computers do things that are completely counter-intuitive to us, and
  1179. ' we find ourselves having to step back as programmers and simply say, "WOW!!"  
  1180. ' Here's a perfect example of that:
  1181. ' Here we look at two different circle fill routines -- one, which I'd assume to
  1182. ' be faster, which precalculates the offset needed to find the endpoints for each
  1183. ' line which composes a circle, and another, which is the same old CircleFill
  1184. ' program which I've shared countless times over the years with people on various
  1185. ' QB64 forums.
  1186. '
  1187. ' When all is said and done though, CircleFill is STILL even faster than
  1188. ' CircleFillFast, which pregenerates those end-points for us!
  1189.  
  1190. ' -----------------------------------------------------------------------------
  1191. ' Modified to work with 3 dimensional array
  1192. ' -----------------------------------------------------------------------------
  1193. ' Dependencies:
  1194. ' Needs the following constants defined: cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1195.  
  1196. ' Receives:
  1197. ' iAxis   = which plane to draw it on, where 1=X,Y 2=Y,Z 3=X,Z
  1198. ' X,Y,Z   = center point of circle
  1199. ' R       = radius
  1200. ' iTile   = tile to plot with using PlotTile
  1201. ' iColor  = color to make the tile
  1202.  
  1203. ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1204. ' CircleFill iAxis, startX, startY, startZ, radius, iTile, iColor
  1205.  
  1206. ' TODO: add parameter to specify array to plot to
  1207.  
  1208. SUB CircleFill (iAxis As Integer, CX AS INTEGER, CY AS INTEGER, CZ AS INTEGER, R AS INTEGER, iTile As Integer, iColor As _Unsigned Long)
  1209.     DIM Radius AS INTEGER
  1210.         Dim RadiusError AS INTEGER
  1211.     DIM X AS INTEGER
  1212.         Dim Y AS INTEGER
  1213.         Dim iLoopX as INTEGER
  1214.         Dim iLoopY as INTEGER
  1215.         Dim iLoopZ as INTEGER
  1216.        
  1217.     Radius = ABS(R)
  1218.     RadiusError = -Radius
  1219.     X = Radius
  1220.     Y = 0
  1221.        
  1222.         'TODO: SHOULDN'T WE JUST PLOT A DOT IF RADIUS IS 1 RATHER THAN 0 ?
  1223.         IF Radius = 0 THEN
  1224.                 ''PSET (CX, CY), C
  1225.                 'PlotPoint CX, CY, S, MyArray()
  1226.                 PlotTile CX, CY, CZ, iTile, iColor
  1227.                 EXIT SUB
  1228.         END IF
  1229.        
  1230.         Select Case iAxis
  1231.                 Case cPlaneXY:
  1232.                         ' X, Y
  1233.                         ' (just add Z)
  1234.                        
  1235.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1236.                         ' which would be a problem with blending turned on.
  1237.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1238.                         FOR iLoopX = CX - X TO CX + X
  1239.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1240.                                 PlotTile iLoopX, CY, CZ, iTile, iColor
  1241.                         NEXT iLoopX
  1242.                        
  1243.                         WHILE X > Y
  1244.                                 RadiusError = RadiusError + Y * 2 + 1
  1245.                                 IF RadiusError >= 0 THEN
  1246.                                         IF X <> Y + 1 THEN
  1247.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1248.                                                 iLoopY = CY - X
  1249.                                                 FOR iLoopX = CX - Y TO CX + Y
  1250.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1251.                                                         PlotTile iLoopX, iLoopY, CZ, iTile, iColor
  1252.                                                 NEXT iLoopX
  1253.                                                
  1254.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1255.                                                 iLoopY = CY + X
  1256.                                                 FOR iLoopX = CX - Y TO CX + Y
  1257.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1258.                                                         PlotTile iLoopX, iLoopY, CZ, iTile, iColor
  1259.                                                 NEXT iLoopX
  1260.                                         END IF
  1261.                                         X = X - 1
  1262.                                         RadiusError = RadiusError - X * 2
  1263.                                 END IF
  1264.                                 Y = Y + 1
  1265.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1266.                                 iLoopY = CY - Y
  1267.                                 FOR iLoopX = CX - X TO CX + X
  1268.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1269.                                         PlotTile iLoopX, iLoopY, CZ, iTile, iColor
  1270.                                 NEXT iLoopX
  1271.                                
  1272.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1273.                                 iLoopY = CY + Y
  1274.                                 FOR iLoopX = CX - X TO CX + X
  1275.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1276.                                         PlotTile iLoopX, iLoopY, CZ, iTile, iColor
  1277.                                 NEXT iLoopX
  1278.                         WEND
  1279.                        
  1280.                 Case cPlaneYZ:
  1281.                         ' Y, Z
  1282.                         ' (x becomes z)
  1283.                        
  1284.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1285.                         ' which would be a problem with blending turned on.
  1286.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1287.                         FOR iLoopZ = CZ - X TO CZ + X
  1288.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1289.                                 PlotTile CX, CY, iLoopZ, iTile, iColor
  1290.                         NEXT iLoopZ
  1291.                        
  1292.                         WHILE X > Y
  1293.                                 RadiusError = RadiusError + Y * 2 + 1
  1294.                                 IF RadiusError >= 0 THEN
  1295.                                         IF X <> Y + 1 THEN
  1296.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1297.                                                 iLoopY = CY - X
  1298.                                                 FOR iLoopZ = CZ - Y TO CZ + Y
  1299.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1300.                                                         PlotTile CX, iLoopY, iLoopZ, iTile, iColor
  1301.                                                 NEXT iLoopZ
  1302.                                                
  1303.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1304.                                                 iLoopY = CY + X
  1305.                                                 FOR iLoopZ = CZ - Y TO CZ + Y
  1306.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1307.                                                         PlotTile CX, iLoopY, iLoopZ, iTile, iColor
  1308.                                                 NEXT iLoopZ
  1309.                                         END IF
  1310.                                         X = X - 1
  1311.                                         RadiusError = RadiusError - X * 2
  1312.                                 END IF
  1313.                                 Y = Y + 1
  1314.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1315.                                 iLoopY = CY - Y
  1316.                                 FOR iLoopZ = CZ - X TO CZ + X
  1317.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1318.                                         PlotTile CX, iLoopY, iLoopZ, iTile, iColor
  1319.                                 NEXT iLoopZ
  1320.                                
  1321.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1322.                                 iLoopY = CY + Y
  1323.                                 FOR iLoopZ = CZ - X TO CZ + X
  1324.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1325.                                         PlotTile CX, iLoopY, iLoopZ, iTile, iColor
  1326.                                 NEXT iLoopZ
  1327.                         WEND
  1328.                        
  1329.                 Case cPlaneZX:
  1330.                         ' X, Z
  1331.                         ' (x stays x, y becomes z)
  1332.                        
  1333.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1334.                         ' which would be a problem with blending turned on.
  1335.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1336.                         FOR iLoopX = CX - X TO CX + X
  1337.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1338.                                 PlotTile iLoopX, CY, CZ, iTile, iColor
  1339.                         NEXT iLoopX
  1340.                        
  1341.                         WHILE X > Y
  1342.                                 RadiusError = RadiusError + Y * 2 + 1
  1343.                                 IF RadiusError >= 0 THEN
  1344.                                         IF X <> Y + 1 THEN
  1345.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1346.                                                 iLoopZ = CZ - X
  1347.                                                 FOR iLoopX = CX - Y TO CX + Y
  1348.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1349.                                                         PlotTile iLoopX, CY, iLoopZ, iTile, iColor
  1350.                                                 NEXT iLoopX
  1351.                                                
  1352.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1353.                                                 iLoopZ = CZ + X
  1354.                                                 FOR iLoopX = CX - Y TO CX + Y
  1355.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1356.                                                         PlotTile iLoopX, CY, iLoopZ, iTile, iColor
  1357.                                                 NEXT iLoopX
  1358.                                         END IF
  1359.                                         X = X - 1
  1360.                                         RadiusError = RadiusError - X * 2
  1361.                                 END IF
  1362.                                 Y = Y + 1
  1363.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1364.                                 iLoopZ = CZ - Y
  1365.                                 FOR iLoopX = CX - X TO CX + X
  1366.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1367.                                         PlotTile iLoopX, CY, iLoopZ, iTile, iColor
  1368.                                 NEXT iLoopX
  1369.                                
  1370.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1371.                                 iLoopZ = CZ + Y
  1372.                                 FOR iLoopX = CX - X TO CX + X
  1373.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1374.                                         PlotTile iLoopX, CY, iLoopZ, iTile, iColor
  1375.                                 NEXT iLoopX
  1376.                         WEND                   
  1377.                        
  1378.                 Case Else:
  1379.                         ' DO NOTHING
  1380.         End Select
  1381.        
  1382. END SUB ' CircleFill
  1383.  
  1384. ' /////////////////////////////////////////////////////////////////////////////
  1385. ' Temporary variable version
  1386. ' later we will update CircleFill and all will use that
  1387. ' for now bSaveToRecording is disabled
  1388. ' later we will use a global variable for that
  1389.  
  1390. ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1391. ' CircleFill2 arrMap(), iAxis, X, Y, Z, R, iTile, iColor
  1392.  
  1393. SUB CircleFill2 (arrMap() As MapTileType, iAxis As Integer, CX AS INTEGER, CY AS INTEGER, CZ AS INTEGER, R AS INTEGER, iTile As Integer, iColor As _Unsigned Long)
  1394.     DIM Radius AS INTEGER
  1395.         Dim RadiusError AS INTEGER
  1396.     DIM X AS INTEGER
  1397.         Dim Y AS INTEGER
  1398.         Dim iLoopX as INTEGER
  1399.         Dim iLoopY as INTEGER
  1400.         Dim iLoopZ as INTEGER
  1401.        
  1402.     Radius = ABS(R)
  1403.     RadiusError = -Radius
  1404.     X = Radius
  1405.     Y = 0
  1406.        
  1407.         'TODO: SHOULDN'T WE JUST PLOT A DOT IF RADIUS IS 1 RATHER THAN 0 ?
  1408.         IF Radius = 0 THEN
  1409.                 ''PSET (CX, CY), C
  1410.                 'PlotPoint CX, CY, S, MyArray()
  1411.                 PlotTile2 arrMap(), CX, CY, CZ, iTile, iColor
  1412.                 EXIT SUB
  1413.         END IF
  1414.        
  1415.         Select Case iAxis
  1416.                 Case cPlaneXY:
  1417.                         ' X, Y
  1418.                         ' (just add Z)
  1419.                        
  1420.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1421.                         ' which would be a problem with blending turned on.
  1422.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1423.                         FOR iLoopX = CX - X TO CX + X
  1424.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1425.                                 PlotTile2 arrMap(), iLoopX, CY, CZ, iTile, iColor
  1426.                         NEXT iLoopX
  1427.                        
  1428.                         WHILE X > Y
  1429.                                 RadiusError = RadiusError + Y * 2 + 1
  1430.                                 IF RadiusError >= 0 THEN
  1431.                                         IF X <> Y + 1 THEN
  1432.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1433.                                                 iLoopY = CY - X
  1434.                                                 FOR iLoopX = CX - Y TO CX + Y
  1435.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1436.                                                         PlotTile2 arrMap(), iLoopX, iLoopY, CZ, iTile, iColor
  1437.                                                 NEXT iLoopX
  1438.                                                
  1439.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1440.                                                 iLoopY = CY + X
  1441.                                                 FOR iLoopX = CX - Y TO CX + Y
  1442.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1443.                                                         PlotTile2 arrMap(), iLoopX, iLoopY, CZ, iTile, iColor
  1444.                                                 NEXT iLoopX
  1445.                                         END IF
  1446.                                         X = X - 1
  1447.                                         RadiusError = RadiusError - X * 2
  1448.                                 END IF
  1449.                                 Y = Y + 1
  1450.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1451.                                 iLoopY = CY - Y
  1452.                                 FOR iLoopX = CX - X TO CX + X
  1453.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1454.                                         PlotTile2 arrMap(), iLoopX, iLoopY, CZ, iTile, iColor
  1455.                                 NEXT iLoopX
  1456.                                
  1457.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1458.                                 iLoopY = CY + Y
  1459.                                 FOR iLoopX = CX - X TO CX + X
  1460.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1461.                                         PlotTile2 arrMap(), iLoopX, iLoopY, CZ, iTile, iColor
  1462.                                 NEXT iLoopX
  1463.                         WEND
  1464.                        
  1465.                 Case cPlaneYZ:
  1466.                         ' Y, Z
  1467.                         ' (x becomes z)
  1468.                        
  1469.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1470.                         ' which would be a problem with blending turned on.
  1471.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1472.                         FOR iLoopZ = CZ - X TO CZ + X
  1473.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1474.                                 PlotTile2 arrMap(), CX, CY, iLoopZ, iTile, iColor
  1475.                         NEXT iLoopZ
  1476.                        
  1477.                         WHILE X > Y
  1478.                                 RadiusError = RadiusError + Y * 2 + 1
  1479.                                 IF RadiusError >= 0 THEN
  1480.                                         IF X <> Y + 1 THEN
  1481.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1482.                                                 iLoopY = CY - X
  1483.                                                 FOR iLoopZ = CZ - Y TO CZ + Y
  1484.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1485.                                                         PlotTile2 arrMap(), CX, iLoopY, iLoopZ, iTile, iColor
  1486.                                                 NEXT iLoopZ
  1487.                                                
  1488.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1489.                                                 iLoopY = CY + X
  1490.                                                 FOR iLoopZ = CZ - Y TO CZ + Y
  1491.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1492.                                                         PlotTile2 arrMap(), CX, iLoopY, iLoopZ, iTile, iColor
  1493.                                                 NEXT iLoopZ
  1494.                                         END IF
  1495.                                         X = X - 1
  1496.                                         RadiusError = RadiusError - X * 2
  1497.                                 END IF
  1498.                                 Y = Y + 1
  1499.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1500.                                 iLoopY = CY - Y
  1501.                                 FOR iLoopZ = CZ - X TO CZ + X
  1502.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1503.                                         PlotTile2 arrMap(), CX, iLoopY, iLoopZ, iTile, iColor
  1504.                                 NEXT iLoopZ
  1505.                                
  1506.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1507.                                 iLoopY = CY + Y
  1508.                                 FOR iLoopZ = CZ - X TO CZ + X
  1509.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1510.                                         PlotTile2 arrMap(), CX, iLoopY, iLoopZ, iTile, iColor
  1511.                                 NEXT iLoopZ
  1512.                         WEND
  1513.                        
  1514.                 Case cPlaneZX:
  1515.                         ' X, Z
  1516.                         ' (x stays x, y becomes z)
  1517.                        
  1518.                         ' Draw the middle span here so we don't draw it twice in the main loop,
  1519.                         ' which would be a problem with blending turned on.
  1520.                         'LINE (CX - X, CY)-(CX + X, CY), C, BF
  1521.                         FOR iLoopX = CX - X TO CX + X
  1522.                                 'PlotPoint iLoopX, CY, S, MyArray()
  1523.                                 PlotTile2 arrMap(), iLoopX, CY, CZ, iTile, iColor
  1524.                         NEXT iLoopX
  1525.                        
  1526.                         WHILE X > Y
  1527.                                 RadiusError = RadiusError + Y * 2 + 1
  1528.                                 IF RadiusError >= 0 THEN
  1529.                                         IF X <> Y + 1 THEN
  1530.                                                 'LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  1531.                                                 iLoopZ = CZ - X
  1532.                                                 FOR iLoopX = CX - Y TO CX + Y
  1533.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1534.                                                         PlotTile2 arrMap(), iLoopX, CY, iLoopZ, iTile, iColor
  1535.                                                 NEXT iLoopX
  1536.                                                
  1537.                                                 'LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  1538.                                                 iLoopZ = CZ + X
  1539.                                                 FOR iLoopX = CX - Y TO CX + Y
  1540.                                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1541.                                                         PlotTile2 arrMap(), iLoopX, CY, iLoopZ, iTile, iColor
  1542.                                                 NEXT iLoopX
  1543.                                         END IF
  1544.                                         X = X - 1
  1545.                                         RadiusError = RadiusError - X * 2
  1546.                                 END IF
  1547.                                 Y = Y + 1
  1548.                                 'LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  1549.                                 iLoopZ = CZ - Y
  1550.                                 FOR iLoopX = CX - X TO CX + X
  1551.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1552.                                         PlotTile2 arrMap(), iLoopX, CY, iLoopZ, iTile, iColor
  1553.                                 NEXT iLoopX
  1554.                                
  1555.                                 'LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  1556.                                 iLoopZ = CZ + Y
  1557.                                 FOR iLoopX = CX - X TO CX + X
  1558.                                         'PlotPoint iLoopX, iLoopY, S, MyArray()
  1559.                                         PlotTile2 arrMap(), iLoopX, CY, iLoopZ, iTile, iColor
  1560.                                 NEXT iLoopX
  1561.                         WEND                   
  1562.                        
  1563.                 Case Else:
  1564.                         ' DO NOTHING
  1565.         End Select
  1566.        
  1567. END SUB ' CircleFill2
  1568.  
  1569. ' /////////////////////////////////////////////////////////////////////////////
  1570. ' Returns a semicircle represented in a _Byte array
  1571.  
  1572. ' R       = radius
  1573. ' Q       = which quarter of the circle to return
  1574. '           where 1=top right, 2=bottom right, 3=bottom left, 4=top left
  1575. '           like this:
  1576.             ' .......4444111.......
  1577.             ' .....44.......11.....
  1578.             ' ....4...........1....
  1579.             ' ...4.............1...
  1580.             ' ..4...............1..
  1581.             ' .4.................1.
  1582.             ' .4.................1.
  1583.             ' 4...................1
  1584.             ' 4...................1
  1585.             ' 4...................1
  1586.             ' 3...................1
  1587.             ' 3...................2
  1588.             ' 3...................2
  1589.             ' 3...................2
  1590.             ' .3.................2.
  1591.             ' .3.................2.
  1592.             ' ..3...............2..
  1593.             ' ...3.............2...
  1594.             ' ....3...........2....
  1595.             ' .....33.......22.....
  1596.             ' .......3333222.......
  1597. ' S       = char to draw
  1598. ' MyArray = 2D *dynamic* array to plot semicircle in, (0 To R, 0 To R) of _Byte
  1599.  
  1600. ' Usage:
  1601. ' ReDim MyArray(-1, -1) As _Byte
  1602. ' GetSemicircle R, Q, MyArray()
  1603.  
  1604. Sub GetSemicircle (R As Integer, Q As Integer, MyArray() As _Byte)
  1605.     Dim RoutineName As String : RoutineName = "GetSemicircle"
  1606.     Dim A As Integer
  1607.     Dim B As Integer
  1608.     Dim C As Integer
  1609.     Dim DY As Integer
  1610.     Dim DX As Integer
  1611.    
  1612.     ' Resize array
  1613.     ReDim MyArray(0 To R, 0 To R) As _Byte
  1614.        
  1615.         ' Clear array
  1616.         FOR DX = 0 TO R
  1617.                 FOR DY = 0 TO R
  1618.                         MyArray(X,Y) = 0
  1619.                 NEXT DY
  1620.         NEXT DX
  1621.        
  1622.     If R > 0 Then
  1623.         ' Plot semicircle to array
  1624.         B = R
  1625.         C = 0
  1626.         A = R - 1
  1627.         Do
  1628.             ' PORTIONS OF CIRCLE:
  1629.             ' .......3333222.......
  1630.             ' .....33.......22.....
  1631.             ' ....3...........2....
  1632.             ' ...7.............6...
  1633.             ' ..7...............6..
  1634.             ' .7.................6.
  1635.             ' .7.................6.
  1636.             ' 7...................6
  1637.             ' 7...................6
  1638.             ' 7...................6
  1639.             ' 8...................6
  1640.             ' 8...................5
  1641.             ' 8...................5
  1642.             ' 8...................5
  1643.             ' .8.................5.
  1644.             ' .8.................5.
  1645.             ' ..8...............5..
  1646.             ' ...8.............5...
  1647.             ' ....4...........1....
  1648.             ' .....44.......11.....
  1649.             ' .......4444111.......
  1650.            
  1651.             ' JUST PLOT SELECTED QUADRANT:
  1652.             Select Case Q
  1653.                 Case 1:
  1654.                     ' quadrant #1
  1655.                     MyArray(C, R - B) = 1 ' 2
  1656.                     MyArray(B, R - C) = 1 ' 6
  1657.                 Case 2:
  1658.                     ' quadrant #2
  1659.                     MyArray(B, C) = 1 ' 5
  1660.                     MyArray(C, B) = 1 ' 1
  1661.                 Case 3:
  1662.                     ' quadrant #3
  1663.                     MyArray(R - C, B) = 1 ' 4
  1664.                     MyArray(R - B, C) = 1 ' 8
  1665.                 Case 4:
  1666.                     ' quadrant #4
  1667.                     MyArray(R - B, R - C) = 1 ' 7
  1668.                     MyArray(R - C, R - B) = 1 ' 3
  1669.                 Case Else:
  1670.                     ' (DO NOTHING)
  1671.             End Select
  1672.            
  1673.             '' PLOT CIRCLE:
  1674.             '' quadrant #1
  1675.             'PlotPoint R + C, R - B, S2, arrTemp() ' 2
  1676.             'PlotPoint R + B, R - C, S2, arrTemp() ' 6
  1677.             '
  1678.             '' quadrant #2
  1679.             'PlotPoint R + B, R + C, S2, arrTemp() ' 5
  1680.             'PlotPoint R + C, R + B, S2, arrTemp() ' 1
  1681.             '
  1682.             '' quadrant #3
  1683.             'PlotPoint R - C, R + B, S2, arrTemp() ' 4
  1684.             'PlotPoint R - B, R + C, S2, arrTemp() ' 8
  1685.             '
  1686.             '' quadrant #4
  1687.             'PlotPoint R - B, R - C, S2, arrTemp() ' 7
  1688.             'PlotPoint R - C, R - B, S2, arrTemp() ' 3
  1689.            
  1690.             C = C + 1
  1691.             A = A + 1 - C - C
  1692.             If A < 0 Then
  1693.                 B = B - 1
  1694.                 A = A + B + B
  1695.             End If
  1696.             If B < C Then Exit Do
  1697.         Loop
  1698.     End If
  1699. End Sub ' GetSemicircle
  1700.  
  1701. ' /////////////////////////////////////////////////////////////////////////////
  1702. ' ShearRotate v4
  1703.  
  1704. ' *****************************************************************************
  1705. ' UNDER CONSTRUCTION
  1706. ' Tried to get this working for 3D and positive indexed array,
  1707. ' and no runtime or compile errors,
  1708. ' but doesn't seem to be working (the screen goes black when we render it!)
  1709. ' *****************************************************************************
  1710.  
  1711. ' -----------------------------------------------------------------------------
  1712. ' CHANGES
  1713. ' -----------------------------------------------------------------------------
  1714. ' * Modified to work with 3 dimensional array (iterates through z axis)
  1715. ' * Modified to work with non-polar array (converts coordinates to polar coordinates)
  1716.  
  1717. ' -----------------------------------------------------------------------------
  1718. ' NOTES
  1719. ' -----------------------------------------------------------------------------
  1720. ' Tries to fix the problem of 2 points resolving to the same coordinate
  1721. ' (one overwrites the other, which becomes "lost")
  1722. ' using a different approach, by just looking at the problem angles:
  1723. ' 30, 60, 120, 150, 210, 240, 300, 330 degrees
  1724.  
  1725. ' (which can be cClockwise or cCounterClockwise)
  1726. ' together with which quarter of the screen the point is in,
  1727.  
  1728. ' Note: cClockwise and cCounterClockwise constants must be declared globally.
  1729.  
  1730. ' Returns # points missing (that could not be corrected) in iMissing parameter.
  1731.  
  1732. ' -----------------------------------------------------------------------------
  1733. ' Dependencies
  1734. ' -----------------------------------------------------------------------------
  1735. ' Needs the following constants defined:
  1736. ' cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  1737. ' cCounterClockwise = -1, cClockwise = 1
  1738.  
  1739. ' Receives:
  1740. ' OldArray() = original 3d array (x,y,z) of MapTileType to be rotated,
  1741. '              * must contain an odd # of elements, so there is a center axis to rotate around
  1742. ' NewArray() = rotated  3d array (x,y,z) of MapTileType to be returned
  1743. '              * must be the same array size/type as OldArray
  1744. '              * must be declared as a dynamic array with ReDim
  1745. ' angle1     = angle to rotate OldArray to, can be 0-360
  1746. ' iDirection = direction of rotation, can be cClockwise or cCounterClockwise
  1747. ' iAxis      = which plane to draw it on, where cPlaneXY=X,Y cPlaneYZ=Y,Z cPlaneZX=X,Z
  1748. '              * currently only cPlaneXY is supported
  1749. ' iMissing   = return value, # of points which were "lost in rotation"
  1750.  
  1751. ' -----------------------------------------------------------------------------
  1752. ' TODO:
  1753. ' * get it working
  1754. ' * maybe add option to only rotate one slice
  1755. '   (e.g. if we're rotating x/y, specify a single z)
  1756.  
  1757. ' -----------------------------------------------------------------------------
  1758. ' USAGE:
  1759. ' ShearRotate4 OldArray(), NewRotatedArray(), angleToRotateTo, cClockwise, cPlaneXY, iMissingTileCount
  1760.  
  1761. Sub ShearRotate4 ( _
  1762.         OldArray() As MapTileType, _
  1763.         NewArray() As MapTileType, _
  1764.         angle1 As Integer, _
  1765.         iDirection As Integer, _
  1766.         iAxis As Integer, _
  1767.         iMissing As Integer)
  1768.        
  1769.     Const Pi = 4 * Atn(1)
  1770.    
  1771.     Dim angle As Integer
  1772.     Dim TwoPi As Double: TwoPi = 8 * Atn(1)
  1773.     Dim RtoD As Double: RtoD = 180 / Pi ' radians * RtoD = degrees
  1774.     Dim DtoR As Double: DtoR = Pi / 180 ' degrees * DtoR = radians
  1775.     Dim x As Integer
  1776.     Dim y As Integer
  1777.         Dim z As Integer ' added for 3D
  1778.     Dim nangle As Integer
  1779.     Dim nx As Integer
  1780.     Dim ny As Integer
  1781.         Dim nz As Integer ' added for 3D
  1782.     Dim flipper As Integer
  1783.     Dim rotr As Double
  1784.     Dim shear1 As Double
  1785.     Dim shear2 As Double
  1786.     Dim clr As RotationType ' Integer
  1787.     Dim y1 As _Byte
  1788.     Dim xy1 As _Byte
  1789.     Dim fy As _Byte
  1790.     Dim fx As _Byte
  1791.     Dim in$
  1792.     Dim sLine As String
  1793.     ReDim arrLost(-1) As RotationType
  1794.     Dim iLoop As Integer
  1795.     Dim bFound As Integer
  1796.     Dim iScreenZone As Integer
  1797.         Dim iMidX As Integer
  1798.         Dim iMidY As Integer
  1799.         Dim iMidZ As Integer ' added for 3D
  1800.        
  1801.         Dim iPolarMinX As Integer
  1802.         Dim iPolarMaxX As Integer
  1803.         Dim iPolarMidX As Integer
  1804.         Dim iPolarMinY As Integer
  1805.         Dim iPolarMaxY As Integer
  1806.         Dim iPolarMidY As Integer
  1807.         Dim iPolarMinZ As Integer
  1808.         Dim iPolarMaxZ As Integer
  1809.         Dim iPolarMidZ As Integer
  1810.         Dim iDiffPolarX As Integer ' used to convert array coordinates to polar coordinates
  1811.         Dim iDiffPolarY As Integer
  1812.         Dim iDiffPolarZ As Integer
  1813.        
  1814.         ' -----------------------------------------------------------------------------
  1815.     ' initialize new with empty
  1816.     ReDim NewArray( _
  1817.                 LBound(OldArray, 1) To UBound(OldArray, 1), _
  1818.                 LBound(OldArray, 2) To UBound(OldArray, 2), _
  1819.                 LBound(OldArray, 3) To UBound(OldArray, 3) _
  1820.                 ) As MapTileType
  1821.                
  1822.     For x = LBound(NewArray, 1) To UBound(NewArray, 1)
  1823.         For y = LBound(NewArray, 2) To UBound(NewArray, 2)
  1824.                         For z = LBound(NewArray, 3) To UBound(NewArray, 3)
  1825.                                 NewArray(x, y, z).origx = x
  1826.                                 NewArray(x, y, z).origy = y
  1827.                                 NewArray(x, y, z).origz = z
  1828.                                 NewArray(x, y, z).Typ = c_iTile_Empty
  1829.                                 NewArray(x, y, z).Color1 = cEmpty
  1830.                         Next z
  1831.         Next y
  1832.     Next x
  1833.    
  1834.         ' -----------------------------------------------------------------------------
  1835.     ' angle is reversed
  1836.     angle = 360 - angle1
  1837.    
  1838.     ' Shearing each element 3 times in one shot
  1839.     nangle = angle
  1840.    
  1841.     ' this pre-processing portion basically rotates by 90 to get
  1842.     ' between -45 and 45 degrees, where the 3-shear routine works correctly...
  1843.     If angle > 45 And angle < 225 Then
  1844.         If angle < 135 Then
  1845.             nangle = angle - 90
  1846.         Else
  1847.             nangle = angle - 180
  1848.         End If
  1849.     End If
  1850.     If angle > 135 And angle < 315 Then
  1851.         If angle < 225 Then
  1852.             nangle = angle - 180
  1853.         Else
  1854.             nangle = angle - 270
  1855.         End If
  1856.     End If
  1857.     If nangle < 0 Then
  1858.         nangle = nangle + 360
  1859.     End If
  1860.     If nangle > 359 Then
  1861.         nangle = nangle - 360
  1862.     End If
  1863.    
  1864.     rotr = nangle * DtoR
  1865.     shear1 = Tan(rotr / 2) ' correct way
  1866.     shear2 = Sin(rotr)
  1867.    
  1868.     ' *** NOTE: this had a bug where the values 135, 224, and 314
  1869.     ' ***       all resolve to -45 degrees.
  1870.     ' ***       Fixed by changing < to <=
  1871.    
  1872.     'if angle >  45 and angle < 134 then
  1873.     If angle > 45 And angle <= 134 Then
  1874.         flipper = 1
  1875.     ElseIf angle > 134 And angle <= 224 Then
  1876.         flipper = 2
  1877.     ElseIf angle > 224 And angle <= 314 Then
  1878.         ' *** NOTE: this had a bug where this flipper was wrong
  1879.         '           Fixed by adding case 7
  1880.         'flipper = 3
  1881.         flipper = 7
  1882.     Else
  1883.         flipper = 0
  1884.     End If
  1885.        
  1886.         ' -----------------------------------------------------------------------------
  1887.         ' find midpoints
  1888.         iMidX = (UBound(OldArray, 1) - LBound(OldArray, 1)) / 2
  1889.         iMidY = (UBound(OldArray, 2) - LBound(OldArray, 2)) / 2
  1890.         iMidZ = (UBound(OldArray, 3) - LBound(OldArray, 3)) / 2
  1891.        
  1892.         ' -----------------------------------------------------------------------------
  1893.         ' determine polar coordinates
  1894.         ' since our arrays use positive coordinates
  1895.         ' e.g. convert 1 To 15 to -7 To 7
  1896.         iDiffPolarX = 0 - iMidX
  1897.         iPolarMinX = LBound(OldArray, 1) + iDiffPolarX
  1898.         iPolarMaxX = UBound(OldArray, 1) + iDiffPolarX
  1899.         iPolarMidX = 0
  1900.        
  1901.         iDiffPolarY = 0 - iMidY
  1902.         iPolarMinY = LBound(OldArray, 2) + iDiffPolarY
  1903.         iPolarMaxY = UBound(OldArray, 2) + iDiffPolarY
  1904.         iPolarMidY = 0
  1905.        
  1906.         iDiffPolarZ = 0 - iMidZ
  1907.         iPolarMinZ = LBound(OldArray, 3) + iDiffPolarZ
  1908.         iPolarMaxZ = UBound(OldArray, 3) + iDiffPolarZ
  1909.         iPolarMidZ = 0
  1910.        
  1911.         ' -----------------------------------------------------------------------------
  1912.         ' THIS PART DEPENDS ON WHICH AXIS WE'RE ROTATING ON
  1913.        
  1914.         Select Case iAxis
  1915.                 Case cPlaneXY:
  1916.                         ' X, Y
  1917.                        
  1918.                         ' Here is where it needs some optimizing possibly... kinda slow...
  1919.                        
  1920.                         For z = iPolarMinZ To iPolarMaxZ
  1921.                                 'For y = LBound(NewArray, 2) To UBound(NewArray, 2)
  1922.                                 For y = iPolarMinY To iPolarMaxY
  1923.                                         'For x = LBound(NewArray, 1) To UBound(NewArray, 1)
  1924.                                         For x = iPolarMinX To iPolarMaxX
  1925.                                                
  1926.                                                 ' find which part of screen the current point is in
  1927.                                                 if y > iPolarMidY then
  1928.                                                         ' bottom half of screen
  1929.                                                         if x > iPolarMidX then
  1930.                                                                 ' right half of screen
  1931.                                                                 iScreenZone = 2
  1932.                                                         else
  1933.                                                                 ' left half of screen
  1934.                                                                 iScreenZone = 3
  1935.                                                         end if
  1936.                                                 else
  1937.                                                         ' top half of screen
  1938.                                                         if x > iPolarMidX then
  1939.                                                                 ' right half of screen
  1940.                                                                 iScreenZone = 1
  1941.                                                         else
  1942.                                                                 ' left half of screen
  1943.                                                                 iScreenZone = 4
  1944.                                                         end if
  1945.                                                 end if
  1946.                                                
  1947.                                                 ' calculate directions
  1948.                                                 Select Case flipper
  1949.                                                         Case 1:
  1950.                                                                 nx = -y
  1951.                                                                 ny = x
  1952.                                                         Case 2:
  1953.                                                                 nx = -x
  1954.                                                                 ny = -y
  1955.                                                         Case 3:
  1956.                                                                 nx = -y
  1957.                                                                 ny = -x
  1958.                                                         Case 4:
  1959.                                                                 nx = -x
  1960.                                                                 ny = y
  1961.                                                         Case 5:
  1962.                                                                 nx = x
  1963.                                                                 ny = -y
  1964.                                                         Case 6:
  1965.                                                                 nx = y
  1966.                                                                 ny = x
  1967.                                                         Case 7:
  1968.                                                                 nx = y
  1969.                                                                 ny = -x
  1970.                                                         Case Else:
  1971.                                                                 nx = x
  1972.                                                                 ny = y
  1973.                                                 End Select
  1974.                                                
  1975.                                                 clr.Typ = OldArray(nx - iDiffPolarX, ny - iDiffPolarY, z - iDiffPolarZ).Typ
  1976.                                                 clr.Color1 = OldArray(nx - iDiffPolarX, ny - iDiffPolarY, z - iDiffPolarZ).Color1
  1977.                                                 clr.Alpha1 = OldArray(nx - iDiffPolarX, ny - iDiffPolarY, z - iDiffPolarZ).Alpha1
  1978.                                                
  1979.                                                 y1 = y * shear1
  1980.                                                 xy1 = x + y1
  1981.                                                 fy = (y - xy1 * shear2)
  1982.                                                 fx = xy1 + fy * shear1
  1983.                                                
  1984.                                                 If fx >= iPolarMinX And fx <= iPolarMaxX Then
  1985.                                                         If fy >= iPolarMinY And fy <= iPolarMaxY Then
  1986.                                                                 ' only draw here if this spot is empty
  1987.                                                                 if NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).Typ = c_iTile_Empty then
  1988.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).Typ = clr.Typ
  1989.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).Color1 = clr.Color1
  1990.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).Alpha1 = clr.Alpha1
  1991.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).origx = fx
  1992.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).origy = fy
  1993.                                                                         NewArray(fx - iDiffPolarX, fy - iDiffPolarY, z - iDiffPolarZ).origz = z ' added for 3D
  1994.                                                                 else
  1995.                                                                         ' don't draw, but save it to a list to handle later
  1996.                                                                         ReDim _Preserve arrLost(0 To UBound(arrLost) + 1) As RotationType
  1997.                                                                         arrLost(UBound(arrLost)).Typ = clr.Typ
  1998.                                                                         arrLost(UBound(arrLost)).Color1 = clr.Color1
  1999.                                                                         arrLost(UBound(arrLost)).Alpha1 = clr.Alpha1
  2000.                                                                         arrLost(UBound(arrLost)).origx = fx
  2001.                                                                         arrLost(UBound(arrLost)).origy = fy
  2002.                                                                         arrLost(UBound(arrLost)).origz = z ' added for 3D
  2003.                                                                        
  2004.                                                                         ' preserve which zone screen is in, 1 = top right, 2 = bottom right, 3 = bottom left, 4 = top left
  2005.                                                                         arrLost(UBound(arrLost)).zone = iScreenZone
  2006.                                                                 end if
  2007.                                                         End If
  2008.                                                 End If
  2009.                                         Next x
  2010.                                 Next y
  2011.                                
  2012.                                 ' try to place any points that would have overwritten to a spot nearby
  2013.                                 ' can nearby be determined by the direction of rotation  (iDirection)
  2014.                                 ' together with which quarter of the screen the point is in (iScreenZone)
  2015.                                 ' where we divide the screen up into 4 zones:
  2016.                                
  2017.                                 ' --------------------------------------
  2018.                                 '|                   |                  |
  2019.                                 '| zone 4            | zone 1           |
  2020.                                 '|                   |                  |
  2021.                                 '|--------------------------------------|
  2022.                                 '|                   |                  |
  2023.                                 '| zone 3            | zone 2           |
  2024.                                 '|                   |                  |
  2025.                                 '|                   |                  |
  2026.                                 ' --------------------------------------
  2027.                                
  2028.                                 ' in zone   rotation direction   search direction (y,x)
  2029.                                 ' -------   ------------------   ----------------------
  2030.                                 ' 1         clockwise            down + right
  2031.                                 ' 1         counter-clockwise    up   + left
  2032.                                 ' 2         clockwise            down + left
  2033.                                 ' 2         counter-clockwise    up   + right
  2034.                                 ' 3         clockwise            up   + left
  2035.                                 ' 3         counter-clockwise    down + right
  2036.                                 ' 4         clockwise            up   + right
  2037.                                 ' 4         counter-clockwise    down + left
  2038.                                
  2039.                                 if IsProblemAngle%(angle1) then
  2040.                                         iMissing = 0
  2041.                                         For iLoop = 0 To UBound(arrLost)
  2042.                                                 bFound = FindEmptyShearRotationPoint4%(arrLost(iLoop), iDirection, x - iDiffPolarX, y - iDiffPolarY, z - iDiffPolarZ, NewArray())
  2043.                                                 if bFound = TRUE then
  2044.                                                         'If m_bDebug = TRUE Then
  2045.                                                         '       _echo "Plotted  missing point " + chr$(34) + chr$(arrLost(iLoop).Typ) + chr$(34) + " to (x=" + cstr$(x) + ", y=" + cstr$(y) + ")"
  2046.                                                         'End If
  2047.                                                 else
  2048.                                                         iMissing = iMissing + 1
  2049.                                                         'If m_bDebug = TRUE Then
  2050.                                                         '       _echo "Detected missing point " + chr$(34) + chr$(arrLost(iLoop).Typ) + chr$(34) + " at (x=" + cstr$(x) + ", y=" + cstr$(y) + ")"
  2051.                                                         'End If
  2052.                                                 end if
  2053.                                         Next iLoop
  2054.                                 end if
  2055.                         Next z
  2056.                        
  2057.                 Case cPlaneYZ:
  2058.                         ' Y, Z
  2059.                         ' (UNDER CONSTRUCTION)
  2060.                 Case cPlaneZX:
  2061.                         ' X, Z
  2062.                         ' (UNDER CONSTRUCTION)
  2063.                 Case Else:
  2064.                         ' DO NOTHING
  2065.         End Select
  2066.        
  2067. End Sub ' ShearRotate4
  2068.  
  2069. ' /////////////////////////////////////////////////////////////////////////////
  2070. ' div: int1% = num1% \ den1%
  2071. ' mod: rem1% = num1% MOD den1%
  2072.  
  2073. function IsProblemAngle%(angle as integer)
  2074.         dim bResult as integer : bResult = FALSE
  2075.         Dim i%
  2076.         For i% = 0 To 360 Step 30
  2077.                 If i% Mod 90 <> 0 Then
  2078.                         if angle = i% then
  2079.                                 bResult = TRUE
  2080.                                 exit for
  2081.                         end if
  2082.                 End If
  2083.         Next i%
  2084.         IsProblemAngle% = bResult
  2085. end function ' IsProblemAngle%
  2086.  
  2087. ' /////////////////////////////////////////////////////////////////////////////
  2088. ' Looks for a new point
  2089. ' a little more accurately, using iDirection parameter
  2090. ' which can be cClockwise or cCounterClockwise.
  2091.  
  2092. ' Note: cClockwise and cCounterClockwise constants must be declared globally.
  2093.  
  2094. ' Receives
  2095. ' FindMe (RotationType) = contains
  2096. '                         .origx, .origy, .origz = the starting location to start looking from,
  2097. '                         .zone = which area of the screen the point is in
  2098. '                              (1=top right, 2=bottom right, 3=bottom left, 4=top left)
  2099. '                              to determine direction to look in
  2100. '                         .Typ = the value to write
  2101. ' iDirection (Integer) = direction of rotation, can be cClockwise or cCounterClockwise (constants must be declared globally)
  2102. ' destX (Integer) = if an empty spot is found, returns the x location here byref
  2103. ' destY (Integer) = if an empty spot is found, returns the y location here byref
  2104. ' destZ (Integer) = if an empty spot is found, returns the z location here byref
  2105. ' NewArray() (RotationType array (x,y,127) ) = array representing the screen to search in and plot to
  2106.  
  2107. ' Returns
  2108. ' FALSE if no empty spot was found
  2109. ' TRUE if an empty spot was found, and x,y,z location returned byref in destX,destY,destZ parameters
  2110.  
  2111. 'bFound= FindEmptyShearRotationPoint4%(arrLost(iLoop)        , iDirection           , x - iDiffPolarX , y - iDiffPolarY , z - iDiffPolarZ, NewArray() )
  2112. Function FindEmptyShearRotationPoint4%(FindMe As RotationType, iDirection As Integer, destX as integer, destY as integer, destZ, NewArray() As MapTileType)
  2113.     Dim bResult as Integer : bResult = FALSE
  2114.     Dim x As Integer
  2115.     Dim y As Integer
  2116.         Dim z As Integer
  2117.     Dim dirX As Integer
  2118.     Dim dirY As Integer
  2119.     Dim bContinue As Integer
  2120.        
  2121.         ' Initialize
  2122.     destX = 0
  2123.     destY = 0
  2124.         destZ = 0 ' added for 3D
  2125.     bContinue = TRUE
  2126.        
  2127.     ' Choose search direction based on the quadrant of the screen
  2128.         ' and the direction of rotation:
  2129.        
  2130.         ' iScreenZone   iDirection           search direction (y,x)
  2131.     ' -----------   ------------------   ----------------------
  2132.     ' 1             cClockwise           down + right ( 1, 1)
  2133.         ' 1             cCounterClockwise    up   + left  (-1,-1)
  2134.     ' 2             cClockwise           down + left  ( 1,-1)
  2135.     ' 2             cCounterClockwise    up   + right (-1, 1)
  2136.     ' 3             cClockwise           up   + left  (-1,-1)
  2137.     ' 3             cCounterClockwise    down + right ( 1, 1)
  2138.     ' 4             cClockwise           up   + right (-1, 1)
  2139.     ' 4             cCounterClockwise    down + left  ( 1,-1)
  2140.        
  2141.     If     FindMe.zone = 1 And iDirection = cClockwise Then
  2142.         dirY = 1
  2143.         dirX = 1
  2144.     ElseIf FindMe.zone = 1 And iDirection = cCounterClockwise Then
  2145.         dirY = -1
  2146.         dirX = -1
  2147.     ElseIf FindMe.zone = 2 And iDirection = cClockwise Then
  2148.         dirY = 1
  2149.         dirX = -1
  2150.     ElseIf FindMe.zone = 2 And iDirection = cCounterClockwise Then
  2151.         dirY = -1
  2152.         dirX = 1
  2153.     ElseIf FindMe.zone = 3 And iDirection = cClockwise Then
  2154.         dirY = -1
  2155.         dirX = -1
  2156.     ElseIf FindMe.zone = 3 And iDirection = cCounterClockwise Then
  2157.         dirY = 1
  2158.         dirX = 1
  2159.     ElseIf FindMe.zone = 4 And iDirection = cClockwise Then
  2160.         dirY = -1
  2161.         dirX = 1
  2162.     ElseIf FindMe.zone = 4 And iDirection = cCounterClockwise Then
  2163.         dirY = 1
  2164.         dirX = -1
  2165.     Else
  2166.         bContinue = FALSE
  2167.     End If
  2168.    
  2169.         ' Quit if we're out of bounds
  2170.     If bContinue = TRUE Then
  2171.                 bContinue = FALSE
  2172.         x = FindMe.origx
  2173.         y = FindMe.origy
  2174.                 z = FindMe.origz
  2175.                 if x >= LBound(NewArray, 1) then
  2176.                         if x <= UBound(NewArray, 1) then
  2177.                                 if y >= LBound(NewArray, 2) then
  2178.                                         if y <= UBound(NewArray, 2) then
  2179.                                                 if z >= LBound(NewArray, 3) then ' added checking z for 3D
  2180.                                                         if z <= UBound(NewArray, 3) then  ' added checking z for 3D
  2181.                                                                 bContinue = TRUE
  2182.                                                         end if
  2183.                                                 end if
  2184.                                         end if
  2185.                                 end if
  2186.                         end if
  2187.                 end if
  2188.         End If
  2189.        
  2190.         ' look along y axis for an available adjacent point
  2191.         If bContinue = TRUE Then
  2192.                 destX = x
  2193.                 destY = y + dirY
  2194.                 destZ = z
  2195.                 if destX >= LBound(NewArray, 1) then
  2196.                         if destX <= UBound(NewArray, 1) then
  2197.                                 if destY >= LBound(NewArray, 2) then
  2198.                                         if destY <= UBound(NewArray, 2) then
  2199.                                                 if NewArray(destX, destY, destZ).Typ = c_iTile_Empty then
  2200.                                                         NewArray(destX, destY, destZ).Typ = FindMe.Typ
  2201.                                                         NewArray(destX, destY, destZ).Color1 = FindMe.Color1
  2202.                                                         NewArray(destX, destY, destZ).Alpha1 = FindMe.Alpha1
  2203.                                                         bResult = TRUE
  2204.                                                         bContinue = FALSE
  2205.                                                 end if
  2206.                                         end if
  2207.                                 end if
  2208.                         end if
  2209.                 end if
  2210.         end if
  2211.        
  2212.         ' look along x axis for an available adjacent point
  2213.         If bContinue = TRUE Then
  2214.                 destX = x + dirX
  2215.                 destY = y
  2216.                 destZ = z
  2217.                 if destX >= LBound(NewArray, 1) then
  2218.                         if destX <= UBound(NewArray, 1) then
  2219.                                 if destY >= LBound(NewArray, 2) then
  2220.                                         if destY <= UBound(NewArray, 2) then
  2221.                                                 if NewArray(x + dirX, y, destZ).Typ = c_iTile_Empty then
  2222.                                                         NewArray(destX, destY, destZ).Typ = FindMe.Typ
  2223.                                                         NewArray(destX, destY, destZ).Color1 = FindMe.Color1
  2224.                                                         NewArray(destX, destY, destZ).Alpha1 = FindMe.Alpha1
  2225.                                                         bResult = TRUE
  2226.                                                         bContinue = FALSE
  2227.                                                 end if
  2228.                                         end if
  2229.                                 end if
  2230.                         end if
  2231.                 end if
  2232.         end if
  2233.        
  2234.         ' look diagonally for an available adjacent point
  2235.         If bContinue = TRUE Then
  2236.                 destX = x + dirX
  2237.                 destY = y + dirY
  2238.                 destZ = z
  2239.                 if destX >= LBound(NewArray, 1) then
  2240.                         if destX <= UBound(NewArray, 1) then
  2241.                                 if destY >= LBound(NewArray, 2) then
  2242.                                         if destY <= UBound(NewArray, 2) then
  2243.                                                 if NewArray(x + dirX, y + dirY, destZ).Typ = c_iTile_Empty then
  2244.                                                         NewArray(destX, destY, destZ).Typ = FindMe.Typ
  2245.                                                         NewArray(destX, destY, destZ).Color1 = FindMe.Color1
  2246.                                                         NewArray(destX, destY, destZ).Alpha1 = FindMe.Alpha1
  2247.                                                         bResult = TRUE
  2248.                                                         bContinue = FALSE
  2249.                                                 end if
  2250.                                         end if
  2251.                                 end if
  2252.                         end if
  2253.                 end if
  2254.     End If
  2255.        
  2256.     ' Return result
  2257.     FindEmptyShearRotationPoint4% = bResult
  2258. End Sub ' FindEmptyShearRotationPoint4%
  2259.  
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.  
  2268.  
  2269.  
  2270.  
  2271.  
  2272.  
  2273.  
  2274.  
  2275.  
  2276.  
  2277.  
  2278.  
  2279.  
  2280.  
  2281.  
  2282.  
  2283.  
  2284.  
  2285.  
  2286.  
  2287.  
  2288.  
  2289.  
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311. ' /////////////////////////////////////////////////////////////////////////////
  2312. ' Lets you draw a scene in 2.5D and save it to a file. Woo hoo!
  2313.  
  2314. ' Version 1 only supports 2 tile types:
  2315. ' c_iTile_Empty
  2316. ' c_iTile_Wall
  2317.  
  2318. Function IsometricDraw1$
  2319.     Dim RoutineName As String: RoutineName = "IsometricDraw1"
  2320.     Dim sResult As String: sResult = ""
  2321.     Dim sError As String: sError = ""
  2322.     Dim iX%
  2323.     Dim iY%
  2324.     Dim iZ%
  2325.     Dim iNewX%
  2326.     Dim iNewY%
  2327.     Dim iNewZ%
  2328.     Dim iMyColor~&
  2329.     Dim iColorScheme%
  2330.     Dim iDirection%
  2331.     Dim bFound As Integer
  2332.     Dim bDone As Integer
  2333.     Dim in$
  2334.     Dim iTotal% ' compute total available spaces
  2335.     Dim iCount% ' count # of spaces searched
  2336.     Dim bEnableRepeatingKeys As Integer
  2337.     Dim iLastKey As Integer ' USED WHEN REPEATING KEYS DISABLED
  2338.     Dim iLoop1 As Integer
  2339.     Dim iLoop2 As Integer
  2340.  
  2341.     Dim iPosX1%
  2342.     Dim iPosX2%
  2343.     Dim iPosY1%
  2344.     Dim iPosY2%
  2345.     Dim iPosZ1%
  2346.     Dim iPosZ2%
  2347.     Dim iNextColor~&
  2348.     Dim iFirstColor~&
  2349.     Dim bContinue As Integer
  2350.     Dim iLoopX%
  2351.     Dim iLoopY%
  2352.     Dim iLoopZ%
  2353.     Dim iLevelCount%
  2354.     Dim iLevelSize%
  2355.  
  2356.     Dim iDrawX%
  2357.     Dim iDrawY%
  2358.     Dim iSize%
  2359.         Dim iSizeX%
  2360.         Dim iSizeY%
  2361.         Dim iOffsetX%
  2362.     Dim iOffsetY%
  2363.  
  2364.     Dim iPlayerLoop As Integer
  2365.     Dim iDirLoop As Integer
  2366.     Dim iNextX As Integer
  2367.     Dim iNextY As Integer
  2368.  
  2369.     Dim iDrawColor%
  2370.     Dim iCursorColor~&
  2371.  
  2372.     Dim bIgnoreTerrain As Integer ' If TRUE, player can move through walls, etc.
  2373.     Dim iIndex As Long
  2374.     Dim sNextErr As String: sNextErr = ""
  2375.     Dim MapTileTempUndo As MapUndoType
  2376.    
  2377.     Dim iWidth As Integer
  2378.     Dim iLength As Integer
  2379.     Dim iHeight As Integer
  2380.     Dim iRadius As Integer
  2381.         Dim iBaseRadius As Integer
  2382.     ReDim arrColors(-1) As _Unsigned Long
  2383.     Dim bFinished As Integer
  2384.         dim iDR As Integer
  2385.         dim iDDR As Integer
  2386.         Dim iHalfZ%
  2387.         Dim iBaseZ%
  2388.         Dim iNextBaseZ%
  2389.         Dim iHalfRadius%
  2390.         'Dim sngDR As Single
  2391.         'Dim sngLevelSize As Single
  2392.         Dim iDL as integer
  2393.         Dim iValue As Integer
  2394.         Dim iSnow As Integer ' used to control how frequently a snowflake is spawned
  2395.        
  2396.         ReDim arrSemicircle(-1, -1) As _Byte
  2397.         ReDim arrDistance(-1) As Integer
  2398.         ReDim arrSnow(100) As SnowflakeType
  2399.         Dim iAngleXY As Integer
  2400.         Dim iRotationCount As Integer
  2401.         Dim iRotationMax As Integer
  2402.         Dim iIncrementAngle As Integer
  2403.        
  2404.         Dim arrLights(100) As SnowflakeType
  2405.         Dim oStar As SnowflakeType
  2406.        
  2407. '       ' USED FOR FIRST PERSON VIEW
  2408. '       Dim iDistance As Integer
  2409. '       Dim arrFPBrickSize(0 to 7) as Integer
  2410.        
  2411.        
  2412.        
  2413.        
  2414.         'USED FOR ANIMATIONS
  2415.         'm_arrRender0
  2416.         'yoda
  2417.        
  2418.        
  2419.        
  2420.     ' =============================================================================
  2421.     ' GET OPTIONS
  2422.     m_iPlayerCount = 1
  2423.     'm_iPlayerCount = PromptForIntegerInRange%("How many players ({min}-{max} or blank to quit)?", 1, 4, 0)
  2424.     'IF m_iPlayerCount = 0 THEN Goto CleanupAndExit
  2425.     bEnableRepeatingKeys = FALSE
  2426.        
  2427.         ' INITIALIZE OTHER SHARED VARIABLES
  2428.         'TODO: store color sequences in a linked list or dictionary
  2429.         'GetGreenTreeColors m_arrGreenTreeColors
  2430.        
  2431.     ' =============================================================================
  2432.     ' INITIALIZE GRAPHIC SCREEN
  2433.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  2434.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  2435.        
  2436.        
  2437. '       ' -----------------------------------------------------------------------------
  2438. '       ' INITIALIZE FIRST PERSON VIEW VARIABLES
  2439. '       iWidth = 16
  2440. '       for iDistance = 0 to 7
  2441. '               arrFPBrickSize(iDistance) = iWidth
  2442. '               iWidth = iWidth - 1
  2443. '       next iDistance
  2444. '      
  2445. '       arrFP_From(0) = -3
  2446. '       arrFP_From(1) = -3
  2447. '       arrFP_From(2) = -3
  2448. '       arrFP_From(3) = -3
  2449. '       arrFP_From(4) = -4
  2450. '       arrFP_From(5) = -4
  2451. '       arrFP_From(6) = -5
  2452. '       arrFP_From(7) = -6
  2453. '      
  2454. '       arrFP_To(0) = 4
  2455. '       arrFP_To(1) = 4
  2456. '       arrFP_To(2) = 4
  2457. '       arrFP_To(3) = 4
  2458. '       arrFP_To(4) = 5
  2459. '       arrFP_To(5) = 5
  2460. '       arrFP_To(6) = 6
  2461. '       arrFP_To(7) = 7
  2462.        
  2463.         ' -----------------------------------------------------------------------------
  2464.         ' BEGIN PLAYER 1 SCREEN PLACEMENT
  2465.         ' -----------------------------------------------------------------------------
  2466.     ' WINDOW PLACEMENT
  2467.         m_arrSplitScreen(1).GridOffsetX = 50
  2468.     m_arrSplitScreen(1).GridOffsetY = 50
  2469.     m_arrSplitScreen(1).GridOffsetZ = 0
  2470.     m_arrSplitScreen(1).ScreenOffsetX = 450
  2471.     m_arrSplitScreen(1).ScreenOffsetY = 200
  2472.     m_arrSplitScreen(1).ScreenOffsetZ = 0
  2473.        
  2474.         ' MINIMAP PLACEMENT
  2475.     m_arrSplitScreen(1).MiniMapFirstPersonX = m_iMiniMapStartCol + (0 * m_iMiniMapSize)
  2476.     m_arrSplitScreen(1).MiniMapFirstPersonY = m_iMiniMapStartRow
  2477.         m_arrSplitScreen(1).MiniMapTopDownX = m_iMiniMapStartCol + (1 * m_iMiniMapSize)
  2478.     m_arrSplitScreen(1).MiniMapTopDownY = m_iMiniMapStartRow
  2479.     m_arrSplitScreen(1).MiniMapFrontBackX = m_iMiniMapStartCol + (2 * m_iMiniMapSize)
  2480.     m_arrSplitScreen(1).MiniMapFrontBackY = m_iMiniMapStartRow
  2481.     m_arrSplitScreen(1).MiniMapRightLeftX = m_iMiniMapStartCol + (3 * m_iMiniMapSize)
  2482.     m_arrSplitScreen(1).MiniMapRightLeftY = m_iMiniMapStartRow
  2483.        
  2484.         ' MINIMAP TEXT PLACEMENT
  2485.     m_arrSplitScreen(1).MiniMapFirstPersonTextX = m_iMiniMapTextStartCol + (0 * m_iMiniMapTextSize)
  2486.     m_arrSplitScreen(1).MiniMapFirstPersonTextY = m_iMiniMapTextStartRow
  2487.     m_arrSplitScreen(1).MiniMapTopDownTextX = m_iMiniMapTextStartCol + (1 * m_iMiniMapTextSize)
  2488.     m_arrSplitScreen(1).MiniMapTopDownTextY = m_iMiniMapTextStartRow
  2489.     m_arrSplitScreen(1).MiniMapFrontBackTextX = m_iMiniMapTextStartCol + (2 * m_iMiniMapTextSize)
  2490.     m_arrSplitScreen(1).MiniMapFrontBackTextY = m_iMiniMapTextStartRow
  2491.     m_arrSplitScreen(1).MiniMapRightLeftTextX = m_iMiniMapTextStartCol + (3 * m_iMiniMapTextSize)
  2492.     m_arrSplitScreen(1).MiniMapRightLeftTextY = m_iMiniMapTextStartRow
  2493.         ' -----------------------------------------------------------------------------
  2494.         ' END PLAYER 1 SCREEN PLACEMENT
  2495.         ' -----------------------------------------------------------------------------
  2496.        
  2497.        
  2498.        
  2499.         ' -----------------------------------------------------------------------------
  2500.         ' BEGIN PLAYER 2 SCREEN PLACEMENT
  2501.         ' -----------------------------------------------------------------------------
  2502.     ' WINDOW PLACEMENT
  2503.         m_arrSplitScreen(2).GridOffsetX = 50
  2504.     m_arrSplitScreen(2).GridOffsetY = 50
  2505.     m_arrSplitScreen(2).GridOffsetZ = 0
  2506.     m_arrSplitScreen(2).ScreenOffsetX = 1000
  2507.     m_arrSplitScreen(2).ScreenOffsetY = 200
  2508.     m_arrSplitScreen(2).ScreenOffsetZ = 0
  2509.     'TODO: add minimap parameters for player 2
  2510.         ' -----------------------------------------------------------------------------
  2511.         ' END PLAYER 2 SCREEN PLACEMENT
  2512.         ' -----------------------------------------------------------------------------
  2513.        
  2514.         ' -----------------------------------------------------------------------------
  2515.         ' BEGIN PLAYER 3 SCREEN PLACEMENT
  2516.         ' -----------------------------------------------------------------------------
  2517.     ' WINDOW PLACEMENT
  2518.         m_arrSplitScreen(3).GridOffsetX = 50
  2519.     m_arrSplitScreen(3).GridOffsetY = 50
  2520.     m_arrSplitScreen(3).GridOffsetZ = 0
  2521.     m_arrSplitScreen(3).ScreenOffsetX = 450
  2522.     m_arrSplitScreen(3).ScreenOffsetY = 700
  2523.     m_arrSplitScreen(3).ScreenOffsetZ = 0
  2524.     'TODO: add minimap parameters for player 3
  2525.         ' -----------------------------------------------------------------------------
  2526.         ' END PLAYER 3 SCREEN PLACEMENT
  2527.         ' -----------------------------------------------------------------------------
  2528.        
  2529.         ' -----------------------------------------------------------------------------
  2530.         ' BEGIN PLAYER 4 SCREEN PLACEMENT
  2531.         ' -----------------------------------------------------------------------------
  2532.     ' WINDOW PLACEMENT
  2533.         m_arrSplitScreen(4).GridOffsetX = 50
  2534.     m_arrSplitScreen(4).GridOffsetY = 50
  2535.     m_arrSplitScreen(4).GridOffsetZ = 0
  2536.     m_arrSplitScreen(4).ScreenOffsetX = 1000
  2537.     m_arrSplitScreen(4).ScreenOffsetY = 700
  2538.     m_arrSplitScreen(4).ScreenOffsetZ = 0
  2539.     'TODO: add minimap parameters for player 4
  2540.         ' -----------------------------------------------------------------------------
  2541.         ' END PLAYER 4 SCREEN PLACEMENT
  2542.         ' -----------------------------------------------------------------------------
  2543.        
  2544.        
  2545.        
  2546.     ' -----------------------------------------------------------------------------
  2547.     ' INITIALIZE MAP TO EMPTY
  2548.     ClearIsometricMap
  2549.     ReDim m_arrRecord(-1) As RecordType
  2550.  
  2551.     ' -----------------------------------------------------------------------------
  2552.     ' INITIALIZE COLOR ARRAY
  2553.     m_arrColors(0) = cEmpty
  2554.     m_arrColors(1) = cBlack
  2555.     m_arrColors(2) = cDarkGray
  2556.     m_arrColors(3) = cDimGray
  2557.     m_arrColors(4) = cGray
  2558.     m_arrColors(5) = cLightGray
  2559.     m_arrColors(6) = cSilver
  2560.     m_arrColors(7) = cWhite
  2561.     m_arrColors(8) = cRed
  2562.     m_arrColors(9) = cOrangeRed
  2563.     m_arrColors(10) = cDarkOrange
  2564.     m_arrColors(11) = cOrange
  2565.     m_arrColors(12) = cGold
  2566.     m_arrColors(13) = cYellow
  2567.     m_arrColors(14) = cOliveDrab1
  2568.     m_arrColors(15) = cLime
  2569.     m_arrColors(16) = cMediumSpringGreen
  2570.     m_arrColors(17) = cCyan
  2571.     m_arrColors(18) = cDeepSkyBlue
  2572.     m_arrColors(19) = cDodgerBlue
  2573.     m_arrColors(20) = cSeaBlue
  2574.     m_arrColors(21) = cBlue
  2575.     m_arrColors(22) = cBluePurple
  2576.     m_arrColors(23) = cDeepPurple
  2577.     m_arrColors(24) = cPurple
  2578.     m_arrColors(25) = cPurpleRed
  2579.  
  2580.     ' -----------------------------------------------------------------------------
  2581.     ' INITIALIZE OTHER VARIABLES
  2582.     bIgnoreTerrain = TRUE
  2583.  
  2584.     ' -----------------------------------------------------------------------------
  2585.     ' BEGIN DRAW GROUND
  2586.     ' -----------------------------------------------------------------------------
  2587.     IF TRUE=TRUE THEN
  2588.         For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  2589.             For iLoopX% = m_iMapMinX To m_iMapMaxX
  2590.                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  2591.                     'PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cLightBrown
  2592.                                         PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cWhiteSmoke
  2593.                 Next iLoopY%
  2594.             Next iLoopX%
  2595.         Next iLoopZ%
  2596.     END IF
  2597.     ' -----------------------------------------------------------------------------
  2598.     ' END DRAW GROUND
  2599.     ' -----------------------------------------------------------------------------
  2600.        
  2601.     ' -----------------------------------------------------------------------------
  2602.     ' BEGIN DRAW TILE FLOOR
  2603.     ' -----------------------------------------------------------------------------
  2604.     IF TRUE=FALSE THEN
  2605.         For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  2606.             For iLoopX% = m_iMapMinX To m_iMapMaxX
  2607.                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  2608.                     ' ALTERNATE TILE COLORS
  2609.                     If IsEven%(iLoopX%) = TRUE Then
  2610.                         If IsEven%(iLoopY%) = TRUE Then
  2611.                             PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cGray
  2612.                         Else
  2613.                             PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cWhite
  2614.                         End If
  2615.                     Else
  2616.                         If IsEven%(iLoopY%) = TRUE Then
  2617.                             PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cWhite
  2618.                         Else
  2619.                             PlotTile iLoopX%, iLoopY%, iLoopZ%, c_iTile_Wall, cGray
  2620.                         End If
  2621.                     End If
  2622.                 Next iLoopY%
  2623.             Next iLoopX%
  2624.         Next iLoopZ%
  2625.     END IF
  2626.     ' -----------------------------------------------------------------------------
  2627.     ' END DRAW TILE FLOOR
  2628.     ' -----------------------------------------------------------------------------
  2629.        
  2630.     ' -----------------------------------------------------------------------------
  2631.     ' BEGIN DRAW A TALL HOLLOW PYRAMID
  2632.     ' -----------------------------------------------------------------------------
  2633.     If TRUE = FALSE Then
  2634.         iX% = 5
  2635.         iY% = 10
  2636.         iZ% = 1
  2637.         iLevelSize% = 4
  2638.  
  2639.         iPosX1% = iX%
  2640.         iPosX2% = iX% + 7
  2641.         iPosY1% = iY%
  2642.         iPosY2% = iY% + 7
  2643.  
  2644.         iNextColor~& = cRed
  2645.         iColorScheme% = 1 ' 1 = Rainbow6 #1, 9 = Rainbow6 #2, etc.
  2646.  
  2647.         'iNextColor~& = cWhite
  2648.         'iColorScheme% = 3 ' 3, 11 = grayscale, ascending
  2649.  
  2650.         iLevelCount% = 0
  2651.  
  2652.         bContinue = TRUE
  2653.         Do
  2654.             ' Draw front/back walls
  2655.             For iLoopX% = iPosX1% To iPosX2%
  2656.                 iLoopY% = iPosY1%
  2657.                 PlotTile iLoopX%, iLoopY%, iZ%, c_iTile_Wall, iNextColor~&
  2658.  
  2659.                 iLoopY% = iPosY2%
  2660.                 PlotTile iLoopX%, iLoopY%, iZ%, c_iTile_Wall, iNextColor~&
  2661.             Next iLoopX%
  2662.  
  2663.             ' Draw left/right walls
  2664.             For iLoopY% = iPosY1% To iPosY2%
  2665.                 iLoopX% = iPosX1%
  2666.                 PlotTile iLoopX%, iLoopY%, iZ%, c_iTile_Wall, iNextColor~&
  2667.  
  2668.                 iLoopX% = iPosX2%
  2669.                 PlotTile iLoopX%, iLoopY%, iZ%, c_iTile_Wall, iNextColor~&
  2670.             Next iLoopY%
  2671.  
  2672.             ' Add a door to middle of right wall
  2673.             iX% = iPosX1% + ((iPosX2% - iPosX1%) \ 2)
  2674.             PlotTile iX%, iPosY2%, iZ%, c_iTile_Empty, iNextColor~&
  2675.  
  2676.             ' Add a door to middle of front wall
  2677.             iY% = iPosY1% + ((iPosY2% - iPosY1%) \ 2)
  2678.             PlotTile iPosX2%, iY%, iZ%, c_iTile_Empty, iNextColor~&
  2679.  
  2680.             ' MOVE UP A LEVEL
  2681.             iLevelCount% = iLevelCount% + 1
  2682.             If iLevelCount% > iLevelSize% Then
  2683.                 iLevelCount% = 0
  2684.                 iPosX1% = iPosX1% + 1
  2685.                 iPosX2% = iPosX2% - 1
  2686.                 iPosY1% = iPosY1% + 1
  2687.                 iPosY2% = iPosY2% - 1
  2688.             End If
  2689.  
  2690.             ' QUIT AFTER WE REACH THE TOP
  2691.             If (iPosX1% <= iPosX2%) And (iPosY1% <= iPosY2%) Then
  2692.                 iZ% = iZ% + 1
  2693.                 DoCycleColor iColorScheme%, iNextColor~&
  2694.                 If iZ% > m_iMapMaxZ Then
  2695.                     bContinue = FALSE
  2696.                 End If
  2697.             Else
  2698.                 bContinue = FALSE
  2699.             End If
  2700.  
  2701.         Loop Until bContinue = FALSE
  2702.     End If
  2703.     ' -----------------------------------------------------------------------------
  2704.     ' END DRAW A TALL HOLLOW PYRAMID
  2705.     ' -----------------------------------------------------------------------------
  2706.    
  2707.     ' -----------------------------------------------------------------------------
  2708.     ' BEGIN DRAW A CUBOID
  2709.     ' -----------------------------------------------------------------------------
  2710.     IF TRUE = FALSE THEN
  2711.         'PlotCuboid startX, widthX, startY, lengthY, startZ, heightZ, iTile, iColor
  2712.         PlotCuboid 1, 5, 2, 4, 2, 3, c_iTile_Wall, cHotPink
  2713.     END IF
  2714.     ' -----------------------------------------------------------------------------
  2715.     ' END DRAW A CUBOID
  2716.     ' -----------------------------------------------------------------------------
  2717.    
  2718.     ' -----------------------------------------------------------------------------
  2719.     ' BEGIN DRAW SOME CIRCLES
  2720.     ' -----------------------------------------------------------------------------
  2721.     IF TRUE=FALSE THEN
  2722.         ' PlotCircle iAxis, startX, startY, startZ, radius, iTile, iColor
  2723.         PlotCircle cPlaneXY, 15, 15, 2, 7, c_iTile_Wall, cRed
  2724.         PlotCircle cPlaneYZ, 19, 20, 10, 6, c_iTile_Wall, cLime
  2725.         PlotCircle cPlaneZX, 23, 25, 20, 8, c_iTile_Wall, cBlue
  2726.     END IF
  2727.     ' -----------------------------------------------------------------------------
  2728.     ' END DRAW SOME CIRCLES
  2729.     ' -----------------------------------------------------------------------------
  2730.    
  2731.     ' -----------------------------------------------------------------------------
  2732.     ' BEGIN TEST SOME COLORS
  2733.     ' -----------------------------------------------------------------------------
  2734.     IF TRUE=FALSE THEN
  2735.         GetGreenTreeColors arrColors()
  2736.         iX% = 2
  2737.         iY% = 2
  2738.         iZ% = 2
  2739.         iWidth = 2
  2740.         iLength = 2
  2741.         iHeight = 8
  2742.         for iLoop1 = lbound(arrColors) to ubound(arrColors)
  2743.             iMyColor~& = arrColors(iLoop1)
  2744.             iY% = iY% + 2
  2745.             if (iY% > (m_iMapMaxY - 2) ) then
  2746.                 iY% = 2
  2747.                 iX% = iX% + 6
  2748.                 if (iX% > (m_iMapMaxX - 6) ) then
  2749.                     iX% = 6
  2750.                     iZ% = iZ% + 8
  2751.                     if (iZ% > (m_iMapMaxZ - 8) ) then
  2752.                         Exit For
  2753.                     end if
  2754.                 end if
  2755.             end if
  2756.             'PlotCuboid startX, widthX, startY, lengthY, startZ, heightZ, iTile, iColor
  2757.             PlotCuboid iX%, iWidth, iY%, iLength, iZ%, iHeight, c_iTile_Wall, iMyColor~&
  2758.         next iLoop1
  2759.     END IF
  2760.     ' -----------------------------------------------------------------------------
  2761.     ' END TEST SOME COLORS
  2762.     ' -----------------------------------------------------------------------------
  2763.        
  2764.        
  2765.        
  2766.        
  2767.        
  2768.        
  2769.        
  2770.        
  2771.        
  2772.        
  2773.        
  2774.        
  2775.        
  2776.        
  2777.     ' -----------------------------------------------------------------------------
  2778.     ' BEGIN DRAW TREE
  2779.         ' -----------------------------------------------------------------------------
  2780.     IF TRUE = TRUE THEN
  2781.                
  2782.                 ' x/y location of tree
  2783.                 iX% = 31
  2784.                 iY% = 31
  2785.                
  2786.                 ' star is same as tree
  2787.                 oStar.x = iX%
  2788.                 oStar.y = iY%
  2789.                
  2790.                 ' DRAW TRUNK
  2791.                 iRadius = 2
  2792.                 for iZ% = 1 to 4
  2793.                         ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  2794.                         CircleFill cPlaneXY, iX%, iY%, iZ%, iRadius, c_iTile_Wall, cLightBrown
  2795.                 next iZ%
  2796.                
  2797.                 ' DRAW THE TREE
  2798.                 iBaseZ% = 4 ' initial z location
  2799.                 iBaseRadius = 20 ' initial radius size
  2800.                 iLevelSize% = 6 ' how many blocks high each level is
  2801.                 iDR = 3 ' how fast radius decreases with each level
  2802.                 'iDL = 1
  2803.                 'sngDR = 0.5
  2804.                 'sngLevelSize = 7
  2805.                
  2806.                 'iHalfZ% = iBaseRadius / 2
  2807.                 iColorScheme% = 20
  2808.                 iNextColor~& = cGreen
  2809.                 bFinished = FALSE
  2810.                 Do
  2811.                         ' GET NEXT COLOR
  2812.                         DoCycleColor iColorScheme%, iNextColor~&
  2813.                        
  2814.                         ' GET CURVE
  2815.                         ReDim arrSemicircle(-1, -1) As _Byte
  2816.                         ReDim arrDistance(-1) As Integer
  2817.                         'GetSemicircle R, Q, arrSemicircle()
  2818.                         GetSemicircle iBaseRadius, 3, arrSemicircle()
  2819.                         iDrawY% = 0
  2820.                         For iLoopY% = ubound(arrSemiCircle,2) to lbound(arrSemiCircle,2) step -1
  2821.                                 iDrawX% = 0
  2822.                                 For iLoopX% = lbound(arrSemiCircle,1) to ubound(arrSemiCircle,1)
  2823.                                         if arrSemiCircle(iLoopX%, iLoopY%) = 0 then
  2824.                                                 iDrawX% = iDrawX% + 1
  2825.                                         else
  2826.                                                 Exit For
  2827.                                         end if
  2828.                                 Next iLoopX%
  2829.                                 iDrawY% = iDrawY% + 1
  2830.                                 ReDim _Preserve arrDistance(1 To iDrawY%) As Integer
  2831.                                 arrDistance(iDrawY%) = iDrawX%
  2832.                         Next iLoopY%
  2833.                        
  2834.                         ' NEXT PLOT A CONE IN THE CROSS SHAPE OF THE CURVE
  2835.                         'iHalfZ% = ubound(arrDistance) / 2
  2836.                         FOR iLoopZ% = 1 TO ubound(arrDistance)
  2837.                                 iRadius = arrDistance(iLoopZ%)
  2838.                                 iZ% = iBaseZ% + iLoopZ%
  2839.                                
  2840.                                 if iZ% > m_iMapMaxZ then
  2841.                                         bFinished = TRUE
  2842.                                         exit do
  2843.                                 end if
  2844.                                
  2845.                                 ' remember the highest point
  2846.                                 oStar.z = iZ%
  2847.                                
  2848.                                 ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  2849.                                 CircleFill cPlaneXY, iX%, iY%, iZ%, iRadius, c_iTile_Wall, iNextColor~&
  2850.                         NEXT iLoopZ%
  2851.                        
  2852.                         ' GET NEXT HEIGHT
  2853.                         iBaseZ% = iBaseZ% + iLevelSize%
  2854.                         iBaseRadius = iBaseRadius - iDR
  2855.                         if iBaseRadius < 5 then bFinished = TRUE
  2856.                        
  2857.                         ' GET NEXT LEVEL SIZE
  2858.                         'sngLevelSize = sngLevelSize - sngDR
  2859.                         'iLevelSize% = sngLevelSize
  2860.                         'iLevelSize% = iLevelSize% - iDL
  2861.                        
  2862.                         ' QUIT?
  2863.                         if bFinished = TRUE then exit do
  2864.                 Loop
  2865.     END IF
  2866.     ' -----------------------------------------------------------------------------
  2867.     ' END DRAW TREE
  2868.         ' -----------------------------------------------------------------------------
  2869.        
  2870.        
  2871.        
  2872.        
  2873.     ' -----------------------------------------------------------------------------
  2874.     ' BEGIN DRAW A TREE v1
  2875.     ' -----------------------------------------------------------------------------
  2876.     IF TRUE = FALSE THEN
  2877.         iNextColor~& = cGreen
  2878.         iColorScheme% = 20
  2879.         iX% = 31
  2880.         iY% = 31
  2881.         'iZ% = 1
  2882.                 iPosZ1% = 1
  2883.                 iBaseRadius = 15
  2884.                 iLevelSize% = 3
  2885.                 bFinished = FALSE
  2886.                
  2887.                 Do
  2888.                         iRadius = iBaseRadius
  2889.                         iLevelCount% = 0
  2890.                         iCount% = 0
  2891.                         iZ% = iPosZ1%
  2892.                         iDR = 1
  2893.                         iDDR = iRadius / 3
  2894.                        
  2895.                         Do
  2896.                                 iZ% = iZ% + 1
  2897.                                 if iZ% > m_iMapMaxZ then
  2898.                                         bFinished = TRUE
  2899.                                         exit do
  2900.                                 end if
  2901.                                
  2902.                                 DoCycleColor iColorScheme%, iNextColor~&
  2903.                                 iLevelCount% = iLevelCount% + 1
  2904.                                 if iLevelCount% >= iLevelSize% then
  2905.                                         iLevelCount% = 0
  2906.                                         iRadius = iRadius - iDR
  2907.                                 end if
  2908.                                
  2909.                                 if iRadius > 0 then
  2910.                                         'PlotCircle cPlaneXY, iX%, iY%, iZ%, iRadius, c_iTile_Wall, iNextColor~&
  2911.                                        
  2912.                                         ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  2913.                                         CircleFill cPlaneXY, iX%, iY%, iZ%, iRadius, c_iTile_Wall, iNextColor~&
  2914.                                        
  2915.                                 else
  2916.                                         iCount% = iCount% + 1
  2917.                                         if iCount% <= iLevelSize% then
  2918.                                                 PlotTile iX%, iY%, iZ%, c_iTile_Wall, iNextColor~&
  2919.                                         else
  2920.                                                 exit do
  2921.                                         end if
  2922.                                 end if
  2923.                                
  2924.                                 iDR = iDR + iDDR
  2925.                                 iDDR = iDDR - 1
  2926.                                
  2927.                         Loop
  2928.                        
  2929.                         iPosZ1% = iPosZ1% + ( (iZ% - iPosZ1%) \ 2 )
  2930.                         iBaseRadius = iBaseRadius - 1
  2931.                         if iBaseRadius < 2 then bFinished = TRUE
  2932.                        
  2933.                         if bFinished = TRUE then exit do
  2934.                 Loop
  2935.                
  2936.     END IF
  2937.     ' -----------------------------------------------------------------------------
  2938.     ' END DRAW A TREE v1
  2939.     ' -----------------------------------------------------------------------------
  2940.    
  2941.     ' -----------------------------------------------------------------------------
  2942.     ' BEGIN DRAW FRAME AROUND ENTIRE SPACE (TOP)
  2943.     ' -----------------------------------------------------------------------------
  2944.     IF TRUE=FALSE THEN
  2945.         For iLoopX% = m_iMapMinX + 3 To m_iMapMaxX - 3
  2946.             PlotTile iLoopX%, m_iMapMaxY - 3, m_iMapMaxZ, c_iTile_Wall, cPurple
  2947.             PlotTile iLoopX%, m_iMapMinY + 3, m_iMapMaxZ, c_iTile_Wall, cCyan
  2948.         Next iLoopX%
  2949.         For iLoopY% = m_iMapMinY + 3 To m_iMapMaxY - 3
  2950.             PlotTile m_iMapMinX + 3, iLoopY%, m_iMapMaxZ, c_iTile_Wall, cOrange
  2951.             PlotTile m_iMapMaxX - 3, iLoopY%, m_iMapMaxZ, c_iTile_Wall, cLime
  2952.         Next iLoopY%
  2953.     END IF
  2954.     ' -----------------------------------------------------------------------------
  2955.     ' END DRAW FRAME AROUND ENTIRE SPACE (TOP)
  2956.     ' -----------------------------------------------------------------------------
  2957.  
  2958.     ' -----------------------------------------------------------------------------
  2959.     ' BEGIN DRAW FRAME AROUND ENTIRE SPACE (MIDDLE)
  2960.     ' -----------------------------------------------------------------------------
  2961.     IF TRUE=FALSE THEN
  2962.         For iLoopX% = m_iMapMinX + 2 To m_iMapMaxX - 2
  2963.             PlotTile iLoopX%, m_iMapMaxY - 2, m_iMapMidZ, c_iTile_Wall, cDodgerBlue
  2964.             PlotTile iLoopX%, m_iMapMinY + 2, m_iMapMidZ, c_iTile_Wall, cDeepPurple
  2965.         Next iLoopX%
  2966.         For iLoopY% = m_iMapMinY + 2 To m_iMapMaxY - 2
  2967.             PlotTile m_iMapMinX + 2, iLoopY%, m_iMapMidZ, c_iTile_Wall, cDarkRed
  2968.             PlotTile m_iMapMaxX - 2, iLoopY%, m_iMapMidZ, c_iTile_Wall, cGold
  2969.         Next iLoopY%
  2970.     END IF
  2971.     ' -----------------------------------------------------------------------------
  2972.     ' END DRAW FRAME AROUND ENTIRE SPACE (MIDDLE)
  2973.     ' -----------------------------------------------------------------------------
  2974.  
  2975.     ' -----------------------------------------------------------------------------
  2976.     ' BEGIN DRAW FRAME AROUND ENTIRE SPACE (BOTTOM)
  2977.     ' -----------------------------------------------------------------------------
  2978.     IF TRUE=FALSE THEN
  2979.         For iLoopX% = m_iMapMinX + 1 To m_iMapMaxX - 1
  2980.             PlotTile iLoopX%, m_iMapMaxY - 1, m_iMapMinZ + 1, c_iTile_Wall, cSeaBlue
  2981.             PlotTile iLoopX%, m_iMapMinY + 1, m_iMapMinZ + 1, c_iTile_Wall, cChartreuse
  2982.         Next iLoopX%
  2983.         For iLoopY% = m_iMapMinY + 1 To m_iMapMaxY - 1
  2984.             PlotTile m_iMapMinX + 1, iLoopY%, m_iMapMinZ + 1, c_iTile_Wall, cOrangeRed
  2985.             PlotTile m_iMapMaxX - 1, iLoopY%, m_iMapMinZ + 1, c_iTile_Wall, cDeepSkyBlue
  2986.         Next iLoopY%
  2987.     END IF
  2988.     ' -----------------------------------------------------------------------------
  2989.     ' END DRAW FRAME AROUND ENTIRE SPACE (BOTTOM)
  2990.     ' -----------------------------------------------------------------------------
  2991.    
  2992.    
  2993.    
  2994.    
  2995.    
  2996.    
  2997.    
  2998.    
  2999.    
  3000.     ' =============================================================================
  3001.     ' PLACE PLAYER(S) <- ONLY ONE FOR THIS DEMO
  3002.  
  3003.     For iPlayerLoop = 1 To m_iPlayerCount
  3004.  
  3005.         ' -----------------------------------------------------------------------------
  3006.         ' BEGIN Map the 6 directional keys
  3007.         ' -----------------------------------------------------------------------------
  3008.         '*** CURRENTLY THIS IS NOT USED ***
  3009.         'TODO: GET THIS WORKING (CURRENTLY IT'S ALL WEIRD)
  3010.         'TODO: WHATEVER THE KEYS MAPPED ARE, SWAP THEM NON-HARDCODED
  3011.  
  3012.         ' differently for each of the 6 directional orientations!
  3013.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyBack = c_iKeyDown_Down
  3014.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyForward = c_iKeyDown_Up
  3015.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyLeft = c_iKeyDown_Left
  3016.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyRight = c_iKeyDown_Right
  3017.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyUp = c_iKeyDown_PgDn
  3018.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyDown = c_iKeyDown_PgUp
  3019.  
  3020.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyBack = c_iKeyDown_PgDn
  3021.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyForward = c_iKeyDown_PgUp
  3022.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyLeft = c_iKeyDown_Left
  3023.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyRight = c_iKeyDown_Right
  3024.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyUp = c_iKeyDown_Up
  3025.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyDown = c_iKeyDown_Down
  3026.  
  3027.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyBack = c_iKeyDown_Right
  3028.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyForward = c_iKeyDown_Left
  3029.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyLeft = c_iKeyDown_Down
  3030.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyRight = c_iKeyDown_Up
  3031.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyUp = c_iKeyDown_PgUp
  3032.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyDown = c_iKeyDown_PgDn
  3033.  
  3034.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyBack = c_iKeyDown_Left
  3035.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyForward = c_iKeyDown_Right
  3036.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyLeft = c_iKeyDown_Up
  3037.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyRight = c_iKeyDown_Down
  3038.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyUp = c_iKeyDown_PgUp
  3039.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyDown = c_iKeyDown_PgDn
  3040.  
  3041.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyBack = c_iKeyDown_Down
  3042.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyForward = c_iKeyDown_Up
  3043.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyLeft = c_iKeyDown_Right
  3044.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyRight = c_iKeyDown_Left
  3045.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyUp = c_iKeyDown_PgUp
  3046.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyDown = c_iKeyDown_PgDn
  3047.  
  3048.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyBack = c_iKeyDown_Up
  3049.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyForward = c_iKeyDown_Down
  3050.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyLeft = c_iKeyDown_Left
  3051.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyRight = c_iKeyDown_Right
  3052.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyUp = c_iKeyDown_PgUp
  3053.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyDown = c_iKeyDown_PgDn
  3054.         ' -----------------------------------------------------------------------------
  3055.         ' END Map the 6 directional keys
  3056.         ' -----------------------------------------------------------------------------
  3057.  
  3058.         ' FIND START POSITION
  3059.         iX% = RandomNumber(m_iMapMinX, m_iMapMaxX)
  3060.         iY% = RandomNumber(m_iMapMinY, m_iMapMaxY)
  3061.         iZ% = 1 ' RandomNumber(m_iMapMinZ, m_iMapMaxZ)
  3062.  
  3063.         ' MAKE SURE IT'S EMPTY
  3064.         If m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty Then
  3065.             bFound = TRUE
  3066.         Else
  3067.             ' IF NOT EMPTY THEN TRY TO FIND AN EMPTY SPOT
  3068.             iTotal% = ((m_iMapMaxX - m_iMapMinX) + 1) * ((m_iMapMaxY - m_iMapMinY) + 1) * ((m_iMapMaxZ - m_iMapMinZ) + 1)
  3069.             iCount% = 0
  3070.             bFound = FALSE
  3071.             Do
  3072.                 iX% = iX% + 1
  3073.                 If iX% > m_iMapMaxX Then
  3074.                     ' reset x and move to next y
  3075.                     iX% = m_iMapMinX
  3076.                     iY% = iY% + 1
  3077.                     If iY% > m_iMapMaxY Then
  3078.                         ' reset y and move to next z
  3079.                         iY% = m_iMapMinY
  3080.                         iZ% = iZ% + 1
  3081.                         If iZ% > m_iMapMaxZ Then
  3082.                             ' RESET Z AND SEE IF WE HAVE CHECKED EVERYTHING
  3083.                             iZ% = m_iMapMinZ
  3084.                             iCount% = iCount% + 1
  3085.                             If iCount% >= iTotal% Then
  3086.                                 ' NONE FOUND, EXIT
  3087.                                 Exit Do
  3088.                             End If
  3089.                         Else
  3090.                             iCount% = iCount% + 1
  3091.                         End If
  3092.                     Else
  3093.                         iCount% = iCount% + 1
  3094.                     End If
  3095.                 Else
  3096.                     iCount% = iCount% + 1
  3097.                 End If
  3098.                 If m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty Then
  3099.                     ' FOUND AN EMPTY SPACE, EXIT
  3100.                     bFound = TRUE
  3101.                     Exit Do
  3102.                 End If
  3103.             Loop
  3104.         End If
  3105.  
  3106.         If bFound = TRUE Then
  3107.             ' PICK A DIRECTION (SIMPLE FOR NOW, LEFT OR RIGHT)
  3108.             If iX% <= m_iMapMidX Then
  3109.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  3110.             Else
  3111.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  3112.             End If
  3113.  
  3114.             m_arrPlayer(iPlayerLoop).Tile1 = c_iTile_Player1
  3115.  
  3116.             ' SAVE COORDINATES TO PLAYER
  3117.             ' ****************************************************************************************************************************************************************
  3118.             ' for this demo we'll just use iX% instead of m_arrPlayer(iPlayerLoop).x, etc.
  3119.             ' to make it more readable
  3120.             ' ****************************************************************************************************************************************************************
  3121.             m_arrPlayer(iPlayerLoop).x = iX%
  3122.             m_arrPlayer(iPlayerLoop).y = iY%
  3123.             m_arrPlayer(iPlayerLoop).z = iZ%
  3124.             m_arrPlayer(iPlayerLoop).View = c_iDir_Forward
  3125.             m_arrPlayer(iPlayerLoop).Color1 = cRed
  3126.             m_arrPlayer(iPlayerLoop).Alpha1 = 255
  3127.             m_arrPlayer(iPlayerLoop).AlphaOverride = 255
  3128.             m_arrPlayer(iPlayerLoop).ColorScheme1 = 2
  3129.             m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 = 5 ' change color every 5 frames
  3130.             m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  3131.  
  3132.             ' DISPLAY OPTIONS
  3133.             m_arrPlayer(iPlayerLoop).GridSize = 4
  3134.             m_arrPlayer(iPlayerLoop).MapSize = 2
  3135.  
  3136.             ' RESET MOVEMENT VARIABLES
  3137.             m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  3138.             m_arrPlayer(iPlayerLoop).IsMoved = FALSE
  3139.  
  3140.             ' ********************************************************************************
  3141.             ' *** THIS IS NOW DONE AT THE RENDERING LEVEL FOR PLAYERS AND NON-TERRAIN OBJECTS
  3142.             ' ********************************************************************************
  3143.             '' DRAW PLAYER
  3144.             'm_arrMap(iX%, iY%, iZ%).Typ = m_arrPlayer(iPlayerLoop).Tile1
  3145.             'm_arrMap(iX%, iY%, iZ%).Color1 = m_arrPlayer(iPlayerLoop).Color1
  3146.             'm_arrMap(iX%, iY%, iZ%).AlphaOverride = m_arrPlayer(iPlayerLoop).Alpha1
  3147.  
  3148.         Else
  3149.             sError = "Could not find an empty space to start player."
  3150.             Exit For
  3151.         End If
  3152.  
  3153.     Next iPlayerLoop
  3154.  
  3155.     ' =============================================================================
  3156.     ' OTHER SETUP
  3157.     If Len(sError) = 0 Then
  3158.         ' RESET INPUT
  3159.         _KeyClear
  3160.         iLastKey = c_iKeyDown_Enter
  3161.     End If
  3162.  
  3163.     ' INIT UNDO INFO:
  3164.     m_MapTileUndo.x = iX%
  3165.     m_MapTileUndo.y = iY%
  3166.     m_MapTileUndo.z = iZ%
  3167.     m_MapTileUndo.Typ = m_arrMap(iX%, iY%, iZ%).Typ
  3168.     m_MapTileUndo.Color1 = m_arrMap(iX%, iY%, iZ%).Color1
  3169.     m_MapTileUndo.Alpha1 = m_arrMap(iX%, iY%, iZ%).Alpha1
  3170.        
  3171.        
  3172.        
  3173.        
  3174.        
  3175.        
  3176.        
  3177.        
  3178.        
  3179.        
  3180.        
  3181.        
  3182.        
  3183.        
  3184.        
  3185.        
  3186.        
  3187.     ' =============================================================================
  3188.         ' BEGIN ANIMATION LOOP #1
  3189.     ' =============================================================================
  3190.     If Len(sError) = 0 Then
  3191.                 ' show text message
  3192.                 in$ = "Happy New Year 2022!"
  3193.                 iMyColor~& = cYellow
  3194.                 For iLoop1 = 1 to len(in$)
  3195.                         DoCycleColor 1, iMyColor~&
  3196.                         Color iMyColor~&
  3197.                         LOCATE 10, 18 + iLoop1 ' <-- not sure why it starts to be truncated after column 20!
  3198.                         Print mid$(in$, iLoop1, 1);
  3199.                 Next iLoop1
  3200.                 Color cWhite
  3201.                
  3202.                
  3203.                 ' reset snowflakes
  3204.                 For iCount% = lbound(arrSnow) to ubound(arrSnow)
  3205.                         arrSnow(iCount%).IsEnabled = FALSE
  3206.                         arrSnow(iCount%).xCount = 0
  3207.                         arrSnow(iCount%).xMax = 5
  3208.                         arrSnow(iCount%).yCount = 0
  3209.                         arrSnow(iCount%).yMax = 5
  3210.                         arrSnow(iCount%).zCount = 0
  3211.                         arrSnow(iCount%).zMax = 5
  3212.                 Next iCount%
  3213.                 iSnow = 50
  3214.                
  3215.                 ' set up star
  3216.                 oStar.Color1 = cYellow
  3217.                 oStar.Color2 = cGold
  3218.                 oStar.Color3 = cYellow
  3219.                
  3220.                 ' these values control the star size
  3221.                 oStar.xCount = 0
  3222.                 oStar.xMax = 4
  3223.                 oStar.yCount = 0
  3224.                 oStar.yMax = 3
  3225.                 oStar.zCount = 0
  3226.                 oStar.zMax = 4
  3227.                
  3228.                 ' set up rotation
  3229.                 iIncrementAngle = 1 ' angle to increase/decrease when rotating, set to 0 to disable rotation
  3230.                 iRotationMax = 5 ' rotates every # of frames
  3231.                 iRotationCount = 0 '
  3232.                 iAngleXY = 0
  3233.                
  3234.                 ' Animate until user presses <ESC>
  3235.         Do
  3236.                         ' MOVE EXISTING SNOWFLAKES
  3237.                         For iCount% = lbound(arrSnow) to ubound(arrSnow)
  3238.                                 ' IS THIS SNOWFLAKE ACTIVE?
  3239.                                 if arrSnow(iCount%).IsEnabled = TRUE then
  3240.                                        
  3241.                                         ' maybe move along x axis
  3242.                                         arrSnow(iCount%).xCount = arrSnow(iCount%).xCount + 1
  3243.                                         if arrSnow(iCount%).xCount > arrSnow(iCount%).xMax then
  3244.                                                 arrSnow(iCount%).xCount = arrSnow(iCount%).xMax
  3245.                                                
  3246.                                                 ' maybe move
  3247.                                                 iNewX% = RandomNumber% (1, 255)
  3248.                                                 if iNewX% < 32 then
  3249.                                                         arrSnow(iCount%).xMax = 0
  3250.                                                         if iNewX% < 16 then
  3251.                                                                 arrSnow(iCount%).x = arrSnow(iCount%).x - 1
  3252.                                                                 if arrSnow(iCount%).x < m_iMapMinX then
  3253.                                                                         arrSnow(iCount%).x = m_iMapMaxX
  3254.                                                                 end if
  3255.                                                         else
  3256.                                                                 arrSnow(iCount%).x = arrSnow(iCount%).x + 1
  3257.                                                                 if arrSnow(iCount%).x > m_iMapMaxX then
  3258.                                                                         arrSnow(iCount%).x = m_iMapMinX
  3259.                                                                 end if
  3260.                                                         end if
  3261.                                                 end if
  3262.                                         end if
  3263.                                        
  3264.                                         ' maybe move along y axis
  3265.                                         arrSnow(iCount%).yCount = arrSnow(iCount%).yCount + 1
  3266.                                         if arrSnow(iCount%).yCount > arrSnow(iCount%).yMax then
  3267.                                                 arrSnow(iCount%).yCount = arrSnow(iCount%).yMax
  3268.                                                
  3269.                                                 ' maybe move
  3270.                                                 iNewY% = RandomNumber% (1, 255)
  3271.                                                 if iNewY% < 32 then
  3272.                                                         arrSnow(iCount%).yMax = 0
  3273.                                                         if iNewY% < 16 then
  3274.                                                                 arrSnow(iCount%).y = arrSnow(iCount%).y - 1
  3275.                                                                 if arrSnow(iCount%).y < m_iMapMinY then
  3276.                                                                         arrSnow(iCount%).y = m_iMapMaxY
  3277.                                                                 end if
  3278.                                                         else
  3279.                                                                 arrSnow(iCount%).y = arrSnow(iCount%).y + 1
  3280.                                                                 if arrSnow(iCount%).y > m_iMapMaxY then
  3281.                                                                         arrSnow(iCount%).y = m_iMapMinY
  3282.                                                                 end if
  3283.                                                         end if
  3284.                                                 end if
  3285.                                         end if
  3286.                                        
  3287.                                         ' fall to earth
  3288.                                         arrSnow(iCount%).zCount = arrSnow(iCount%).zCount + 1
  3289.                                         if arrSnow(iCount%).zCount > arrSnow(iCount%).zMax then
  3290.                                                 arrSnow(iCount%).zMax = 0
  3291.                                                 arrSnow(iCount%).z = arrSnow(iCount%).z - 1
  3292.                                                 ' has snowflake hit bottom or landed on something?
  3293.                                                 if arrSnow(iCount%).z = m_iMapMinZ + 1 or m_arrMap(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z - 1).Typ = c_iTile_Wall then
  3294.                                                         ' stop moving, copy to the world
  3295.                                                         arrSnow(iCount%).IsEnabled = FALSE
  3296.                                                         m_arrMap(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Typ = arrSnow(iCount%).Tile1
  3297.                                                         m_arrMap(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Color1 = arrSnow(iCount%).Color1
  3298.                                                         m_arrMap(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Alpha1 = arrSnow(iCount%).Alpha1
  3299.                                                 end if
  3300.                                         end if
  3301.                                        
  3302.                                 end if
  3303.                         Next iCount%
  3304.                        
  3305.                         ' CYCLE STAR COLOR
  3306.                         'DoCycleColor 1, oStar.Color1
  3307.                         if oStar.Color1 = cYellow then
  3308.                                 oStar.Color1 = cGold
  3309.                         else
  3310.                                 oStar.Color1 = cYellow
  3311.                         end if
  3312.                        
  3313.                         if oStar.Color2 = cYellow then
  3314.                                 oStar.Color2 = cGold
  3315.                         else
  3316.                                 oStar.Color2 = cYellow
  3317.                         end if
  3318.                        
  3319.                         if oStar.Color3 = cYellow then
  3320.                                 oStar.Color3 = cGold
  3321.                         else
  3322.                                 oStar.Color3 = cYellow
  3323.                         end if
  3324.                        
  3325.                        
  3326.                        
  3327.                         oStar.xCount = oStar.xCount + 1
  3328.                         if oStar.xCount > oStar.xMax then oStar.xCount = 1
  3329.                         oStar.yCount = oStar.yCount + 1
  3330.                         if oStar.yCount > oStar.yMax then oStar.yCount = 1
  3331.                         oStar.zCount = oStar.zCount + 1
  3332.                         if oStar.zCount > oStar.zMax then oStar.zCount = 1
  3333.                        
  3334.                         ' CYCLE LIGHTS COLOR
  3335.                         ' (UNDER CONSTRUCTION)
  3336.                         'For iCount% = lbound(arrLights) to ubound(arrLights)
  3337.                         '       ' IS THIS LIGHT ACTIVE?
  3338.                         '       if arrLights(iCount%).IsEnabled = TRUE then
  3339.                         '       end if
  3340.                         'Next iCount%
  3341.                        
  3342.                        
  3343.                         ' CLEAR SCREEN
  3344.                         ' xMin = 310, yMin = -9
  3345.                         ' xMax = 1090, yMax = 765                      
  3346.                         'DrawRect (iX%, iY%, iSizeW%, iSizeH%, iColor~&)
  3347.                         DrawRect 310, 0, 780, 765, cBlack
  3348.                        
  3349.                        
  3350. 'galaxie
  3351.  
  3352.                         ' DRAW SPLIT SCREEN (MAIN VIEW)
  3353.                         'DrawSnowScreen iAngleXY, iScreenOffsetX, iScreenOffsetY, iGridSize, arrSnow() As SnowflakeType
  3354.                         DrawSnowScreen iAngleXY, m_arrSplitScreen(1).ScreenOffsetX, m_arrSplitScreen(1).ScreenOffsetY, m_arrPlayer(1).GridSize, arrSnow(), arrLights(), oStar
  3355.                        
  3356.  
  3357.                         ' BIRTH A SNOWFLAKE?
  3358.                         iValue = RandomNumber% (1, 255)
  3359.                         if iValue <= iSnow then
  3360.                                 For iCount% = lbound(arrSnow) to ubound(arrSnow)
  3361.                                         if arrSnow(iCount%).IsEnabled = FALSE then
  3362.                                                 arrSnow(iCount%).IsEnabled = TRUE
  3363.                                                 arrSnow(iCount%).x = RandomNumber%(m_iMapMinX, m_iMapMaxX)
  3364.                                                 arrSnow(iCount%).y = RandomNumber%(m_iMapMinY, m_iMapMaxY)
  3365.                                                 arrSnow(iCount%).z = m_iMapMaxZ
  3366.                                                 arrSnow(iCount%).Tile1 = c_iTile_Wall
  3367.                                                 arrSnow(iCount%).Color1 = cWhite
  3368.                                                 arrSnow(iCount%).Alpha1 = 255 ' RandomNumber%(190, 255)
  3369.                                                
  3370.                                                 arrSnow(iCount%).xCount = 0 ' snowflake x waver counter
  3371.                                                 arrSnow(iCount%).xMax = 20 ' snowflake can waver along x axis every n steps
  3372.                                                 arrSnow(iCount%).yCount = 0 ' snowflake y waver counter
  3373.                                                 arrSnow(iCount%).yMax = 20 ' snowflake can waver along y axis every n steps
  3374.                                                 arrSnow(iCount%).zCount = 10 ' snowflake descent counter
  3375.                                                 arrSnow(iCount%).zMax = 10 ' snowflake descends every n steps
  3376.                                                 'm_arrSnow(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z) = iCount%
  3377.                                                 exit for
  3378.                                         end if
  3379.                                 Next iCount%
  3380.                         end if
  3381.                         iSnow = iSnow + 1 ' increase chance of snow
  3382.                         if iSnow > 200 then iSnow = 200
  3383.                        
  3384. IF TRUE=FALSE THEN
  3385.                         ' UNDER CONSTRUCTION:
  3386.                         ' (DOESN'T WORK!)
  3387.                         ' ROTATE THE SCENE?
  3388.                         if iIncrementAngle <> 0 then
  3389.                                 iRotationCount = iRotationCount + 1
  3390.                                 if iRotationCount > iRotationMax then
  3391.                                         iRotationCount = 0
  3392.                                         iAngleXY = iAngleXY + iIncrementAngle
  3393.                                         if iAngleXY < 0 then
  3394.                                                 iAngleXY = 359
  3395.                                         elseif iAngleXY > 359 then
  3396.                                                 iAngleXY = 0
  3397.                                         end if
  3398.                                 end if
  3399.                         end if
  3400.                        
  3401.                         ' GET KEYBOARD INPUT
  3402.             If _KeyDown(c_iKeyDown_Esc) Then
  3403.                 Exit Do
  3404.                         End If
  3405.                        
  3406.                         ' REGULATE LOOP + REFRESH SCREEN
  3407.             _Limit 60
  3408.             _Display
  3409.         Loop
  3410.     End If
  3411.     ' =============================================================================
  3412.         ' END ANIMATION LOOP #1
  3413.     ' =============================================================================
  3414.        
  3415.        
  3416.        
  3417.        
  3418.        
  3419.        
  3420.        
  3421.        
  3422.        
  3423.        
  3424.        
  3425.        
  3426.        
  3427.        
  3428.        
  3429.        
  3430.        
  3431.        
  3432.        
  3433.        
  3434.        
  3435.        
  3436.        
  3437.     ' =============================================================================
  3438.     ' MAIN LOOP
  3439.     If Len(sError) = 0 Then
  3440.         iDrawColor% = 8 ' RED
  3441.         iCursorColor~& = cRed
  3442.        
  3443.         Do
  3444.             Cls ' is cls necessary?
  3445.                        
  3446.                        
  3447.                        
  3448. 'TODO: ONLY DRAW IF IT CHANGES?
  3449.                         ' -----------------------------------------------------------------------------
  3450.             ' BEGIN SHOW INSTRUCTIONS / COORDINATES ON SCREEN
  3451.             ' -----------------------------------------------------------------------------
  3452.                         Locate m_iInstrStartRow+0, m_iInstrStartCol: Print "IsometricDraw1"
  3453.             Locate m_iInstrStartRow+2, m_iInstrStartCol: Print "CRSR RT/LF MOVES X = " + cstr$(iX%)
  3454.             Locate m_iInstrStartRow+3, m_iInstrStartCol: Print "CRSR UP/DN MOVES Y = " + cstr$(iY%)
  3455.             Locate m_iInstrStartRow+4, m_iInstrStartCol: Print "PAGE UP/DN MOVES Z = " + cstr$(iZ%)
  3456.             Locate m_iInstrStartRow+5, m_iInstrStartCol: Print "=    / -   CHANGES GRID SIZE     = " + cstr$(m_arrPlayer(1).GridSize)
  3457.             Locate m_iInstrStartRow+6, m_iInstrStartCol: Print "[    / ]   TOGGLES MOVEMENT      = " + IIFSTR$(m_arrPlayer(1).IsMoving, "TRUE", "FALSE")
  3458.             Locate m_iInstrStartRow+7, m_iInstrStartCol: Print "INS  / DEL TOGGLES REPEAT KEYS   = " + IIFSTR$(bEnableRepeatingKeys, "TRUE", "FALSE")
  3459.             Locate m_iInstrStartRow+8, m_iInstrStartCol: Print ",    / .   CHANGES MINI MAP SIZE = " + cstr$(m_arrPlayer(1).MapSize)
  3460.             Locate m_iInstrStartRow+9, m_iInstrStartCol: Print "a    / b   FOR UNDO / REDO"
  3461.             Locate m_iInstrStartRow+11, m_iInstrStartCol: Print "PRESS <ESC> TO QUIT"
  3462.                        
  3463.             Locate m_iPaletteTextRow+0, m_iPaletteTextCol: Print "1 color-"
  3464.             Locate m_iPaletteTextRow+1, m_iPaletteTextCol: Print "2 color+"
  3465.             Locate m_iPaletteTextRow+2, m_iPaletteTextCol: Print "3 draw"
  3466.             Locate m_iPaletteTextRow+3, m_iPaletteTextCol: Print "4 erase"
  3467.             Locate m_iPaletteTextRow+4, m_iPaletteTextCol: Print "5 toggle"
  3468.             Locate m_iPaletteTextRow+5, m_iPaletteTextCol: Print "6 eyedropper"
  3469.             Locate m_iPaletteTextRow+6, m_iPaletteTextCol: Print "7 clear"
  3470.             Locate m_iPaletteTextRow+7, m_iPaletteTextCol: Print "8 open"
  3471.             Locate m_iPaletteTextRow+8, m_iPaletteTextCol: Print "9 save"
  3472.                         ' -----------------------------------------------------------------------------
  3473.                         ' END SHOW INSTRUCTIONS / COORDINATES ON SCREEN
  3474.                         ' -----------------------------------------------------------------------------
  3475.                        
  3476.             ' ****************************************************************************************************************************************************************
  3477.             ' BEGIN DRAW PALETTE
  3478.             ' ****************************************************************************************************************************************************************
  3479.             'TODO: support variable screen resolutions instead of hardcoded 1280x1024
  3480.             iSize% = 24 ' {n}x{n} pixels square
  3481.             iDrawX% = 10
  3482.             iOffsetY% = 250
  3483.             For iLoop1 = 0 To 25
  3484.                 iDrawY% = iOffsetY% + (iLoop1 * iSize%)
  3485.                 If iLoop1 = 0 Then
  3486.                     ' COLOR = TRANSPARENT
  3487.  
  3488.                     ' DRAW A CHECKERBOARD PATTERN FOR TRANSPARENT
  3489.                     iFirstColor~& = cDarkGray
  3490.                     For iLoopY% = iDrawY% To ((iDrawY% + iSize%) - 4) Step 4
  3491.                         If iFirstColor~& = cDarkGray Then
  3492.                             iFirstColor~& = cGray
  3493.                         Else
  3494.                             iFirstColor~& = cDarkGray
  3495.                         End If
  3496.                         iNextColor~& = iFirstColor~&
  3497.                         For iLoopX% = iDrawX% To ((iDrawX% + iSize%) - 4) Step 4
  3498.                             DrawBox iLoopX%, iLoopY%, 4, iNextColor~&
  3499.                             If iNextColor~& = cDarkGray Then
  3500.                                 iNextColor~& = cGray
  3501.                             Else
  3502.                                 iNextColor~& = cDarkGray
  3503.                             End If
  3504.                         Next iLoopX%
  3505.                     Next iLoopY%
  3506.                 ElseIf iLoop1 = 1 Then
  3507.                     ' COLOR = BLACK
  3508.                 Else
  3509.                     iNextColor~& = m_arrColors(iLoop1)
  3510.                     DrawBox iDrawX%, iDrawY%, iSize%, iNextColor~&
  3511.                 End If
  3512.  
  3513.                 ' DRAW A BORDER AROUND IT
  3514.                 iNextColor~& = cDarkGray
  3515.                 DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor~&, 1
  3516.             Next iLoop1
  3517.  
  3518.             ' DRAW WHITE BOX AROUND CURRENT COLOR
  3519.             DoCycleColor 1, iCursorColor~&
  3520.             iDrawY% = iOffsetY% + (iDrawColor% * iSize%)
  3521.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iCursorColor~&, 1
  3522.             ' ****************************************************************************************************************************************************************
  3523.             ' END DRAW PALETTE
  3524.             ' ****************************************************************************************************************************************************************
  3525.  
  3526.  
  3527.  
  3528.  
  3529.             ' ****************************************************************************************************************************************************************
  3530.             ' BEGIN DRAW MAP
  3531.                         ' ****************************************************************************************************************************************************************
  3532.                         ' DRAW SPLIT SCREEN (MAIN VIEW)
  3533.                         DrawScreen c_iDir_Forward, m_arrSplitScreen(1).ScreenOffsetX, m_arrSplitScreen(1).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  3534.            
  3535.                         '' DRAW SPLIT SCREEN (3 OTHER VIEWS)
  3536.                         'DrawScreen c_iDir_Back, m_arrSplitScreen(2).ScreenOffsetX, m_arrSplitScreen(2).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  3537.             'DrawScreen c_iDir_Left, m_arrSplitScreen(3).ScreenOffsetX, m_arrSplitScreen(3).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  3538.             'DrawScreen c_iDir_Right, m_arrSplitScreen(4).ScreenOffsetX, m_arrSplitScreen(4).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  3539.             ' ****************************************************************************************************************************************************************
  3540.             ' END DRAW MAP
  3541.                         ' ****************************************************************************************************************************************************************
  3542.                        
  3543.                        
  3544.                        
  3545.                        
  3546.                        
  3547.                        
  3548.                        
  3549.                        
  3550.                        
  3551.                        
  3552.                        
  3553.                        
  3554.             ' ****************************************************************************************************************************************************************
  3555.             ' BEGIN PLAYER LOOP
  3556.             ' ****************************************************************************************************************************************************************
  3557.                         For iPlayerLoop = 1 To m_iPlayerCount
  3558.                 'DrawScreen m_arrPlayer(iPlayerLoop).View, cScreenOffsetX, cScreenOffsetY, iX%, iY%, iZ%
  3559.                                
  3560.                                
  3561.                                
  3562.                                
  3563.                                
  3564. ' this first person stuff is kind of hard
  3565. '                ' -----------------------------------------------------------------------------
  3566. '                ' BEGIN SHOW SIMPLE FIRST-PERSON MINI-DISPLAY ON SCREEN
  3567. '                ' -----------------------------------------------------------------------------
  3568. '                               ' POINTING WHICHEVER WAY USER MOVED LAST
  3569. '                              
  3570. '                ' ADD TEXT LABEL
  3571. '                Locate m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonTextY, m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonTextX: Print "First person";
  3572. '                               Locate m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonTextY+1, m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonTextX: Print "(" + GetDirection$(m_arrPlayer(iPlayerLoop).Direction) + ")";
  3573. '                              
  3574. '                ' ERASE OLD MAP
  3575. '                               iDrawX% = m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonX
  3576. '                               iDrawY% = m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonY
  3577. '                               iSize% = m_arrPlayer(1).MapSize * m_iMapMaxX ' m_iMapMaxY m_iMapMaxZ
  3578. '                               DrawBox iDrawX%, iDrawY%, iSize%, cBlack ' TODO: variable background color
  3579. '                              
  3580. '                               Select Case m_arrPlayer(iPlayerLoop).Direction
  3581. '                                       Case c_iDir_Down:
  3582. '                                              
  3583. '                                       Case c_iDir_Up:
  3584. '                                              
  3585. '                                       Case c_iDir_Left:
  3586. '                                              
  3587. '                                       Case c_iDir_Right:
  3588. '                                              
  3589. '                                       Case c_iDir_Back:
  3590. '                                               ' z = up/down
  3591. '                                               ' x = left/right
  3592. '                                               ' y = closeness (m_iMapMinY = farthest)
  3593. '                                              
  3594. '                                               ' first person tiles / scaling
  3595. '                                               ' ----------------------------
  3596. '                                               ' distance   tile size   # tiles   # total   # incl. partial
  3597. '                                               ' 0          16           8        8          8
  3598. '                                               ' 1          15           8  8/15  8         10
  3599. '                                               ' 2          14           9  2/14  8         10
  3600. '                                               ' 3          13           9 11/13  8         10
  3601. '                                               ' 4          12          10  8/12  9         12
  3602. '                                               ' 5          11          11  7/11  10        12
  3603. '                                               ' 6          10          12  8/10  12        14
  3604. '                                               ' 7           9          14  2/ 9  14        16
  3605. '                                              
  3606. '                                               ' each level closer, 1 pixel taller/wider, 4 pixels up & over
  3607. '                                              
  3608. '                                               ' draw in relation to player's position
  3609. '                                               ' point blank range = 8 tiles x 8 tiles
  3610. '                                              
  3611. '                                               ' XoXoXoXoXoXoXoXo
  3612. '                                               '        P
  3613. '                                               ' 0123456789012345
  3614. '                                               '           111111
  3615. '                                              
  3616. '                                               ' XoXoXoXoXoXoXo
  3617. '                                               '       P
  3618. '                                               ' 01234567890123
  3619. '                                               '           1111
  3620. '                                              
  3621. '                                               ' XoXoXoXoXoXoXo
  3622. '                                               '    P
  3623. '                                               ' 01234567890123
  3624. '                                               '           1111
  3625. '                                              
  3626. '                                               ' FOR DISTANCE:
  3627. '                                              
  3628. '                                               '        y: 76543210
  3629. '                                               '           P
  3630. '                                               ' distance: 01234567
  3631. '                                              
  3632. '                                               '        y: 76543210
  3633. '                                               '              P
  3634. '                                               ' distance: 01234567
  3635. '                                              
  3636. '                                               '        y: 76543210
  3637. '                                               '                P
  3638. '                                               ' distance: 01234567
  3639. '                                              
  3640. '                                               '        y: 76543210
  3641. '                                               '                  P
  3642. '                                               ' distance: 01234567
  3643. '                                              
  3644. '                                               ' start at   iDistance
  3645. '                                               ' y-7        7
  3646. '                                               ' 0          y
  3647. '                                              
  3648. '                                               ' Q: where is player?
  3649. '                                               '     m_arrPlayer(iLoop1).x
  3650. '                                               '     m_arrPlayer(iLoop1).y
  3651. '                                               '     m_arrPlayer(iLoop1).z
  3652. '                                              
  3653. '                                               ' scan from right X2 to left X1, step-1
  3654. '                                               if m_arrPlayer(iLoop1).x < 7 then
  3655. '                                                       iPosX1% = m_iMapMinX
  3656. '                                                       iPosX2% = m_iMapMinX+13
  3657. '                                               else
  3658. '                                                       iPosX1% = m_arrPlayer(iLoop1).x - 6
  3659. '                                                       iPosX2% = m_arrPlayer(iLoop1).x + 7
  3660. '                                               end if
  3661. '                                              
  3662. '                                               ' scan from bottom Z1 to top Z2
  3663. '                                               if m_arrPlayer(iLoop1).z < 7 then
  3664. '                                                       iPosZ1% = m_iMapMinZ
  3665. '                                                       iPosZ2% = m_iMapMinZ+13
  3666. '                                               else
  3667. '                                                       iPosZ1% = m_arrPlayer(iLoop1).z - 6
  3668. '                                                       iPosZ2% = m_arrPlayer(iLoop1).z + 7
  3669. '                                               end if
  3670. '                                              
  3671. '                                               ' scan from far Y2 to close Y1
  3672. '                                               if m_arrPlayer(iLoop1).y < 7 then
  3673. '                                                       iPosY1% = 0
  3674. '                                                       iPosY2% = m_arrPlayer(iLoop1).y
  3675. '                                                       iDistance = m_arrPlayer(iLoop1).y
  3676. '                                               else
  3677. '                                                       iPosY1% = m_arrPlayer(iLoop1).y - 7
  3678. '                                                       iPosY2% = m_arrPlayer(iLoop1).y
  3679. '                                                       iDistance = 7
  3680. '                                               end if
  3681. '                                              
  3682. '                                               For iLoopZ% = iPosZ1% To iPosZ2%
  3683. '                                                       For iLoopX% = iPosX2% To iPosX1% Step -1
  3684. '                                                               For iLoopY% = iPosY1% To iPosY2%
  3685. '                                                                      
  3686. '                                                                       ' Q: how big does block grow with each step closer?  1*MapSize
  3687. '                                                                       ' Q: what is the offset from the left/top?           4*MapSize
  3688. '                                                                       ' Q: what is the size of the smallest blocks?        1*MapSize
  3689. '                                                                       ' Q: what is the size of the largest blocks?         8*MapSize
  3690. '                                                                       ' Q: how far away do we see? what is the minimum y?  8 tiles
  3691. '                                                                      
  3692. '                                                                       ' at y, offset = 0
  3693. '                                                                       ' at y, what is x/y size of 1 block?
  3694. '                                                                       '     m_arrPlayer(1).MapSize
  3695. '                                                                       '     m_iMapMaxX
  3696. '                                                                       ' at y, how many blocks? 8x8
  3697. '                                                                      
  3698. '                                                                       iWidth = arrFPBrickSize(iDistance)
  3699. '                                                                      
  3700. '                                                                       arrFP_From(iDistance)
  3701. '                                                                       arrFP_To(iDistance)
  3702. '                                                                      
  3703. '                                                                       iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonX
  3704. '                                                                       iDrawY% = (iLoopY% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonY
  3705. '                                                                      
  3706. '
  3707. '                                                                       If m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall Then
  3708. '                                                                               'DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3709. '                                                                               IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  3710. '                                                                              
  3711. '                                                                       ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player1 Then
  3712. '                                                                              
  3713. '                                                                       ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player2 Then
  3714. '                                                                              
  3715. '                                                                       ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player3 Then
  3716. '                                                                              
  3717. '                                                                       ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player4 Then
  3718. '                                                                              
  3719. '                                                                       Else
  3720. '                                                                               'DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki
  3721. '                                                                       End If
  3722. '                                                                      
  3723. '                                                               Next iLoopY%
  3724. '                                                       Next iLoopX%
  3725. '                                               Next iLoopZ%
  3726. '                                              
  3727. '                                       Case c_iDir_Forward:
  3728. '                                              
  3729. '                                       Case Else:
  3730. '                                               ' (DO NOTHING)
  3731. '                               End Select
  3732. '                              
  3733. '                               'm_arrPlayer(1).MapSize
  3734. '                              
  3735. '                For iLoopX% = m_iMapMinX To m_iMapMaxX
  3736. '                    For iLoopY% = m_iMapMinY To m_iMapMaxY
  3737. '                        iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonX
  3738. '                        iDrawY% = (iLoopY% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFirstPersonY
  3739. '                        If m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall Then
  3740. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3741. '                        ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player1 Then
  3742. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3743. '                        ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player2 Then
  3744. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3745. '                        ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player3 Then
  3746. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3747. '                        ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player4 Then
  3748. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3749. '                            'TODO: ADD OTHER TYPES
  3750. '                        Else
  3751. '                            DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki
  3752. '                        End If
  3753. '                    Next iLoopY%
  3754. '                Next iLoopX%
  3755. '                ' -----------------------------------------------------------------------------
  3756. '                ' END SHOW SIMPLE FIRST-PERSON MINI-DISPLAY ON SCREEN
  3757. '                ' -----------------------------------------------------------------------------
  3758.                                
  3759.                                
  3760.                                
  3761.                 ' -----------------------------------------------------------------------------
  3762.                 ' BEGIN SHOW TOP-DOWN X/Y 2D MINI MAP ON SCREEN
  3763.                 ' -----------------------------------------------------------------------------
  3764.                 ' TODO: FOR MULTIPLAYER, DRAW A SEPARATE MAP PER PLAYER TO SPLIT SCREEN
  3765.                 ' ADD TEXT LABEL
  3766.                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapTopDownTextY, m_arrSplitScreen(iPlayerLoop).MiniMapTopDownTextX: Print "Top-down";
  3767.                                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapTopDownTextY+1, m_arrSplitScreen(iPlayerLoop).MiniMapTopDownTextX: Print "(Z-slice)";
  3768.                                
  3769.                 ' DRAW MAP
  3770.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  3771.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  3772.                         iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapTopDownX
  3773.                         iDrawY% = (iLoopY% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapTopDownY
  3774.                         If m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall Then
  3775.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3776.                         ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player1 Then
  3777.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3778.                         ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player2 Then
  3779.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3780.                         ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player3 Then
  3781.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3782.                         ElseIf m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player4 Then
  3783.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  3784.                             'TODO: ADD OTHER TYPES
  3785.                         Else
  3786.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki
  3787.                         End If
  3788.                     Next iLoopY%
  3789.                 Next iLoopX%
  3790.                 ' DRAW THE PLAYERS ON THE MINI MAP
  3791.                 For iLoop1 = m_iPlayerMin To m_iPlayerCount
  3792.                     iDrawX% = (m_arrPlayer(iLoop1).x * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapTopDownX
  3793.                     iDrawY% = (m_arrPlayer(iLoop1).y * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapTopDownY
  3794.                     ' TODO: ADD Alpha PARAMETER TO DrawBox
  3795.                     DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrPlayer(iLoop1).Color1
  3796.                 Next iLoop1
  3797.                 ' DRAW THE OBJECTS ON THE MINI MAP
  3798.                 ' (TO DO WHEN WE ADD OBJECTS)
  3799.                 ' -----------------------------------------------------------------------------
  3800.                 ' END SHOW TOP-DOWN X/Y 2D MINI MAP ON SCREEN
  3801.                 ' -----------------------------------------------------------------------------
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807.                 ' -----------------------------------------------------------------------------
  3808.                 ' BEGIN SHOW FRONT-BACK X/Z 2D MINI MAP ON SCREEN
  3809.                 ' -----------------------------------------------------------------------------
  3810.                 ' TODO: FOR MULTIPLAYER, DRAW A SEPARATE MAP PER PLAYER TO SPLIT SCREEN
  3811.                 ' ADD TEXT LABEL
  3812.                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackTextY, m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackTextX: Print "Front/back";
  3813.                                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackTextY+1, m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackTextX: Print "(Y-slice)";
  3814.                                
  3815.                 ' DRAW MAP
  3816.                 For iLoopZ% = m_iMapMaxZ To m_iMapMinZ Step -1
  3817.                     For iLoopX% = m_iMapMinX To m_iMapMaxX
  3818.                         iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackX
  3819.                         iDrawY% = ((m_iMapMaxZ - iLoopZ%) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackY
  3820.                         If m_arrMap(iLoopX%, iY%, iLoopZ%).Typ = c_iTile_Wall Then
  3821.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iY%, iLoopZ%).Color1
  3822.                         ElseIf m_arrMap(iLoopX%, iY%, iLoopZ%).Typ = c_iTile_Player1 Then
  3823.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iY%, iLoopZ%).Color1
  3824.                         ElseIf m_arrMap(iLoopX%, iY%, iLoopZ%).Typ = c_iTile_Player2 Then
  3825.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iY%, iLoopZ%).Color1
  3826.                         ElseIf m_arrMap(iLoopX%, iY%, iLoopZ%).Typ = c_iTile_Player3 Then
  3827.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iY%, iLoopZ%).Color1
  3828.                         ElseIf m_arrMap(iLoopX%, iY%, iLoopZ%).Typ = c_iTile_Player4 Then
  3829.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iY%, iLoopZ%).Color1
  3830.                             'TODO: ADD OTHER TYPES
  3831.                         Else
  3832.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki
  3833.                         End If
  3834.                     Next iLoopX%
  3835.                 Next iLoopZ%
  3836.                                
  3837.                 ' DRAW THE PLAYERS ON THE MINI MAP
  3838.                 For iLoop1 = m_iPlayerMin To m_iPlayerCount
  3839.                     iDrawX% = (m_arrPlayer(iLoop1).x * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackX
  3840.                     iDrawY% = ((m_iMapMaxZ - m_arrPlayer(iLoop1).z) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapFrontBackY
  3841.                     ' TODO: ADD Alpha PARAMETER TO DrawBox
  3842.                     DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrPlayer(iLoop1).Color1
  3843.                 Next iLoop1
  3844.                 ' DRAW THE OBJECTS ON THE MINI MAP
  3845.                 ' (TO DO WHEN WE ADD OBJECTS)
  3846.                 ' -----------------------------------------------------------------------------
  3847.                 ' END SHOW FRONT-BACK X/Z 2D MINI MAP ON SCREEN
  3848.                 ' -----------------------------------------------------------------------------
  3849.  
  3850.  
  3851.  
  3852.  
  3853.  
  3854.                 ' -----------------------------------------------------------------------------
  3855.                 ' BEGIN SHOW RIGHT/LEFT Y/Z 2D MINI MAP ON SCREEN
  3856.                 ' -----------------------------------------------------------------------------
  3857.                 ' TODO: FOR MULTIPLAYER, DRAW A SEPARATE MAP PER PLAYER TO SPLIT SCREEN
  3858.                 ' ADD TEXT LABEL
  3859.                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftTextY, m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftTextX: Print "Right/left";
  3860.                                 Locate m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftTextY+1, m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftTextX: Print "(X-slice)";
  3861.                                
  3862.                 ' DRAW MAP
  3863.                 For iLoopZ% = m_iMapMaxZ To m_iMapMinZ Step -1
  3864.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  3865.                         iDrawX% = ((m_iMapMaxY - iLoopY%) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftX
  3866.                         iDrawY% = ((m_iMapMaxZ - iLoopZ%) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftY
  3867.                         If m_arrMap(iX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  3868.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iX%, iLoopY%, iLoopZ%).Color1
  3869.                         ElseIf m_arrMap(iX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  3870.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iX%, iLoopY%, iLoopZ%).Color1
  3871.                         ElseIf m_arrMap(iX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  3872.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iX%, iLoopY%, iLoopZ%).Color1
  3873.                         ElseIf m_arrMap(iX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  3874.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iX%, iLoopY%, iLoopZ%).Color1
  3875.                         ElseIf m_arrMap(iX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  3876.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iX%, iLoopY%, iLoopZ%).Color1
  3877.                             'TODO: ADD OTHER TYPES
  3878.                         Else
  3879.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki
  3880.                         End If
  3881.                     Next iLoopY%
  3882.                 Next iLoopZ%
  3883.                 ' DRAW THE PLAYERS ON THE MINI MAP
  3884.                 For iLoop1 = m_iPlayerMin To m_iPlayerCount
  3885.                     iDrawX% = ((m_iMapMaxY - m_arrPlayer(iLoop1).y) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftX
  3886.                     iDrawY% = ((m_iMapMaxZ - m_arrPlayer(iLoop1).z) * m_arrPlayer(1).MapSize) + m_arrSplitScreen(iPlayerLoop).MiniMapRightLeftY
  3887.                     ' TODO: ADD Alpha PARAMETER TO DrawBox
  3888.                     DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrPlayer(iLoop1).Color1
  3889.                 Next iLoop1
  3890.                 ' DRAW THE OBJECTS ON THE MINI MAP
  3891.                 ' (TO DO WHEN WE ADD OBJECTS)
  3892.                 ' -----------------------------------------------------------------------------
  3893.                 ' END SHOW RIGHT/LEFT Y/Z 2D MINI MAP ON SCREEN
  3894.                 ' -----------------------------------------------------------------------------
  3895.  
  3896.  
  3897.  
  3898.  
  3899.  
  3900.  
  3901.                 ' =============================================================================
  3902.                 ' BEGIN GET KEYBOARD INPUT WITH _BUTTON
  3903.                 ' =============================================================================
  3904.                 ' *** HEY WHY HAS _BUTTON STOPPED WORKING? DID I NOT GET A MEMO? ***
  3905.                 ' -----------------------------------------------------------------------------
  3906.                 ' BEGIN UNDO v1
  3907.                 ' TODO: unlimited levels of undo, for now just 1
  3908.                 ' -----------------------------------------------------------------------------
  3909.                 'IF _BUTTON(KeyCode_CtrlLeft%) OR _BUTTON(KeyCode_CtrlRight%) THEN
  3910.                 '   IF _BUTTON(KeyCode_Z%) THEN
  3911.                 '       IF Not m_bButton_Z THEN
  3912.                 '           m_bButton_Z = TRUE
  3913.                 '           ' UNDO!
  3914.                 '       END IF
  3915.                 '   ELSEIF _BUTTON(KeyCode_Y%) THEN
  3916.                 '       IF Not m_bButton_Y THEN
  3917.                 '           m_bButton_Y = TRUE
  3918.                 '           ' REDO!
  3919.                 '       END IF
  3920.                 '   END IF
  3921.                 'END IF
  3922.                 '
  3923.                 ' TRACK WHEN KEYS ARE RELEASED (DISABLES REPEATING KEYS)
  3924.                 'IF Not _BUTTON(KeyCode_Z%) THEN
  3925.                 '   m_bButton_Z = FALSE
  3926.                 'END IF
  3927.                 'IF Not _BUTTON(KeyCode_Y%) THEN
  3928.                 '   m_bButton_Y = FALSE
  3929.                 'END IF
  3930.                 ' -----------------------------------------------------------------------------
  3931.                 ' END UNDO v1
  3932.                 ' -----------------------------------------------------------------------------
  3933.  
  3934.                 ' =============================================================================
  3935.                 ' END GET KEYBOARD INPUT WITH _BUTTON
  3936.                 ' =============================================================================
  3937.  
  3938.  
  3939.                 ' =============================================================================
  3940.                 ' BEGIN GET DIRECTIONAL KEYBOARD INPUT
  3941.                 ' =============================================================================
  3942.                 If _KeyDown(c_iKeyDown_Up) Then
  3943.                     If iLastKey <> c_iKeyDown_Up Or bEnableRepeatingKeys = TRUE Then
  3944.                         iLastKey = c_iKeyDown_Up
  3945.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  3946.                         bMoved = TRUE
  3947.                     End If
  3948.                 ElseIf _KeyDown(c_iKeyDown_Down) Then
  3949.                     If iLastKey <> c_iKeyDown_Down Or bEnableRepeatingKeys = TRUE Then
  3950.                         iLastKey = c_iKeyDown_Down
  3951.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  3952.                         bMoved = TRUE
  3953.                     End If
  3954.                 ElseIf _KeyDown(c_iKeyDown_Left) Then
  3955.                     If iLastKey <> c_iKeyDown_Left Or bEnableRepeatingKeys = TRUE Then
  3956.                         iLastKey = c_iKeyDown_Left
  3957.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  3958.                         bMoved = TRUE
  3959.                     End If
  3960.                 ElseIf _KeyDown(c_iKeyDown_Right) Then
  3961.                     If iLastKey <> c_iKeyDown_Right Or bEnableRepeatingKeys = TRUE Then
  3962.                         iLastKey = c_iKeyDown_Right
  3963.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  3964.                         bMoved = TRUE
  3965.                     End If
  3966.                 ElseIf _KeyDown(c_iKeyDown_PgUp) Then
  3967.                     If iLastKey <> c_iKeyDown_PgUp Or bEnableRepeatingKeys = TRUE Then
  3968.                         iLastKey = c_iKeyDown_PgUp
  3969.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  3970.                         bMoved = TRUE
  3971.                     End If
  3972.                 ElseIf _KeyDown(c_iKeyDown_PgDn) Then
  3973.                     If iLastKey <> c_iKeyDown_PgDn Or bEnableRepeatingKeys = TRUE Then
  3974.                         iLastKey = c_iKeyDown_PgDn
  3975.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  3976.                         bMoved = TRUE
  3977.                     End If
  3978.                     ' =============================================================================
  3979.                     ' END GET DIRECTIONAL KEYBOARD INPUT
  3980.                     ' =============================================================================
  3981.  
  3982.  
  3983.  
  3984.                     ' =============================================================================
  3985.                     ' BEGIN GET UNDO/REDO INPUT
  3986.                     ' =============================================================================
  3987.                 ElseIf _KeyDown(c_iKeyDown_A) Then
  3988.                     If iLastKey <> c_iKeyDown_A Then
  3989.                         iLastKey = c_iKeyDown_A
  3990.  
  3991.                         ' UNDO!
  3992.                         MapTileTempUndo.Typ = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Typ
  3993.                         MapTileTempUndo.Color1 = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Color1
  3994.                         MapTileTempUndo.Alpha1 = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Alpha1
  3995.  
  3996.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Typ = m_MapTileUndo.Typ
  3997.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Color1 = m_MapTileUndo.Color1
  3998.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Alpha1 = m_MapTileUndo.Alpha1
  3999.  
  4000.                         m_MapTileUndo.Typ = MapTileTempUndo.Typ
  4001.                         m_MapTileUndo.Color1 = MapTileTempUndo.Color1
  4002.                         m_MapTileUndo.Alpha1 = MapTileTempUndo.Alpha1
  4003.                     End If
  4004.                 ElseIf _KeyDown(c_iKeyDown_B) Then
  4005.                     If iLastKey <> c_iKeyDown_B Or bEnableRepeatingKeys = TRUE Then
  4006.                         iLastKey = c_iKeyDown_B
  4007.  
  4008.                         ' REDO! *** FOR NOW IT'S THE SAME AS UNDO, JUST SWAPS CURRENT WITH UNDO INFO ***
  4009.                         MapTileTempUndo.Typ = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Typ
  4010.                         MapTileTempUndo.Color1 = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Color1
  4011.                         MapTileTempUndo.Alpha1 = m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Alpha1
  4012.  
  4013.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Typ = m_MapTileUndo.Typ
  4014.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Color1 = m_MapTileUndo.Color1
  4015.                         m_arrMap(m_MapTileUndo.x, m_MapTileUndo.y, m_MapTileUndo.z).Alpha1 = m_MapTileUndo.Alpha1
  4016.  
  4017.                         m_MapTileUndo.Typ = MapTileTempUndo.Typ
  4018.                         m_MapTileUndo.Color1 = MapTileTempUndo.Color1
  4019.                         m_MapTileUndo.Alpha1 = MapTileTempUndo.Alpha1
  4020.                     End If
  4021.                     ' =============================================================================
  4022.                     ' END GET UNDO/REDO INPUT
  4023.                     ' =============================================================================
  4024.  
  4025.  
  4026.  
  4027.  
  4028.  
  4029.  
  4030.  
  4031.                     ' =============================================================================
  4032.                     ' BEGIN GET DRAWING INPUT
  4033.                     ' =============================================================================
  4034.  
  4035.                     ' -----------------------------------------------------------------------------
  4036.                     ' 1 color-
  4037.                 ElseIf _KeyDown(c_iKeyDown_1) Then
  4038.                     If iLastKey <> c_iKeyDown_1 Or bEnableRepeatingKeys = TRUE Then
  4039.                         iLastKey = c_iKeyDown_1
  4040.  
  4041.                         iDrawColor% = iDrawColor% - 1
  4042.                         If iDrawColor% < 0 Then
  4043.                             iDrawColor% = 25
  4044.                         End If
  4045.                     End If
  4046.  
  4047.                     ' -----------------------------------------------------------------------------
  4048.                     ' 2 color+
  4049.                 ElseIf _KeyDown(c_iKeyDown_2) Then
  4050.                     If iLastKey <> c_iKeyDown_2 Or bEnableRepeatingKeys = TRUE Then
  4051.                         iLastKey = c_iKeyDown_2
  4052.  
  4053.                         iDrawColor% = iDrawColor% + 1
  4054.                         If iDrawColor% > 25 Then
  4055.                             iDrawColor% = 0
  4056.                         End If
  4057.                     End If
  4058.  
  4059.                     ' -----------------------------------------------------------------------------
  4060.                     ' 3 draw
  4061.                 ElseIf _KeyDown(c_iKeyDown_3) Then
  4062.                     If iLastKey <> c_iKeyDown_3 Or bEnableRepeatingKeys = TRUE Then
  4063.                         iLastKey = c_iKeyDown_3
  4064.  
  4065.                         ' SAVE UNDO INFO:
  4066.                         m_MapTileUndo.x = iX%
  4067.                         m_MapTileUndo.y = iY%
  4068.                         m_MapTileUndo.z = iZ%
  4069.                         m_MapTileUndo.Typ = m_arrMap(iX%, iY%, iZ%).Typ
  4070.                         m_MapTileUndo.Color1 = m_arrMap(iX%, iY%, iZ%).Color1
  4071.                         m_MapTileUndo.Alpha1 = m_arrMap(iX%, iY%, iZ%).Alpha1
  4072.  
  4073.                         ' DRAW CURRENT COLOR (OR ERASE IF COLOR=TRANSPARENT)
  4074.                         If iDrawColor% > 0 Then
  4075.                             PlotTile iX%, iY%, iZ%, c_iTile_Wall, m_arrColors(iDrawColor%)
  4076.                         Else
  4077.                             PlotTile iX%, iY%, iZ%, c_iTile_Empty, m_arrColors(iDrawColor%)
  4078.                         End If
  4079.  
  4080.                         '' ADD TO RECORDING
  4081.                         'ReDim _Preserve m_arrRecord(0 To UBound(m_arrRecord) + 1) As RecordType
  4082.                         'iIndex = UBound(m_arrRecord)
  4083.                         'm_arrRecord(iIndex).Command = "plot"
  4084.                         'm_arrRecord(iIndex).intParam1 = iX%
  4085.                         'm_arrRecord(iIndex).intParam2 = iY%
  4086.                         'm_arrRecord(iIndex).intParam3 = iZ%
  4087.                         'm_arrRecord(iIndex).intParam4 = m_arrMap(iX%, iY%, iZ%).Typ
  4088.                         'm_arrRecord(iIndex).ulngParam1 = m_arrMap(iX%, iY%, iZ%).Color1
  4089.                     End If
  4090.  
  4091.                     ' -----------------------------------------------------------------------------
  4092.                     ' 4 erase
  4093.                 ElseIf _KeyDown(c_iKeyDown_4) Then
  4094.                     If iLastKey <> c_iKeyDown_4 Or bEnableRepeatingKeys = TRUE Then
  4095.                         iLastKey = c_iKeyDown_4
  4096.  
  4097.                         ' SAVE UNDO INFO:
  4098.                         m_MapTileUndo.x = iX%
  4099.                         m_MapTileUndo.y = iY%
  4100.                         m_MapTileUndo.z = iZ%
  4101.                         m_MapTileUndo.Typ = m_arrMap(iX%, iY%, iZ%).Typ
  4102.                         m_MapTileUndo.Color1 = m_arrMap(iX%, iY%, iZ%).Color1
  4103.                         m_MapTileUndo.Alpha1 = m_arrMap(iX%, iY%, iZ%).Alpha1
  4104.  
  4105.                         ' ERASE CURRENT TILE
  4106.                         PlotTile iX%, iY%, iZ%, c_iTile_Empty, m_arrColors(iDrawColor%)
  4107.  
  4108.                         '' ADD TO RECORDING
  4109.                         'ReDim _Preserve m_arrRecord(0 To UBound(m_arrRecord) + 1) As RecordType
  4110.                         'iIndex = UBound(m_arrRecord)
  4111.                         'm_arrRecord(iIndex).Command = "plot"
  4112.                         'm_arrRecord(iIndex).intParam1 = iX%
  4113.                         'm_arrRecord(iIndex).intParam2 = iY%
  4114.                         'm_arrRecord(iIndex).intParam3 = iZ%
  4115.                         'm_arrRecord(iIndex).intParam4 = m_arrMap(iX%, iY%, iZ%).Typ
  4116.                         'm_arrRecord(iIndex).ulngParam1 = m_arrMap(iX%, iY%, iZ%).Color1
  4117.                     End If
  4118.  
  4119.                     ' -----------------------------------------------------------------------------
  4120.                     ' 5 toggle
  4121.                 ElseIf _KeyDown(c_iKeyDown_5) Then
  4122.                     If iLastKey <> c_iKeyDown_5 Or bEnableRepeatingKeys = TRUE Then
  4123.                         iLastKey = c_iKeyDown_5
  4124.  
  4125.                         ' SAVE UNDO INFO:
  4126.                         m_MapTileUndo.x = iX%
  4127.                         m_MapTileUndo.y = iY%
  4128.                         m_MapTileUndo.z = iZ%
  4129.                         m_MapTileUndo.Typ = m_arrMap(iX%, iY%, iZ%).Typ
  4130.                         m_MapTileUndo.Color1 = m_arrMap(iX%, iY%, iZ%).Color1
  4131.                         m_MapTileUndo.Alpha1 = m_arrMap(iX%, iY%, iZ%).Alpha1
  4132.  
  4133.                         ' TOGGLE CURRENT TILE:
  4134.                         If m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty Then
  4135.                             If iDrawColor% > 0 Then
  4136.                                 'm_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Wall
  4137.                                 PlotTile iX%, iY%, iZ%, c_iTile_Wall, m_arrColors(iDrawColor%)
  4138.                             Else
  4139.                                 'm_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  4140.                                 PlotTile iX%, iY%, iZ%, c_iTile_Empty, m_arrColors(iDrawColor%)
  4141.                             End If
  4142.                         Else
  4143.                             'm_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  4144.                             PlotTile iX%, iY%, iZ%, c_iTile_Empty, m_arrColors(iDrawColor%)
  4145.                         End If
  4146.  
  4147.                         '' ADD TO RECORDING
  4148.                         'ReDim _Preserve m_arrRecord(0 To UBound(m_arrRecord) + 1) As RecordType
  4149.                         'iIndex = UBound(m_arrRecord)
  4150.                         'm_arrRecord(iIndex).Command = "plot"
  4151.                         'm_arrRecord(iIndex).intParam1 = iX%
  4152.                         'm_arrRecord(iIndex).intParam2 = iY%
  4153.                         'm_arrRecord(iIndex).intParam3 = iZ%
  4154.                         'm_arrRecord(iIndex).intParam4 = m_arrMap(iX%, iY%, iZ%).Typ
  4155.                         'm_arrRecord(iIndex).ulngParam1 = m_arrMap(iX%, iY%, iZ%).Color1
  4156.                     End If
  4157.  
  4158.                     ' -----------------------------------------------------------------------------
  4159.                     ' 6 eyedropper
  4160.                 ElseIf _KeyDown(c_iKeyDown_6) Then
  4161.                     If iLastKey <> c_iKeyDown_6 Or bEnableRepeatingKeys = TRUE Then
  4162.                         iLastKey = c_iKeyDown_6
  4163.  
  4164.                         iDrawColor% = GetPaletteFromColor%(m_arrMap(iX%, iY%, iZ%).Color1)
  4165.                     End If
  4166.  
  4167.                     ' -----------------------------------------------------------------------------
  4168.                     ' 7 clear all
  4169.                 ElseIf _KeyDown(c_iKeyDown_7) Then
  4170.                     If iLastKey <> c_iKeyDown_7 Or bEnableRepeatingKeys = TRUE Then
  4171.                         iLastKey = c_iKeyDown_7
  4172.  
  4173.                         ReDim m_arrRecord(-1) As RecordType
  4174.                         ClearIsometricMap
  4175.                         'For iLoopX% = m_iMapMinX To m_iMapMaxX
  4176.                         '    For iLoopY% = m_iMapMinY To m_iMapMaxY
  4177.                         '        For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  4178.                         '            m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  4179.                         '            m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cEmpty
  4180.                         '            m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1 = 255
  4181.                         '            m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  4182.                         '        Next iLoopZ%
  4183.                         '    Next iLoopY%
  4184.                         'Next iLoopX%
  4185.  
  4186.                     End If
  4187.  
  4188.                     ' -----------------------------------------------------------------------------
  4189.                     ' 8 open
  4190.                 ElseIf _KeyDown(c_iKeyDown_8) Then
  4191.                     If iLastKey <> c_iKeyDown_8 Or bEnableRepeatingKeys = TRUE Then
  4192.                         iLastKey = c_iKeyDown_8
  4193.                         _KeyClear
  4194.                         sNextErr = LoadIsometricDrawing$
  4195.                     End If
  4196.  
  4197.                     ' -----------------------------------------------------------------------------
  4198.                     ' 9 save
  4199.                 ElseIf _KeyDown(c_iKeyDown_9) Then
  4200.                     If iLastKey <> c_iKeyDown_9 Or bEnableRepeatingKeys = TRUE Then
  4201.                         iLastKey = c_iKeyDown_9
  4202.                         _KeyClear
  4203.                         sNextErr = SaveIsometricDrawing$
  4204.                     End If
  4205.                     ' =============================================================================
  4206.                     ' END GET DRAWING INPUT
  4207.                     ' =============================================================================
  4208.  
  4209.  
  4210.  
  4211.  
  4212.                     ' =============================================================================
  4213.                     ' BEGIN GET OTHER KEYBOARD INPUT
  4214.                     ' =============================================================================
  4215.                 ElseIf _KeyDown(c_iKeyDown_BracketLeft) Then
  4216.                     If iLastKey <> c_iKeyDown_BracketLeft Or bEnableRepeatingKeys = TRUE Then
  4217.                         iLastKey = c_iKeyDown_BracketLeft
  4218.                         m_arrPlayer(iPlayerLoop).IsMoving = TRUE
  4219.                     End If
  4220.                 ElseIf _KeyDown(c_iKeyDown_BracketRight) Then
  4221.                     If iLastKey <> c_iKeyDown_BracketRight Or bEnableRepeatingKeys = TRUE Then
  4222.                         iLastKey = c_iKeyDown_BracketRight
  4223.                         m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  4224.                     End If
  4225.  
  4226.                 ElseIf _KeyDown(c_iKeyDown_Comma) Then
  4227.                     If iLastKey <> c_iKeyDown_Comma Or bEnableRepeatingKeys = TRUE Then
  4228.                         iLastKey = c_iKeyDown_Comma
  4229.                         ' TODO: HAVE MAP SIZE PER PLAYER
  4230.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize - 1
  4231.                         If m_arrPlayer(iPlayerLoop).MapSize < 1 Then
  4232.                             m_arrPlayer(iPlayerLoop).MapSize = 1
  4233.                         Else
  4234.                             bMoved = TRUE
  4235.                         End If
  4236.                     End If
  4237.                 ElseIf _KeyDown(c_iKeyDown_Period) Then
  4238.                     If iLastKey <> c_iKeyDown_Period Or bEnableRepeatingKeys = TRUE Then
  4239.                         iLastKey = c_iKeyDown_Period
  4240.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize + 1
  4241.                         If m_arrPlayer(iPlayerLoop).MapSize > m_iGridSizeMax Then
  4242.                             m_arrPlayer(iPlayerLoop).MapSize = m_iGridSizeMax
  4243.                         Else
  4244.                             bMoved = TRUE
  4245.                         End If
  4246.                     End If
  4247.  
  4248.                 ElseIf _KeyDown(c_iKeyDown_Minus) Then
  4249.                     If iLastKey <> c_iKeyDown_Minus Or bEnableRepeatingKeys = TRUE Then
  4250.                         iLastKey = c_iKeyDown_Minus
  4251.                         ' TODO: HAVE SEPARATE GRID SIZE PER PLAYER / SPLIT SCREEN?
  4252.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize - 1
  4253.                         If m_arrPlayer(iPlayerLoop).GridSize < m_iGridSizeMin Then
  4254.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMin
  4255.                         Else
  4256.                             bMoved = TRUE
  4257.                         End If
  4258.                     End If
  4259.                 ElseIf _KeyDown(c_iKeyDown_EqualPlus) Then
  4260.                     If iLastKey <> c_iKeyDown_EqualPlus Or bEnableRepeatingKeys = TRUE Then
  4261.                         iLastKey = c_iKeyDown_EqualPlus
  4262.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize + 1
  4263.                         If m_arrPlayer(iPlayerLoop).GridSize > m_iGridSizeMax Then
  4264.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMax
  4265.                         Else
  4266.                             bMoved = TRUE
  4267.                         End If
  4268.                     End If
  4269.  
  4270.                 ElseIf _KeyDown(c_iKeyDown_Home) Then
  4271.                     If iLastKey <> c_iKeyDown_Home Or bEnableRepeatingKeys = TRUE Then
  4272.                         iLastKey = c_iKeyDown_Home
  4273.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  4274.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View - 1
  4275.                         If m_arrPlayer(iPlayerLoop).View < c_iDir_Min Then
  4276.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Max
  4277.                         End If
  4278.                     End If
  4279.                 ElseIf _KeyDown(c_iKeyDown_End) Then
  4280.                     If iLastKey <> c_iKeyDown_End Or bEnableRepeatingKeys = TRUE Then
  4281.                         iLastKey = c_iKeyDown_End
  4282.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  4283.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View + 1
  4284.                         If m_arrPlayer(iPlayerLoop).View > c_iDir_Max Then
  4285.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Min
  4286.                         End If
  4287.                     End If
  4288.  
  4289.                 ElseIf _KeyDown(c_iKeyDown_Ins) Then
  4290.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  4291.                     If iLastKey <> c_iKeyDown_Ins Or bEnableRepeatingKeys = TRUE Then
  4292.                         iLastKey = c_iKeyDown_Ins
  4293.                         bEnableRepeatingKeys = TRUE
  4294.                     End If
  4295.  
  4296.                 ElseIf _KeyDown(c_iKeyDown_Del) Then
  4297.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  4298.                     If iLastKey <> c_iKeyDown_Del Or bEnableRepeatingKeys = TRUE Then
  4299.                         iLastKey = c_iKeyDown_Del
  4300.                         bEnableRepeatingKeys = FALSE
  4301.                     End If
  4302.  
  4303.                 ElseIf _KeyDown(c_iKeyDown_Esc) Then
  4304.                     Exit Do
  4305.                 Else
  4306.                     iLastKey = -1
  4307.                 End If
  4308.                 ' =============================================================================
  4309.                 ' END GET OTHER KEYBOARD INPUT
  4310.                 ' =============================================================================
  4311.  
  4312.  
  4313.  
  4314.                 ' =============================================================================
  4315.                 ' BEGIN MOVE PLAYER BASED ON DIRECTION
  4316.                 ' =============================================================================
  4317.                 If m_arrPlayer(iPlayerLoop).IsMoving = TRUE Or bMoved = TRUE Then
  4318.                     bMoved = FALSE
  4319.  
  4320.                     Select Case m_arrPlayer(iPlayerLoop).Direction
  4321.                         Case c_iDir_Down:
  4322.                             iNewX% = iX%
  4323.                             iNewY% = iY%
  4324.                             iNewZ% = iZ% - 1
  4325.                             If iNewZ% < m_iMapMinZ Then
  4326.                                 iNewZ% = m_iMapMaxZ
  4327.                             End If
  4328.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4329.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  4330.                                 iNewZ% = iZ%
  4331.                             End If
  4332.  
  4333.                         Case c_iDir_Up:
  4334.                             iNewX% = iX%
  4335.                             iNewY% = iY%
  4336.                             iNewZ% = iZ% + 1
  4337.                             If iNewZ% > m_iMapMaxZ Then
  4338.                                 iNewZ% = m_iMapMinZ
  4339.                             End If
  4340.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4341.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  4342.                                 iNewZ% = iZ%
  4343.                             End If
  4344.  
  4345.                         Case c_iDir_Left:
  4346.                             iNewX% = iX% - 1
  4347.                             iNewY% = iY%
  4348.                             iNewZ% = iZ%
  4349.                             If iNewX% < m_iMapMinX Then
  4350.                                 iNewX% = m_iMapMaxX
  4351.                             End If
  4352.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4353.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  4354.                                 iNewX% = iX%
  4355.                             End If
  4356.  
  4357.                         Case c_iDir_Right:
  4358.                             iNewX% = iX% + 1
  4359.                             iNewY% = iY%
  4360.                             iNewZ% = iZ%
  4361.                             If iNewX% > m_iMapMaxX Then
  4362.                                 iNewX% = m_iMapMinX
  4363.                             End If
  4364.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4365.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  4366.                                 iNewX% = iX%
  4367.                             End If
  4368.  
  4369.                         Case c_iDir_Back:
  4370.                             iNewX% = iX%
  4371.                             iNewY% = iY% - 1
  4372.                             iNewZ% = iZ%
  4373.                             If iNewY% < m_iMapMinY Then
  4374.                                 iNewY% = m_iMapMaxY
  4375.                             End If
  4376.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4377.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  4378.                                 iNewY% = iY%
  4379.                             End If
  4380.  
  4381.                         Case c_iDir_Forward:
  4382.                             iNewX% = iX%
  4383.                             iNewY% = iY% + 1
  4384.                             iNewZ% = iZ%
  4385.                             If iNewY% > m_iMapMaxY Then
  4386.                                 iNewY% = m_iMapMinY
  4387.                             End If
  4388.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) And (bIgnoreTerrain = FALSE) Then
  4389.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  4390.                                 iNewY% = iY%
  4391.                             End If
  4392.  
  4393.                         Case Else:
  4394.                             ' (DO NOTHING)
  4395.                             'iNewX% = iX%
  4396.                             'iNewY% = iY%
  4397.                             'iNewZ% = iZ%
  4398.                     End Select
  4399.  
  4400.                     ' SAVE NEW POSITION
  4401.                     iX% = iNewX%
  4402.                     iY% = iNewY%
  4403.                     iZ% = iNewZ%
  4404.  
  4405.                     ' FOR MULTIPLAYER WE WOULD USE:
  4406.                     m_arrPlayer(iPlayerLoop).x = iNewX%
  4407.                     m_arrPlayer(iPlayerLoop).y = iNewY%
  4408.                     m_arrPlayer(iPlayerLoop).z = iNewZ%
  4409.  
  4410.                 End If
  4411.                 ' =============================================================================
  4412.                 ' END MOVE PLAYER BASED ON DIRECTION
  4413.                 ' =============================================================================
  4414.  
  4415.  
  4416.                 ' =============================================================================
  4417.                 ' BEGIN CYCLE COLOR
  4418.                 ' =============================================================================
  4419.                 If m_arrPlayer(iPlayerLoop).ColorScheme1 > 0 Then
  4420.                     m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = m_arrPlayer(iPlayerLoop).ColorSchemeCount1 + 1
  4421.                     If m_arrPlayer(iPlayerLoop).ColorSchemeCount1 > m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 Then
  4422.                         m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  4423.                         DoCycleColor m_arrPlayer(iPlayerLoop).ColorScheme1, m_arrPlayer(iPlayerLoop).Color1
  4424.                     End If
  4425.                 End If
  4426.                 ' =============================================================================
  4427.                 ' END CYCLE COLOR
  4428.                 ' =============================================================================
  4429.  
  4430.  
  4431.             Next iPlayerLoop
  4432.  
  4433.             ' ****************************************************************************************************************************************************************
  4434.             ' END PLAYER LOOP
  4435.             ' ****************************************************************************************************************************************************************
  4436.                        
  4437.                        
  4438.                        
  4439.             ' ****************************************************************************************************************************************************************
  4440.             ' BEGIN DRAW SCREEN MARKERS
  4441.                         ' ****************************************************************************************************************************************************************
  4442.                         IF m_bDebugGrid = TRUE THEN
  4443.                                
  4444.                                 ' -----------------------------------------------------------------------------
  4445.                                 ' BEGIN DRAW BITMAP GRID
  4446.                                 ' -----------------------------------------------------------------------------
  4447.                                 ' screen = 1280h x 1024w
  4448.                                 iLoopX% = 1
  4449.                                 for iLoopY% = 50 to 950 step 100
  4450.                                         DrawRect iLoopX%, iLoopY%, 1280, 1, cWhite
  4451.                                         DrawRect iLoopX%, iLoopY%+50, 1280, 1, cCyan
  4452.                                 next iLoopY%
  4453.                                 iLoopY% = 1
  4454.                                 for iLoopX% = 50 to 1250 step 100
  4455.                                         DrawRect iLoopX%, iLoopY%, 1, 1024, cWhite
  4456.                                         DrawRect iLoopX%+50, iLoopY%, 1, 1024, cCyan
  4457.                                 next iLoopX%
  4458.                                 ' -----------------------------------------------------------------------------
  4459.                                 ' END DRAW BITMAP GRID
  4460.                                 ' -----------------------------------------------------------------------------
  4461.                                
  4462.                                 ' -----------------------------------------------------------------------------
  4463.                                 ' BEGIN DRAW TEXT GRID
  4464.                                 ' -----------------------------------------------------------------------------
  4465.                                 iLoopY% = 64
  4466.                                 for iLoopX% = 1 TO 160
  4467.                                         ' show 100s place
  4468.                                         in$ = cstr$(iLoopX%)
  4469.                                         if len(in$) > 2 then
  4470.                                                 in$ = mid$(in$, len(in$)-2, 1)
  4471.                                         else
  4472.                                                 in$ = " "
  4473.                                         end if
  4474.                                         Locate iLoopY%-2, iLoopX%
  4475.                                         Print in$;
  4476.                                        
  4477.                                         ' show 10s place
  4478.                                         in$ = cstr$(iLoopX%)
  4479.                                         if len(in$) > 1 then
  4480.                                                 in$ = mid$(in$, len(in$)-1, 1)
  4481.                                         else
  4482.                                                 in$ = " "
  4483.                                         end if
  4484.                                         Locate iLoopY%-1, iLoopX%
  4485.                                         Print in$;
  4486.                                        
  4487.                                         ' show 1s place
  4488.                                         in$ = right$(cstr$(iLoopX%), 1)
  4489.                                         Locate iLoopY%, iLoopX%
  4490.                                         Print in$;
  4491.                                 next iLoopX%
  4492.                                
  4493.                                 iLoopX% = 1
  4494.                                 for iLoopY% = 1 TO 64
  4495.                                         Locate iLoopY%, iLoopX%
  4496.                                         in$ = right$("  " + cstr$(iLoopY%), 2)
  4497.                                         Print in$;
  4498.                                 next iLoopY%
  4499.                                 ' -----------------------------------------------------------------------------
  4500.                                 ' END DRAW TEXT GRID
  4501.                                 ' -----------------------------------------------------------------------------
  4502.                                
  4503.                         END IF
  4504.             ' ****************************************************************************************************************************************************************
  4505.             ' END DRAW SCREEN MARKERS
  4506.                         ' ****************************************************************************************************************************************************************
  4507.                        
  4508.                        
  4509.                        
  4510.                        
  4511.             _Limit 30
  4512.             _Display
  4513.  
  4514.         Loop
  4515.     End If
  4516.  
  4517.     CleanupAndExit:
  4518.     ' FINISH UP AND EXIT
  4519.     _KeyClear
  4520.     Screen 0
  4521.     IsometricDraw1$ = sResult
  4522. End Function ' IsometricDraw1$
  4523.  
  4524. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4525. ' BEGIN FILE FUNCTIONS
  4526. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4527.  
  4528. ' /////////////////////////////////////////////////////////////////////////////
  4529. ' PLOT TILE TO MAP AND SAVE TO RECORDING
  4530.  
  4531. 'PlotTile iX, iY, iZ, iTile, ulngColor1
  4532. Sub PlotTile (iX As Integer, iY As Integer, iZ As Integer, iTile As Integer, ulngColor1 As _Unsigned Long)
  4533.     if iX >= lbound(m_arrMap, 1) and iX <= ubound(m_arrMap, 1) then
  4534.                 if iY >= lbound(m_arrMap, 2) and iY <= ubound(m_arrMap, 2) then
  4535.                         if iZ >= lbound(m_arrMap, 3) and iZ <= ubound(m_arrMap, 3) then
  4536.                                 m_arrMap(iX, iY, iZ).Typ = iTile
  4537.                                 m_arrMap(iX, iY, iZ).Color1 = ulngColor1
  4538.                                 m_arrMap(iX, iY, iZ).Alpha1 = 255
  4539.                                 m_arrMap(iX, iY, iZ).AlphaOverride = 255
  4540.                                 LogPlotTile iX, iY, iZ, iTile, ulngColor1
  4541.                         end if
  4542.                 end if
  4543.         end if
  4544. End Sub ' PlotTile
  4545.  
  4546. ' /////////////////////////////////////////////////////////////////////////////
  4547. ' PLOT TILE TO SPECIFIED MAP, AND SAVE TO RECORDING IF SPECIFIED
  4548.  
  4549. ' temporary function for now
  4550. ' later we will update PlotTile and all will use that
  4551. ' and global bSaveToRecording will control whether LogPlotTile is called
  4552.  
  4553. 'PlotTile2 arrMap, iX, iY, iZ, iTile, ulngColor1
  4554. Sub PlotTile2 (arrMap() As MapTileType, iX As Integer, iY As Integer, iZ As Integer, iTile As Integer, ulngColor1 As _Unsigned Long)
  4555.     if iX >= lbound(arrMap, 1) and iX <= ubound(m_arrMap, 1) then
  4556.                 if iY >= lbound(arrMap, 2) and iY <= ubound(m_arrMap, 2) then
  4557.                         if iZ >= lbound(arrMap, 3) and iZ <= ubound(m_arrMap, 3) then
  4558.                                 arrMap(iX, iY, iZ).Typ = iTile
  4559.                                 arrMap(iX, iY, iZ).Color1 = ulngColor1
  4560.                                 arrMap(iX, iY, iZ).Alpha1 = 255
  4561.                                 arrMap(iX, iY, iZ).AlphaOverride = 255
  4562.                                 'if bSaveToRecording = TRUE then
  4563.                                 '       LogPlotTile iX, iY, iZ, iTile, ulngColor1
  4564.                                 'end if
  4565.                         end if
  4566.                 end if
  4567.         end if
  4568. End Sub ' PlotTile2
  4569.  
  4570. ' /////////////////////////////////////////////////////////////////////////////
  4571. ' SAVE PLOT COMMAND TO RECORDING
  4572.  
  4573. 'LogPlotTile iX, iY, iZ, iTile, ulngColor1
  4574. Sub LogPlotTile (iX As Integer, iY As Integer, iZ As Integer, iTile As Integer, ulngColor1 As _Unsigned Long)
  4575.     Dim iIndex As Long
  4576.     ReDim _Preserve m_arrRecord(0 To UBound(m_arrRecord) + 1) As RecordType
  4577.     iIndex = UBound(m_arrRecord)
  4578.     m_arrRecord(iIndex).Command = "plot"
  4579.     m_arrRecord(iIndex).intParam1 = iX
  4580.     m_arrRecord(iIndex).intParam2 = iY
  4581.     m_arrRecord(iIndex).intParam3 = iZ
  4582.     m_arrRecord(iIndex).intParam4 = iTile
  4583.     m_arrRecord(iIndex).ulngParam1 = ulngColor1
  4584. End Sub ' LogPlotTile
  4585.  
  4586. ' /////////////////////////////////////////////////////////////////////////////
  4587. '   - save screens to file (stored as editable text)
  4588. '     + FORMAT: [tile=t][color@x,y,z][color@x,y,z][color@x,y,z]...
  4589.  
  4590. Function SaveIsometricDrawing$
  4591.     Dim RoutineName As String:: RoutineName = "SaveIsometricDrawing$"
  4592.     Dim sError As String: sError = ""
  4593.     Dim sFile As String
  4594.     Dim in$
  4595.     Dim iX As Integer
  4596.     Dim iY As Integer
  4597.     Dim iZ As Integer
  4598.     Dim iTile As Integer
  4599.     Dim ulngColor1 As _Unsigned Long
  4600.     Dim iIndex As Long
  4601.     Dim sLine As String
  4602.     Dim iCount As Long: iCount = 0
  4603.     Dim iError As Long: iError = 0
  4604.    
  4605.         'IF m_bTesting = TRUE THEN
  4606.         '       _echo "--------------------------------------------------------------------------------"
  4607.     '   _echo "Started " + RoutineName
  4608.     '   _echo "--------------------------------------------------------------------------------"
  4609.         'END IF
  4610.        
  4611.     _KeyClear
  4612.  
  4613.     ' Get file name
  4614.     Cls
  4615.     If Len(m_SaveFileName$) = 0 Then
  4616.         m_SaveFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "txt"
  4617.     End If
  4618.     Print "SAVE DRAWING:"
  4619.     Print "Default file name is " + Chr$(34) + m_SaveFileName$ + Chr$(34) + "."
  4620.     Input "Type save file name, or blank for default: ", in$
  4621.     in$ = _Trim$(in$)
  4622.     If Len(in$) > 0 Then
  4623.         m_SaveFileName$ = in$
  4624.     End If
  4625.     sFile = m_ProgramPath$ + m_SaveFileName$
  4626.  
  4627.         'IF m_bTesting = TRUE THEN
  4628.     '   _echo "sFile=" + CHR$(34) + sFile + CHR$(34)
  4629.         'END IF
  4630.  
  4631.     ' Save recording to file
  4632.     Open sFile For Output As #1
  4633.  
  4634.     '[tile=t][color@x,y,z][color@x,y,z][color@x,y,z]
  4635.     For iIndex = 0 To UBound(m_arrRecord)
  4636.         If m_arrRecord(iIndex).Command = "plot" Then
  4637.             sLine = ""
  4638.             sLine = sLine + "plot,"
  4639.             sLine = sLine + "tile=" + _Trim$(Str$(m_arrRecord(iIndex).intParam4)) + ","
  4640.             sLine = sLine + "color=" + _Trim$(Str$(m_arrRecord(iIndex).ulngParam1)) + ","
  4641.             sLine = sLine + "x=" + _Trim$(Str$(m_arrRecord(iIndex).intParam1)) + ","
  4642.             sLine = sLine + "y=" + _Trim$(Str$(m_arrRecord(iIndex).intParam2)) + ","
  4643.             sLine = sLine + "z=" + _Trim$(Str$(m_arrRecord(iIndex).intParam3))
  4644.             Print #1, sLine
  4645.             iCount = iCount + 1
  4646.         Else
  4647.                         'IF m_bTesting = TRUE THEN
  4648.             '   _echo "SKIPPED m_arrRecord(" + _Trim$(Str$(iIndex)) + ") INVALID .Command=" + CHR$(34) + m_arrRecord(iIndex).Command + CHR$(34)
  4649.                         'END IF
  4650.             iError = iError + 1
  4651.         End If
  4652.     Next iIndex
  4653.  
  4654.     Close #1
  4655.  
  4656.     Print "Wrote   " + _Trim$(Str$(iCount)) + " lines."
  4657.     Print "Skipped " + _Trim$(Str$(iError)) + " lines."
  4658.     Print
  4659.     Input "PRESS <ENTER> TO CONTINUE", in$
  4660.  
  4661.     SaveIsometricDrawing$ = sError
  4662. End Function ' SaveIsometricDrawing$
  4663.  
  4664. ' /////////////////////////////////////////////////////////////////////////////
  4665. '   - load screens into array m_arrRecord
  4666. '     + PARSER:
  4667. '       1. replace all ][ with [
  4668. '       2. split by "[" into simple 1D array
  4669. '       3. each element is either "tile=t" or "plot=color@x,y,z"
  4670. '       4. parse data into array to playback recording
  4671. '          [n][0] = command$ = "draw"
  4672. '          [n][1] = intParam1 = x
  4673. '          [n][2] = intValue2 = y
  4674. '          [n][3] = intValue3 = z
  4675. '          [n][4] = intParam4 = tile #
  4676. '          [n][5] = intValue5 = alpha1
  4677. '          [n][6] = ulngValue1 = color1
  4678.  
  4679. Function LoadIsometricDrawing$
  4680.     Dim RoutineName As String:: RoutineName = "LoadIsometricDrawing$"
  4681.     Dim sError As String: sError = ""
  4682.     Dim sFile As String
  4683.     Dim iIndex As Long
  4684.     Dim iLine As Long
  4685.     Dim iPair As Long
  4686.     Dim sText As String
  4687.     Dim sLine As String
  4688.     Dim sPair As String
  4689.     Dim iTotal As Long: iTotal = 0
  4690.     Dim iRead As Long: iRead = 0
  4691.     Dim iKnown As Long: iKnown = 0
  4692.     Dim iSkipped As Long: iSkipped = 0
  4693.     Dim iErrors As Long: iErrors = 0
  4694.     Dim iValid As Long: iValid = 0
  4695.     Dim iUnknown As Long: iUnknown = 0
  4696.     ReDim arrLines(-1) As String
  4697.     ReDim m_arrRecord(-1) As RecordType
  4698.     ReDim arrNextLine(-1) As String
  4699.     ReDim arrNameValue(-1) As String
  4700.     Dim sName As String
  4701.     Dim sValue As String
  4702.     Dim iX As Integer
  4703.     Dim iY As Integer
  4704.     Dim iZ As Integer
  4705.     Dim iTile As Integer
  4706.     Dim ulngColor1 As _Unsigned Long
  4707.     Dim sNextErr As String
  4708.     Dim sCommand As String
  4709.     'Dim sDebugLine As String
  4710.     Dim iPercent As Long
  4711.     Dim iStatusEvery As Long
  4712.     Dim iStatusCount As Long
  4713.  
  4714.         'IF m_bTesting = TRUE THEN
  4715.     '   _echo "--------------------------------------------------------------------------------"
  4716.     '   _echo "Started " + RoutineName
  4717.     '   _echo "--------------------------------------------------------------------------------"
  4718.         'END IF
  4719.  
  4720.     _KeyClear
  4721.  
  4722.     ' Get file name
  4723.     If Len(sError) = 0 Then
  4724.         Cls
  4725.         If Len(m_SaveFileName$) = 0 Then
  4726.             m_SaveFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "txt"
  4727.         End If
  4728.         Print "LOAD DRAWING:"
  4729.         Print "Default file name is " + Chr$(34) + m_SaveFileName$ + Chr$(34) + "."
  4730.         Input "Type name of file to open, or blank for default: ", in$
  4731.         in$ = _Trim$(in$)
  4732.         If Len(in$) > 0 Then
  4733.             m_SaveFileName$ = in$
  4734.         End If
  4735.         sFile = m_ProgramPath$ + m_SaveFileName$
  4736.     End If
  4737.  
  4738.     ' Make sure file exists
  4739.     If Len(sError) = 0 Then
  4740.         If _FileExists(sFile) = FALSE Then
  4741.             sError = "File not found: " + Chr$(34) + sFile + Chr$(34)
  4742.         Else
  4743.                         'IF m_bTesting = TRUE THEN
  4744.             '   _echo "Found file: " + chr$(34) + sFile + chr$(34)
  4745.                         'END IF
  4746.         End If
  4747.     End If
  4748.  
  4749.     ' Load recording from file
  4750.     If Len(sError) = 0 Then
  4751.         ClearIsometricMap
  4752.         ReDim m_arrRecord(-1) As RecordType
  4753.  
  4754.                 'IF m_bTesting = TRUE THEN
  4755.         '       _echo "OPEN sFile FOR BINARY AS #1"
  4756.                 'END IF
  4757.         Open sFile For Binary As #1
  4758.         sText = Space$(LOF(1))
  4759.         Get #1, , sText
  4760.         Close #1
  4761.         iTotal = Len(sText) - Len(Replace$(sText, Chr$(13), ""))
  4762.         sText = ""
  4763.  
  4764.         ' SPLIT IS TOO SLOW!
  4765.                 'IF m_bTesting = TRUE THEN
  4766.         '       _echo "split sText, CHR$(13), arrLines()"
  4767.                 'END IF
  4768.         'split sText, CHR$(13), arrLines()
  4769.         'iTotal = ubound(arrLines)-1
  4770.  
  4771.         ' PARSE LINES: plot,tile=2,color=4294901760,x=10,y=10,z=10
  4772.         iStatusCount = 0
  4773.         iStatusEvery = iTotal / 100
  4774.  
  4775.         'Print "iTotal      =" + _Trim$(Str$(iTotal))
  4776.         'Print "iStatusEvery=" + _Trim$(Str$(iStatusEvery))
  4777.         'Input "PRESS <ENTER> TO CONTINUE",in$
  4778.  
  4779.         'FOR iLine = lbound(arrLines) TO ubound(arrLines)-1
  4780.         'sLine = arrLines(iLine)
  4781.         Open sFile For Input As #1
  4782.         While Not EOF(1)
  4783.             'INPUT #1, sLine
  4784.             Line Input #1, sLine ' read entire text file line
  4785.  
  4786.             iRead = iRead + 1
  4787.                         'IF m_bTesting = TRUE THEN
  4788.             '   _echo "Parsing line " + _Trim$(Str$(iRead))
  4789.                         'END IF
  4790.  
  4791.             ' SHOW STATUS
  4792.             ' TODO: FIX <- DOESN'T SEEM TO DISPLAY UNTIL THE END, ALL AT ONCE
  4793.             iStatusCount = iStatusCount + 1
  4794.             If iStatusCount > iStatusEvery Then
  4795.                 iStatusCount = 0
  4796.                 iPercent = 100 * (iRead / iTotal)
  4797.                 Print _Trim$(Str$(iPercent)) + "%"
  4798.                                 'IF m_bTesting = TRUE THEN
  4799.                 '       _echo _Trim$(Str$(iPercent)) + "%"
  4800.                                 'END IF
  4801.             End If
  4802.  
  4803.             'sDebugLine = sLine
  4804.             'sDebugLine = Replace$(sDebugLine, CHR$(9), "\t")
  4805.             'sDebugLine = Replace$(sDebugLine, CHR$(13), "\n")
  4806.             'sDebugLine = Replace$(sDebugLine, CHR$(10), "\r")
  4807.                         'IF m_bTesting = TRUE THEN
  4808.             '   _echo "    Raw    =" + chr$(34) + sDebugLine + chr$(34)
  4809.             ''  _echo "    Raw    =" + chr$(34) + arrLines(iLine) + chr$(34)
  4810.                         'END IF
  4811.  
  4812.             sLine = Replace$(sLine, " ", "") ' Remove spaces
  4813.             sLine = Replace$(sLine, Chr$(9), "") ' Remove tabs
  4814.             sLine = Replace$(sLine, Chr$(10), "") ' Remove line breaks
  4815.             sLine = Replace$(sLine, Chr$(13), "") ' Remove carriage returns
  4816.                         'IF m_bTesting = TRUE THEN
  4817.             '   _echo "    Trimmed=" + chr$(34) + sLine + chr$(34)
  4818.                         'END IF
  4819.  
  4820.             If Len(sLine) > 0 Then
  4821.                 split sLine, ",", arrNextLine()
  4822.                                 'IF m_bTesting = TRUE THEN
  4823.                 '       _echo "    lbound =" + _Trim$(Str$(lbound(arrNextLine))) '+ CHR$(10)
  4824.                 '       _echo "    ubound =" + _Trim$(Str$(ubound(arrNextLine))) '+ CHR$(10)
  4825.                                 'END IF
  4826.  
  4827.                 sCommand = arrNextLine(LBound(arrNextLine))
  4828.                 sCommand = LCase$(sCommand)
  4829.                                 'IF m_bTesting = TRUE THEN
  4830.                 '       _echo "    Command=" + chr$(34) + sCommand + chr$(34)
  4831.                                 'END IF
  4832.  
  4833.                 If sCommand = "plot" Then
  4834.                     iKnown = iKnown + 1
  4835.  
  4836.                     For iPair = LBound(arrNextLine) + 1 To UBound(arrNextLine)
  4837.                         sPair = arrNextLine(iPair)
  4838.                         If InStr(1, sPair, "=") > 0 Then
  4839.                             split sPair, "=", arrNameValue()
  4840.                             sName = LCase$(arrNameValue(LBound(arrNameValue)))
  4841.                             If UBound(arrNameValue) > LBound(arrNameValue) Then
  4842.                                 sValue = arrNameValue(LBound(arrNameValue) + 1)
  4843.                             Else
  4844.                                 sValue = ""
  4845.                             End If
  4846.                         Else
  4847.                             sName = ""
  4848.                         End If
  4849.                         sNextErr = ""
  4850.                         Select Case sName
  4851.                             Case "tile":
  4852.                                 If IsNum%(sValue) Then
  4853.                                     iTile = Val(sValue)
  4854.                                 Else
  4855.                                     sNextErr = "Invalid value: " + sName + " = " + Chr$(34) + sValue + Chr$(34)
  4856.                                 End If
  4857.                             Case "color":
  4858.                                 If IsNum%(sValue) Then
  4859.                                     ulngColor1 = Val(sValue)
  4860.                                 Else
  4861.                                     sNextErr = "Invalid value: " + sName + " = " + Chr$(34) + sValue + Chr$(34)
  4862.                                 End If
  4863.                             Case "x":
  4864.                                 If IsNum%(sValue) Then
  4865.                                     iX = Val(sValue)
  4866.                                 Else
  4867.                                     sNextErr = "Invalid value: " + sName + " = " + Chr$(34) + sValue + Chr$(34)
  4868.                                 End If
  4869.                             Case "y":
  4870.                                 If IsNum%(sValue) Then
  4871.                                     iY = Val(sValue)
  4872.                                 Else
  4873.                                     sNextErr = "Invalid value: " + sName + " = " + Chr$(34) + sValue + Chr$(34)
  4874.                                 End If
  4875.                             Case "z":
  4876.                                 If IsNum%(sValue) Then
  4877.                                     iZ = Val(sValue)
  4878.                                 Else
  4879.                                     sNextErr = "Invalid value: " + sName + " = " + Chr$(34) + sValue + Chr$(34)
  4880.                                 End If
  4881.                             Case Else:
  4882.                                 sNextErr = "Unknown parameter: " + Chr$(34) + sName + Chr$(34) + "," + Chr$(34) + sValue + Chr$(34)
  4883.                         End Select
  4884.                     Next iPair
  4885.                     If Len(sNextErr) = 0 Then
  4886.                         iValid = iValid + 1
  4887.  
  4888.                                                 'IF m_bTesting = TRUE THEN
  4889.                         '       _echo "READ VALUES SUCCESSFULLY:" + CHR$(13)
  4890.                         '       _echo "iTile     =" + _Trim$(Str$(iTile)) + CHR$(13)
  4891.                         '       _echo "ulngColor1=" + _Trim$(Str$(ulngColor1)) + CHR$(13)
  4892.                         '       _echo "iX        =" + _Trim$(Str$(iX)) + CHR$(13)
  4893.                         '       _echo "iY        =" + _Trim$(Str$(iY)) + CHR$(13)
  4894.                         '       _echo "iZ        =" + _Trim$(Str$(iZ)) + CHR$(13)
  4895.                         ''      EXIT FOR
  4896.                                                 'END IF
  4897.  
  4898.                         PlotTile iX, iY, iZ, iTile, ulngColor1
  4899.                     Else
  4900.                         iErrors = iErrors + 1
  4901.  
  4902.                         Print "Line " + _Trim$(Str$(iRead)) + "=" + Chr$(34) + sLine + Chr$(34) + Chr$(10)
  4903.                         Print "    ERROR: " + sNextErr
  4904.  
  4905.                                                 'IF m_bTesting = TRUE THEN
  4906.                         ''      _echo "Line " + _Trim$(Str$(iRead)) + "=" + CHR$(34) + sLine + CHR$(34) + CHR$(10)
  4907.                         '       _echo "    ERROR: " + sNextErr
  4908.                         ''      EXIT FOR
  4909.                                                 'END IF
  4910.                     End If
  4911.                 Else
  4912.                                         'IF m_bTesting = TRUE THEN
  4913.                     ''  _echo "Line " + _Trim$(Str$(iRead)) + "=" + CHR$(34) + sLine + CHR$(34) + CHR$(10)
  4914.                     '   _echo "    command not recognized: skipped"
  4915.                                         'END IF
  4916.                     iUnknown = iUnknown + 1
  4917.                 End If
  4918.  
  4919.             Else
  4920.                                 'IF m_bTesting = TRUE THEN
  4921.                 ''      _echo "Line " + _Trim$(Str$(iRead)) + "=" + CHR$(34) + sLine + CHR$(34) + CHR$(10)
  4922.                 '       _echo "    Line is blank: skipped"
  4923.                                 'END IF
  4924.                 iSkipped = iSkipped + 1
  4925.             End If ' LEN(sLine) > 0
  4926.  
  4927.         Wend
  4928.         Close #1
  4929.         'NEXT iLine
  4930.     End If
  4931.  
  4932.     Print
  4933.     Print "Total lines read: " + _Trim$(Str$(iRead))
  4934.     Print "Known commands  : " + _Trim$(Str$(iKnown))
  4935.     Print "       -> Good  : " + _Trim$(Str$(iValid))
  4936.     Print "       ->  Bad  : " + _Trim$(Str$(iErrors))
  4937.     Print "Not recognized  : " + _Trim$(Str$(iUnknown))
  4938.     Print "Skipped blank   : " + _Trim$(Str$(iSkipped))
  4939.     Print
  4940.     Input "PRESS <ENTER> TO CONTINUE", in$
  4941.  
  4942.     LoadIsometricDrawing$ = sError
  4943. End Function ' LoadIsometricDrawing$
  4944.  
  4945. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4946. ' END FILE FUNCTIONS
  4947. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4948.  
  4949. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4950. ' BEGIN GRAPHICS FUNCTIONS
  4951. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4952.  
  4953. ' =============================================================================
  4954. ' LET'S GET THE COORDINATES STRAIGHT!
  4955. ' Coordinates are m_arrMap(x,y,z)
  4956. '           ________________
  4957. '          /|e            /|e
  4958. '         / |            / |
  4959. '        /  |           /  |z-axis
  4960. '       /   |          /   |
  4961. '      /    /---------/----/
  4962. '     /    / a       /   b/
  4963. '    /    /         /    /
  4964. '   |--------------|    /
  4965. '   |f  /         g|   / y-axis
  4966. '   |  /           |  /
  4967. '   | /            | /
  4968. '   |/c           d|/
  4969. '   ----------------
  4970. '      x-axis
  4971. '
  4972. ' POINT    ( X, Y, Z)
  4973. ' a        ( 0, 0, 0)
  4974. ' b        (32, 0, 0)
  4975. ' c        ( 0,32, 0)
  4976. ' d        (32,32, 0)
  4977. ' e        ( 0, 0,32)
  4978. ' f        ( 0,32,32)
  4979. ' g        (32,32,32)
  4980. ' =============================================================================
  4981.  
  4982. ' /////////////////////////////////////////////////////////////////////////////
  4983. ' INITIALIZE MAP TO EMPTY
  4984.  
  4985. ' Requires shared global variable:
  4986. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  4987. Sub ClearIsometricMap
  4988.     Dim RoutineName As String: RoutineName = "ClearIsometricMap"
  4989.     Dim iLoopX%
  4990.     Dim iLoopY%
  4991.     Dim iLoopZ%
  4992.  
  4993.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  4994.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  4995.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  4996.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  4997.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  4998.             Next iLoopY%
  4999.         Next iLoopX%
  5000.     Next iLoopZ%
  5001. End Sub ' ClearIsometricMap
  5002.  
  5003. ' /////////////////////////////////////////////////////////////////////////////
  5004. ' INITIALIZE RENDERING MAP #1 TO EMPTY
  5005.  
  5006. ' Requires shared global variable:
  5007. ' m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5008.  
  5009. Sub ClearRenderMap1
  5010.     Dim RoutineName As String: RoutineName = "ClearRenderMap1"
  5011.     Dim iLoopX%
  5012.     Dim iLoopY%
  5013.     Dim iLoopZ%
  5014.        
  5015.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5016.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5017.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5018.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  5019.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 0
  5020.             Next iLoopY%
  5021.         Next iLoopX%
  5022.     Next iLoopZ%
  5023. End Sub ' ClearRenderMap1
  5024.  
  5025. ' /////////////////////////////////////////////////////////////////////////////
  5026. ' INITIALIZE RENDERING MAP #2 TO EMPTY
  5027.  
  5028. ' Requires shared global variable:
  5029. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5030.  
  5031. Sub ClearRenderMap2
  5032.     Dim RoutineName As String: RoutineName = "ClearRenderMap2"
  5033.     Dim iLoopX%
  5034.     Dim iLoopY%
  5035.     Dim iLoopZ%
  5036.        
  5037.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5038.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5039.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5040.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  5041.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 0
  5042.             Next iLoopY%
  5043.         Next iLoopX%
  5044.     Next iLoopZ%
  5045. End Sub ' ClearRenderMap2
  5046.  
  5047. ' /////////////////////////////////////////////////////////////////////////////
  5048. ' Determine which squares are visible in isometric map
  5049.  
  5050. ' Original operates directly on the main map array m_arrMap
  5051. ' and not the copy (m_arrRender2) used to rotate the perspective.
  5052.  
  5053. ' Requires shared global variable (3D array of map):
  5054. ' m_arrMap(x,y,z) = 3D array map of world
  5055. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5056.  
  5057. ' RECEIVES:
  5058. ' iX% = player's X positon
  5059. ' iY% = player's Y position
  5060. ' iZ% = player's Z position
  5061.  
  5062. ' Direction is assumed to be c_iDir_Forward.
  5063.  
  5064. ' If iX% < 0 then we just render everything with its normal alpha value.
  5065.  
  5066. Sub ComputeVisible (iX%, iY%, iZ%, iGridSize)
  5067.     Dim RoutineName As String: RoutineName = "ComputeVisible"
  5068.     Dim iLoopX%
  5069.     Dim iLoopY%
  5070.     Dim iLoopZ%
  5071.  
  5072.     Dim iPX1%
  5073.     Dim iPY1%
  5074.     Dim iPZ1%
  5075.     Dim iPlayer2Dx As Integer
  5076.     Dim iPlayer2Dy As Integer
  5077.     Dim iTile2Dx As Integer
  5078.     Dim iTile2Dy As Integer
  5079.  
  5080.     If iX% > -1 Then
  5081.         ' CALCULATE PLAYER'S 2-D POSITION
  5082.         iPX1% = iX% * iGridSize + cGridOffsetX
  5083.         iPY1% = iY% * iGridSize + cGridOffsetY
  5084.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  5085.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  5086.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  5087.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  5088.  
  5089.         ' LOOK AT EACH TILE
  5090.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5091.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5092.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5093.  
  5094.                     ' *****************************************************************************
  5095.                     ' IF SPACE HAS A TILE
  5096.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  5097.                     ' THEN MAKE THE TILE TRANSPARENT
  5098.                     ' *****************************************************************************
  5099.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  5100.                     If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Or m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  5101.                         ' CALCULATE TILE'S 2-D POSITION
  5102.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  5103.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  5104.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  5105.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  5106.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  5107.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  5108.  
  5109.                         'If iLoopZ% >= iZ% Then
  5110.                         'If iLoopX% >= iX% Then
  5111.  
  5112.                         ' FOR TILES FORWARD OF PLAYER
  5113.                         If iLoopY% > iY% Then
  5114.  
  5115.                             ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  5116.                             If (iPlayer2Dy >= (iTile2Dy - iGridSize)) And (iPlayer2Dy <= (iTile2Dy + iGridSize)) Then
  5117.  
  5118.                                 ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  5119.                                 If (iPlayer2Dx >= (iTile2Dx - iGridSize)) And (iPlayer2Dx <= (iTile2Dx + iGridSize)) Then
  5120.                                     ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  5121.                                     ' TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE
  5122.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  5123.                                 Else
  5124.                                     ' LEAVE THE TILE OPAQUE
  5125.                                     ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5126.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5127.                                 End If
  5128.                             Else
  5129.                                 ' LEAVE THE TILE OPAQUE
  5130.                                 ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5131.                                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5132.                             End If
  5133.                         Else
  5134.                             ' LEAVE THE TILE OPAQUE
  5135.                             ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5136.                             m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5137.                         End If
  5138.                         'End If
  5139.                         'End If
  5140.                     Else
  5141.                         ' LEAVE THE TILE OPAQUE
  5142.                         ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5143.                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5144.                     End If
  5145.                 Next iLoopZ%
  5146.             Next iLoopY%
  5147.         Next iLoopX%
  5148.     Else
  5149.         ' JUST MAKE ALL TILES VISIBLE
  5150.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5151.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5152.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5153.                     ' LEAVE THE TILE OPAQUE
  5154.                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5155.  
  5156.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5157.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5158.                     'm_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5159.  
  5160.                 Next iLoopZ%
  5161.             Next iLoopY%
  5162.         Next iLoopX%
  5163.     End If
  5164. End Sub ' ComputeVisible
  5165.  
  5166. ' /////////////////////////////////////////////////////////////////////////////
  5167. ' Determine which squares are visible in isometric map
  5168.  
  5169. ' Same as ComputeVisible except uses the rotated copy
  5170. ' (m_arrRender2 instead of m_arrMap)
  5171.  
  5172. ' Requires shared global variable (3D array of map):
  5173. ' m_arrRender2(x,y,z) = rotated copy of 3D array map of world
  5174. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5175.  
  5176. ' RECEIVES:
  5177. ' iX% = player's X positon
  5178. ' iY% = player's Y position
  5179. ' iZ% = player's Z position
  5180.  
  5181. ' If iX% < 0 then we just render everything with its normal alpha value.
  5182.  
  5183. ' TODO: FIX FOR c_iDir_Down and c_iDir_Up DIRECTIONS
  5184. '       "FOR TILES FORWARD OF PLAYER" SECTION BELOW
  5185. '       NEEDS TO LOOK AT Z AXIS INSTEAD OF Y ?
  5186.  
  5187. Sub ComputeRenderVisible (iX%, iY%, iZ%, iGridSize)
  5188.     Dim RoutineName As String: RoutineName = "ComputeRenderVisible"
  5189.     Dim iLoopX%
  5190.     Dim iLoopY%
  5191.     Dim iLoopZ%
  5192.  
  5193.     Dim iPX1%
  5194.     Dim iPY1%
  5195.     Dim iPZ1%
  5196.     Dim iPlayer2Dx As Integer
  5197.     Dim iPlayer2Dy As Integer
  5198.     Dim iTile2Dx As Integer
  5199.     Dim iTile2Dy As Integer
  5200.  
  5201.     If iX% > -1 Then
  5202.         ' CALCULATE PLAYER'S 2-D POSITION
  5203.         iPX1% = iX% * iGridSize + cGridOffsetX
  5204.         iPY1% = iY% * iGridSize + cGridOffsetY
  5205.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  5206.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  5207.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  5208.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  5209.  
  5210.         ' LOOK AT EACH TILE
  5211.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5212.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5213.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5214.  
  5215.                     ' *****************************************************************************
  5216.                     ' IF SPACE HAS A TILE
  5217.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  5218.                     ' THEN MAKE THE TILE TRANSPARENT
  5219.                     ' *****************************************************************************
  5220.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  5221.                     If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Or m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  5222.                         ' CALCULATE TILE'S 2-D POSITION
  5223.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  5224.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  5225.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  5226.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  5227.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  5228.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  5229.  
  5230.                         'If iLoopZ% >= iZ% Then
  5231.                         'If iLoopX% >= iX% Then
  5232.  
  5233.                         ' FOR TILES FORWARD OF PLAYER
  5234.                         If iLoopY% > iY% Then
  5235.  
  5236.                             ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  5237.                             If (iPlayer2Dy >= (iTile2Dy - iGridSize)) And (iPlayer2Dy <= (iTile2Dy + iGridSize)) Then
  5238.  
  5239.                                 ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  5240.                                 If (iPlayer2Dx >= (iTile2Dx - iGridSize)) And (iPlayer2Dx <= (iTile2Dx + iGridSize)) Then
  5241.                                     ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  5242.                                     'TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE?
  5243.                                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  5244.                                 Else
  5245.                                     ' LEAVE THE TILE OPAQUE
  5246.                                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5247.  
  5248.                                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5249.                                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5250.                                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5251.                                 End If
  5252.                             Else
  5253.                                 ' LEAVE THE TILE OPAQUE
  5254.                                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5255.  
  5256.                                 'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5257.                                 'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5258.                                 'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5259.                             End If
  5260.                         Else
  5261.                             ' LEAVE THE TILE OPAQUE
  5262.                             m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5263.  
  5264.                             'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5265.                             'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5266.                             'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5267.                         End If
  5268.                         'End If
  5269.                         'End If
  5270.                     Else
  5271.                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5272.  
  5273.                         'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5274.                         'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5275.                     End If
  5276.                 Next iLoopZ%
  5277.             Next iLoopY%
  5278.         Next iLoopX%
  5279.     Else
  5280.         ' JUST MAKE ALL TILES VISIBLE
  5281.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5282.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5283.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5284.                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  5285.  
  5286.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  5287.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  5288.                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  5289.                 Next iLoopZ%
  5290.             Next iLoopY%
  5291.         Next iLoopX%
  5292.     End If
  5293. End Sub ' ComputeRenderVisible
  5294.  
  5295. ' /////////////////////////////////////////////////////////////////////////////
  5296. ' Draw the map in 3D Isometic Perspective
  5297. ' from the forward (default) perspective.
  5298.  
  5299. ' Requires shared global variable
  5300. ' m_arrMap(x,y,z) = 3D array map of world
  5301. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5302.  
  5303. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  5304. ' params instead of constants:
  5305. ' Const cScreenOffsetX = 500 ' 450
  5306. ' Const cScreenOffsetY = 300 ' 50
  5307. ' Const cScreenOffsetZ = 0
  5308.  
  5309. ' what about?
  5310. ' Const cGridOffsetX = 50
  5311. ' Const cGridOffsetY = 50
  5312. ' Const cGridOffsetZ = 0
  5313.  
  5314. Sub DrawIsometricScreen (iScreenOffsetX, iScreenOffsetY, iGridSize)
  5315.     Dim RoutineName As String: RoutineName = "DrawIsometricScreen"
  5316.     Dim bTile As Integer
  5317.     Dim iLoopX%
  5318.     Dim iLoopY%
  5319.     Dim iLoopZ%
  5320.     Dim iColor As _Unsigned Long
  5321.     Dim iPosX1%
  5322.     Dim iPosX2%
  5323.     Dim iPosY1%
  5324.     Dim iPosY2%
  5325.     Dim iPosZ1%
  5326.     Dim alpha&
  5327.  
  5328.     alpha& = 255
  5329.     bTile = FALSE
  5330.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5331.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5332.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5333.  
  5334.                 ' CALCULATE POSITION
  5335.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  5336.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  5337.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  5338.                 iPosX2% = iPosX1% + iGridSize
  5339.                 iPosY2% = iPosY1% + iGridSize
  5340.  
  5341.                 ' DETERMINE COLOR
  5342.                 If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  5343.                     If bTile = TRUE Then
  5344.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5345.                         bTile = FALSE
  5346.                     Else
  5347.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  5348.                         bTile = TRUE
  5349.                     End If
  5350.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  5351.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5352.                     alpha& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  5353.  
  5354.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  5355.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5356.                     alpha& = 255
  5357.  
  5358.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  5359.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5360.                     alpha& = 255
  5361.  
  5362.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  5363.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5364.                     alpha& = 255
  5365.  
  5366.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  5367.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5368.                     alpha& = 255
  5369.  
  5370.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  5371.                     'TODO: transparent for water
  5372.                     iColor = cEmpty
  5373.                     alpha& = 64
  5374.  
  5375.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  5376.                     'TODO: transparent for windows
  5377.                     iColor = cEmpty
  5378.                     alpha& = 64
  5379.  
  5380.                 Else
  5381.                     iColor = cEmpty
  5382.                 End If
  5383.  
  5384.                 ' PLOT NEXT TILE
  5385.                 If iColor <> cEmpty Then
  5386.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  5387.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  5388.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  5389.                 End If
  5390.  
  5391.             Next iLoopY%
  5392.         Next iLoopX%
  5393.     Next iLoopZ%
  5394. End Sub ' DrawIsometricScreen
  5395.  
  5396. ' /////////////////////////////////////////////////////////////////////////////
  5397. ' Draw the map in 3D Isometic Perspective.
  5398.  
  5399. ' Requires shared global variable
  5400. ' m_arrRender2(x,y,z) = 3D array map of world
  5401. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5402.  
  5403. Sub DrawRenderScreen (iScreenOffsetX, iScreenOffsetY, iGridSize)
  5404.     Dim RoutineName As String: RoutineName = "DrawRenderScreen"
  5405.     Dim bTile As Integer
  5406.     Dim iLoopX%
  5407.     Dim iLoopY%
  5408.     Dim iLoopZ%
  5409.     Dim iColor As _Unsigned Long
  5410.     Dim iPosX1%
  5411.     Dim iPosX2%
  5412.     Dim iPosY1%
  5413.     Dim iPosY2%
  5414.     Dim iPosZ1%
  5415.     Dim alpha&
  5416.  
  5417.     alpha& = 255
  5418.     bTile = FALSE
  5419.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5420.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5421.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5422.  
  5423.                 ' CALCULATE POSITION
  5424.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  5425.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  5426.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  5427.                 iPosX2% = iPosX1% + iGridSize
  5428.                 iPosY2% = iPosY1% + iGridSize
  5429.  
  5430.                 ' DETERMINE COLOR
  5431.                 If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  5432.                     If bTile = TRUE Then
  5433.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5434.                         bTile = FALSE
  5435.                     Else
  5436.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color2
  5437.                         bTile = TRUE
  5438.                     End If
  5439.  
  5440.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  5441.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5442.                     alpha& = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  5443.  
  5444.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  5445.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5446.                     alpha& = 255
  5447.  
  5448.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  5449.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5450.                     alpha& = 255
  5451.  
  5452.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  5453.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5454.                     alpha& = 255
  5455.  
  5456.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  5457.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  5458.                     alpha& = 255
  5459.  
  5460.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  5461.                     'TODO: transparent for water
  5462.                     iColor = cEmpty
  5463.                     alpha& = 64
  5464.  
  5465.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  5466.                     'TODO: transparent for windows
  5467.                     iColor = cEmpty
  5468.                     alpha& = 64
  5469.  
  5470.                 Else
  5471.                     iColor = cEmpty
  5472.                 End If
  5473.  
  5474.                 ' PLOT NEXT TILE
  5475.                 If iColor <> cEmpty Then
  5476.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  5477.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  5478.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  5479.                 End If
  5480.  
  5481.             Next iLoopY%
  5482.         Next iLoopX%
  5483.     Next iLoopZ%
  5484. End Sub ' DrawRenderScreen
  5485.  
  5486. ' /////////////////////////////////////////////////////////////////////////////
  5487. ' Draw the map in 3D Isometic Perspective
  5488. ' from a different direction.
  5489.  
  5490. ' This is the lazy man's version which simply copies the tiles to
  5491. ' a temporary array, rotated to the specified direction/orientation.
  5492. ' A more efficient + faster method would operate directly on the
  5493. ' main array, but I am too bogged down to figure that out right now!
  5494.  
  5495. ' RECEIVES:
  5496. ' iDirection% = point of view to render from
  5497. '     i.e. the direction we are looking at the scene FROM
  5498. '     iDirection% can be one of the following:
  5499. '     c_iDir_Down
  5500. '     c_iDir_Up
  5501. '     c_iDir_Left
  5502. '     c_iDir_Right
  5503. '     c_iDir_Back
  5504. '     c_iDir_Forward = default
  5505. '
  5506. '     If iDirection% = c_iDir_Forward, just call DrawIsometricScreen instead (faster).
  5507. '
  5508. ' iScreenOffsetX, iScreenOffsetY = where on display to draw
  5509. '
  5510. ' iX%, iY%, iZ% = player's position, used for ComputeRenderVisible
  5511. '     to compute which tiles to hide / make transparent
  5512. '     (tiles that might be hiding the player)
  5513. '     If these are <0, then ComputeRenderVisible uses original alpha values.
  5514.  
  5515. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  5516. ' params instead of constants:
  5517. ' Const cScreenOffsetX = 500 ' 450
  5518. ' Const cScreenOffsetY = 300 ' 50
  5519. ' Const cScreenOffsetZ = 0
  5520.  
  5521. ' what about?
  5522. ' Const cGridOffsetX = 50
  5523. ' Const cGridOffsetY = 50
  5524. ' Const cGridOffsetZ = 0
  5525.  
  5526. ' TODO: player layer
  5527. ' m_iPlayerCount
  5528. ' shared for current player #?
  5529. ' first copy world and superimpose player coords?
  5530.  
  5531. Sub DrawScreen (iDirection%, iScreenOffsetX, iScreenOffsetY, iGridSize, iX%, iY%, iZ%)
  5532.     Dim RoutineName As String: RoutineName = "DrawScreen"
  5533.     Dim bTile As Integer
  5534.     Dim iLoopX%
  5535.     Dim iLoopY%
  5536.     Dim iLoopZ%
  5537.     Dim iColor As _Unsigned Long
  5538.     Dim iPosX1%
  5539.     Dim iPosX2%
  5540.     Dim iPosY1%
  5541.     Dim iPosY2%
  5542.     Dim iPosZ1%
  5543.     Dim alpha&
  5544.  
  5545.     ' =============================================================================
  5546.     ' USE FIRST TEMPORARY ARRAY TO STORE SCENE OVERLAID WITH PLAYERS + OBJECTS
  5547.  
  5548.     ' CLEAR THE MAP (NECESSARY?)
  5549.     ClearRenderMap1
  5550.  
  5551.     ' FIRST COPY THE MAP
  5552.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5553.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5554.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5555.                 'm_arrRender1(iLoopX%,iLoopY%,iLoopZ%) = m_arrMap(iLoopX%, iLoopY%, iLoopZ%)
  5556.                 CopyMapTile m_arrMap(iLoopX%, iLoopY%, iLoopZ%), m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5557.             Next iLoopY%
  5558.         Next iLoopX%
  5559.     Next iLoopZ%
  5560.  
  5561.     ' NEXT COPY THE PLAYERS
  5562.     For iLoopX% = m_iPlayerMin To m_iPlayerCount
  5563.         m_arrRender1(m_arrPlayer(iLoopX%).x, m_arrPlayer(iLoopX%).y, m_arrPlayer(iLoopX%).z).Typ = m_arrPlayer(iLoopX%).Tile1
  5564.         m_arrRender1(m_arrPlayer(iLoopX%).x, m_arrPlayer(iLoopX%).y, m_arrPlayer(iLoopX%).z).Color1 = m_arrPlayer(iLoopX%).Color1
  5565.         m_arrRender1(m_arrPlayer(iLoopX%).x, m_arrPlayer(iLoopX%).y, m_arrPlayer(iLoopX%).z).Alpha1 = m_arrPlayer(iLoopX%).Alpha1
  5566.         m_arrRender1(m_arrPlayer(iLoopX%).x, m_arrPlayer(iLoopX%).y, m_arrPlayer(iLoopX%).z).AlphaOverride = m_arrPlayer(iLoopX%).AlphaOverride
  5567.     Next iLoopX%
  5568.  
  5569.     ' NEXT COPY THE OBJECTS
  5570.     ' (TO DO WHEN WE HAVE OBJECTS)
  5571.        
  5572.     ' =============================================================================
  5573.     ' USE SECOND TEMPORARY ARRAY TO STORE ROTATED SCENE THEN DRAW IT
  5574.        
  5575.     ' CLEAR THE MAP (NECESSARY?)
  5576.     ClearRenderMap2
  5577.        
  5578.     ' COPY TILES, ROTATED TO DESIRED VIEWING PERSPECTIVE / ANGLE
  5579.     Select Case iDirection%
  5580.         Case c_iDir_Down:
  5581.             ' SCENE IS FLIPPED UP (TOP FACE NOW FACING AWAY FROM US)
  5582.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5583.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5584.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5585.                         m_arrRender2(iLoopX%, m_iMapMaxZ - iLoopZ%, iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5586.                     Next iLoopY%
  5587.                 Next iLoopX%
  5588.             Next iLoopZ%
  5589.             ComputeRenderVisible iX%, m_iMapMaxZ - iZ%, iY%, iGridSize
  5590.         Case c_iDir_Up:
  5591.             ' SCENE IS FLIPPED DOWN (TOP FACE NOW FACING TOWARD US)
  5592.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5593.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5594.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5595.                         m_arrRender2(iLoopX%, iLoopZ%, m_iMapMaxY - iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5596.                     Next iLoopY%
  5597.                 Next iLoopX%
  5598.             Next iLoopZ%
  5599.             ComputeRenderVisible iX%, iZ%, m_iMapMaxY - iY%, iGridSize
  5600.         Case c_iDir_Left:
  5601.             ' SCENE IS ROTATED COUNTER CLOCKWISE FROM TOP (LEFT FACE NOW FACING TOWARD US)
  5602.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5603.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5604.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5605.                         m_arrRender2(iLoopY%, m_iMapMaxX - iLoopX%, iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5606.                     Next iLoopY%
  5607.                 Next iLoopX%
  5608.             Next iLoopZ%
  5609.             ComputeRenderVisible iY%, m_iMapMaxX - iX%, iZ%, iGridSize
  5610.         Case c_iDir_Right:
  5611.             ' SCENE IS ROTATED CLOCKWISE FROM TOP (RIGHT FACE NOW FACING TOWARD US)
  5612.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5613.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5614.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5615.                         m_arrRender2(m_iMapMaxY - iLoopY%, iLoopX%, iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5616.                     Next iLoopY%
  5617.                 Next iLoopX%
  5618.             Next iLoopZ%
  5619.             ComputeRenderVisible m_iMapMaxY - iY%, iX%, iZ%, iGridSize
  5620.         Case c_iDir_Back:
  5621.             ' SCENE IS TURNED AROUND (FRONT FACE NOW FACING AWAY FROM US)
  5622.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5623.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5624.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5625.                         m_arrRender2(m_iMapMaxX - iLoopX%, m_iMapMaxY - iLoopY%, iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5626.                     Next iLoopY%
  5627.                 Next iLoopX%
  5628.             Next iLoopZ%
  5629.             ComputeRenderVisible m_iMapMaxX - iX%, m_iMapMaxY - iY%, iZ%, iGridSize
  5630.         Case Else: ' c_iDir_Forward
  5631.             ' FOR ALL OTHER CASES WE JUST DRAW FORWARD (FACING TOWARD US)
  5632.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5633.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  5634.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  5635.                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5636.                     Next iLoopY%
  5637.                 Next iLoopX%
  5638.             Next iLoopZ%
  5639.             ComputeRenderVisible iX%, iY%, iZ%, iGridSize
  5640.     End Select
  5641.     DrawRenderScreen iScreenOffsetX, iScreenOffsetY, iGridSize
  5642. End Sub ' DrawScreen
  5643.  
  5644. ' /////////////////////////////////////////////////////////////////////////////
  5645. ' similar to DrawScreen
  5646. ' but instead of player, draws objects
  5647. ' and free rotates (to angle iAngleXY)
  5648.  
  5649. ' TODO: get free rotation working
  5650. Sub DrawSnowScreen (iAngleXY, iScreenOffsetX, iScreenOffsetY, iGridSize, arrSnow() As SnowflakeType, arrLights() As SnowflakeType, oStar As SnowflakeType)
  5651.     Dim RoutineName As String: RoutineName = "DrawScreen"
  5652.     Dim bTile As Integer
  5653.     Dim iLoopX%
  5654.     Dim iLoopY%
  5655.     Dim iLoopZ%
  5656.     Dim iColor As _Unsigned Long
  5657.     Dim iPosX1%
  5658.     Dim iPosX2%
  5659.     Dim iPosY1%
  5660.     Dim iPosY2%
  5661.     Dim iPosZ1%
  5662.     Dim alpha&
  5663.         Dim iCount%
  5664.         Dim iMissingTileCount As Integer
  5665.        
  5666.     ' =============================================================================
  5667.     ' USE FIRST TEMPORARY ARRAY TO STORE SCENE OVERLAID WITH OBJECTS
  5668.        
  5669.     ' CLEAR THE MAP (NECESSARY?)
  5670.     ClearRenderMap1
  5671.        
  5672.     ' FIRST COPY THE MAP
  5673.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5674.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5675.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  5676.                 'm_arrRender1(iLoopX%,iLoopY%,iLoopZ%) = m_arrMap(iLoopX%, iLoopY%, iLoopZ%)
  5677.                 CopyMapTile m_arrMap(iLoopX%, iLoopY%, iLoopZ%), m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5678.             Next iLoopY%
  5679.         Next iLoopX%
  5680.     Next iLoopZ%
  5681.        
  5682.         ' -----------------------------------------------------------------------------
  5683.     ' NEXT COPY THE OBJECTS
  5684.        
  5685.         ' STAR
  5686.         ' usage: iAxis can be cPlaneXY=1, cPlaneYZ=2, cPlaneZX=3
  5687.         ' PlotCircle2 arrMap(), iAxis, X, Y, Z, R, iTile, iColor
  5688.         PlotCircle2 m_arrRender1(), cPlaneXY, oStar.x, oStar.y, oStar.z, oStar.xCount, c_iTile_Wall, oStar.Color1
  5689.         PlotCircle2 m_arrRender1(), cPlaneYZ, oStar.x, oStar.y, oStar.z, oStar.yCount, c_iTile_Wall, oStar.Color2
  5690.         PlotCircle2 m_arrRender1(), cPlaneZX, oStar.x, oStar.y, oStar.z, oStar.zCount, c_iTile_Wall, oStar.Color3
  5691.         'CircleFill2 m_arrRender1(), cPlaneXY, oStar.x, oStar.y, oStar.z, oStar.xCount, c_iTile_Wall, oStar.Color1
  5692.         'CircleFill2 m_arrRender1(), cPlaneYZ, oStar.x, oStar.y, oStar.z, oStar.yCount, c_iTile_Wall, oStar.Color1
  5693.         'CircleFill2 m_arrRender1(), cPlaneZX, oStar.x, oStar.y, oStar.z, oStar.zCount, c_iTile_Wall, oStar.Color1
  5694.        
  5695.         ' LIGHTS
  5696.         ' (UNDER CONSTRUCTION)
  5697.        
  5698.         ' SNOW
  5699.         For iCount% = lbound(arrSnow) to ubound(arrSnow)
  5700.                 'm_arrRender1(m_arrPlayer(iLoopX%).x, m_arrPlayer(iLoopX%).y, m_arrPlayer(iLoopX%).z).Typ = m_arrPlayer(iLoopX%).Tile1
  5701.                
  5702.                 ' IS THIS SNOWFLAKE ACTIVE?
  5703.                 if arrSnow(iCount%).IsEnabled = TRUE then
  5704.                         m_arrRender1(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Typ = arrSnow(iCount%).Tile1
  5705.                         m_arrRender1(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Color1 = arrSnow(iCount%).Color1
  5706.                         m_arrRender1(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).Alpha1 = arrSnow(iCount%).Alpha1
  5707.                         m_arrRender1(arrSnow(iCount%).x, arrSnow(iCount%).y, arrSnow(iCount%).z).AlphaOverride = arrSnow(iCount%).Alpha1
  5708.                 end if
  5709.         Next iCount%   
  5710.        
  5711.     ' =============================================================================
  5712.     ' USE SECOND TEMPORARY ARRAY TO STORE ROTATED SCENE THEN DRAW IT
  5713.        
  5714.         if (iAngleXY MOD 360 = 0) then
  5715.                 ' CLEAR THE MAP (NECESSARY?)
  5716.                 ClearRenderMap2
  5717.                
  5718.                 ' COPY TILES, ROTATED TO DESIRED VIEWING PERSPECTIVE / ANGLE
  5719.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  5720.                         'TODO: here is where we would do rotation
  5721.                         For iLoopX% = m_iMapMinX To m_iMapMaxX
  5722.                                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  5723.                                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  5724.                                 Next iLoopY%
  5725.                         Next iLoopX%
  5726.                 Next iLoopZ%
  5727.                 'ComputeRenderVisible iX%, iY%, iZ%, iGridSize
  5728.         else
  5729.                 ShearRotate4 m_arrRender1(), m_arrRender2(), iAngleXY, cClockwise, cPlaneXY, iMissingTileCount
  5730.         end if
  5731.        
  5732.         ' =============================================================================
  5733.         ' DRAW THE FINAL SCENE
  5734.     DrawRenderScreen iScreenOffsetX, iScreenOffsetY, iGridSize
  5735. End Sub ' DrawSnowScreen
  5736.  
  5737. ' /////////////////////////////////////////////////////////////////////////////
  5738. ' Copies a MapTileType user defined type variable, member by member
  5739. ' (not sure if you can just do MyUDT1 = MyUDT2?)
  5740.  
  5741. Sub CopyMapTile (SourceMap As MapTileType, DestMap As MapTileType)
  5742.     DestMap.Typ = SourceMap.Typ
  5743.     DestMap.Color1 = SourceMap.Color1
  5744.     DestMap.Color2 = SourceMap.Color2
  5745.     DestMap.Color3 = SourceMap.Color3
  5746.     DestMap.Alpha1 = SourceMap.Alpha1
  5747.     DestMap.Alpha2 = SourceMap.Alpha2
  5748.     DestMap.Alpha3 = SourceMap.Alpha3
  5749.     DestMap.AlphaOverride = SourceMap.AlphaOverride
  5750. End Sub ' CopyMapTile
  5751.  
  5752. ' /////////////////////////////////////////////////////////////////////////////
  5753. ' RETURNS MAP AS TEXT
  5754.  
  5755. ' Requires shared global variable
  5756. ' m_arrMap(x,y,z) = 3D array map of world
  5757. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  5758.  
  5759. ' USAGE:
  5760. 'Input "See a text dump (y/n)? ", in$
  5761. 'If LCase$(in$) = LCase$("y") Then
  5762. '    Print MapToText$
  5763. 'End If
  5764.  
  5765. Function MapToText$
  5766.     Dim RoutineName As String: RoutineName = "MapToText$"
  5767.     Dim sResult As String
  5768.     Dim iLoopX%
  5769.     Dim iLoopY%
  5770.     Dim iLoopZ%
  5771.     Dim iMinX%
  5772.     Dim iMaxX%
  5773.     Dim iMinY%
  5774.     Dim iMaxY%
  5775.     Dim iMinZ%
  5776.     Dim iMaxZ%
  5777.     Dim sLine As String
  5778.     Dim iType%
  5779.     Dim iColor1&
  5780.     Dim iColor2&
  5781.     Dim iColor3&
  5782.     Dim in$
  5783.  
  5784.     sResult = ""
  5785.  
  5786.     ' FIND USED BOUNDARIES OF MAP
  5787.     iMinX% = -1
  5788.     iMaxX% = -1
  5789.     iMinY% = -1
  5790.     iMaxY% = -1
  5791.     iMinZ% = -1
  5792.     iMaxZ% = -1
  5793.     For iLoopZ% = 0 To 32
  5794.         For iLoopX% = 0 To 32
  5795.             For iLoopY% = 0 To 32
  5796.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  5797.                 If iType% <> c_iTile_Empty And iType% <> c_iTile_Floor Then
  5798.                     If iMinX% = -1 Then
  5799.                         iMinX% = iLoopX%
  5800.                     End If
  5801.                     If iMinY% = -1 Then
  5802.                         iMinY% = iLoopY%
  5803.                     End If
  5804.                     If iMinZ% = -1 Then
  5805.                         iMinZ% = iLoopZ%
  5806.                     End If
  5807.                     If iLoopX% > iMaxX% Then
  5808.                         iMaxX% = iLoopX%
  5809.                     End If
  5810.                     If iLoopY% > iMaxY% Then
  5811.                         iMaxY% = iLoopY%
  5812.                     End If
  5813.                     If iLoopZ% > iMaxZ% Then
  5814.                         iMaxZ% = iLoopZ%
  5815.                     End If
  5816.                 End If
  5817.             Next iLoopY%
  5818.         Next iLoopX%
  5819.     Next iLoopZ%
  5820.  
  5821.     ' GENERATE OUTPUT
  5822.     For iLoopZ% = iMinZ% To iMaxZ%
  5823.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  5824.         sResult = sResult + "Map Z=" + cstr$(iLoopZ%) + ":" + Chr$(13)
  5825.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  5826.         For iLoopY% = iMinY% To iMaxY%
  5827.             sLine = ""
  5828.             For iLoopX% = iMinX% To iMaxX%
  5829.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  5830.                 iColor1& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  5831.                 iColor2& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  5832.                 iColor3& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color3
  5833.  
  5834.                 If iType% = c_iTile_Empty Then
  5835.                     sLine = sLine + " "
  5836.                 Else
  5837.                     If iColor1& = cEmpty Then
  5838.                         sLine = sLine + " "
  5839.                     Else
  5840.                         sLine = sLine + "#"
  5841.                     End If
  5842.                 End If
  5843.             Next iLoopX%
  5844.             sResult = sResult + sLine + Chr$(13)
  5845.         Next iLoopY%
  5846.  
  5847.         sResult = sResult + Chr$(13)
  5848.     Next iLoopZ%
  5849.  
  5850.     MapToText$ = sResult
  5851. End Function ' MapToText$
  5852.  
  5853. ' /////////////////////////////////////////////////////////////////////////////
  5854. ' Return string description for 2.5D movement constants
  5855.  
  5856. Function GetDirection$ (iDir As Integer)
  5857.     Dim sDir As String
  5858.     Select Case iDir
  5859.         Case c_iDir_Down:
  5860.             sDir = "Down"
  5861.         Case c_iDir_Up:
  5862.             sDir = "Up"
  5863.         Case c_iDir_Left:
  5864.             sDir = "Left"
  5865.         Case c_iDir_Right:
  5866.             sDir = "Right"
  5867.         Case c_iDir_Back:
  5868.             sDir = "Back"
  5869.         Case c_iDir_Forward:
  5870.             sDir = "Forward"
  5871.         Case Else:
  5872.             sDir = "Unknown"
  5873.     End Select
  5874.     GetDirection$ = sDir
  5875. End Function ' GetDirection$
  5876.  
  5877. ' /////////////////////////////////////////////////////////////////////////////
  5878.  
  5879. Function CX2I (x As Long, y As Long) 'Convert Cartesian X To Isometic coordinates
  5880.     CX2I = x - y
  5881. End Function ' CX2I
  5882.  
  5883. ' /////////////////////////////////////////////////////////////////////////////
  5884.  
  5885. Function CY2I (x As Long, y As Long) 'Convert Cartesian Y To Isometic coordinates
  5886.     CY2I = (x + y) / 2
  5887. End Function ' CY2I
  5888.  
  5889. ' /////////////////////////////////////////////////////////////////////////////
  5890. ' since we're drawing a diamond and not a square box, we can't use Line BF.
  5891. ' We have to manually down the 4 points of the line.
  5892.  
  5893. Sub IsoLine (x, y, x2, y2, xoffset, yoffset, iColor As _Unsigned Long)
  5894.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), iColor
  5895.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), iColor
  5896.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), iColor
  5897.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), iColor
  5898.     Paint (CX2I(x, y) + xoffset, CY2I(x, y) + 4), iColor 'and fill the diamond solid
  5899.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), &HFFFFFFFF
  5900.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), &HFFFFFFFF
  5901.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), &HFFFFFFFF
  5902.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), &HFFFFFFFF
  5903. End Sub ' IsoLine
  5904.  
  5905. ' /////////////////////////////////////////////////////////////////////////////
  5906. ' Like IsoLine, we're going to have to draw our lines manually.
  5907. ' only in this case, we also need a Z coordinate to tell us how
  5908. ' THICK/TALL/HIGH to make our tile
  5909.  
  5910. ' MODIFIED by madscijr to draw a single tile of height iHeight at Z axis
  5911. ' MODIFIED by madscijr to accept an alpha& value to control transparency (where 0=fully transparent, 255=opaque)
  5912.  
  5913. ''Sub IsoLine3D (x, y, x2, y2, z, xoffset, yoffset, iColor As _Unsigned Long)
  5914. 'Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long)
  5915. Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long, alpha&)
  5916.     Dim r 'as integer
  5917.     Dim g 'as integer
  5918.     Dim b 'as integer
  5919.        
  5920.     r = _Red32(iColor)
  5921.     g = _Green32(iColor)
  5922.     b = _Blue32(iColor)
  5923.        
  5924.     ' Let's just do all the math first this time.
  5925.     ' We need to turn those 4 normal points into 4 isometric points (x, y, x1, y1)
  5926.     TempX1 = CX2I(x, y) + xoffset
  5927.     TempY1 = CY2I(x, y) + yoffset
  5928.     TempX2 = CX2I(x2, y) + xoffset
  5929.     TempY2 = CY2I(x2, y) + yoffset
  5930.     TempX3 = CX2I(x2, y2) + xoffset
  5931.     TempY3 = CY2I(x2, y2) + yoffset
  5932.     TempX4 = CX2I(x, y2) + xoffset
  5933.     TempY4 = CY2I(x, y2) + yoffset
  5934.        
  5935.     ' The top
  5936.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, iColor
  5937.     fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  5938.        
  5939.     If z <> 0 Then
  5940.         ' TODO: maybe change which sides gets shaded depending on the direction of the light source?
  5941.  
  5942.         ' draw the left side, shaded 75%
  5943.         'fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b)
  5944.         fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b, alpha&)
  5945.  
  5946.         ' draw the right side,s haded 50%
  5947.         'fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b)
  5948.         fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b, alpha&)
  5949.     Else
  5950.         ' no need to draw any height, if there isn't any.
  5951.     End If
  5952. End Sub ' IsoLine3D
  5953.  
  5954. ' /////////////////////////////////////////////////////////////////////////////
  5955. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  5956. ' don't go there: http://www.qb64.[net]/forum/index.php?topic=14425.0
  5957.  
  5958. Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  5959.     Dim D As Long
  5960.     Dim a&
  5961.  
  5962.     D = _Dest
  5963.     a& = _NewImage(1, 1, 32)
  5964.     _Dest a&
  5965.     PSet (0, 0), K
  5966.     _Dest D
  5967.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  5968.     _FreeImage a& ' <<< this is important!
  5969. End Sub ' ftri
  5970.  
  5971. ' /////////////////////////////////////////////////////////////////////////////
  5972. ' 2019-11-20 Steve saves some time with STATIC
  5973. ' and saves and restores last dest
  5974.  
  5975. Sub ftri1 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  5976.     Dim D As Long
  5977.     Static a&
  5978.        
  5979.     D = _Dest
  5980.     If a& = 0 Then
  5981.         a& = _NewImage(1, 1, 32)
  5982.     End If
  5983.     _Dest a&
  5984.     _DontBlend a&
  5985.     PSet (0, 0), K
  5986.     _Blend a&
  5987.     _Dest D
  5988.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  5989. End Sub ' ftri1
  5990.  
  5991. ' /////////////////////////////////////////////////////////////////////////////
  5992. ' original fill quad that may be at fault using Steve's fTri version
  5993. ' need 4 non linear points (not all on 1 line) list them clockwise
  5994. ' so x2, y2 is opposite of x4, y4
  5995.  
  5996. Sub fquad1 (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  5997.     ftri1 x1, y1, x2, y2, x4, y4, K
  5998.     ftri1 x3, y3, x2, y2, x4, y4, K
  5999. End Sub ' fquad1
  6000.  
  6001. ' /////////////////////////////////////////////////////////////////////////////
  6002. ' update 2019-12-16 needs orig fTri
  6003. ' need 4 non linear points (not all on 1 line)
  6004. ' list them clockwise so x2, y2 is opposite of x4, y4
  6005.  
  6006. Sub fquad (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  6007.     ftri x1, y1, x2, y2, x3, y3, K
  6008.     ftri x3, y3, x4, y4, x1, y1, K
  6009. End Sub ' fquad
  6010.  
  6011. ' /////////////////////////////////////////////////////////////////////////////
  6012. ' DRAW A 2-D RECTANGLE (SOLID)
  6013. ' Based on DrawBox
  6014.  
  6015. 'SUB DrawRect (iX%, iY%, iSizeW%, iSizeH%, iColor%)
  6016. Sub DrawRect (iX%, iY%, iSizeW%, iSizeH%, iColor~&)
  6017.     Line (iX%, iY%)-(iX% + iSizeW%, iY% + iSizeH%), iColor~&, BF ' Draw a solid box
  6018.     'LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor%, BF ' Draw a solid box
  6019.     'LINE (60, 60)-(130, 100), iColor%, B ' Draw a box outline
  6020. End Sub ' DrawRect
  6021.  
  6022. ' /////////////////////////////////////////////////////////////////////////////
  6023. ' DRAW A 2-D BOX (SOLID)
  6024. ' https://www.qb64.org/wiki/LINE
  6025.  
  6026. 'SUB DrawBox (iX%, iY%, iSize%, iColor%)
  6027. Sub DrawBox (iX%, iY%, iSize%, iColor~&)
  6028.     Line (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor~&, BF ' Draw a solid box
  6029.     'LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor%, BF ' Draw a solid box
  6030.     'LINE (60, 60)-(130, 100), iColor%, B ' Draw a box outline
  6031. End Sub ' DrawBox
  6032.  
  6033. ' /////////////////////////////////////////////////////////////////////////////
  6034. ' DRAW A 2-D BOX (OUTLINE)
  6035. ' https://www.qb64.org/wiki/LINE
  6036.  
  6037. ' The style parameter 0-255 doesn't seemt to have a solid line?
  6038.  
  6039. 'SUB DrawStyledOutlineBox (iX%, iY%, iSize%, iColor%, iStyle%)
  6040. Sub DrawStyledOutlineBox (iX%, iY%, iSize%, iColor~&, iStyle%)
  6041.     ' LINE [STEP] [(column1, row1)]-[STEP] (column2, row2), color[, [{B|BF}], style%]
  6042.     ' B creates a box outline with each side parallel to the program screen sides. BF creates a filled box.
  6043.     ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  6044.  
  6045.     Line (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor~&, B , iStyle%
  6046. End Sub ' DrawStyledOutlineBox
  6047.  
  6048. ' /////////////////////////////////////////////////////////////////////////////
  6049. ' DRAW A 2-D BOX (OUTLINE) WITH A SOLID LINE
  6050.  
  6051. Sub DrawOutlineBox (iX%, iY%, iSize2%, iColor~&, iWeight2%)
  6052.     Dim iFromX%
  6053.     Dim iFromY%
  6054.     Dim iToX%
  6055.     Dim iToY%
  6056.     iSize% = iSize2% - 1
  6057.     iWeight% = iWeight2% - 1
  6058.     If iWeight% = 0 Then
  6059.         ' TOP LINE
  6060.         iFromX% = iX%
  6061.         iFromY% = iY%
  6062.         iToX% = iX% + iSize%
  6063.         iToY% = iY%
  6064.         Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6065.  
  6066.         ' BOTTOM LINE
  6067.         iFromX% = iX%
  6068.         iFromY% = iY% + iSize%
  6069.         iToX% = iX% + iSize%
  6070.         iToY% = iY% + iSize%
  6071.         Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6072.  
  6073.         ' LEFT LINE
  6074.         iFromX% = iX%
  6075.         iFromY% = iY%
  6076.         iToX% = iX%
  6077.         iToY% = iY% + iSize%
  6078.         Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6079.  
  6080.         ' RIGHT LINE
  6081.         iFromX% = iX% + iSize%
  6082.         iFromY% = iY%
  6083.         iToX% = iX% + iSize%
  6084.         iToY% = iY% + iSize%
  6085.         Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6086.     ElseIf iWeight% > 0 Then
  6087.         ' TOP LINE
  6088.         For iFromY% = iY% To (iY% + iWeight%)
  6089.             iFromX% = iX%
  6090.             'iFromY% = iY%
  6091.             iToX% = iX% + iSize%
  6092.             iToY% = iFromY%
  6093.             Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6094.         Next iFromY%
  6095.  
  6096.         ' BOTTOM LINE
  6097.         For iFromY% = ((iY% + iSize%) - iWeight%) To (iY% + iSize%)
  6098.             iFromX% = iX%
  6099.             'iFromY% = iY% + iSize%
  6100.             iToX% = iX% + iSize%
  6101.             iToY% = iFromY%
  6102.             Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6103.         Next iFromY%
  6104.  
  6105.         ' LEFT LINE
  6106.         For iFromX% = iX% To (iX% + iWeight%)
  6107.             'iFromX% = iX%
  6108.             iFromY% = iY%
  6109.             iToX% = iFromX%
  6110.             iToY% = iY% + iSize%
  6111.             Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6112.         Next iFromX%
  6113.  
  6114.         ' RIGHT LINE
  6115.         For iFromX% = ((iX% + iSize%) - iWeight%) To (iX% + iSize%)
  6116.             'iFromX% = iX% + iSize%
  6117.             iFromY% = iY%
  6118.             iToX% = iFromX%
  6119.             iToY% = iY% + iSize%
  6120.             Line (iFromX%, iFromY%)-(iToX%, iToY%), iColor~&, BF
  6121.         Next iFromX%
  6122.     End If
  6123. End Sub ' DrawOutlineBox
  6124.  
  6125. ' /////////////////////////////////////////////////////////////////////////////
  6126.  
  6127. Function GetPaletteFromColor% (iColor~&)
  6128.     Select Case iColor~&
  6129.         Case cEmpty:
  6130.             GetPaletteFromColor% = 0
  6131.         Case cBlack:
  6132.             GetPaletteFromColor% = 1
  6133.         Case cDarkGray:
  6134.             GetPaletteFromColor% = 2
  6135.         Case cDimGray:
  6136.             GetPaletteFromColor% = 3
  6137.         Case cGray:
  6138.             GetPaletteFromColor% = 4
  6139.         Case cLightGray:
  6140.             GetPaletteFromColor% = 5
  6141.         Case cSilver:
  6142.             GetPaletteFromColor% = 6
  6143.         Case cWhite:
  6144.             GetPaletteFromColor% = 7
  6145.         Case cRed:
  6146.             GetPaletteFromColor% = 8
  6147.         Case cOrangeRed:
  6148.             GetPaletteFromColor% = 9
  6149.         Case cDarkOrange:
  6150.             GetPaletteFromColor% = 10
  6151.         Case cOrange:
  6152.             GetPaletteFromColor% = 11
  6153.         Case cGold:
  6154.             GetPaletteFromColor% = 12
  6155.         Case cYellow:
  6156.             GetPaletteFromColor% = 13
  6157.         Case cOliveDrab1:
  6158.             GetPaletteFromColor% = 14
  6159.         Case cLime:
  6160.             GetPaletteFromColor% = 15
  6161.         Case cMediumSpringGreen:
  6162.             GetPaletteFromColor% = 16
  6163.         Case cCyan:
  6164.             GetPaletteFromColor% = 17
  6165.         Case cDeepSkyBlue:
  6166.             GetPaletteFromColor% = 18
  6167.         Case cDodgerBlue:
  6168.             GetPaletteFromColor% = 19
  6169.         Case cSeaBlue:
  6170.             GetPaletteFromColor% = 20
  6171.         Case cBlue:
  6172.             GetPaletteFromColor% = 21
  6173.         Case cBluePurple:
  6174.             GetPaletteFromColor% = 22
  6175.         Case cDeepPurple:
  6176.             GetPaletteFromColor% = 23
  6177.         Case cPurple:
  6178.             GetPaletteFromColor% = 24
  6179.         Case cPurpleRed:
  6180.             GetPaletteFromColor% = 25
  6181.         Case Else:
  6182.             GetPaletteFromColor% = 0
  6183.     End Select
  6184. End Function ' GetPaletteFromColor%
  6185.  
  6186. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6187. ' END GRAPHICS FUNCTIONS
  6188. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6189.  
  6190. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6191. ' BEGIN GENERAL PURPOSE ROUTINES
  6192. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6193.  
  6194. ' /////////////////////////////////////////////////////////////////////////////
  6195. ' Convert a value to string and trim it (because normal Str$ adds spaces)
  6196.  
  6197. Function cstr$ (myValue)
  6198.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  6199.     cstr$ = _Trim$(Str$(myValue))
  6200. End Function ' cstr$
  6201.  
  6202. ' /////////////////////////////////////////////////////////////////////////////
  6203. ' Convert a Long value to string and trim it (because normal Str$ adds spaces)
  6204.  
  6205. Function cstrl$ (myValue As Long)
  6206.     cstrl$ = _Trim$(Str$(myValue))
  6207. End Function ' cstrl$
  6208.  
  6209. ' /////////////////////////////////////////////////////////////////////////////
  6210. ' Convert a Single value to string and trim it (because normal Str$ adds spaces)
  6211.  
  6212. Function cstrs$ (myValue As Single)
  6213.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  6214.     cstrs$ = _Trim$(Str$(myValue))
  6215. End Function ' cstrs$
  6216.  
  6217. ' /////////////////////////////////////////////////////////////////////////////
  6218. ' Convert an unsigned Long value to string and trim it (because normal Str$ adds spaces)
  6219.  
  6220. Function cstrul$ (myValue As _Unsigned Long)
  6221.     cstrul$ = _Trim$(Str$(myValue))
  6222. End Function ' cstrul$
  6223.  
  6224. ' /////////////////////////////////////////////////////////////////////////////
  6225. ' based on code from:
  6226. ' Qbasic Programs - Download free bas source code
  6227. ' http://www.thedubber.altervista.org/qbsrc.htm
  6228.  
  6229. Sub DrawTextLine (x%, y%, x2%, y2%, c$)
  6230.     'bError% = FALSE
  6231.     'LOCATE 2, 2: PRINT "(" + STR$(x%) + "," + STR$(y%) + ") to (" + STR$(x2%) + "," + STR$(y2%) + ") of " + CHR$(34) + c$ + CHR$(34);
  6232.  
  6233.     i% = 0
  6234.     steep% = 0
  6235.     e1% = 0
  6236.     If (x2% - x%) > 0 Then sx% = 1: Else sx% = -1
  6237.     dx% = Abs(x2% - x%)
  6238.     If (y2% - y%) > 0 Then sy% = 1: Else sy% = -1
  6239.     dy% = Abs(y2% - y%)
  6240.     If (dy% > dx%) Then
  6241.         steep% = 1
  6242.         Swap x%, y%
  6243.         Swap dx%, dy%
  6244.         Swap sx%, sy%
  6245.     End If
  6246.     e1% = 2 * dy% - dx%
  6247.     For i% = 0 To dx% - 1
  6248.         If steep% = 1 Then
  6249.             'PSET (y%, x%), c%:
  6250.             Locate y%, x%
  6251.             Print c$;
  6252.         Else
  6253.             'PSET (x%, y%), c%
  6254.             Locate x%, y%
  6255.             Print c$;
  6256.         End If
  6257.  
  6258.         While E% >= 0
  6259.             y% = y% + sy%: e1% = e1% - 2 * dx%
  6260.         Wend
  6261.         x% = x% + sx%: e1% = e1% + 2 * dy%
  6262.     Next
  6263.     'PSET (x2%, y2%), c%
  6264.     Locate x2%, y2%
  6265.     Print c$;
  6266.  
  6267. End Sub ' DrawTextLine
  6268.  
  6269. ' /////////////////////////////////////////////////////////////////////////////
  6270. ' From: Bitwise Manipulations By Steven Roman
  6271. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  6272.  
  6273. ' Returns the 8-bit binary representation
  6274. ' of an integer iInput where 0 <= iInput <= 255
  6275.  
  6276. Function GetBinary$ (iInput1 As Integer)
  6277.     Dim sResult As String
  6278.     Dim iLoop As Integer
  6279.     Dim iInput As Integer: iInput = iInput1
  6280.  
  6281.     sResult = ""
  6282.  
  6283.     If iInput >= 0 And iInput <= 255 Then
  6284.         For iLoop = 1 To 8
  6285.             sResult = LTrim$(RTrim$(Str$(iInput Mod 2))) + sResult
  6286.             iInput = iInput \ 2
  6287.             'If iLoop = 4 Then sResult = " " + sResult
  6288.         Next iLoop
  6289.     End If
  6290.  
  6291.     GetBinary$ = sResult
  6292. End Function ' GetBinary$
  6293.  
  6294. ' /////////////////////////////////////////////////////////////////////////////
  6295. ' wonderfully inefficient way to read if a bit is set
  6296. ' ival = GetBit256%(int we are comparing, int containing the bits we want to read)
  6297.  
  6298. ' See also: GetBit256%, SetBit256%
  6299.  
  6300. Function GetBit256% (iNum1 As Integer, iBit1 As Integer)
  6301.     Dim iResult As Integer
  6302.     Dim sNum As String
  6303.     Dim sBit As String
  6304.     Dim iLoop As Integer
  6305.     Dim bContinue As Integer
  6306.     'DIM iTemp AS INTEGER
  6307.     Dim iNum As Integer: iNum = iNum1
  6308.     Dim iBit As Integer: iBit = iBit1
  6309.  
  6310.     iResult = FALSE
  6311.     bContinue = TRUE
  6312.  
  6313.     If iNum < 256 And iBit <= 128 Then
  6314.         sNum = GetBinary$(iNum)
  6315.         sBit = GetBinary$(iBit)
  6316.         For iLoop = 1 To 8
  6317.             If Mid$(sBit, iLoop, 1) = "1" Then
  6318.                 'if any of the bits in iBit are false, return false
  6319.                 If Mid$(sNum, iLoop, 1) = "0" Then
  6320.                     iResult = FALSE
  6321.                     bContinue = FALSE
  6322.                     Exit For
  6323.                 End If
  6324.             End If
  6325.         Next iLoop
  6326.         If bContinue = TRUE Then
  6327.             iResult = TRUE
  6328.         End If
  6329.     End If
  6330.  
  6331.     GetBit256% = iResult
  6332. End Function ' GetBit256%
  6333.  
  6334. ' /////////////////////////////////////////////////////////////////////////////
  6335. ' From: Bitwise Manipulations By Steven Roman
  6336. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  6337.  
  6338. ' Returns the integer that corresponds to a binary string of length 8
  6339.  
  6340. Function GetIntegerFromBinary% (sBinary1 As String)
  6341.     Dim iResult As Integer
  6342.     Dim iLoop As Integer
  6343.     Dim strBinary As String
  6344.     Dim sBinary As String: sBinary = sBinary1
  6345.  
  6346.     iResult = 0
  6347.     strBinary = Replace$(sBinary, " ", "") ' Remove any spaces
  6348.     For iLoop = 0 To Len(strBinary) - 1
  6349.         iResult = iResult + 2 ^ iLoop * Val(Mid$(strBinary, Len(strBinary) - iLoop, 1))
  6350.     Next iLoop
  6351.  
  6352.     GetIntegerFromBinary% = iResult
  6353. End Function ' GetIntegerFromBinary%
  6354.  
  6355. ' /////////////////////////////////////////////////////////////////////////////
  6356.  
  6357. Function IIF (Condition, IfTrue, IfFalse)
  6358.     If Condition Then IIF = IfTrue Else IIF = IfFalse
  6359.  
  6360. ' /////////////////////////////////////////////////////////////////////////////
  6361.  
  6362. Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
  6363.     If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
  6364.  
  6365. ' /////////////////////////////////////////////////////////////////////////////
  6366. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  6367.  
  6368. Function IsEven% (n)
  6369.     If n Mod 2 = 0 Then
  6370.         IsEven% = TRUE
  6371.     Else
  6372.         IsEven% = FALSE
  6373.     End If
  6374. End Function ' IsEven%
  6375.  
  6376. ' /////////////////////////////////////////////////////////////////////////////
  6377. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  6378.  
  6379. Function IsOdd% (n)
  6380.     If n Mod 2 = 1 Then
  6381.         IsOdd% = TRUE
  6382.     Else
  6383.         IsOdd% = FALSE
  6384.     End If
  6385. End Function ' IsOdd%
  6386.  
  6387. ' /////////////////////////////////////////////////////////////////////////////
  6388. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  6389.  
  6390. Function IsNum% (text$)
  6391.     Dim a$
  6392.     Dim b$
  6393.     a$ = _Trim$(text$)
  6394.     b$ = _Trim$(Str$(Val(text$)))
  6395.     If a$ = b$ Then
  6396.         IsNum% = TRUE
  6397.     Else
  6398.         IsNum% = FALSE
  6399.     End If
  6400. End Function ' IsNum%
  6401.  
  6402. ' /////////////////////////////////////////////////////////////////////////////
  6403. ' Re: Does a Is Number function exist in QB64?
  6404. ' https://www.qb64.org/forum/index.php?topic=896.15
  6405.  
  6406. ' MWheatley
  6407. ' « Reply #18 on: January 01, 2019, 11:24:30 AM »
  6408.  
  6409. ' returns 1 if string is an integer, 0 if not
  6410. Function IsNumber (text$)
  6411.     Dim i As Integer
  6412.  
  6413.     IsNumber = 1
  6414.     For i = 1 To Len(text$)
  6415.         If Asc(Mid$(text$, i, 1)) < 45 Or Asc(Mid$(text$, i, 1)) >= 58 Then
  6416.             IsNumber = 0
  6417.             Exit For
  6418.         ElseIf Asc(Mid$(text$, i, 1)) = 47 Then
  6419.             IsNumber = 0
  6420.             Exit For
  6421.         End If
  6422.     Next i
  6423. End Function ' IsNumber
  6424.  
  6425. ' /////////////////////////////////////////////////////////////////////////////
  6426. ' Split and join strings
  6427. ' https://www.qb64.org/forum/index.php?topic=1073.0
  6428.  
  6429. 'Combine all elements of in$() into a single string with delimiter$ separating the elements.
  6430.  
  6431. Function join$ (in$(), delimiter$)
  6432.     Dim result$
  6433.     Dim i As Long
  6434.     result$ = in$(LBound(in$))
  6435.     For i = LBound(in$) + 1 To UBound(in$)
  6436.         result$ = result$ + delimiter$ + in$(i)
  6437.     Next i
  6438.     join$ = result$
  6439. End Function ' join$
  6440.  
  6441. ' /////////////////////////////////////////////////////////////////////////////
  6442. ' ABS was returning strange values with type LONG
  6443. ' so I created this which does not.
  6444.  
  6445. Function LongABS& (lngValue As Long)
  6446.     If Sgn(lngValue) = -1 Then
  6447.         LongABS& = 0 - lngValue
  6448.     Else
  6449.         LongABS& = lngValue
  6450.     End If
  6451. End Function ' LongABS&
  6452.  
  6453. ' /////////////////////////////////////////////////////////////////////////////
  6454. ' Writes sText to a debug file in the EXE folder.
  6455. ' Debug file is named the same thing as the program EXE name with ".txt" at the end.
  6456. ' For example the program "C:\QB64\MyProgram.BAS" running as
  6457. ' "C:\QB64\MyProgram.EXE" would have an output file "C:\QB64\MyProgram.EXE.txt".
  6458. ' If the file doesn't exist, it is created, otherwise it is appended to.
  6459.  
  6460. Sub PrintDebugFile (sText As String)
  6461.     Dim sFileName As String
  6462.     Dim sError As String
  6463.     Dim sOut As String
  6464.  
  6465.     sFileName = ProgramPath$ + ProgramName$ + ".txt"
  6466.     sError = ""
  6467.     If _FileExists(sFileName) = FALSE Then
  6468.         sOut = ""
  6469.         sOut = sOut + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + Chr$(13) + Chr$(10)
  6470.         sOut = sOut + "PROGRAM : " + ProgramName$ + Chr$(13) + Chr$(10)
  6471.         sOut = sOut + "RUN DATE: " + CurrentDateTime$ + Chr$(13) + Chr$(10)
  6472.         sOut = sOut + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + Chr$(13) + Chr$(10)
  6473.         sError = PrintFile$(sFileName, sOut, FALSE)
  6474.     End If
  6475.     If Len(sError) = 0 Then
  6476.         sError = PrintFile$(sFileName, sText, TRUE)
  6477.     End If
  6478.     If Len(sError) <> 0 Then
  6479.         Print CurrentDateTime$ + " PrintDebugFile FAILED: " + sError
  6480.     End If
  6481. End Sub ' PrintDebugFile
  6482.  
  6483. ' /////////////////////////////////////////////////////////////////////////////
  6484. ' Returns blank if successful else returns error message.
  6485.  
  6486. Function PrintFile$ (sFileName As String, sText As String, bAppend As Integer)
  6487.     'x = 1: y = 2: z$ = "Three"
  6488.  
  6489.     Dim sError As String: sError = ""
  6490.  
  6491.     If Len(sError) = 0 Then
  6492.         If (bAppend = TRUE) Then
  6493.             If _FileExists(sFileName) Then
  6494.                 Open sFileName For Append As #1 ' opens an existing file for appending
  6495.             Else
  6496.                 sError = "Error in PrintFile$ : File not found. Cannot append."
  6497.             End If
  6498.         Else
  6499.             Open sFileName For Output As #1 ' opens and clears an existing file or creates new empty file
  6500.         End If
  6501.     End If
  6502.     If Len(sError) = 0 Then
  6503.         ' WRITE places text in quotes in the file
  6504.         'WRITE #1, x, y, z$
  6505.         'WRITE #1, sText
  6506.  
  6507.         ' PRINT does not put text inside quotes
  6508.         Print #1, sText
  6509.  
  6510.         Close #1
  6511.  
  6512.         'PRINT "File created with data. Press a key!"
  6513.         'K$ = INPUT$(1) 'press a key
  6514.  
  6515.         'OPEN sFileName FOR INPUT AS #2 ' opens a file to read it
  6516.         'INPUT #2, a, b, c$
  6517.         'CLOSE #2
  6518.  
  6519.         'PRINT a, b, c$
  6520.         'WRITE a, b, c$
  6521.     End If
  6522.  
  6523.     PrintFile$ = sError
  6524. End Function ' PrintFile$
  6525.  
  6526. ' /////////////////////////////////////////////////////////////////////////////
  6527. ' iNum% = PromptForIntegerInRange%("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  6528.  
  6529. Function PromptForIntegerInRange% (sPrompt$, iMin%, iMax%, iDefault%)
  6530.     Dim iValue%
  6531.     Dim bFinished%
  6532.     Dim sPrompt1$
  6533.     Dim in$
  6534.  
  6535.     If Len(sPrompt$) > 0 Then
  6536.         sPrompt1$ = sPrompt$
  6537.     Else
  6538.         sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  6539.     End If
  6540.  
  6541.     sPrompt1$ = Replace$(sPrompt1$, "{min}", cstr$(iMin%))
  6542.     sPrompt1$ = Replace$(sPrompt1$, "{max}", cstr$(iMax%))
  6543.  
  6544.     bFinished% = FALSE
  6545.     Do
  6546.         Print sPrompt1$
  6547.  
  6548.         Input in$
  6549.         in$ = _Trim$(in$)
  6550.         If Len(in$) > 0 Then
  6551.             If IsNumber(in$) Then
  6552.                 iValue% = Val(in$)
  6553.                 If iValue% >= iMin% And iValue% <= iMax% Then
  6554.                     'bFinished% = TRUE
  6555.                     Exit Do
  6556.                 Else
  6557.                     Print "Number out of range."
  6558.                     Print
  6559.                 End If
  6560.             Else
  6561.                 Print "Not a valid number."
  6562.                 Print
  6563.             End If
  6564.         Else
  6565.             iValue% = iDefault%
  6566.             Exit Do
  6567.             'bFinished% = TRUE
  6568.         End If
  6569.     Loop Until bFinished% = TRUE
  6570.  
  6571.     PromptForIntegerInRange% = iValue%
  6572. End Function ' PromptForIntegerInRange%
  6573.  
  6574. ' /////////////////////////////////////////////////////////////////////////////
  6575. ' iNum& = PromptForLongInRange&("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  6576.  
  6577. Function PromptForLongInRange& (sPrompt$, iMin&, iMax&, iDefault&)
  6578.     Dim iValue&
  6579.     Dim bFinished&
  6580.     Dim sPrompt1$
  6581.     Dim in$
  6582.  
  6583.     bFinished& = FALSE
  6584.     Do
  6585.         If Len(sPrompt$) > 0 Then
  6586.             sPrompt1$ = sPrompt$
  6587.         Else
  6588.             sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  6589.         End If
  6590.  
  6591.         sPrompt1$ = Replace$(sPrompt1$, "{min}", cstrl$(iMin&))
  6592.         sPrompt1$ = Replace$(sPrompt1$, "{max}", cstrl$(iMax&))
  6593.  
  6594.         Input in$
  6595.         in$ = _Trim$(in$)
  6596.         If Len(in$) > 0 Then
  6597.             If IsNumber(in$) Then
  6598.                 iValue& = Val(in$)
  6599.                 If iValue& >= iMin& And iValue& <= iMax& Then
  6600.                     bFinished& = TRUE
  6601.                 Else
  6602.                     Print "Number out of range."
  6603.                     Print
  6604.                 End If
  6605.             Else
  6606.                 Print "Not a valid number."
  6607.                 Print
  6608.             End If
  6609.         Else
  6610.             iValue& = iDefault&
  6611.             bFinished& = TRUE
  6612.         End If
  6613.     Loop Until bFinished&
  6614.  
  6615.     PromptForLongInRange& = iValue&
  6616. End Function ' PromptForLongInRange&
  6617.  
  6618. ' /////////////////////////////////////////////////////////////////////////////
  6619. ' Generate random value between Min and Max.
  6620. Function RandomNumber% (Min%, Max%)
  6621.     Dim NumSpread%
  6622.  
  6623.     ' SET RANDOM SEED
  6624.     'Randomize ' Initialize random-number generator.
  6625.  
  6626.     ' GET RANDOM # Min%-Max%
  6627.     'RandomNumber = Int((Max * Rnd) + Min) ' generate number
  6628.  
  6629.     NumSpread% = (Max% - Min%) + 1
  6630.  
  6631.     RandomNumber% = Int(Rnd * NumSpread%) + Min% ' GET RANDOM # BETWEEN Max% AND Min%
  6632.  
  6633. End Function ' RandomNumber%
  6634.  
  6635. ' /////////////////////////////////////////////////////////////////////////////
  6636.  
  6637. Sub RandomNumberTest
  6638.     Dim iCols As Integer: iCols = 10
  6639.     Dim iRows As Integer: iRows = 20
  6640.     Dim iLoop As Integer
  6641.     Dim iX As Integer
  6642.     Dim iY As Integer
  6643.     Dim sError As String
  6644.     Dim sFileName As String
  6645.     Dim sText As String
  6646.     Dim bAppend As Integer
  6647.     Dim iMin As Integer
  6648.     Dim iMax As Integer
  6649.     Dim iNum As Integer
  6650.     Dim iErrorCount As Integer
  6651.     Dim sInput$
  6652.  
  6653.     sFileName = "c:\temp\maze_test_1.txt"
  6654.     sText = "Count" + Chr$(9) + "Min" + Chr$(9) + "Max" + Chr$(9) + "Random"
  6655.     bAppend = FALSE
  6656.     sError = PrintFile$(sFileName, sText, bAppend)
  6657.     If Len(sError) = 0 Then
  6658.         bAppend = TRUE
  6659.         iErrorCount = 0
  6660.  
  6661.         iMin = 0
  6662.         iMax = iCols - 1
  6663.         For iLoop = 1 To 100
  6664.             iNum = RandomNumber%(iMin, iMax)
  6665.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  6666.             sError = PrintFile$(sFileName, sText, bAppend)
  6667.             If Len(sError) > 0 Then
  6668.                 iErrorCount = iErrorCount + 1
  6669.                 Print Str$(iLoop) + ". ERROR"
  6670.                 Print "    " + "iMin=" + Str$(iMin)
  6671.                 Print "    " + "iMax=" + Str$(iMax)
  6672.                 Print "    " + "iNum=" + Str$(iNum)
  6673.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  6674.                 Print "    " + sError
  6675.             End If
  6676.         Next iLoop
  6677.  
  6678.         iMin = 0
  6679.         iMax = iRows - 1
  6680.         For iLoop = 1 To 100
  6681.             iNum = RandomNumber%(iMin, iMax)
  6682.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  6683.             sError = PrintFile$(sFileName, sText, bAppend)
  6684.             If Len(sError) > 0 Then
  6685.                 iErrorCount = iErrorCount + 1
  6686.                 Print Str$(iLoop) + ". ERROR"
  6687.                 Print "    " + "iMin=" + Str$(iMin)
  6688.                 Print "    " + "iMax=" + Str$(iMax)
  6689.                 Print "    " + "iNum=" + Str$(iNum)
  6690.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  6691.                 Print "    " + sError
  6692.             End If
  6693.         Next iLoop
  6694.  
  6695.         Print "Finished generating numbers. Errors: " + Str$(iErrorCount)
  6696.     Else
  6697.         Print "Error creating file " + Chr$(34) + sFileName + Chr$(34) + "."
  6698.         Print sError
  6699.     End If
  6700.  
  6701.     Input "Press <ENTER> to continue", sInput$
  6702. End Sub ' RandomNumberTest
  6703.  
  6704. ' /////////////////////////////////////////////////////////////////////////////
  6705. ' FROM: String Manipulation
  6706. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  6707. ' http://www.qb64.[net]/forum/index_topic_5964-0/
  6708. '
  6709. 'SUMMARY:
  6710. '   Purpose:  A library of custom functions that transform strings.
  6711. '   Author:   Dustinian Camburides (dustinian@gmail.com)
  6712. '   Platform: QB64 (www.qb64.org)
  6713. '   Revision: 1.6
  6714. '   Updated:  5/28/2012
  6715.  
  6716. 'SUMMARY:
  6717. '[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
  6718. 'INPUT:
  6719. 'Text: The input string; the text that's being manipulated.
  6720. 'Find: The specified sub-string; the string sought within the [Text] string.
  6721. 'Add: The sub-string that's being added to the [Text] string.
  6722.  
  6723. Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
  6724.     ' VARIABLES:
  6725.     Dim Text2 As String
  6726.     Dim Find2 As String
  6727.     Dim Add2 As String
  6728.     Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
  6729.     Dim strBefore As String ' The characters before the string to be replaced.
  6730.     Dim strAfter As String ' The characters after the string to be replaced.
  6731.  
  6732.     ' INITIALIZE:
  6733.     ' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
  6734.     Text2 = Text1
  6735.     Find2 = Find1
  6736.     Add2 = Add1
  6737.  
  6738.     lngLocation = InStr(1, Text2, Find2)
  6739.  
  6740.     ' PROCESSING:
  6741.     ' While [Find2] appears in [Text2]...
  6742.     While lngLocation
  6743.         ' Extract all Text2 before the [Find2] substring:
  6744.         strBefore = Left$(Text2, lngLocation - 1)
  6745.  
  6746.         ' Extract all text after the [Find2] substring:
  6747.         strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
  6748.  
  6749.         ' Return the substring:
  6750.         Text2 = strBefore + Add2 + strAfter
  6751.  
  6752.         ' Locate the next instance of [Find2]:
  6753.         lngLocation = InStr(1, Text2, Find2)
  6754.  
  6755.         ' Next instance of [Find2]...
  6756.     Wend
  6757.  
  6758.     ' OUTPUT:
  6759.     Replace$ = Text2
  6760. End Function ' Replace$
  6761.  
  6762. ' /////////////////////////////////////////////////////////////////////////////
  6763.  
  6764. Sub ReplaceTest
  6765.     Dim in$
  6766.  
  6767.     Print "-------------------------------------------------------------------------------"
  6768.     Print "ReplaceTest"
  6769.     Print
  6770.  
  6771.     Print "Original value"
  6772.     in$ = "Thiz iz a teZt."
  6773.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6774.     Print
  6775.  
  6776.     Print "Replacing lowercase " + Chr$(34) + "z" + Chr$(34) + " with " + Chr$(34) + "s" + Chr$(34) + "..."
  6777.     in$ = Replace$(in$, "z", "s")
  6778.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6779.     Print
  6780.  
  6781.     Print "Replacing uppercase " + Chr$(34) + "Z" + Chr$(34) + " with " + Chr$(34) + "s" + Chr$(34) + "..."
  6782.     in$ = Replace$(in$, "Z", "s")
  6783.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6784.     Print
  6785.  
  6786.     Print "ReplaceTest finished."
  6787. End Sub ' ReplaceTest
  6788.  
  6789. ' /////////////////////////////////////////////////////////////////////////////
  6790. ' fantastically inefficient way to set a bit
  6791.  
  6792. ' example use: arrMaze(iX, iY) = SetBit256%(arrMaze(iX, iY), cS, FALSE)
  6793.  
  6794. ' See also: GetBit256%, SetBit256%
  6795.  
  6796. ' newint=SetBit256%(oldint, int containing the bits we want to set, value to set them to)
  6797. Function SetBit256% (iNum1 As Integer, iBit1 As Integer, bVal1 As Integer)
  6798.     Dim sNum As String
  6799.     Dim sBit As String
  6800.     Dim sVal As String
  6801.     Dim iLoop As Integer
  6802.     Dim strResult As String
  6803.     Dim iResult As Integer
  6804.     Dim iNum As Integer: iNum = iNum1
  6805.     Dim iBit As Integer: iBit = iBit1
  6806.     Dim bVal As Integer: bVal = bVal1
  6807.  
  6808.     If iNum < 256 And iBit <= 128 Then
  6809.         sNum = GetBinary$(iNum)
  6810.         sBit = GetBinary$(iBit)
  6811.         If bVal = TRUE Then
  6812.             sVal = "1"
  6813.         Else
  6814.             sVal = "0"
  6815.         End If
  6816.         strResult = ""
  6817.         For iLoop = 1 To 8
  6818.             If Mid$(sBit, iLoop, 1) = "1" Then
  6819.                 strResult = strResult + sVal
  6820.             Else
  6821.                 strResult = strResult + Mid$(sNum, iLoop, 1)
  6822.             End If
  6823.         Next iLoop
  6824.         iResult = GetIntegerFromBinary%(strResult)
  6825.     Else
  6826.         iResult = iNum
  6827.     End If
  6828.  
  6829.     SetBit256% = iResult
  6830. End Function ' SetBit256%
  6831.  
  6832. ' /////////////////////////////////////////////////////////////////////////////
  6833. ' Split and join strings
  6834. ' https://www.qb64.org/forum/index.php?topic=1073.0
  6835. '
  6836. ' FROM luke, QB64 Developer
  6837. ' Date: February 15, 2019, 04:11:07 AM »
  6838. '
  6839. ' Given a string of words separated by spaces (or any other character),
  6840. ' splits it into an array of the words. I've no doubt many people have
  6841. ' written a version of this over the years and no doubt there's a million
  6842. ' ways to do it, but I thought I'd put mine here so we have at least one
  6843. ' version. There's also a join function that does the opposite
  6844. ' array -> single string.
  6845. '
  6846. ' Code is hopefully reasonably self explanatory with comments and a little demo.
  6847. ' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
  6848.  
  6849. 'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
  6850. 'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
  6851. '
  6852. 'delimiter$ must be one character long.
  6853. 'result$() must have been REDIMmed previously.
  6854.  
  6855. ' Modified to handle multi-character delimiters
  6856.  
  6857. Sub split (in$, delimiter$, result$())
  6858.     Dim start As Integer
  6859.     Dim finish As Integer
  6860.     Dim iDelimLen As Integer
  6861.     ReDim result$(-1)
  6862.  
  6863.     iDelimLen = Len(delimiter$)
  6864.  
  6865.     start = 1
  6866.     Do
  6867.         'While Mid$(in$, start, 1) = delimiter$
  6868.         While Mid$(in$, start, iDelimLen) = delimiter$
  6869.             'start = start + 1
  6870.             start = start + iDelimLen
  6871.             If start > Len(in$) Then
  6872.                 Exit Sub
  6873.             End If
  6874.         Wend
  6875.         finish = InStr(start, in$, delimiter$)
  6876.         If finish = 0 Then
  6877.             finish = Len(in$) + 1
  6878.         End If
  6879.  
  6880.         ReDim _Preserve result$(0 To UBound(result$) + 1)
  6881.  
  6882.         result$(UBound(result$)) = Mid$(in$, start, finish - start)
  6883.         start = finish + 1
  6884.     Loop While start <= Len(in$)
  6885. End Sub ' split
  6886.  
  6887. ' /////////////////////////////////////////////////////////////////////////////
  6888.  
  6889. Sub SplitTest
  6890.     Dim in$
  6891.     Dim delim$
  6892.     ReDim arrTest$(0)
  6893.     Dim iLoop%
  6894.  
  6895.     delim$ = Chr$(10)
  6896.     in$ = "this" + delim$ + "is" + delim$ + "a" + delim$ + "test"
  6897.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6898.     Print "delim$ = " + Chr$(34) + delim$ + Chr$(34)
  6899.     split in$, delim$, arrTest$()
  6900.  
  6901.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  6902.         Print "arrTest$(" + LTrim$(RTrim$(Str$(iLoop%))) + ") = " + Chr$(34) + arrTest$(iLoop%) + Chr$(34)
  6903.     Next iLoop%
  6904.     Print
  6905.     Print "Split test finished."
  6906. End Sub ' SplitTest
  6907.  
  6908. ' /////////////////////////////////////////////////////////////////////////////
  6909.  
  6910. Sub SplitAndReplaceTest
  6911.     Dim in$
  6912.     Dim out$
  6913.     Dim iLoop%
  6914.     ReDim arrTest$(0)
  6915.  
  6916.     Print "-------------------------------------------------------------------------------"
  6917.     Print "SplitAndReplaceTest"
  6918.     Print
  6919.  
  6920.     Print "Original value"
  6921.     in$ = "This line 1 " + Chr$(13) + Chr$(10) + "and line 2" + Chr$(10) + "and line 3 " + Chr$(13) + "finally THE END."
  6922.     out$ = in$
  6923.     out$ = Replace$(out$, Chr$(13), "\r")
  6924.     out$ = Replace$(out$, Chr$(10), "\n")
  6925.     out$ = Replace$(out$, Chr$(9), "\t")
  6926.     Print "in$ = " + Chr$(34) + out$ + Chr$(34)
  6927.     Print
  6928.  
  6929.     Print "Fixing linebreaks..."
  6930.     in$ = Replace$(in$, Chr$(13) + Chr$(10), Chr$(13))
  6931.     in$ = Replace$(in$, Chr$(10), Chr$(13))
  6932.     out$ = in$
  6933.     out$ = Replace$(out$, Chr$(13), "\r")
  6934.     out$ = Replace$(out$, Chr$(10), "\n")
  6935.     out$ = Replace$(out$, Chr$(9), "\t")
  6936.     Print "in$ = " + Chr$(34) + out$ + Chr$(34)
  6937.     Print
  6938.  
  6939.     Print "Splitting up..."
  6940.     split in$, Chr$(13), arrTest$()
  6941.  
  6942.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  6943.         out$ = arrTest$(iLoop%)
  6944.         out$ = Replace$(out$, Chr$(13), "\r")
  6945.         out$ = Replace$(out$, Chr$(10), "\n")
  6946.         out$ = Replace$(out$, Chr$(9), "\t")
  6947.         Print "arrTest$(" + cstr$(iLoop%) + ") = " + Chr$(34) + out$ + Chr$(34)
  6948.     Next iLoop%
  6949.     Print
  6950.  
  6951.     Print "SplitAndReplaceTest finished."
  6952. End Sub ' SplitAndReplaceTest
  6953.  
  6954. ' /////////////////////////////////////////////////////////////////////////////
  6955.  
  6956. Sub WaitForEnter
  6957.     Dim in$
  6958.     Input "Press <ENTER> to continue", in$
  6959. End Sub ' WaitForEnter
  6960.  
  6961. ' /////////////////////////////////////////////////////////////////////////////
  6962. ' WaitForKey "Press <ESC> to continue", 27, 0
  6963. ' WaitForKey "Press <ENTER> to begin;", 13, 0
  6964. ' waitforkey "", 65, 5
  6965.  
  6966. Sub WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  6967.     ' SHOW PROMPT (IF SPECIFIED)
  6968.     If Len(prompt$) > 0 Then
  6969.         If Right$(prompt$, 1) <> ";" Then
  6970.             Print prompt$
  6971.         Else
  6972.             Print Right$(prompt$, Len(prompt$) - 1);
  6973.         End If
  6974.     End If
  6975.  
  6976.     ' WAIT FOR KEY
  6977.     Do: Loop Until _KeyDown(KeyCode&) ' leave loop when specified key pressed
  6978.  
  6979.     ' PAUSE AFTER (IF SPECIFIED)
  6980.     If DelaySeconds% < 1 Then
  6981.         _KeyClear: '_DELAY 1
  6982.     Else
  6983.         _KeyClear: _Delay DelaySeconds%
  6984.     End If
  6985. End Sub ' WaitForKey
  6986.  
  6987. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6988. ' END GENERAL PURPOSE ROUTINES
  6989. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6990.  
  6991. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6992. ' BEGIN COLOR ROUTINES
  6993. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6994.  
  6995. ' /////////////////////////////////////////////////////////////////////////////
  6996. ' Receives:
  6997. ' cycleColor = determines how foreColor, backColor are modified
  6998. ' foreColor  = the foreground color
  6999. ' backColor  = the background color (if needed)
  7000.  
  7001. ' /////////////////////////////////////////////////////////////////////////////
  7002. ' DoCycleColor colorScheme%, myColor~&
  7003.  
  7004. ' colorScheme = color scheme (value is alternated on subsequent calls)
  7005. ' myColor     = the current color (value is incremented/decremented on subsequent calls)
  7006.  
  7007. ' colorScheme  values:
  7008. '  1 Rainbow6  #1
  7009. '  9 Rainbow6  #2
  7010. '  2 Rainbow18 #1
  7011. ' 10 Rainbow18 #2
  7012. '  3 Grayscale #1
  7013. ' 11 Grayscale #2
  7014. '  4 Grayscale #1
  7015. ' 12 Grayscale #2
  7016. ' 20 green6    #1
  7017. ' 21 green6    #2
  7018.  
  7019. Sub DoCycleColor (colorScheme As Integer, myColor As _Unsigned Long)
  7020.     ReDim ColorArray(-1) As _Unsigned Long
  7021.     Dim iPos As Integer
  7022.    
  7023.     ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
  7024.     ' CYCLE FORE COLOR
  7025.    
  7026.     ' 1, 9 = simple rainbow
  7027.     If colorScheme = 1 Or colorScheme = 9 Then
  7028.         Select Case myColor
  7029.             Case cRed:
  7030.                 myColor = cOrange
  7031.             Case cOrange:
  7032.                 myColor = cYellow
  7033.             Case cYellow:
  7034.                 myColor = cGreen
  7035.             Case cGreen:
  7036.                 myColor = cBlue
  7037.             Case cBlue:
  7038.                 myColor = cPurple
  7039.             Case Else:
  7040.                 myColor = cRed
  7041.         End Select
  7042.  
  7043.         ' 2, 10 = complex rainbow
  7044.     ElseIf colorScheme = 2 Or colorScheme = 10 Then
  7045.         Select Case myColor
  7046.             Case cRed:
  7047.                 myColor = cOrangeRed
  7048.             Case cOrangeRed:
  7049.                 myColor = cDarkOrange
  7050.             Case cDarkOrange:
  7051.                 myColor = cOrange
  7052.             Case cOrange:
  7053.                 myColor = cGold
  7054.             Case cGold:
  7055.                 myColor = cYellow
  7056.             Case cYellow:
  7057.                 myColor = cOliveDrab1
  7058.             Case cOliveDrab1:
  7059.                 myColor = cLime
  7060.             Case cLime:
  7061.                 myColor = cMediumSpringGreen
  7062.             Case cMediumSpringGreen:
  7063.                 myColor = cCyan
  7064.             Case cCyan:
  7065.                 myColor = cDeepSkyBlue
  7066.             Case cDeepSkyBlue:
  7067.                 myColor = cDodgerBlue
  7068.             Case cDodgerBlue:
  7069.                 myColor = cSeaBlue
  7070.             Case cSeaBlue:
  7071.                 myColor = cBlue
  7072.             Case cBlue:
  7073.                 myColor = cBluePurple
  7074.             Case cBluePurple:
  7075.                 myColor = cDeepPurple
  7076.             Case cDeepPurple:
  7077.                 myColor = cPurple
  7078.             Case cPurple:
  7079.                 myColor = cPurpleRed
  7080.             Case Else:
  7081.                 myColor = cRed
  7082.         End Select
  7083.  
  7084.         ' 3, 11 = grayscale, ascending
  7085.     ElseIf colorScheme = 3 Or colorScheme = 11 Then
  7086.         Select Case myColor
  7087.             Case cBlack:
  7088.                 myColor = cDarkGray
  7089.             Case cDarkGray:
  7090.                 myColor = cDimGray
  7091.             Case cDimGray:
  7092.                 myColor = cGray
  7093.             Case cGray:
  7094.                 myColor = cLightGray
  7095.             Case cLightGray:
  7096.                 myColor = cSilver
  7097.             Case cSilver:
  7098.                 myColor = cWhite
  7099.             Case Else:
  7100.                 'myColor = cBlack
  7101.                 myColor = cSilver
  7102.  
  7103.                 ' go in the other direction!
  7104.                 If colorScheme = 3 Then
  7105.                     colorScheme = 4
  7106.                 Else
  7107.                     colorScheme = 12
  7108.                 End If
  7109.  
  7110.         End Select
  7111.  
  7112.         ' 4, 8, 12 = grayscale, descending
  7113.     ElseIf colorScheme = 4 Or colorScheme = 12 Then
  7114.         Select Case myColor
  7115.             Case cWhite:
  7116.                 myColor = cSilver
  7117.             Case cSilver:
  7118.                 myColor = cLightGray
  7119.             Case cLightGray:
  7120.                 myColor = cGray
  7121.             Case cGray:
  7122.                 myColor = cDimGray
  7123.             Case cDimGray:
  7124.                 myColor = cDarkGray
  7125.             Case cDarkGray:
  7126.                 myColor = cBlack
  7127.             Case Else:
  7128.                 myColor = cDarkGray
  7129.  
  7130.                 ' go in the other direction!
  7131.                 If colorScheme = 4 Then
  7132.                     colorScheme = 3
  7133.                 Else
  7134.                     colorScheme = 11
  7135.                 End If
  7136.         End Select
  7137.    
  7138.    
  7139.    
  7140. 'yoda
  7141.     ' =============================================================================
  7142.     ' BEGIN GreenTreeColors 20,21
  7143.     ' =============================================================================
  7144.     ' 20 = GetGreenTreeColors ascending
  7145.     ElseIf colorScheme = 20 Then
  7146.         GetGreenTreeColors ColorArray()
  7147.         iPos = FindInColorArray%(ColorArray(), myColor, 0)
  7148.         if iPos < ubound(ColorArray) then
  7149.             myColor = ColorArray(iPos+1)
  7150.         else
  7151.             myColor = ColorArray(iPos-1)
  7152.             colorScheme = 21 ' go in the other direction!
  7153.         end if
  7154.     ' 21 = GetGreenTreeColors descending
  7155.     ElseIf colorScheme = 21 Then
  7156.         GetGreenTreeColors ColorArray()
  7157.         iPos = FindInColorArray%(ColorArray(), myColor, 0)
  7158.         if iPos > lbound(ColorArray) then
  7159.             myColor = ColorArray(iPos-1)
  7160.         else
  7161.             myColor = ColorArray(iPos+1)
  7162.             colorScheme = 20 ' go in the other direction!
  7163.         end if
  7164.     ' =============================================================================
  7165.     ' END GreenTreeColors 20,21
  7166.     ' =============================================================================
  7167.     End If
  7168.  
  7169. End Sub ' DoCycleColor
  7170.  
  7171. Function FindInColorArray%(ColorArray() As _Unsigned Long, iColor As _Unsigned Long, iDefaultIfNotFound As Integer)
  7172.     Dim iLoop As Integer
  7173.     Dim bFound As Integer : bFound = FALSE
  7174.     For iLoop = lbound(ColorArray) to ubound(ColorArray)
  7175.         if ColorArray(iLoop) = iColor then
  7176.             bFound = TRUE
  7177.             FindInColorArray% = iLoop
  7178.             Exit For
  7179.         end if
  7180.     Next iLoop
  7181.     If bFound = FALSE Then
  7182.         FindInColorArray% = iDefaultIfNotFound
  7183.     End If
  7184. End Function ' FindInColorArray
  7185.  
  7186. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7187. ' END COLOR ROUTINES
  7188. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7189.  
  7190. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7191. ' BEGIN COLOR FUNCTIONS
  7192. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7193.  
  7194. ' NOTE: these are mostly negative numbers
  7195. '       and have to be forced to positive
  7196. '       when stored in the dictionary
  7197. '       (only cEmpty should be negative)
  7198.  
  7199. Function cRed~& ()
  7200.     cRed = _RGB32(255, 0, 0)
  7201.  
  7202. Function cOrangeRed~& ()
  7203.     cOrangeRed = _RGB32(255, 69, 0)
  7204. End Function ' cOrangeRed~&
  7205.  
  7206. Function cDarkOrange~& ()
  7207.     cDarkOrange = _RGB32(255, 140, 0)
  7208. End Function ' cDarkOrange~&
  7209.  
  7210. Function cOrange~& ()
  7211.     cOrange = _RGB32(255, 165, 0)
  7212. End Function ' cOrange~&
  7213.  
  7214. Function cGold~& ()
  7215.     cGold = _RGB32(255, 215, 0)
  7216. End Function ' cGold~&
  7217.  
  7218. Function cYellow~& ()
  7219.     cYellow = _RGB32(255, 255, 0)
  7220. End Function ' cYellow~&
  7221.  
  7222. ' LONG-HAIRED FRIENDS OF JESUS OR NOT,
  7223. ' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
  7224. ' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
  7225. Function cChartreuse~& ()
  7226.     cChartreuse = _RGB32(127, 255, 0)
  7227. End Function ' cChartreuse~&
  7228.  
  7229. ' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
  7230. Function cOliveDrab1~& ()
  7231.     cOliveDrab1 = _RGB32(192, 255, 62)
  7232. End Function ' cOliveDrab1~&
  7233.  
  7234. Function cLime~& ()
  7235.     cLime = _RGB32(0, 255, 0)
  7236. End Function ' cLime~&
  7237.  
  7238. Function cMediumSpringGreen~& ()
  7239.     cMediumSpringGreen = _RGB32(0, 250, 154)
  7240. End Function ' cMediumSpringGreen~&
  7241.  
  7242. Function cCyan~& ()
  7243.     cCyan = _RGB32(0, 255, 255)
  7244. End Function ' cCyan~&
  7245.  
  7246. Function cDeepSkyBlue~& ()
  7247.     cDeepSkyBlue = _RGB32(0, 191, 255)
  7248. End Function ' cDeepSkyBlue~&
  7249.  
  7250. Function cDodgerBlue~& ()
  7251.     cDodgerBlue = _RGB32(30, 144, 255)
  7252. End Function ' cDodgerBlue~&
  7253.  
  7254. Function cSeaBlue~& ()
  7255.     cSeaBlue = _RGB32(0, 64, 255)
  7256. End Function ' cSeaBlue~&
  7257.  
  7258. Function cBlue~& ()
  7259.     cBlue = _RGB32(0, 0, 255)
  7260. End Function ' cBlue~&
  7261.  
  7262. Function cBluePurple~& ()
  7263.     cBluePurple = _RGB32(64, 0, 255)
  7264. End Function ' cBluePurple~&
  7265.  
  7266. Function cDeepPurple~& ()
  7267.     cDeepPurple = _RGB32(96, 0, 255)
  7268. End Function ' cDeepPurple~&
  7269.  
  7270. Function cPurple~& ()
  7271.     cPurple = _RGB32(128, 0, 255)
  7272. End Function ' cPurple~&
  7273.  
  7274. Function cPurpleRed~& ()
  7275.     cPurpleRed = _RGB32(128, 0, 192)
  7276. End Function ' cPurpleRed~&
  7277.  
  7278. Function cDarkRed~& ()
  7279.     cDarkRed = _RGB32(160, 0, 64)
  7280. End Function ' cDarkRed~&
  7281.  
  7282. Function cBrickRed~& ()
  7283.     cBrickRed = _RGB32(192, 0, 32)
  7284. End Function ' cBrickRed~&
  7285.  
  7286. Function cDarkGreen~& ()
  7287.     cDarkGreen = _RGB32(0, 100, 0)
  7288. End Function ' cDarkGreen~&
  7289.  
  7290. Function cGreen~& ()
  7291.     cGreen = _RGB32(0, 128, 0)
  7292. End Function ' cGreen~&
  7293.  
  7294. Function cOliveDrab~& ()
  7295.     cOliveDrab = _RGB32(107, 142, 35)
  7296. End Function ' cOliveDrab~&
  7297.  
  7298. Function cLightPink~& ()
  7299.     cLightPink = _RGB32(255, 182, 193)
  7300. End Function ' cLightPink~&
  7301.  
  7302. Function cHotPink~& ()
  7303.     cHotPink = _RGB32(255, 105, 180)
  7304. End Function ' cHotPink~&
  7305.  
  7306. Function cDeepPink~& ()
  7307.     cDeepPink = _RGB32(255, 20, 147)
  7308. End Function ' cDeepPink~&
  7309.  
  7310. Function cMagenta~& ()
  7311.     cMagenta = _RGB32(255, 0, 255)
  7312. End Function ' cMagenta~&
  7313.  
  7314. Function cBlack~& ()
  7315.     cBlack = _RGB32(0, 0, 0)
  7316. End Function ' cBlack~&
  7317.  
  7318. Function cDimGray~& ()
  7319.     cDimGray = _RGB32(105, 105, 105)
  7320. End Function ' cDimGray~&
  7321.  
  7322. Function cGray~& ()
  7323.     cGray = _RGB32(128, 128, 128)
  7324. End Function ' cGray~&
  7325.  
  7326. Function cDarkGray~& ()
  7327.     cDarkGray = _RGB32(169, 169, 169)
  7328. End Function ' cDarkGray~&
  7329.  
  7330. Function cSilver~& ()
  7331.     cSilver = _RGB32(192, 192, 192)
  7332. End Function ' cSilver~&
  7333.  
  7334. Function cLightGray~& ()
  7335.     cLightGray = _RGB32(211, 211, 211)
  7336. End Function ' cLightGray~&
  7337.  
  7338. Function cGainsboro~& ()
  7339.     cGainsboro = _RGB32(220, 220, 220)
  7340. End Function ' cGainsboro~&
  7341.  
  7342. Function cWhiteSmoke~& ()
  7343.     cWhiteSmoke = _RGB32(245, 245, 245)
  7344. End Function ' cWhiteSmoke~&
  7345.  
  7346. Function cWhite~& ()
  7347.     cWhite = _RGB32(255, 255, 255)
  7348.     'cWhite = _RGB32(254, 254, 254)
  7349. End Function ' cWhite~&
  7350.  
  7351. Function cDarkBrown~& ()
  7352.     cDarkBrown = _RGB32(128, 64, 0)
  7353. End Function ' cDarkBrown~&
  7354.  
  7355. Function cLightBrown~& ()
  7356.     cLightBrown = _RGB32(196, 96, 0)
  7357. End Function ' cLightBrown~&
  7358.  
  7359. Function cKhaki~& ()
  7360.     cKhaki = _RGB32(240, 230, 140)
  7361. End Function ' cKhaki~&
  7362.  
  7363. Function cEmpty~& ()
  7364.     'cEmpty~& = -1
  7365.     cEmpty = _RGB32(0, 0, 0, 0)
  7366. End Function ' cEmpty~&
  7367.  
  7368. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7369. ' END COLOR FUNCTIONS
  7370. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7371.  
  7372. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7373. ' BEGIN CUSTOM COLOR FUNCTIONS
  7374. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7375.  
  7376. Sub GetGreenTreeColors ( ColorArray() As _Unsigned Long )
  7377.         ReDim ColorArray(-1) As _Unsigned Long
  7378.     AddColor ColorArray(), _RGB32(0, 71, 0)
  7379.     AddColor ColorArray(), _RGB32(0, 102, 0)
  7380.     AddColor ColorArray(), _RGB32(0, 153, 0)
  7381.     AddColor ColorArray(), _RGB32(0, 204, 0)
  7382.     AddColor ColorArray(), _RGB32(0, 255, 0)
  7383. End Sub ' GetGreenTreeColors
  7384.  
  7385. Sub AddColor (ColorArray() As _Unsigned Long, iColor As _Unsigned Long)
  7386.         ReDim _Preserve ColorArray(1 To UBound(ColorArray) + 1) As _Unsigned Long
  7387.         ColorArray(UBound(ColorArray)) = iColor
  7388. End Sub ' AddColor
  7389.  
  7390. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7391. ' END CUSTOM COLOR FUNCTIONS
  7392. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7393.  
  7394.  
  7395.  
  7396.  
  7397.  
  7398. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7399. ' BEGIN KEYBOARD CODE FUNCTIONS
  7400. ' NOTE: ALL CODES ARE FOR _BUTTON
  7401. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7402.  
  7403. Function KeyCode_CtrlLeft% ()
  7404.     KeyCode_CtrlLeft% = 30
  7405.  
  7406. Function KeyCode_CtrlRight% ()
  7407.     KeyCode_CtrlRight% = 286
  7408.  
  7409. Function KeyCode_Y% ()
  7410.     KeyCode_Y% = 22
  7411.  
  7412. Function KeyCode_Z% ()
  7413.     KeyCode_Z% = 45
  7414.  
  7415. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7416. ' END KEYBOARD CODE FUNCTIONS
  7417. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7418.  
  7419. ' #END
  7420. ' ################################################################################################################################################################
  7421.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: WIP: Isometric Demo re-revisited v3.01, showing animation
« Reply #1 on: December 29, 2021, 06:53:36 pm »
@madscijr Really nice, you even have accumulating snow!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: WIP: Isometric Demo re-revisited v3.01, showing animation
« Reply #2 on: December 29, 2021, 09:44:16 pm »
@madscijr Really nice, you even have accumulating snow!

Thanks, the snow wasn't too hard to do.
The difficult part was collecting all the pieces together! I had to learn how to plot circles, solid circles, etc. in 2D and then get them working in 3D! All those experiments are collected in this program https://qb64forum.alephc.xyz/index.php?topic=4502.15

I hacked the circle routine to return just a quarter portion (a curve) which I used to make the Christmas tree taper up (as we go higher, the radius follows the curve). It took a lot of experimenting to arrive at something that looked like a tree!

The hardest (and most frustrating) part had been trying to make a routine to free rotate the scene. I found a 2D shear rotation routine, and got all caught up in trying to get it to look better when rotating to multiples of 30 degrees (excluding multiples of 90) where at those angles a lot of points overlap and it looks really bad. The above link includes a bunch of those experiments. I took one algorithm that works ok, and tried converting it to 2.5D, so our little Christmas scene could rotate as the snow falls, but the rotation function just isn't working, and it's about time to get back to work, life, etc. Oh well!

Another thing I haven't yet wrapped my head around is how to render the scene in a simple first person (1 point perspective) view... I know people have posted some first person engines on here that I can learn from, but I feel like a fish out of water with 3D stuff.

Anyway that was all a distraction from putting some simple ornaments and lights on the tree! Next I need to take the circle routine and turn it into a sphere! And then a 3D line plotting function - it never ends!

Anyway I am glad you enjoyed it and thanks again for the kind words!