Author Topic: any idea why the color white is not visible?  (Read 5593 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
any idea why the color white is not visible?
« on: December 12, 2021, 04:00:08 pm »
I've got a little problem that has been driving me crazy.

This isometric 2.5D code (Exhibit A below) is working pretty good, except for one small problem -
it can't seem to draw the color white! Where white should be, there is only blank.

However, in a simple test on the isolated graphics routines (Exhibit B below), white appears just fine.

If anyone has a minute and could lend a second set of eyes, it would be much appreciated,
because I haven't be able to figure out what the problem is.

Exhibit A: the full program, works except can't draw white?
Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' #TOP
  3.  
  4. ' Isomatric mapping demo re-revisited
  5. ' Version 3.00.12 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. ' * Render cubes that block the view of the player as transparent.
  18. ' * 2-D top down "map" view of the player's current Z slice.
  19. ' * variable grid size
  20. ' * change arrMap to global shared variable (for simpler code) & rename m_arrMap
  21. ' * allow player to rotate their view
  22. ' * preliminary multiplayer changes
  23. '   - move player info into array (upto 4 players)
  24. '   - key mapping variables
  25. ' * fixed some keyboard input (repeating keys, continuous motion)
  26. ' * fixed right point of view bug where x & y coordinates were reversed
  27. ' * preliminary multiplayer changes
  28. '   - split screen display (4, 6, or 8?)
  29. '     + for now display player 1's world rotated in each window (for editor)
  30. '       * x4: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  31. '       * x6: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  32. '       * x8: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, (none), (none)
  33. '     + will eventually be one per player
  34. ' * 2D minimap background = cKhaki&
  35. ' * , and . change minimap size
  36.  
  37. ' -----------------------------------------------------------------------------
  38. ' TO DO:
  39. ' * editor v1 = simple drawing program
  40. '   - add type RecordType to hold recording steps
  41. '   - add array m_arrRecord of RecordType to hold recording
  42. '   - display available tiles/colors/etc. at bottom of screen
  43. '     + 26 colors including empty
  44. '     + 2 tiles (empty, wall)
  45. '   - cursor places tiles (ENTER = add/delete at current space)
  46. '   - 0-9 keys change colors/etc.
  47. '   - CTRL+Z, CTRL+Y UNDO & REDO ? (save levels of undo, or history of commands)
  48. '   - save screens to file (stored as editable text)
  49. '     + FORMAT: [tile=t][color@x,y,z][color@x,y,z][color@x,y,z]...
  50. '   - load screens into array m_arrRecord
  51. '     + PARSER:
  52. '       1. replace all ][ with [
  53. '       2. split by "[" into simple 1D array
  54. '       3. each element is either "tile=t" or "plot=color@x,y,z"
  55. '       4. parse data into array to playback recording
  56. '          [n][0] = command
  57. '                   -1 = select tile "tile=t"
  58. '                   0+ = color to plot "color@x,y,z"
  59. '          [n][1] = parameter #1 = tile
  60. '          [n][2] = parameter #2 = x
  61. '          [n][3] = parameter #3 = y
  62. '          [n][3] = parameter #4 = z
  63. '   - run commands in m_arrRecord to plot tiles and display
  64.  
  65. ' -----------------------------------------------------------------------------
  66. ' * rotating view changes orientation of keys (get it working)
  67.  
  68. ' * add parameters to tiles
  69. ' * - color scheme (for cycle colors)
  70.  
  71. ' * add tiles
  72. '   - transparent lights (blinking / cycle colors)
  73.  
  74. ' * editor v2 = simple animation program
  75. '   - records cursor movements and adding/deleting tiles
  76. '   - press key to record a "frame"
  77. '     + flash screen + play a sound
  78. '   - can change animation speed
  79. '   - realtime=on command enables redrawing screen every step (until realtime=off command encountered)
  80. '   - playback mode recreates editing actions
  81. '   - playback updates screen every "update"
  82. '   - tweak save format (still editable text)
  83. '     + FORMAT: [cls][rotate=d][speed=n][tile=t][color@x,y,z][tile=t][color@x,y,z][update][tile=t][color@x,y,z][realtime=on][tile=t][color@x,y,z]...
  84. '     + PARSER:
  85. '       1. replace all ][ with [
  86. '       2. split by "[" into simple 1D array
  87. '       3. each element is either "color@x,y,z", "tile=t", "cls", "update", "speed=s", "realtime=on", "realtime=off", "rotate=d"
  88. '       4. parse array into array of LONG for playback
  89. '          [n].Command
  90. '                   -7 = rotate point of view (up, down, left, right, back, forward) "rotate=d"
  91. '                   -6 = disable screen update every step "realtime=off"
  92. '                   -5 = enable screen update every step "realtime=on"
  93. '                   -4 = set speed "speed=s"
  94. '                   -3 = update screen "update"
  95. '                   -2 = clear screen "cls"
  96. '                   -1 = select tile "tile=t"
  97. '                   0+ = color to plot "color@x,y,z"
  98. '          [n].Param1 = parameter #1 = tile, speed, direction
  99. '          [n].Param2 = parameter #2 = x
  100. '          [n].Param3 = parameter #3 = y
  101. '          [n].Param4 = parameter #4 = z
  102. '   - effects of gravity (from bottom up, ie z=0 to z=max)
  103.  
  104. ' -----------------------------------------------------------------------------
  105. ' * expand world to bigger than screen (2.5d scrolling view)
  106.  
  107. ' * editor v3 = mouse
  108. '   - mouse movement controls cursor x,y position
  109. '   - mouse wheel controls z position
  110. '   - left click draws a tile
  111. '   - right click erases a tile
  112. '   - ENTER records a frame
  113. '   - Add animation playback command:
  114. '          [n][0] = command
  115. '                   -8 = enable user to rotate image in realtime with mouse? "mouse=on"
  116.  
  117. ' -----------------------------------------------------------------------------
  118. ' TO DO (LATER):
  119. ' * local multiplayer (2-4 players)
  120. '   - split screen (x2 or x4)
  121.  
  122. ' * fix/control screen placement/rendering/scroll boundaries for grid sizes
  123. '   (to not overwrite other players, go off screen, etc., when grid size changes)
  124.  
  125. ' * auto-rotate view depending on direction player is facing
  126.  
  127. ' * control the x/y/z slice axis, for a cutaway view
  128.  
  129. ' * gravity (players stay on ground, can fall)
  130. ' * player can climb up to next level if it is 1 tile higher
  131. ' * add ability to jump over 1 space
  132.  
  133. ' * option to remap keys
  134. ' * support game controllers
  135. ' * game controller calibration/mapping function
  136.  
  137. ' * option to hide objects out of player's line-of-sight
  138.  
  139. ' * show player as a stick figure (like "Realm of Impossibility")
  140. ' * walking movement
  141.  
  142. ' * add tiles (water, ladders, steps, ropes, windows, doors, etc.)
  143. ' * add toggle tiles - door "opens" when triggered
  144. ' * triggers
  145. ' * add tiles
  146. '   - Water = transparent blue)
  147. '   - Window = more transparent cyan)
  148.  
  149. ' * add directional tiles (can be rotated?)
  150. '   - ladder
  151. '   - bridge
  152. '   - hand-over-hand bars?
  153. '   - Slope45 = 45° slope <- 4 or 6 directions?
  154. '   - InvSlope45 = 45° inverted slope <- 4 or 6 directions?
  155. '   - Pyramid45 = 45° pyramid "cap stone" <- 4 or 6 directions?
  156. '   - ramp (player can walk up/down slope45)
  157.  
  158. ' * add ability to climb ladders + climbing animation
  159. ' * add ability to walk up ramps with smooth z-movement inbetween tiles
  160. ' * add ability to climb monkey bars (animation like lode runner)
  161.  
  162. ' * simultaneously show additional 1st person view
  163. ' * add ability for tilting head up/down in first person
  164.  
  165. ' * simple open world (players can add/remove tiles, build in real time)
  166. ' * make simple games (maze craze, capture the flag, snake, surround, 2.5d pong)
  167. ' * make more complex games (berzerk, lode runner, atari combat / tank)
  168. ' * make awesome complex games (2.5d lunar lander, atari adventure, asteroids, gravitar, etc.)
  169. ' * text adventure features (to create graphic Infocom or Scott Adams style games)
  170.  
  171. ' * for 2.5D animation program: independent animated objects?
  172. '   - 2.5D sprites?
  173. '     + animation sequence
  174. '     + motion path / algorithm
  175. '     + storage / library
  176. '     + multiple instances?
  177. '   - gravity? (tile falls if no tiles underneath)
  178.  
  179. ' ################################################################################################################################################################
  180.  
  181. ' =============================================================================
  182. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  183. ' div: int1% = num1% \ den1%
  184. ' mod: rem1% = num1% MOD den1%
  185.  
  186. ' -----------------------------------------------------------------------------
  187. ' boolean constants
  188. ' -----------------------------------------------------------------------------
  189. Const FALSE = 0
  190. Const TRUE = Not FALSE
  191.  
  192. ' -----------------------------------------------------------------------------
  193. ' KeyDownConstants
  194. ' -----------------------------------------------------------------------------
  195. Const c_iKeyDown_Esc = 27
  196. Const c_iKeyDown_F1 = 15104
  197. Const c_iKeyDown_F2 = 15360
  198. Const c_iKeyDown_F3 = 15616
  199. Const c_iKeyDown_F4 = 15872
  200. Const c_iKeyDown_F5 = 16128
  201. Const c_iKeyDown_F6 = 16384
  202. Const c_iKeyDown_F7 = 16640
  203. Const c_iKeyDown_F8 = 16896
  204. Const c_iKeyDown_F9 = 17152
  205. Const c_iKeyDown_F10 = 17408
  206. Const c_iKeyDown_Tilde = 96
  207. Const c_iKeyDown_1 = 49
  208. Const c_iKeyDown_2 = 50
  209. Const c_iKeyDown_3 = 51
  210. Const c_iKeyDown_4 = 52
  211. Const c_iKeyDown_5 = 53
  212. Const c_iKeyDown_6 = 54
  213. Const c_iKeyDown_7 = 55
  214. Const c_iKeyDown_8 = 56
  215. Const c_iKeyDown_9 = 57
  216. Const c_iKeyDown_0 = 48
  217. Const c_iKeyDown_Minus = 45
  218. Const c_iKeyDown_EqualPlus = 61
  219. Const c_iKeyDown_BkSp = 8
  220. Const c_iKeyDown_Ins = 20992
  221. Const c_iKeyDown_Home = 18176
  222. Const c_iKeyDown_PgUp = 18688
  223. Const c_iKeyDown_Del = 21248
  224. Const c_iKeyDown_End = 20224
  225. Const c_iKeyDown_PgDn = 20736
  226. Const c_iKeyDown_KEYPAD_7_Home = 18176
  227. Const c_iKeyDown_KEYPAD_8_Up = 18432
  228. Const c_iKeyDown_KEYPAD_9_PgUp = 18688
  229. Const c_iKeyDown_KEYPAD_4_Left = 19200
  230. Const c_iKeyDown_KEYPAD_6_Right = 19712
  231. Const c_iKeyDown_KEYPAD_1_End = 20224
  232. Const c_iKeyDown_KEYPAD_2_Down = 20480
  233. Const c_iKeyDown_KEYPAD_3_PgDn = 20736
  234. Const c_iKeyDown_KEYPAD_0_Ins = 20992
  235. Const c_iKeyDown_KEYPAD_Period_Del = 21248
  236. Const c_iKeyDown_Tab = 9
  237. Const c_iKeyDown_Q = 113
  238. Const c_iKeyDown_W = 119
  239. Const c_iKeyDown_E = 101
  240. Const c_iKeyDown_R = 114
  241. Const c_iKeyDown_T = 116
  242. Const c_iKeyDown_Y = 121
  243. Const c_iKeyDown_U = 117
  244. Const c_iKeyDown_Pipe = 105
  245. Const c_iKeyDown_O = 111
  246. Const c_iKeyDown_P = 112
  247. Const c_iKeyDown_BracketLeft = 91
  248. Const c_iKeyDown_BracketRight = 93
  249. Const c_iKeyDown_Backslash = 92
  250. Const c_iKeyDown_A = 97
  251. Const c_iKeyDown_S = 115
  252. Const c_iKeyDown_D = 100
  253. Const c_iKeyDown_F = 102
  254. Const c_iKeyDown_G = 103
  255. Const c_iKeyDown_H = 104
  256. Const c_iKeyDown_J = 106
  257. Const c_iKeyDown_K = 107
  258. Const c_iKeyDown_L = 108
  259. Const c_iKeyDown_SemiColon = 59
  260. Const c_iKeyDown_Apostrophe = 39
  261. Const c_iKeyDown_Enter = 13
  262. Const c_iKeyDown_Z = 22
  263. Const c_iKeyDown_X = 120
  264. Const c_iKeyDown_C = 99
  265. Const c_iKeyDown_V = 118
  266. Const c_iKeyDown_B = 98
  267. Const c_iKeyDown_N = 110
  268. Const c_iKeyDown_M = 109
  269. Const c_iKeyDown_Comma = 44
  270. Const c_iKeyDown_Period = 46
  271. Const c_iKeyDown_Slash = 47
  272. Const c_iKeyDown_Up = 18432
  273. Const c_iKeyDown_Left = 19200
  274. Const c_iKeyDown_Down = 20480
  275. Const c_iKeyDown_Right = 19712
  276. Const c_iKeyDown_Spacebar = 32
  277.  
  278. ' -----------------------------------------------------------------------------
  279. ' Constants for layers
  280. ' -----------------------------------------------------------------------------
  281. CONST cTerrainType = 1
  282. CONST cObjectsType = 2
  283. CONST cPlayersType = 3
  284.  
  285. ' -----------------------------------------------------------------------------
  286. ' Tile value constants for map (MapTileType.Typ)
  287. ' -----------------------------------------------------------------------------
  288. Const c_iTile_Empty = 0
  289. Const c_iTile_Floor = 1
  290. Const c_iTile_Wall = 2
  291. Const c_iTile_Water = 3
  292. Const c_iTile_Window = 4
  293. Const c_iTile_Player1 = 5
  294. Const c_iTile_Player2 = 6
  295. Const c_iTile_Player3 = 7
  296. Const c_iTile_Player4 = 8
  297. Const c_iTile_Blinking = 9
  298. Const c_iTile_Snow = 10
  299. Const c_iTile_Slope45 = 11
  300. Const c_iTile_InvSlope45 = 12
  301.  
  302. ' -----------------------------------------------------------------------------
  303. ' constants for 2.5D movement
  304. ' -----------------------------------------------------------------------------
  305. Const c_iDir_Down = 1
  306. Const c_iDir_Up = 2
  307. Const c_iDir_Left = 3
  308. Const c_iDir_Right = 4
  309. Const c_iDir_Back = 5
  310. Const c_iDir_Forward = 6
  311. Const c_iDir_Min = 1
  312. Const c_iDir_Max = 6
  313.  
  314. ' -----------------------------------------------------------------------------
  315. ' constants for drawing the 2.5D screen
  316. ' -----------------------------------------------------------------------------
  317. Const cGridOffsetX = 50
  318. Const cGridOffsetY = 50
  319. Const cGridOffsetZ = 0
  320. Const cScreenOffsetX = 500
  321. Const cScreenOffsetY = 300
  322. Const cScreenOffsetZ = 0
  323.  
  324. ' =============================================================================
  325. ' USER DEFINED TYPES
  326. ' =============================================================================
  327. Type MapTileType
  328.     Typ As Integer ' c_iTile_Empty, c_iTile_Floor, c_iTile_Wall, etc.
  329.     'Vis As Integer ' TRUE = visible, FALSE = don't render
  330.     'Lit As Long ' light offset
  331.     Color1 As Long ' main color
  332.     Color2 As Long ' secondary color if needed
  333.     Color3 As Long ' third color if needed
  334.     Alpha1 As Long ' transparency of tile Color1
  335.     Alpha2 As Long ' transparency of tile Color2
  336.     Alpha3 As Long ' transparency of tile Color3
  337.     AlphaOverride As Integer ' can be used to override alpha (255 treated as opaque)
  338. End Type ' MapTileType
  339.  
  340. Type RecordType
  341.     Command As Integer
  342.     Param1 As Integer
  343.     Param2 As Integer
  344.     Param3 As Integer
  345.     Param4 As Integer
  346. End Type ' RecordType
  347.  
  348. ' UDT TO HOLD THE INFO FOR A PLAYER
  349. TYPE PlayerType
  350.     IsEnabled AS Integer ' TRUE or FALSE
  351.     x AS Integer ' player x position
  352.     y AS Integer ' player y position
  353.     z AS Integer ' player z position
  354.     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
  355.     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
  356.     Tile1 As Long ' later we will instead use directional animation sequences
  357.    
  358.     Color1 As Long ' main color
  359.     'Color2 As Long ' secondary color if needed
  360.     'Color3 As Long ' third color if needed    
  361.    
  362.     Alpha1 As Long ' transparency of player Color1
  363.     'Alpha2 As Long ' transparency of player Color2
  364.     'Alpha3 As Long ' transparency of player Color3
  365.    
  366.     ColorScheme1 As Long ' for cycling colors
  367.     ColorSchemeSpeed1 As Long
  368.     ColorSchemeCount1 As Long
  369.    
  370.     'ColorScheme2 As Long ' for cycling colors
  371.     'ColorSchemeSpeed2 As Long
  372.     'ColorSchemeCount2 As Long
  373.    
  374.     'ColorScheme3 As Long ' for cycling colors
  375.     'ColorSchemeSpeed3 As Long
  376.     'ColorSchemeCount3 As Long
  377.    
  378.     AlphaOverride As Integer ' can be used to override alpha (0 treated as opaque)
  379.    
  380.     IsMoving As Integer ' TRUE/FALSE
  381.     IsMoved As Integer ' TRUE/FALSE
  382.    
  383.     GridSize As Integer
  384.     MapSize As Integer
  385.    
  386.     'hx AS Integer ' home base x position
  387.     'hy AS Integer ' home base y position
  388.     'ex AS Integer ' exit x position
  389.     'ey AS Integer ' exit y position
  390.     'wins AS Integer ' count # of wins
  391.     'points AS Long ' count points (more points for harder)
  392.     'difficulty AS Integer ' 1-5, from 1 (easiest, maze width 5) to 5 (hardest, maze width 1). Each win awards {difficulty} # of points.
  393.     'speed AS Integer ' the higher the faster
  394.     'delay AS Integer ' counter, player can move based on speed
  395.     'bit AS Integer ' bit value for masking player in map
  396.     'rows AS Integer ' # of rows in player's maze
  397.     'cols AS Integer ' # of columns in player's maze
  398. END TYPE ' PlayerType
  399.  
  400. ' KEY MAPPING v1
  401. ' UDT TO HOLD THE KEY MAPPINGS
  402. TYPE DirKeyMapType
  403.     KeyBack As Long
  404.     KeyForward As Long
  405.     KeyLeft As Long
  406.     KeyRight As Long
  407.     KeyUp As Long
  408.     KeyDown As Long
  409. END TYPE ' DirKeyMapType
  410.  
  411. ' SPLIT SCREEN OFFSETS
  412. TYPE SplitScreenType
  413.     GridOffsetX As Integer
  414.     GridOffsetY As Integer
  415.     GridOffsetZ As Integer
  416.     ScreenOffsetX As Integer
  417.     ScreenOffsetY As Integer
  418.     ScreenOffsetZ As Integer
  419. END TYPE ' SplitScreenType
  420.  
  421. ' =============================================================================
  422. ' GLOBAL VARIABLES
  423. Dim Shared m_ProgramPath$ : m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  424. Dim Shared m_ProgramName$ : m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  425. Dim Shared m_iGridSize As Integer : m_iGridSize = 8 ' BEFORE, < 10 wass causing problems with PAINT, but new method doesn't use PAINT, so nyah!
  426. Dim Shared m_iGridSizeMin As Integer : m_iGridSizeMin = 1
  427. Dim Shared m_iGridSizeMax As Integer : m_iGridSizeMax = 128
  428.  
  429. Dim Shared m_iMapMinX As Integer : m_iMapMinX = 0
  430. Dim Shared m_iMapMaxX As Integer : m_iMapMaxX = 32
  431. Dim Shared m_iMapMidX As Integer : m_iMapMidX = (m_iMapMaxX-m_iMapMinX)\2
  432. Dim Shared m_iMapMinY As Integer : m_iMapMinY = 0
  433. Dim Shared m_iMapMaxY As Integer : m_iMapMaxY = 32
  434. Dim Shared m_iMapMidY As Integer : m_iMapMidY = (m_iMapMaxY-m_iMapMinY)\2
  435. Dim Shared m_iMapMinZ As Integer : m_iMapMinZ = 0
  436. Dim Shared m_iMapMaxZ As Integer : m_iMapMaxZ = 32
  437. Dim Shared m_iMapMidZ As Integer : m_iMapMidZ = (m_iMapMaxZ-m_iMapMinZ)\2
  438.  
  439. Dim Shared m_iPlayerMin As Integer : m_iPlayerMin = 1
  440. Dim Shared m_iPlayerMax As Integer : m_iPlayerMax = 4
  441. Dim Shared m_iPlayerCount As Integer : m_iPlayerCount = 0
  442. Dim Shared m_iObjectCount As Integer : m_iObjectCount = 0 ' <- TO BE USED WHEN WE HAVE OBJECTS
  443.  
  444. ' Max # tiles in (32x32x32) world = 32,768
  445. ' Max # tiles for 16 (32x32x32) worlds = 524,288
  446. ' Max # tiles for 256 (32x32x32) worlds = 8,388,608
  447. Dim Shared m_iRecordMin As Long : m_iRecordMin = 0
  448. Dim Shared m_iRecordMax As Long : m_iRecordMax = 524288
  449.  
  450. Dim Shared m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  451. Dim Shared m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  452. Dim Shared m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  453. Dim Shared m_arrPlayer(m_iPlayerMin To m_iPlayerMax) As PlayerType
  454. Dim Shared m_arrRecord(m_iRecordMin To m_iRecordMax) As RecordType
  455.  
  456. ' For each player, map the 6 directional keys differently for each of the 6 directional orientations!
  457. Dim Shared m_arrDirKeyMap(m_iPlayerMin To m_iPlayerMax, c_iDir_Min To c_iDir_Max) As DirKeyMapType
  458.  
  459. ' Store offsets for splitscreen
  460. Dim Shared m_arrSplitScreen(m_iPlayerMin To m_iPlayerMax) As SplitScreenType
  461.  
  462. ' Store colors in an array
  463. Dim Shared m_arrColors(0 To 25) As Long
  464.  
  465. ' =============================================================================
  466. ' LOCAL VARIABLES
  467. Dim in$
  468.  
  469. ' ****************************************************************************************************************************************************************
  470. ' ACTIVATE DEBUGGING WINDOW
  471. _Echo "Started " + m_ProgramName$
  472. _Echo "Debugging on..."
  473. ' ****************************************************************************************************************************************************************
  474.  
  475. ' =============================================================================
  476. ' START THE MAIN ROUTINE
  477. main
  478.  
  479. ' =============================================================================
  480. ' FINISH
  481. System ' return control to the operating system
  482. Print m_ProgramName$ + " finished."
  483. Input "Press <ENTER> to continue", in$
  484.  
  485. ' ****************************************************************************************************************************************************************
  486. ' DEACTIVATE DEBUGGING WINDOW
  487. ' ****************************************************************************************************************************************************************
  488.  
  489.  
  490. ' /////////////////////////////////////////////////////////////////////////////
  491.  
  492. Sub main
  493.     Dim RoutineName as String : RoutineName = "main"
  494.     Dim in$
  495.     Dim result$
  496.    
  497.     Screen 0
  498.  
  499.     Do
  500.         Cls
  501.         Print m_ProgramName$
  502.         Print
  503.         Print "Isomatric Mapping Demo Re-visited"
  504.         Print "v3.00.12, by Softintheheadware (Dec, 2021)"
  505.         Print
  506.         'PRINT "CONTROLS: PRESS <ESC> TO RETURN TO MENU"
  507.         'PRINT "PLAYER  LEFT       RIGHT       UP        DOWN       "
  508.         'PRINT "1       CRSR LEFT  CRSR RIGHT  CRSR UP   CRSR DOWN  "
  509.         'PRINT "2       KEYPAD 4   KEYPAD 6    KEYPAD 8  KEYPAD 2   "
  510.         'PRINT "3       A          S           W         Z          "
  511.         'PRINT "4       J          K           I         M          "
  512.         'PRINT
  513.  
  514.         Print "1. (TBD)"
  515.         Print "2. (TBD)"
  516.         Print "3. (TBD)"
  517.         Print "4. BoxDrawTest1$ <- draws white OK"
  518.         Print "5. Draw in 2.5D! <- draws all colors except white(?)"
  519.         Print
  520.         Print "What to do? ('q' to exit)"
  521.  
  522.         Input in$: in$ = LCase$(Left$(in$, 1))
  523.  
  524.         If in$ = "1" Then
  525.             result$ = IsometricDemo1$
  526.         ElseIf in$ = "2" Then
  527.             result$ = IsometricDemo2$
  528.         ElseIf in$ = "3" Then
  529.             result$ = IsometricDemo3$
  530.         ElseIf in$ = "4" Then
  531.             result$ = BoxDrawTest1$
  532.         ElseIf in$ = "5" Then
  533.             result$ = IsometricDraw1$
  534.         End If
  535.        
  536.         If LEN(result$) > 0 Then
  537.             PRINT result$
  538.         End If
  539.        
  540.     Loop Until in$ = "q"
  541. End Sub ' main
  542.  
  543. ' /////////////////////////////////////////////////////////////////////////////
  544.  
  545. Function IsometricDemo1$
  546.     IsometricDemo1$ = "(TBD)"
  547. End Sub ' IsometricDemo1
  548.  
  549. ' /////////////////////////////////////////////////////////////////////////////
  550.  
  551. Function IsometricDemo2$
  552.     IsometricDemo2$ = "(TBD)"
  553. End Sub ' IsometricDemo2
  554.  
  555. ' /////////////////////////////////////////////////////////////////////////////
  556.  
  557. Function IsometricDemo3$
  558.     IsometricDemo3$ = "(TBD)"
  559. End Sub ' IsometricDemo3
  560.  
  561. ' /////////////////////////////////////////////////////////////////////////////
  562. ' Test all the values 0-255 for style
  563. ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  564.  
  565. Function BoxDrawTest1$
  566.     Dim in$
  567.     Dim iSize%
  568.     Dim iDrawX%
  569.     Dim iDrawY%
  570.     Dim iFromX%
  571.     Dim iFromY%
  572.     Dim iToX%
  573.     Dim iToY%
  574.     Dim iNextColor&
  575.     Dim iLoop As Integer
  576.     Dim iSpace%
  577.     Dim sError As String : sError = ""
  578.    
  579.     iSize% = 48 ' {n}x{n} pixels square
  580.     iDrawX% = 10
  581.     iDrawY% = 10
  582.     iNextColor& = cWhite&
  583.     iSpace% = 8
  584.     Screen _NewImage(1280, 1024, 32) : _ScreenMove 0,0
  585.     FOR iLoop = 0 TO 255
  586.         DrawStyledOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, iLoop
  587.         'DrawOutlineBox iDrawX%+1, iDrawY%+1, iSize%-2, iNextColor&, iLoop
  588.        
  589.         iDrawX% = iDrawX% + iSize% + iSpace%
  590.         IF iDrawX% > (1280 - (iSize% * 2)) THEN
  591.             iDrawX% = 10
  592.             iDrawY% = iDrawY% + iSize% + iSpace%
  593.            
  594.             IF iDrawY% > (1024 - (iSize% * 2)) THEN
  595.                 sError = "Ran out of Y space."
  596.                 EXIT FOR
  597.             END IF
  598.         END IF
  599.     NEXT iLoop
  600.    
  601.     IF LEN(sError)=0 THEN
  602.         FOR iLoop = 1 TO (iSize% \ 2)
  603.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, iLoop
  604.             iDrawX% = iDrawX% + iSize% + iSpace%
  605.             IF iDrawX% > (1280 - (iSize% * 2)) THEN
  606.                 iDrawX% = 10
  607.                 iDrawY% = iDrawY% + iSize% + iSpace%
  608.                 IF iDrawY% > (1024 - (iSize% * 2)) THEN
  609.                     sError = "Ran out of Y space."
  610.                     EXIT FOR
  611.                 END IF
  612.             END IF
  613.         NEXT iLoop
  614.     END IF
  615.    
  616.     LOCATE 58,1
  617.     IF LEN(sError) > 0 THEN
  618.         PRINT sError
  619.     END IF
  620.     INPUT "PRESS <ENTER> TO CONTINUE";in$
  621.    
  622.     WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  623.     SCREEN 0
  624.    
  625.     BoxDrawTest1$ = ""
  626. End Sub ' BoxDrawTest1$
  627.  
  628. ' /////////////////////////////////////////////////////////////////////////////
  629. ' Lets you draw a scene in 2.5D and save it to a file. Woo hoo!
  630.  
  631. ' Version 1 only supports 2 tile types:
  632. ' c_iTile_Empty
  633. ' c_iTile_Wall
  634.  
  635. Function IsometricDraw1$
  636.     Dim RoutineName As String: RoutineName = "IsometricDraw1"
  637.     Dim sResult AS String : sResult = ""
  638.     Dim sError As String: sError = ""
  639.     Dim iX%
  640.     Dim iY%
  641.     Dim iZ%
  642.     Dim iNewX%
  643.     Dim iNewY%
  644.     Dim iNewZ%
  645.     Dim iMyColor&
  646.     Dim iColorScheme%
  647.     Dim iDirection%
  648.     Dim bFound As Integer
  649.     DIM bDone As Integer
  650.     Dim in$
  651.     Dim iTotal% ' compute total available spaces
  652.     Dim iCount% ' count # of spaces searched
  653.     Dim bEnableRepeatingKeys As Integer
  654.     Dim iLastKey As Integer ' USED WHEN REPEATING KEYS DISABLED
  655.     Dim iLoop1 As Integer
  656.     Dim iLoop2 As Integer
  657.    
  658.     Dim iPosX1%
  659.     Dim iPosX2%
  660.     Dim iPosY1%
  661.     Dim iPosY2%
  662.     Dim iNextColor&
  663.     Dim iFirstColor&
  664.     Dim bContinue As Integer
  665.     Dim iLoopX%
  666.     Dim iLoopY%
  667.     Dim iLoopZ%
  668.     Dim iLevelCount%
  669.     Dim iLevelSize%
  670.    
  671.     Dim iDrawX%
  672.     Dim iDrawY%
  673.     Dim iSize%
  674.     Dim iOffsetY%
  675.    
  676.     Dim iPlayerLoop AS Integer
  677.     Dim iDirLoop AS Integer
  678.     Dim iNextX As Integer
  679.     Dim iNextY As Integer
  680.    
  681.     Dim iDrawColor%
  682.     Dim iCursorColor&
  683.    
  684.     Dim bIgnoreTerrain As Integer ' If TRUE, player can move through walls, etc.
  685.    
  686.     ' =============================================================================
  687.     ' GET OPTIONS
  688.     m_iPlayerCount = 1
  689.     'm_iPlayerCount = PromptForIntegerInRange%("How many players ({min}-{max} or blank to quit)?", 1, 4, 0)
  690.     'IF m_iPlayerCount = 0 THEN Goto CleanupAndExit
  691.     bEnableRepeatingKeys = FALSE
  692.    
  693.     ' =============================================================================
  694.     ' INITIALIZE GRAPHIC SCREEN
  695.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  696.     Screen _NewImage(1280, 1024, 32) : _ScreenMove 0,0
  697.    
  698.     m_arrSplitScreen(1).GridOffsetX = 50
  699.     m_arrSplitScreen(1).GridOffsetY = 50
  700.     m_arrSplitScreen(1).GridOffsetZ = 0
  701.     m_arrSplitScreen(1).ScreenOffsetX = 450
  702.     m_arrSplitScreen(1).ScreenOffsetY = 200
  703.     m_arrSplitScreen(1).ScreenOffsetZ = 0
  704.    
  705.     m_arrSplitScreen(2).GridOffsetX = 50
  706.     m_arrSplitScreen(2).GridOffsetY = 50
  707.     m_arrSplitScreen(2).GridOffsetZ = 0
  708.     m_arrSplitScreen(2).ScreenOffsetX = 1000
  709.     m_arrSplitScreen(2).ScreenOffsetY = 200
  710.     m_arrSplitScreen(2).ScreenOffsetZ = 0
  711.    
  712.     m_arrSplitScreen(3).GridOffsetX = 50
  713.     m_arrSplitScreen(3).GridOffsetY = 50
  714.     m_arrSplitScreen(3).GridOffsetZ = 0
  715.     m_arrSplitScreen(3).ScreenOffsetX = 450
  716.     m_arrSplitScreen(3).ScreenOffsetY = 700
  717.     m_arrSplitScreen(3).ScreenOffsetZ = 0
  718.    
  719.     m_arrSplitScreen(4).GridOffsetX = 50
  720.     m_arrSplitScreen(4).GridOffsetY = 50
  721.     m_arrSplitScreen(4).GridOffsetZ = 0
  722.     m_arrSplitScreen(4).ScreenOffsetX = 1000
  723.     m_arrSplitScreen(4).ScreenOffsetY = 700
  724.     m_arrSplitScreen(4).ScreenOffsetZ = 0
  725.    
  726.     ' -----------------------------------------------------------------------------
  727.     ' INITIALIZE MAP TO EMPTY
  728.     ClearIsometricMap
  729.    
  730.     ' -----------------------------------------------------------------------------
  731.     ' INITIALIZE COLOR ARRAY
  732.     m_arrColors( 0) = cEmpty&
  733.     m_arrColors( 1) = cBlack&
  734.     m_arrColors( 2) = cDarkGray&
  735.     m_arrColors( 3) = cDimGray&
  736.     m_arrColors( 4) = cGray&
  737.     m_arrColors( 5) = cLightGray&
  738.     m_arrColors( 6) = cSilver&
  739.     m_arrColors( 7) = cWhite&
  740.     m_arrColors( 8) = cRed&
  741.     m_arrColors( 9) = cOrangeRed&
  742.     m_arrColors(10) = cDarkOrange&
  743.     m_arrColors(11) = cOrange&
  744.     m_arrColors(12) = cGold&
  745.     m_arrColors(13) = cYellow&
  746.     m_arrColors(14) = cOliveDrab1&
  747.     m_arrColors(15) = cLime&
  748.     m_arrColors(16) = cMediumSpringGreen&
  749.     m_arrColors(17) = cCyan&
  750.     m_arrColors(18) = cDeepSkyBlue&
  751.     m_arrColors(19) = cDodgerBlue&
  752.     m_arrColors(20) = cSeaBlue&
  753.     m_arrColors(21) = cBlue&
  754.     m_arrColors(22) = cBluePurple&
  755.     m_arrColors(23) = cDeepPurple&
  756.     m_arrColors(24) = cPurple&
  757.     m_arrColors(25) = cPurpleRed&
  758.    
  759.     ' -----------------------------------------------------------------------------
  760.     ' INITIALIZE OTHER VARIABLES
  761.     bIgnoreTerrain = TRUE
  762.    
  763.     ' -----------------------------------------------------------------------------
  764.     ' DRAW FLOOR
  765.     For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  766.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  767.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  768.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor
  769.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cGray&
  770.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2 = cWhite& ' cLightGray&
  771.             Next iLoopY%
  772.         Next iLoopX%
  773.     Next iLoopZ%
  774.  
  775.     ' -----------------------------------------------------------------------------
  776.     ' DRAW A TALL HOLLOW PYRAMID
  777.     If TRUE = TRUE Then
  778.         iX% = 5
  779.         iY% = 10
  780.         iZ% = 1
  781.         iLevelSize% = 4
  782.        
  783.         iPosX1% = iX%
  784.         iPosX2% = iX% + 7
  785.         iPosY1% = iY%
  786.         iPosY2% = iY% + 7
  787.                
  788.         'iNextColor& = cRed&
  789.         'iColorScheme% = 1 ' 1 = Rainbow6 #1, 9 = Rainbow6 #2, etc.
  790.                
  791.                 iNextColor& = cWhite&
  792.                 iColorScheme% = 3 ' 3, 11 = grayscale, ascending
  793.                
  794.         iLevelCount% = 0
  795.        
  796.         bContinue = TRUE
  797.         Do
  798.             ' Draw front/back walls
  799.             For iLoopX% = iPosX1% To iPosX2%
  800.                 iLoopY% = iPosY1%
  801.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  802.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  803.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  804.                
  805.                 iLoopY% = iPosY2%
  806.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  807.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  808.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  809.             Next iLoopX%
  810.            
  811.             ' Draw left/right walls
  812.             For iLoopY% = iPosY1% To iPosY2%
  813.                 iLoopX% = iPosX1%
  814.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  815.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  816.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  817.                
  818.                 iLoopX% = iPosX2%
  819.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  820.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  821.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  822.             Next iLoopY%
  823.            
  824.             ' Add a door to middle of right wall
  825.             iX% = iPosX1% + ( (iPosX2% - iPosX1%) \ 2)
  826.             m_arrMap(iX%, iPosY2%, iZ%).Typ = c_iTile_Empty
  827.            
  828.             ' Add a door to middle of front wall
  829.             iY% = iPosY1% + ( (iPosY2% - iPosY1%) \ 2)
  830.             m_arrMap(iPosX2%, iY%, iZ%).Typ = c_iTile_Empty
  831.            
  832.             ' MOVE UP A LEVEL
  833.             iLevelCount% = iLevelCount% + 1
  834.             IF iLevelCount% > iLevelSize% THEN
  835.                 iLevelCount% = 0
  836.                 iPosX1% = iPosX1% + 1
  837.                 iPosX2% = iPosX2% - 1
  838.                 iPosY1% = iPosY1% + 1
  839.                 iPosY2% = iPosY2% - 1
  840.             END IF
  841.            
  842.             ' QUIT AFTER WE REACH THE TOP
  843.             If (iPosX1% <= iPosX2%) And (iPosY1% <= iPosY2%) Then
  844.                 iZ% = iZ% + 1
  845.                 DoCycleColor iColorScheme%, iNextColor&
  846.                 If iZ% > m_iMapMaxZ Then
  847.                     bContinue = FALSE
  848.                 End If
  849.             Else
  850.                 bContinue = FALSE
  851.             End If
  852.            
  853.         Loop Until bContinue = FALSE
  854.     End If    
  855.    
  856.     ' -----------------------------------------------------------------------------
  857.     ' DRAW FRAME AROUND ENTIRE SPACE (TOP)
  858.    
  859.     FOR iLoopX% = m_iMapMinX+3 TO m_iMapMaxX-3
  860.         m_arrMap(iLoopX%, m_iMapMaxY-3, m_iMapMaxZ).Typ = c_iTile_Wall
  861.         m_arrMap(iLoopX%, m_iMapMaxY-3, m_iMapMaxZ).Color1 = cWhite& ' cPurple&
  862.        
  863.         m_arrMap(iLoopX%, m_iMapMinY+3, m_iMapMaxZ).Typ = c_iTile_Wall
  864.         m_arrMap(iLoopX%, m_iMapMinY+3, m_iMapMaxZ).Color1 = cCyan&
  865.     NEXT iLoopX%
  866.    
  867.     FOR iLoopY% = m_iMapMinY+3 TO m_iMapMaxY-3
  868.         m_arrMap(m_iMapMinX+3, iLoopY%, m_iMapMaxZ).Typ = c_iTile_Wall
  869.         m_arrMap(m_iMapMinX+3, iLoopY%, m_iMapMaxZ).Color1 = cOrange&
  870.        
  871.         m_arrMap(m_iMapMaxX-3, iLoopY%, m_iMapMaxZ).Typ = c_iTile_Wall
  872.         m_arrMap(m_iMapMaxX-3, iLoopY%, m_iMapMaxZ).Color1 = cLime&
  873.     NEXT iLoopY%
  874.    
  875.     ' -----------------------------------------------------------------------------
  876.     ' DRAW FRAME AROUND ENTIRE SPACE (MIDDLE)
  877.    
  878.     FOR iLoopX% = m_iMapMinX+2 TO m_iMapMaxX-2
  879.         m_arrMap(iLoopX%, m_iMapMaxY-2, m_iMapMidZ).Typ = c_iTile_Wall
  880.         m_arrMap(iLoopX%, m_iMapMaxY-2, m_iMapMidZ).Color1 = cWhite& ' cDodgerBlue&
  881.        
  882.         m_arrMap(iLoopX%, m_iMapMinY+2, m_iMapMidZ).Typ = c_iTile_Wall
  883.         m_arrMap(iLoopX%, m_iMapMinY+2, m_iMapMidZ).Color1 = cDeepPurple&
  884.     NEXT iLoopX%
  885.    
  886.     FOR iLoopY% = m_iMapMinY+2 TO m_iMapMaxY-2
  887.         m_arrMap(m_iMapMinX+2, iLoopY%, m_iMapMidZ).Typ = c_iTile_Wall
  888.         m_arrMap(m_iMapMinX+2, iLoopY%, m_iMapMidZ).Color1 = cDarkRed&
  889.        
  890.         m_arrMap(m_iMapMaxX-2, iLoopY%, m_iMapMidZ).Typ = c_iTile_Wall
  891.         m_arrMap(m_iMapMaxX-2, iLoopY%, m_iMapMidZ).Color1 = cGold&
  892.     NEXT iLoopY%
  893.    
  894.     ' -----------------------------------------------------------------------------
  895.     ' DRAW FRAME AROUND ENTIRE SPACE (BOTTOM)
  896.    
  897.     FOR iLoopX% = m_iMapMinX+1 TO m_iMapMaxX-1
  898.         m_arrMap(iLoopX%, m_iMapMaxY-1, m_iMapMinZ+1).Typ = c_iTile_Wall
  899.         m_arrMap(iLoopX%, m_iMapMaxY-1, m_iMapMinZ+1).Color1 = cWhite& ' cSeaBlue&
  900.        
  901.         m_arrMap(iLoopX%, m_iMapMinY+1, m_iMapMinZ+1).Typ = c_iTile_Wall
  902.         m_arrMap(iLoopX%, m_iMapMinY+1, m_iMapMinZ+1).Color1 = cChartreuse&
  903.     NEXT iLoopX%
  904.    
  905.     FOR iLoopY% = m_iMapMinY+1 TO m_iMapMaxY-1
  906.         m_arrMap(m_iMapMinX+1, iLoopY%, m_iMapMinZ+1).Typ = c_iTile_Wall
  907.         m_arrMap(m_iMapMinX+1, iLoopY%, m_iMapMinZ+1).Color1 = cOrangeRed&
  908.        
  909.         m_arrMap(m_iMapMaxX-1, iLoopY%, m_iMapMinZ+1).Typ = c_iTile_Wall
  910.         m_arrMap(m_iMapMaxX-1, iLoopY%, m_iMapMinZ+1).Color1 = cDeepSkyBlue&
  911.     NEXT iLoopY%
  912.    
  913.     ' =============================================================================
  914.     ' PLACE PLAYER(S) <- ONLY ONE FOR THIS DEMO
  915.    
  916.     FOR iPlayerLoop = 1 TO m_iPlayerCount
  917.        
  918.         ' -----------------------------------------------------------------------------
  919.         ' BEGIN Map the 6 directional keys
  920.         ' -----------------------------------------------------------------------------
  921.         '*** CURRENTLY THIS IS NOT USED ***
  922.         'TODO: GET THIS WORKING (CURRENTLY IT'S ALL WEIRD)
  923.         'TODO: WHATEVER THE KEYS MAPPED ARE, SWAP THEM NON-HARDCODED
  924.        
  925.         ' differently for each of the 6 directional orientations!
  926.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyBack = c_iKeyDown_Down
  927.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyForward = c_iKeyDown_Up
  928.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyLeft = c_iKeyDown_Left
  929.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyRight = c_iKeyDown_Right
  930.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyUp = c_iKeyDown_PgDn
  931.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyDown = c_iKeyDown_PgUp
  932.        
  933.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyBack = c_iKeyDown_PgDn
  934.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyForward = c_iKeyDown_PgUp
  935.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyLeft = c_iKeyDown_Left
  936.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyRight = c_iKeyDown_Right
  937.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyUp = c_iKeyDown_Up
  938.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyDown = c_iKeyDown_Down
  939.        
  940.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyBack = c_iKeyDown_Right
  941.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyForward = c_iKeyDown_Left
  942.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyLeft = c_iKeyDown_Down
  943.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyRight = c_iKeyDown_Up
  944.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyUp = c_iKeyDown_PgUp
  945.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyDown = c_iKeyDown_PgDn
  946.        
  947.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyBack = c_iKeyDown_Left
  948.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyForward = c_iKeyDown_Right
  949.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyLeft = c_iKeyDown_Up
  950.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyRight = c_iKeyDown_Down
  951.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyUp = c_iKeyDown_PgUp
  952.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyDown = c_iKeyDown_PgDn
  953.        
  954.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyBack = c_iKeyDown_Down
  955.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyForward = c_iKeyDown_Up
  956.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyLeft = c_iKeyDown_Right
  957.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyRight = c_iKeyDown_Left
  958.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyUp = c_iKeyDown_PgUp
  959.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyDown = c_iKeyDown_PgDn
  960.        
  961.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyBack = c_iKeyDown_Up
  962.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyForward = c_iKeyDown_Down
  963.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyLeft = c_iKeyDown_Left
  964.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyRight = c_iKeyDown_Right
  965.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyUp = c_iKeyDown_PgUp
  966.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyDown = c_iKeyDown_PgDn
  967.         ' -----------------------------------------------------------------------------
  968.         ' END Map the 6 directional keys
  969.         ' -----------------------------------------------------------------------------
  970.        
  971.         ' FIND START POSITION
  972.         iX% = RandomNumber(m_iMapMinX, m_iMapMaxX)
  973.         iY% = RandomNumber(m_iMapMinY, m_iMapMaxY)
  974.         iZ% = 1 ' RandomNumber(m_iMapMinZ, m_iMapMaxZ)
  975.        
  976.         ' MAKE SURE IT'S EMPTY
  977.         IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  978.             bFound = TRUE
  979.         ELSE
  980.             ' IF NOT EMPTY THEN TRY TO FIND AN EMPTY SPOT
  981.             iTotal% = ((m_iMapMaxX - m_iMapMinX)+1) * ((m_iMapMaxY - m_iMapMinY)+1) * ((m_iMapMaxZ - m_iMapMinZ)+1)
  982.             iCount% = 0
  983.             bFound = FALSE
  984.             Do
  985.                 iX% = iX% + 1
  986.                 if iX% > m_iMapMaxX then
  987.                     ' reset x and move to next y
  988.                     iX% = m_iMapMinX
  989.                     iY% = iY% + 1
  990.                     if iY% > m_iMapMaxY then
  991.                         ' reset y and move to next z
  992.                         iY% = m_iMapMinY
  993.                         iZ% = iZ% + 1
  994.                         if iZ% > m_iMapMaxZ then
  995.                             ' RESET Z AND SEE IF WE HAVE CHECKED EVERYTHING
  996.                             iZ% = m_iMapMinZ
  997.                             iCount% = iCount% + 1
  998.                             if iCount% >= iTotal% then
  999.                                 ' NONE FOUND, EXIT
  1000.                                 Exit Do
  1001.                             end if
  1002.                         else
  1003.                             iCount% = iCount% + 1
  1004.                         end if
  1005.                     else
  1006.                         iCount% = iCount% + 1
  1007.                     end if
  1008.                 else
  1009.                     iCount% = iCount% + 1
  1010.                 end if
  1011.                 IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  1012.                     ' FOUND AN EMPTY SPACE, EXIT
  1013.                     bFound = TRUE
  1014.                     Exit Do
  1015.                 END IF
  1016.             Loop
  1017.         END IF
  1018.        
  1019.         If bFound = TRUE THEN
  1020.             ' PICK A DIRECTION (SIMPLE FOR NOW, LEFT OR RIGHT)
  1021.             if iX% <= m_iMapMidX then
  1022.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1023.             else
  1024.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1025.             end if
  1026.            
  1027.             m_arrPlayer(iPlayerLoop).Tile1 = c_iTile_Player1
  1028.            
  1029.             ' SAVE COORDINATES TO PLAYER
  1030.             ' ****************************************************************************************************************************************************************
  1031.             ' for this demo we'll just use iX% instead of m_arrPlayer(iPlayerLoop).x, etc.
  1032.             ' to make it more readable
  1033.             ' ****************************************************************************************************************************************************************
  1034.             m_arrPlayer(iPlayerLoop).x = iX%
  1035.             m_arrPlayer(iPlayerLoop).y = iY%
  1036.             m_arrPlayer(iPlayerLoop).z = iZ%
  1037.             m_arrPlayer(iPlayerLoop).View = c_iDir_Forward
  1038.             m_arrPlayer(iPlayerLoop).Color1 = cRed&
  1039.             m_arrPlayer(iPlayerLoop).Alpha1 = 255
  1040.             m_arrPlayer(iPlayerLoop).AlphaOverride = 255
  1041.             m_arrPlayer(iPlayerLoop).ColorScheme1 = 2
  1042.             m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 = 5 ' change color every 5 frames
  1043.             m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  1044.            
  1045.             ' DISPLAY OPTIONS
  1046.             m_arrPlayer(iPlayerLoop).GridSize = 8
  1047.             m_arrPlayer(iPlayerLoop).MapSize = 4
  1048.            
  1049.             ' RESET MOVEMENT VARIABLES
  1050.             m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  1051.             m_arrPlayer(iPlayerLoop).IsMoved = FALSE
  1052.            
  1053.             ' ********************************************************************************
  1054.             ' *** THIS IS NOW DONE AT THE RENDERING LEVEL FOR PLAYERS AND NON-TERRAIN OBJECTS
  1055.             ' ********************************************************************************
  1056.             '' DRAW PLAYER
  1057.             'm_arrMap(iX%, iY%, iZ%).Typ = m_arrPlayer(iPlayerLoop).Tile1
  1058.             'm_arrMap(iX%, iY%, iZ%).Color1 = m_arrPlayer(iPlayerLoop).Color1
  1059.             'm_arrMap(iX%, iY%, iZ%).AlphaOverride = m_arrPlayer(iPlayerLoop).Alpha1
  1060.            
  1061.         Else
  1062.             sError = "Could not find an empty space to start player."    
  1063.             Exit For
  1064.         End If
  1065.        
  1066.     NEXT iPlayerLoop
  1067.    
  1068.     ' =============================================================================
  1069.     ' OTHER SETUP
  1070.     If Len(sError)=0 Then
  1071.         ' RESET INPUT
  1072.         WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  1073.         iLastKey = c_iKeyDown_Enter
  1074.     End If
  1075.    
  1076.     ' =============================================================================
  1077.     ' MAIN LOOP
  1078.     If Len(sError)=0 Then
  1079.         iDrawColor% = 8 ' RED
  1080.         iCursorColor& = cRed&
  1081.         bFinished = FALSE
  1082.         Do
  1083.             CLS ' is cls necessary?
  1084.            
  1085.             ' SHOW INSTRUCTIONS / COORDINATES ON SCREEN
  1086.             LOCATE  1, 3: PRINT "IsometricDraw1"
  1087.             LOCATE  3, 3: PRINT "CRSR RT/LF MOVES X = " + CSTR$(iX%)
  1088.             LOCATE  4, 3: PRINT "CRSR UP/DN MOVES Y = " + CSTR$(iY%)
  1089.             LOCATE  5, 3: PRINT "PAGE UP/DN MOVES Z = " + CSTR$(iZ%)
  1090.             LOCATE  6, 3: PRINT "=    / -   CHANGES GRID SIZE     = " + CSTR$(m_arrPlayer(1).GridSize)
  1091.             LOCATE  7, 3: PRINT "[    / ]   TOGGLES MOVEMENT      = " + IIFSTR$(m_arrPlayer(1).IsMoving, "TRUE", "FALSE")
  1092.             LOCATE  8, 3: PRINT "INS  / DEL TOGGLES REPEAT KEYS   = " + IIFSTR$(bEnableRepeatingKeys, "TRUE", "FALSE")
  1093.             LOCATE  9, 3: PRINT ",    / .   CHANGES MINI MAP SIZE = " + CSTR$(m_arrPlayer(1).MapSize)
  1094.            
  1095.             LOCATE 12, 3: PRINT "PRESS <ESC> TO QUIT"
  1096.            
  1097.             LOCATE 25, 10: PRINT "1 color-"
  1098.             LOCATE 26, 10: PRINT "2 color+"
  1099.             LOCATE 27, 10: PRINT "3 draw"
  1100.             LOCATE 28, 10: PRINT "4 erase"
  1101.             LOCATE 29, 10: PRINT "5 toggle"
  1102.             LOCATE 30, 10: PRINT "6 eyedropper"
  1103.             LOCATE 31, 10: PRINT "7 clear"
  1104.             LOCATE 32, 10: PRINT "8 open"
  1105.             LOCATE 33, 10: PRINT "9 save"
  1106.            
  1107.             ' ****************************************************************************************************************************************************************
  1108.             ' BEGIN DRAW PALETTE
  1109.             ' ****************************************************************************************************************************************************************
  1110.             'TODO: support variable screen resolutions instead of hardcoded 1280x1024
  1111.             iSize% = 24 ' {n}x{n} pixels square
  1112.             iDrawX% = 10
  1113.             iOffsetY% = 350
  1114.             FOR iLoop1 = 0 TO 25
  1115.                 iDrawY% = iOffsetY%+(iLoop1 * iSize%)
  1116.                 IF iLoop1 = 0 THEN
  1117.                     ' COLOR = TRANSPARENT
  1118.                    
  1119.                     ' DRAW A CHECKERBOARD PATTERN FOR TRANSPARENT
  1120.                     iFirstColor& = cDarkGray&
  1121.                     FOR iLoopY% = iDrawY% TO ((iDrawY% + iSize%)-4) STEP 4
  1122.                         IF iFirstColor& = cDarkGray& THEN
  1123.                             iFirstColor& = cGray&
  1124.                         ELSE
  1125.                             iFirstColor& = cDarkGray&
  1126.                         END IF
  1127.                         iNextColor& = iFirstColor&
  1128.                         FOR iLoopX% = iDrawX% TO ((iDrawX% + iSize%)-4) STEP 4
  1129.                             DrawBox iLoopX%, iLoopY%, 4, iNextColor&
  1130.                             IF iNextColor& = cDarkGray& THEN
  1131.                                 iNextColor& = cGray&
  1132.                             ELSE
  1133.                                 iNextColor& = cDarkGray&
  1134.                             END IF
  1135.                         NEXT iLoopX%
  1136.                     NEXT iLoopY%
  1137.                 ELSEIF iLoop1 = 1 THEN
  1138.                     ' COLOR = BLACK
  1139.                 ELSE
  1140.                     iNextColor& = m_arrColors(iLoop1)
  1141.                     DrawBox iDrawX%, iDrawY%, iSize%, iNextColor&
  1142.                 END IF
  1143.                
  1144.                 ' DRAW A BORDER AROUND IT
  1145.                 iNextColor& = cDarkGray&
  1146.                 DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, 1
  1147.             NEXT iLoop1
  1148.            
  1149.             ' DRAW WHITE BOX AROUND CURRENT COLOR
  1150.             DoCycleColor 1, iCursorColor&
  1151.             iDrawY% = iOffsetY%+(iDrawColor% * iSize%)
  1152.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iCursorColor&, 1
  1153.             ' ****************************************************************************************************************************************************************
  1154.             ' END DRAW PALETTE
  1155.             ' ****************************************************************************************************************************************************************
  1156.            
  1157.            
  1158.            
  1159.            
  1160.            
  1161.             ' ****************************************************************************************************************************************************************
  1162.             ' BEGIN PLAYER LOOP
  1163.             ' ****************************************************************************************************************************************************************
  1164.             DrawScreen c_iDir_Forward, m_arrSplitScreen(1).ScreenOffsetX, m_arrSplitScreen(1).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1165.             DrawScreen c_iDir_Back,    m_arrSplitScreen(2).ScreenOffsetX, m_arrSplitScreen(2).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1166.             DrawScreen c_iDir_Left,    m_arrSplitScreen(3).ScreenOffsetX, m_arrSplitScreen(3).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1167.             DrawScreen c_iDir_Right,   m_arrSplitScreen(4).ScreenOffsetX, m_arrSplitScreen(4).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1168.            
  1169.             FOR iPlayerLoop = 1 TO m_iPlayerCount
  1170.                 'DrawScreen m_arrPlayer(iPlayerLoop).View, cScreenOffsetX, cScreenOffsetY, iX%, iY%, iZ%
  1171.                
  1172.                 ' -----------------------------------------------------------------------------
  1173.                 ' BEGIN SHOW 2D MINI MAP ON SCREEN
  1174.                 ' -----------------------------------------------------------------------------
  1175.                 ' TODO: FOR MULTIPLAYER, DRAW A SEPARATE MAP PER PLAYER TO SPLIT SCREEN
  1176.                 FOR iLoopX% = m_iMapMinX TO m_iMapMaxX
  1177.                     FOR iLoopY% = m_iMapMinY TO m_iMapMaxY
  1178.                         'iDrawX% = (iLoopX% * 4) + 20
  1179.                         iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + 20
  1180.                        
  1181.                         'iDrawY% = (iLoopY% * 4) + 200
  1182.                         iDrawY% = (iLoopY% * m_arrPlayer(1).MapSize) + 200
  1183.                        
  1184.                         IF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall THEN
  1185.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1186.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1187.                            
  1188.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player1 THEN
  1189.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1190.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1191.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player2 THEN
  1192.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1193.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1194.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player3 THEN
  1195.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1196.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1197.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player4 THEN
  1198.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1199.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1200.                            
  1201.                         'TODO: ADD OTHER TYPES
  1202.                        
  1203.                         ELSE
  1204.                             'DrawBox iDrawX%, iDrawY%, 4, cBlack&
  1205.                             'DrawBox iDrawX%, iDrawY%, 4, cKhaki&
  1206.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki&
  1207.                         END IF
  1208.                     NEXT iLoopY%
  1209.                 NEXT iLoopX%
  1210.                                
  1211.                                 ' DRAW THE PLAYERS ON THE MINI MAP
  1212.                                 For iLoop1 = m_iPlayerMin To m_iPlayerCount
  1213.                                         iDrawX% = (m_arrPlayer(iLoop1).x * m_arrPlayer(1).MapSize) + 20
  1214.                                         iDrawY% = (m_arrPlayer(iLoop1).y * m_arrPlayer(1).MapSize) + 200
  1215.                                        
  1216.                                         ' TODO: ADD Alpha PARAMETER TO DrawBox
  1217.                                         DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrPlayer(iLoop1).Color1
  1218.                                 Next iLoop1
  1219.                                
  1220.                                 ' DRAW THE OBJECTS ON THE MINI MAP
  1221.                                 ' (TO DO WHEN WE ADD OBJECTS)
  1222.                                
  1223.                 ' -----------------------------------------------------------------------------
  1224.                 ' END SHOW 2D MINI MAP ON SCREEN
  1225.                 ' -----------------------------------------------------------------------------
  1226.                
  1227.                
  1228.                 ' -----------------------------------------------------------------------------
  1229.                 ' BEGIN GET DIRECTIONAL KEYBOARD INPUT
  1230.                 ' -----------------------------------------------------------------------------
  1231.                 If _KeyDown(c_iKeyDown_Up) Then
  1232.                     If iLastKey <> c_iKeyDown_Up OR bEnableRepeatingKeys=TRUE Then
  1233.                         iLastKey = c_iKeyDown_Up
  1234.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  1235.                         bMoved = TRUE
  1236.                     End If
  1237.                 ElseIf _KeyDown(c_iKeyDown_Down) Then
  1238.                     If iLastKey <> c_iKeyDown_Down OR bEnableRepeatingKeys=TRUE Then
  1239.                         iLastKey = c_iKeyDown_Down
  1240.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  1241.                         bMoved = TRUE
  1242.                     End If
  1243.                 ElseIf _KeyDown(c_iKeyDown_Left) Then
  1244.                     If iLastKey <> c_iKeyDown_Left OR bEnableRepeatingKeys=TRUE Then
  1245.                         iLastKey = c_iKeyDown_Left
  1246.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1247.                         bMoved = TRUE
  1248.                     End If
  1249.                 ElseIf _KeyDown(c_iKeyDown_Right) Then
  1250.                     If iLastKey <> c_iKeyDown_Right OR bEnableRepeatingKeys=TRUE Then
  1251.                         iLastKey = c_iKeyDown_Right
  1252.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1253.                         bMoved = TRUE
  1254.                     End If
  1255.                 ElseIf _KeyDown(c_iKeyDown_PgUp) Then
  1256.                     If iLastKey <> c_iKeyDown_PgUp OR bEnableRepeatingKeys=TRUE Then
  1257.                         iLastKey = c_iKeyDown_PgUp
  1258.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  1259.                         bMoved = TRUE
  1260.                     End If
  1261.                 ElseIf _KeyDown(c_iKeyDown_PgDn) Then
  1262.                     If iLastKey <> c_iKeyDown_PgDn OR bEnableRepeatingKeys=TRUE Then
  1263.                         iLastKey = c_iKeyDown_PgDn
  1264.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  1265.                         bMoved = TRUE
  1266.                     End If                
  1267.                 ' -----------------------------------------------------------------------------
  1268.                 ' END GET DIRECTIONAL KEYBOARD INPUT
  1269.                 ' -----------------------------------------------------------------------------
  1270.                
  1271.                
  1272.                 ' -----------------------------------------------------------------------------
  1273.                 ' BEGIN GET DRAWING INPUT
  1274.                 ' -----------------------------------------------------------------------------
  1275.                 ' 1 color-
  1276.                 ElseIf _KeyDown(c_iKeyDown_1) Then
  1277.                     If iLastKey <> c_iKeyDown_1 OR bEnableRepeatingKeys=TRUE Then
  1278.                         iLastKey = c_iKeyDown_1
  1279.                        
  1280.                         iDrawColor% = iDrawColor% - 1
  1281.                         IF iDrawColor% < 0 THEN
  1282.                             iDrawColor% = 25
  1283.                         END IF
  1284.                     End If
  1285.                    
  1286.                 ' 2 color+
  1287.                 ElseIf _KeyDown(c_iKeyDown_2) Then
  1288.                     If iLastKey <> c_iKeyDown_2 OR bEnableRepeatingKeys=TRUE Then
  1289.                         iLastKey = c_iKeyDown_2
  1290.                        
  1291.                         iDrawColor% = iDrawColor% + 1
  1292.                         IF iDrawColor% > 25 THEN
  1293.                             iDrawColor% = 0
  1294.                         END IF
  1295.                     End If
  1296.                    
  1297.                 ' 3 draw
  1298.                 ElseIf _KeyDown(c_iKeyDown_3) Then
  1299.                     If iLastKey <> c_iKeyDown_3 OR bEnableRepeatingKeys=TRUE Then
  1300.                         iLastKey = c_iKeyDown_3
  1301.                        
  1302.                         IF iDrawColor% > 0 THEN
  1303.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Wall
  1304.                         ELSE
  1305.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1306.                         END IF
  1307.                         m_arrMap(iX%, iY%, iZ%).Color1 = m_arrColors(iDrawColor%)
  1308.                         m_arrMap(iX%, iY%, iZ%).Alpha1 = 255
  1309.                         m_arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1310.                     End If
  1311.                    
  1312.                 ' 4 erase
  1313.                 ElseIf _KeyDown(c_iKeyDown_4) Then
  1314.                     If iLastKey <> c_iKeyDown_4 OR bEnableRepeatingKeys=TRUE Then
  1315.                         iLastKey = c_iKeyDown_4
  1316.                        
  1317.                         m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1318.                     End If
  1319.                    
  1320.                 ' 5 toggle
  1321.                 ElseIf _KeyDown(c_iKeyDown_5) Then
  1322.                     If iLastKey <> c_iKeyDown_5 OR bEnableRepeatingKeys=TRUE Then
  1323.                         iLastKey = c_iKeyDown_5
  1324.                        
  1325.                         IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  1326.                             IF iDrawColor% > 0 THEN
  1327.                                 m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Wall
  1328.                             ELSE
  1329.                                 m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1330.                             END IF
  1331.                             m_arrMap(iX%, iY%, iZ%).Color1 = m_arrColors(iDrawColor%)
  1332.                             m_arrMap(iX%, iY%, iZ%).Alpha1 = 255
  1333.                             m_arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1334.                         ELSE
  1335.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1336.                         END IF
  1337.                     End If
  1338.                    
  1339.                 ' 6 eyedropper
  1340.                 ElseIf _KeyDown(c_iKeyDown_6) Then
  1341.                     If iLastKey <> c_iKeyDown_6 OR bEnableRepeatingKeys=TRUE Then
  1342.                         iLastKey = c_iKeyDown_6
  1343.                        
  1344.                         iDrawColor% = GetPaletteFromColor%(m_arrMap(iX%, iY%, iZ%).Color1)
  1345.                     End If
  1346.                    
  1347.                 ' 7 clear all
  1348.                 ElseIf _KeyDown(c_iKeyDown_7) Then
  1349.                     If iLastKey <> c_iKeyDown_7 OR bEnableRepeatingKeys=TRUE Then
  1350.                         iLastKey = c_iKeyDown_7
  1351.                        
  1352.                         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1353.                             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1354.                                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1355.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1356.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cEmpty&
  1357.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1 = 255
  1358.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1359.                                 Next iLoopZ%
  1360.                             Next iLoopY%
  1361.                         Next iLoopX%
  1362.                        
  1363.                     End If
  1364.                    
  1365.                 ' 8 open
  1366.                 ElseIf _KeyDown(c_iKeyDown_8) Then
  1367.                     If iLastKey <> c_iKeyDown_8 OR bEnableRepeatingKeys=TRUE Then
  1368.                         iLastKey = c_iKeyDown_8
  1369.                         'TBD
  1370.                     End If
  1371.                    
  1372.                 ' 9 save
  1373.                 ElseIf _KeyDown(c_iKeyDown_9) Then
  1374.                     If iLastKey <> c_iKeyDown_9 OR bEnableRepeatingKeys=TRUE Then
  1375.                         iLastKey = c_iKeyDown_9
  1376.                         'TBD
  1377.                     End If
  1378.                 ' -----------------------------------------------------------------------------
  1379.                 ' END GET DRAWING INPUT
  1380.                 ' -----------------------------------------------------------------------------
  1381.                
  1382.                
  1383.                
  1384.                
  1385.                 ' -----------------------------------------------------------------------------
  1386.                 ' BEGIN GET OTHER KEYBOARD INPUT
  1387.                 ' -----------------------------------------------------------------------------
  1388.                 ElseIf _KeyDown(c_iKeyDown_BracketLeft) Then
  1389.                     If iLastKey <> c_iKeyDown_BracketLeft OR bEnableRepeatingKeys=TRUE Then
  1390.                         iLastKey = c_iKeyDown_BracketLeft
  1391.                         m_arrPlayer(iPlayerLoop).IsMoving = TRUE
  1392.                     End If
  1393.                 ElseIf _KeyDown(c_iKeyDown_BracketRight) Then
  1394.                     If iLastKey <> c_iKeyDown_BracketRight OR bEnableRepeatingKeys=TRUE Then
  1395.                         iLastKey = c_iKeyDown_BracketRight
  1396.                         m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  1397.                     End If
  1398.                    
  1399.                 ElseIf _KeyDown(c_iKeyDown_Comma) Then
  1400.                     If iLastKey <> c_iKeyDown_Comma OR bEnableRepeatingKeys=TRUE Then
  1401.                         iLastKey = c_iKeyDown_Comma
  1402.                         ' TODO: HAVE MAP SIZE PER PLAYER
  1403.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize - 1
  1404.                         IF m_arrPlayer(iPlayerLoop).MapSize < 1 THEN
  1405.                             m_arrPlayer(iPlayerLoop).MapSize = 1
  1406.                         ELSE
  1407.                             bMoved = TRUE
  1408.                         END IF
  1409.                     End If
  1410.                 ElseIf _KeyDown(c_iKeyDown_Period) Then
  1411.                     If iLastKey <> c_iKeyDown_Period OR bEnableRepeatingKeys=TRUE Then
  1412.                         iLastKey = c_iKeyDown_Period
  1413.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize + 1
  1414.                         IF m_arrPlayer(iPlayerLoop).MapSize > m_iGridSizeMax THEN
  1415.                             m_arrPlayer(iPlayerLoop).MapSize = m_iGridSizeMax
  1416.                         ELSE
  1417.                             bMoved = TRUE
  1418.                         END IF
  1419.                     End If
  1420.                    
  1421.                 ElseIf _KeyDown(c_iKeyDown_Minus) Then
  1422.                     If iLastKey <> c_iKeyDown_Minus OR bEnableRepeatingKeys=TRUE Then
  1423.                         iLastKey = c_iKeyDown_Minus
  1424.                         ' TODO: HAVE SEPARATE GRID SIZE PER PLAYER / SPLIT SCREEN?
  1425.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize - 1
  1426.                         IF m_arrPlayer(iPlayerLoop).GridSize < m_iGridSizeMin THEN
  1427.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMin
  1428.                         ELSE
  1429.                             bMoved = TRUE
  1430.                         END IF
  1431.                     End If
  1432.                 ElseIf _KeyDown(c_iKeyDown_EqualPlus) Then
  1433.                     If iLastKey <> c_iKeyDown_EqualPlus OR bEnableRepeatingKeys=TRUE Then
  1434.                         iLastKey = c_iKeyDown_EqualPlus
  1435.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize + 1
  1436.                         IF m_arrPlayer(iPlayerLoop).GridSize > m_iGridSizeMax THEN
  1437.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMax
  1438.                         ELSE
  1439.                             bMoved = TRUE
  1440.                         END IF
  1441.                     End If
  1442.                    
  1443.                 ElseIf _KeyDown(c_iKeyDown_Home) Then
  1444.                     If iLastKey <> c_iKeyDown_Home OR bEnableRepeatingKeys=TRUE Then
  1445.                         iLastKey = c_iKeyDown_Home
  1446.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  1447.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View - 1
  1448.                         IF m_arrPlayer(iPlayerLoop).View < c_iDir_Min THEN
  1449.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Max
  1450.                         END IF
  1451.                     End If
  1452.                 ElseIf _KeyDown(c_iKeyDown_End) Then
  1453.                     If iLastKey <> c_iKeyDown_End OR bEnableRepeatingKeys=TRUE Then
  1454.                         iLastKey = c_iKeyDown_End
  1455.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  1456.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View + 1
  1457.                         IF m_arrPlayer(iPlayerLoop).View > c_iDir_Max THEN
  1458.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Min
  1459.                         END IF
  1460.                     End If
  1461.                    
  1462.                 ElseIf _KeyDown(c_iKeyDown_Ins) Then
  1463.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  1464.                     If iLastKey <> c_iKeyDown_Ins OR bEnableRepeatingKeys=TRUE Then
  1465.                         iLastKey = c_iKeyDown_Ins
  1466.                         bEnableRepeatingKeys = TRUE
  1467.                     End If
  1468.                    
  1469.                 ElseIf _KeyDown(c_iKeyDown_Del) Then
  1470.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  1471.                     If iLastKey <> c_iKeyDown_Del OR bEnableRepeatingKeys=TRUE Then
  1472.                         iLastKey = c_iKeyDown_Del
  1473.                         bEnableRepeatingKeys = FALSE
  1474.                     End If
  1475.                    
  1476.                 ElseIf _KeyDown(c_iKeyDown_Esc) Then
  1477.                     Exit Do
  1478.                 Else
  1479.                     iLastKey = -1
  1480.                 End If
  1481.                 ' -----------------------------------------------------------------------------
  1482.                 ' END GET OTHER KEYBOARD INPUT
  1483.                 ' -----------------------------------------------------------------------------
  1484.                
  1485.                
  1486.                
  1487.                 ' --------------------------------------------------------------------------------
  1488.                 ' MOVE PLAYER BASED ON DIRECTION
  1489.                 ' --------------------------------------------------------------------------------
  1490.                 IF m_arrPlayer(iPlayerLoop).IsMoving=TRUE OR bMoved=TRUE THEN
  1491.                     bMoved = FALSE
  1492.                    
  1493.                     SELECT CASE m_arrPlayer(iPlayerLoop).Direction
  1494.                         CASE c_iDir_Down:
  1495.                             iNewX% = iX%
  1496.                             iNewY% = iY%
  1497.                             iNewZ% = iZ% - 1
  1498.                             If iNewZ% < m_iMapMinZ Then
  1499.                                 iNewZ% = m_iMapMaxZ
  1500.                             End If
  1501.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1502.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  1503.                                 iNewZ% = iZ%
  1504.                             End If
  1505.                            
  1506.                         CASE c_iDir_Up:
  1507.                             iNewX% = iX%
  1508.                             iNewY% = iY%
  1509.                             iNewZ% = iZ% + 1
  1510.                             If iNewZ% > m_iMapMaxZ Then
  1511.                                 iNewZ% = m_iMapMinZ
  1512.                             End If
  1513.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1514.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  1515.                                 iNewZ% = iZ%
  1516.                             End If
  1517.                            
  1518.                         CASE c_iDir_Left:
  1519.                             iNewX% = iX% - 1
  1520.                             iNewY% = iY%
  1521.                             iNewZ% = iZ%
  1522.                             If iNewX% < m_iMapMinX Then
  1523.                                 iNewX% = m_iMapMaxX
  1524.                             End If
  1525.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1526.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1527.                                 iNewX% = iX%
  1528.                             End If
  1529.                            
  1530.                         CASE c_iDir_Right:
  1531.                             iNewX% = iX% + 1
  1532.                             iNewY% = iY%
  1533.                             iNewZ% = iZ%
  1534.                             If iNewX% > m_iMapMaxX Then
  1535.                                 iNewX% = m_iMapMinX
  1536.                             End If
  1537.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1538.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1539.                                 iNewX% = iX%
  1540.                             End If
  1541.                            
  1542.                         CASE c_iDir_Back:
  1543.                             iNewX% = iX%
  1544.                             iNewY% = iY% - 1
  1545.                             iNewZ% = iZ%
  1546.                             If iNewY% < m_iMapMinY Then
  1547.                                 iNewY% = m_iMapMaxY
  1548.                             End If
  1549.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1550.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  1551.                                 iNewY% = iY%
  1552.                             End If
  1553.                            
  1554.                         CASE c_iDir_Forward:
  1555.                             iNewX% = iX%
  1556.                             iNewY% = iY% + 1
  1557.                             iNewZ% = iZ%
  1558.                             If iNewY% > m_iMapMaxY Then
  1559.                                 iNewY% = m_iMapMinY
  1560.                             End If
  1561.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1562.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  1563.                                 iNewY% = iY%
  1564.                             End If
  1565.                            
  1566.                         CASE ELSE:
  1567.                             ' (DO NOTHING)
  1568.                             'iNewX% = iX%
  1569.                             'iNewY% = iY%
  1570.                             'iNewZ% = iZ%
  1571.                     END SELECT
  1572.                    
  1573.                     ' SAVE NEW POSITION
  1574.                     iX% = iNewX%
  1575.                     iY% = iNewY%
  1576.                     iZ% = iNewZ%
  1577.                    
  1578.                     ' FOR MULTIPLAYER WE WOULD USE:
  1579.                     m_arrPlayer(iPlayerLoop).x = iNewX%
  1580.                     m_arrPlayer(iPlayerLoop).y = iNewY%
  1581.                     m_arrPlayer(iPlayerLoop).z = iNewZ%
  1582.                    
  1583.                 END IF
  1584.                
  1585.                 ' CYCLE COLOR
  1586.                 IF m_arrPlayer(iPlayerLoop).ColorScheme1 > 0 THEN
  1587.                     m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = m_arrPlayer(iPlayerLoop).ColorSchemeCount1 + 1
  1588.                     IF m_arrPlayer(iPlayerLoop).ColorSchemeCount1 > m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 THEN
  1589.                         m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  1590.                         DoCycleColor m_arrPlayer(iPlayerLoop).ColorScheme1, m_arrPlayer(iPlayerLoop).Color1
  1591.                     END IF
  1592.                 END IF
  1593.                
  1594.             NEXT iPlayerLoop
  1595.            
  1596.             ' ****************************************************************************************************************************************************************
  1597.             ' END PLAYER LOOP
  1598.             ' ****************************************************************************************************************************************************************
  1599.            
  1600.         _Limit 30
  1601.         _Display
  1602.        
  1603.         Loop
  1604.     END IF
  1605.    
  1606. CleanupAndExit:
  1607.     ' FINISH UP AND EXIT
  1608.     WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  1609.     SCREEN 0
  1610.     IsometricDraw1$ = sResult
  1611. End Sub ' IsometricDraw1$
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1619. ' BEGIN GRAPHICS FUNCTIONS
  1620. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1621.  
  1622. ' =============================================================================
  1623. ' LET'S GET THE COORDINATES STRAIGHT!
  1624. ' Coordinates are m_arrMap(x,y,z)
  1625. '           ________________
  1626. '          /|e            /|e
  1627. '         / |            / |
  1628. '        /  |           /  |z-axis
  1629. '       /   |          /   |
  1630. '      /    /---------/----/
  1631. '     /    / a       /   b/  
  1632. '    /    /         /    /        
  1633. '   |--------------|    /  
  1634. '   |f  /         g|   / y-axis
  1635. '   |  /           |  /
  1636. '   | /            | /
  1637. '   |/c           d|/
  1638. '   ----------------
  1639. '      x-axis
  1640. '
  1641. ' POINT    ( X, Y, Z)
  1642. ' a        ( 0, 0, 0)
  1643. ' b        (32, 0, 0)
  1644. ' c        ( 0,32, 0)
  1645. ' d        (32,32, 0)
  1646. ' e        ( 0, 0,32)
  1647. ' f        ( 0,32,32)
  1648. ' g        (32,32,32)
  1649. ' =============================================================================
  1650.  
  1651. ' /////////////////////////////////////////////////////////////////////////////
  1652. ' INITIALIZE MAP TO EMPTY
  1653.  
  1654. ' Requires shared global variable:
  1655. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1656. Sub ClearIsometricMap
  1657.     Dim RoutineName As String: RoutineName = "ClearIsometricMap"
  1658.     Dim iLoopX%
  1659.     Dim iLoopY%
  1660.     Dim iLoopZ%
  1661.    
  1662.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1663.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1664.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1665.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1666.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1667.             Next iLoopY%
  1668.         Next iLoopX%
  1669.     Next iLoopZ%
  1670. End Sub ' ClearIsometricMap
  1671.  
  1672. ' /////////////////////////////////////////////////////////////////////////////
  1673. ' INITIALIZE RENDERING MAP #1 TO EMPTY
  1674.  
  1675. ' Requires shared global variable:
  1676. ' m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1677.  
  1678. Sub ClearRenderMap1
  1679.     Dim RoutineName As String: RoutineName = "ClearRenderMap1"
  1680.     Dim iLoopX%
  1681.     Dim iLoopY%
  1682.     Dim iLoopZ%
  1683.    
  1684.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1685.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1686.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1687.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1688.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1689.             Next iLoopY%
  1690.         Next iLoopX%
  1691.     Next iLoopZ%
  1692. End Sub ' ClearRenderMap1
  1693.  
  1694. ' /////////////////////////////////////////////////////////////////////////////
  1695. ' INITIALIZE RENDERING MAP #2 TO EMPTY
  1696.  
  1697. ' Requires shared global variable:
  1698. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1699.  
  1700. Sub ClearRenderMap2
  1701.     Dim RoutineName As String: RoutineName = "ClearRenderMap2"
  1702.     Dim iLoopX%
  1703.     Dim iLoopY%
  1704.     Dim iLoopZ%
  1705.    
  1706.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1707.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1708.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1709.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1710.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1711.             Next iLoopY%
  1712.         Next iLoopX%
  1713.     Next iLoopZ%
  1714. End Sub ' ClearRenderMap2
  1715.  
  1716. ' /////////////////////////////////////////////////////////////////////////////
  1717. ' Determine which squares are visible in isometric map
  1718.  
  1719. ' Original operates directly on the main map array m_arrMap
  1720. ' and not the copy (m_arrRender2) used to rotate the perspective.
  1721.  
  1722. ' Requires shared global variable (3D array of map):
  1723. ' m_arrMap(x,y,z) = 3D array map of world
  1724. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1725.  
  1726. ' RECEIVES:
  1727. ' iX% = player's X positon
  1728. ' iY% = player's Y position
  1729. ' iZ% = player's Z position
  1730.  
  1731. ' Direction is assumed to be c_iDir_Forward.
  1732.  
  1733. ' If iX% < 0 then we just render everything with its normal alpha value.
  1734.  
  1735. Sub ComputeVisible (iX%, iY%, iZ%, iGridSize)
  1736.     Dim RoutineName As String: RoutineName = "ComputeVisible"
  1737.     Dim iLoopX%
  1738.     Dim iLoopY%
  1739.     Dim iLoopZ%
  1740.    
  1741.     Dim iPX1%
  1742.     Dim iPY1%
  1743.     Dim iPZ1%
  1744.     Dim iPlayer2Dx As Integer
  1745.     Dim iPlayer2Dy As Integer
  1746.     Dim iTile2Dx As Integer
  1747.     Dim iTile2Dy As Integer
  1748.    
  1749.     IF iX% > -1 THEN
  1750.         ' CALCULATE PLAYER'S 2-D POSITION
  1751.         iPX1% = iX% * iGridSize + cGridOffsetX
  1752.         iPY1% = iY% * iGridSize + cGridOffsetY
  1753.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  1754.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1755.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1756.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1757.        
  1758.         ' LOOK AT EACH TILE
  1759.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1760.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1761.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1762.                    
  1763.                     ' *****************************************************************************
  1764.                     ' IF SPACE HAS A TILE
  1765.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  1766.                     ' THEN MAKE THE TILE TRANSPARENT
  1767.                     ' *****************************************************************************
  1768.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  1769.                     If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall OR m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  1770.                         ' CALCULATE TILE'S 2-D POSITION
  1771.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  1772.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  1773.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  1774.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1775.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1776.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1777.                        
  1778.                         'If iLoopZ% >= iZ% Then
  1779.                             'If iLoopX% >= iX% Then
  1780.                                
  1781.                                 ' FOR TILES FORWARD OF PLAYER
  1782.                                 If iLoopY% > iY% Then
  1783.                                    
  1784.                                     ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  1785.                                     If ( iPlayer2Dy >= (iTile2Dy - iGridSize) ) AND ( iPlayer2Dy <= (iTile2Dy + iGridSize) ) Then
  1786.                                        
  1787.                                         ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  1788.                                         If ( iPlayer2Dx >= (iTile2Dx - iGridSize) ) AND ( iPlayer2Dx <= (iTile2Dx + iGridSize) ) Then
  1789.                                             ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  1790.                                             ' TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE
  1791.                                             m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  1792.                                         Else
  1793.                                             ' LEAVE THE TILE OPAQUE
  1794.                                             ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1795.                                             m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1796.                                         End If
  1797.                                     Else
  1798.                                         ' LEAVE THE TILE OPAQUE
  1799.                                         ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1800.                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1801.                                     End If
  1802.                                 Else
  1803.                                     ' LEAVE THE TILE OPAQUE
  1804.                                     ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1805.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1806.                                 End If
  1807.                             'End If
  1808.                         'End If
  1809.                     Else
  1810.                         ' LEAVE THE TILE OPAQUE
  1811.                         ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1812.                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1813.                     End If
  1814.                 Next iLoopZ%
  1815.             Next iLoopY%
  1816.         Next iLoopX%
  1817.     ELSE
  1818.         ' JUST MAKE ALL TILES VISIBLE
  1819.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1820.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1821.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1822.                     ' LEAVE THE TILE OPAQUE
  1823.                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1824.                    
  1825.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1826.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1827.                     'm_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1828.                    
  1829.                 Next iLoopZ%
  1830.             Next iLoopY%
  1831.         Next iLoopX%
  1832.     END IF
  1833. End Sub ' ComputeVisible
  1834.  
  1835. ' /////////////////////////////////////////////////////////////////////////////
  1836. ' Determine which squares are visible in isometric map
  1837.  
  1838. ' Same as ComputeVisible except uses the rotated copy
  1839. ' (m_arrRender2 instead of m_arrMap)
  1840.  
  1841. ' Requires shared global variable (3D array of map):
  1842. ' m_arrRender2(x,y,z) = rotated copy of 3D array map of world
  1843. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1844.  
  1845. ' RECEIVES:
  1846. ' iX% = player's X positon
  1847. ' iY% = player's Y position
  1848. ' iZ% = player's Z position
  1849.  
  1850. ' If iX% < 0 then we just render everything with its normal alpha value.
  1851.  
  1852. ' TODO: FIX FOR c_iDir_Down and c_iDir_Up DIRECTIONS
  1853. '       "FOR TILES FORWARD OF PLAYER" SECTION BELOW
  1854. '       NEEDS TO LOOK AT Z AXIS INSTEAD OF Y ?
  1855.  
  1856. Sub ComputeRenderVisible (iX%, iY%, iZ%, iGridSize)
  1857.     Dim RoutineName As String: RoutineName = "ComputeRenderVisible"
  1858.     Dim iLoopX%
  1859.     Dim iLoopY%
  1860.     Dim iLoopZ%
  1861.    
  1862.     Dim iPX1%
  1863.     Dim iPY1%
  1864.     Dim iPZ1%
  1865.     Dim iPlayer2Dx As Integer
  1866.     Dim iPlayer2Dy As Integer
  1867.     Dim iTile2Dx As Integer
  1868.     Dim iTile2Dy As Integer
  1869.    
  1870.     IF iX% > -1 THEN
  1871.         ' CALCULATE PLAYER'S 2-D POSITION
  1872.         iPX1% = iX% * iGridSize + cGridOffsetX
  1873.         iPY1% = iY% * iGridSize + cGridOffsetY
  1874.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  1875.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1876.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1877.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1878.        
  1879.         ' LOOK AT EACH TILE
  1880.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1881.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1882.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1883.                    
  1884.                     ' *****************************************************************************
  1885.                     ' IF SPACE HAS A TILE
  1886.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  1887.                     ' THEN MAKE THE TILE TRANSPARENT
  1888.                     ' *****************************************************************************
  1889.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  1890.                     If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall OR m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  1891.                         ' CALCULATE TILE'S 2-D POSITION
  1892.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  1893.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  1894.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  1895.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1896.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1897.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1898.                        
  1899.                         'If iLoopZ% >= iZ% Then
  1900.                             'If iLoopX% >= iX% Then
  1901.                                
  1902.                                 ' FOR TILES FORWARD OF PLAYER
  1903.                                 If iLoopY% > iY% Then
  1904.                                    
  1905.                                     ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  1906.                                     If ( iPlayer2Dy >= (iTile2Dy - iGridSize) ) AND ( iPlayer2Dy <= (iTile2Dy + iGridSize) ) Then
  1907.                                        
  1908.                                         ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  1909.                                         If ( iPlayer2Dx >= (iTile2Dx - iGridSize) ) AND ( iPlayer2Dx <= (iTile2Dx + iGridSize) ) Then
  1910.                                             ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  1911.                                             'TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE?
  1912.                                             m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  1913.                                         Else
  1914.                                             ' LEAVE THE TILE OPAQUE
  1915.                                             m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1916.                                            
  1917.                                             'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1918.                                             'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1919.                                             'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1920.                                         End If
  1921.                                     Else
  1922.                                         ' LEAVE THE TILE OPAQUE
  1923.                                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1924.                                        
  1925.                                         'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1926.                                         'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1927.                                         'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1928.                                     End If
  1929.                                 Else
  1930.                                     ' LEAVE THE TILE OPAQUE
  1931.                                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1932.                                    
  1933.                                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1934.                                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1935.                                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1936.                                 End If
  1937.                             'End If
  1938.                         'End If
  1939.                     Else
  1940.                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1941.                        
  1942.                         'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1943.                         'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1944.                     End If
  1945.                 Next iLoopZ%
  1946.             Next iLoopY%
  1947.         Next iLoopX%
  1948.     ELSE
  1949.         ' JUST MAKE ALL TILES VISIBLE
  1950.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1951.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1952.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1953.                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1954.                    
  1955.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1956.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1957.                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1958.                 Next iLoopZ%
  1959.             Next iLoopY%
  1960.         Next iLoopX%
  1961.     END IF
  1962. End Sub ' ComputeRenderVisible
  1963.  
  1964. ' /////////////////////////////////////////////////////////////////////////////
  1965. ' Draw the map in 3D Isometic Perspective
  1966. ' from the forward (default) perspective.
  1967.  
  1968. ' Requires shared global variable
  1969. ' m_arrMap(x,y,z) = 3D array map of world
  1970. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1971.  
  1972. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  1973. ' params instead of constants:
  1974. ' Const cScreenOffsetX = 500 ' 450
  1975. ' Const cScreenOffsetY = 300 ' 50
  1976. ' Const cScreenOffsetZ = 0
  1977.  
  1978. ' what about?
  1979. ' Const cGridOffsetX = 50
  1980. ' Const cGridOffsetY = 50
  1981. ' Const cGridOffsetZ = 0
  1982.  
  1983. Sub DrawIsometricScreen(iScreenOffsetX, iScreenOffsetY, iGridSize)
  1984.     Dim RoutineName As String: RoutineName = "DrawIsometricScreen"
  1985.     Dim bTile As Integer
  1986.     Dim iLoopX%
  1987.     Dim iLoopY%
  1988.     Dim iLoopZ%
  1989.     Dim iColor As _Unsigned Long
  1990.     Dim iPosX1%
  1991.     Dim iPosX2%
  1992.     Dim iPosY1%
  1993.     Dim iPosY2%
  1994.     Dim iPosZ1%
  1995.     Dim alpha&
  1996.    
  1997.     alpha& = 255
  1998.     bTile = FALSE
  1999.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2000.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2001.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2002.                
  2003.                 ' CALCULATE POSITION
  2004.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  2005.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  2006.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  2007.                 iPosX2% = iPosX1% + iGridSize
  2008.                 iPosY2% = iPosY1% + iGridSize
  2009.                
  2010.                 ' DETERMINE COLOR
  2011.                 If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  2012.                     If bTile = TRUE Then
  2013.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2014.                         bTile = FALSE
  2015.                     Else
  2016.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  2017.                         bTile = TRUE
  2018.                     End If
  2019.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  2020.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2021.                     alpha& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  2022.                    
  2023.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  2024.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2025.                     alpha& = 255
  2026.                    
  2027.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  2028.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2029.                     alpha& = 255
  2030.                    
  2031.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  2032.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2033.                     alpha& = 255
  2034.                    
  2035.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  2036.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2037.                     alpha& = 255
  2038.                    
  2039.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  2040.                     'TODO: transparent for water
  2041.                     iColor = cEmpty&
  2042.                     alpha& = 64
  2043.                    
  2044.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  2045.                     'TODO: transparent for windows
  2046.                     iColor = cEmpty&
  2047.                     alpha& = 64
  2048.                    
  2049.                 Else
  2050.                     iColor = cEmpty&
  2051.                 End If
  2052.                
  2053.                 ' PLOT NEXT TILE
  2054.                 If iColor <> cEmpty& Then
  2055.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  2056.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  2057.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  2058.                 End If
  2059.                
  2060.             Next iLoopY%
  2061.         Next iLoopX%
  2062.     Next iLoopZ%
  2063. End Sub ' DrawIsometricScreen
  2064.  
  2065. ' /////////////////////////////////////////////////////////////////////////////
  2066. ' Draw the map in 3D Isometic Perspective.
  2067.  
  2068. ' Requires shared global variable
  2069. ' m_arrRender2(x,y,z) = 3D array map of world
  2070. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  2071.  
  2072. Sub DrawRenderScreen(iScreenOffsetX, iScreenOffsetY, iGridSize)
  2073.     Dim RoutineName As String: RoutineName = "DrawRenderScreen"
  2074.     Dim bTile As Integer
  2075.     Dim iLoopX%
  2076.     Dim iLoopY%
  2077.     Dim iLoopZ%
  2078.     Dim iColor As _Unsigned Long
  2079.     Dim iPosX1%
  2080.     Dim iPosX2%
  2081.     Dim iPosY1%
  2082.     Dim iPosY2%
  2083.     Dim iPosZ1%
  2084.     Dim alpha&
  2085.    
  2086.     alpha& = 255
  2087.     bTile = FALSE
  2088.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2089.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2090.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2091.                
  2092.                 ' CALCULATE POSITION
  2093.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  2094.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  2095.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  2096.                 iPosX2% = iPosX1% + iGridSize
  2097.                 iPosY2% = iPosY1% + iGridSize
  2098.                
  2099.                 ' DETERMINE COLOR
  2100.                 If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  2101.                     If bTile = TRUE Then
  2102.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2103.                         bTile = FALSE
  2104.                     Else
  2105.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color2
  2106.                         bTile = TRUE
  2107.                     End If
  2108.                    
  2109.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  2110.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2111.                     alpha& = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  2112.                    
  2113.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  2114.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2115.                     alpha& = 255
  2116.                    
  2117.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  2118.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2119.                     alpha& = 255
  2120.                    
  2121.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  2122.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2123.                     alpha& = 255
  2124.                    
  2125.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  2126.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2127.                     alpha& = 255
  2128.                    
  2129.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  2130.                     'TODO: transparent for water
  2131.                     iColor = cEmpty&
  2132.                     alpha& = 64
  2133.                    
  2134.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  2135.                     'TODO: transparent for windows
  2136.                     iColor = cEmpty&
  2137.                     alpha& = 64
  2138.                    
  2139.                 Else
  2140.                     iColor = cEmpty&
  2141.                 End If
  2142.                
  2143.                 ' PLOT NEXT TILE
  2144.                 If iColor <> cEmpty& Then
  2145.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  2146.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  2147.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  2148.                 End If
  2149.                
  2150.             Next iLoopY%
  2151.         Next iLoopX%
  2152.     Next iLoopZ%
  2153. End Sub ' DrawRenderScreen
  2154.  
  2155. ' /////////////////////////////////////////////////////////////////////////////
  2156. ' Draw the map in 3D Isometic Perspective
  2157. ' from a different direction.
  2158.  
  2159. ' This is the lazy man's version which simply copies the tiles to
  2160. ' a temporary array, rotated to the specified direction/orientation.
  2161. ' A more efficient + faster method would operate directly on the
  2162. ' main array, but I am too bogged down to figure that out right now!
  2163.  
  2164. ' RECEIVES:
  2165. ' iDirection% = point of view to render from
  2166. '     i.e. the direction we are looking at the scene FROM
  2167. '     iDirection% can be one of the following:
  2168. '     c_iDir_Down
  2169. '     c_iDir_Up
  2170. '     c_iDir_Left
  2171. '     c_iDir_Right
  2172. '     c_iDir_Back
  2173. '     c_iDir_Forward = default
  2174. '    
  2175. '     If iDirection% = c_iDir_Forward, just call DrawIsometricScreen instead (faster).
  2176. '
  2177. ' iScreenOffsetX, iScreenOffsetY = where on display to draw
  2178. '
  2179. ' iX%, iY%, iZ% = player's position, used for ComputeRenderVisible
  2180. '     to compute which tiles to hide / make transparent
  2181. '     (tiles that might be hiding the player)
  2182. '     If these are <0, then ComputeRenderVisible uses original alpha values.
  2183.  
  2184. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  2185. ' params instead of constants:
  2186. ' Const cScreenOffsetX = 500 ' 450
  2187. ' Const cScreenOffsetY = 300 ' 50
  2188. ' Const cScreenOffsetZ = 0
  2189.  
  2190. ' what about?
  2191. ' Const cGridOffsetX = 50
  2192. ' Const cGridOffsetY = 50
  2193. ' Const cGridOffsetZ = 0
  2194.  
  2195. ' TODO: player layer
  2196. ' m_iPlayerCount
  2197. ' shared for current player #?
  2198. ' first copy world and superimpose player coords?
  2199.  
  2200. Sub DrawScreen(iDirection%, iScreenOffsetX, iScreenOffsetY, iGridSize, iX%, iY%, iZ%)
  2201.     Dim RoutineName As String: RoutineName = "DrawScreen"
  2202.     Dim bTile As Integer
  2203.     Dim iLoopX%
  2204.     Dim iLoopY%
  2205.     Dim iLoopZ%
  2206.     Dim iColor As _Unsigned Long
  2207.     Dim iPosX1%
  2208.     Dim iPosX2%
  2209.     Dim iPosY1%
  2210.     Dim iPosY2%
  2211.     Dim iPosZ1%
  2212.     Dim alpha&
  2213.    
  2214.     ' =============================================================================
  2215.     ' USE FIRST TEMPORARY ARRAY TO STORE SCENE OVERLAID WITH PLAYERS + OBJECTS
  2216.    
  2217.     ' CLEAR THE MAP (NECESSARY?)
  2218.     ClearRenderMap1
  2219.    
  2220.     ' FIRST COPY THE MAP
  2221.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2222.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2223.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2224.                 'm_arrRender1(iLoopX%,iLoopY%,iLoopZ%) = m_arrMap(iLoopX%, iLoopY%, iLoopZ%)
  2225.                 CopyMapTile m_arrMap(iLoopX%, iLoopY%, iLoopZ%), m_arrRender1(iLoopX%,iLoopY%,iLoopZ%)
  2226.             Next iLoopY%
  2227.         Next iLoopX%
  2228.     Next iLoopZ%
  2229.    
  2230.     ' NEXT COPY THE PLAYERS
  2231.     For iLoopX% = m_iPlayerMin To m_iPlayerCount
  2232.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Typ = m_arrPlayer(iLoopX%).Tile1
  2233.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Color1 = m_arrPlayer(iLoopX%).Color1
  2234.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Alpha1 = m_arrPlayer(iLoopX%).Alpha1
  2235.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).AlphaOverride = m_arrPlayer(iLoopX%).AlphaOverride
  2236.     Next iLoopX%
  2237.    
  2238.     ' NEXT COPY THE OBJECTS
  2239.     ' (TO DO WHEN WE HAVE OBJECTS)
  2240.    
  2241.     ' =============================================================================
  2242.     ' USE SECOND TEMPORARY ARRAY TO STORE ROTATED SCENE THEN DRAW IT
  2243.    
  2244.     ' CLEAR THE MAP (NECESSARY?)
  2245.     ClearRenderMap2
  2246.    
  2247.     ' COPY TILES, ROTATED TO DESIRED VIEWING PERSPECTIVE / ANGLE
  2248.     SELECT CASE iDirection%
  2249.         CASE c_iDir_Down:
  2250.             ' SCENE IS FLIPPED UP (TOP FACE NOW FACING AWAY FROM US)
  2251.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2252.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2253.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2254.                         m_arrRender2(iLoopX%,m_iMapMaxZ-iLoopZ%,iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2255.                     Next iLoopY%
  2256.                 Next iLoopX%
  2257.             Next iLoopZ%
  2258.             ComputeRenderVisible iX%, m_iMapMaxZ-iZ%, iY%, iGridSize
  2259.         CASE c_iDir_Up:
  2260.             ' SCENE IS FLIPPED DOWN (TOP FACE NOW FACING TOWARD US)
  2261.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2262.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2263.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2264.                         m_arrRender2(iLoopX%,iLoopZ%,m_iMapMaxY-iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2265.                     Next iLoopY%
  2266.                 Next iLoopX%
  2267.             Next iLoopZ%
  2268.             ComputeRenderVisible iX%, iZ%, m_iMapMaxY-iY%, iGridSize
  2269.         CASE c_iDir_Left:
  2270.             ' SCENE IS ROTATED COUNTER CLOCKWISE FROM TOP (LEFT FACE NOW FACING TOWARD US)
  2271.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2272.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2273.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2274.                         m_arrRender2(iLoopY%,m_iMapMaxX-iLoopX%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2275.                     Next iLoopY%
  2276.                 Next iLoopX%
  2277.             Next iLoopZ%
  2278.             ComputeRenderVisible iY%, m_iMapMaxX-iX%, iZ%, iGridSize
  2279.         CASE c_iDir_Right:
  2280.             ' SCENE IS ROTATED CLOCKWISE FROM TOP (RIGHT FACE NOW FACING TOWARD US)
  2281.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2282.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2283.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2284.                         m_arrRender2(m_iMapMaxY-iLoopY%,iLoopX%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2285.                     Next iLoopY%
  2286.                 Next iLoopX%
  2287.             Next iLoopZ%
  2288.             ComputeRenderVisible m_iMapMaxY-iY%, iX%, iZ%, iGridSize
  2289.         CASE c_iDir_Back:
  2290.             ' SCENE IS TURNED AROUND (FRONT FACE NOW FACING AWAY FROM US)
  2291.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2292.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2293.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2294.                         m_arrRender2(m_iMapMaxX-iLoopX%,m_iMapMaxY-iLoopY%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2295.                     Next iLoopY%
  2296.                 Next iLoopX%
  2297.             Next iLoopZ%
  2298.             ComputeRenderVisible m_iMapMaxX-iX%, m_iMapMaxY-iY%, iZ%, iGridSize
  2299.         CASE ELSE: ' c_iDir_Forward
  2300.             ' FOR ALL OTHER CASES WE JUST DRAW FORWARD (FACING TOWARD US)
  2301.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2302.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2303.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2304.                         m_arrRender2(iLoopX%,iLoopY%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2305.                     Next iLoopY%
  2306.                 Next iLoopX%
  2307.             Next iLoopZ%
  2308.             ComputeRenderVisible iX%, iY%, iZ%, iGridSize
  2309.     END SELECT
  2310.     DrawRenderScreen iScreenOffsetX, iScreenOffsetY, iGridSize
  2311. End Sub ' DrawScreen
  2312.  
  2313. ' /////////////////////////////////////////////////////////////////////////////
  2314. ' Copies a MapTileType user defined type variable, member by member
  2315. ' (not sure if you can just do MyUDT1 = MyUDT2?)
  2316.  
  2317. Sub CopyMapTile(SourceMap As MapTileType, DestMap As MapTileType)
  2318.     DestMap.Typ = SourceMap.Typ
  2319.     DestMap.Color1 = SourceMap.Color1
  2320.     DestMap.Color2 = SourceMap.Color2
  2321.     DestMap.Color3 = SourceMap.Color3
  2322.     DestMap.Alpha1 = SourceMap.Alpha1
  2323.     DestMap.Alpha2 = SourceMap.Alpha2
  2324.     DestMap.Alpha3 = SourceMap.Alpha3
  2325.     DestMap.AlphaOverride = SourceMap.AlphaOverride
  2326. End Sub ' CopyMapTile
  2327.  
  2328. ' /////////////////////////////////////////////////////////////////////////////
  2329. ' RETURNS MAP AS TEXT
  2330.  
  2331. ' Requires shared global variable
  2332. ' m_arrMap(x,y,z) = 3D array map of world
  2333. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  2334.  
  2335. ' USAGE:
  2336. 'Input "See a text dump (y/n)? ", in$
  2337. 'If LCase$(in$) = LCase$("y") Then
  2338. '    Print MapToText$
  2339. 'End If
  2340.  
  2341. Function MapToText$
  2342.     Dim RoutineName As String: RoutineName = "MapToText$"
  2343.     Dim sResult As String
  2344.     Dim iLoopX%
  2345.     Dim iLoopY%
  2346.     Dim iLoopZ%
  2347.     Dim iMinX%
  2348.     Dim iMaxX%
  2349.     Dim iMinY%
  2350.     Dim iMaxY%
  2351.     Dim iMinZ%
  2352.     Dim iMaxZ%
  2353.     Dim sLine As String
  2354.     Dim iType%
  2355.     Dim iColor1&
  2356.     Dim iColor2&
  2357.     Dim iColor3&
  2358.     Dim in$
  2359.  
  2360.     sResult = ""
  2361.  
  2362.     ' FIND USED BOUNDARIES OF MAP
  2363.     iMinX% = -1
  2364.     iMaxX% = -1
  2365.     iMinY% = -1
  2366.     iMaxY% = -1
  2367.     iMinZ% = -1
  2368.     iMaxZ% = -1
  2369.     For iLoopZ% = 0 To 32
  2370.         For iLoopX% = 0 To 32
  2371.             For iLoopY% = 0 To 32
  2372.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  2373.                 If iType% <> c_iTile_Empty And iType% <> c_iTile_Floor Then
  2374.                     If iMinX% = -1 Then
  2375.                         iMinX% = iLoopX%
  2376.                     End If
  2377.                     If iMinY% = -1 Then
  2378.                         iMinY% = iLoopY%
  2379.                     End If
  2380.                     If iMinZ% = -1 Then
  2381.                         iMinZ% = iLoopZ%
  2382.                     End If
  2383.                     If iLoopX% > iMaxX% Then
  2384.                         iMaxX% = iLoopX%
  2385.                     End If
  2386.                     If iLoopY% > iMaxY% Then
  2387.                         iMaxY% = iLoopY%
  2388.                     End If
  2389.                     If iLoopZ% > iMaxZ% Then
  2390.                         iMaxZ% = iLoopZ%
  2391.                     End If
  2392.                 End If
  2393.             Next iLoopY%
  2394.         Next iLoopX%
  2395.     Next iLoopZ%
  2396.  
  2397.     ' GENERATE OUTPUT
  2398.     For iLoopZ% = iMinZ% To iMaxZ%
  2399.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  2400.         sResult = sResult + "Map Z=" + cstr$(iLoopZ%) + ":" + Chr$(13)
  2401.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  2402.         For iLoopY% = iMinY% To iMaxY%
  2403.             sLine = ""
  2404.             For iLoopX% = iMinX% To iMaxX%
  2405.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  2406.                 iColor1& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2407.                 iColor2& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  2408.                 iColor3& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color3
  2409.                
  2410.                 If iType% = c_iTile_Empty Then
  2411.                     sLine = sLine + " "
  2412.                 Else
  2413.                     If iColor1& = cEmpty& Then
  2414.                         sLine = sLine + " "
  2415.                     Else
  2416.                         sLine = sLine + "#"
  2417.                     End If
  2418.                 End If
  2419.             Next iLoopX%
  2420.             sResult = sResult + sLine + Chr$(13)
  2421.         Next iLoopY%
  2422.  
  2423.         sResult = sResult + Chr$(13)
  2424.     Next iLoopZ%
  2425.  
  2426.     MapToText$ = sResult
  2427. End Function ' MapToText$
  2428.  
  2429. ' /////////////////////////////////////////////////////////////////////////////
  2430. ' Return string description for 2.5D movement constants
  2431.  
  2432. FUNCTION GetDirection$(iDir AS INTEGER)
  2433.     DIM sDir AS STRING
  2434.     SELECT CASE iDir
  2435.         CASE c_iDir_Down:
  2436.             sDir = "Down"
  2437.         CASE c_iDir_Up:
  2438.             sDir = "Up"
  2439.         CASE c_iDir_Left:
  2440.             sDir = "Left"
  2441.         CASE c_iDir_Right:
  2442.             sDir = "Right"
  2443.         CASE c_iDir_Back:
  2444.             sDir = "Back"
  2445.         CASE c_iDir_Forward:
  2446.             sDir = "Forward"
  2447.         CASE ELSE:
  2448.             sDir = "Unknown"
  2449.     END SELECT
  2450.     GetDirection$ = sDir
  2451. END FUNCTION ' GetDirection$
  2452.  
  2453. ' /////////////////////////////////////////////////////////////////////////////
  2454.  
  2455. Function CX2I (x As Long, y As Long) 'Convert Cartesian X To Isometic coordinates
  2456.     CX2I = x - y
  2457. End Function ' CX2I
  2458.  
  2459. ' /////////////////////////////////////////////////////////////////////////////
  2460.  
  2461. Function CY2I (x As Long, y As Long) 'Convert Cartesian Y To Isometic coordinates
  2462.     CY2I = (x + y) / 2
  2463. End Function ' CY2I
  2464.  
  2465. ' /////////////////////////////////////////////////////////////////////////////
  2466. ' since we're drawing a diamond and not a square box, we can't use Line BF.
  2467. ' We have to manually down the 4 points of the line.
  2468.  
  2469. Sub IsoLine (x, y, x2, y2, xoffset, yoffset, iColor As _Unsigned Long)
  2470.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), iColor
  2471.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), iColor
  2472.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), iColor
  2473.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), iColor
  2474.     Paint (CX2I(x, y) + xoffset, CY2I(x, y) + 4), iColor 'and fill the diamond solid
  2475.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), &HFFFFFFFF
  2476.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), &HFFFFFFFF
  2477.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), &HFFFFFFFF
  2478.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), &HFFFFFFFF
  2479. End Sub ' IsoLine
  2480.  
  2481. ' /////////////////////////////////////////////////////////////////////////////
  2482. ' Like IsoLine, we're going to have to draw our lines manually.
  2483. ' only in this case, we also need a Z coordinate to tell us how
  2484. ' THICK/TALL/HIGH to make our tile
  2485.  
  2486. ' MODIFIED by madscijr to draw a single tile of height iHeight at Z axis
  2487. ' MODIFIED by madscijr to accept an alpha& value to control transparency (where 0=fully transparent, 255=opaque)
  2488.  
  2489. ''Sub IsoLine3D (x, y, x2, y2, z, xoffset, yoffset, iColor As _Unsigned Long)
  2490. 'Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long)
  2491. Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long, alpha&)
  2492.     dim r 'as integer
  2493.     dim g 'as integer
  2494.     dim b 'as integer
  2495.     'dim iNewColor As _Unsigned Long
  2496.    
  2497.     r = _Red32(iColor)
  2498.     g = _Green32(iColor)
  2499.     b = _Blue32(iColor)
  2500.    
  2501.     ' Let's just do all the math first this time.
  2502.     ' We need to turn those 4 normal points into 4 isometric points (x, y, x1, y1)
  2503.     TempX1 = CX2I(x, y) + xoffset
  2504.     TempY1 = CY2I(x, y) + yoffset
  2505.     TempX2 = CX2I(x2, y) + xoffset
  2506.     TempY2 = CY2I(x2, y) + yoffset
  2507.     TempX3 = CX2I(x2, y2) + xoffset
  2508.     TempY3 = CY2I(x2, y2) + yoffset
  2509.     TempX4 = CX2I(x, y2) + xoffset
  2510.     TempY4 = CY2I(x, y2) + yoffset
  2511.    
  2512.     ' The top
  2513.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, iColor
  2514.     fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  2515.    
  2516.     If z <> 0 Then
  2517.         ' TODO: maybe change which sides gets shaded depending on the direction of the light source?
  2518.        
  2519.         ' draw the left side, shaded 75%
  2520.         'fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b)
  2521.         fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b, alpha&)
  2522.        
  2523.         ' draw the right side,s haded 50%
  2524.         'fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b)
  2525.         fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b, alpha&)
  2526.     Else
  2527.         ' no need to draw any height, if there isn't any.
  2528.     End If
  2529. End Sub ' IsoLine3D
  2530.  
  2531. ' /////////////////////////////////////////////////////////////////////////////
  2532. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  2533. ' don’t go there: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  2534.  
  2535. Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  2536.     Dim D As Long
  2537.     Dim a&
  2538.  
  2539.     D = _Dest
  2540.     a& = _NewImage(1, 1, 32)
  2541.     _Dest a&
  2542.     PSet (0, 0), K
  2543.     _Dest D
  2544.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  2545.     _FreeImage a& ' <<< this is important!
  2546. End Sub ' ftri
  2547.  
  2548. ' /////////////////////////////////////////////////////////////////////////////
  2549. ' 2019-11-20 Steve saves some time with STATIC
  2550. ' and saves and restores last dest
  2551.  
  2552. Sub ftri1 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  2553.     Dim D As Long
  2554.     Static a&
  2555.  
  2556.     D = _Dest
  2557.     If a& = 0 Then
  2558.         a& = _NewImage(1, 1, 32)
  2559.     End If
  2560.     _Dest a&
  2561.     _DontBlend a&
  2562.     PSet (0, 0), K
  2563.     _Blend a&
  2564.     _Dest D
  2565.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  2566. End Sub ' ftri1
  2567.  
  2568. ' /////////////////////////////////////////////////////////////////////////////
  2569. ' original fill quad that may be at fault using Steve's fTri version
  2570. ' need 4 non linear points (not all on 1 line) list them clockwise
  2571. ' so x2, y2 is opposite of x4, y4
  2572.  
  2573. Sub fquad1 (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  2574.     ftri1 x1, y1, x2, y2, x4, y4, K
  2575.     ftri1 x3, y3, x2, y2, x4, y4, K
  2576. End Sub ' fquad1
  2577.  
  2578. ' /////////////////////////////////////////////////////////////////////////////
  2579. ' update 2019-12-16 needs orig fTri
  2580. ' need 4 non linear points (not all on 1 line)
  2581. ' list them clockwise so x2, y2 is opposite of x4, y4
  2582.  
  2583. Sub fquad (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  2584.     ftri x1, y1, x2, y2, x3, y3, K
  2585.     ftri x3, y3, x4, y4, x1, y1, K
  2586. End Sub ' fquad
  2587.  
  2588. ' /////////////////////////////////////////////////////////////////////////////
  2589. ' DRAW A 2-D BOX (SOLID)
  2590. ' https://www.qb64.org/wiki/LINE
  2591.  
  2592. 'SUB DrawBox (iX%, iY%, iSize%, iColor%)
  2593. SUB DrawBox (iX%, iY%, iSize%, iColor&)
  2594.     LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor&, BF ' Draw a solid box
  2595.     'LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor%, BF ' Draw a solid box
  2596.     'LINE (60, 60)-(130, 100), iColor%, B ' Draw a box outline
  2597. END SUB ' DrawBox
  2598.  
  2599. ' /////////////////////////////////////////////////////////////////////////////
  2600. ' DRAW A 2-D BOX (OUTLINE)
  2601. ' https://www.qb64.org/wiki/LINE
  2602.  
  2603. ' The style parameter 0-255 doesn't seemt to have a solid line?
  2604.  
  2605. 'SUB DrawStyledOutlineBox (iX%, iY%, iSize%, iColor%, iStyle%)
  2606. SUB DrawStyledOutlineBox (iX%, iY%, iSize%, iColor&, iStyle%)
  2607.     ' LINE [STEP] [(column1, row1)]-[STEP] (column2, row2), color[, [{B|BF}], style%]
  2608.     ' B creates a box outline with each side parallel to the program screen sides. BF creates a filled box.
  2609.     ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  2610.    
  2611.     LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor&, B, iStyle%
  2612. END SUB ' DrawStyledOutlineBox
  2613.  
  2614. ' /////////////////////////////////////////////////////////////////////////////
  2615. ' DRAW A 2-D BOX (OUTLINE) WITH A SOLID LINE
  2616.  
  2617. SUB DrawOutlineBox (iX%, iY%, iSize2%, iColor&, iWeight2%)
  2618.     Dim iFromX%
  2619.     Dim iFromY%
  2620.     Dim iToX%
  2621.     Dim iToY%
  2622.     iSize% = iSize2% - 1
  2623.     iWeight% = iWeight2% - 1
  2624.     IF iWeight% = 0 THEN
  2625.         ' TOP LINE
  2626.         iFromX% = iX%
  2627.         iFromY% = iY%
  2628.         iToX% = iX% + iSize%
  2629.         iToY% = iY%
  2630.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2631.        
  2632.         ' BOTTOM LINE
  2633.         iFromX% = iX%
  2634.         iFromY% = iY% + iSize%
  2635.         iToX% = iX% + iSize%
  2636.         iToY% = iY% + iSize%
  2637.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2638.        
  2639.         ' LEFT LINE
  2640.         iFromX% = iX%
  2641.         iFromY% = iY%
  2642.         iToX% = iX%
  2643.         iToY% = iY% + iSize%
  2644.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2645.        
  2646.         ' RIGHT LINE
  2647.         iFromX% = iX% + iSize%
  2648.         iFromY% = iY%
  2649.         iToX% = iX% + iSize%
  2650.         iToY% = iY% + iSize%
  2651.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2652.     ELSEIF iWeight% > 0 THEN
  2653.         ' TOP LINE
  2654.         FOR iFromY% = iY% TO (iY% + iWeight%)
  2655.             iFromX% = iX%
  2656.             'iFromY% = iY%
  2657.             iToX% = iX% + iSize%
  2658.             iToY% = iFromY%
  2659.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2660.         NEXT iFromY%
  2661.        
  2662.         ' BOTTOM LINE
  2663.         FOR iFromY% = ((iY% + iSize%) - iWeight%) TO (iY% + iSize%)
  2664.             iFromX% = iX%
  2665.             'iFromY% = iY% + iSize%
  2666.             iToX% = iX% + iSize%
  2667.             iToY% = iFromY%
  2668.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2669.         NEXT iFromY%
  2670.        
  2671.         ' LEFT LINE
  2672.         FOR iFromX% = iX% TO (iX% + iWeight%)
  2673.             'iFromX% = iX%
  2674.             iFromY% = iY%
  2675.             iToX% = iFromX%
  2676.             iToY% = iY% + iSize%
  2677.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2678.         NEXT iFromX%
  2679.        
  2680.         ' RIGHT LINE
  2681.         FOR iFromX% = ((iX% + iSize%) - iWeight%) TO (iX% + iSize%)
  2682.             'iFromX% = iX% + iSize%
  2683.             iFromY% = iY%
  2684.             iToX% = iFromX%
  2685.             iToY% = iY% + iSize%
  2686.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2687.         NEXT iFromX%
  2688.     END IF
  2689. END SUB ' DrawOutlineBox
  2690.  
  2691. ' /////////////////////////////////////////////////////////////////////////////
  2692.  
  2693. Function GetPaletteFromColor%(iColor&)
  2694.     SELECT CASE iColor&
  2695.         CASE cEmpty&:
  2696.             GetPaletteFromColor% = 0
  2697.         CASE cBlack&:
  2698.             GetPaletteFromColor% = 1
  2699.         CASE cDarkGray&:
  2700.             GetPaletteFromColor% = 2
  2701.         CASE cDimGray&:
  2702.             GetPaletteFromColor% = 3
  2703.         CASE cGray&:
  2704.             GetPaletteFromColor% = 4
  2705.         CASE cLightGray&:
  2706.             GetPaletteFromColor% = 5
  2707.         CASE cSilver&:
  2708.             GetPaletteFromColor% = 6
  2709.         CASE cWhite&:
  2710.             GetPaletteFromColor% = 7
  2711.         CASE cRed&:
  2712.             GetPaletteFromColor% = 8
  2713.         CASE cOrangeRed&:
  2714.             GetPaletteFromColor% = 9
  2715.         CASE cDarkOrange&:
  2716.             GetPaletteFromColor% = 10
  2717.         CASE cOrange&:
  2718.             GetPaletteFromColor% = 11
  2719.         CASE cGold&:
  2720.             GetPaletteFromColor% = 12
  2721.         CASE cYellow&:
  2722.             GetPaletteFromColor% = 13
  2723.         CASE cOliveDrab1&:
  2724.             GetPaletteFromColor% = 14
  2725.         CASE cLime&:
  2726.             GetPaletteFromColor% = 15
  2727.         CASE cMediumSpringGreen&:
  2728.             GetPaletteFromColor% = 16
  2729.         CASE cCyan&:
  2730.             GetPaletteFromColor% = 17
  2731.         CASE cDeepSkyBlue&:
  2732.             GetPaletteFromColor% = 18
  2733.         CASE cDodgerBlue&:
  2734.             GetPaletteFromColor% = 19
  2735.         CASE cSeaBlue&:
  2736.             GetPaletteFromColor% = 20
  2737.         CASE cBlue&:
  2738.             GetPaletteFromColor% = 21
  2739.         CASE cBluePurple&:
  2740.             GetPaletteFromColor% = 22
  2741.         CASE cDeepPurple&:
  2742.             GetPaletteFromColor% = 23
  2743.         CASE cPurple&:
  2744.             GetPaletteFromColor% = 24
  2745.         CASE cPurpleRed&:
  2746.             GetPaletteFromColor% = 25
  2747.         CASE ELSE:
  2748.             GetPaletteFromColor% = 0
  2749.     END SELECT
  2750. End Function ' GetPaletteFromColor%
  2751.  
  2752. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2753. ' END GRAPHICS FUNCTIONS
  2754. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2755.  
  2756. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2757. ' BEGIN GENERAL PURPOSE FUNCTIONS
  2758. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2759.  
  2760. ' /////////////////////////////////////////////////////////////////////////////
  2761.  
  2762. Function cstr$ (myValue)
  2763.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  2764.     cstr$ = _Trim$(Str$(myValue))
  2765. End Function ' cstr$
  2766.  
  2767. ' /////////////////////////////////////////////////////////////////////////////
  2768.  
  2769. Function cstrl$ (myValue As Long)
  2770.     cstrl$ = _Trim$(Str$(myValue))
  2771. End Function ' cstrl$
  2772.  
  2773. ' /////////////////////////////////////////////////////////////////////////////
  2774.  
  2775. Function cstrs$ (myValue As Single)
  2776.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  2777.     cstrs$ = _Trim$(Str$(myValue))
  2778. End Function ' cstrs$
  2779.  
  2780. ' /////////////////////////////////////////////////////////////////////////////
  2781.  
  2782. Function IIF (Condition, IfTrue, IfFalse)
  2783.     If Condition Then IIF = IfTrue Else IIF = IfFalse
  2784.  
  2785. ' /////////////////////////////////////////////////////////////////////////////
  2786.  
  2787. Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
  2788.     If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
  2789.  
  2790. ' /////////////////////////////////////////////////////////////////////////////
  2791. ' From: Bitwise Manipulations By Steven Roman
  2792. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  2793.  
  2794. ' Returns the 8-bit binary representation
  2795. ' of an integer iInput where 0 <= iInput <= 255
  2796.  
  2797. Function GetBinary$ (iInput1 As Integer)
  2798.     Dim sResult As String
  2799.     Dim iLoop As Integer
  2800.     Dim iInput As Integer: iInput = iInput1
  2801.  
  2802.     sResult = ""
  2803.  
  2804.     If iInput >= 0 And iInput <= 255 Then
  2805.         For iLoop = 1 To 8
  2806.             sResult = LTrim$(RTrim$(Str$(iInput Mod 2))) + sResult
  2807.             iInput = iInput \ 2
  2808.             'If iLoop = 4 Then sResult = " " + sResult
  2809.         Next iLoop
  2810.     End If
  2811.  
  2812.     GetBinary$ = sResult
  2813. End Function ' GetBinary$
  2814.  
  2815. ' /////////////////////////////////////////////////////////////////////////////
  2816. ' wonderfully inefficient way to read if a bit is set
  2817. ' ival = GetBit256%(int we are comparing, int containing the bits we want to read)
  2818.  
  2819. ' See also: GetBit256%, SetBit256%
  2820.  
  2821. Function GetBit256% (iNum1 As Integer, iBit1 As Integer)
  2822.     Dim iResult As Integer
  2823.     Dim sNum As String
  2824.     Dim sBit As String
  2825.     Dim iLoop As Integer
  2826.     Dim bContinue As Integer
  2827.     'DIM iTemp AS INTEGER
  2828.     Dim iNum As Integer: iNum = iNum1
  2829.     Dim iBit As Integer: iBit = iBit1
  2830.  
  2831.     iResult = FALSE
  2832.     bContinue = TRUE
  2833.  
  2834.     If iNum < 256 And iBit <= 128 Then
  2835.         sNum = GetBinary$(iNum)
  2836.         sBit = GetBinary$(iBit)
  2837.         For iLoop = 1 To 8
  2838.             If Mid$(sBit, iLoop, 1) = "1" Then
  2839.                 'if any of the bits in iBit are false, return false
  2840.                 If Mid$(sNum, iLoop, 1) = "0" Then
  2841.                     iResult = FALSE
  2842.                     bContinue = FALSE
  2843.                     Exit For
  2844.                 End If
  2845.             End If
  2846.         Next iLoop
  2847.         If bContinue = TRUE Then
  2848.             iResult = TRUE
  2849.         End If
  2850.     End If
  2851.  
  2852.     GetBit256% = iResult
  2853. End Function ' GetBit256%
  2854.  
  2855. ' /////////////////////////////////////////////////////////////////////////////
  2856. ' From: Bitwise Manipulations By Steven Roman
  2857. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  2858.  
  2859. ' Returns the integer that corresponds to a binary string of length 8
  2860.  
  2861. Function GetIntegerFromBinary% (sBinary1 As String)
  2862.     Dim iResult As Integer
  2863.     Dim iLoop As Integer
  2864.     Dim strBinary As String
  2865.     Dim sBinary As String: sBinary = sBinary1
  2866.  
  2867.     iResult = 0
  2868.     strBinary = Replace$(sBinary, " ", "") ' Remove any spaces
  2869.     For iLoop = 0 To Len(strBinary) - 1
  2870.         iResult = iResult + 2 ^ iLoop * Val(Mid$(strBinary, Len(strBinary) - iLoop, 1))
  2871.     Next iLoop
  2872.  
  2873.     GetIntegerFromBinary% = iResult
  2874. End Function ' GetIntegerFromBinary%
  2875.  
  2876. ' /////////////////////////////////////////////////////////////////////////////
  2877. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  2878.  
  2879. Function IsEven% (n)
  2880.     IF n MOD 2 = 0 THEN
  2881.         IsEven% = TRUE
  2882.     Else
  2883.         IsEven% = FALSE
  2884.     End If
  2885. End Function ' IsEven%
  2886.  
  2887. ' /////////////////////////////////////////////////////////////////////////////
  2888. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  2889.  
  2890. Function IsOdd% (n)
  2891.     IF n MOD 2 = 1 THEN
  2892.         IsOdd% = TRUE
  2893.     Else
  2894.         IsOdd% = FALSE
  2895.     End If
  2896. End Function ' IsOdd%
  2897.  
  2898. ' /////////////////////////////////////////////////////////////////////////////
  2899. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  2900.  
  2901. Function IsNum% (text$)
  2902.     Dim a$
  2903.     Dim b$
  2904.     a$ = _Trim$(text$)
  2905.     b$ = _Trim$(Str$(Val(text$)))
  2906.     If a$ = b$ Then
  2907.         IsNum% = TRUE
  2908.     Else
  2909.         IsNum% = FALSE
  2910.     End If
  2911. End Function ' IsNum%
  2912.  
  2913. ' /////////////////////////////////////////////////////////////////////////////
  2914. ' Split and join strings
  2915. ' https://www.qb64.org/forum/index.php?topic=1073.0
  2916.  
  2917. 'Combine all elements of in$() into a single string with delimiter$ separating the elements.
  2918.  
  2919. Function join$ (in$(), delimiter$)
  2920.     result$ = in$(LBound(in$))
  2921.     For i = LBound(in$) + 1 To UBound(in$)
  2922.         result$ = result$ + delimiter$ + in$(i)
  2923.     Next i
  2924.     join$ = result$
  2925. End Function ' join$
  2926.  
  2927. ' /////////////////////////////////////////////////////////////////////////////
  2928. ' ABS was returning strange values with type LONG
  2929. ' so I created this which does not.
  2930.  
  2931. Function LongABS& (lngValue As Long)
  2932.     If Sgn(lngValue) = -1 Then
  2933.         LongABS& = 0 - lngValue
  2934.     Else
  2935.         LongABS& = lngValue
  2936.     End If
  2937. End Function ' LongABS&
  2938.  
  2939. ' /////////////////////////////////////////////////////////////////////////////
  2940. ' Re: Does a Is Number function exist in QB64?
  2941. ' https://www.qb64.org/forum/index.php?topic=896.15
  2942.  
  2943. ' MWheatley
  2944. ' « Reply #18 on: January 01, 2019, 11:24:30 AM »
  2945.  
  2946. ' returns 1 if string is an integer, 0 if not
  2947. Function IsNumber (text$)
  2948.     Dim i As Integer
  2949.  
  2950.     IsNumber = 1
  2951.     For i = 1 To Len(text$)
  2952.         If Asc(Mid$(text$, i, 1)) < 45 Or Asc(Mid$(text$, i, 1)) >= 58 Then
  2953.             IsNumber = 0
  2954.             Exit For
  2955.         ElseIf Asc(Mid$(text$, i, 1)) = 47 Then
  2956.             IsNumber = 0
  2957.             Exit For
  2958.         End If
  2959.     Next i
  2960. End Function ' IsNumber
  2961.  
  2962. ' /////////////////////////////////////////////////////////////////////////////
  2963. ' iNum% = PromptForIntegerInRange%("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  2964.  
  2965. Function PromptForIntegerInRange% (sPrompt$, iMin%, iMax%, iDefault%)
  2966.     Dim iValue%
  2967.     Dim bFinished%
  2968.     Dim sPrompt1$
  2969.     Dim in$
  2970.  
  2971.     If Len(sPrompt$) > 0 Then
  2972.         sPrompt1$ = sPrompt$
  2973.     Else
  2974.         sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  2975.     End If
  2976.  
  2977.     sPrompt1$ = Replace$(sPrompt1$, "{min}", cstr$(iMin%))
  2978.     sPrompt1$ = Replace$(sPrompt1$, "{max}", cstr$(iMax%))
  2979.  
  2980.     bFinished% = FALSE
  2981.     Do
  2982.         Print sPrompt1$
  2983.  
  2984.         Input in$
  2985.         in$ = _Trim$(in$)
  2986.         If Len(in$) > 0 Then
  2987.             If IsNumber(in$) Then
  2988.                 iValue% = Val(in$)
  2989.                 If iValue% >= iMin% And iValue% <= iMax% Then
  2990.                     'bFinished% = TRUE
  2991.                     Exit Do
  2992.                 Else
  2993.                     Print "Number out of range."
  2994.                     Print
  2995.                 End If
  2996.             Else
  2997.                 Print "Not a valid number."
  2998.                 Print
  2999.             End If
  3000.         Else
  3001.             iValue% = iDefault%
  3002.             Exit Do
  3003.             'bFinished% = TRUE
  3004.         End If
  3005.     Loop Until bFinished% = TRUE
  3006.  
  3007.     PromptForIntegerInRange% = iValue%
  3008. End Function ' PromptForIntegerInRange%
  3009.  
  3010. ' /////////////////////////////////////////////////////////////////////////////
  3011. ' iNum& = PromptForLongInRange&("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  3012.  
  3013. Function PromptForLongInRange& (sPrompt$, iMin&, iMax&, iDefault&)
  3014.     Dim iValue&
  3015.     Dim bFinished&
  3016.     Dim sPrompt1$
  3017.     Dim in$
  3018.    
  3019.     bFinished& = FALSE
  3020.     Do
  3021.         If Len(sPrompt$) > 0 Then
  3022.             sPrompt1$ = sPrompt$
  3023.         Else
  3024.             sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  3025.         End If
  3026.        
  3027.         sPrompt1$ = Replace$ (sPrompt1$, "{min}", cstrl$(iMin&))
  3028.         sPrompt1$ = Replace$ (sPrompt1$, "{max}", cstrl$(iMax&))
  3029.        
  3030.         Input in$
  3031.         in$ = _Trim$(in$)
  3032.         If Len(in$) > 0 Then
  3033.             If IsNumber(in$) Then
  3034.                 iValue& = Val(in$)
  3035.                 If iValue& >= iMin& And iValue& <= iMax& Then
  3036.                     bFinished& = TRUE
  3037.                 Else
  3038.                     Print "Number out of range."
  3039.                     Print
  3040.                 End If
  3041.             Else
  3042.                 Print "Not a valid number."
  3043.                 Print
  3044.             End If
  3045.         Else
  3046.             iValue& = iDefault&
  3047.             bFinished& = TRUE
  3048.         End If
  3049.     Loop Until bFinished&
  3050.    
  3051.     PromptForLongInRange& = iValue&
  3052. End Function ' PromptForLongInRange&
  3053.  
  3054. ' /////////////////////////////////////////////////////////////////////////////
  3055. ' Returns blank if successful else returns error message.
  3056.  
  3057. Function PrintFile$ (sFileName As String, sText As String, bAppend As Integer)
  3058.     'x = 1: y = 2: z$ = "Three"
  3059.  
  3060.     Dim sError As String: sError = ""
  3061.  
  3062.     If Len(sError) = 0 Then
  3063.         If (bAppend = TRUE) Then
  3064.             If _FileExists(sFileName) Then
  3065.                 Open sFileName For Append As #1 ' opens an existing file for appending
  3066.             Else
  3067.                 sError = "Error in PrintFile$ : File not found. Cannot append."
  3068.             End If
  3069.         Else
  3070.             Open sFileName For Output As #1 ' opens and clears an existing file or creates new empty file
  3071.         End If
  3072.     End If
  3073.     If Len(sError) = 0 Then
  3074.         ' WRITE places text in quotes in the file
  3075.         'WRITE #1, x, y, z$
  3076.         'WRITE #1, sText
  3077.  
  3078.         ' PRINT does not put text inside quotes
  3079.         Print #1, sText
  3080.  
  3081.         Close #1
  3082.  
  3083.         'PRINT "File created with data. Press a key!"
  3084.         'K$ = INPUT$(1) 'press a key
  3085.  
  3086.         'OPEN sFileName FOR INPUT AS #2 ' opens a file to read it
  3087.         'INPUT #2, a, b, c$
  3088.         'CLOSE #2
  3089.  
  3090.         'PRINT a, b, c$
  3091.         'WRITE a, b, c$
  3092.     End If
  3093.  
  3094.     PrintFile$ = sError
  3095. End Function ' PrintFile$
  3096.  
  3097. ' /////////////////////////////////////////////////////////////////////////////
  3098. ' Generate random value between Min and Max.
  3099. Function RandomNumber% (Min%, Max%)
  3100.     Dim NumSpread%
  3101.  
  3102.     ' SET RANDOM SEED
  3103.     'Randomize ' Initialize random-number generator.
  3104.  
  3105.     ' GET RANDOM # Min%-Max%
  3106.     'RandomNumber = Int((Max * Rnd) + Min) ' generate number
  3107.  
  3108.     NumSpread% = (Max% - Min%) + 1
  3109.  
  3110.     RandomNumber% = Int(Rnd * NumSpread%) + Min% ' GET RANDOM # BETWEEN Max% AND Min%
  3111.  
  3112. End Function ' RandomNumber%
  3113.  
  3114. ' /////////////////////////////////////////////////////////////////////////////
  3115.  
  3116. Sub RandomNumberTest
  3117.     Dim iCols As Integer: iCols = 10
  3118.     Dim iRows As Integer: iRows = 20
  3119.     Dim iLoop As Integer
  3120.     Dim iX As Integer
  3121.     Dim iY As Integer
  3122.     Dim sError As String
  3123.     Dim sFileName As String
  3124.     Dim sText As String
  3125.     Dim bAppend As Integer
  3126.     Dim iMin As Integer
  3127.     Dim iMax As Integer
  3128.     Dim iNum As Integer
  3129.     Dim iErrorCount As Integer
  3130.     Dim sInput$
  3131.  
  3132.     sFileName = "c:\temp\maze_test_1.txt"
  3133.     sText = "Count" + Chr$(9) + "Min" + Chr$(9) + "Max" + Chr$(9) + "Random"
  3134.     bAppend = FALSE
  3135.     sError = PrintFile$(sFileName, sText, bAppend)
  3136.     If Len(sError) = 0 Then
  3137.         bAppend = TRUE
  3138.         iErrorCount = 0
  3139.  
  3140.         iMin = 0
  3141.         iMax = iCols - 1
  3142.         For iLoop = 1 To 100
  3143.             iNum = RandomNumber%(iMin, iMax)
  3144.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  3145.             sError = PrintFile$(sFileName, sText, bAppend)
  3146.             If Len(sError) > 0 Then
  3147.                 iErrorCount = iErrorCount + 1
  3148.                 Print Str$(iLoop) + ". ERROR"
  3149.                 Print "    " + "iMin=" + Str$(iMin)
  3150.                 Print "    " + "iMax=" + Str$(iMax)
  3151.                 Print "    " + "iNum=" + Str$(iNum)
  3152.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  3153.                 Print "    " + sError
  3154.             End If
  3155.         Next iLoop
  3156.  
  3157.         iMin = 0
  3158.         iMax = iRows - 1
  3159.         For iLoop = 1 To 100
  3160.             iNum = RandomNumber%(iMin, iMax)
  3161.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  3162.             sError = PrintFile$(sFileName, sText, bAppend)
  3163.             If Len(sError) > 0 Then
  3164.                 iErrorCount = iErrorCount + 1
  3165.                 Print Str$(iLoop) + ". ERROR"
  3166.                 Print "    " + "iMin=" + Str$(iMin)
  3167.                 Print "    " + "iMax=" + Str$(iMax)
  3168.                 Print "    " + "iNum=" + Str$(iNum)
  3169.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  3170.                 Print "    " + sError
  3171.             End If
  3172.         Next iLoop
  3173.  
  3174.         Print "Finished generating numbers. Errors: " + Str$(iErrorCount)
  3175.     Else
  3176.         Print "Error creating file " + Chr$(34) + sFileName + Chr$(34) + "."
  3177.         Print sError
  3178.     End If
  3179.  
  3180.     Input "Press <ENTER> to continue", sInput$
  3181. End Sub ' RandomNumberTest
  3182.  
  3183. ' /////////////////////////////////////////////////////////////////////////////
  3184. ' FROM: String Manipulation
  3185. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_5964-0/
  3186. '
  3187. 'SUMMARY:
  3188. '   Purpose:  A library of custom functions that transform strings.
  3189. '   Author:   Dustinian Camburides (dustinian@gmail.com)
  3190. '   Platform: QB64 (www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there])
  3191. '   Revision: 1.6
  3192. '   Updated:  5/28/2012
  3193.  
  3194. 'SUMMARY:
  3195. '[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
  3196. 'INPUT:
  3197. 'Text: The input string; the text that's being manipulated.
  3198. 'Find: The specified sub-string; the string sought within the [Text] string.
  3199. 'Add: The sub-string that's being added to the [Text] string.
  3200.  
  3201. Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
  3202.     ' VARIABLES:
  3203.     Dim Text2 As String
  3204.     Dim Find2 As String
  3205.     Dim Add2 As String
  3206.     Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
  3207.     Dim strBefore As String ' The characters before the string to be replaced.
  3208.     Dim strAfter As String ' The characters after the string to be replaced.
  3209.  
  3210.     ' INITIALIZE:
  3211.     ' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
  3212.     Text2 = Text1
  3213.     Find2 = Find1
  3214.     Add2 = Add1
  3215.  
  3216.     lngLocation = InStr(1, Text2, Find2)
  3217.  
  3218.     ' PROCESSING:
  3219.     ' While [Find2] appears in [Text2]...
  3220.     While lngLocation
  3221.         ' Extract all Text2 before the [Find2] substring:
  3222.         strBefore = Left$(Text2, lngLocation - 1)
  3223.  
  3224.         ' Extract all text after the [Find2] substring:
  3225.         strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
  3226.  
  3227.         ' Return the substring:
  3228.         Text2 = strBefore + Add2 + strAfter
  3229.  
  3230.         ' Locate the next instance of [Find2]:
  3231.         lngLocation = InStr(1, Text2, Find2)
  3232.  
  3233.         ' Next instance of [Find2]...
  3234.     Wend
  3235.  
  3236.     ' OUTPUT:
  3237.     Replace$ = Text2
  3238. End Function ' Replace$
  3239.  
  3240. ' /////////////////////////////////////////////////////////////////////////////
  3241. ' fantastically inefficient way to set a bit
  3242.  
  3243. ' example use: arrMaze(iX, iY) = SetBit256%(arrMaze(iX, iY), cS, FALSE)
  3244.  
  3245. ' See also: GetBit256%, SetBit256%
  3246.  
  3247. ' newint=SetBit256%(oldint, int containing the bits we want to set, value to set them to)
  3248. Function SetBit256% (iNum1 As Integer, iBit1 As Integer, bVal1 As Integer)
  3249.     Dim sNum As String
  3250.     Dim sBit As String
  3251.     Dim sVal As String
  3252.     Dim iLoop As Integer
  3253.     Dim strResult As String
  3254.     Dim iResult As Integer
  3255.     Dim iNum As Integer: iNum = iNum1
  3256.     Dim iBit As Integer: iBit = iBit1
  3257.     Dim bVal As Integer: bVal = bVal1
  3258.  
  3259.     If iNum < 256 And iBit <= 128 Then
  3260.         sNum = GetBinary$(iNum)
  3261.         sBit = GetBinary$(iBit)
  3262.         If bVal = TRUE Then
  3263.             sVal = "1"
  3264.         Else
  3265.             sVal = "0"
  3266.         End If
  3267.         strResult = ""
  3268.         For iLoop = 1 To 8
  3269.             If Mid$(sBit, iLoop, 1) = "1" Then
  3270.                 strResult = strResult + sVal
  3271.             Else
  3272.                 strResult = strResult + Mid$(sNum, iLoop, 1)
  3273.             End If
  3274.         Next iLoop
  3275.         iResult = GetIntegerFromBinary%(strResult)
  3276.     Else
  3277.         iResult = iNum
  3278.     End If
  3279.  
  3280.     SetBit256% = iResult
  3281. End Function ' SetBit256%
  3282.  
  3283. ' /////////////////////////////////////////////////////////////////////////////
  3284. ' Split and join strings
  3285. ' https://www.qb64.org/forum/index.php?topic=1073.0
  3286. '
  3287. ' FROM luke, QB64 Developer
  3288. ' Date: February 15, 2019, 04:11:07 AM »
  3289. '
  3290. ' Given a string of words separated by spaces (or any other character),
  3291. ' splits it into an array of the words. I've no doubt many people have
  3292. ' written a version of this over the years and no doubt there's a million
  3293. ' ways to do it, but I thought I'd put mine here so we have at least one
  3294. ' version. There's also a join function that does the opposite
  3295. ' array -> single string.
  3296. '
  3297. ' Code is hopefully reasonably self explanatory with comments and a little demo.
  3298. ' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
  3299.  
  3300. 'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
  3301. 'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
  3302. '
  3303. 'delimiter$ must be one character long.
  3304. 'result$() must have been REDIMmed previously.
  3305.  
  3306. Sub split (in$, delimiter$, result$())
  3307.     ReDim result$(-1)
  3308.     start = 1
  3309.     Do
  3310.         While Mid$(in$, start, 1) = delimiter$
  3311.             start = start + 1
  3312.             If start > Len(in$) Then Exit Sub
  3313.         Wend
  3314.         finish = InStr(start, in$, delimiter$)
  3315.         If finish = 0 Then finish = Len(in$) + 1
  3316.         ReDim _Preserve result$(0 To UBound(result$) + 1)
  3317.         result$(UBound(result$)) = Mid$(in$, start, finish - start)
  3318.         start = finish + 1
  3319.     Loop While start <= Len(in$)
  3320. End Sub ' split
  3321.  
  3322. ' /////////////////////////////////////////////////////////////////////////////
  3323.  
  3324. Sub SplitTest
  3325.  
  3326.     Dim in$
  3327.     Dim delim$
  3328.     ReDim arrTest$(0)
  3329.     Dim iLoop%
  3330.  
  3331.     delim$ = Chr$(10)
  3332.     in$ = "this" + delim$ + "is" + delim$ + "a" + delim$ + "test"
  3333.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  3334.     Print "delim$ = " + Chr$(34) + delimeter$ + Chr$(34)
  3335.     split in$, delim$, arrTest$()
  3336.  
  3337.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  3338.         Print "arrTest$(" + LTrim$(RTrim$(Str$(iLoop%))) + ") = " + Chr$(34) + arrTest$(iLoop%) + Chr$(34)
  3339.     Next iLoop%
  3340.     Print
  3341.     Print "Split test finished."
  3342. End Sub ' SplitTest
  3343.  
  3344. ' /////////////////////////////////////////////////////////////////////////////
  3345.  
  3346. Sub WaitForEnter
  3347.     Dim in$
  3348.     Input "Press <ENTER> to continue", in$
  3349. End Sub ' WaitForEnter
  3350.  
  3351. ' /////////////////////////////////////////////////////////////////////////////
  3352. ' WaitForKey "Press <ESC> to continue", 27, 0
  3353. ' WaitForKey "Press <ENTER> to begin;", 13, 0
  3354. ' waitforkey "", 65, 5
  3355.  
  3356. Sub WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  3357.     ' SHOW PROMPT (IF SPECIFIED)
  3358.     If Len(prompt$) > 0 Then
  3359.         If Right$(prompt$, 1) <> ";" Then
  3360.             Print prompt$
  3361.         Else
  3362.             Print Right$(prompt$, Len(prompt$) - 1);
  3363.         End If
  3364.     End If
  3365.  
  3366.     ' WAIT FOR KEY
  3367.     Do: Loop Until _KeyDown(KeyCode&) ' leave loop when specified key pressed
  3368.  
  3369.     ' PAUSE AFTER (IF SPECIFIED)
  3370.     If DelaySeconds% < 1 Then
  3371.         _KeyClear: '_DELAY 1
  3372.     Else
  3373.         _KeyClear: _Delay DelaySeconds%
  3374.     End If
  3375. End Sub ' WaitForKey
  3376.  
  3377. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3378. ' END GENERAL PURPOSE FUNCTIONS
  3379. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3380.  
  3381. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3382. ' BEGIN COLOR ROUTINES
  3383. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3384.  
  3385. ' /////////////////////////////////////////////////////////////////////////////
  3386. ' Receives:
  3387. ' cycleColor = determines how foreColor, backColor are modified
  3388. ' foreColor  = the foreground color
  3389. ' backColor  = the background color (if needed)
  3390.  
  3391. ' /////////////////////////////////////////////////////////////////////////////
  3392. ' DoCycleColor colorScheme%, myColor&
  3393.  
  3394. ' colorScheme = color scheme (value is alternated on subsequent calls)
  3395. ' myColor     = the current color (value is incremented/decremented on subsequent calls)
  3396.  
  3397. ' colorScheme values:
  3398. '  1 Rainbow6 #1
  3399. '  9 Rainbow6 #2
  3400. '  2 Rainbow18 #1
  3401. ' 10 Rainbow18 #2
  3402. '  3 Grayscale #1
  3403. ' 11 Grayscale #2
  3404. '  4 Grayscale #1
  3405. ' 12 Grayscale #2
  3406.  
  3407. Sub DoCycleColor (colorScheme As Integer, myColor As Long)
  3408.     ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
  3409.     ' CYCLE FORE COLOR
  3410.  
  3411.     ' 1, 9 = simple rainbow
  3412.     If colorScheme = 1 Or colorScheme = 9 Then
  3413.         Select Case myColor
  3414.             Case cRed&:
  3415.                 myColor = cOrange&
  3416.             Case cOrange&:
  3417.                 myColor = cYellow&
  3418.             Case cYellow&:
  3419.                 myColor = cGreen&
  3420.             Case cGreen&:
  3421.                 myColor = cBlue&
  3422.             Case cBlue&:
  3423.                 myColor = cPurple&
  3424.             Case Else:
  3425.                 myColor = cRed&
  3426.         End Select
  3427.  
  3428.     ' 2, 10 = complex rainbow
  3429.     ElseIf colorScheme = 2 Or colorScheme = 10 Then
  3430.         Select Case myColor
  3431.             Case cRed&:
  3432.                 myColor = cOrangeRed&
  3433.             Case cOrangeRed&:
  3434.                 myColor = cDarkOrange&
  3435.             Case cDarkOrange&:
  3436.                 myColor = cOrange&
  3437.             Case cOrange&:
  3438.                 myColor = cGold&
  3439.             Case cGold&:
  3440.                 myColor = cYellow&
  3441.             Case cYellow&:
  3442.                 myColor = cOliveDrab1&
  3443.             Case cOliveDrab1&:
  3444.                 myColor = cLime&
  3445.             Case cLime&:
  3446.                 myColor = cMediumSpringGreen&
  3447.             Case cMediumSpringGreen&:
  3448.                 myColor = cCyan&
  3449.             Case cCyan&:
  3450.                 myColor = cDeepSkyBlue&
  3451.             Case cDeepSkyBlue&:
  3452.                 myColor = cDodgerBlue&
  3453.             Case cDodgerBlue&:
  3454.                 myColor = cSeaBlue&
  3455.             Case cSeaBlue&:
  3456.                 myColor = cBlue&
  3457.             Case cBlue&:
  3458.                 myColor = cBluePurple&
  3459.             Case cBluePurple&:
  3460.                 myColor = cDeepPurple&
  3461.             Case cDeepPurple&:
  3462.                 myColor = cPurple&
  3463.             Case cPurple&:
  3464.                 myColor = cPurpleRed&
  3465.             Case Else:
  3466.                 myColor = cRed&
  3467.         End Select
  3468.  
  3469.     ' 3, 11 = grayscale, ascending
  3470.     ElseIf colorScheme = 3 Or colorScheme = 11 Then
  3471.         Select Case myColor
  3472.             Case cBlack&:
  3473.                 myColor = cDarkGray&
  3474.             Case cDarkGray&:
  3475.                 myColor = cDimGray&
  3476.             Case cDimGray&:
  3477.                 myColor = cGray&
  3478.             Case cGray&:
  3479.                 myColor = cLightGray&
  3480.             Case cLightGray&:
  3481.                 myColor = cSilver&
  3482.             Case cSilver&:
  3483.                 myColor = cWhite&
  3484.             Case Else:
  3485.                 'myColor = cBlack&
  3486.                 myColor = cSilver&
  3487.  
  3488.                 ' go in the other direction!
  3489.                 If colorScheme = 3 Then
  3490.                     colorScheme = 4
  3491.                 Else
  3492.                     colorScheme = 12
  3493.                 End If
  3494.  
  3495.         End Select
  3496.  
  3497.     ' 4, 8, 12 = grayscale, descending
  3498.     ElseIf colorScheme = 4 Or colorScheme = 12 Then
  3499.         Select Case myColor
  3500.             Case cWhite&:
  3501.                 myColor = cSilver&
  3502.             Case cSilver&:
  3503.                 myColor = cLightGray&
  3504.             Case cLightGray&:
  3505.                 myColor = cGray&
  3506.             Case cGray&:
  3507.                 myColor = cDimGray&
  3508.             Case cDimGray&:
  3509.                 myColor = cDarkGray&
  3510.             Case cDarkGray&:
  3511.                 myColor = cBlack&
  3512.             Case Else:
  3513.                 myColor = cDarkGray&
  3514.  
  3515.                 ' go in the other direction!
  3516.                 If colorScheme = 4 Then
  3517.                     colorScheme = 3
  3518.                 Else
  3519.                     colorScheme = 11
  3520.                 End If
  3521.         End Select
  3522.  
  3523.     End If
  3524.    
  3525. End Sub ' DoCycleColor
  3526.  
  3527. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3528. ' END COLOR ROUTINES
  3529. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3530.  
  3531. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3532. ' BEGIN COLOR FUNCTIONS
  3533. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3534.  
  3535. ' NOTE: these are mostly negative numbers
  3536. '       and have to be forced to positive
  3537. '       when stored in the dictionary
  3538. '       (only cEmpty& should be negative)
  3539.  
  3540. Function cRed& ()
  3541.     cRed& = _RGB32(255, 0, 0)
  3542.  
  3543. Function cOrangeRed& ()
  3544.     cOrangeRed& = _RGB32(255, 69, 0)
  3545. End Function ' cOrangeRed&
  3546.  
  3547. Function cDarkOrange& ()
  3548.     cDarkOrange& = _RGB32(255, 140, 0)
  3549. End Function ' cDarkOrange&
  3550.  
  3551. Function cOrange& ()
  3552.     cOrange& = _RGB32(255, 165, 0)
  3553. End Function ' cOrange&
  3554.  
  3555. Function cGold& ()
  3556.     cGold& = _RGB32(255, 215, 0)
  3557. End Function ' cGold&
  3558.  
  3559. Function cYellow& ()
  3560.     cYellow& = _RGB32(255, 255, 0)
  3561. End Function ' cYellow&
  3562.  
  3563. ' LONG-HAIRED FRIENDS OF JESUS OR NOT,
  3564. ' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
  3565. ' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
  3566. Function cChartreuse& ()
  3567.     cChartreuse& = _RGB32(127, 255, 0)
  3568. End Function ' cChartreuse&
  3569.  
  3570. ' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
  3571. Function cOliveDrab1& ()
  3572.     cOliveDrab1& = _RGB32(192, 255, 62)
  3573. End Function ' cOliveDrab1&
  3574.  
  3575. Function cLime& ()
  3576.     cLime& = _RGB32(0, 255, 0)
  3577. End Function ' cLime&
  3578.  
  3579. Function cMediumSpringGreen& ()
  3580.     cMediumSpringGreen& = _RGB32(0, 250, 154)
  3581. End Function ' cMediumSpringGreen&
  3582.  
  3583. Function cCyan& ()
  3584.     cCyan& = _RGB32(0, 255, 255)
  3585. End Function ' cCyan&
  3586.  
  3587. Function cDeepSkyBlue& ()
  3588.     cDeepSkyBlue& = _RGB32(0, 191, 255)
  3589. End Function ' cDeepSkyBlue&
  3590.  
  3591. Function cDodgerBlue& ()
  3592.     cDodgerBlue& = _RGB32(30, 144, 255)
  3593. End Function ' cDodgerBlue&
  3594.  
  3595. Function cSeaBlue& ()
  3596.     cSeaBlue& = _RGB32(0, 64, 255)
  3597. End Function ' cSeaBlue&
  3598.  
  3599. Function cBlue& ()
  3600.     cBlue& = _RGB32(0, 0, 255)
  3601. End Function ' cBlue&
  3602.  
  3603. Function cBluePurple& ()
  3604.     cBluePurple& = _RGB32(64, 0, 255)
  3605. End Function ' cBluePurple&
  3606.  
  3607. Function cDeepPurple& ()
  3608.     cDeepPurple& = _RGB32(96, 0, 255)
  3609. End Function ' cDeepPurple&
  3610.  
  3611. Function cPurple& ()
  3612.     cPurple& = _RGB32(128, 0, 255)
  3613. End Function ' cPurple&
  3614.  
  3615. Function cPurpleRed& ()
  3616.     cPurpleRed& = _RGB32(128, 0, 192)
  3617. End Function ' cPurpleRed&
  3618.  
  3619. Function cDarkRed& ()
  3620.     cDarkRed& = _RGB32(160, 0, 64)
  3621. End Function ' cDarkRed&
  3622.  
  3623. Function cBrickRed& ()
  3624.     cBrickRed& = _RGB32(192, 0, 32)
  3625. End Function ' cBrickRed&
  3626.  
  3627. Function cDarkGreen& ()
  3628.     cDarkGreen& = _RGB32(0, 100, 0)
  3629. End Function ' cDarkGreen&
  3630.  
  3631. Function cGreen& ()
  3632.     cGreen& = _RGB32(0, 128, 0)
  3633. End Function ' cGreen&
  3634.  
  3635. Function cOliveDrab& ()
  3636.     cOliveDrab& = _RGB32(107, 142, 35)
  3637. End Function ' cOliveDrab&
  3638.  
  3639. Function cLightPink& ()
  3640.     cLightPink& = _RGB32(255, 182, 193)
  3641. End Function ' cLightPink&
  3642.  
  3643. Function cHotPink& ()
  3644.     cHotPink& = _RGB32(255, 105, 180)
  3645. End Function ' cHotPink&
  3646.  
  3647. Function cDeepPink& ()
  3648.     cDeepPink& = _RGB32(255, 20, 147)
  3649. End Function ' cDeepPink&
  3650.  
  3651. Function cMagenta& ()
  3652.     cMagenta& = _RGB32(255, 0, 255)
  3653. End Function ' cMagenta&
  3654.  
  3655. Function cBlack& ()
  3656.     cBlack& = _RGB32(0, 0, 0)
  3657. End Function ' cBlack&
  3658.  
  3659. Function cDimGray& ()
  3660.     cDimGray& = _RGB32(105, 105, 105)
  3661. End Function ' cDimGray&
  3662.  
  3663. Function cGray& ()
  3664.     cGray& = _RGB32(128, 128, 128)
  3665. End Function ' cGray&
  3666.  
  3667. Function cDarkGray& ()
  3668.     cDarkGray& = _RGB32(169, 169, 169)
  3669. End Function ' cDarkGray&
  3670.  
  3671. Function cSilver& ()
  3672.     cSilver& = _RGB32(192, 192, 192)
  3673. End Function ' cSilver&
  3674.  
  3675. Function cLightGray& ()
  3676.     cLightGray& = _RGB32(211, 211, 211)
  3677. End Function ' cLightGray&
  3678.  
  3679. Function cGainsboro& ()
  3680.     cGainsboro& = _RGB32(220, 220, 220)
  3681. End Function ' cGainsboro&
  3682.  
  3683. Function cWhiteSmoke& ()
  3684.     cWhiteSmoke& = _RGB32(245, 245, 245)
  3685. End Function ' cWhiteSmoke&
  3686.  
  3687. Function cWhite& ()
  3688.     cWhite& = _RGB32(255, 255, 255)
  3689. End Function ' cWhite&
  3690.  
  3691. Function cDarkBrown& ()
  3692.     cDarkBrown& = _RGB32(128, 64, 0)
  3693. End Function ' cDarkBrown&
  3694.  
  3695. Function cLightBrown& ()
  3696.     cLightBrown& = _RGB32(196, 96, 0)
  3697. End Function ' cLightBrown&
  3698.  
  3699. Function cKhaki& ()
  3700.     cKhaki& = _RGB32(240, 230, 140)
  3701. End Function ' cKhaki&
  3702.  
  3703. Function cEmpty& ()
  3704.     cEmpty& = -1
  3705. End Function ' cEmpty&
  3706.  
  3707. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3708. ' END COLOR FUNCTIONS
  3709. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3710.  
  3711. ' #END
  3712. ' ################################################################################################################################################################
  3713.  



Exhibit B: simple test works
Code: QB64: [Select]
  1. ' Isomatric mapping demo re-revisited
  2. ' test code
  3.  
  4. ' Based on Isometric Mapping Demo
  5. ' by SMcNeill, bplus, and others at
  6. ' https://www.qb64.org/forum/index.php?topic=1903.30
  7.  
  8. ' -----------------------------------------------------------------------------
  9. ' boolean constants
  10. ' -----------------------------------------------------------------------------
  11. Const FALSE = 0
  12. Const TRUE = Not FALSE
  13.  
  14. ' -----------------------------------------------------------------------------
  15. ' constants for drawing the 2.5D screen
  16. ' -----------------------------------------------------------------------------
  17. Const cGridOffsetX = 200
  18. Const cGridOffsetY = 200
  19. Const cGridOffsetZ = 0
  20.  
  21. ' -----------------------------------------------------------------------------
  22. ' TEST DRAWING IN COLORS, WHITE NOT VISIBLE
  23. ' -----------------------------------------------------------------------------
  24. Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  25.  
  26. Dim iScreenOffsetX As Integer : iScreenOffsetX = 450
  27. Dim iScreenOffsetY As Integer : iScreenOffsetY = 200
  28. Dim iGridSize As Integer : iGridSize = 8
  29. Dim alpha& : alpha& = 255
  30. Dim iPosX1%
  31. Dim iPosX2%
  32. Dim iPosY1%
  33. Dim iPosY2%
  34. Dim iPosZ1%
  35. Dim in$
  36.  
  37.  
  38. iColor = cRed&
  39. iPosX1% = 40 * iGridSize + cGridOffsetX
  40. iPosY1% = 10 * iGridSize + cGridOffsetY
  41. iPosZ1% = 10 * iGridSize + cGridOffsetZ
  42. iPosX2% = iPosX1% + iGridSize
  43. iPosY2% = iPosY1% + iGridSize
  44. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  45.  
  46. iColor = cLime&
  47. iPosX1% = 25 * iGridSize + cGridOffsetX
  48. iPosY1% = 20 * iGridSize + cGridOffsetY
  49. iPosZ1% = 10 * iGridSize + cGridOffsetZ
  50. iPosX2% = iPosX1% + iGridSize
  51. iPosY2% = iPosY1% + iGridSize
  52. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  53.  
  54. iColor = cBlue&
  55. iPosX1% = 20 * iGridSize + cGridOffsetX
  56. iPosY1% = 20 * iGridSize + cGridOffsetY
  57. iPosZ1% = 10 * iGridSize + cGridOffsetZ
  58. iPosX2% = iPosX1% + iGridSize
  59. iPosY2% = iPosY1% + iGridSize
  60. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  61.  
  62. iColor = cWhite&
  63. iPosX1% = 20 * iGridSize + cGridOffsetX
  64. iPosY1% = 20 * iGridSize + cGridOffsetY
  65. iPosZ1% = 20 * iGridSize + cGridOffsetZ
  66. iPosX2% = iPosX1% + iGridSize
  67. iPosY2% = iPosY1% + iGridSize
  68. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  69.  
  70. iColor = cYellow&
  71. iPosX1% = 30 * iGridSize + cGridOffsetX
  72. iPosY1% = 20 * iGridSize + cGridOffsetY
  73. iPosZ1% = 20 * iGridSize + cGridOffsetZ
  74. iPosX2% = iPosX1% + iGridSize
  75. iPosY2% = iPosY1% + iGridSize
  76. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  77.  
  78. iColor = cSilver&
  79. iPosX1% = 40 * iGridSize + cGridOffsetX
  80. iPosY1% = 10 * iGridSize + cGridOffsetY
  81. iPosZ1% = 30 * iGridSize + cGridOffsetZ
  82. iPosX2% = iPosX1% + iGridSize
  83. iPosY2% = iPosY1% + iGridSize
  84. IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  85.  
  86. PRINT "You should see 6 cubes, colored: red, lime, blue, white, yellow, silver."
  87. INPUT "PRESS <ENTER> TO CONTINUE";in$
  88. System ' return control to the operating system
  89.  
  90. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  91. ' BEGIN GRAPHICS FUNCTIONS
  92. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  93.  
  94. ' /////////////////////////////////////////////////////////////////////////////
  95.  
  96. Function CX2I (x As Long, y As Long) 'Convert Cartesian X To Isometic coordinates
  97.     CX2I = x - y
  98. End Function ' CX2I
  99.  
  100. ' /////////////////////////////////////////////////////////////////////////////
  101.  
  102. Function CY2I (x As Long, y As Long) 'Convert Cartesian Y To Isometic coordinates
  103.     CY2I = (x + y) / 2
  104. End Function ' CY2I
  105.  
  106. ' /////////////////////////////////////////////////////////////////////////////
  107. ' since we're drawing a diamond and not a square box, we can't use Line BF.
  108. ' We have to manually down the 4 points of the line.
  109.  
  110. Sub IsoLine (x, y, x2, y2, xoffset, yoffset, iColor As _Unsigned Long)
  111.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), iColor
  112.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), iColor
  113.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), iColor
  114.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), iColor
  115.     Paint (CX2I(x, y) + xoffset, CY2I(x, y) + 4), iColor 'and fill the diamond solid
  116.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), &HFFFFFFFF
  117.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), &HFFFFFFFF
  118.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), &HFFFFFFFF
  119.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), &HFFFFFFFF
  120. End Sub ' IsoLine
  121.  
  122. ' /////////////////////////////////////////////////////////////////////////////
  123. ' Like IsoLine, we're going to have to draw our lines manually.
  124. ' only in this case, we also need a Z coordinate to tell us how
  125. ' THICK/TALL/HIGH to make our tile
  126.  
  127. ' MODIFIED by madscijr to draw a single tile of height iHeight at Z axis
  128. ' MODIFIED by madscijr to accept an alpha& value to control transparency (where 0=fully transparent, 255=opaque)
  129.  
  130. ''Sub IsoLine3D (x, y, x2, y2, z, xoffset, yoffset, iColor As _Unsigned Long)
  131. 'Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long)
  132. Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long, alpha&)
  133.     Dim r 'as integer
  134.     Dim g 'as integer
  135.     Dim b 'as integer
  136.     'dim iNewColor As _Unsigned Long
  137.  
  138.     r = _Red32(iColor)
  139.     g = _Green32(iColor)
  140.     b = _Blue32(iColor)
  141.  
  142.     ' Let's just do all the math first this time.
  143.     ' We need to turn those 4 normal points into 4 isometric points (x, y, x1, y1)
  144.     TempX1 = CX2I(x, y) + xoffset
  145.     TempY1 = CY2I(x, y) + yoffset
  146.     TempX2 = CX2I(x2, y) + xoffset
  147.     TempY2 = CY2I(x2, y) + yoffset
  148.     TempX3 = CX2I(x2, y2) + xoffset
  149.     TempY3 = CY2I(x2, y2) + yoffset
  150.     TempX4 = CX2I(x, y2) + xoffset
  151.     TempY4 = CY2I(x, y2) + yoffset
  152.  
  153.     ' The top
  154.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, iColor
  155.     fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  156.  
  157.     If z <> 0 Then
  158.         ' TODO: maybe change which sides gets shaded depending on the direction of the light source?
  159.  
  160.         ' draw the left side, shaded 75%
  161.         'fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b)
  162.         fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b, alpha&)
  163.  
  164.         ' draw the right side,s haded 50%
  165.         'fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b)
  166.         fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b, alpha&)
  167.     Else
  168.         ' no need to draw any height, if there isn't any.
  169.     End If
  170. End Sub ' IsoLine3D
  171.  
  172. ' /////////////////////////////////////////////////////////////////////////////
  173. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  174. ' don’t go there: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  175.  
  176. Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  177.     Dim D As Long
  178.     Dim a&
  179.  
  180.     D = _Dest
  181.     a& = _NewImage(1, 1, 32)
  182.     _Dest a&
  183.     PSet (0, 0), K
  184.     _Dest D
  185.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  186.     _FreeImage a& ' <<< this is important!
  187. End Sub ' ftri
  188.  
  189. ' /////////////////////////////////////////////////////////////////////////////
  190. ' 2019-11-20 Steve saves some time with STATIC
  191. ' and saves and restores last dest
  192.  
  193. Sub ftri1 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  194.     Dim D As Long
  195.     Static a&
  196.  
  197.     D = _Dest
  198.     If a& = 0 Then
  199.         a& = _NewImage(1, 1, 32)
  200.     End If
  201.     _Dest a&
  202.     _DontBlend a&
  203.     PSet (0, 0), K
  204.     _Blend a&
  205.     _Dest D
  206.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  207. End Sub ' ftri1
  208.  
  209. ' /////////////////////////////////////////////////////////////////////////////
  210. ' original fill quad that may be at fault using Steve's fTri version
  211. ' need 4 non linear points (not all on 1 line) list them clockwise
  212. ' so x2, y2 is opposite of x4, y4
  213.  
  214. Sub fquad1 (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  215.     ftri1 x1, y1, x2, y2, x4, y4, K
  216.     ftri1 x3, y3, x2, y2, x4, y4, K
  217. End Sub ' fquad1
  218.  
  219. ' /////////////////////////////////////////////////////////////////////////////
  220. ' update 2019-12-16 needs orig fTri
  221. ' need 4 non linear points (not all on 1 line)
  222. ' list them clockwise so x2, y2 is opposite of x4, y4
  223.  
  224. Sub fquad (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  225.     ftri x1, y1, x2, y2, x3, y3, K
  226.     ftri x3, y3, x4, y4, x1, y1, K
  227. End Sub ' fquad
  228.  
  229. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  230. ' END GRAPHICS FUNCTIONS
  231. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  232.  
  233. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  234. ' BEGIN COLOR FUNCTIONS
  235. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  236.  
  237. ' NOTE: these are mostly negative numbers
  238. '       and have to be forced to positive
  239. '       when stored in the dictionary
  240. '       (only cEmpty& should be negative)
  241.  
  242. Function cRed& ()
  243.     cRed& = _RGB32(255, 0, 0)
  244.  
  245. Function cOrangeRed& ()
  246.     cOrangeRed& = _RGB32(255, 69, 0)
  247. End Function ' cOrangeRed&
  248.  
  249. Function cDarkOrange& ()
  250.     cDarkOrange& = _RGB32(255, 140, 0)
  251. End Function ' cDarkOrange&
  252.  
  253. Function cOrange& ()
  254.     cOrange& = _RGB32(255, 165, 0)
  255. End Function ' cOrange&
  256.  
  257. Function cGold& ()
  258.     cGold& = _RGB32(255, 215, 0)
  259. End Function ' cGold&
  260.  
  261. Function cYellow& ()
  262.     cYellow& = _RGB32(255, 255, 0)
  263. End Function ' cYellow&
  264.  
  265. ' LONG-HAIRED FRIENDS OF JESUS OR NOT,
  266. ' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
  267. ' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
  268. Function cChartreuse& ()
  269.     cChartreuse& = _RGB32(127, 255, 0)
  270. End Function ' cChartreuse&
  271.  
  272. ' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
  273. Function cOliveDrab1& ()
  274.     cOliveDrab1& = _RGB32(192, 255, 62)
  275. End Function ' cOliveDrab1&
  276.  
  277. Function cLime& ()
  278.     cLime& = _RGB32(0, 255, 0)
  279. End Function ' cLime&
  280.  
  281. Function cMediumSpringGreen& ()
  282.     cMediumSpringGreen& = _RGB32(0, 250, 154)
  283. End Function ' cMediumSpringGreen&
  284.  
  285. Function cCyan& ()
  286.     cCyan& = _RGB32(0, 255, 255)
  287. End Function ' cCyan&
  288.  
  289. Function cDeepSkyBlue& ()
  290.     cDeepSkyBlue& = _RGB32(0, 191, 255)
  291. End Function ' cDeepSkyBlue&
  292.  
  293. Function cDodgerBlue& ()
  294.     cDodgerBlue& = _RGB32(30, 144, 255)
  295. End Function ' cDodgerBlue&
  296.  
  297. Function cSeaBlue& ()
  298.     cSeaBlue& = _RGB32(0, 64, 255)
  299. End Function ' cSeaBlue&
  300.  
  301. Function cBlue& ()
  302.     cBlue& = _RGB32(0, 0, 255)
  303. End Function ' cBlue&
  304.  
  305. Function cBluePurple& ()
  306.     cBluePurple& = _RGB32(64, 0, 255)
  307. End Function ' cBluePurple&
  308.  
  309. Function cDeepPurple& ()
  310.     cDeepPurple& = _RGB32(96, 0, 255)
  311. End Function ' cDeepPurple&
  312.  
  313. Function cPurple& ()
  314.     cPurple& = _RGB32(128, 0, 255)
  315. End Function ' cPurple&
  316.  
  317. Function cPurpleRed& ()
  318.     cPurpleRed& = _RGB32(128, 0, 192)
  319. End Function ' cPurpleRed&
  320.  
  321. Function cDarkRed& ()
  322.     cDarkRed& = _RGB32(160, 0, 64)
  323. End Function ' cDarkRed&
  324.  
  325. Function cBrickRed& ()
  326.     cBrickRed& = _RGB32(192, 0, 32)
  327. End Function ' cBrickRed&
  328.  
  329. Function cDarkGreen& ()
  330.     cDarkGreen& = _RGB32(0, 100, 0)
  331. End Function ' cDarkGreen&
  332.  
  333. Function cGreen& ()
  334.     cGreen& = _RGB32(0, 128, 0)
  335. End Function ' cGreen&
  336.  
  337. Function cOliveDrab& ()
  338.     cOliveDrab& = _RGB32(107, 142, 35)
  339. End Function ' cOliveDrab&
  340.  
  341. Function cLightPink& ()
  342.     cLightPink& = _RGB32(255, 182, 193)
  343. End Function ' cLightPink&
  344.  
  345. Function cHotPink& ()
  346.     cHotPink& = _RGB32(255, 105, 180)
  347. End Function ' cHotPink&
  348.  
  349. Function cDeepPink& ()
  350.     cDeepPink& = _RGB32(255, 20, 147)
  351. End Function ' cDeepPink&
  352.  
  353. Function cMagenta& ()
  354.     cMagenta& = _RGB32(255, 0, 255)
  355. End Function ' cMagenta&
  356.  
  357. Function cBlack& ()
  358.     cBlack& = _RGB32(0, 0, 0)
  359. End Function ' cBlack&
  360.  
  361. Function cDimGray& ()
  362.     cDimGray& = _RGB32(105, 105, 105)
  363. End Function ' cDimGray&
  364.  
  365. Function cGray& ()
  366.     cGray& = _RGB32(128, 128, 128)
  367. End Function ' cGray&
  368.  
  369. Function cDarkGray& ()
  370.     cDarkGray& = _RGB32(169, 169, 169)
  371. End Function ' cDarkGray&
  372.  
  373. Function cSilver& ()
  374.     cSilver& = _RGB32(192, 192, 192)
  375. End Function ' cSilver&
  376.  
  377. Function cLightGray& ()
  378.     cLightGray& = _RGB32(211, 211, 211)
  379. End Function ' cLightGray&
  380.  
  381. Function cGainsboro& ()
  382.     cGainsboro& = _RGB32(220, 220, 220)
  383. End Function ' cGainsboro&
  384.  
  385. Function cWhiteSmoke& ()
  386.     cWhiteSmoke& = _RGB32(245, 245, 245)
  387. End Function ' cWhiteSmoke&
  388.  
  389. Function cWhite& ()
  390.     cWhite& = _RGB32(255, 255, 255)
  391. End Function ' cWhite&
  392.  
  393. Function cDarkBrown& ()
  394.     cDarkBrown& = _RGB32(128, 64, 0)
  395. End Function ' cDarkBrown&
  396.  
  397. Function cLightBrown& ()
  398.     cLightBrown& = _RGB32(196, 96, 0)
  399. End Function ' cLightBrown&
  400.  
  401. Function cKhaki& ()
  402.     cKhaki& = _RGB32(240, 230, 140)
  403. End Function ' cKhaki&
  404.  
  405. Function cEmpty& ()
  406.     cEmpty& = -1
  407. End Function ' cEmpty&
  408.  
  409. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  410. ' END COLOR FUNCTIONS
  411. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  412.  
  413. ' GENERAL PURPOSE FUNCTIONS
  414. ' /////////////////////////////////////////////////////////////////////////////
  415.  
  416. Function cstr$ (myValue)
  417.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  418.     cstr$ = _Trim$(Str$(myValue))
  419. End Function ' cstr$
  420.  
  421. ' /////////////////////////////////////////////////////////////////////////////
  422.  
  423. Function cstrl$ (myValue As Long)
  424.     cstrl$ = _Trim$(Str$(myValue))
  425. End Function ' cstrl$
  426.  
  427. ' /////////////////////////////////////////////////////////////////////////////
  428.  
  429. Function cstrs$ (myValue As Single)
  430.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  431.     cstrs$ = _Trim$(Str$(myValue))
  432. End Function ' cstrs$
  433.  
  434.  

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: any idea why the color white is not visible?
« Reply #1 on: December 12, 2021, 04:07:05 pm »
What's interesting is white shows back up when I change its definition to:

Code: QB64: [Select]
  1. Function cWhite& ()
  2.     cWhite& = _RGB32(254, 255, 255)
  3. End Function ' cWhite&

Note the one digit being off from 255. This could probably help you find whatever off-by-one error is going on.
You're not done when it works, you're done when it's right.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #2 on: December 12, 2021, 04:35:46 pm »
What's interesting is white shows back up when I change its definition to:

Code: QB64: [Select]
  1. Function cWhite& ()
  2.     cWhite& = _RGB32(254, 255, 255)
  3. End Function ' cWhite&

Note the one digit being off from 255. This could probably help you find whatever off-by-one error is going on.

Thank you for your response.
Well that is definitely a workaround, using "off white".
I'm not sure how to find the error though.

An interesting thing I found -
I disabled all the drawing except for three colors: red, white, blue (full program listing below).
I have it _echo the values and the strange thing is,
when it gets to white, the values are the same as for red!
Go figure?

Debugging console output:
Code: [Select]
Started untitled.exe
Debugging on...
IsoLine3D
    x=194
    y=170
    x2=202
    y2=178
    z=8
    iHeight=8
    xoffset=450
    yoffset=200
    iColor=4294901760
    alpha&=255
    r=255
    g=0
    b=0
    _RGB32(r, g, b, alpha&)=4294901760
IsoLine3D
    x=130
    y=130
    x2=138
    y2=138
    z=80
    iHeight=8
    xoffset=450
    yoffset=200
    iColor=4294901760
    alpha&=255
    r=255
    g=0
    b=0
    _RGB32(r, g, b, alpha&)=4294901760
IsoLine3D
    x=210
    y=130
    x2=218
    y2=138
    z=80
    iHeight=8
    xoffset=450
    yoffset=200
    iColor=4278190335
    alpha&=255
    r=0
    g=0
    b=255
    _RGB32(r, g, b, alpha&)=4278190335

The code:
Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' #TOP
  3.  
  4. ' Isomatric mapping demo re-revisited
  5. ' Version 3.00.14 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. ' * Render cubes that block the view of the player as transparent.
  18. ' * 2-D top down "map" view of the player's current Z slice.
  19. ' * variable grid size
  20. ' * change arrMap to global shared variable (for simpler code) & rename m_arrMap
  21. ' * allow player to rotate their view
  22. ' * preliminary multiplayer changes
  23. '   - move player info into array (upto 4 players)
  24. '   - key mapping variables
  25. ' * fixed some keyboard input (repeating keys, continuous motion)
  26. ' * fixed right point of view bug where x & y coordinates were reversed
  27. ' * preliminary multiplayer changes
  28. '   - split screen display (4, 6, or 8?)
  29. '     + for now display player 1's world rotated in each window (for editor)
  30. '       * x4: c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  31. '       * x6: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward
  32. '       * x8: c_iDir_Down, c_iDir_Up, c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, (none), (none)
  33. '     + will eventually be one per player
  34. ' * 2D minimap background = cKhaki&
  35. ' * , and . change minimap size
  36.  
  37. ' -----------------------------------------------------------------------------
  38. ' TO DO:
  39. ' * editor v1 = simple drawing program
  40. '   - add type RecordType to hold recording steps
  41. '   - add array m_arrRecord of RecordType to hold recording
  42. '   - display available tiles/colors/etc. at bottom of screen
  43. '     + 26 colors including empty
  44. '     + 2 tiles (empty, wall)
  45. '   - cursor places tiles (ENTER = add/delete at current space)
  46. '   - 0-9 keys change colors/etc.
  47. '   - CTRL+Z, CTRL+Y UNDO & REDO ? (save levels of undo, or history of commands)
  48. '   - save screens to file (stored as editable text)
  49. '     + FORMAT: [tile=t][color@x,y,z][color@x,y,z][color@x,y,z]...
  50. '   - load screens into array m_arrRecord
  51. '     + PARSER:
  52. '       1. replace all ][ with [
  53. '       2. split by "[" into simple 1D array
  54. '       3. each element is either "tile=t" or "plot=color@x,y,z"
  55. '       4. parse data into array to playback recording
  56. '          [n][0] = command
  57. '                   -1 = select tile "tile=t"
  58. '                   0+ = color to plot "color@x,y,z"
  59. '          [n][1] = parameter #1 = tile
  60. '          [n][2] = parameter #2 = x
  61. '          [n][3] = parameter #3 = y
  62. '          [n][3] = parameter #4 = z
  63. '   - run commands in m_arrRecord to plot tiles and display
  64.  
  65. ' -----------------------------------------------------------------------------
  66. ' * rotating view changes orientation of keys (get it working)
  67.  
  68. ' * add parameters to tiles
  69. ' * - color scheme (for cycle colors)
  70.  
  71. ' * add tiles
  72. '   - transparent lights (blinking / cycle colors)
  73.  
  74. ' * editor v2 = simple animation program
  75. '   - records cursor movements and adding/deleting tiles
  76. '   - press key to record a "frame"
  77. '     + flash screen + play a sound
  78. '   - can change animation speed
  79. '   - realtime=on command enables redrawing screen every step (until realtime=off command encountered)
  80. '   - playback mode recreates editing actions
  81. '   - playback updates screen every "update"
  82. '   - tweak save format (still editable text)
  83. '     + FORMAT: [cls][rotate=d][speed=n][tile=t][color@x,y,z][tile=t][color@x,y,z][update][tile=t][color@x,y,z][realtime=on][tile=t][color@x,y,z]...
  84. '     + PARSER:
  85. '       1. replace all ][ with [
  86. '       2. split by "[" into simple 1D array
  87. '       3. each element is either "color@x,y,z", "tile=t", "cls", "update", "speed=s", "realtime=on", "realtime=off", "rotate=d"
  88. '       4. parse array into array of LONG for playback
  89. '          [n].Command
  90. '                   -7 = rotate point of view (up, down, left, right, back, forward) "rotate=d"
  91. '                   -6 = disable screen update every step "realtime=off"
  92. '                   -5 = enable screen update every step "realtime=on"
  93. '                   -4 = set speed "speed=s"
  94. '                   -3 = update screen "update"
  95. '                   -2 = clear screen "cls"
  96. '                   -1 = select tile "tile=t"
  97. '                   0+ = color to plot "color@x,y,z"
  98. '          [n].Param1 = parameter #1 = tile, speed, direction
  99. '          [n].Param2 = parameter #2 = x
  100. '          [n].Param3 = parameter #3 = y
  101. '          [n].Param4 = parameter #4 = z
  102. '   - effects of gravity (from bottom up, ie z=0 to z=max)
  103.  
  104. ' -----------------------------------------------------------------------------
  105. ' * expand world to bigger than screen (2.5d scrolling view)
  106.  
  107. ' * editor v3 = mouse
  108. '   - mouse movement controls cursor x,y position
  109. '   - mouse wheel controls z position
  110. '   - left click draws a tile
  111. '   - right click erases a tile
  112. '   - ENTER records a frame
  113. '   - Add animation playback command:
  114. '          [n][0] = command
  115. '                   -8 = enable user to rotate image in realtime with mouse? "mouse=on"
  116.  
  117. ' -----------------------------------------------------------------------------
  118. ' TO DO (LATER):
  119. ' * local multiplayer (2-4 players)
  120. '   - split screen (x2 or x4)
  121.  
  122. ' * fix/control screen placement/rendering/scroll boundaries for grid sizes
  123. '   (to not overwrite other players, go off screen, etc., when grid size changes)
  124.  
  125. ' * auto-rotate view depending on direction player is facing
  126.  
  127. ' * control the x/y/z slice axis, for a cutaway view
  128.  
  129. ' * gravity (players stay on ground, can fall)
  130. ' * player can climb up to next level if it is 1 tile higher
  131. ' * add ability to jump over 1 space
  132.  
  133. ' * option to remap keys
  134. ' * support game controllers
  135. ' * game controller calibration/mapping function
  136.  
  137. ' * option to hide objects out of player's line-of-sight
  138.  
  139. ' * show player as a stick figure (like "Realm of Impossibility")
  140. ' * walking movement
  141.  
  142. ' * add tiles (water, ladders, steps, ropes, windows, doors, etc.)
  143. ' * add toggle tiles - door "opens" when triggered
  144. ' * triggers
  145. ' * add tiles
  146. '   - Water = transparent blue)
  147. '   - Window = more transparent cyan)
  148.  
  149. ' * add directional tiles (can be rotated?)
  150. '   - ladder
  151. '   - bridge
  152. '   - hand-over-hand bars?
  153. '   - Slope45 = 45° slope <- 4 or 6 directions?
  154. '   - InvSlope45 = 45° inverted slope <- 4 or 6 directions?
  155. '   - Pyramid45 = 45° pyramid "cap stone" <- 4 or 6 directions?
  156. '   - ramp (player can walk up/down slope45)
  157.  
  158. ' * add ability to climb ladders + climbing animation
  159. ' * add ability to walk up ramps with smooth z-movement inbetween tiles
  160. ' * add ability to climb monkey bars (animation like lode runner)
  161.  
  162. ' * simultaneously show additional 1st person view
  163. ' * add ability for tilting head up/down in first person
  164.  
  165. ' * simple open world (players can add/remove tiles, build in real time)
  166. ' * make simple games (maze craze, capture the flag, snake, surround, 2.5d pong)
  167. ' * make more complex games (berzerk, lode runner, atari combat / tank)
  168. ' * make awesome complex games (2.5d lunar lander, atari adventure, asteroids, gravitar, etc.)
  169. ' * text adventure features (to create graphic Infocom or Scott Adams style games)
  170.  
  171. ' * for 2.5D animation program: independent animated objects?
  172. '   - 2.5D sprites?
  173. '     + animation sequence
  174. '     + motion path / algorithm
  175. '     + storage / library
  176. '     + multiple instances?
  177. '   - gravity? (tile falls if no tiles underneath)
  178.  
  179. ' ################################################################################################################################################################
  180.  
  181. ' =============================================================================
  182. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  183. ' div: int1% = num1% \ den1%
  184. ' mod: rem1% = num1% MOD den1%
  185.  
  186. ' -----------------------------------------------------------------------------
  187. ' boolean constants
  188. ' -----------------------------------------------------------------------------
  189. Const FALSE = 0
  190. Const TRUE = Not FALSE
  191.  
  192. ' -----------------------------------------------------------------------------
  193. ' KeyDownConstants
  194. ' -----------------------------------------------------------------------------
  195. Const c_iKeyDown_Esc = 27
  196. Const c_iKeyDown_F1 = 15104
  197. Const c_iKeyDown_F2 = 15360
  198. Const c_iKeyDown_F3 = 15616
  199. Const c_iKeyDown_F4 = 15872
  200. Const c_iKeyDown_F5 = 16128
  201. Const c_iKeyDown_F6 = 16384
  202. Const c_iKeyDown_F7 = 16640
  203. Const c_iKeyDown_F8 = 16896
  204. Const c_iKeyDown_F9 = 17152
  205. Const c_iKeyDown_F10 = 17408
  206. Const c_iKeyDown_Tilde = 96
  207. Const c_iKeyDown_1 = 49
  208. Const c_iKeyDown_2 = 50
  209. Const c_iKeyDown_3 = 51
  210. Const c_iKeyDown_4 = 52
  211. Const c_iKeyDown_5 = 53
  212. Const c_iKeyDown_6 = 54
  213. Const c_iKeyDown_7 = 55
  214. Const c_iKeyDown_8 = 56
  215. Const c_iKeyDown_9 = 57
  216. Const c_iKeyDown_0 = 48
  217. Const c_iKeyDown_Minus = 45
  218. Const c_iKeyDown_EqualPlus = 61
  219. Const c_iKeyDown_BkSp = 8
  220. Const c_iKeyDown_Ins = 20992
  221. Const c_iKeyDown_Home = 18176
  222. Const c_iKeyDown_PgUp = 18688
  223. Const c_iKeyDown_Del = 21248
  224. Const c_iKeyDown_End = 20224
  225. Const c_iKeyDown_PgDn = 20736
  226. Const c_iKeyDown_KEYPAD_7_Home = 18176
  227. Const c_iKeyDown_KEYPAD_8_Up = 18432
  228. Const c_iKeyDown_KEYPAD_9_PgUp = 18688
  229. Const c_iKeyDown_KEYPAD_4_Left = 19200
  230. Const c_iKeyDown_KEYPAD_6_Right = 19712
  231. Const c_iKeyDown_KEYPAD_1_End = 20224
  232. Const c_iKeyDown_KEYPAD_2_Down = 20480
  233. Const c_iKeyDown_KEYPAD_3_PgDn = 20736
  234. Const c_iKeyDown_KEYPAD_0_Ins = 20992
  235. Const c_iKeyDown_KEYPAD_Period_Del = 21248
  236. Const c_iKeyDown_Tab = 9
  237. Const c_iKeyDown_Q = 113
  238. Const c_iKeyDown_W = 119
  239. Const c_iKeyDown_E = 101
  240. Const c_iKeyDown_R = 114
  241. Const c_iKeyDown_T = 116
  242. Const c_iKeyDown_Y = 121
  243. Const c_iKeyDown_U = 117
  244. Const c_iKeyDown_Pipe = 105
  245. Const c_iKeyDown_O = 111
  246. Const c_iKeyDown_P = 112
  247. Const c_iKeyDown_BracketLeft = 91
  248. Const c_iKeyDown_BracketRight = 93
  249. Const c_iKeyDown_Backslash = 92
  250. Const c_iKeyDown_A = 97
  251. Const c_iKeyDown_S = 115
  252. Const c_iKeyDown_D = 100
  253. Const c_iKeyDown_F = 102
  254. Const c_iKeyDown_G = 103
  255. Const c_iKeyDown_H = 104
  256. Const c_iKeyDown_J = 106
  257. Const c_iKeyDown_K = 107
  258. Const c_iKeyDown_L = 108
  259. Const c_iKeyDown_SemiColon = 59
  260. Const c_iKeyDown_Apostrophe = 39
  261. Const c_iKeyDown_Enter = 13
  262. Const c_iKeyDown_Z = 22
  263. Const c_iKeyDown_X = 120
  264. Const c_iKeyDown_C = 99
  265. Const c_iKeyDown_V = 118
  266. Const c_iKeyDown_B = 98
  267. Const c_iKeyDown_N = 110
  268. Const c_iKeyDown_M = 109
  269. Const c_iKeyDown_Comma = 44
  270. Const c_iKeyDown_Period = 46
  271. Const c_iKeyDown_Slash = 47
  272. Const c_iKeyDown_Up = 18432
  273. Const c_iKeyDown_Left = 19200
  274. Const c_iKeyDown_Down = 20480
  275. Const c_iKeyDown_Right = 19712
  276. Const c_iKeyDown_Spacebar = 32
  277.  
  278. ' -----------------------------------------------------------------------------
  279. ' Constants for layers
  280. ' -----------------------------------------------------------------------------
  281. CONST cTerrainType = 1
  282. CONST cObjectsType = 2
  283. CONST cPlayersType = 3
  284.  
  285. ' -----------------------------------------------------------------------------
  286. ' Tile value constants for map (MapTileType.Typ)
  287. ' -----------------------------------------------------------------------------
  288. Const c_iTile_Empty = 0
  289. Const c_iTile_Floor = 1
  290. Const c_iTile_Wall = 2
  291. Const c_iTile_Water = 3
  292. Const c_iTile_Window = 4
  293. Const c_iTile_Player1 = 5
  294. Const c_iTile_Player2 = 6
  295. Const c_iTile_Player3 = 7
  296. Const c_iTile_Player4 = 8
  297. Const c_iTile_Blinking = 9
  298. Const c_iTile_Snow = 10
  299. Const c_iTile_Slope45 = 11
  300. Const c_iTile_InvSlope45 = 12
  301.  
  302. ' -----------------------------------------------------------------------------
  303. ' constants for 2.5D movement
  304. ' -----------------------------------------------------------------------------
  305. Const c_iDir_Down = 1
  306. Const c_iDir_Up = 2
  307. Const c_iDir_Left = 3
  308. Const c_iDir_Right = 4
  309. Const c_iDir_Back = 5
  310. Const c_iDir_Forward = 6
  311. Const c_iDir_Min = 1
  312. Const c_iDir_Max = 6
  313.  
  314. ' -----------------------------------------------------------------------------
  315. ' constants for drawing the 2.5D screen
  316. ' -----------------------------------------------------------------------------
  317. Const cGridOffsetX = 50
  318. Const cGridOffsetY = 50
  319. Const cGridOffsetZ = 0
  320. Const cScreenOffsetX = 500
  321. Const cScreenOffsetY = 300
  322. Const cScreenOffsetZ = 0
  323.  
  324. ' =============================================================================
  325. ' USER DEFINED TYPES
  326. ' =============================================================================
  327. Type MapTileType
  328.     Typ As Integer ' c_iTile_Empty, c_iTile_Floor, c_iTile_Wall, etc.
  329.     'Vis As Integer ' TRUE = visible, FALSE = don't render
  330.     'Lit As Long ' light offset
  331.     Color1 As _Unsigned Long ' main color
  332.     Color2 As _Unsigned Long ' secondary color if needed
  333.     Color3 As _Unsigned Long ' third color if needed
  334.     Alpha1 As Integer ' transparency of tile Color1
  335.     Alpha2 As Integer ' transparency of tile Color2
  336.     Alpha3 As Integer ' transparency of tile Color3
  337.     AlphaOverride As Integer ' can be used to override alpha (255 treated as opaque)
  338. End Type ' MapTileType
  339.  
  340. Type RecordType
  341.     Command As Integer
  342.     Param1 As Integer
  343.     Param2 As Integer
  344.     Param3 As Integer
  345.     Param4 As Integer
  346. End Type ' RecordType
  347.  
  348. ' UDT TO HOLD THE INFO FOR A PLAYER
  349. TYPE PlayerType
  350.     IsEnabled AS Integer ' TRUE or FALSE
  351.     x AS Integer ' player x position
  352.     y AS Integer ' player y position
  353.     z AS Integer ' player z position
  354.     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
  355.     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
  356.     Tile1 As Long ' later we will instead use directional animation sequences
  357.    
  358.     Color1 As _Unsigned Long ' main color
  359.     'Color2 As _Unsigned Long ' secondary color if needed
  360.     'Color3 As _Unsigned Long ' third color if needed    
  361.    
  362.     Alpha1 As Integer ' transparency of player Color1
  363.     'Alpha2 As Integer ' transparency of player Color2
  364.     'Alpha3 As Integer ' transparency of player Color3
  365.    
  366.     ColorScheme1 As Long ' for cycling colors
  367.     ColorSchemeSpeed1 As Long
  368.     ColorSchemeCount1 As Long
  369.    
  370.     'ColorScheme2 As Long ' for cycling colors
  371.     'ColorSchemeSpeed2 As Long
  372.     'ColorSchemeCount2 As Long
  373.    
  374.     'ColorScheme3 As Long ' for cycling colors
  375.     'ColorSchemeSpeed3 As Long
  376.     'ColorSchemeCount3 As Long
  377.    
  378.     AlphaOverride As Integer ' can be used to override alpha (0 treated as opaque)
  379.    
  380.     IsMoving As Integer ' TRUE/FALSE
  381.     IsMoved As Integer ' TRUE/FALSE
  382.    
  383.     GridSize As Integer
  384.     MapSize As Integer
  385.    
  386.     'hx AS Integer ' home base x position
  387.     'hy AS Integer ' home base y position
  388.     'ex AS Integer ' exit x position
  389.     'ey AS Integer ' exit y position
  390.     'wins AS Integer ' count # of wins
  391.     'points AS Long ' count points (more points for harder)
  392.     'difficulty AS Integer ' 1-5, from 1 (easiest, maze width 5) to 5 (hardest, maze width 1). Each win awards {difficulty} # of points.
  393.     'speed AS Integer ' the higher the faster
  394.     'delay AS Integer ' counter, player can move based on speed
  395.     'bit AS Integer ' bit value for masking player in map
  396.     'rows AS Integer ' # of rows in player's maze
  397.     'cols AS Integer ' # of columns in player's maze
  398. END TYPE ' PlayerType
  399.  
  400. ' KEY MAPPING v1
  401. ' UDT TO HOLD THE KEY MAPPINGS
  402. TYPE DirKeyMapType
  403.     KeyBack As Long
  404.     KeyForward As Long
  405.     KeyLeft As Long
  406.     KeyRight As Long
  407.     KeyUp As Long
  408.     KeyDown As Long
  409. END TYPE ' DirKeyMapType
  410.  
  411. ' SPLIT SCREEN OFFSETS
  412. TYPE SplitScreenType
  413.     GridOffsetX As Integer
  414.     GridOffsetY As Integer
  415.     GridOffsetZ As Integer
  416.     ScreenOffsetX As Integer
  417.     ScreenOffsetY As Integer
  418.     ScreenOffsetZ As Integer
  419. END TYPE ' SplitScreenType
  420.  
  421. ' =============================================================================
  422. ' GLOBAL VARIABLES
  423. Dim Shared m_ProgramPath$ : m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  424. Dim Shared m_ProgramName$ : m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  425. Dim Shared m_iGridSize As Integer : m_iGridSize = 8 ' BEFORE, < 10 wass causing problems with PAINT, but new method doesn't use PAINT, so nyah!
  426. Dim Shared m_iGridSizeMin As Integer : m_iGridSizeMin = 1
  427. Dim Shared m_iGridSizeMax As Integer : m_iGridSizeMax = 128
  428.  
  429. Dim Shared m_iMapMinX As Integer : m_iMapMinX = 0
  430. Dim Shared m_iMapMaxX As Integer : m_iMapMaxX = 32
  431. Dim Shared m_iMapMidX As Integer : m_iMapMidX = (m_iMapMaxX-m_iMapMinX)\2
  432. Dim Shared m_iMapMinY As Integer : m_iMapMinY = 0
  433. Dim Shared m_iMapMaxY As Integer : m_iMapMaxY = 32
  434. Dim Shared m_iMapMidY As Integer : m_iMapMidY = (m_iMapMaxY-m_iMapMinY)\2
  435. Dim Shared m_iMapMinZ As Integer : m_iMapMinZ = 0
  436. Dim Shared m_iMapMaxZ As Integer : m_iMapMaxZ = 32
  437. Dim Shared m_iMapMidZ As Integer : m_iMapMidZ = (m_iMapMaxZ-m_iMapMinZ)\2
  438.  
  439. Dim Shared m_iPlayerMin As Integer : m_iPlayerMin = 1
  440. Dim Shared m_iPlayerMax As Integer : m_iPlayerMax = 4
  441. Dim Shared m_iPlayerCount As Integer : m_iPlayerCount = 0
  442. Dim Shared m_iObjectCount As Integer : m_iObjectCount = 0 ' <- TO BE USED WHEN WE HAVE OBJECTS
  443.  
  444. ' Max # tiles in (32x32x32) world = 32,768
  445. ' Max # tiles for 16 (32x32x32) worlds = 524,288
  446. ' Max # tiles for 256 (32x32x32) worlds = 8,388,608
  447. Dim Shared m_iRecordMin As Long : m_iRecordMin = 0
  448. Dim Shared m_iRecordMax As Long : m_iRecordMax = 524288
  449.  
  450. Dim Shared m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  451. Dim Shared m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  452. Dim Shared m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  453. Dim Shared m_arrPlayer(m_iPlayerMin To m_iPlayerMax) As PlayerType
  454. Dim Shared m_arrRecord(m_iRecordMin To m_iRecordMax) As RecordType
  455.  
  456. ' For each player, map the 6 directional keys differently for each of the 6 directional orientations!
  457. Dim Shared m_arrDirKeyMap(m_iPlayerMin To m_iPlayerMax, c_iDir_Min To c_iDir_Max) As DirKeyMapType
  458.  
  459. ' Store offsets for splitscreen
  460. Dim Shared m_arrSplitScreen(m_iPlayerMin To m_iPlayerMax) As SplitScreenType
  461.  
  462. ' Store colors in an array
  463. Dim Shared m_arrColors(0 To 25) As Long
  464.  
  465. Dim Shared m_bTesting As Integer
  466.  
  467. ' =============================================================================
  468. ' LOCAL VARIABLES
  469. Dim in$
  470.  
  471. ' ****************************************************************************************************************************************************************
  472. ' ACTIVATE DEBUGGING WINDOW
  473. _Echo "Started " + m_ProgramName$
  474. _Echo "Debugging on..."
  475. ' ****************************************************************************************************************************************************************
  476.  
  477. ' =============================================================================
  478. ' START THE MAIN ROUTINE
  479. main
  480.  
  481. ' =============================================================================
  482. ' FINISH
  483. System ' return control to the operating system
  484. Print m_ProgramName$ + " finished."
  485. Input "Press <ENTER> to continue", in$
  486.  
  487. ' ****************************************************************************************************************************************************************
  488. ' DEACTIVATE DEBUGGING WINDOW
  489. ' ****************************************************************************************************************************************************************
  490.  
  491.  
  492. ' /////////////////////////////////////////////////////////////////////////////
  493.  
  494. Sub main
  495.     Dim RoutineName as String : RoutineName = "main"
  496.     Dim in$
  497.     Dim result$
  498.    
  499.     Screen 0
  500.  
  501.     Do
  502.         Cls
  503.         Print m_ProgramName$
  504.         Print
  505.         Print "Isomatric Mapping Demo Re-visited"
  506.         Print "v3.00.14, by Softintheheadware (Dec, 2021)"
  507.         Print
  508.         'PRINT "CONTROLS: PRESS <ESC> TO RETURN TO MENU"
  509.         'PRINT "PLAYER  LEFT       RIGHT       UP        DOWN       "
  510.         'PRINT "1       CRSR LEFT  CRSR RIGHT  CRSR UP   CRSR DOWN  "
  511.         'PRINT "2       KEYPAD 4   KEYPAD 6    KEYPAD 8  KEYPAD 2   "
  512.         'PRINT "3       A          S           W         Z          "
  513.         'PRINT "4       J          K           I         M          "
  514.         'PRINT
  515.  
  516.         Print "1. (TBD)"
  517.         Print "2. (TBD)"
  518.         Print "3. (TBD)"
  519.         Print "4. BoxDrawTest1$ <- draws white OK"
  520.         Print "5. Draw in 2.5D! <- draws all colors except white(?)"
  521.         Print
  522.         Print "What to do? ('q' to exit)"
  523.  
  524.         Input in$: in$ = LCase$(Left$(in$, 1))
  525.  
  526.         If in$ = "1" Then
  527.             result$ = IsometricDemo1$
  528.         ElseIf in$ = "2" Then
  529.             result$ = IsometricDemo2$
  530.         ElseIf in$ = "3" Then
  531.             result$ = IsometricDemo3$
  532.         ElseIf in$ = "4" Then
  533.             result$ = BoxDrawTest1$
  534.         ElseIf in$ = "5" Then
  535.             result$ = IsometricDraw1$
  536.         End If
  537.        
  538.         If LEN(result$) > 0 Then
  539.             PRINT result$
  540.         End If
  541.        
  542.     Loop Until in$ = "q"
  543. End Sub ' main
  544.  
  545. ' /////////////////////////////////////////////////////////////////////////////
  546.  
  547. Function IsometricDemo1$
  548.     IsometricDemo1$ = "(TBD)"
  549. End Sub ' IsometricDemo1
  550.  
  551. ' /////////////////////////////////////////////////////////////////////////////
  552.  
  553. Function IsometricDemo2$
  554.     IsometricDemo2$ = "(TBD)"
  555. End Sub ' IsometricDemo2
  556.  
  557. ' /////////////////////////////////////////////////////////////////////////////
  558.  
  559. Function IsometricDemo3$
  560.     IsometricDemo3$ = "(TBD)"
  561. End Sub ' IsometricDemo3
  562.  
  563. ' /////////////////////////////////////////////////////////////////////////////
  564. ' Test all the values 0-255 for style
  565. ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  566.  
  567. Function BoxDrawTest1$
  568.     Dim in$
  569.     Dim iSize%
  570.     Dim iDrawX%
  571.     Dim iDrawY%
  572.     Dim iFromX%
  573.     Dim iFromY%
  574.     Dim iToX%
  575.     Dim iToY%
  576.     Dim iNextColor&
  577.     Dim iLoop As Integer
  578.     Dim iSpace%
  579.     Dim sError As String : sError = ""
  580.    
  581.     iSize% = 48 ' {n}x{n} pixels square
  582.     iDrawX% = 10
  583.     iDrawY% = 10
  584.     iNextColor& = cWhite&
  585.     iSpace% = 8
  586.     Screen _NewImage(1280, 1024, 32) : _ScreenMove 0,0
  587.     FOR iLoop = 0 TO 255
  588.         DrawStyledOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, iLoop
  589.         'DrawOutlineBox iDrawX%+1, iDrawY%+1, iSize%-2, iNextColor&, iLoop
  590.        
  591.         iDrawX% = iDrawX% + iSize% + iSpace%
  592.         IF iDrawX% > (1280 - (iSize% * 2)) THEN
  593.             iDrawX% = 10
  594.             iDrawY% = iDrawY% + iSize% + iSpace%
  595.            
  596.             IF iDrawY% > (1024 - (iSize% * 2)) THEN
  597.                 sError = "Ran out of Y space."
  598.                 EXIT FOR
  599.             END IF
  600.         END IF
  601.     NEXT iLoop
  602.    
  603.     IF LEN(sError)=0 THEN
  604.         FOR iLoop = 1 TO (iSize% \ 2)
  605.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, iLoop
  606.             iDrawX% = iDrawX% + iSize% + iSpace%
  607.             IF iDrawX% > (1280 - (iSize% * 2)) THEN
  608.                 iDrawX% = 10
  609.                 iDrawY% = iDrawY% + iSize% + iSpace%
  610.                 IF iDrawY% > (1024 - (iSize% * 2)) THEN
  611.                     sError = "Ran out of Y space."
  612.                     EXIT FOR
  613.                 END IF
  614.             END IF
  615.         NEXT iLoop
  616.     END IF
  617.    
  618.     LOCATE 58,1
  619.     IF LEN(sError) > 0 THEN
  620.         PRINT sError
  621.     END IF
  622.     INPUT "PRESS <ENTER> TO CONTINUE";in$
  623.    
  624.     WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  625.     SCREEN 0
  626.    
  627.     BoxDrawTest1$ = ""
  628. End Sub ' BoxDrawTest1$
  629.  
  630. ' /////////////////////////////////////////////////////////////////////////////
  631. ' Lets you draw a scene in 2.5D and save it to a file. Woo hoo!
  632.  
  633. ' Version 1 only supports 2 tile types:
  634. ' c_iTile_Empty
  635. ' c_iTile_Wall
  636.  
  637. Function IsometricDraw1$
  638.     Dim RoutineName As String: RoutineName = "IsometricDraw1"
  639.     Dim sResult AS String : sResult = ""
  640.     Dim sError As String: sError = ""
  641.     Dim iX%
  642.     Dim iY%
  643.     Dim iZ%
  644.     Dim iNewX%
  645.     Dim iNewY%
  646.     Dim iNewZ%
  647.     Dim iMyColor&
  648.     Dim iColorScheme%
  649.     Dim iDirection%
  650.     Dim bFound As Integer
  651.     DIM bDone As Integer
  652.     Dim in$
  653.     Dim iTotal% ' compute total available spaces
  654.     Dim iCount% ' count # of spaces searched
  655.     Dim bEnableRepeatingKeys As Integer
  656.     Dim iLastKey As Integer ' USED WHEN REPEATING KEYS DISABLED
  657.     Dim iLoop1 As Integer
  658.     Dim iLoop2 As Integer
  659.    
  660.     Dim iPosX1%
  661.     Dim iPosX2%
  662.     Dim iPosY1%
  663.     Dim iPosY2%
  664.     Dim iNextColor&
  665.     Dim iFirstColor&
  666.     Dim bContinue As Integer
  667.     Dim iLoopX%
  668.     Dim iLoopY%
  669.     Dim iLoopZ%
  670.     Dim iLevelCount%
  671.     Dim iLevelSize%
  672.    
  673.     Dim iDrawX%
  674.     Dim iDrawY%
  675.     Dim iSize%
  676.     Dim iOffsetY%
  677.    
  678.     Dim iPlayerLoop AS Integer
  679.     Dim iDirLoop AS Integer
  680.     Dim iNextX As Integer
  681.     Dim iNextY As Integer
  682.    
  683.     Dim iDrawColor%
  684.     Dim iCursorColor&
  685.    
  686.     Dim bIgnoreTerrain As Integer ' If TRUE, player can move through walls, etc.
  687.    
  688.     ' =============================================================================
  689.     ' GET OPTIONS
  690.     m_iPlayerCount = 1
  691.     'm_iPlayerCount = PromptForIntegerInRange%("How many players ({min}-{max} or blank to quit)?", 1, 4, 0)
  692.     'IF m_iPlayerCount = 0 THEN Goto CleanupAndExit
  693.     bEnableRepeatingKeys = FALSE
  694.    
  695.     ' =============================================================================
  696.     ' INITIALIZE GRAPHIC SCREEN
  697.     'Screen _NewImage(1024, 720, 32) : _ScreenMove _Middle
  698.     Screen _NewImage(1280, 1024, 32) : _ScreenMove 0,0
  699.    
  700.     m_arrSplitScreen(1).GridOffsetX = 50
  701.     m_arrSplitScreen(1).GridOffsetY = 50
  702.     m_arrSplitScreen(1).GridOffsetZ = 0
  703.     m_arrSplitScreen(1).ScreenOffsetX = 450
  704.     m_arrSplitScreen(1).ScreenOffsetY = 200
  705.     m_arrSplitScreen(1).ScreenOffsetZ = 0
  706.    
  707.     m_arrSplitScreen(2).GridOffsetX = 50
  708.     m_arrSplitScreen(2).GridOffsetY = 50
  709.     m_arrSplitScreen(2).GridOffsetZ = 0
  710.     m_arrSplitScreen(2).ScreenOffsetX = 1000
  711.     m_arrSplitScreen(2).ScreenOffsetY = 200
  712.     m_arrSplitScreen(2).ScreenOffsetZ = 0
  713.    
  714.     m_arrSplitScreen(3).GridOffsetX = 50
  715.     m_arrSplitScreen(3).GridOffsetY = 50
  716.     m_arrSplitScreen(3).GridOffsetZ = 0
  717.     m_arrSplitScreen(3).ScreenOffsetX = 450
  718.     m_arrSplitScreen(3).ScreenOffsetY = 700
  719.     m_arrSplitScreen(3).ScreenOffsetZ = 0
  720.    
  721.     m_arrSplitScreen(4).GridOffsetX = 50
  722.     m_arrSplitScreen(4).GridOffsetY = 50
  723.     m_arrSplitScreen(4).GridOffsetZ = 0
  724.     m_arrSplitScreen(4).ScreenOffsetX = 1000
  725.     m_arrSplitScreen(4).ScreenOffsetY = 700
  726.     m_arrSplitScreen(4).ScreenOffsetZ = 0
  727.    
  728.     ' -----------------------------------------------------------------------------
  729.     ' INITIALIZE MAP TO EMPTY
  730.     ClearIsometricMap
  731.    
  732.     ' -----------------------------------------------------------------------------
  733.     ' INITIALIZE COLOR ARRAY
  734.     m_arrColors( 0) = cEmpty&
  735.     m_arrColors( 1) = cBlack&
  736.     m_arrColors( 2) = cDarkGray&
  737.     m_arrColors( 3) = cDimGray&
  738.     m_arrColors( 4) = cGray&
  739.     m_arrColors( 5) = cLightGray&
  740.     m_arrColors( 6) = cSilver&
  741.     m_arrColors( 7) = cWhite&
  742.     m_arrColors( 8) = cRed&
  743.     m_arrColors( 9) = cOrangeRed&
  744.     m_arrColors(10) = cDarkOrange&
  745.     m_arrColors(11) = cOrange&
  746.     m_arrColors(12) = cGold&
  747.     m_arrColors(13) = cYellow&
  748.     m_arrColors(14) = cOliveDrab1&
  749.     m_arrColors(15) = cLime&
  750.     m_arrColors(16) = cMediumSpringGreen&
  751.     m_arrColors(17) = cCyan&
  752.     m_arrColors(18) = cDeepSkyBlue&
  753.     m_arrColors(19) = cDodgerBlue&
  754.     m_arrColors(20) = cSeaBlue&
  755.     m_arrColors(21) = cBlue&
  756.     m_arrColors(22) = cBluePurple&
  757.     m_arrColors(23) = cDeepPurple&
  758.     m_arrColors(24) = cPurple&
  759.     m_arrColors(25) = cPurpleRed&
  760.    
  761.     ' -----------------------------------------------------------------------------
  762.     ' INITIALIZE OTHER VARIABLES
  763.     bIgnoreTerrain = TRUE
  764.    
  765.    
  766.         If TRUE = TRUE Then
  767.                 m_bTesting = TRUE
  768.                
  769.                 m_arrMap(10, 10, 10).Typ = c_iTile_Wall
  770.                 m_arrMap(10, 10, 10).Color1 = cRed&
  771.                 m_arrMap(10, 10, 10).AlphaOverride = 255
  772.                
  773.                 m_arrMap(15, 10, 10).Typ = c_iTile_Wall
  774.                 m_arrMap(15, 10, 10).Color1 = cWhite& ' cLime&
  775.                 m_arrMap(15, 10, 10).AlphaOverride = 255
  776.                
  777.                 m_arrMap(20, 10, 10).Typ = c_iTile_Wall
  778.                 m_arrMap(20, 10, 10).Color1 = cBlue&
  779.                 m_arrMap(20, 10, 10).AlphaOverride = 255
  780.                
  781.         End If
  782.        
  783.         If TRUE = FALSE Then
  784.                 ' -----------------------------------------------------------------------------
  785.                 ' DRAW FLOOR
  786.                 For iLoopZ% = m_iMapMinZ To m_iMapMinZ
  787.                         For iLoopX% = m_iMapMinX To m_iMapMaxX
  788.                                 For iLoopY% = m_iMapMinY To m_iMapMaxY
  789.                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor
  790.                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cGray&
  791.                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2 = cWhite& ' cLightGray&
  792.                                 Next iLoopY%
  793.                         Next iLoopX%
  794.                 Next iLoopZ%
  795.  
  796.                 ' -----------------------------------------------------------------------------
  797.                 ' DRAW A TALL HOLLOW PYRAMID
  798.         iX% = 5
  799.         iY% = 10
  800.         iZ% = 1
  801.         iLevelSize% = 4
  802.        
  803.         iPosX1% = iX%
  804.         iPosX2% = iX% + 7
  805.         iPosY1% = iY%
  806.         iPosY2% = iY% + 7
  807.                
  808.         'iNextColor& = cRed&
  809.         'iColorScheme% = 1 ' 1 = Rainbow6 #1, 9 = Rainbow6 #2, etc.
  810.                
  811.                 iNextColor& = cWhite&
  812.                 iColorScheme% = 3 ' 3, 11 = grayscale, ascending
  813.                
  814.         iLevelCount% = 0
  815.        
  816.         bContinue = TRUE
  817.         Do
  818.             ' Draw front/back walls
  819.             For iLoopX% = iPosX1% To iPosX2%
  820.                 iLoopY% = iPosY1%
  821.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  822.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  823.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  824.                
  825.                 iLoopY% = iPosY2%
  826.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  827.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  828.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  829.             Next iLoopX%
  830.            
  831.             ' Draw left/right walls
  832.             For iLoopY% = iPosY1% To iPosY2%
  833.                 iLoopX% = iPosX1%
  834.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  835.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  836.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  837.                
  838.                 iLoopX% = iPosX2%
  839.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall
  840.                 m_arrMap(iLoopX%, iLoopY%, iZ%).Color1 = iNextColor&
  841.                 m_arrMap(iLoopX%, iLoopY%, iZ%).AlphaOverride = 255
  842.             Next iLoopY%
  843.            
  844.             ' Add a door to middle of right wall
  845.             iX% = iPosX1% + ( (iPosX2% - iPosX1%) \ 2)
  846.             m_arrMap(iX%, iPosY2%, iZ%).Typ = c_iTile_Empty
  847.            
  848.             ' Add a door to middle of front wall
  849.             iY% = iPosY1% + ( (iPosY2% - iPosY1%) \ 2)
  850.             m_arrMap(iPosX2%, iY%, iZ%).Typ = c_iTile_Empty
  851.            
  852.             ' MOVE UP A LEVEL
  853.             iLevelCount% = iLevelCount% + 1
  854.             IF iLevelCount% > iLevelSize% THEN
  855.                 iLevelCount% = 0
  856.                 iPosX1% = iPosX1% + 1
  857.                 iPosX2% = iPosX2% - 1
  858.                 iPosY1% = iPosY1% + 1
  859.                 iPosY2% = iPosY2% - 1
  860.             END IF
  861.            
  862.             ' QUIT AFTER WE REACH THE TOP
  863.             If (iPosX1% <= iPosX2%) And (iPosY1% <= iPosY2%) Then
  864.                 iZ% = iZ% + 1
  865.                 DoCycleColor iColorScheme%, iNextColor&
  866.                 If iZ% > m_iMapMaxZ Then
  867.                     bContinue = FALSE
  868.                 End If
  869.             Else
  870.                 bContinue = FALSE
  871.             End If
  872.            
  873.         Loop Until bContinue = FALSE
  874.                
  875.                 ' -----------------------------------------------------------------------------
  876.                 ' DRAW FRAME AROUND ENTIRE SPACE (TOP)
  877.                 FOR iLoopX% = m_iMapMinX+3 TO m_iMapMaxX-3
  878.                         m_arrMap(iLoopX%, m_iMapMaxY-3, m_iMapMaxZ).Typ = c_iTile_Wall
  879.                         m_arrMap(iLoopX%, m_iMapMaxY-3, m_iMapMaxZ).Color1 = cWhite& ' cPurple&
  880.                        
  881.                         m_arrMap(iLoopX%, m_iMapMinY+3, m_iMapMaxZ).Typ = c_iTile_Wall
  882.                         m_arrMap(iLoopX%, m_iMapMinY+3, m_iMapMaxZ).Color1 = cCyan&
  883.                 NEXT iLoopX%
  884.                
  885.                 FOR iLoopY% = m_iMapMinY+3 TO m_iMapMaxY-3
  886.                         m_arrMap(m_iMapMinX+3, iLoopY%, m_iMapMaxZ).Typ = c_iTile_Wall
  887.                         m_arrMap(m_iMapMinX+3, iLoopY%, m_iMapMaxZ).Color1 = cOrange&
  888.                        
  889.                         m_arrMap(m_iMapMaxX-3, iLoopY%, m_iMapMaxZ).Typ = c_iTile_Wall
  890.                         m_arrMap(m_iMapMaxX-3, iLoopY%, m_iMapMaxZ).Color1 = cLime&
  891.                 NEXT iLoopY%
  892.                
  893.                 ' -----------------------------------------------------------------------------
  894.                 ' DRAW FRAME AROUND ENTIRE SPACE (MIDDLE)
  895.                
  896.                 FOR iLoopX% = m_iMapMinX+2 TO m_iMapMaxX-2
  897.                         m_arrMap(iLoopX%, m_iMapMaxY-2, m_iMapMidZ).Typ = c_iTile_Wall
  898.                         m_arrMap(iLoopX%, m_iMapMaxY-2, m_iMapMidZ).Color1 = cWhite& ' cDodgerBlue&
  899.                        
  900.                         m_arrMap(iLoopX%, m_iMapMinY+2, m_iMapMidZ).Typ = c_iTile_Wall
  901.                         m_arrMap(iLoopX%, m_iMapMinY+2, m_iMapMidZ).Color1 = cDeepPurple&
  902.                 NEXT iLoopX%
  903.                
  904.                 FOR iLoopY% = m_iMapMinY+2 TO m_iMapMaxY-2
  905.                         m_arrMap(m_iMapMinX+2, iLoopY%, m_iMapMidZ).Typ = c_iTile_Wall
  906.                         m_arrMap(m_iMapMinX+2, iLoopY%, m_iMapMidZ).Color1 = cDarkRed&
  907.                        
  908.                         m_arrMap(m_iMapMaxX-2, iLoopY%, m_iMapMidZ).Typ = c_iTile_Wall
  909.                         m_arrMap(m_iMapMaxX-2, iLoopY%, m_iMapMidZ).Color1 = cGold&
  910.                 NEXT iLoopY%
  911.                
  912.                 ' -----------------------------------------------------------------------------
  913.                 ' DRAW FRAME AROUND ENTIRE SPACE (BOTTOM)
  914.                
  915.                 FOR iLoopX% = m_iMapMinX+1 TO m_iMapMaxX-1
  916.                         m_arrMap(iLoopX%, m_iMapMaxY-1, m_iMapMinZ+1).Typ = c_iTile_Wall
  917.                         m_arrMap(iLoopX%, m_iMapMaxY-1, m_iMapMinZ+1).Color1 = cWhite& ' cSeaBlue&
  918.                        
  919.                         m_arrMap(iLoopX%, m_iMapMinY+1, m_iMapMinZ+1).Typ = c_iTile_Wall
  920.                         m_arrMap(iLoopX%, m_iMapMinY+1, m_iMapMinZ+1).Color1 = cChartreuse&
  921.                 NEXT iLoopX%
  922.                
  923.                 FOR iLoopY% = m_iMapMinY+1 TO m_iMapMaxY-1
  924.                         m_arrMap(m_iMapMinX+1, iLoopY%, m_iMapMinZ+1).Typ = c_iTile_Wall
  925.                         m_arrMap(m_iMapMinX+1, iLoopY%, m_iMapMinZ+1).Color1 = cOrangeRed&
  926.                        
  927.                         m_arrMap(m_iMapMaxX-1, iLoopY%, m_iMapMinZ+1).Typ = c_iTile_Wall
  928.                         m_arrMap(m_iMapMaxX-1, iLoopY%, m_iMapMinZ+1).Color1 = cDeepSkyBlue&
  929.                 NEXT iLoopY%
  930.     END IF
  931.        
  932.     ' =============================================================================
  933.     ' PLACE PLAYER(S) <- ONLY ONE FOR THIS DEMO
  934.    
  935.     FOR iPlayerLoop = 1 TO m_iPlayerCount
  936.        
  937.         ' -----------------------------------------------------------------------------
  938.         ' BEGIN Map the 6 directional keys
  939.         ' -----------------------------------------------------------------------------
  940.         '*** CURRENTLY THIS IS NOT USED ***
  941.         'TODO: GET THIS WORKING (CURRENTLY IT'S ALL WEIRD)
  942.         'TODO: WHATEVER THE KEYS MAPPED ARE, SWAP THEM NON-HARDCODED
  943.        
  944.         ' differently for each of the 6 directional orientations!
  945.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyBack = c_iKeyDown_Down
  946.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyForward = c_iKeyDown_Up
  947.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyLeft = c_iKeyDown_Left
  948.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyRight = c_iKeyDown_Right
  949.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyUp = c_iKeyDown_PgDn
  950.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Down).KeyDown = c_iKeyDown_PgUp
  951.        
  952.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyBack = c_iKeyDown_PgDn
  953.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyForward = c_iKeyDown_PgUp
  954.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyLeft = c_iKeyDown_Left
  955.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyRight = c_iKeyDown_Right
  956.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyUp = c_iKeyDown_Up
  957.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Up).KeyDown = c_iKeyDown_Down
  958.        
  959.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyBack = c_iKeyDown_Right
  960.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyForward = c_iKeyDown_Left
  961.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyLeft = c_iKeyDown_Down
  962.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyRight = c_iKeyDown_Up
  963.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyUp = c_iKeyDown_PgUp
  964.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Left).KeyDown = c_iKeyDown_PgDn
  965.        
  966.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyBack = c_iKeyDown_Left
  967.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyForward = c_iKeyDown_Right
  968.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyLeft = c_iKeyDown_Up
  969.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyRight = c_iKeyDown_Down
  970.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyUp = c_iKeyDown_PgUp
  971.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Right).KeyDown = c_iKeyDown_PgDn
  972.        
  973.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyBack = c_iKeyDown_Down
  974.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyForward = c_iKeyDown_Up
  975.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyLeft = c_iKeyDown_Right
  976.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyRight = c_iKeyDown_Left
  977.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyUp = c_iKeyDown_PgUp
  978.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Back).KeyDown = c_iKeyDown_PgDn
  979.        
  980.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyBack = c_iKeyDown_Up
  981.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyForward = c_iKeyDown_Down
  982.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyLeft = c_iKeyDown_Left
  983.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyRight = c_iKeyDown_Right
  984.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyUp = c_iKeyDown_PgUp
  985.         m_arrDirKeyMap(iPlayerLoop, c_iDir_Forward).KeyDown = c_iKeyDown_PgDn
  986.         ' -----------------------------------------------------------------------------
  987.         ' END Map the 6 directional keys
  988.         ' -----------------------------------------------------------------------------
  989.        
  990.         ' FIND START POSITION
  991.         iX% = RandomNumber(m_iMapMinX, m_iMapMaxX)
  992.         iY% = RandomNumber(m_iMapMinY, m_iMapMaxY)
  993.         iZ% = 1 ' RandomNumber(m_iMapMinZ, m_iMapMaxZ)
  994.        
  995.         ' MAKE SURE IT'S EMPTY
  996.         IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  997.             bFound = TRUE
  998.         ELSE
  999.             ' IF NOT EMPTY THEN TRY TO FIND AN EMPTY SPOT
  1000.             iTotal% = ((m_iMapMaxX - m_iMapMinX)+1) * ((m_iMapMaxY - m_iMapMinY)+1) * ((m_iMapMaxZ - m_iMapMinZ)+1)
  1001.             iCount% = 0
  1002.             bFound = FALSE
  1003.             Do
  1004.                 iX% = iX% + 1
  1005.                 if iX% > m_iMapMaxX then
  1006.                     ' reset x and move to next y
  1007.                     iX% = m_iMapMinX
  1008.                     iY% = iY% + 1
  1009.                     if iY% > m_iMapMaxY then
  1010.                         ' reset y and move to next z
  1011.                         iY% = m_iMapMinY
  1012.                         iZ% = iZ% + 1
  1013.                         if iZ% > m_iMapMaxZ then
  1014.                             ' RESET Z AND SEE IF WE HAVE CHECKED EVERYTHING
  1015.                             iZ% = m_iMapMinZ
  1016.                             iCount% = iCount% + 1
  1017.                             if iCount% >= iTotal% then
  1018.                                 ' NONE FOUND, EXIT
  1019.                                 Exit Do
  1020.                             end if
  1021.                         else
  1022.                             iCount% = iCount% + 1
  1023.                         end if
  1024.                     else
  1025.                         iCount% = iCount% + 1
  1026.                     end if
  1027.                 else
  1028.                     iCount% = iCount% + 1
  1029.                 end if
  1030.                 IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  1031.                     ' FOUND AN EMPTY SPACE, EXIT
  1032.                     bFound = TRUE
  1033.                     Exit Do
  1034.                 END IF
  1035.             Loop
  1036.         END IF
  1037.        
  1038.         If bFound = TRUE THEN
  1039.             ' PICK A DIRECTION (SIMPLE FOR NOW, LEFT OR RIGHT)
  1040.             if iX% <= m_iMapMidX then
  1041.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1042.             else
  1043.                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1044.             end if
  1045.            
  1046.             m_arrPlayer(iPlayerLoop).Tile1 = c_iTile_Player1
  1047.            
  1048.             ' SAVE COORDINATES TO PLAYER
  1049.             ' ****************************************************************************************************************************************************************
  1050.             ' for this demo we'll just use iX% instead of m_arrPlayer(iPlayerLoop).x, etc.
  1051.             ' to make it more readable
  1052.             ' ****************************************************************************************************************************************************************
  1053.             m_arrPlayer(iPlayerLoop).x = iX%
  1054.             m_arrPlayer(iPlayerLoop).y = iY%
  1055.             m_arrPlayer(iPlayerLoop).z = iZ%
  1056.             m_arrPlayer(iPlayerLoop).View = c_iDir_Forward
  1057.             m_arrPlayer(iPlayerLoop).Color1 = cRed&
  1058.             m_arrPlayer(iPlayerLoop).Alpha1 = 255
  1059.             m_arrPlayer(iPlayerLoop).AlphaOverride = 255
  1060.             m_arrPlayer(iPlayerLoop).ColorScheme1 = 2
  1061.             m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 = 5 ' change color every 5 frames
  1062.             m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  1063.            
  1064.             ' DISPLAY OPTIONS
  1065.             m_arrPlayer(iPlayerLoop).GridSize = 8
  1066.             m_arrPlayer(iPlayerLoop).MapSize = 4
  1067.            
  1068.             ' RESET MOVEMENT VARIABLES
  1069.             m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  1070.             m_arrPlayer(iPlayerLoop).IsMoved = FALSE
  1071.            
  1072.             ' ********************************************************************************
  1073.             ' *** THIS IS NOW DONE AT THE RENDERING LEVEL FOR PLAYERS AND NON-TERRAIN OBJECTS
  1074.             ' ********************************************************************************
  1075.             '' DRAW PLAYER
  1076.             'm_arrMap(iX%, iY%, iZ%).Typ = m_arrPlayer(iPlayerLoop).Tile1
  1077.             'm_arrMap(iX%, iY%, iZ%).Color1 = m_arrPlayer(iPlayerLoop).Color1
  1078.             'm_arrMap(iX%, iY%, iZ%).AlphaOverride = m_arrPlayer(iPlayerLoop).Alpha1
  1079.            
  1080.         Else
  1081.             sError = "Could not find an empty space to start player."    
  1082.             Exit For
  1083.         End If
  1084.        
  1085.     NEXT iPlayerLoop
  1086.    
  1087.     ' =============================================================================
  1088.     ' OTHER SETUP
  1089.     If Len(sError)=0 Then
  1090.         ' RESET INPUT
  1091.         WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  1092.         iLastKey = c_iKeyDown_Enter
  1093.     End If
  1094.    
  1095.     ' =============================================================================
  1096.     ' MAIN LOOP
  1097.     If Len(sError)=0 Then
  1098.         iDrawColor% = 8 ' RED
  1099.         iCursorColor& = cRed&
  1100.         bFinished = FALSE
  1101.         Do
  1102.             CLS ' is cls necessary?
  1103.            
  1104.             ' SHOW INSTRUCTIONS / COORDINATES ON SCREEN
  1105.             LOCATE  1, 3: PRINT "IsometricDraw1"
  1106.             LOCATE  3, 3: PRINT "CRSR RT/LF MOVES X = " + CSTR$(iX%)
  1107.             LOCATE  4, 3: PRINT "CRSR UP/DN MOVES Y = " + CSTR$(iY%)
  1108.             LOCATE  5, 3: PRINT "PAGE UP/DN MOVES Z = " + CSTR$(iZ%)
  1109.             LOCATE  6, 3: PRINT "=    / -   CHANGES GRID SIZE     = " + CSTR$(m_arrPlayer(1).GridSize)
  1110.             LOCATE  7, 3: PRINT "[    / ]   TOGGLES MOVEMENT      = " + IIFSTR$(m_arrPlayer(1).IsMoving, "TRUE", "FALSE")
  1111.             LOCATE  8, 3: PRINT "INS  / DEL TOGGLES REPEAT KEYS   = " + IIFSTR$(bEnableRepeatingKeys, "TRUE", "FALSE")
  1112.             LOCATE  9, 3: PRINT ",    / .   CHANGES MINI MAP SIZE = " + CSTR$(m_arrPlayer(1).MapSize)
  1113.            
  1114.             LOCATE 12, 3: PRINT "PRESS <ESC> TO QUIT"
  1115.            
  1116.             LOCATE 25, 10: PRINT "1 color-"
  1117.             LOCATE 26, 10: PRINT "2 color+"
  1118.             LOCATE 27, 10: PRINT "3 draw"
  1119.             LOCATE 28, 10: PRINT "4 erase"
  1120.             LOCATE 29, 10: PRINT "5 toggle"
  1121.             LOCATE 30, 10: PRINT "6 eyedropper"
  1122.             LOCATE 31, 10: PRINT "7 clear"
  1123.             LOCATE 32, 10: PRINT "8 open"
  1124.             LOCATE 33, 10: PRINT "9 save"
  1125.            
  1126.             ' ****************************************************************************************************************************************************************
  1127.             ' BEGIN DRAW PALETTE
  1128.             ' ****************************************************************************************************************************************************************
  1129.             'TODO: support variable screen resolutions instead of hardcoded 1280x1024
  1130.             iSize% = 24 ' {n}x{n} pixels square
  1131.             iDrawX% = 10
  1132.             iOffsetY% = 350
  1133.             FOR iLoop1 = 0 TO 25
  1134.                 iDrawY% = iOffsetY%+(iLoop1 * iSize%)
  1135.                 IF iLoop1 = 0 THEN
  1136.                     ' COLOR = TRANSPARENT
  1137.                    
  1138.                     ' DRAW A CHECKERBOARD PATTERN FOR TRANSPARENT
  1139.                     iFirstColor& = cDarkGray&
  1140.                     FOR iLoopY% = iDrawY% TO ((iDrawY% + iSize%)-4) STEP 4
  1141.                         IF iFirstColor& = cDarkGray& THEN
  1142.                             iFirstColor& = cGray&
  1143.                         ELSE
  1144.                             iFirstColor& = cDarkGray&
  1145.                         END IF
  1146.                         iNextColor& = iFirstColor&
  1147.                         FOR iLoopX% = iDrawX% TO ((iDrawX% + iSize%)-4) STEP 4
  1148.                             DrawBox iLoopX%, iLoopY%, 4, iNextColor&
  1149.                             IF iNextColor& = cDarkGray& THEN
  1150.                                 iNextColor& = cGray&
  1151.                             ELSE
  1152.                                 iNextColor& = cDarkGray&
  1153.                             END IF
  1154.                         NEXT iLoopX%
  1155.                     NEXT iLoopY%
  1156.                 ELSEIF iLoop1 = 1 THEN
  1157.                     ' COLOR = BLACK
  1158.                 ELSE
  1159.                     iNextColor& = m_arrColors(iLoop1)
  1160.                     DrawBox iDrawX%, iDrawY%, iSize%, iNextColor&
  1161.                 END IF
  1162.                
  1163.                 ' DRAW A BORDER AROUND IT
  1164.                 iNextColor& = cDarkGray&
  1165.                 DrawOutlineBox iDrawX%, iDrawY%, iSize%, iNextColor&, 1
  1166.             NEXT iLoop1
  1167.            
  1168.             ' DRAW WHITE BOX AROUND CURRENT COLOR
  1169.             DoCycleColor 1, iCursorColor&
  1170.             iDrawY% = iOffsetY%+(iDrawColor% * iSize%)
  1171.             DrawOutlineBox iDrawX%, iDrawY%, iSize%, iCursorColor&, 1
  1172.             ' ****************************************************************************************************************************************************************
  1173.             ' END DRAW PALETTE
  1174.             ' ****************************************************************************************************************************************************************
  1175.            
  1176.            
  1177.            
  1178.            
  1179.            
  1180.             ' ****************************************************************************************************************************************************************
  1181.             ' BEGIN PLAYER LOOP
  1182.             ' ****************************************************************************************************************************************************************
  1183.             DrawScreen c_iDir_Forward, m_arrSplitScreen(1).ScreenOffsetX, m_arrSplitScreen(1).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1184.                         m_bTesting = FALSE
  1185.                        
  1186.             DrawScreen c_iDir_Back,    m_arrSplitScreen(2).ScreenOffsetX, m_arrSplitScreen(2).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1187.             DrawScreen c_iDir_Left,    m_arrSplitScreen(3).ScreenOffsetX, m_arrSplitScreen(3).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1188.             DrawScreen c_iDir_Right,   m_arrSplitScreen(4).ScreenOffsetX, m_arrSplitScreen(4).ScreenOffsetY, m_arrPlayer(1).GridSize, iX%, iY%, iZ%
  1189.            
  1190.             FOR iPlayerLoop = 1 TO m_iPlayerCount
  1191.                 'DrawScreen m_arrPlayer(iPlayerLoop).View, cScreenOffsetX, cScreenOffsetY, iX%, iY%, iZ%
  1192.                
  1193.                 ' -----------------------------------------------------------------------------
  1194.                 ' BEGIN SHOW 2D MINI MAP ON SCREEN
  1195.                 ' -----------------------------------------------------------------------------
  1196.                 ' TODO: FOR MULTIPLAYER, DRAW A SEPARATE MAP PER PLAYER TO SPLIT SCREEN
  1197.                 FOR iLoopX% = m_iMapMinX TO m_iMapMaxX
  1198.                     FOR iLoopY% = m_iMapMinY TO m_iMapMaxY
  1199.                         'iDrawX% = (iLoopX% * 4) + 20
  1200.                         iDrawX% = (iLoopX% * m_arrPlayer(1).MapSize) + 20
  1201.                        
  1202.                         'iDrawY% = (iLoopY% * 4) + 200
  1203.                         iDrawY% = (iLoopY% * m_arrPlayer(1).MapSize) + 200
  1204.                        
  1205.                         IF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Wall THEN
  1206.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1207.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1208.                            
  1209.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player1 THEN
  1210.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1211.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1212.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player2 THEN
  1213.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1214.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1215.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player3 THEN
  1216.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1217.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1218.                         ELSEIF m_arrMap(iLoopX%, iLoopY%, iZ%).Typ = c_iTile_Player4 THEN
  1219.                             'DrawBox iDrawX%, iDrawY%, 4, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1220.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrMap(iLoopX%, iLoopY%, iZ%).Color1
  1221.                            
  1222.                         'TODO: ADD OTHER TYPES
  1223.                        
  1224.                         ELSE
  1225.                             'DrawBox iDrawX%, iDrawY%, 4, cBlack&
  1226.                             'DrawBox iDrawX%, iDrawY%, 4, cKhaki&
  1227.                             DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, cKhaki&
  1228.                         END IF
  1229.                     NEXT iLoopY%
  1230.                 NEXT iLoopX%
  1231.                                
  1232.                                 ' DRAW THE PLAYERS ON THE MINI MAP
  1233.                                 For iLoop1 = m_iPlayerMin To m_iPlayerCount
  1234.                                         iDrawX% = (m_arrPlayer(iLoop1).x * m_arrPlayer(1).MapSize) + 20
  1235.                                         iDrawY% = (m_arrPlayer(iLoop1).y * m_arrPlayer(1).MapSize) + 200
  1236.                                        
  1237.                                         ' TODO: ADD Alpha PARAMETER TO DrawBox
  1238.                                         DrawBox iDrawX%, iDrawY%, m_arrPlayer(1).MapSize, m_arrPlayer(iLoop1).Color1
  1239.                                 Next iLoop1
  1240.                                
  1241.                                 ' DRAW THE OBJECTS ON THE MINI MAP
  1242.                                 ' (TO DO WHEN WE ADD OBJECTS)
  1243.                                
  1244.                 ' -----------------------------------------------------------------------------
  1245.                 ' END SHOW 2D MINI MAP ON SCREEN
  1246.                 ' -----------------------------------------------------------------------------
  1247.                
  1248.                
  1249.                 ' -----------------------------------------------------------------------------
  1250.                 ' BEGIN GET DIRECTIONAL KEYBOARD INPUT
  1251.                 ' -----------------------------------------------------------------------------
  1252.                 If _KeyDown(c_iKeyDown_Up) Then
  1253.                     If iLastKey <> c_iKeyDown_Up OR bEnableRepeatingKeys=TRUE Then
  1254.                         iLastKey = c_iKeyDown_Up
  1255.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  1256.                         bMoved = TRUE
  1257.                     End If
  1258.                 ElseIf _KeyDown(c_iKeyDown_Down) Then
  1259.                     If iLastKey <> c_iKeyDown_Down OR bEnableRepeatingKeys=TRUE Then
  1260.                         iLastKey = c_iKeyDown_Down
  1261.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  1262.                         bMoved = TRUE
  1263.                     End If
  1264.                 ElseIf _KeyDown(c_iKeyDown_Left) Then
  1265.                     If iLastKey <> c_iKeyDown_Left OR bEnableRepeatingKeys=TRUE Then
  1266.                         iLastKey = c_iKeyDown_Left
  1267.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1268.                         bMoved = TRUE
  1269.                     End If
  1270.                 ElseIf _KeyDown(c_iKeyDown_Right) Then
  1271.                     If iLastKey <> c_iKeyDown_Right OR bEnableRepeatingKeys=TRUE Then
  1272.                         iLastKey = c_iKeyDown_Right
  1273.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1274.                         bMoved = TRUE
  1275.                     End If
  1276.                 ElseIf _KeyDown(c_iKeyDown_PgUp) Then
  1277.                     If iLastKey <> c_iKeyDown_PgUp OR bEnableRepeatingKeys=TRUE Then
  1278.                         iLastKey = c_iKeyDown_PgUp
  1279.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  1280.                         bMoved = TRUE
  1281.                     End If
  1282.                 ElseIf _KeyDown(c_iKeyDown_PgDn) Then
  1283.                     If iLastKey <> c_iKeyDown_PgDn OR bEnableRepeatingKeys=TRUE Then
  1284.                         iLastKey = c_iKeyDown_PgDn
  1285.                         m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  1286.                         bMoved = TRUE
  1287.                     End If                
  1288.                 ' -----------------------------------------------------------------------------
  1289.                 ' END GET DIRECTIONAL KEYBOARD INPUT
  1290.                 ' -----------------------------------------------------------------------------
  1291.                
  1292.                
  1293.                 ' -----------------------------------------------------------------------------
  1294.                 ' BEGIN GET DRAWING INPUT
  1295.                 ' -----------------------------------------------------------------------------
  1296.                 ' 1 color-
  1297.                 ElseIf _KeyDown(c_iKeyDown_1) Then
  1298.                     If iLastKey <> c_iKeyDown_1 OR bEnableRepeatingKeys=TRUE Then
  1299.                         iLastKey = c_iKeyDown_1
  1300.                        
  1301.                         iDrawColor% = iDrawColor% - 1
  1302.                         IF iDrawColor% < 0 THEN
  1303.                             iDrawColor% = 25
  1304.                         END IF
  1305.                     End If
  1306.                    
  1307.                 ' 2 color+
  1308.                 ElseIf _KeyDown(c_iKeyDown_2) Then
  1309.                     If iLastKey <> c_iKeyDown_2 OR bEnableRepeatingKeys=TRUE Then
  1310.                         iLastKey = c_iKeyDown_2
  1311.                        
  1312.                         iDrawColor% = iDrawColor% + 1
  1313.                         IF iDrawColor% > 25 THEN
  1314.                             iDrawColor% = 0
  1315.                         END IF
  1316.                     End If
  1317.                    
  1318.                 ' 3 draw
  1319.                 ElseIf _KeyDown(c_iKeyDown_3) Then
  1320.                     If iLastKey <> c_iKeyDown_3 OR bEnableRepeatingKeys=TRUE Then
  1321.                         iLastKey = c_iKeyDown_3
  1322.                        
  1323.                         IF iDrawColor% > 0 THEN
  1324.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Wall
  1325.                         ELSE
  1326.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1327.                         END IF
  1328.                         m_arrMap(iX%, iY%, iZ%).Color1 = m_arrColors(iDrawColor%)
  1329.                         m_arrMap(iX%, iY%, iZ%).Alpha1 = 255
  1330.                         m_arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1331.                     End If
  1332.                    
  1333.                 ' 4 erase
  1334.                 ElseIf _KeyDown(c_iKeyDown_4) Then
  1335.                     If iLastKey <> c_iKeyDown_4 OR bEnableRepeatingKeys=TRUE Then
  1336.                         iLastKey = c_iKeyDown_4
  1337.                        
  1338.                         m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1339.                     End If
  1340.                    
  1341.                 ' 5 toggle
  1342.                 ElseIf _KeyDown(c_iKeyDown_5) Then
  1343.                     If iLastKey <> c_iKeyDown_5 OR bEnableRepeatingKeys=TRUE Then
  1344.                         iLastKey = c_iKeyDown_5
  1345.                        
  1346.                         IF m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty THEN
  1347.                             IF iDrawColor% > 0 THEN
  1348.                                 m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Wall
  1349.                             ELSE
  1350.                                 m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1351.                             END IF
  1352.                             m_arrMap(iX%, iY%, iZ%).Color1 = m_arrColors(iDrawColor%)
  1353.                             m_arrMap(iX%, iY%, iZ%).Alpha1 = 255
  1354.                             m_arrMap(iX%, iY%, iZ%).AlphaOverride = 255
  1355.                         ELSE
  1356.                             m_arrMap(iX%, iY%, iZ%).Typ = c_iTile_Empty
  1357.                         END IF
  1358.                     End If
  1359.                    
  1360.                 ' 6 eyedropper
  1361.                 ElseIf _KeyDown(c_iKeyDown_6) Then
  1362.                     If iLastKey <> c_iKeyDown_6 OR bEnableRepeatingKeys=TRUE Then
  1363.                         iLastKey = c_iKeyDown_6
  1364.                        
  1365.                         iDrawColor% = GetPaletteFromColor%(m_arrMap(iX%, iY%, iZ%).Color1)
  1366.                     End If
  1367.                    
  1368.                 ' 7 clear all
  1369.                 ElseIf _KeyDown(c_iKeyDown_7) Then
  1370.                     If iLastKey <> c_iKeyDown_7 OR bEnableRepeatingKeys=TRUE Then
  1371.                         iLastKey = c_iKeyDown_7
  1372.                        
  1373.                         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1374.                             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1375.                                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1376.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1377.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1 = cEmpty&
  1378.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1 = 255
  1379.                                                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1380.                                 Next iLoopZ%
  1381.                             Next iLoopY%
  1382.                         Next iLoopX%
  1383.                        
  1384.                     End If
  1385.                    
  1386.                 ' 8 open
  1387.                 ElseIf _KeyDown(c_iKeyDown_8) Then
  1388.                     If iLastKey <> c_iKeyDown_8 OR bEnableRepeatingKeys=TRUE Then
  1389.                         iLastKey = c_iKeyDown_8
  1390.                         'TBD
  1391.                     End If
  1392.                    
  1393.                 ' 9 save
  1394.                 ElseIf _KeyDown(c_iKeyDown_9) Then
  1395.                     If iLastKey <> c_iKeyDown_9 OR bEnableRepeatingKeys=TRUE Then
  1396.                         iLastKey = c_iKeyDown_9
  1397.                         'TBD
  1398.                     End If
  1399.                 ' -----------------------------------------------------------------------------
  1400.                 ' END GET DRAWING INPUT
  1401.                 ' -----------------------------------------------------------------------------
  1402.                
  1403.                
  1404.                
  1405.                
  1406.                 ' -----------------------------------------------------------------------------
  1407.                 ' BEGIN GET OTHER KEYBOARD INPUT
  1408.                 ' -----------------------------------------------------------------------------
  1409.                 ElseIf _KeyDown(c_iKeyDown_BracketLeft) Then
  1410.                     If iLastKey <> c_iKeyDown_BracketLeft OR bEnableRepeatingKeys=TRUE Then
  1411.                         iLastKey = c_iKeyDown_BracketLeft
  1412.                         m_arrPlayer(iPlayerLoop).IsMoving = TRUE
  1413.                     End If
  1414.                 ElseIf _KeyDown(c_iKeyDown_BracketRight) Then
  1415.                     If iLastKey <> c_iKeyDown_BracketRight OR bEnableRepeatingKeys=TRUE Then
  1416.                         iLastKey = c_iKeyDown_BracketRight
  1417.                         m_arrPlayer(iPlayerLoop).IsMoving = FALSE
  1418.                     End If
  1419.                    
  1420.                 ElseIf _KeyDown(c_iKeyDown_Comma) Then
  1421.                     If iLastKey <> c_iKeyDown_Comma OR bEnableRepeatingKeys=TRUE Then
  1422.                         iLastKey = c_iKeyDown_Comma
  1423.                         ' TODO: HAVE MAP SIZE PER PLAYER
  1424.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize - 1
  1425.                         IF m_arrPlayer(iPlayerLoop).MapSize < 1 THEN
  1426.                             m_arrPlayer(iPlayerLoop).MapSize = 1
  1427.                         ELSE
  1428.                             bMoved = TRUE
  1429.                         END IF
  1430.                     End If
  1431.                 ElseIf _KeyDown(c_iKeyDown_Period) Then
  1432.                     If iLastKey <> c_iKeyDown_Period OR bEnableRepeatingKeys=TRUE Then
  1433.                         iLastKey = c_iKeyDown_Period
  1434.                         m_arrPlayer(iPlayerLoop).MapSize = m_arrPlayer(iPlayerLoop).MapSize + 1
  1435.                         IF m_arrPlayer(iPlayerLoop).MapSize > m_iGridSizeMax THEN
  1436.                             m_arrPlayer(iPlayerLoop).MapSize = m_iGridSizeMax
  1437.                         ELSE
  1438.                             bMoved = TRUE
  1439.                         END IF
  1440.                     End If
  1441.                    
  1442.                 ElseIf _KeyDown(c_iKeyDown_Minus) Then
  1443.                     If iLastKey <> c_iKeyDown_Minus OR bEnableRepeatingKeys=TRUE Then
  1444.                         iLastKey = c_iKeyDown_Minus
  1445.                         ' TODO: HAVE SEPARATE GRID SIZE PER PLAYER / SPLIT SCREEN?
  1446.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize - 1
  1447.                         IF m_arrPlayer(iPlayerLoop).GridSize < m_iGridSizeMin THEN
  1448.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMin
  1449.                         ELSE
  1450.                             bMoved = TRUE
  1451.                         END IF
  1452.                     End If
  1453.                 ElseIf _KeyDown(c_iKeyDown_EqualPlus) Then
  1454.                     If iLastKey <> c_iKeyDown_EqualPlus OR bEnableRepeatingKeys=TRUE Then
  1455.                         iLastKey = c_iKeyDown_EqualPlus
  1456.                         m_arrPlayer(iPlayerLoop).GridSize = m_arrPlayer(iPlayerLoop).GridSize + 1
  1457.                         IF m_arrPlayer(iPlayerLoop).GridSize > m_iGridSizeMax THEN
  1458.                             m_arrPlayer(iPlayerLoop).GridSize = m_iGridSizeMax
  1459.                         ELSE
  1460.                             bMoved = TRUE
  1461.                         END IF
  1462.                     End If
  1463.                    
  1464.                 ElseIf _KeyDown(c_iKeyDown_Home) Then
  1465.                     If iLastKey <> c_iKeyDown_Home OR bEnableRepeatingKeys=TRUE Then
  1466.                         iLastKey = c_iKeyDown_Home
  1467.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  1468.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View - 1
  1469.                         IF m_arrPlayer(iPlayerLoop).View < c_iDir_Min THEN
  1470.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Max
  1471.                         END IF
  1472.                     End If
  1473.                 ElseIf _KeyDown(c_iKeyDown_End) Then
  1474.                     If iLastKey <> c_iKeyDown_End OR bEnableRepeatingKeys=TRUE Then
  1475.                         iLastKey = c_iKeyDown_End
  1476.                         ' c_iDir_Left, c_iDir_Right, c_iDir_Back, c_iDir_Forward, c_iDir_Down, c_iDir_Up
  1477.                         m_arrPlayer(iPlayerLoop).View = m_arrPlayer(iPlayerLoop).View + 1
  1478.                         IF m_arrPlayer(iPlayerLoop).View > c_iDir_Max THEN
  1479.                             m_arrPlayer(iPlayerLoop).View = c_iDir_Min
  1480.                         END IF
  1481.                     End If
  1482.                    
  1483.                 ElseIf _KeyDown(c_iKeyDown_Ins) Then
  1484.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  1485.                     If iLastKey <> c_iKeyDown_Ins OR bEnableRepeatingKeys=TRUE Then
  1486.                         iLastKey = c_iKeyDown_Ins
  1487.                         bEnableRepeatingKeys = TRUE
  1488.                     End If
  1489.                    
  1490.                 ElseIf _KeyDown(c_iKeyDown_Del) Then
  1491.                     ' TODO: DO WE NEED TO HANDLE REPEATING KEYS FOR MULTIPLAYER?
  1492.                     If iLastKey <> c_iKeyDown_Del OR bEnableRepeatingKeys=TRUE Then
  1493.                         iLastKey = c_iKeyDown_Del
  1494.                         bEnableRepeatingKeys = FALSE
  1495.                     End If
  1496.                    
  1497.                 ElseIf _KeyDown(c_iKeyDown_Esc) Then
  1498.                     Exit Do
  1499.                 Else
  1500.                     iLastKey = -1
  1501.                 End If
  1502.                 ' -----------------------------------------------------------------------------
  1503.                 ' END GET OTHER KEYBOARD INPUT
  1504.                 ' -----------------------------------------------------------------------------
  1505.                
  1506.                
  1507.                
  1508.                 ' --------------------------------------------------------------------------------
  1509.                 ' MOVE PLAYER BASED ON DIRECTION
  1510.                 ' --------------------------------------------------------------------------------
  1511.                 IF m_arrPlayer(iPlayerLoop).IsMoving=TRUE OR bMoved=TRUE THEN
  1512.                     bMoved = FALSE
  1513.                    
  1514.                     SELECT CASE m_arrPlayer(iPlayerLoop).Direction
  1515.                         CASE c_iDir_Down:
  1516.                             iNewX% = iX%
  1517.                             iNewY% = iY%
  1518.                             iNewZ% = iZ% - 1
  1519.                             If iNewZ% < m_iMapMinZ Then
  1520.                                 iNewZ% = m_iMapMaxZ
  1521.                             End If
  1522.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1523.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Up
  1524.                                 iNewZ% = iZ%
  1525.                             End If
  1526.                            
  1527.                         CASE c_iDir_Up:
  1528.                             iNewX% = iX%
  1529.                             iNewY% = iY%
  1530.                             iNewZ% = iZ% + 1
  1531.                             If iNewZ% > m_iMapMaxZ Then
  1532.                                 iNewZ% = m_iMapMinZ
  1533.                             End If
  1534.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1535.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Down
  1536.                                 iNewZ% = iZ%
  1537.                             End If
  1538.                            
  1539.                         CASE c_iDir_Left:
  1540.                             iNewX% = iX% - 1
  1541.                             iNewY% = iY%
  1542.                             iNewZ% = iZ%
  1543.                             If iNewX% < m_iMapMinX Then
  1544.                                 iNewX% = m_iMapMaxX
  1545.                             End If
  1546.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1547.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Right
  1548.                                 iNewX% = iX%
  1549.                             End If
  1550.                            
  1551.                         CASE c_iDir_Right:
  1552.                             iNewX% = iX% + 1
  1553.                             iNewY% = iY%
  1554.                             iNewZ% = iZ%
  1555.                             If iNewX% > m_iMapMaxX Then
  1556.                                 iNewX% = m_iMapMinX
  1557.                             End If
  1558.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1559.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Left
  1560.                                 iNewX% = iX%
  1561.                             End If
  1562.                            
  1563.                         CASE c_iDir_Back:
  1564.                             iNewX% = iX%
  1565.                             iNewY% = iY% - 1
  1566.                             iNewZ% = iZ%
  1567.                             If iNewY% < m_iMapMinY Then
  1568.                                 iNewY% = m_iMapMaxY
  1569.                             End If
  1570.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1571.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Forward
  1572.                                 iNewY% = iY%
  1573.                             End If
  1574.                            
  1575.                         CASE c_iDir_Forward:
  1576.                             iNewX% = iX%
  1577.                             iNewY% = iY% + 1
  1578.                             iNewZ% = iZ%
  1579.                             If iNewY% > m_iMapMaxY Then
  1580.                                 iNewY% = m_iMapMinY
  1581.                             End If
  1582.                             If (m_arrMap(iNewX%, iNewY%, iNewZ%).Typ <> c_iTile_Empty) AND (bIgnoreTerrain = FALSE) Then
  1583.                                 m_arrPlayer(iPlayerLoop).Direction = c_iDir_Back
  1584.                                 iNewY% = iY%
  1585.                             End If
  1586.                            
  1587.                         CASE ELSE:
  1588.                             ' (DO NOTHING)
  1589.                             'iNewX% = iX%
  1590.                             'iNewY% = iY%
  1591.                             'iNewZ% = iZ%
  1592.                     END SELECT
  1593.                    
  1594.                     ' SAVE NEW POSITION
  1595.                     iX% = iNewX%
  1596.                     iY% = iNewY%
  1597.                     iZ% = iNewZ%
  1598.                    
  1599.                     ' FOR MULTIPLAYER WE WOULD USE:
  1600.                     m_arrPlayer(iPlayerLoop).x = iNewX%
  1601.                     m_arrPlayer(iPlayerLoop).y = iNewY%
  1602.                     m_arrPlayer(iPlayerLoop).z = iNewZ%
  1603.                    
  1604.                 END IF
  1605.                
  1606.                 ' CYCLE COLOR
  1607.                 IF m_arrPlayer(iPlayerLoop).ColorScheme1 > 0 THEN
  1608.                     m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = m_arrPlayer(iPlayerLoop).ColorSchemeCount1 + 1
  1609.                     IF m_arrPlayer(iPlayerLoop).ColorSchemeCount1 > m_arrPlayer(iPlayerLoop).ColorSchemeSpeed1 THEN
  1610.                         m_arrPlayer(iPlayerLoop).ColorSchemeCount1 = 0
  1611.                         DoCycleColor m_arrPlayer(iPlayerLoop).ColorScheme1, m_arrPlayer(iPlayerLoop).Color1
  1612.                     END IF
  1613.                 END IF
  1614.                
  1615.             NEXT iPlayerLoop
  1616.            
  1617.             ' ****************************************************************************************************************************************************************
  1618.             ' END PLAYER LOOP
  1619.             ' ****************************************************************************************************************************************************************
  1620.            
  1621.         _Limit 30
  1622.         _Display
  1623.        
  1624.         Loop
  1625.     END IF
  1626.    
  1627. CleanupAndExit:
  1628.     ' FINISH UP AND EXIT
  1629.     WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  1630.     SCREEN 0
  1631.     IsometricDraw1$ = sResult
  1632. End Sub ' IsometricDraw1$
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1640. ' BEGIN GRAPHICS FUNCTIONS
  1641. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1642.  
  1643. ' =============================================================================
  1644. ' LET'S GET THE COORDINATES STRAIGHT!
  1645. ' Coordinates are m_arrMap(x,y,z)
  1646. '           ________________
  1647. '          /|e            /|e
  1648. '         / |            / |
  1649. '        /  |           /  |z-axis
  1650. '       /   |          /   |
  1651. '      /    /---------/----/
  1652. '     /    / a       /   b/  
  1653. '    /    /         /    /        
  1654. '   |--------------|    /  
  1655. '   |f  /         g|   / y-axis
  1656. '   |  /           |  /
  1657. '   | /            | /
  1658. '   |/c           d|/
  1659. '   ----------------
  1660. '      x-axis
  1661. '
  1662. ' POINT    ( X, Y, Z)
  1663. ' a        ( 0, 0, 0)
  1664. ' b        (32, 0, 0)
  1665. ' c        ( 0,32, 0)
  1666. ' d        (32,32, 0)
  1667. ' e        ( 0, 0,32)
  1668. ' f        ( 0,32,32)
  1669. ' g        (32,32,32)
  1670. ' =============================================================================
  1671.  
  1672. ' /////////////////////////////////////////////////////////////////////////////
  1673. ' INITIALIZE MAP TO EMPTY
  1674.  
  1675. ' Requires shared global variable:
  1676. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1677. Sub ClearIsometricMap
  1678.     Dim RoutineName As String: RoutineName = "ClearIsometricMap"
  1679.     Dim iLoopX%
  1680.     Dim iLoopY%
  1681.     Dim iLoopZ%
  1682.    
  1683.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1684.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1685.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1686.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1687.                 m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1688.             Next iLoopY%
  1689.         Next iLoopX%
  1690.     Next iLoopZ%
  1691. End Sub ' ClearIsometricMap
  1692.  
  1693. ' /////////////////////////////////////////////////////////////////////////////
  1694. ' INITIALIZE RENDERING MAP #1 TO EMPTY
  1695.  
  1696. ' Requires shared global variable:
  1697. ' m_arrRender1(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1698.  
  1699. Sub ClearRenderMap1
  1700.     Dim RoutineName As String: RoutineName = "ClearRenderMap1"
  1701.     Dim iLoopX%
  1702.     Dim iLoopY%
  1703.     Dim iLoopZ%
  1704.    
  1705.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1706.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1707.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1708.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1709.                 m_arrRender1(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1710.             Next iLoopY%
  1711.         Next iLoopX%
  1712.     Next iLoopZ%
  1713. End Sub ' ClearRenderMap1
  1714.  
  1715. ' /////////////////////////////////////////////////////////////////////////////
  1716. ' INITIALIZE RENDERING MAP #2 TO EMPTY
  1717.  
  1718. ' Requires shared global variable:
  1719. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1720.  
  1721. Sub ClearRenderMap2
  1722.     Dim RoutineName As String: RoutineName = "ClearRenderMap2"
  1723.     Dim iLoopX%
  1724.     Dim iLoopY%
  1725.     Dim iLoopZ%
  1726.    
  1727.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1728.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1729.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1730.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Empty
  1731.                 m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1732.             Next iLoopY%
  1733.         Next iLoopX%
  1734.     Next iLoopZ%
  1735. End Sub ' ClearRenderMap2
  1736.  
  1737. ' /////////////////////////////////////////////////////////////////////////////
  1738. ' Determine which squares are visible in isometric map
  1739.  
  1740. ' Original operates directly on the main map array m_arrMap
  1741. ' and not the copy (m_arrRender2) used to rotate the perspective.
  1742.  
  1743. ' Requires shared global variable (3D array of map):
  1744. ' m_arrMap(x,y,z) = 3D array map of world
  1745. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1746.  
  1747. ' RECEIVES:
  1748. ' iX% = player's X positon
  1749. ' iY% = player's Y position
  1750. ' iZ% = player's Z position
  1751.  
  1752. ' Direction is assumed to be c_iDir_Forward.
  1753.  
  1754. ' If iX% < 0 then we just render everything with its normal alpha value.
  1755.  
  1756. Sub ComputeVisible (iX%, iY%, iZ%, iGridSize)
  1757.     Dim RoutineName As String: RoutineName = "ComputeVisible"
  1758.     Dim iLoopX%
  1759.     Dim iLoopY%
  1760.     Dim iLoopZ%
  1761.    
  1762.     Dim iPX1%
  1763.     Dim iPY1%
  1764.     Dim iPZ1%
  1765.     Dim iPlayer2Dx As Integer
  1766.     Dim iPlayer2Dy As Integer
  1767.     Dim iTile2Dx As Integer
  1768.     Dim iTile2Dy As Integer
  1769.    
  1770.     IF iX% > -1 THEN
  1771.         ' CALCULATE PLAYER'S 2-D POSITION
  1772.         iPX1% = iX% * iGridSize + cGridOffsetX
  1773.         iPY1% = iY% * iGridSize + cGridOffsetY
  1774.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  1775.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1776.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1777.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1778.        
  1779.         ' LOOK AT EACH TILE
  1780.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1781.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1782.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1783.                    
  1784.                     ' *****************************************************************************
  1785.                     ' IF SPACE HAS A TILE
  1786.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  1787.                     ' THEN MAKE THE TILE TRANSPARENT
  1788.                     ' *****************************************************************************
  1789.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  1790.                     If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall OR m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  1791.                         ' CALCULATE TILE'S 2-D POSITION
  1792.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  1793.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  1794.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  1795.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1796.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1797.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1798.                        
  1799.                         'If iLoopZ% >= iZ% Then
  1800.                             'If iLoopX% >= iX% Then
  1801.                                
  1802.                                 ' FOR TILES FORWARD OF PLAYER
  1803.                                 If iLoopY% > iY% Then
  1804.                                    
  1805.                                     ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  1806.                                     If ( iPlayer2Dy >= (iTile2Dy - iGridSize) ) AND ( iPlayer2Dy <= (iTile2Dy + iGridSize) ) Then
  1807.                                        
  1808.                                         ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  1809.                                         If ( iPlayer2Dx >= (iTile2Dx - iGridSize) ) AND ( iPlayer2Dx <= (iTile2Dx + iGridSize) ) Then
  1810.                                             ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  1811.                                             ' TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE
  1812.                                             m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  1813.                                         Else
  1814.                                             ' LEAVE THE TILE OPAQUE
  1815.                                             ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1816.                                             m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1817.                                         End If
  1818.                                     Else
  1819.                                         ' LEAVE THE TILE OPAQUE
  1820.                                         ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1821.                                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1822.                                     End If
  1823.                                 Else
  1824.                                     ' LEAVE THE TILE OPAQUE
  1825.                                     ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1826.                                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1827.                                 End If
  1828.                             'End If
  1829.                         'End If
  1830.                     Else
  1831.                         ' LEAVE THE TILE OPAQUE
  1832.                         ' TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1833.                         m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1834.                     End If
  1835.                 Next iLoopZ%
  1836.             Next iLoopY%
  1837.         Next iLoopX%
  1838.     ELSE
  1839.         ' JUST MAKE ALL TILES VISIBLE
  1840.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1841.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1842.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1843.                     ' LEAVE THE TILE OPAQUE
  1844.                     m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1845.                    
  1846.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1847.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1848.                     'm_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1849.                    
  1850.                 Next iLoopZ%
  1851.             Next iLoopY%
  1852.         Next iLoopX%
  1853.     END IF
  1854. End Sub ' ComputeVisible
  1855.  
  1856. ' /////////////////////////////////////////////////////////////////////////////
  1857. ' Determine which squares are visible in isometric map
  1858.  
  1859. ' Same as ComputeVisible except uses the rotated copy
  1860. ' (m_arrRender2 instead of m_arrMap)
  1861.  
  1862. ' Requires shared global variable (3D array of map):
  1863. ' m_arrRender2(x,y,z) = rotated copy of 3D array map of world
  1864. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1865.  
  1866. ' RECEIVES:
  1867. ' iX% = player's X positon
  1868. ' iY% = player's Y position
  1869. ' iZ% = player's Z position
  1870.  
  1871. ' If iX% < 0 then we just render everything with its normal alpha value.
  1872.  
  1873. ' TODO: FIX FOR c_iDir_Down and c_iDir_Up DIRECTIONS
  1874. '       "FOR TILES FORWARD OF PLAYER" SECTION BELOW
  1875. '       NEEDS TO LOOK AT Z AXIS INSTEAD OF Y ?
  1876.  
  1877. Sub ComputeRenderVisible (iX%, iY%, iZ%, iGridSize)
  1878.     Dim RoutineName As String: RoutineName = "ComputeRenderVisible"
  1879.     Dim iLoopX%
  1880.     Dim iLoopY%
  1881.     Dim iLoopZ%
  1882.    
  1883.     Dim iPX1%
  1884.     Dim iPY1%
  1885.     Dim iPZ1%
  1886.     Dim iPlayer2Dx As Integer
  1887.     Dim iPlayer2Dy As Integer
  1888.     Dim iTile2Dx As Integer
  1889.     Dim iTile2Dy As Integer
  1890.    
  1891.     IF iX% > -1 THEN
  1892.         ' CALCULATE PLAYER'S 2-D POSITION
  1893.         iPX1% = iX% * iGridSize + cGridOffsetX
  1894.         iPY1% = iY% * iGridSize + cGridOffsetY
  1895.         iPZ1% = iZ% * iGridSize + cGridOffsetZ
  1896.         iPlayer2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1897.         iPlayer2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1898.         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1899.        
  1900.         ' LOOK AT EACH TILE
  1901.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1902.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1903.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1904.                    
  1905.                     ' *****************************************************************************
  1906.                     ' IF SPACE HAS A TILE
  1907.                     ' AND ITS 2D (X,Y) IS > PLAYER'S 2D (X,Y)
  1908.                     ' THEN MAKE THE TILE TRANSPARENT
  1909.                     ' *****************************************************************************
  1910.                     ' TODO: COMPARE AGAINST ALL TYPES OF TILES NOT JUST WALL/FLOOR
  1911.                     If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall OR m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  1912.                         ' CALCULATE TILE'S 2-D POSITION
  1913.                         iPX1% = iLoopX% * iGridSize + cGridOffsetX
  1914.                         iPY1% = iLoopY% * iGridSize + cGridOffsetY
  1915.                         iPZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  1916.                         iTile2Dx = CX2I(iPX1%, iPY1%) + cScreenOffsetX
  1917.                         iTile2Dy = (CY2I(iPX1%, iPY1%) + cScreenOffsetY) - iPZ1%
  1918.                         'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)    
  1919.                        
  1920.                         'If iLoopZ% >= iZ% Then
  1921.                             'If iLoopX% >= iX% Then
  1922.                                
  1923.                                 ' FOR TILES FORWARD OF PLAYER
  1924.                                 If iLoopY% > iY% Then
  1925.                                    
  1926.                                     ' IF PLAYER'S 2D Y POSITION IS WITHIN RANGE OF TILE'S 2D Y POSITION
  1927.                                     If ( iPlayer2Dy >= (iTile2Dy - iGridSize) ) AND ( iPlayer2Dy <= (iTile2Dy + iGridSize) ) Then
  1928.                                        
  1929.                                         ' AND IF PLAYER'S 2D X POSITION IS WITHIN RANGE OF TILE'S 2D X POSITION
  1930.                                         If ( iPlayer2Dx >= (iTile2Dx - iGridSize) ) AND ( iPlayer2Dx <= (iTile2Dx + iGridSize) ) Then
  1931.                                             ' RENDER THE TILE TRANSPARENT SO WE CAN SEE THE PLAYER
  1932.                                             'TODO: CHANGE AlphaOverride TO BE RELATIVE TO ORIGINAL Alpha VALUE?
  1933.                                             m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 86
  1934.                                         Else
  1935.                                             ' LEAVE THE TILE OPAQUE
  1936.                                             m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1937.                                            
  1938.                                             'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1939.                                             'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1940.                                             'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1941.                                         End If
  1942.                                     Else
  1943.                                         ' LEAVE THE TILE OPAQUE
  1944.                                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1945.                                        
  1946.                                         'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1947.                                         'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1948.                                         'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1949.                                     End If
  1950.                                 Else
  1951.                                     ' LEAVE THE TILE OPAQUE
  1952.                                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1953.                                    
  1954.                                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1955.                                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1956.                                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1957.                                 End If
  1958.                             'End If
  1959.                         'End If
  1960.                     Else
  1961.                         m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1962.                        
  1963.                         'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1964.                         'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1965.                     End If
  1966.                 Next iLoopZ%
  1967.             Next iLoopY%
  1968.         Next iLoopX%
  1969.     ELSE
  1970.         ' JUST MAKE ALL TILES VISIBLE
  1971.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  1972.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  1973.                 For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  1974.                     m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = 255
  1975.                    
  1976.                     'TODO: CHANGE 255 TO ORIGINAL Alpha VALUE
  1977.                     'TODO: SUPPORT CUSTOM ALPHA FOR COLORS (EVENTUALLY 3-COLOR TILES .Alpha1, .Alpha2, .Alpha3)
  1978.                     'm_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Alpha1
  1979.                 Next iLoopZ%
  1980.             Next iLoopY%
  1981.         Next iLoopX%
  1982.     END IF
  1983. End Sub ' ComputeRenderVisible
  1984.  
  1985. ' /////////////////////////////////////////////////////////////////////////////
  1986. ' Draw the map in 3D Isometic Perspective
  1987. ' from the forward (default) perspective.
  1988.  
  1989. ' Requires shared global variable
  1990. ' m_arrMap(x,y,z) = 3D array map of world
  1991. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  1992.  
  1993. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  1994. ' params instead of constants:
  1995. ' Const cScreenOffsetX = 500 ' 450
  1996. ' Const cScreenOffsetY = 300 ' 50
  1997. ' Const cScreenOffsetZ = 0
  1998.  
  1999. ' what about?
  2000. ' Const cGridOffsetX = 50
  2001. ' Const cGridOffsetY = 50
  2002. ' Const cGridOffsetZ = 0
  2003.  
  2004. Sub DrawIsometricScreen(iScreenOffsetX, iScreenOffsetY, iGridSize)
  2005.     Dim RoutineName As String: RoutineName = "DrawIsometricScreen"
  2006.     Dim bTile As Integer
  2007.     Dim iLoopX%
  2008.     Dim iLoopY%
  2009.     Dim iLoopZ%
  2010.     Dim iColor As _Unsigned Long
  2011.     Dim iPosX1%
  2012.     Dim iPosX2%
  2013.     Dim iPosY1%
  2014.     Dim iPosY2%
  2015.     Dim iPosZ1%
  2016.     Dim alpha&
  2017.    
  2018.     alpha& = 255
  2019.     bTile = FALSE
  2020.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2021.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2022.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2023.                
  2024.                 ' CALCULATE POSITION
  2025.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  2026.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  2027.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  2028.                 iPosX2% = iPosX1% + iGridSize
  2029.                 iPosY2% = iPosY1% + iGridSize
  2030.                
  2031.                 ' DETERMINE COLOR
  2032.                 If m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  2033.                     If bTile = TRUE Then
  2034.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2035.                         bTile = FALSE
  2036.                     Else
  2037.                         iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  2038.                         bTile = TRUE
  2039.                     End If
  2040.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  2041.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2042.                     alpha& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  2043.                    
  2044.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  2045.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2046.                     alpha& = 255
  2047.                    
  2048.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  2049.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2050.                     alpha& = 255
  2051.                    
  2052.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  2053.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2054.                     alpha& = 255
  2055.                    
  2056.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  2057.                     iColor = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2058.                     alpha& = 255
  2059.                    
  2060.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  2061.                     'TODO: transparent for water
  2062.                     iColor = cEmpty&
  2063.                     alpha& = 64
  2064.                    
  2065.                 ElseIf m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  2066.                     'TODO: transparent for windows
  2067.                     iColor = cEmpty&
  2068.                     alpha& = 64
  2069.                    
  2070.                 Else
  2071.                     iColor = cEmpty&
  2072.                 End If
  2073.                
  2074.                 ' PLOT NEXT TILE
  2075.                 If iColor <> cEmpty& Then
  2076.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  2077.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  2078.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  2079.                 End If
  2080.                
  2081.             Next iLoopY%
  2082.         Next iLoopX%
  2083.     Next iLoopZ%
  2084. End Sub ' DrawIsometricScreen
  2085.  
  2086. ' /////////////////////////////////////////////////////////////////////////////
  2087. ' Draw the map in 3D Isometic Perspective.
  2088.  
  2089. ' Requires shared global variable
  2090. ' m_arrRender2(x,y,z) = 3D array map of world
  2091. ' m_arrRender2(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  2092.  
  2093. Sub DrawRenderScreen(iScreenOffsetX, iScreenOffsetY, iGridSize)
  2094.     Dim RoutineName As String: RoutineName = "DrawRenderScreen"
  2095.     Dim bTile As Integer
  2096.     Dim iLoopX%
  2097.     Dim iLoopY%
  2098.     Dim iLoopZ%
  2099.     Dim iColor As _Unsigned Long
  2100.     Dim iPosX1%
  2101.     Dim iPosX2%
  2102.     Dim iPosY1%
  2103.     Dim iPosY2%
  2104.     Dim iPosZ1%
  2105.     Dim alpha&
  2106.    
  2107.     alpha& = 255
  2108.     bTile = FALSE
  2109.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2110.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2111.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2112.                
  2113.                 ' CALCULATE POSITION
  2114.                 iPosZ1% = iLoopZ% * iGridSize + cGridOffsetZ
  2115.                 iPosX1% = iLoopX% * iGridSize + cGridOffsetX
  2116.                 iPosY1% = iLoopY% * iGridSize + cGridOffsetY
  2117.                 iPosX2% = iPosX1% + iGridSize
  2118.                 iPosY2% = iPosY1% + iGridSize
  2119.                
  2120.                 ' DETERMINE COLOR
  2121.                 If m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Floor Then
  2122.                     If bTile = TRUE Then
  2123.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2124.                         bTile = FALSE
  2125.                     Else
  2126.                         iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color2
  2127.                         bTile = TRUE
  2128.                     End If
  2129.                    
  2130.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Wall Then
  2131.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2132.                     alpha& = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).AlphaOverride
  2133.                    
  2134.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player1 Then
  2135.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2136.                     alpha& = 255
  2137.                    
  2138.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player2 Then
  2139.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2140.                     alpha& = 255
  2141.                    
  2142.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player3 Then
  2143.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2144.                     alpha& = 255
  2145.                    
  2146.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Player4 Then
  2147.                     iColor = m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Color1
  2148.                     alpha& = 255
  2149.                    
  2150.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Water Then
  2151.                     'TODO: transparent for water
  2152.                     iColor = cEmpty&
  2153.                     alpha& = 64
  2154.                    
  2155.                 ElseIf m_arrRender2(iLoopX%, iLoopY%, iLoopZ%).Typ = c_iTile_Window Then
  2156.                     'TODO: transparent for windows
  2157.                     iColor = cEmpty&
  2158.                     alpha& = 64
  2159.                    
  2160.                 Else
  2161.                     iColor = cEmpty&
  2162.                 End If
  2163.                
  2164.                 ' PLOT NEXT TILE
  2165.                 If iColor <> cEmpty& Then
  2166.                     'IsoLine3D(x,      y,       x2,      y2,      z,       iHeight,     xoffset,        yoffset,        iColor As _Unsigned Long, alpha&)
  2167.                     'IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, m_iGridSize, cScreenOffsetX, cScreenOffsetY, iColor, alpha&
  2168.                     IsoLine3D iPosX1%, iPosY1%, iPosX2%, iPosY2%, iPosZ1%, iGridSize, iScreenOffsetX, iScreenOffsetY, iColor, alpha&
  2169.                 End If
  2170.                
  2171.             Next iLoopY%
  2172.         Next iLoopX%
  2173.     Next iLoopZ%
  2174. End Sub ' DrawRenderScreen
  2175.  
  2176. ' /////////////////////////////////////////////////////////////////////////////
  2177. ' Draw the map in 3D Isometic Perspective
  2178. ' from a different direction.
  2179.  
  2180. ' This is the lazy man's version which simply copies the tiles to
  2181. ' a temporary array, rotated to the specified direction/orientation.
  2182. ' A more efficient + faster method would operate directly on the
  2183. ' main array, but I am too bogged down to figure that out right now!
  2184.  
  2185. ' RECEIVES:
  2186. ' iDirection% = point of view to render from
  2187. '     i.e. the direction we are looking at the scene FROM
  2188. '     iDirection% can be one of the following:
  2189. '     c_iDir_Down
  2190. '     c_iDir_Up
  2191. '     c_iDir_Left
  2192. '     c_iDir_Right
  2193. '     c_iDir_Back
  2194. '     c_iDir_Forward = default
  2195. '    
  2196. '     If iDirection% = c_iDir_Forward, just call DrawIsometricScreen instead (faster).
  2197. '
  2198. ' iScreenOffsetX, iScreenOffsetY = where on display to draw
  2199. '
  2200. ' iX%, iY%, iZ% = player's position, used for ComputeRenderVisible
  2201. '     to compute which tiles to hide / make transparent
  2202. '     (tiles that might be hiding the player)
  2203. '     If these are <0, then ComputeRenderVisible uses original alpha values.
  2204.  
  2205. ' TODO: ADD OFFSET PARAMETERS FOR WHERE TO DRAW ON SCREEN (FOR SPLIT SCREEN)
  2206. ' params instead of constants:
  2207. ' Const cScreenOffsetX = 500 ' 450
  2208. ' Const cScreenOffsetY = 300 ' 50
  2209. ' Const cScreenOffsetZ = 0
  2210.  
  2211. ' what about?
  2212. ' Const cGridOffsetX = 50
  2213. ' Const cGridOffsetY = 50
  2214. ' Const cGridOffsetZ = 0
  2215.  
  2216. ' TODO: player layer
  2217. ' m_iPlayerCount
  2218. ' shared for current player #?
  2219. ' first copy world and superimpose player coords?
  2220.  
  2221. Sub DrawScreen(iDirection%, iScreenOffsetX, iScreenOffsetY, iGridSize, iX%, iY%, iZ%)
  2222.     Dim RoutineName As String: RoutineName = "DrawScreen"
  2223.     Dim bTile As Integer
  2224.     Dim iLoopX%
  2225.     Dim iLoopY%
  2226.     Dim iLoopZ%
  2227.     Dim iColor As _Unsigned Long
  2228.     Dim iPosX1%
  2229.     Dim iPosX2%
  2230.     Dim iPosY1%
  2231.     Dim iPosY2%
  2232.     Dim iPosZ1%
  2233.     Dim alpha&
  2234.    
  2235.     ' =============================================================================
  2236.     ' USE FIRST TEMPORARY ARRAY TO STORE SCENE OVERLAID WITH PLAYERS + OBJECTS
  2237.    
  2238.     ' CLEAR THE MAP (NECESSARY?)
  2239.     ClearRenderMap1
  2240.    
  2241.     ' FIRST COPY THE MAP
  2242.     For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2243.         For iLoopX% = m_iMapMinX To m_iMapMaxX
  2244.             For iLoopY% = m_iMapMinY To m_iMapMaxY
  2245.                 'm_arrRender1(iLoopX%,iLoopY%,iLoopZ%) = m_arrMap(iLoopX%, iLoopY%, iLoopZ%)
  2246.                 CopyMapTile m_arrMap(iLoopX%, iLoopY%, iLoopZ%), m_arrRender1(iLoopX%,iLoopY%,iLoopZ%)
  2247.             Next iLoopY%
  2248.         Next iLoopX%
  2249.     Next iLoopZ%
  2250.    
  2251.     ' NEXT COPY THE PLAYERS
  2252.     For iLoopX% = m_iPlayerMin To m_iPlayerCount
  2253.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Typ = m_arrPlayer(iLoopX%).Tile1
  2254.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Color1 = m_arrPlayer(iLoopX%).Color1
  2255.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).Alpha1 = m_arrPlayer(iLoopX%).Alpha1
  2256.         m_arrRender1(m_arrPlayer(iLoopX%).x,m_arrPlayer(iLoopX%).y,m_arrPlayer(iLoopX%).z).AlphaOverride = m_arrPlayer(iLoopX%).AlphaOverride
  2257.     Next iLoopX%
  2258.    
  2259.     ' NEXT COPY THE OBJECTS
  2260.     ' (TO DO WHEN WE HAVE OBJECTS)
  2261.    
  2262.     ' =============================================================================
  2263.     ' USE SECOND TEMPORARY ARRAY TO STORE ROTATED SCENE THEN DRAW IT
  2264.    
  2265.     ' CLEAR THE MAP (NECESSARY?)
  2266.     ClearRenderMap2
  2267.    
  2268.     ' COPY TILES, ROTATED TO DESIRED VIEWING PERSPECTIVE / ANGLE
  2269.     SELECT CASE iDirection%
  2270.         CASE c_iDir_Down:
  2271.             ' SCENE IS FLIPPED UP (TOP FACE NOW FACING AWAY FROM US)
  2272.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2273.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2274.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2275.                         m_arrRender2(iLoopX%,m_iMapMaxZ-iLoopZ%,iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2276.                     Next iLoopY%
  2277.                 Next iLoopX%
  2278.             Next iLoopZ%
  2279.             ComputeRenderVisible iX%, m_iMapMaxZ-iZ%, iY%, iGridSize
  2280.         CASE c_iDir_Up:
  2281.             ' SCENE IS FLIPPED DOWN (TOP FACE NOW FACING TOWARD US)
  2282.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2283.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2284.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2285.                         m_arrRender2(iLoopX%,iLoopZ%,m_iMapMaxY-iLoopY%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2286.                     Next iLoopY%
  2287.                 Next iLoopX%
  2288.             Next iLoopZ%
  2289.             ComputeRenderVisible iX%, iZ%, m_iMapMaxY-iY%, iGridSize
  2290.         CASE c_iDir_Left:
  2291.             ' SCENE IS ROTATED COUNTER CLOCKWISE FROM TOP (LEFT FACE NOW FACING TOWARD US)
  2292.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2293.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2294.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2295.                         m_arrRender2(iLoopY%,m_iMapMaxX-iLoopX%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2296.                     Next iLoopY%
  2297.                 Next iLoopX%
  2298.             Next iLoopZ%
  2299.             ComputeRenderVisible iY%, m_iMapMaxX-iX%, iZ%, iGridSize
  2300.         CASE c_iDir_Right:
  2301.             ' SCENE IS ROTATED CLOCKWISE FROM TOP (RIGHT FACE NOW FACING TOWARD US)
  2302.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2303.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2304.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2305.                         m_arrRender2(m_iMapMaxY-iLoopY%,iLoopX%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2306.                     Next iLoopY%
  2307.                 Next iLoopX%
  2308.             Next iLoopZ%
  2309.             ComputeRenderVisible m_iMapMaxY-iY%, iX%, iZ%, iGridSize
  2310.         CASE c_iDir_Back:
  2311.             ' SCENE IS TURNED AROUND (FRONT FACE NOW FACING AWAY FROM US)
  2312.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2313.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2314.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2315.                         m_arrRender2(m_iMapMaxX-iLoopX%,m_iMapMaxY-iLoopY%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2316.                     Next iLoopY%
  2317.                 Next iLoopX%
  2318.             Next iLoopZ%
  2319.             ComputeRenderVisible m_iMapMaxX-iX%, m_iMapMaxY-iY%, iZ%, iGridSize
  2320.         CASE ELSE: ' c_iDir_Forward
  2321.             ' FOR ALL OTHER CASES WE JUST DRAW FORWARD (FACING TOWARD US)
  2322.             For iLoopZ% = m_iMapMinZ To m_iMapMaxZ
  2323.                 For iLoopX% = m_iMapMinX To m_iMapMaxX
  2324.                     For iLoopY% = m_iMapMinY To m_iMapMaxY
  2325.                         m_arrRender2(iLoopX%,iLoopY%,iLoopZ%) = m_arrRender1(iLoopX%, iLoopY%, iLoopZ%)
  2326.                     Next iLoopY%
  2327.                 Next iLoopX%
  2328.             Next iLoopZ%
  2329.             ComputeRenderVisible iX%, iY%, iZ%, iGridSize
  2330.     END SELECT
  2331.     DrawRenderScreen iScreenOffsetX, iScreenOffsetY, iGridSize
  2332. End Sub ' DrawScreen
  2333.  
  2334. ' /////////////////////////////////////////////////////////////////////////////
  2335. ' Copies a MapTileType user defined type variable, member by member
  2336. ' (not sure if you can just do MyUDT1 = MyUDT2?)
  2337.  
  2338. Sub CopyMapTile(SourceMap As MapTileType, DestMap As MapTileType)
  2339.     DestMap.Typ = SourceMap.Typ
  2340.     DestMap.Color1 = SourceMap.Color1
  2341.     DestMap.Color2 = SourceMap.Color2
  2342.     DestMap.Color3 = SourceMap.Color3
  2343.     DestMap.Alpha1 = SourceMap.Alpha1
  2344.     DestMap.Alpha2 = SourceMap.Alpha2
  2345.     DestMap.Alpha3 = SourceMap.Alpha3
  2346.     DestMap.AlphaOverride = SourceMap.AlphaOverride
  2347. End Sub ' CopyMapTile
  2348.  
  2349. ' /////////////////////////////////////////////////////////////////////////////
  2350. ' RETURNS MAP AS TEXT
  2351.  
  2352. ' Requires shared global variable
  2353. ' m_arrMap(x,y,z) = 3D array map of world
  2354. ' m_arrMap(m_iMapMinX To m_iMapMaxX, m_iMapMinY To m_iMapMaxY, m_iMapMinZ To m_iMapMaxZ) As MapTileType
  2355.  
  2356. ' USAGE:
  2357. 'Input "See a text dump (y/n)? ", in$
  2358. 'If LCase$(in$) = LCase$("y") Then
  2359. '    Print MapToText$
  2360. 'End If
  2361.  
  2362. Function MapToText$
  2363.     Dim RoutineName As String: RoutineName = "MapToText$"
  2364.     Dim sResult As String
  2365.     Dim iLoopX%
  2366.     Dim iLoopY%
  2367.     Dim iLoopZ%
  2368.     Dim iMinX%
  2369.     Dim iMaxX%
  2370.     Dim iMinY%
  2371.     Dim iMaxY%
  2372.     Dim iMinZ%
  2373.     Dim iMaxZ%
  2374.     Dim sLine As String
  2375.     Dim iType%
  2376.     Dim iColor1&
  2377.     Dim iColor2&
  2378.     Dim iColor3&
  2379.     Dim in$
  2380.  
  2381.     sResult = ""
  2382.  
  2383.     ' FIND USED BOUNDARIES OF MAP
  2384.     iMinX% = -1
  2385.     iMaxX% = -1
  2386.     iMinY% = -1
  2387.     iMaxY% = -1
  2388.     iMinZ% = -1
  2389.     iMaxZ% = -1
  2390.     For iLoopZ% = 0 To 32
  2391.         For iLoopX% = 0 To 32
  2392.             For iLoopY% = 0 To 32
  2393.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  2394.                 If iType% <> c_iTile_Empty And iType% <> c_iTile_Floor Then
  2395.                     If iMinX% = -1 Then
  2396.                         iMinX% = iLoopX%
  2397.                     End If
  2398.                     If iMinY% = -1 Then
  2399.                         iMinY% = iLoopY%
  2400.                     End If
  2401.                     If iMinZ% = -1 Then
  2402.                         iMinZ% = iLoopZ%
  2403.                     End If
  2404.                     If iLoopX% > iMaxX% Then
  2405.                         iMaxX% = iLoopX%
  2406.                     End If
  2407.                     If iLoopY% > iMaxY% Then
  2408.                         iMaxY% = iLoopY%
  2409.                     End If
  2410.                     If iLoopZ% > iMaxZ% Then
  2411.                         iMaxZ% = iLoopZ%
  2412.                     End If
  2413.                 End If
  2414.             Next iLoopY%
  2415.         Next iLoopX%
  2416.     Next iLoopZ%
  2417.  
  2418.     ' GENERATE OUTPUT
  2419.     For iLoopZ% = iMinZ% To iMaxZ%
  2420.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  2421.         sResult = sResult + "Map Z=" + cstr$(iLoopZ%) + ":" + Chr$(13)
  2422.         sResult = sResult + "-------------------------------------------------------------------------------" + Chr$(13)
  2423.         For iLoopY% = iMinY% To iMaxY%
  2424.             sLine = ""
  2425.             For iLoopX% = iMinX% To iMaxX%
  2426.                 iType% = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Typ
  2427.                 iColor1& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color1
  2428.                 iColor2& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color2
  2429.                 iColor3& = m_arrMap(iLoopX%, iLoopY%, iLoopZ%).Color3
  2430.                
  2431.                 If iType% = c_iTile_Empty Then
  2432.                     sLine = sLine + " "
  2433.                 Else
  2434.                     If iColor1& = cEmpty& Then
  2435.                         sLine = sLine + " "
  2436.                     Else
  2437.                         sLine = sLine + "#"
  2438.                     End If
  2439.                 End If
  2440.             Next iLoopX%
  2441.             sResult = sResult + sLine + Chr$(13)
  2442.         Next iLoopY%
  2443.  
  2444.         sResult = sResult + Chr$(13)
  2445.     Next iLoopZ%
  2446.  
  2447.     MapToText$ = sResult
  2448. End Function ' MapToText$
  2449.  
  2450. ' /////////////////////////////////////////////////////////////////////////////
  2451. ' Return string description for 2.5D movement constants
  2452.  
  2453. FUNCTION GetDirection$(iDir AS INTEGER)
  2454.     DIM sDir AS STRING
  2455.     SELECT CASE iDir
  2456.         CASE c_iDir_Down:
  2457.             sDir = "Down"
  2458.         CASE c_iDir_Up:
  2459.             sDir = "Up"
  2460.         CASE c_iDir_Left:
  2461.             sDir = "Left"
  2462.         CASE c_iDir_Right:
  2463.             sDir = "Right"
  2464.         CASE c_iDir_Back:
  2465.             sDir = "Back"
  2466.         CASE c_iDir_Forward:
  2467.             sDir = "Forward"
  2468.         CASE ELSE:
  2469.             sDir = "Unknown"
  2470.     END SELECT
  2471.     GetDirection$ = sDir
  2472. END FUNCTION ' GetDirection$
  2473.  
  2474. ' /////////////////////////////////////////////////////////////////////////////
  2475.  
  2476. Function CX2I (x As Long, y As Long) 'Convert Cartesian X To Isometic coordinates
  2477.     CX2I = x - y
  2478. End Function ' CX2I
  2479.  
  2480. ' /////////////////////////////////////////////////////////////////////////////
  2481.  
  2482. Function CY2I (x As Long, y As Long) 'Convert Cartesian Y To Isometic coordinates
  2483.     CY2I = (x + y) / 2
  2484. End Function ' CY2I
  2485.  
  2486. ' /////////////////////////////////////////////////////////////////////////////
  2487. ' since we're drawing a diamond and not a square box, we can't use Line BF.
  2488. ' We have to manually down the 4 points of the line.
  2489.  
  2490. Sub IsoLine (x, y, x2, y2, xoffset, yoffset, iColor As _Unsigned Long)
  2491.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), iColor
  2492.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), iColor
  2493.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), iColor
  2494.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), iColor
  2495.     Paint (CX2I(x, y) + xoffset, CY2I(x, y) + 4), iColor 'and fill the diamond solid
  2496.     Line (CX2I(x, y) + xoffset, CY2I(x, y) + yoffset)-(CX2I(x2, y) + xoffset, CY2I(x2, y) + yoffset), &HFFFFFFFF
  2497.     Line -(CX2I(x2, y2) + xoffset, CY2I(x2, y2) + yoffset), &HFFFFFFFF
  2498.     Line -(CX2I(x, y2) + xoffset, CY2I(x, y2) + yoffset), &HFFFFFFFF
  2499.     Line -(CX2I(x, y) + xoffset, CY2I(x, y) + yoffset), &HFFFFFFFF
  2500. End Sub ' IsoLine
  2501.  
  2502. ' /////////////////////////////////////////////////////////////////////////////
  2503. ' Like IsoLine, we're going to have to draw our lines manually.
  2504. ' only in this case, we also need a Z coordinate to tell us how
  2505. ' THICK/TALL/HIGH to make our tile
  2506.  
  2507. ' MODIFIED by madscijr to draw a single tile of height iHeight at Z axis
  2508. ' MODIFIED by madscijr to accept an alpha& value to control transparency (where 0=fully transparent, 255=opaque)
  2509.  
  2510. ''Sub IsoLine3D (x, y, x2, y2, z, xoffset, yoffset, iColor As _Unsigned Long)
  2511. 'Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long)
  2512. Sub IsoLine3D (x, y, x2, y2, z, iHeight, xoffset, yoffset, iColor As _Unsigned Long, alpha&)
  2513.     dim r 'as integer
  2514.     dim g 'as integer
  2515.     dim b 'as integer
  2516.    
  2517.     r = _Red32(iColor)
  2518.     g = _Green32(iColor)
  2519.     b = _Blue32(iColor)
  2520.    
  2521.     If m_bTesting = TRUE Then
  2522.                 _Echo "IsoLine3D"
  2523.                 _Echo "    x=" + cstr$(x)
  2524.                 _Echo "    y=" + cstr$(y)
  2525.                 _Echo "    x2=" + cstr$(x2)
  2526.                 _Echo "    y2=" + cstr$(y2)
  2527.                 _Echo "    z=" + cstr$(z)
  2528.                 _Echo "    iHeight=" + cstr$(iHeight)
  2529.                 _Echo "    xoffset=" + cstr$(xoffset)
  2530.                 _Echo "    yoffset=" + cstr$(yoffset)
  2531.                 _Echo "    iColor=" + cstrul$(iColor)
  2532.                 _Echo "    alpha&=" + cstrl$(alpha&)
  2533.                 _Echo "    r=" + cstr$(r)
  2534.                 _Echo "    g=" + cstr$(g)
  2535.                 _Echo "    b=" + cstr$(b)
  2536.                 _Echo "    _RGB32(r, g, b, alpha&)=" + cstrul$(_RGB32(r, g, b, alpha&))
  2537.         End If
  2538.        
  2539.         ' Let's just do all the math first this time.
  2540.     ' We need to turn those 4 normal points into 4 isometric points (x, y, x1, y1)
  2541.     TempX1 = CX2I(x, y) + xoffset
  2542.     TempY1 = CY2I(x, y) + yoffset
  2543.     TempX2 = CX2I(x2, y) + xoffset
  2544.     TempY2 = CY2I(x2, y) + yoffset
  2545.     TempX3 = CX2I(x2, y2) + xoffset
  2546.     TempY3 = CY2I(x2, y2) + yoffset
  2547.     TempX4 = CX2I(x, y2) + xoffset
  2548.     TempY4 = CY2I(x, y2) + yoffset
  2549.    
  2550.     ' The top
  2551.     'fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, iColor
  2552.     fquad TempX1, TempY1 - z, TempX2, TempY2 - z, TempX3, TempY3 - z, TempX4, TempY4 - z, _RGB32(r, g, b, alpha&)
  2553.    
  2554.     If z <> 0 Then
  2555.         ' TODO: maybe change which sides gets shaded depending on the direction of the light source?
  2556.        
  2557.         ' draw the left side, shaded 75%
  2558.         'fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b)
  2559.         fquad TempX4, TempY4 - z, TempX4, TempY4 - z + iHeight, TempX3, TempY3 - z + iHeight, TempX3, TempY3 - z, _RGB32(.75 * r, .75 * g, .75 * b, alpha&)
  2560.        
  2561.         ' draw the right side,s haded 50%
  2562.         'fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b)
  2563.         fquad TempX3, TempY3 - z, TempX3, TempY3 - z + iHeight, TempX2, TempY2 - z + iHeight, TempX2, TempY2 - z, _RGB32(.5 * r, .5 * g, .5 * b, alpha&)
  2564.     Else
  2565.         ' no need to draw any height, if there isn't any.
  2566.     End If
  2567. End Sub ' IsoLine3D
  2568.  
  2569. ' /////////////////////////////////////////////////////////////////////////////
  2570. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  2571. ' don’t go there: http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=14425.0
  2572.  
  2573. Sub ftri (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  2574.     Dim D As Long
  2575.     Dim a&
  2576.  
  2577.     D = _Dest
  2578.     a& = _NewImage(1, 1, 32)
  2579.     _Dest a&
  2580.     PSet (0, 0), K
  2581.     _Dest D
  2582.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  2583.     _FreeImage a& ' <<< this is important!
  2584. End Sub ' ftri
  2585.  
  2586. ' /////////////////////////////////////////////////////////////////////////////
  2587. ' 2019-11-20 Steve saves some time with STATIC
  2588. ' and saves and restores last dest
  2589.  
  2590. Sub ftri1 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  2591.     Dim D As Long
  2592.     Static a&
  2593.  
  2594.     D = _Dest
  2595.     If a& = 0 Then
  2596.         a& = _NewImage(1, 1, 32)
  2597.     End If
  2598.     _Dest a&
  2599.     _DontBlend a&
  2600.     PSet (0, 0), K
  2601.     _Blend a&
  2602.     _Dest D
  2603.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  2604. End Sub ' ftri1
  2605.  
  2606. ' /////////////////////////////////////////////////////////////////////////////
  2607. ' original fill quad that may be at fault using Steve's fTri version
  2608. ' need 4 non linear points (not all on 1 line) list them clockwise
  2609. ' so x2, y2 is opposite of x4, y4
  2610.  
  2611. Sub fquad1 (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  2612.     ftri1 x1, y1, x2, y2, x4, y4, K
  2613.     ftri1 x3, y3, x2, y2, x4, y4, K
  2614. End Sub ' fquad1
  2615.  
  2616. ' /////////////////////////////////////////////////////////////////////////////
  2617. ' update 2019-12-16 needs orig fTri
  2618. ' need 4 non linear points (not all on 1 line)
  2619. ' list them clockwise so x2, y2 is opposite of x4, y4
  2620.  
  2621. Sub fquad (x1, y1, x2, y2, x3, y3, x4, y4, K As _Unsigned Long)
  2622.     ftri x1, y1, x2, y2, x3, y3, K
  2623.     ftri x3, y3, x4, y4, x1, y1, K
  2624. End Sub ' fquad
  2625.  
  2626. ' /////////////////////////////////////////////////////////////////////////////
  2627. ' DRAW A 2-D BOX (SOLID)
  2628. ' https://www.qb64.org/wiki/LINE
  2629.  
  2630. 'SUB DrawBox (iX%, iY%, iSize%, iColor%)
  2631. SUB DrawBox (iX%, iY%, iSize%, iColor&)
  2632.     LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor&, BF ' Draw a solid box
  2633.     'LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor%, BF ' Draw a solid box
  2634.     'LINE (60, 60)-(130, 100), iColor%, B ' Draw a box outline
  2635. END SUB ' DrawBox
  2636.  
  2637. ' /////////////////////////////////////////////////////////////////////////////
  2638. ' DRAW A 2-D BOX (OUTLINE)
  2639. ' https://www.qb64.org/wiki/LINE
  2640.  
  2641. ' The style parameter 0-255 doesn't seemt to have a solid line?
  2642.  
  2643. 'SUB DrawStyledOutlineBox (iX%, iY%, iSize%, iColor%, iStyle%)
  2644. SUB DrawStyledOutlineBox (iX%, iY%, iSize%, iColor&, iStyle%)
  2645.     ' LINE [STEP] [(column1, row1)]-[STEP] (column2, row2), color[, [{B|BF}], style%]
  2646.     ' B creates a box outline with each side parallel to the program screen sides. BF creates a filled box.
  2647.     ' The style% signed INTEGER value sets a dotted pattern to draw the line or rectangle outline.
  2648.    
  2649.     LINE (iX%, iY%)-(iX% + iSize%, iY% + iSize%), iColor&, B, iStyle%
  2650. END SUB ' DrawStyledOutlineBox
  2651.  
  2652. ' /////////////////////////////////////////////////////////////////////////////
  2653. ' DRAW A 2-D BOX (OUTLINE) WITH A SOLID LINE
  2654.  
  2655. SUB DrawOutlineBox (iX%, iY%, iSize2%, iColor&, iWeight2%)
  2656.     Dim iFromX%
  2657.     Dim iFromY%
  2658.     Dim iToX%
  2659.     Dim iToY%
  2660.     iSize% = iSize2% - 1
  2661.     iWeight% = iWeight2% - 1
  2662.     IF iWeight% = 0 THEN
  2663.         ' TOP LINE
  2664.         iFromX% = iX%
  2665.         iFromY% = iY%
  2666.         iToX% = iX% + iSize%
  2667.         iToY% = iY%
  2668.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2669.        
  2670.         ' BOTTOM LINE
  2671.         iFromX% = iX%
  2672.         iFromY% = iY% + iSize%
  2673.         iToX% = iX% + iSize%
  2674.         iToY% = iY% + iSize%
  2675.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2676.        
  2677.         ' LEFT LINE
  2678.         iFromX% = iX%
  2679.         iFromY% = iY%
  2680.         iToX% = iX%
  2681.         iToY% = iY% + iSize%
  2682.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2683.        
  2684.         ' RIGHT LINE
  2685.         iFromX% = iX% + iSize%
  2686.         iFromY% = iY%
  2687.         iToX% = iX% + iSize%
  2688.         iToY% = iY% + iSize%
  2689.         LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2690.     ELSEIF iWeight% > 0 THEN
  2691.         ' TOP LINE
  2692.         FOR iFromY% = iY% TO (iY% + iWeight%)
  2693.             iFromX% = iX%
  2694.             'iFromY% = iY%
  2695.             iToX% = iX% + iSize%
  2696.             iToY% = iFromY%
  2697.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2698.         NEXT iFromY%
  2699.        
  2700.         ' BOTTOM LINE
  2701.         FOR iFromY% = ((iY% + iSize%) - iWeight%) TO (iY% + iSize%)
  2702.             iFromX% = iX%
  2703.             'iFromY% = iY% + iSize%
  2704.             iToX% = iX% + iSize%
  2705.             iToY% = iFromY%
  2706.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2707.         NEXT iFromY%
  2708.        
  2709.         ' LEFT LINE
  2710.         FOR iFromX% = iX% TO (iX% + iWeight%)
  2711.             'iFromX% = iX%
  2712.             iFromY% = iY%
  2713.             iToX% = iFromX%
  2714.             iToY% = iY% + iSize%
  2715.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2716.         NEXT iFromX%
  2717.        
  2718.         ' RIGHT LINE
  2719.         FOR iFromX% = ((iX% + iSize%) - iWeight%) TO (iX% + iSize%)
  2720.             'iFromX% = iX% + iSize%
  2721.             iFromY% = iY%
  2722.             iToX% = iFromX%
  2723.             iToY% = iY% + iSize%
  2724.             LINE (iFromX%, iFromY%)-(iToX%, iToY%), iColor&, BF
  2725.         NEXT iFromX%
  2726.     END IF
  2727. END SUB ' DrawOutlineBox
  2728.  
  2729. ' /////////////////////////////////////////////////////////////////////////////
  2730.  
  2731. Function GetPaletteFromColor%(iColor&)
  2732.     SELECT CASE iColor&
  2733.         CASE cEmpty&:
  2734.             GetPaletteFromColor% = 0
  2735.         CASE cBlack&:
  2736.             GetPaletteFromColor% = 1
  2737.         CASE cDarkGray&:
  2738.             GetPaletteFromColor% = 2
  2739.         CASE cDimGray&:
  2740.             GetPaletteFromColor% = 3
  2741.         CASE cGray&:
  2742.             GetPaletteFromColor% = 4
  2743.         CASE cLightGray&:
  2744.             GetPaletteFromColor% = 5
  2745.         CASE cSilver&:
  2746.             GetPaletteFromColor% = 6
  2747.         CASE cWhite&:
  2748.             GetPaletteFromColor% = 7
  2749.         CASE cRed&:
  2750.             GetPaletteFromColor% = 8
  2751.         CASE cOrangeRed&:
  2752.             GetPaletteFromColor% = 9
  2753.         CASE cDarkOrange&:
  2754.             GetPaletteFromColor% = 10
  2755.         CASE cOrange&:
  2756.             GetPaletteFromColor% = 11
  2757.         CASE cGold&:
  2758.             GetPaletteFromColor% = 12
  2759.         CASE cYellow&:
  2760.             GetPaletteFromColor% = 13
  2761.         CASE cOliveDrab1&:
  2762.             GetPaletteFromColor% = 14
  2763.         CASE cLime&:
  2764.             GetPaletteFromColor% = 15
  2765.         CASE cMediumSpringGreen&:
  2766.             GetPaletteFromColor% = 16
  2767.         CASE cCyan&:
  2768.             GetPaletteFromColor% = 17
  2769.         CASE cDeepSkyBlue&:
  2770.             GetPaletteFromColor% = 18
  2771.         CASE cDodgerBlue&:
  2772.             GetPaletteFromColor% = 19
  2773.         CASE cSeaBlue&:
  2774.             GetPaletteFromColor% = 20
  2775.         CASE cBlue&:
  2776.             GetPaletteFromColor% = 21
  2777.         CASE cBluePurple&:
  2778.             GetPaletteFromColor% = 22
  2779.         CASE cDeepPurple&:
  2780.             GetPaletteFromColor% = 23
  2781.         CASE cPurple&:
  2782.             GetPaletteFromColor% = 24
  2783.         CASE cPurpleRed&:
  2784.             GetPaletteFromColor% = 25
  2785.         CASE ELSE:
  2786.             GetPaletteFromColor% = 0
  2787.     END SELECT
  2788. End Function ' GetPaletteFromColor%
  2789.  
  2790. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2791. ' END GRAPHICS FUNCTIONS
  2792. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2793.  
  2794. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2795. ' BEGIN GENERAL PURPOSE FUNCTIONS
  2796. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2797.  
  2798. ' /////////////////////////////////////////////////////////////////////////////
  2799.  
  2800. Function cstr$ (myValue)
  2801.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  2802.     cstr$ = _Trim$(Str$(myValue))
  2803. End Function ' cstr$
  2804.  
  2805. ' /////////////////////////////////////////////////////////////////////////////
  2806.  
  2807. Function cstrul$ (myValue As _Unsigned Long)
  2808.     cstrul$ = _Trim$(Str$(myValue))
  2809. End Function ' cstrul$
  2810.  
  2811. ' /////////////////////////////////////////////////////////////////////////////
  2812.  
  2813. Function cstrl$ (myValue As Long)
  2814.     cstrl$ = _Trim$(Str$(myValue))
  2815. End Function ' cstrl$
  2816.  
  2817. ' /////////////////////////////////////////////////////////////////////////////
  2818.  
  2819. Function cstrs$ (myValue As Single)
  2820.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  2821.     cstrs$ = _Trim$(Str$(myValue))
  2822. End Function ' cstrs$
  2823.  
  2824. ' /////////////////////////////////////////////////////////////////////////////
  2825.  
  2826. Function IIF (Condition, IfTrue, IfFalse)
  2827.     If Condition Then IIF = IfTrue Else IIF = IfFalse
  2828.  
  2829. ' /////////////////////////////////////////////////////////////////////////////
  2830.  
  2831. Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
  2832.     If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
  2833.  
  2834. ' /////////////////////////////////////////////////////////////////////////////
  2835. ' From: Bitwise Manipulations By Steven Roman
  2836. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  2837.  
  2838. ' Returns the 8-bit binary representation
  2839. ' of an integer iInput where 0 <= iInput <= 255
  2840.  
  2841. Function GetBinary$ (iInput1 As Integer)
  2842.     Dim sResult As String
  2843.     Dim iLoop As Integer
  2844.     Dim iInput As Integer: iInput = iInput1
  2845.  
  2846.     sResult = ""
  2847.  
  2848.     If iInput >= 0 And iInput <= 255 Then
  2849.         For iLoop = 1 To 8
  2850.             sResult = LTrim$(RTrim$(Str$(iInput Mod 2))) + sResult
  2851.             iInput = iInput \ 2
  2852.             'If iLoop = 4 Then sResult = " " + sResult
  2853.         Next iLoop
  2854.     End If
  2855.  
  2856.     GetBinary$ = sResult
  2857. End Function ' GetBinary$
  2858.  
  2859. ' /////////////////////////////////////////////////////////////////////////////
  2860. ' wonderfully inefficient way to read if a bit is set
  2861. ' ival = GetBit256%(int we are comparing, int containing the bits we want to read)
  2862.  
  2863. ' See also: GetBit256%, SetBit256%
  2864.  
  2865. Function GetBit256% (iNum1 As Integer, iBit1 As Integer)
  2866.     Dim iResult As Integer
  2867.     Dim sNum As String
  2868.     Dim sBit As String
  2869.     Dim iLoop As Integer
  2870.     Dim bContinue As Integer
  2871.     'DIM iTemp AS INTEGER
  2872.     Dim iNum As Integer: iNum = iNum1
  2873.     Dim iBit As Integer: iBit = iBit1
  2874.  
  2875.     iResult = FALSE
  2876.     bContinue = TRUE
  2877.  
  2878.     If iNum < 256 And iBit <= 128 Then
  2879.         sNum = GetBinary$(iNum)
  2880.         sBit = GetBinary$(iBit)
  2881.         For iLoop = 1 To 8
  2882.             If Mid$(sBit, iLoop, 1) = "1" Then
  2883.                 'if any of the bits in iBit are false, return false
  2884.                 If Mid$(sNum, iLoop, 1) = "0" Then
  2885.                     iResult = FALSE
  2886.                     bContinue = FALSE
  2887.                     Exit For
  2888.                 End If
  2889.             End If
  2890.         Next iLoop
  2891.         If bContinue = TRUE Then
  2892.             iResult = TRUE
  2893.         End If
  2894.     End If
  2895.  
  2896.     GetBit256% = iResult
  2897. End Function ' GetBit256%
  2898.  
  2899. ' /////////////////////////////////////////////////////////////////////////////
  2900. ' From: Bitwise Manipulations By Steven Roman
  2901. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  2902.  
  2903. ' Returns the integer that corresponds to a binary string of length 8
  2904.  
  2905. Function GetIntegerFromBinary% (sBinary1 As String)
  2906.     Dim iResult As Integer
  2907.     Dim iLoop As Integer
  2908.     Dim strBinary As String
  2909.     Dim sBinary As String: sBinary = sBinary1
  2910.  
  2911.     iResult = 0
  2912.     strBinary = Replace$(sBinary, " ", "") ' Remove any spaces
  2913.     For iLoop = 0 To Len(strBinary) - 1
  2914.         iResult = iResult + 2 ^ iLoop * Val(Mid$(strBinary, Len(strBinary) - iLoop, 1))
  2915.     Next iLoop
  2916.  
  2917.     GetIntegerFromBinary% = iResult
  2918. End Function ' GetIntegerFromBinary%
  2919.  
  2920. ' /////////////////////////////////////////////////////////////////////////////
  2921. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  2922.  
  2923. Function IsEven% (n)
  2924.     IF n MOD 2 = 0 THEN
  2925.         IsEven% = TRUE
  2926.     Else
  2927.         IsEven% = FALSE
  2928.     End If
  2929. End Function ' IsEven%
  2930.  
  2931. ' /////////////////////////////////////////////////////////////////////////////
  2932. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  2933.  
  2934. Function IsOdd% (n)
  2935.     IF n MOD 2 = 1 THEN
  2936.         IsOdd% = TRUE
  2937.     Else
  2938.         IsOdd% = FALSE
  2939.     End If
  2940. End Function ' IsOdd%
  2941.  
  2942. ' /////////////////////////////////////////////////////////////////////////////
  2943. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  2944.  
  2945. Function IsNum% (text$)
  2946.     Dim a$
  2947.     Dim b$
  2948.     a$ = _Trim$(text$)
  2949.     b$ = _Trim$(Str$(Val(text$)))
  2950.     If a$ = b$ Then
  2951.         IsNum% = TRUE
  2952.     Else
  2953.         IsNum% = FALSE
  2954.     End If
  2955. End Function ' IsNum%
  2956.  
  2957. ' /////////////////////////////////////////////////////////////////////////////
  2958. ' Split and join strings
  2959. ' https://www.qb64.org/forum/index.php?topic=1073.0
  2960.  
  2961. 'Combine all elements of in$() into a single string with delimiter$ separating the elements.
  2962.  
  2963. Function join$ (in$(), delimiter$)
  2964.     result$ = in$(LBound(in$))
  2965.     For i = LBound(in$) + 1 To UBound(in$)
  2966.         result$ = result$ + delimiter$ + in$(i)
  2967.     Next i
  2968.     join$ = result$
  2969. End Function ' join$
  2970.  
  2971. ' /////////////////////////////////////////////////////////////////////////////
  2972. ' ABS was returning strange values with type LONG
  2973. ' so I created this which does not.
  2974.  
  2975. Function LongABS& (lngValue As Long)
  2976.     If Sgn(lngValue) = -1 Then
  2977.         LongABS& = 0 - lngValue
  2978.     Else
  2979.         LongABS& = lngValue
  2980.     End If
  2981. End Function ' LongABS&
  2982.  
  2983. ' /////////////////////////////////////////////////////////////////////////////
  2984. ' Re: Does a Is Number function exist in QB64?
  2985. ' https://www.qb64.org/forum/index.php?topic=896.15
  2986.  
  2987. ' MWheatley
  2988. ' « Reply #18 on: January 01, 2019, 11:24:30 AM »
  2989.  
  2990. ' returns 1 if string is an integer, 0 if not
  2991. Function IsNumber (text$)
  2992.     Dim i As Integer
  2993.  
  2994.     IsNumber = 1
  2995.     For i = 1 To Len(text$)
  2996.         If Asc(Mid$(text$, i, 1)) < 45 Or Asc(Mid$(text$, i, 1)) >= 58 Then
  2997.             IsNumber = 0
  2998.             Exit For
  2999.         ElseIf Asc(Mid$(text$, i, 1)) = 47 Then
  3000.             IsNumber = 0
  3001.             Exit For
  3002.         End If
  3003.     Next i
  3004. End Function ' IsNumber
  3005.  
  3006. ' /////////////////////////////////////////////////////////////////////////////
  3007. ' iNum% = PromptForIntegerInRange%("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  3008.  
  3009. Function PromptForIntegerInRange% (sPrompt$, iMin%, iMax%, iDefault%)
  3010.     Dim iValue%
  3011.     Dim bFinished%
  3012.     Dim sPrompt1$
  3013.     Dim in$
  3014.  
  3015.     If Len(sPrompt$) > 0 Then
  3016.         sPrompt1$ = sPrompt$
  3017.     Else
  3018.         sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  3019.     End If
  3020.  
  3021.     sPrompt1$ = Replace$(sPrompt1$, "{min}", cstr$(iMin%))
  3022.     sPrompt1$ = Replace$(sPrompt1$, "{max}", cstr$(iMax%))
  3023.  
  3024.     bFinished% = FALSE
  3025.     Do
  3026.         Print sPrompt1$
  3027.  
  3028.         Input in$
  3029.         in$ = _Trim$(in$)
  3030.         If Len(in$) > 0 Then
  3031.             If IsNumber(in$) Then
  3032.                 iValue% = Val(in$)
  3033.                 If iValue% >= iMin% And iValue% <= iMax% Then
  3034.                     'bFinished% = TRUE
  3035.                     Exit Do
  3036.                 Else
  3037.                     Print "Number out of range."
  3038.                     Print
  3039.                 End If
  3040.             Else
  3041.                 Print "Not a valid number."
  3042.                 Print
  3043.             End If
  3044.         Else
  3045.             iValue% = iDefault%
  3046.             Exit Do
  3047.             'bFinished% = TRUE
  3048.         End If
  3049.     Loop Until bFinished% = TRUE
  3050.  
  3051.     PromptForIntegerInRange% = iValue%
  3052. End Function ' PromptForIntegerInRange%
  3053.  
  3054. ' /////////////////////////////////////////////////////////////////////////////
  3055. ' iNum& = PromptForLongInRange&("Please type a number between {min} and {max} (or blank to quit).", 1, 4, 0)
  3056.  
  3057. Function PromptForLongInRange& (sPrompt$, iMin&, iMax&, iDefault&)
  3058.     Dim iValue&
  3059.     Dim bFinished&
  3060.     Dim sPrompt1$
  3061.     Dim in$
  3062.    
  3063.     bFinished& = FALSE
  3064.     Do
  3065.         If Len(sPrompt$) > 0 Then
  3066.             sPrompt1$ = sPrompt$
  3067.         Else
  3068.             sPrompt1$ = "Please type a number between {min} and {max} (or blank to quit)."
  3069.         End If
  3070.        
  3071.         sPrompt1$ = Replace$ (sPrompt1$, "{min}", cstrl$(iMin&))
  3072.         sPrompt1$ = Replace$ (sPrompt1$, "{max}", cstrl$(iMax&))
  3073.        
  3074.         Input in$
  3075.         in$ = _Trim$(in$)
  3076.         If Len(in$) > 0 Then
  3077.             If IsNumber(in$) Then
  3078.                 iValue& = Val(in$)
  3079.                 If iValue& >= iMin& And iValue& <= iMax& Then
  3080.                     bFinished& = TRUE
  3081.                 Else
  3082.                     Print "Number out of range."
  3083.                     Print
  3084.                 End If
  3085.             Else
  3086.                 Print "Not a valid number."
  3087.                 Print
  3088.             End If
  3089.         Else
  3090.             iValue& = iDefault&
  3091.             bFinished& = TRUE
  3092.         End If
  3093.     Loop Until bFinished&
  3094.    
  3095.     PromptForLongInRange& = iValue&
  3096. End Function ' PromptForLongInRange&
  3097.  
  3098. ' /////////////////////////////////////////////////////////////////////////////
  3099. ' Returns blank if successful else returns error message.
  3100.  
  3101. Function PrintFile$ (sFileName As String, sText As String, bAppend As Integer)
  3102.     'x = 1: y = 2: z$ = "Three"
  3103.  
  3104.     Dim sError As String: sError = ""
  3105.  
  3106.     If Len(sError) = 0 Then
  3107.         If (bAppend = TRUE) Then
  3108.             If _FileExists(sFileName) Then
  3109.                 Open sFileName For Append As #1 ' opens an existing file for appending
  3110.             Else
  3111.                 sError = "Error in PrintFile$ : File not found. Cannot append."
  3112.             End If
  3113.         Else
  3114.             Open sFileName For Output As #1 ' opens and clears an existing file or creates new empty file
  3115.         End If
  3116.     End If
  3117.     If Len(sError) = 0 Then
  3118.         ' WRITE places text in quotes in the file
  3119.         'WRITE #1, x, y, z$
  3120.         'WRITE #1, sText
  3121.  
  3122.         ' PRINT does not put text inside quotes
  3123.         Print #1, sText
  3124.  
  3125.         Close #1
  3126.  
  3127.         'PRINT "File created with data. Press a key!"
  3128.         'K$ = INPUT$(1) 'press a key
  3129.  
  3130.         'OPEN sFileName FOR INPUT AS #2 ' opens a file to read it
  3131.         'INPUT #2, a, b, c$
  3132.         'CLOSE #2
  3133.  
  3134.         'PRINT a, b, c$
  3135.         'WRITE a, b, c$
  3136.     End If
  3137.  
  3138.     PrintFile$ = sError
  3139. End Function ' PrintFile$
  3140.  
  3141. ' /////////////////////////////////////////////////////////////////////////////
  3142. ' Generate random value between Min and Max.
  3143. Function RandomNumber% (Min%, Max%)
  3144.     Dim NumSpread%
  3145.  
  3146.     ' SET RANDOM SEED
  3147.     'Randomize ' Initialize random-number generator.
  3148.  
  3149.     ' GET RANDOM # Min%-Max%
  3150.     'RandomNumber = Int((Max * Rnd) + Min) ' generate number
  3151.  
  3152.     NumSpread% = (Max% - Min%) + 1
  3153.  
  3154.     RandomNumber% = Int(Rnd * NumSpread%) + Min% ' GET RANDOM # BETWEEN Max% AND Min%
  3155.  
  3156. End Function ' RandomNumber%
  3157.  
  3158. ' /////////////////////////////////////////////////////////////////////////////
  3159.  
  3160. Sub RandomNumberTest
  3161.     Dim iCols As Integer: iCols = 10
  3162.     Dim iRows As Integer: iRows = 20
  3163.     Dim iLoop As Integer
  3164.     Dim iX As Integer
  3165.     Dim iY As Integer
  3166.     Dim sError As String
  3167.     Dim sFileName As String
  3168.     Dim sText As String
  3169.     Dim bAppend As Integer
  3170.     Dim iMin As Integer
  3171.     Dim iMax As Integer
  3172.     Dim iNum As Integer
  3173.     Dim iErrorCount As Integer
  3174.     Dim sInput$
  3175.  
  3176.     sFileName = "c:\temp\maze_test_1.txt"
  3177.     sText = "Count" + Chr$(9) + "Min" + Chr$(9) + "Max" + Chr$(9) + "Random"
  3178.     bAppend = FALSE
  3179.     sError = PrintFile$(sFileName, sText, bAppend)
  3180.     If Len(sError) = 0 Then
  3181.         bAppend = TRUE
  3182.         iErrorCount = 0
  3183.  
  3184.         iMin = 0
  3185.         iMax = iCols - 1
  3186.         For iLoop = 1 To 100
  3187.             iNum = RandomNumber%(iMin, iMax)
  3188.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  3189.             sError = PrintFile$(sFileName, sText, bAppend)
  3190.             If Len(sError) > 0 Then
  3191.                 iErrorCount = iErrorCount + 1
  3192.                 Print Str$(iLoop) + ". ERROR"
  3193.                 Print "    " + "iMin=" + Str$(iMin)
  3194.                 Print "    " + "iMax=" + Str$(iMax)
  3195.                 Print "    " + "iNum=" + Str$(iNum)
  3196.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  3197.                 Print "    " + sError
  3198.             End If
  3199.         Next iLoop
  3200.  
  3201.         iMin = 0
  3202.         iMax = iRows - 1
  3203.         For iLoop = 1 To 100
  3204.             iNum = RandomNumber%(iMin, iMax)
  3205.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  3206.             sError = PrintFile$(sFileName, sText, bAppend)
  3207.             If Len(sError) > 0 Then
  3208.                 iErrorCount = iErrorCount + 1
  3209.                 Print Str$(iLoop) + ". ERROR"
  3210.                 Print "    " + "iMin=" + Str$(iMin)
  3211.                 Print "    " + "iMax=" + Str$(iMax)
  3212.                 Print "    " + "iNum=" + Str$(iNum)
  3213.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  3214.                 Print "    " + sError
  3215.             End If
  3216.         Next iLoop
  3217.  
  3218.         Print "Finished generating numbers. Errors: " + Str$(iErrorCount)
  3219.     Else
  3220.         Print "Error creating file " + Chr$(34) + sFileName + Chr$(34) + "."
  3221.         Print sError
  3222.     End If
  3223.  
  3224.     Input "Press <ENTER> to continue", sInput$
  3225. End Sub ' RandomNumberTest
  3226.  
  3227. ' /////////////////////////////////////////////////////////////////////////////
  3228. ' FROM: String Manipulation
  3229. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index_topic_5964-0/
  3230. '
  3231. 'SUMMARY:
  3232. '   Purpose:  A library of custom functions that transform strings.
  3233. '   Author:   Dustinian Camburides (dustinian@gmail.com)
  3234. '   Platform: QB64 (www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there])
  3235. '   Revision: 1.6
  3236. '   Updated:  5/28/2012
  3237.  
  3238. 'SUMMARY:
  3239. '[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
  3240. 'INPUT:
  3241. 'Text: The input string; the text that's being manipulated.
  3242. 'Find: The specified sub-string; the string sought within the [Text] string.
  3243. 'Add: The sub-string that's being added to the [Text] string.
  3244.  
  3245. Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
  3246.     ' VARIABLES:
  3247.     Dim Text2 As String
  3248.     Dim Find2 As String
  3249.     Dim Add2 As String
  3250.     Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
  3251.     Dim strBefore As String ' The characters before the string to be replaced.
  3252.     Dim strAfter As String ' The characters after the string to be replaced.
  3253.  
  3254.     ' INITIALIZE:
  3255.     ' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
  3256.     Text2 = Text1
  3257.     Find2 = Find1
  3258.     Add2 = Add1
  3259.  
  3260.     lngLocation = InStr(1, Text2, Find2)
  3261.  
  3262.     ' PROCESSING:
  3263.     ' While [Find2] appears in [Text2]...
  3264.     While lngLocation
  3265.         ' Extract all Text2 before the [Find2] substring:
  3266.         strBefore = Left$(Text2, lngLocation - 1)
  3267.  
  3268.         ' Extract all text after the [Find2] substring:
  3269.         strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
  3270.  
  3271.         ' Return the substring:
  3272.         Text2 = strBefore + Add2 + strAfter
  3273.  
  3274.         ' Locate the next instance of [Find2]:
  3275.         lngLocation = InStr(1, Text2, Find2)
  3276.  
  3277.         ' Next instance of [Find2]...
  3278.     Wend
  3279.  
  3280.     ' OUTPUT:
  3281.     Replace$ = Text2
  3282. End Function ' Replace$
  3283.  
  3284. ' /////////////////////////////////////////////////////////////////////////////
  3285. ' fantastically inefficient way to set a bit
  3286.  
  3287. ' example use: arrMaze(iX, iY) = SetBit256%(arrMaze(iX, iY), cS, FALSE)
  3288.  
  3289. ' See also: GetBit256%, SetBit256%
  3290.  
  3291. ' newint=SetBit256%(oldint, int containing the bits we want to set, value to set them to)
  3292. Function SetBit256% (iNum1 As Integer, iBit1 As Integer, bVal1 As Integer)
  3293.     Dim sNum As String
  3294.     Dim sBit As String
  3295.     Dim sVal As String
  3296.     Dim iLoop As Integer
  3297.     Dim strResult As String
  3298.     Dim iResult As Integer
  3299.     Dim iNum As Integer: iNum = iNum1
  3300.     Dim iBit As Integer: iBit = iBit1
  3301.     Dim bVal As Integer: bVal = bVal1
  3302.  
  3303.     If iNum < 256 And iBit <= 128 Then
  3304.         sNum = GetBinary$(iNum)
  3305.         sBit = GetBinary$(iBit)
  3306.         If bVal = TRUE Then
  3307.             sVal = "1"
  3308.         Else
  3309.             sVal = "0"
  3310.         End If
  3311.         strResult = ""
  3312.         For iLoop = 1 To 8
  3313.             If Mid$(sBit, iLoop, 1) = "1" Then
  3314.                 strResult = strResult + sVal
  3315.             Else
  3316.                 strResult = strResult + Mid$(sNum, iLoop, 1)
  3317.             End If
  3318.         Next iLoop
  3319.         iResult = GetIntegerFromBinary%(strResult)
  3320.     Else
  3321.         iResult = iNum
  3322.     End If
  3323.  
  3324.     SetBit256% = iResult
  3325. End Function ' SetBit256%
  3326.  
  3327. ' /////////////////////////////////////////////////////////////////////////////
  3328. ' Split and join strings
  3329. ' https://www.qb64.org/forum/index.php?topic=1073.0
  3330. '
  3331. ' FROM luke, QB64 Developer
  3332. ' Date: February 15, 2019, 04:11:07 AM »
  3333. '
  3334. ' Given a string of words separated by spaces (or any other character),
  3335. ' splits it into an array of the words. I've no doubt many people have
  3336. ' written a version of this over the years and no doubt there's a million
  3337. ' ways to do it, but I thought I'd put mine here so we have at least one
  3338. ' version. There's also a join function that does the opposite
  3339. ' array -> single string.
  3340. '
  3341. ' Code is hopefully reasonably self explanatory with comments and a little demo.
  3342. ' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
  3343.  
  3344. 'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
  3345. 'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
  3346. '
  3347. 'delimiter$ must be one character long.
  3348. 'result$() must have been REDIMmed previously.
  3349.  
  3350. Sub split (in$, delimiter$, result$())
  3351.     ReDim result$(-1)
  3352.     start = 1
  3353.     Do
  3354.         While Mid$(in$, start, 1) = delimiter$
  3355.             start = start + 1
  3356.             If start > Len(in$) Then Exit Sub
  3357.         Wend
  3358.         finish = InStr(start, in$, delimiter$)
  3359.         If finish = 0 Then finish = Len(in$) + 1
  3360.         ReDim _Preserve result$(0 To UBound(result$) + 1)
  3361.         result$(UBound(result$)) = Mid$(in$, start, finish - start)
  3362.         start = finish + 1
  3363.     Loop While start <= Len(in$)
  3364. End Sub ' split
  3365.  
  3366. ' /////////////////////////////////////////////////////////////////////////////
  3367.  
  3368. Sub SplitTest
  3369.  
  3370.     Dim in$
  3371.     Dim delim$
  3372.     ReDim arrTest$(0)
  3373.     Dim iLoop%
  3374.  
  3375.     delim$ = Chr$(10)
  3376.     in$ = "this" + delim$ + "is" + delim$ + "a" + delim$ + "test"
  3377.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  3378.     Print "delim$ = " + Chr$(34) + delimeter$ + Chr$(34)
  3379.     split in$, delim$, arrTest$()
  3380.  
  3381.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  3382.         Print "arrTest$(" + LTrim$(RTrim$(Str$(iLoop%))) + ") = " + Chr$(34) + arrTest$(iLoop%) + Chr$(34)
  3383.     Next iLoop%
  3384.     Print
  3385.     Print "Split test finished."
  3386. End Sub ' SplitTest
  3387.  
  3388. ' /////////////////////////////////////////////////////////////////////////////
  3389.  
  3390. Sub WaitForEnter
  3391.     Dim in$
  3392.     Input "Press <ENTER> to continue", in$
  3393. End Sub ' WaitForEnter
  3394.  
  3395. ' /////////////////////////////////////////////////////////////////////////////
  3396. ' WaitForKey "Press <ESC> to continue", 27, 0
  3397. ' WaitForKey "Press <ENTER> to begin;", 13, 0
  3398. ' waitforkey "", 65, 5
  3399.  
  3400. Sub WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  3401.     ' SHOW PROMPT (IF SPECIFIED)
  3402.     If Len(prompt$) > 0 Then
  3403.         If Right$(prompt$, 1) <> ";" Then
  3404.             Print prompt$
  3405.         Else
  3406.             Print Right$(prompt$, Len(prompt$) - 1);
  3407.         End If
  3408.     End If
  3409.  
  3410.     ' WAIT FOR KEY
  3411.     Do: Loop Until _KeyDown(KeyCode&) ' leave loop when specified key pressed
  3412.  
  3413.     ' PAUSE AFTER (IF SPECIFIED)
  3414.     If DelaySeconds% < 1 Then
  3415.         _KeyClear: '_DELAY 1
  3416.     Else
  3417.         _KeyClear: _Delay DelaySeconds%
  3418.     End If
  3419. End Sub ' WaitForKey
  3420.  
  3421. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3422. ' END GENERAL PURPOSE FUNCTIONS
  3423. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3424.  
  3425. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3426. ' BEGIN COLOR ROUTINES
  3427. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3428.  
  3429. ' /////////////////////////////////////////////////////////////////////////////
  3430. ' Receives:
  3431. ' cycleColor = determines how foreColor, backColor are modified
  3432. ' foreColor  = the foreground color
  3433. ' backColor  = the background color (if needed)
  3434.  
  3435. ' /////////////////////////////////////////////////////////////////////////////
  3436. ' DoCycleColor colorScheme%, myColor&
  3437.  
  3438. ' colorScheme = color scheme (value is alternated on subsequent calls)
  3439. ' myColor     = the current color (value is incremented/decremented on subsequent calls)
  3440.  
  3441. ' colorScheme values:
  3442. '  1 Rainbow6 #1
  3443. '  9 Rainbow6 #2
  3444. '  2 Rainbow18 #1
  3445. ' 10 Rainbow18 #2
  3446. '  3 Grayscale #1
  3447. ' 11 Grayscale #2
  3448. '  4 Grayscale #1
  3449. ' 12 Grayscale #2
  3450.  
  3451. Sub DoCycleColor (colorScheme As Integer, myColor As Long)
  3452.     ' ----------------------------------------------------------------------------------------------------------------------------------------------------------------
  3453.     ' CYCLE FORE COLOR
  3454.  
  3455.     ' 1, 9 = simple rainbow
  3456.     If colorScheme = 1 Or colorScheme = 9 Then
  3457.         Select Case myColor
  3458.             Case cRed&:
  3459.                 myColor = cOrange&
  3460.             Case cOrange&:
  3461.                 myColor = cYellow&
  3462.             Case cYellow&:
  3463.                 myColor = cGreen&
  3464.             Case cGreen&:
  3465.                 myColor = cBlue&
  3466.             Case cBlue&:
  3467.                 myColor = cPurple&
  3468.             Case Else:
  3469.                 myColor = cRed&
  3470.         End Select
  3471.  
  3472.     ' 2, 10 = complex rainbow
  3473.     ElseIf colorScheme = 2 Or colorScheme = 10 Then
  3474.         Select Case myColor
  3475.             Case cRed&:
  3476.                 myColor = cOrangeRed&
  3477.             Case cOrangeRed&:
  3478.                 myColor = cDarkOrange&
  3479.             Case cDarkOrange&:
  3480.                 myColor = cOrange&
  3481.             Case cOrange&:
  3482.                 myColor = cGold&
  3483.             Case cGold&:
  3484.                 myColor = cYellow&
  3485.             Case cYellow&:
  3486.                 myColor = cOliveDrab1&
  3487.             Case cOliveDrab1&:
  3488.                 myColor = cLime&
  3489.             Case cLime&:
  3490.                 myColor = cMediumSpringGreen&
  3491.             Case cMediumSpringGreen&:
  3492.                 myColor = cCyan&
  3493.             Case cCyan&:
  3494.                 myColor = cDeepSkyBlue&
  3495.             Case cDeepSkyBlue&:
  3496.                 myColor = cDodgerBlue&
  3497.             Case cDodgerBlue&:
  3498.                 myColor = cSeaBlue&
  3499.             Case cSeaBlue&:
  3500.                 myColor = cBlue&
  3501.             Case cBlue&:
  3502.                 myColor = cBluePurple&
  3503.             Case cBluePurple&:
  3504.                 myColor = cDeepPurple&
  3505.             Case cDeepPurple&:
  3506.                 myColor = cPurple&
  3507.             Case cPurple&:
  3508.                 myColor = cPurpleRed&
  3509.             Case Else:
  3510.                 myColor = cRed&
  3511.         End Select
  3512.  
  3513.     ' 3, 11 = grayscale, ascending
  3514.     ElseIf colorScheme = 3 Or colorScheme = 11 Then
  3515.         Select Case myColor
  3516.             Case cBlack&:
  3517.                 myColor = cDarkGray&
  3518.             Case cDarkGray&:
  3519.                 myColor = cDimGray&
  3520.             Case cDimGray&:
  3521.                 myColor = cGray&
  3522.             Case cGray&:
  3523.                 myColor = cLightGray&
  3524.             Case cLightGray&:
  3525.                 myColor = cSilver&
  3526.             Case cSilver&:
  3527.                 myColor = cWhite&
  3528.             Case Else:
  3529.                 'myColor = cBlack&
  3530.                 myColor = cSilver&
  3531.  
  3532.                 ' go in the other direction!
  3533.                 If colorScheme = 3 Then
  3534.                     colorScheme = 4
  3535.                 Else
  3536.                     colorScheme = 12
  3537.                 End If
  3538.  
  3539.         End Select
  3540.  
  3541.     ' 4, 8, 12 = grayscale, descending
  3542.     ElseIf colorScheme = 4 Or colorScheme = 12 Then
  3543.         Select Case myColor
  3544.             Case cWhite&:
  3545.                 myColor = cSilver&
  3546.             Case cSilver&:
  3547.                 myColor = cLightGray&
  3548.             Case cLightGray&:
  3549.                 myColor = cGray&
  3550.             Case cGray&:
  3551.                 myColor = cDimGray&
  3552.             Case cDimGray&:
  3553.                 myColor = cDarkGray&
  3554.             Case cDarkGray&:
  3555.                 myColor = cBlack&
  3556.             Case Else:
  3557.                 myColor = cDarkGray&
  3558.  
  3559.                 ' go in the other direction!
  3560.                 If colorScheme = 4 Then
  3561.                     colorScheme = 3
  3562.                 Else
  3563.                     colorScheme = 11
  3564.                 End If
  3565.         End Select
  3566.  
  3567.     End If
  3568.    
  3569. End Sub ' DoCycleColor
  3570.  
  3571. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3572. ' END COLOR ROUTINES
  3573. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3574.  
  3575. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3576. ' BEGIN COLOR FUNCTIONS
  3577. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3578.  
  3579. ' NOTE: these are mostly negative numbers
  3580. '       and have to be forced to positive
  3581. '       when stored in the dictionary
  3582. '       (only cEmpty& should be negative)
  3583.  
  3584. Function cRed& ()
  3585.     cRed& = _RGB32(255, 0, 0)
  3586.  
  3587. Function cOrangeRed& ()
  3588.     cOrangeRed& = _RGB32(255, 69, 0)
  3589. End Function ' cOrangeRed&
  3590.  
  3591. Function cDarkOrange& ()
  3592.     cDarkOrange& = _RGB32(255, 140, 0)
  3593. End Function ' cDarkOrange&
  3594.  
  3595. Function cOrange& ()
  3596.     cOrange& = _RGB32(255, 165, 0)
  3597. End Function ' cOrange&
  3598.  
  3599. Function cGold& ()
  3600.     cGold& = _RGB32(255, 215, 0)
  3601. End Function ' cGold&
  3602.  
  3603. Function cYellow& ()
  3604.     cYellow& = _RGB32(255, 255, 0)
  3605. End Function ' cYellow&
  3606.  
  3607. ' LONG-HAIRED FRIENDS OF JESUS OR NOT,
  3608. ' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
  3609. ' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
  3610. Function cChartreuse& ()
  3611.     cChartreuse& = _RGB32(127, 255, 0)
  3612. End Function ' cChartreuse&
  3613.  
  3614. ' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
  3615. Function cOliveDrab1& ()
  3616.     cOliveDrab1& = _RGB32(192, 255, 62)
  3617. End Function ' cOliveDrab1&
  3618.  
  3619. Function cLime& ()
  3620.     cLime& = _RGB32(0, 255, 0)
  3621. End Function ' cLime&
  3622.  
  3623. Function cMediumSpringGreen& ()
  3624.     cMediumSpringGreen& = _RGB32(0, 250, 154)
  3625. End Function ' cMediumSpringGreen&
  3626.  
  3627. Function cCyan& ()
  3628.     cCyan& = _RGB32(0, 255, 255)
  3629. End Function ' cCyan&
  3630.  
  3631. Function cDeepSkyBlue& ()
  3632.     cDeepSkyBlue& = _RGB32(0, 191, 255)
  3633. End Function ' cDeepSkyBlue&
  3634.  
  3635. Function cDodgerBlue& ()
  3636.     cDodgerBlue& = _RGB32(30, 144, 255)
  3637. End Function ' cDodgerBlue&
  3638.  
  3639. Function cSeaBlue& ()
  3640.     cSeaBlue& = _RGB32(0, 64, 255)
  3641. End Function ' cSeaBlue&
  3642.  
  3643. Function cBlue& ()
  3644.     cBlue& = _RGB32(0, 0, 255)
  3645. End Function ' cBlue&
  3646.  
  3647. Function cBluePurple& ()
  3648.     cBluePurple& = _RGB32(64, 0, 255)
  3649. End Function ' cBluePurple&
  3650.  
  3651. Function cDeepPurple& ()
  3652.     cDeepPurple& = _RGB32(96, 0, 255)
  3653. End Function ' cDeepPurple&
  3654.  
  3655. Function cPurple& ()
  3656.     cPurple& = _RGB32(128, 0, 255)
  3657. End Function ' cPurple&
  3658.  
  3659. Function cPurpleRed& ()
  3660.     cPurpleRed& = _RGB32(128, 0, 192)
  3661. End Function ' cPurpleRed&
  3662.  
  3663. Function cDarkRed& ()
  3664.     cDarkRed& = _RGB32(160, 0, 64)
  3665. End Function ' cDarkRed&
  3666.  
  3667. Function cBrickRed& ()
  3668.     cBrickRed& = _RGB32(192, 0, 32)
  3669. End Function ' cBrickRed&
  3670.  
  3671. Function cDarkGreen& ()
  3672.     cDarkGreen& = _RGB32(0, 100, 0)
  3673. End Function ' cDarkGreen&
  3674.  
  3675. Function cGreen& ()
  3676.     cGreen& = _RGB32(0, 128, 0)
  3677. End Function ' cGreen&
  3678.  
  3679. Function cOliveDrab& ()
  3680.     cOliveDrab& = _RGB32(107, 142, 35)
  3681. End Function ' cOliveDrab&
  3682.  
  3683. Function cLightPink& ()
  3684.     cLightPink& = _RGB32(255, 182, 193)
  3685. End Function ' cLightPink&
  3686.  
  3687. Function cHotPink& ()
  3688.     cHotPink& = _RGB32(255, 105, 180)
  3689. End Function ' cHotPink&
  3690.  
  3691. Function cDeepPink& ()
  3692.     cDeepPink& = _RGB32(255, 20, 147)
  3693. End Function ' cDeepPink&
  3694.  
  3695. Function cMagenta& ()
  3696.     cMagenta& = _RGB32(255, 0, 255)
  3697. End Function ' cMagenta&
  3698.  
  3699. Function cBlack& ()
  3700.     cBlack& = _RGB32(0, 0, 0)
  3701. End Function ' cBlack&
  3702.  
  3703. Function cDimGray& ()
  3704.     cDimGray& = _RGB32(105, 105, 105)
  3705. End Function ' cDimGray&
  3706.  
  3707. Function cGray& ()
  3708.     cGray& = _RGB32(128, 128, 128)
  3709. End Function ' cGray&
  3710.  
  3711. Function cDarkGray& ()
  3712.     cDarkGray& = _RGB32(169, 169, 169)
  3713. End Function ' cDarkGray&
  3714.  
  3715. Function cSilver& ()
  3716.     cSilver& = _RGB32(192, 192, 192)
  3717. End Function ' cSilver&
  3718.  
  3719. Function cLightGray& ()
  3720.     cLightGray& = _RGB32(211, 211, 211)
  3721. End Function ' cLightGray&
  3722.  
  3723. Function cGainsboro& ()
  3724.     cGainsboro& = _RGB32(220, 220, 220)
  3725. End Function ' cGainsboro&
  3726.  
  3727. Function cWhiteSmoke& ()
  3728.     cWhiteSmoke& = _RGB32(245, 245, 245)
  3729. End Function ' cWhiteSmoke&
  3730.  
  3731. Function cWhite& ()
  3732.     cWhite& = _RGB32(255, 255, 255)
  3733. End Function ' cWhite&
  3734.  
  3735. Function cDarkBrown& ()
  3736.     cDarkBrown& = _RGB32(128, 64, 0)
  3737. End Function ' cDarkBrown&
  3738.  
  3739. Function cLightBrown& ()
  3740.     cLightBrown& = _RGB32(196, 96, 0)
  3741. End Function ' cLightBrown&
  3742.  
  3743. Function cKhaki& ()
  3744.     cKhaki& = _RGB32(240, 230, 140)
  3745. End Function ' cKhaki&
  3746.  
  3747. Function cEmpty& ()
  3748.     cEmpty& = -1
  3749. End Function ' cEmpty&
  3750.  
  3751. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3752. ' END COLOR FUNCTIONS
  3753. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3754.  
  3755. ' #END
  3756. ' ################################################################################################################################################################
  3757.  

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: any idea why the color white is not visible?
« Reply #3 on: December 12, 2021, 04:44:21 pm »
Just to be extra sure, it's safest that all your colors are unsigned long instead of regular long. But if that doesn't work, just sit tight: someone'll jump in and answer this. (The code has several names in it, so maybe those people.)
You're not done when it works, you're done when it's right.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #4 on: December 12, 2021, 05:00:15 pm »
Just to be extra sure, it's safest that all your colors are unsigned long instead of regular long. But if that doesn't work, just sit tight: someone'll jump in and answer this. (The code has several names in it, so maybe those people.)

I did find some places where I had declared the colors as Long, and changed it to _Unsigned Long, but the white is still missing.

To be clear, when you do
Code: QB64: [Select]
  1. Dim myColor&
is that a Long or _Unsigned Long?
If it is not unsigned, is there a prefix to use instead of "&"?

For now, your "off-white" suggestion is a good workaround, I'm using rgb(254,254,254) for white.

Thanks again...

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: any idea why the color white is not visible?
« Reply #5 on: December 12, 2021, 05:07:52 pm »
Yes _RGB32 colors have to be UNSIGNED LONGS (~& There is a reason there is a WIKI to look these things up)

when calling functions you do NOT need the prefix except when declaring:

FUNCTION WHITE~&
WHITE = _RGB32(254)
END FUNCTION

and using grey scale colors you only need 1 value not 3

as for why 255 white is not showing up, with that code there is probably little chance of finding a reason easily.
Granted after becoming radioactive I only have a half-life!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #6 on: December 12, 2021, 06:46:24 pm »
Yes _RGB32 colors have to be UNSIGNED LONGS (~& There is a reason there is a WIKI to look these things up)

when calling functions you do NOT need the prefix except when declaring:

FUNCTION WHITE~&
WHITE = _RGB32(254)
END FUNCTION

and using grey scale colors you only need 1 value not 3

as for why 255 white is not showing up, with that code there is probably little chance of finding a reason easily.

Thanks for all the info!

Marked as best answer by madscijr on December 12, 2021, 05:14:25 pm

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: any idea why the color white is not visible?
« Reply #7 on: December 12, 2021, 06:59:20 pm »
Is there any place in your code where you're using a -1 as a check to not draw something?  _RGB32(255, 255, 255) returns a hex value of FFFFFFFF.

FFFFFFFF can represent two very different values.  As an UNSIGNED LONG, it represents 4,294,967,295.  As a SIGNED LONG, it represents -1.

Since QB64 allows for overflow, those two values are sometimes equivalent.  Try a simple COLOR -1 sometime and you'll see it's the exact same thing as COLOR _RGB(255, 255, 255).

If -1 is an error check, or a "do not draw" check, it'd explain why _RGB(254, 255, 255) draws while _RGB(255, 255, 255) doesn't.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #8 on: December 12, 2021, 08:34:15 pm »
Is there any place in your code where you're using a -1 as a check to not draw something?  _RGB32(255, 255, 255) returns a hex value of FFFFFFFF.

FFFFFFFF can represent two very different values.  As an UNSIGNED LONG, it represents 4,294,967,295.  As a SIGNED LONG, it represents -1.

Since QB64 allows for overflow, those two values are sometimes equivalent.  Try a simple COLOR -1 sometime and you'll see it's the exact same thing as COLOR _RGB(255, 255, 255).

If -1 is an error check, or a "do not draw" check, it'd explain why _RGB(254, 255, 255) draws while _RGB(255, 255, 255) doesn't.

I very well might have been checking for -1. I'm going to double check all my variable declarations, and make sure nothing is declared as a signed long, that can inadvertently filter out the true color value for white.

Thanks!!

UPDATE: looking through my code, there are tons of color variables that are declared as signed long. I updated them to unsigned long, but still white is not displaying. I suspect there are still more color variables or parameters hiding in there that are signed Long, so will just have to go through everything with a fine tooth comb as time allows.

Thanks again!
« Last Edit: December 12, 2021, 10:42:47 pm by madscijr »

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: any idea why the color white is not visible?
« Reply #9 on: December 12, 2021, 10:04:18 pm »
Hi @madscijr.  Your code looks very well made.  I hope to try it out tomorrow.

I'm not in a position to run QB64 code tonight, but looking through your code, it looks like your're calling the &cWhite function, which calls the _RGB32 function, before setting the screen up (Screen _NewImage(1280, 1024, 32)).  If I remember right, _RGB32 calls won't work without setting the screen up first.  Could that be what is causing white to fail?

- Dav

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #10 on: December 12, 2021, 10:08:13 pm »
Hi @madscijr.  Your code looks very well made.  I hope to try it out tomorrow.

I'm not in a position to run QB64 code tonight, but looking through your code, it looks like your're calling the &cWhite function, which calls the _RGB32 function, before setting the screen up (Screen _NewImage(1280, 1024, 32)).  If I remember right, _RGB32 calls won't work without setting the screen up first.  Could that be what is causing white to fail?

- Dav

Interesting - I'll give it a look and try moving the Screen command before any _RGB32 calls. Thank You!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #11 on: December 12, 2021, 10:10:49 pm »
Is there any place in your code where you're using a -1 as a check to not draw something?  _RGB32(255, 255, 255) returns a hex value of FFFFFFFF.

FFFFFFFF can represent two very different values.  As an UNSIGNED LONG, it represents 4,294,967,295.  As a SIGNED LONG, it represents -1.

Since QB64 allows for overflow, those two values are sometimes equivalent.  Try a simple COLOR -1 sometime and you'll see it's the exact same thing as COLOR _RGB(255, 255, 255).

If -1 is an error check, or a "do not draw" check, it'd explain why _RGB(254, 255, 255) draws while _RGB(255, 255, 255) doesn't.

I think you may be onto something... I wrote these color routines before realizing the values were Unsigned Long, and indeed, the value -1 is used as a check not to draw something (function cEmpty).
I ran a simple test, and sure enough, the value for cEmpty and cWhite is the same.

I changed the value of cEmpty to _RGB32(0, 0, 0, 0) and white is now displaying.

Case closed. Thank You!


Test code:
Code: QB64: [Select]
  1. Dim in$
  2. Print "cEmpty=" + cstrul$(cEmpty)
  3. Print "cWhite=" + cstrul$(cWhite)
  4. Input "PRESS <ENTER> TO CONTINUE"; in$
  5.  
  6. Function cEmpty~& ()
  7.     cEmpty~& = -1
  8. End Function ' cEmpty~&
  9.  
  10. Function cWhite~& ()
  11.     cWhite = _RGB32(255, 255, 255)
  12.     'cWhite = _RGB32(254, 254, 254)
  13. End Function ' cWhite~&
  14.  
  15. Function cstrul$ (myValue As _Unsigned Long)
  16.     cstrul$ = _Trim$(Str$(myValue))
  17. End Function ' cstrul$
  18.  
« Last Edit: December 12, 2021, 10:44:08 pm by madscijr »

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: any idea why the color white is not visible?
« Reply #12 on: December 13, 2021, 03:59:47 am »
Good it's fixed, and no cats have to be dipped in paint.
It works better if you plug it in.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #13 on: December 13, 2021, 07:14:35 am »
Good it's fixed, and no cats have to be dipped in paint.

LoL, is that what happens when we leave bugs in our code?

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: any idea why the color white is not visible?
« Reply #14 on: December 19, 2021, 10:22:53 pm »
For anyone looking for more info on this subject, see Steve's post:

https://www.qb64.org/forum/index.php?topic=4480.0