Author Topic: game input mapping system v2.0 for gamepad+keyboard (upto 8 players)(WIP)  (Read 2638 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
This version adds a simple GUI to the mapping screen.

Supports upto 8 controllers with up/down/left/right + 4 buttons each, and whether each of those is auto-repeating or not.

Tested with Windows, not sure about Mac or Linux.

Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' #TOP
  3.  
  4. ' Basic Input Mapper, Barebones Octo edition.
  5. ' Version 2.00 by madscijr
  6.  
  7. ' CHANGE LOG:
  8. ' Date         Who                What
  9. ' 12/16/2020   madscijr           detect keys 0.70
  10. ' 02/17/2021   madscijr           basic game controller test
  11. ' 01/08/2022   madscijr           input mapping v1.0
  12. '                                 keyboard + game controllers
  13. '                                 text menu driven (no GUI)
  14. ' 01/21/2022   madscijr           input mapping v2.0 with simple GUI
  15.  
  16. ' DESCRIPTION:
  17. ' A way to map input controls (gamepad + keyboard)
  18. ' load/save mapping to a file, and read the input,
  19. ' that you can use in your own games.
  20.  
  21. ' ################################################################################################################################################################
  22. ' BASIC SETTINGS
  23.  
  24. DefLng A-Z
  25.  
  26. ' ################################################################################################################################################################
  27. ' #CONSTANTS = GLOBAL CONSTANTS
  28.  
  29. ' boolean constants:
  30. Const FALSE = 0
  31. Const TRUE = Not FALSE
  32.  
  33. ' BEGIN GAME CONTROLLER MAPPING CONSTANTS
  34. Const cInputNone = 0
  35. Const cInputKey = 1
  36. Const cInputButton = 2
  37. Const cInputAxis = 3
  38.  
  39. Const cMaxButtons = 12
  40. Const cMaxAxis = 8
  41. Const cMaxControllers = 8
  42. Const cMaxPlayers = 8
  43.  
  44. ' Use as index for array of ControlInputType
  45. Const cInputUp = 1
  46. Const cInputDown = 2
  47. Const cInputLeft = 3
  48. Const cInputRight = 4
  49. Const cInputButton1 = 5
  50. Const cInputButton2 = 6
  51. Const cInputButton3 = 7
  52. Const cInputButton4 = 8
  53.  
  54. Const c_iKeyDown_F10 = 17408
  55. Const c_iKeyHit_AltLeft = -30764
  56. Const c_iKeyHit_AltRight = -30765
  57. ' END GAME CONTROLLER MAPPING CONSTANTS
  58.  
  59. ' BEGIN TEXT GUI CONSTANTS
  60. Const cTextGuiSection = 1
  61. Const cTextGuiButton = 2
  62. Const cTextGuiUnknown = 0
  63.  
  64. Const cJustifyLeft = 1
  65. Const cJustifyRight = 2
  66. Const cJustifyCenter = 3
  67. Const cJustifyNone = 4
  68. Const cJustifyUnknown = 0
  69.  
  70. ' END TEXT GUI CONSTANTS
  71. ' ################################################################################################################################################################
  72. ' #UDT #TYPES = USER DEFINED TYPES
  73.  
  74. ' UDT TO HOLD THE INFO FOR A PLAYER
  75. Type PlayerType
  76.     x As Integer ' player x position
  77.     y As Integer ' player y position
  78.     c As Integer ' character to display on screen
  79.     xOld As Integer
  80.     yOld As Integer
  81.  
  82.     ' control buffer
  83.     moveX As Integer
  84.     moveY As Integer
  85.  
  86.     moveUp As Integer
  87.     moveDown As Integer
  88.     moveLeft As Integer
  89.     moveRight As Integer
  90.     button1 As Integer
  91.     button2 As Integer
  92.     button3 As Integer
  93.     button4 As Integer
  94.  
  95.     ' control previous move
  96.     'lastMoveX As Integer
  97.     'lastMoveY As Integer
  98.     lastMoveUp As Integer
  99.     lastMoveDown As Integer
  100.     lastMoveLeft As Integer
  101.     lastMoveRight As Integer
  102.     lastButton1 As Integer
  103.     lastButton2 As Integer
  104.     lastButton3 As Integer
  105.     lastButton4 As Integer
  106.  
  107.     'repeat As Integer
  108. End Type ' PlayerType
  109.  
  110. ' UDT TO HOLD THE INFO FOR A GAME CONTROLLER
  111. Type ControllerType
  112.     buttonCount As Integer
  113.     axisCount As Integer
  114. End Type ' ControllerType
  115.  
  116. ' UDT TO HOLD THE INFO FOR A GAME CONTROLLER
  117. Type ControlInputType
  118.     device As Integer
  119.     typ As Integer ' cInputKey, cInputButton, cInputAxis
  120.     code As Integer
  121.     value As Integer
  122.     repeat As Integer
  123. End Type ' ControlInputType
  124.  
  125. ' UDT TO HOLD COLOR CODE INFO
  126. Type ColorType
  127.     name As String
  128.     value As _Unsigned Long
  129. End Type ' ColorType
  130.  
  131. ' UDT TO HOLD TEXT GUI
  132. Type ScreenAreaType
  133.     name As String
  134.     typ As Integer ' cTextGuiSection, cTextGuiButton
  135.     item As String
  136.     player As Integer
  137.     x1 As Integer
  138.     y1 As Integer
  139.     x2 As Integer
  140.     y2 As Integer
  141.     'index as integer
  142. End Type ' ScreenAreaType
  143.  
  144. ' DEFINES CLICKABLE BUTTON BOUNDARIES
  145. Type TextButtonType
  146.     item As String
  147.     typ As Integer ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  148.     x1 As Integer
  149.     y1 As Integer
  150.     x2 As Integer
  151.     y2 As Integer
  152.     'index as integer
  153. End Type ' TextButtonType
  154.  
  155. ' DEFINES TEXT LABELS
  156. Type TextLabelType
  157.     item As String ' "Section", "Up", "Down"
  158.     name As String ' "caption", "type", "device", "code", "repeat", "value"
  159.     row As Integer ' row (relative to section y1)
  160.     column As Integer ' column (relative to section x1)
  161.     width As Integer ' needed for cJustifyRight, cJustifyCenter
  162.     justify As Integer ' cJustifyLeft, cJustifyRight, cJustifyCenter, cJustifyUnknown
  163.     caption As String ' holds the label text
  164.     fgcolor As _Unsigned Long
  165.     bgcolor As _Unsigned Long
  166.     'index as integer
  167. End Type ' TextLabelType
  168.  
  169. ' DEFINES TEXT FIELDS
  170. Type TextFieldType
  171.     item As String ' "Section", "Up", "Down"
  172.     name As String ' "caption", "type", "device", "code", "repeat", "value"
  173.     row As Integer ' row (relative to section y1)
  174.     column As Integer ' column (relative to section x1)
  175.     width As Integer ' pad values to this width
  176.     justify As Integer ' cJustifyLeft, cJustifyRight, cJustifyCenter, cJustifyUnknown
  177.     value As String ' holds the formatted value as text
  178.     fgcolor As _Unsigned Long
  179.     bgcolor As _Unsigned Long
  180.     'index as integer
  181. End Type ' TextFieldType
  182.  
  183. ' FOR TEXT SCREEN
  184. Type TextCellType
  185.     value As String
  186.     fgColor As _Unsigned Long
  187.     bgcolor As _Unsigned Long
  188. End Type ' TextCellType
  189.  
  190. ' ################################################################################################################################################################
  191. ' #VARS = GLOBAL VARIABLES
  192.  
  193. ' ENABLE / DISABLE DEBUG CONSOLE
  194. Dim Shared m_bTesting As Integer: m_bTesting = TRUE
  195.  
  196. ' BASIC PROGRAM METADATA
  197. Dim Shared m_ProgramPath$: m_ProgramPath$ = Left$(Command$(0), _InStrRev(Command$(0), "\"))
  198. Dim Shared m_ProgramName$: m_ProgramName$ = Mid$(Command$(0), _InStrRev(Command$(0), "\") + 1)
  199. Dim Shared m_VersionInfo$: m_VersionInfo$ = "2.00"
  200.  
  201. ' GAME CONTROLLER MAPPING
  202. Dim Shared m_ControlMapFileName$: m_ControlMapFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "map.txt"
  203. ReDim Shared m_arrControlMap(1 To 8, 1 To 8) As ControlInputType ' holds control mapping for each player (player #, direction)
  204. ReDim Shared m_arrController(1 To 8) As ControllerType ' holds info for each game controller
  205. ReDim Shared m_arrButtonCode(1 To 99) As Integer ' Long
  206. ReDim Shared m_arrButtonKey(1 To 99) As String
  207. ReDim Shared m_arrButtonKeyDesc(0 To 512) As String
  208. ReDim Shared m_arrButtonKeyShortDesc(0 To 512) As String
  209. Dim Shared m_bInitialized As Integer: m_bInitialized = FALSE
  210. Dim Shared m_bHaveMapping As Integer: m_bHaveMapping = FALSE
  211.  
  212. ' USE TO GLOBALLY ENABLE/DISABLE REPEATING INPUT PER FUNCTION
  213. ' To enable override set m_bRepeatOverride=TRUE,
  214. ' otherwise this can be configured for each individual controller
  215. ' when you map the functions.
  216. Dim Shared m_bRepeatOverride As Integer: m_bRepeatOverride = TRUE
  217. Dim Shared m_bRepeatUp As Integer: m_bRepeatUp = TRUE
  218. Dim Shared m_bRepeatDown As Integer: m_bRepeatDown = TRUE
  219. Dim Shared m_bRepeatLeft As Integer: m_bRepeatLeft = FALSE
  220. Dim Shared m_bRepeatRight As Integer: m_bRepeatRight = FALSE
  221. Dim Shared m_bRepeatButton1 As Integer: m_bRepeatButton1 = TRUE
  222. Dim Shared m_bRepeatButton2 As Integer: m_bRepeatButton2 = TRUE
  223. Dim Shared m_bRepeatButton3 As Integer: m_bRepeatButton3 = FALSE
  224. Dim Shared m_bRepeatButton4 As Integer: m_bRepeatButton4 = FALSE
  225.  
  226. ' VARIABLES FOR GRAPHIC PRINTING ROUTINES
  227. Dim Shared m_NumColumns As Integer: m_NumColumns = 1
  228. Dim Shared m_PrintRow As Integer: m_PrintRow = 0
  229. Dim Shared m_PrintCol As Integer: m_PrintCol = 0
  230. Dim Shared m_StartRow As Integer: m_StartRow = 0
  231. Dim Shared m_EndRow As Integer: m_EndRow = 0
  232. Dim Shared m_StartCol As Integer: m_StartCol = 0
  233. Dim Shared m_EndCol As Integer: m_EndCol = 0
  234.  
  235. ' VARIABLES FOR TEXT GUI
  236. ReDim Shared m_arrScreenArea(-1) As ScreenAreaType
  237. ReDim Shared m_arrButton(-1) As TextButtonType
  238. ReDim Shared m_arrTextLabel(-1) As TextLabelType
  239. ReDim Shared m_arrTextField(-1) As TextFieldType
  240.  
  241. ' DEMO GAME / TESTING
  242. ReDim Shared m_arrPlayer(1 To 8) As PlayerType ' holds info for each player
  243.  
  244. ' =============================================================================
  245. ' LOCAL VARIABLES
  246. Dim in$
  247.  
  248. ' ****************************************************************************************************************************************************************
  249. ' ACTIVATE DEBUGGING WINDOW
  250. If m_bTesting = TRUE Then
  251.     $Console
  252.     _Delay 4
  253.     _Console On
  254.     _Echo "Started " + m_ProgramName$
  255.     _Echo "Debugging on..."
  256. ' ****************************************************************************************************************************************************************
  257.  
  258. ' =============================================================================
  259. ' START THE MAIN ROUTINE
  260. main
  261.  
  262. ' =============================================================================
  263. ' FINISH
  264. Print m_ProgramName$ + " finished."
  265. Input "Press <ENTER> to continue", in$
  266.  
  267. ' ****************************************************************************************************************************************************************
  268. ' DEACTIVATE DEBUGGING WINDOW
  269. If m_bTesting = TRUE Then
  270. ' ****************************************************************************************************************************************************************
  271.  
  272. System ' return control to the operating system
  273.  
  274. ' /////////////////////////////////////////////////////////////////////////////
  275.  
  276. Sub main
  277.     Dim RoutineName As String: RoutineName = "main"
  278.     Dim in$
  279.     Dim result$: result$ = ""
  280.  
  281.     ' SET UP SCREEN
  282.     Screen _NewImage(1024, 768, 32): _ScreenMove 0, 0
  283.  
  284.     Do
  285.         If Len(result$) = 0 Then
  286.             Cls
  287.         Else
  288.             Print
  289.         End If
  290.  
  291.         Print m_ProgramName$
  292.         Print
  293.         Print "Game Input Mapping Test " + m_VersionInfo$
  294.         Print "by Softintheheadware (Jan, 2022)"
  295.         Print
  296.  
  297.         Print "1. Basic controller test"
  298.         Print "2. Load controller mapping"
  299.         Print "3. View controller mapping"
  300.         Print "4. Dump controller mappings to console window"
  301.         Print "5. Edit  controller mapping for 1 or more players"
  302.         Print "6. Reset controller mapping for 1 or more players"
  303.         Print "7. Map controllers for 1-8 players (no GUI)"
  304.         Print "8. Map / edit controllers for 1-8 players (GUI)"
  305.         Print "9. Test controller mappings to move around screen"
  306.         Print "10. Save controller mappings"
  307.  
  308.         Print "What to do? ('q' to exit)"
  309.  
  310.         Input in$: in$ = _Trim$(in$) ' in$ = LCase$(Left$(in$, 1))
  311.        
  312.         If in$ = "1" Then
  313.             result$ = TestJoysticks1$
  314.         ElseIf in$ = "2" Then
  315.             result$ = LoadMappings1$
  316.             If Len(result$) = 0 Then result$ = "Loaded mappings."
  317.         ElseIf in$ = "3" Then
  318.             result$ = ViewMappings2$
  319.         ElseIf in$ = "4" Then
  320.             DumpControllerMap1
  321.         ElseIf in$ = "5" Then
  322.             result$ = EditMappings1$
  323.         ElseIf in$ = "6" Then
  324.             result$ = ResetMapping1$
  325.         ElseIf in$ = "7" Then
  326.             result$ = MapInput1$
  327.         ElseIf in$ = "8" Then
  328.             result$ = MapInput2$
  329.         ElseIf in$ = "9" Then
  330.             result$ = TestMappings1$
  331.         ElseIf in$ = "10" Then
  332.             result$ = SaveMappings1$
  333.         End If
  334.  
  335.         If Len(result$) > 0 Then
  336.             Print result$
  337.         End If
  338.  
  339.     Loop Until in$ = "q"
  340.  
  341.     ' RETURN TO TEXT SCREEN
  342.     Screen 0
  343.  
  344. End Sub ' main
  345.  
  346. ' /////////////////////////////////////////////////////////////////////////////
  347. ' Just a little test to verify _DEFAULTCOLOR and _BACKGROUNDCOLOR work.
  348.  
  349. Function DetectColor1$
  350.     Dim sResult As String: sResult = ""
  351.     ReDim arrColor(-1) As ColorType
  352.     Dim ScreenArray(1 To 48, 1 To 128) As String
  353.     Dim iRow As Integer
  354.     Dim iCol As Integer
  355.     Dim iForeColor As _Unsigned Long
  356.     Dim iBackColor As _Unsigned Long
  357.     Dim iY As Integer
  358.     Dim iX As Integer
  359.     Dim in$
  360.     Dim iLoop1 As Integer
  361.     Dim iLoop2 As Integer
  362.     Dim sInfo As String
  363.     Dim sNext As String
  364.     Dim sData As String
  365.     Dim sTest As String
  366.     Dim iMaxLen As Integer
  367.     Dim sValue1 As String
  368.     Dim sValue2 As String
  369.    
  370.     ' INITIALIZE
  371.     'AddColors arrColor()
  372.     'StringToArray ScreenArray(), GetMap$
  373.     ReDim _Preserve arrColor(1 To UBound(arrColor) + 1) As ColorType
  374.     arrColor(UBound(arrColor)).name = "cRed"
  375.     arrColor(UBound(arrColor)).value = cRed
  376.     ReDim _Preserve arrColor(1 To UBound(arrColor) + 1) As ColorType
  377.     arrColor(UBound(arrColor)).name = "cWhite"
  378.     arrColor(UBound(arrColor)).value = cWhite
  379.     ReDim _Preserve arrColor(1 To UBound(arrColor) + 1) As ColorType
  380.     arrColor(UBound(arrColor)).name = "cBlue"
  381.     arrColor(UBound(arrColor)).value = cBlue
  382.    
  383.     ' GET LEN
  384.     iMaxLen = 0
  385.     For iLoop1 = lbound(arrColor) to ubound(arrColor)
  386.         if len(arrColor(iLoop1).name) > iMaxLen then
  387.             iMaxLen = len(arrColor(iLoop1).name)
  388.         end if
  389.     Next iLoop1
  390.    
  391.     ' SET UP SCREEN
  392.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  393.     'Screen _NewImage(1024, 768, 32): _ScreenMove 0, 0
  394.    
  395.     ' DISPLAY GRAPHICALLY
  396.     Cls
  397.     'For iY = LBound(ScreenArray, 1) To UBound(ScreenArray, 1)
  398.     '    For iX = LBound(ScreenArray, 2) To UBound(ScreenArray, 2)
  399.     '        iRow = iY - 1: iCol = iX - 1
  400.     '        Color cRed, cBlack
  401.     '        PrintString iRow, iCol, ScreenArray(iY, iX)
  402.     '    Next iX
  403.     'Next iY
  404.     iRow = 0
  405.     iCol = 0
  406.     For iLoop1 = lbound(arrColor) to ubound(arrColor)
  407.         For iLoop2 = lbound(arrColor) to ubound(arrColor)
  408.             if iLoop1 <> iLoop2 then
  409.                 iCol = 0
  410.                 iForeColor = arrColor(iLoop1).value
  411.                 iBackColor = arrColor(iLoop2).value
  412.                 'sInfo = "Color " + _Trim$(Str$(iForeColor)) + ", " + _Trim$(Str$(iBackColor))
  413.                 sInfo = "Color " + _
  414.                     GetColorName$(arrColor(), iForeColor, _Trim$(Str$(iForeColor))) + _
  415.                     ", " + _
  416.                     GetColorName$(arrColor(), iBackColor, _Trim$(Str$(iBackColor)))                
  417.                 Color cWhite, cBlack : PrintString iRow, iCol, sInfo
  418.                
  419.                 sValue1 = arrColor(iLoop1).name + string$(iMaxLen, " ")
  420.                 sValue1 = left$(svalue1, iMaxLen)
  421.                 sValue2 = arrColor(iLoop2).name + string$(iMaxLen, " ")
  422.                 sValue2 = left$(svalue2, iMaxLen)
  423.                 sNext = sValue1 + " on " + sValue2
  424.                 iCol = len(sInfo) + 1
  425.                 Color iForeColor, iBackColor: PrintString iRow, iCol, sNext
  426.                
  427.                 'sData = "_DEFAULTCOLOR = " + _Trim$(Str$(_DEFAULTCOLOR)) + ", " + "_BACKGROUNDCOLOR = " + _Trim$(Str$(_BACKGROUNDCOLOR))
  428.                 'sTest = "_DEFAULTCOLOR " + IIFSTR$(_DEFAULTCOLOR = arrColor(iLoop1).value, "=", "!=") + " fgcolor" + _
  429.                 '    ", " + _
  430.                 '    "_BACKGROUNDCOLOR " + IIFSTR$(_BACKGROUNDCOLOR = arrColor(iLoop2).value, "=", "!=") + " bgcolor"
  431.                 'iCol = iCol + len(sNext) + 1
  432.                 'Color cWhite, cBlack : PrintString iRow, iCol, sData
  433.                 'iCol = iCol + len(sData) + 1
  434.                 'Color cWhite, cBlack : PrintString iRow, iCol, sTest
  435.                
  436.                 sData = "_DEFAULTCOLOR = " + _
  437.                     GetColorName$(arrColor(), _DEFAULTCOLOR, _Trim$(Str$(_DEFAULTCOLOR))) + _
  438.                     ", " + _
  439.                     "_BACKGROUNDCOLOR = " + _
  440.                     GetColorName$(arrColor(), _BACKGROUNDCOLOR, _Trim$(Str$(_BACKGROUNDCOLOR)))                
  441.                 iCol = iCol + len(sNext) + 1
  442.                 Color cWhite, cBlack : PrintString iRow, iCol, sData
  443.                
  444.             end if
  445.             iRow = iRow + 1
  446.         Next iLoop2
  447.     Next iLoop1
  448.    
  449.     '' Get color
  450.     'iForeColor = _DEFAULTCOLOR
  451.     'iBackColor = _BACKGROUNDCOLOR
  452.    
  453.     ' Show results
  454.     'Cls
  455.     Color cWhite, cBlack
  456.     'print "Color cRed, cBlack"
  457.     'print "Color " + _Trim$(Str$(cRed)) + ", " + _Trim$(Str$(cBlack))
  458.     'print "_DEFAULTCOLOR=" + _Trim$(Str$(iForeColor))
  459.     'print "_BACKGROUNDCOLOR=" + _Trim$(Str$(iBackColor))
  460.     locate iRow+1, 1
  461.     Input "PRESS <ENTER> TO CONTINUE"; in$
  462.    
  463.     ' RETURN RESULT
  464.     DetectColor1$ = sResult
  465. End Function ' DetectColor1$
  466.  
  467. ' /////////////////////////////////////////////////////////////////////////////
  468. ' sName = GetColorName$(arrColor(), ColorValue, DefaultName)
  469.  
  470. Function GetColorName$(arrColor() As ColorType, ColorValue As _Unsigned Long, DefaultName As String)
  471.     Dim sResult As String
  472.     Dim iLoop As Long
  473.     sResult = DefaultName
  474.     For iLoop = lbound(arrColor) to ubound(arrColor)
  475.         If arrColor(iLoop).value = ColorValue Then
  476.             sResult = arrColor(iLoop).name
  477.             Exit For
  478.         End If
  479.     Next iLoop
  480.     GetColorName$ = sResult
  481. End Function ' GetColorName$
  482.  
  483. ' /////////////////////////////////////////////////////////////////////////////
  484. ' TODO: get keyboard input working
  485. ' TODO: get continuous movement working for digital joysticks
  486. ' TODO: adjust analog joystick sensitivity
  487.  
  488. Function TestMappings1$
  489.     Dim sResult As String: sResult = ""
  490.     Dim sError As String: sError = ""
  491.  
  492.     Dim iDeviceCount As Integer
  493.     Dim iDevice As Integer
  494.     Dim iNumControllers As Integer
  495.     Dim iController As Integer
  496.     Dim iValue As Integer
  497.     Dim iWhichInput As Integer
  498.  
  499.     Dim arrButton(32, 16) As Integer ' number of buttons on the joystick
  500.     Dim arrButtonNew(32, 16) As Integer ' tracks when to initialize values
  501.     Dim arrAxis(32, 16) As Double ' number of axis on the joystick
  502.     Dim arrAxisNew(32, 16) As Integer ' tracks when to initialize values
  503.  
  504.     Dim iCols As Integer
  505.     Dim iRows As Integer
  506.  
  507.     Dim iPlayer As Integer
  508.     Dim iNextY As Integer
  509.     Dim iNextX As Integer
  510.     Dim iNextC As Integer
  511.  
  512.     Dim iMinX As Integer
  513.     Dim iMaxX As Integer
  514.     Dim iMinY As Integer
  515.     Dim iMaxY As Integer
  516.  
  517.     Dim bHaveInput As Integer
  518.     Dim bFinished As Integer
  519.     Dim bFoundWho As Integer
  520.     Dim bRepeat As Integer
  521.  
  522.     Dim in$
  523.  
  524.     ' MAKE SURE WE HAVE MAPPING
  525.     If m_bHaveMapping = TRUE Then
  526.         ' INITIALIZE
  527.         InitKeyboardButtonCodes
  528.         iCols = _Width(0) \ _FontWidth
  529.         iRows = _Height(0) \ _FontHeight
  530.         iMinX = 1: iMaxX = iCols
  531.         iMinY = 1: iMaxY = iRows
  532.  
  533.         Cls
  534.         PrintStringCR1 10, 20, "Test control mapping:"
  535.         PrintStringCR1 10, 22, "1. Directional controls move letters around screen."
  536.         PrintStringCR1 10, 23, "2. Buttons make sounds."
  537.         PrintStringCR1 10, 25, "Press <ESC> to exit."
  538.  
  539.         ' INITIALIZE PLAYER COORDINATES AND SCREEN CHARACTERS
  540.         iNextY = 1
  541.         iNextX = -3
  542.         iNextC = 64
  543.  
  544.         For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  545.             iNextX = iNextX + 4
  546.             If iNextX >= iMaxX Then
  547.                 iNextX = iMinX
  548.                 iNextY = iNextY + 4
  549.                 If iNextY > iMaxY Then
  550.                     iNextY = iMinY
  551.                 End If
  552.             End If
  553.             iNextC = iNextC + 1
  554.             m_arrPlayer(iPlayer).x = iNextX
  555.             m_arrPlayer(iPlayer).y = iNextY
  556.             m_arrPlayer(iPlayer).c = iNextC
  557.             m_arrPlayer(iPlayer).xOld = iNextX
  558.             m_arrPlayer(iPlayer).yOld = iNextY
  559.  
  560.             m_arrPlayer(iPlayer).moveX = 0
  561.             m_arrPlayer(iPlayer).moveY = 0
  562.  
  563.             m_arrPlayer(iPlayer).moveUp = FALSE
  564.             m_arrPlayer(iPlayer).moveDown = FALSE
  565.             m_arrPlayer(iPlayer).moveLeft = FALSE
  566.             m_arrPlayer(iPlayer).moveRight = FALSE
  567.             m_arrPlayer(iPlayer).button1 = FALSE
  568.             m_arrPlayer(iPlayer).button2 = FALSE
  569.             m_arrPlayer(iPlayer).button3 = FALSE
  570.             m_arrPlayer(iPlayer).button4 = FALSE
  571.  
  572.             m_arrPlayer(iPlayer).lastMoveUp = FALSE
  573.             m_arrPlayer(iPlayer).lastMoveDown = FALSE
  574.             m_arrPlayer(iPlayer).lastMoveLeft = FALSE
  575.             m_arrPlayer(iPlayer).lastMoveRight = FALSE
  576.             m_arrPlayer(iPlayer).lastButton1 = FALSE
  577.             m_arrPlayer(iPlayer).lastButton2 = FALSE
  578.             m_arrPlayer(iPlayer).lastButton3 = FALSE
  579.             m_arrPlayer(iPlayer).lastButton4 = FALSE
  580.         Next iPlayer
  581.  
  582.         ' COUNT # OF JOYSTICKS
  583.         ' TODO: find out the right way to count joysticks
  584.         If Len(sError) = 0 Then
  585.             ' D= _DEVICES ' MUST be read in order for other 2 device functions to work!
  586.             iDeviceCount = _Devices ' Find the number of devices on someone's system
  587.  
  588.             If iDeviceCount > 2 Then
  589.                 ' LIMIT # OF DEVICES, IF THERE IS A LIMIT DEFINED
  590.                 iNumControllers = iDeviceCount - 2
  591.                 If cMaxControllers > 0 Then
  592.                     If iNumControllers > cMaxControllers Then
  593.                         iNumControllers = cMaxControllers
  594.                     End If
  595.                 End If
  596.             Else
  597.                 ' ONLY 2 FOUND (KEYBOARD, MOUSE)
  598.                 'sError = "No game controllers found."
  599.                 iNumControllers = 0
  600.             End If
  601.         End If
  602.  
  603.         ' INITIALIZE CONTROLLER DATA
  604.         If Len(sError) = 0 Then
  605.             For iController = 1 To iNumControllers
  606.                 m_arrController(iController).buttonCount = cMaxButtons
  607.                 m_arrController(iController).axisCount = cMaxAxis
  608.                 For iLoop = 1 To cMaxButtons
  609.                     arrButtonNew(iController, iLoop) = TRUE
  610.                 Next iLoop
  611.                 For iLoop = 1 To cMaxAxis
  612.                     arrAxisNew(iController, iLoop) = TRUE
  613.                 Next iLoop
  614.             Next iController
  615.         End If
  616.  
  617.         ' INITIALIZE CONTROLLER INPUT
  618.         If Len(sError) = 0 Then
  619.             _KeyClear: _Delay 1
  620.             For iController = 1 To iNumControllers
  621.                 iDevice = iController + 2
  622.                 While _DeviceInput(iDevice) ' clear and update the device buffer
  623.                     For iLoop = 1 To _LastButton(iDevice)
  624.                         If (iLoop > cMaxButtons) Then Exit For
  625.                         m_arrController(iController).buttonCount = iLoop
  626.                         arrButton(iController, iLoop) = FALSE
  627.                     Next iLoop
  628.                     For iLoop = 1 To _LastAxis(iDevice) ' this loop checks all my axis
  629.                         If (iLoop > cMaxAxis) Then Exit For
  630.                         m_arrController(iController).axisCount = iLoop
  631.                         arrAxis(iController, iLoop) = 0
  632.                     Next iLoop
  633.                 Wend ' clear and update the device buffer
  634.             Next iController
  635.         End If
  636.  
  637.         ' GET INPUT AND MOVE PLAYERS AROUND ON SCREEN
  638.         _KeyClear: _Delay 1
  639.         bFinished = FALSE
  640.         Do
  641.             ' Clear control buffer for players
  642.             For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  643.                 m_arrPlayer(iPlayer).moveUp = FALSE
  644.                 m_arrPlayer(iPlayer).moveDown = FALSE
  645.                 m_arrPlayer(iPlayer).moveLeft = FALSE
  646.                 m_arrPlayer(iPlayer).moveRight = FALSE
  647.                 m_arrPlayer(iPlayer).button1 = FALSE
  648.                 m_arrPlayer(iPlayer).button2 = FALSE
  649.                 m_arrPlayer(iPlayer).button3 = FALSE
  650.                 m_arrPlayer(iPlayer).button4 = FALSE
  651.             Next iPlayer
  652.  
  653.             ' -----------------------------------------------------------------------------
  654.             ' BEGIN CHECK FOR CONTROLLER INPUT
  655.             If iNumControllers > 0 Then
  656.                 For iController = 1 To iNumControllers
  657.                     iDevice = iController + 2
  658.  
  659.                     ' Check all devices
  660.                     While _DeviceInput(iDevice)
  661.                     Wend ' clear and update the device buffer
  662.  
  663.                     ' Check each button
  664.                     For iLoop = 1 To _LastButton(iDevice)
  665.                         If (iLoop > cMaxButtons) Then Exit For
  666.  
  667.                         ' update button array to indicate if a button is up or down currently.
  668.                         'if TRUE=TRUE then
  669.                         If _ButtonChange(iLoop) Then
  670.                             iValue = _Button(iLoop)
  671.                             If iValue <> arrButton(iController, iLoop) Then
  672.                                 ' *****************************************************************************
  673.                                 ' PRESSED BUTTON
  674.  
  675.                                 ' BEGIN find who this is mapped for
  676.                                 bFoundWho = FALSE
  677.                                 For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  678.                                     For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  679.                                         If m_arrControlMap(iPlayer, iWhichInput).device = iDevice Then
  680.                                             If m_arrControlMap(iPlayer, iWhichInput).typ = cInputButton Then
  681.                                                 If m_arrControlMap(iPlayer, iWhichInput).code = iLoop Then
  682.                                                     'if m_arrControlMap(iPlayer, iWhichInput).value = iValue then
  683.                                                     bFoundWho = TRUE
  684.                                                     Select Case iWhichInput
  685.                                                         Case cInputUp:
  686.                                                             m_arrPlayer(iPlayer).moveUp = TRUE
  687.                                                         Case cInputDown:
  688.                                                             m_arrPlayer(iPlayer).moveDown = TRUE
  689.                                                         Case cInputLeft:
  690.                                                             m_arrPlayer(iPlayer).moveLeft = TRUE
  691.                                                         Case cInputRight:
  692.                                                             m_arrPlayer(iPlayer).moveRight = TRUE
  693.                                                         Case cInputButton1:
  694.                                                             m_arrPlayer(iPlayer).button1 = TRUE
  695.                                                         Case cInputButton2:
  696.                                                             m_arrPlayer(iPlayer).button2 = TRUE
  697.                                                         Case cInputButton3:
  698.                                                             m_arrPlayer(iPlayer).button3 = TRUE
  699.                                                         Case cInputButton4:
  700.                                                             m_arrPlayer(iPlayer).button4 = TRUE
  701.                                                         Case Else:
  702.                                                             '(IGNORE)
  703.                                                     End Select
  704.                                                     Exit For
  705.                                                     'end if
  706.                                                 End If
  707.                                             End If
  708.                                         End If
  709.                                     Next iWhichInput
  710.                                     If bFoundWho = TRUE Then Exit For
  711.                                 Next iPlayer
  712.                                 ' END find who this is mapped for
  713.  
  714.                             End If
  715.                         End If
  716.                     Next iLoop
  717.  
  718.                     ' Check each axis
  719.                     For iLoop = 1 To _LastAxis(iDevice)
  720.                         If (iLoop > cMaxAxis) Then Exit For
  721.                         dblNextAxis = _Axis(iLoop)
  722.                         dblNextAxis = RoundUpDouble#(dblNextAxis, 3)
  723.  
  724.                         ' I like to give a little "jiggle" resistance to my controls, as I have an old joystick
  725.                         ' which is prone to always give minute values and never really center on true 0.
  726.                         ' A value of 1 means my axis is pushed fully in one direction.
  727.                         ' A value greater than 0.1 means it's been partially pushed in a direction (such as at a 45 degree diagional angle).
  728.                         ' A value of less than 0.1 means we count it as being centered. (As if it was 0.)
  729.  
  730.                         ' Set sensitivity:
  731.                         'These are way too sensitive for analog:
  732.                         'IF ABS(_AXIS(iLoop)) <= 1 AND ABS(_AXIS(iLoop)) >= .1 THEN
  733.                         'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .01 THEN
  734.                         'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .001 THEN
  735.                         ''For digital input, we'll use a big picture:
  736.                         'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= 0.75 THEN
  737.                         If Abs(dblNextAxis) <= 1 And Abs(dblNextAxis) >= 0.5 Then
  738.  
  739.                             ' WE WANT CONTINUOUS MOVEMENT (DISABLE FOR NOT)
  740.                             'if TRUE=TRUE then
  741.                             If dblNextAxis <> arrAxis(iController, iLoop) Then
  742.                                 ' *****************************************************************************
  743.                                 ' MOVED STICK
  744.  
  745.                                 ' convert to a digital value
  746.                                 If dblNextAxis < 0 Then
  747.                                     iValue = -1
  748.                                 Else
  749.                                     iValue = 1
  750.                                 End If
  751.  
  752.                                 ' BEGIN find who this is mapped for
  753.                                 bFoundWho = FALSE
  754.                                 For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  755.                                     For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  756.                                         If m_arrControlMap(iPlayer, iWhichInput).device = iDevice Then
  757.                                             If m_arrControlMap(iPlayer, iWhichInput).typ = cInputAxis Then
  758.                                                 If m_arrControlMap(iPlayer, iWhichInput).code = iLoop Then
  759.                                                     If m_arrControlMap(iPlayer, iWhichInput).value = iValue Then
  760.                                                         bFoundWho = TRUE
  761.                                                         Select Case iWhichInput
  762.                                                             Case cInputUp:
  763.                                                                 m_arrPlayer(iPlayer).moveUp = TRUE
  764.                                                             Case cInputDown:
  765.                                                                 m_arrPlayer(iPlayer).moveDown = TRUE
  766.                                                             Case cInputLeft:
  767.                                                                 m_arrPlayer(iPlayer).moveLeft = TRUE
  768.                                                             Case cInputRight:
  769.                                                                 m_arrPlayer(iPlayer).moveRight = TRUE
  770.                                                             Case cInputButton1:
  771.                                                                 m_arrPlayer(iPlayer).button1 = TRUE
  772.                                                             Case cInputButton2:
  773.                                                                 m_arrPlayer(iPlayer).button2 = TRUE
  774.                                                             Case cInputButton3:
  775.                                                                 m_arrPlayer(iPlayer).button3 = TRUE
  776.                                                             Case cInputButton4:
  777.                                                                 m_arrPlayer(iPlayer).button4 = TRUE
  778.                                                             Case Else:
  779.                                                                 '(IGNORE)
  780.                                                         End Select
  781.                                                         Exit For
  782.                                                     End If
  783.                                                 End If
  784.                                             End If
  785.                                         End If
  786.                                     Next iWhichInput
  787.                                     If bFoundWho = TRUE Then Exit For
  788.                                 Next iPlayer
  789.                                 ' END find who this is mapped for
  790.  
  791.                             End If
  792.                         End If
  793.                     Next iLoop
  794.  
  795.                 Next iController
  796.             End If
  797.             ' END CHECK FOR CONTROLLER INPUT
  798.             ' -----------------------------------------------------------------------------
  799.  
  800.             ' -----------------------------------------------------------------------------
  801.             ' BEGIN CHECK FOR KEYBOARD INPUT #1
  802.             '_KEYCLEAR: _DELAY 1
  803.             While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  804.  
  805.             ' Detect changed key state
  806.             iDevice = 1 ' keyboard
  807.             For iLoop = LBound(m_arrButtonCode) To UBound(m_arrButtonCode)
  808.                 iCode = m_arrButtonCode(iLoop)
  809.                 If _Button(iCode) <> FALSE Then
  810.                     ' *****************************************************************************
  811.                     ' PRESSED KEYBOARD
  812.                     'PRINT "PRESSED " + m_arrButtonKey(iLoop)
  813.  
  814.                     ' BEGIN find who this is mapped for
  815.                     bFoundWho = FALSE
  816.                     For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  817.                         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  818.                             If m_arrControlMap(iPlayer, iWhichInput).device = iDevice Then
  819.                                 If m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey Then
  820.                                     'if m_arrControlMap(iPlayer, iWhichInput).code = iLoop then
  821.                                     If m_arrControlMap(iPlayer, iWhichInput).code = iCode Then
  822.                                         'if m_arrControlMap(iPlayer, iWhichInput).value = iValue then
  823.                                         bFoundWho = TRUE
  824.                                         Select Case iWhichInput
  825.                                             Case cInputUp:
  826.                                                 m_arrPlayer(iPlayer).moveUp = TRUE
  827.                                             Case cInputDown:
  828.                                                 m_arrPlayer(iPlayer).moveDown = TRUE
  829.                                             Case cInputLeft:
  830.                                                 m_arrPlayer(iPlayer).moveLeft = TRUE
  831.                                             Case cInputRight:
  832.                                                 m_arrPlayer(iPlayer).moveRight = TRUE
  833.                                             Case cInputButton1:
  834.                                                 m_arrPlayer(iPlayer).button1 = TRUE
  835.                                             Case cInputButton2:
  836.                                                 m_arrPlayer(iPlayer).button2 = TRUE
  837.                                             Case cInputButton3:
  838.                                                 m_arrPlayer(iPlayer).button3 = TRUE
  839.                                             Case cInputButton4:
  840.                                                 m_arrPlayer(iPlayer).button4 = TRUE
  841.                                             Case Else:
  842.                                                 '(IGNORE)
  843.                                         End Select
  844.                                         Exit For
  845.                                         'end if
  846.                                     End If
  847.                                 End If
  848.                             End If
  849.                         Next iWhichInput
  850.                         If bFoundWho = TRUE Then Exit For
  851.                     Next iPlayer
  852.                     ' END find who this is mapped for
  853.  
  854.                 End If
  855.             Next iLoop
  856.             ' END CHECK FOR KEYBOARD INPUT #1
  857.             ' -----------------------------------------------------------------------------
  858.  
  859.             ' NOW DRAW PLAYERS ON SCREEN
  860.             For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  861.  
  862.                 ' -----------------------------------------------------------------------------
  863.                 ' BEGIN UPDATE MOVEMENT CONTROL STATES
  864.                 ' If repeating keys are disabled then
  865.                 ' disable until the key has been released
  866.  
  867.                 If m_arrControlMap(iPlayer, cInputUp).repeat = FALSE Then
  868.                     If m_arrPlayer(iPlayer).moveUp = TRUE Then
  869.                         If m_arrPlayer(iPlayer).lastMoveUp = TRUE Then
  870.                             m_arrPlayer(iPlayer).moveUp = FALSE
  871.                         End If
  872.                     Else
  873.                         m_arrPlayer(iPlayer).lastMoveUp = FALSE
  874.                     End If
  875.                 End If
  876.  
  877.                 If m_arrControlMap(iPlayer, cInputDown).repeat = FALSE Then
  878.                     If m_arrPlayer(iPlayer).moveDown = TRUE Then
  879.                         If m_arrPlayer(iPlayer).lastMoveDown = TRUE Then
  880.                             m_arrPlayer(iPlayer).moveDown = FALSE
  881.                         End If
  882.                     Else
  883.                         m_arrPlayer(iPlayer).lastMoveDown = FALSE
  884.                     End If
  885.                 End If
  886.  
  887.                 If m_arrControlMap(iPlayer, cInputLeft).repeat = FALSE Then
  888.                     If m_arrPlayer(iPlayer).moveLeft = TRUE Then
  889.                         If m_arrPlayer(iPlayer).lastMoveLeft = TRUE Then
  890.                             m_arrPlayer(iPlayer).moveLeft = FALSE
  891.                         End If
  892.                     Else
  893.                         m_arrPlayer(iPlayer).lastMoveLeft = FALSE
  894.                     End If
  895.                 End If
  896.  
  897.                 If m_arrControlMap(iPlayer, cInputRight).repeat = FALSE Then
  898.                     If m_arrPlayer(iPlayer).moveRight = TRUE Then
  899.                         If m_arrPlayer(iPlayer).lastMoveRight = TRUE Then
  900.                             m_arrPlayer(iPlayer).moveRight = FALSE
  901.                         End If
  902.                     Else
  903.                         m_arrPlayer(iPlayer).lastMoveRight = FALSE
  904.                     End If
  905.                 End If
  906.                 ' END UPDATE MOVEMENT CONTROL STATES
  907.                 ' -----------------------------------------------------------------------------
  908.  
  909.                 ' -----------------------------------------------------------------------------
  910.                 ' BEGIN MOVEMENT ACTIONS
  911.  
  912.                 m_arrPlayer(iPlayer).moveY = 0
  913.                 m_arrPlayer(iPlayer).moveX = 0
  914.  
  915.                 If m_arrPlayer(iPlayer).moveUp = TRUE Then
  916.                     m_arrPlayer(iPlayer).moveY = -1
  917.                     m_arrPlayer(iPlayer).lastMoveUp = TRUE
  918.                 End If
  919.  
  920.                 If m_arrPlayer(iPlayer).moveDown = TRUE Then
  921.                     m_arrPlayer(iPlayer).moveY = 1
  922.                     m_arrPlayer(iPlayer).lastMoveDown = TRUE
  923.                 End If
  924.  
  925.                 If m_arrPlayer(iPlayer).moveLeft = TRUE Then
  926.                     m_arrPlayer(iPlayer).moveX = -1
  927.                     m_arrPlayer(iPlayer).lastMoveLeft = TRUE
  928.                 End If
  929.  
  930.                 If m_arrPlayer(iPlayer).moveRight = TRUE Then
  931.                     m_arrPlayer(iPlayer).moveX = 1
  932.                     m_arrPlayer(iPlayer).lastMoveRight = TRUE
  933.                 End If
  934.                 ' END MOVEMENT ACTIONS
  935.                 ' -----------------------------------------------------------------------------
  936.  
  937.  
  938.                 ' -----------------------------------------------------------------------------
  939.                 ' BEGIN MOVEMENT
  940.  
  941.                 ' MOVE RIGHT/LEFT
  942.                 m_arrPlayer(iPlayer).x = m_arrPlayer(iPlayer).x + m_arrPlayer(iPlayer).moveX
  943.                 If m_arrPlayer(iPlayer).x < iMinX Then
  944.                     m_arrPlayer(iPlayer).x = m_arrPlayer(iPlayer).xOld ' iMinX
  945.                 ElseIf m_arrPlayer(iPlayer).x > iMaxX Then
  946.                     m_arrPlayer(iPlayer).x = m_arrPlayer(iPlayer).xOld ' iMaxX
  947.                 End If
  948.  
  949.                 ' MOVE UP/DOWN
  950.                 m_arrPlayer(iPlayer).y = m_arrPlayer(iPlayer).y + m_arrPlayer(iPlayer).moveY
  951.                 If m_arrPlayer(iPlayer).y < iMinY Then
  952.                     m_arrPlayer(iPlayer).y = m_arrPlayer(iPlayer).yOld ' iMinY
  953.                 ElseIf m_arrPlayer(iPlayer).y > iMaxY Then
  954.                     m_arrPlayer(iPlayer).y = m_arrPlayer(iPlayer).yOld ' iMaxY
  955.                 End If
  956.  
  957.                 ' UPDATE SCREEN
  958.                 '_PRINTSTRING (m_arrPlayer(iPlayer).xOld, m_arrPlayer(iPlayer).yOld), " "
  959.                 '_PRINTSTRING (m_arrPlayer(iPlayer).x, m_arrPlayer(iPlayer).y), CHR$(m_arrPlayer(iPlayer).c)
  960.                 PrintStringCR1 m_arrPlayer(iPlayer).xOld, m_arrPlayer(iPlayer).yOld, " "
  961.                 PrintStringCR1 m_arrPlayer(iPlayer).x, m_arrPlayer(iPlayer).y, Chr$(m_arrPlayer(iPlayer).c)
  962.                 m_arrPlayer(iPlayer).xOld = m_arrPlayer(iPlayer).x
  963.                 m_arrPlayer(iPlayer).yOld = m_arrPlayer(iPlayer).y
  964.  
  965.                 ' END MOVEMENT
  966.                 ' -----------------------------------------------------------------------------
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.                 ' -----------------------------------------------------------------------------
  975.                 ' BEGIN UPDATE BUTTON STATES
  976.                 ' If repeating keys are disabled then
  977.                 ' disable until the key has been released
  978.  
  979.                 'if m_bRepeatButton1 = FALSE then
  980.                 If m_arrControlMap(iPlayer, cInputButton1).repeat = FALSE Then
  981.                     If m_arrPlayer(iPlayer).button1 = TRUE Then
  982.                         If m_arrPlayer(iPlayer).lastButton1 = TRUE Then
  983.                             m_arrPlayer(iPlayer).button1 = FALSE
  984.                         End If
  985.                     Else
  986.                         m_arrPlayer(iPlayer).lastButton1 = FALSE
  987.                     End If
  988.                 End If
  989.                 If m_arrControlMap(iPlayer, cInputButton2).repeat = FALSE Then
  990.                     If m_arrPlayer(iPlayer).button2 = TRUE Then
  991.                         If m_arrPlayer(iPlayer).lastButton2 = TRUE Then
  992.                             m_arrPlayer(iPlayer).button2 = FALSE
  993.                         End If
  994.                     Else
  995.                         m_arrPlayer(iPlayer).lastButton2 = FALSE
  996.                     End If
  997.                 End If
  998.                 If m_arrControlMap(iPlayer, cInputButton3).repeat = FALSE Then
  999.                     If m_arrPlayer(iPlayer).button3 = TRUE Then
  1000.                         If m_arrPlayer(iPlayer).lastButton3 = TRUE Then
  1001.                             m_arrPlayer(iPlayer).button3 = FALSE
  1002.                         End If
  1003.                     Else
  1004.                         m_arrPlayer(iPlayer).lastButton3 = FALSE
  1005.                     End If
  1006.                 End If
  1007.                 If m_arrControlMap(iPlayer, cInputButton4).repeat = FALSE Then
  1008.                     If m_arrPlayer(iPlayer).button4 = TRUE Then
  1009.                         If m_arrPlayer(iPlayer).lastButton4 = TRUE Then
  1010.                             m_arrPlayer(iPlayer).button4 = FALSE
  1011.                         End If
  1012.                     Else
  1013.                         m_arrPlayer(iPlayer).lastButton4 = FALSE
  1014.                     End If
  1015.                 End If
  1016.                 ' END UPDATE BUTTON STATES
  1017.                 ' -----------------------------------------------------------------------------
  1018.  
  1019.  
  1020.  
  1021.                 ' -----------------------------------------------------------------------------
  1022.                 ' BEGIN BUTTON ACTIONS
  1023.                 If m_arrPlayer(iPlayer).button1 = TRUE Then
  1024.                     MakeSound iPlayer, 1
  1025.                     m_arrPlayer(iPlayer).lastButton1 = TRUE
  1026.                 End If
  1027.  
  1028.                 If m_arrPlayer(iPlayer).button2 = TRUE Then
  1029.                     MakeSound iPlayer, 2
  1030.                     m_arrPlayer(iPlayer).lastButton2 = TRUE
  1031.                 End If
  1032.  
  1033.                 If m_arrPlayer(iPlayer).button3 = TRUE Then
  1034.                     MakeSound iPlayer, 3
  1035.                     m_arrPlayer(iPlayer).lastButton3 = TRUE
  1036.                 End If
  1037.  
  1038.                 If m_arrPlayer(iPlayer).button4 = TRUE Then
  1039.                     MakeSound iPlayer, 4
  1040.                     m_arrPlayer(iPlayer).lastButton4 = TRUE
  1041.                 End If
  1042.                 ' END BUTTON ACTIONS
  1043.                 ' -----------------------------------------------------------------------------
  1044.  
  1045.             Next iPlayer
  1046.  
  1047.             _Limit 30
  1048.         Loop Until _KeyHit = 27 ' ESCAPE to quit
  1049.         _KeyClear: _Delay 1
  1050.  
  1051.         sResult = sError
  1052.     Else
  1053.         sResult = "No mapping loaded. Please load a mapping or map keys."
  1054.     End If
  1055.  
  1056.     TestMappings1$ = sResult
  1057. End Function ' TestMappings1$
  1058.  
  1059. ' /////////////////////////////////////////////////////////////////////////////
  1060.  
  1061. Sub MakeSound (iPlayer As Integer, iButton As Integer)
  1062.     Dim note%
  1063.     If iPlayer < 1 Then
  1064.         iPlayer = 1
  1065.     ElseIf iPlayer > 8 Then
  1066.         iPlayer = 8
  1067.     End If
  1068.     If iButton < 1 Then
  1069.         iButton = 1
  1070.     ElseIf iButton > 4 Then
  1071.         iButton = 4
  1072.     End If
  1073.  
  1074.     note% = iPlayer * 100 + (iButton * 25)
  1075.     If note% > 4186 Then
  1076.         note% = 4186
  1077.     End If
  1078.     Sound note%, .75
  1079. End Sub ' MakeSound
  1080.  
  1081. ' /////////////////////////////////////////////////////////////////////////////
  1082. ' V2 prints in 2 columns.
  1083. ' A total kludge!
  1084.  
  1085. Sub PrintControllerMap2
  1086.     Dim RoutineName As String:: RoutineName = "PrintControllerMap2"
  1087.     Dim iPlayer As Integer
  1088.     Dim iWhichInput As Integer
  1089.     Dim iCount As Integer
  1090.     Dim sLine As String
  1091.     Dim iHalf As Integer
  1092.     Dim sColumn1 As String: sColumn1 = ""
  1093.     Dim sColumn2 As String: sColumn2 = ""
  1094.     ReDim arrColumn1(-1) As String
  1095.     ReDim arrColumn2(-1) As String
  1096.     Dim iLoop As Integer
  1097.     Dim iColWidth As Integer: iColWidth = 60
  1098.     Dim sValue As String
  1099.     Dim in$
  1100.  
  1101.     ' INITIALIZE
  1102.     InitKeyboardButtonCodes
  1103.  
  1104.     ' START OUTPUT
  1105.     Print "Controller mapping:"
  1106.     'Print "Player#  Input      Device#  Type     Code              Value"
  1107.     '       1        button #2  x        unknown  x                 x
  1108.     '       9        11         9        9        18                9
  1109.     '       12345678912345678901123456789123456789123456789012345678123456789
  1110.     '       12345678901234567890123456789012345678901234567890123456789012345678901234567890
  1111.     '       00000000011111111112222222222333333333344444444445555555555666666666677777777778
  1112.  
  1113.     If m_bHaveMapping = TRUE Then
  1114.         ' THIS IS A LAZY WAY TO GET 2 COLUMNS!
  1115.         iHalf = UBound(m_arrControlMap, 1) / 2
  1116.  
  1117.         sLine = "Player  Input     Device#  Type     Code         Value Rep"
  1118.         sColumn1 = sColumn1 + StrPadRight$(sLine, iColWidth) + Chr$(13)
  1119.         sLine = "----------------------------------------------------------"
  1120.         sColumn1 = sColumn1 + StrPadRight$(sLine, iColWidth) + Chr$(13)
  1121.         For iPlayer = LBound(m_arrControlMap, 1) To iHalf
  1122.             iCount = 0
  1123.             For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1124.                 If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1125.                     iCount = iCount + 1
  1126.                 End If
  1127.             Next iWhichInput
  1128.             If iCount > 0 Then
  1129.                 For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1130.                     If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1131.                         sLine = IntPadRight$(iPlayer, 8)
  1132.                         sLine = sLine + StrPadRight$(InputToString$(iWhichInput), 10)
  1133.                         sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).device, 9)
  1134.                         sLine = sLine + StrPadRight$(InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ), 9)
  1135.  
  1136.                         'sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 9)
  1137.                         If m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey Then
  1138.                             sValue = GetKeyboardButtonCodeShortText$(m_arrControlMap(iPlayer, iWhichInput).code)
  1139.                             sValue = StrPadRight$(sValue, 13)
  1140.                         Else
  1141.                             sValue = IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 13)
  1142.                         End If
  1143.                         sLine = sLine + sValue
  1144.  
  1145.                         sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).value, 6)
  1146.  
  1147.                         'sValue = TrueFalse$(m_arrControlMap(iPlayer, iWhichInput).repeat)
  1148.                         sValue = IIFSTR$ (m_arrControlMap(iPlayer, iWhichInput).repeat, "Y", "N")
  1149.                         sLine = sLine + StrPadRight$(sValue, 3)
  1150.  
  1151.                         'Print sLine
  1152.                         sLine = StrPadRight$(sLine, iColWidth)
  1153.                         sColumn1 = sColumn1 + sLine + Chr$(13)
  1154.                     End If
  1155.                 Next iWhichInput
  1156.             Else
  1157.                 sLine = IntPadRight$(iPlayer, 9) + "(NONE)"
  1158.                 'Print sLine
  1159.                 sLine = StrPadRight$(sLine, iColWidth)
  1160.                 sColumn1 = sColumn1 + sLine + Chr$(13)
  1161.             End If
  1162.         Next iPlayer
  1163.  
  1164.         'sLine = "Player#  Input      Device#  Type     Code              Value"
  1165.         sLine = "Player  Input     Device#  Type     Code         Value Rep"
  1166.         sColumn2 = sColumn2 + StrPadRight$(sLine, iColWidth) + Chr$(13)
  1167.         sLine = "----------------------------------------------------------"
  1168.         sColumn2 = sColumn2 + StrPadRight$(sLine, iColWidth) + Chr$(13)
  1169.         For iPlayer = iHalf + 1 To UBound(m_arrControlMap, 1)
  1170.             iCount = 0
  1171.             For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1172.                 If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1173.                     iCount = iCount + 1
  1174.                 End If
  1175.             Next iWhichInput
  1176.             If iCount > 0 Then
  1177.                 For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1178.                     If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1179.                         sLine = IntPadRight$(iPlayer, 8)
  1180.                         sLine = sLine + StrPadRight$(InputToString$(iWhichInput), 10)
  1181.                         sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).device, 9)
  1182.                         sLine = sLine + StrPadRight$(InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ), 9)
  1183.  
  1184.                         'sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 9)
  1185.                         If m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey Then
  1186.                             sValue = GetKeyboardButtonCodeShortText$(m_arrControlMap(iPlayer, iWhichInput).code)
  1187.                             sValue = StrPadRight$(sValue, 13)
  1188.                         Else
  1189.                             sValue = IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 13)
  1190.                         End If
  1191.                         sLine = sLine + sValue
  1192.  
  1193.                         sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).value, 6)
  1194.  
  1195.                         'sValue = TrueFalse$(m_arrControlMap(iPlayer, iWhichInput).repeat)
  1196.                         sValue = IIFSTR$ (m_arrControlMap(iPlayer, iWhichInput).repeat, "Y", "N")
  1197.                         sLine = sLine + StrPadRight$(sValue, 3)
  1198.  
  1199.                         'Print sLine
  1200.                         sLine = StrPadRight$(sLine, iColWidth)
  1201.                         sColumn2 = sColumn2 + sLine + Chr$(13)
  1202.                     End If
  1203.                 Next iWhichInput
  1204.             Else
  1205.                 sLine = IntPadRight$(iPlayer, 9) + "(NONE)"
  1206.                 'Print sLine
  1207.                 sLine = StrPadRight$(sLine, iColWidth)
  1208.                 sColumn2 = sColumn2 + sLine + Chr$(13)
  1209.             End If
  1210.         Next iPlayer
  1211.  
  1212.         split sColumn1, Chr$(13), arrColumn1()
  1213.         split sColumn2, Chr$(13), arrColumn2()
  1214.         If UBound(arrColumn1) > UBound(arrColumn2) Then
  1215.             iCount = UBound(arrColumn1)
  1216.         Else
  1217.             iCount = UBound(arrColumn2)
  1218.         End If
  1219.         For iLoop = 0 To iCount
  1220.             sLine = ""
  1221.             If UBound(arrColumn1) >= iLoop Then
  1222.                 sLine = sLine + arrColumn1(iLoop)
  1223.             Else
  1224.                 sLine = sLine + String$(iColWidth, " ")
  1225.             End If
  1226.             sLine = sLine + "     "
  1227.             If UBound(arrColumn2) >= iLoop Then
  1228.                 sLine = sLine + arrColumn2(iLoop)
  1229.             Else
  1230.                 sLine = sLine + String$(iColWidth, " ")
  1231.             End If
  1232.             Print sLine
  1233.         Next iLoop
  1234.     Else
  1235.         Print "No mapping loaded. Please load a mapping or map keys."
  1236.     End If
  1237.  
  1238. End Sub ' PrintControllerMap2
  1239.  
  1240. ' /////////////////////////////////////////////////////////////////////////////
  1241. ' Original (simple) routine
  1242.  
  1243. Sub PrintControllerMap1
  1244.     Dim RoutineName As String:: RoutineName = "PrintControllerMap1"
  1245.     Dim iPlayer As Integer
  1246.     Dim iWhichInput As Integer
  1247.     Dim sLine As String
  1248.     Dim iCount As Integer
  1249.     Dim in$
  1250.  
  1251.     ' INITIALIZE
  1252.     InitKeyboardButtonCodes
  1253.  
  1254.     ' OUTPUT MAPPING
  1255.     Print "Controller mapping:"
  1256.     Print "Player#  Input      Device#  Type     Code     Value"
  1257.     '      1        button #2  x        unknown  x        x
  1258.     '      9        11         9        9        9        9
  1259.     '      12345678912345678901123456789123456789123456789123456789
  1260.     '      12345678901234567890123456789012345678901234567890123456789012345678901234567890
  1261.     For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  1262.         iCount = 0
  1263.         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1264.             If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1265.                 iCount = iCount + 1
  1266.             End If
  1267.         Next iWhichInput
  1268.         If iCount > 0 Then
  1269.             For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1270.                 If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1271.                     sLine = IntPadRight$(iPlayer, 9)
  1272.                     sLine = sLine + StrPadRight$(InputToString$(iWhichInput), 11)
  1273.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).device, 9)
  1274.                     sLine = sLine + StrPadRight$(InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ), 9)
  1275.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 9)
  1276.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).value, 9)
  1277.                     Print sLine
  1278.                 End If
  1279.             Next iWhichInput
  1280.         Else
  1281.             sLine = IntPadRight$(iPlayer, 9) + "(NONE)"
  1282.             Print sLine
  1283.         End If
  1284.     Next iPlayer
  1285. End Sub ' PrintControllerMap1
  1286.  
  1287. ' /////////////////////////////////////////////////////////////////////////////
  1288. ' Simple routine
  1289. ' enables debugging, prints to debug window
  1290. ' when done disables debugging (if it was disabled to begin with)
  1291.  
  1292. Sub DumpControllerMap1
  1293.     Dim RoutineName As String:: RoutineName = "DumpControllerMap1"
  1294.     Dim iPlayer As Integer
  1295.     Dim iWhichInput As Integer
  1296.     Dim sLine As String
  1297.     Dim iCount As Integer
  1298.     Dim in$
  1299.     Dim bTesting As Integer
  1300.  
  1301.     ' ENABLE DEEBUGGING (IF NOT ENABLED)
  1302.     bTesting = m_bTesting
  1303.  
  1304.     ' ACTIVATE DEBUGGING WINDOW (IF NOT ACTIVATED)
  1305.     If m_bTesting = FALSE Then
  1306.         m_bTesting = TRUE
  1307.  
  1308.         $Console
  1309.         _Delay 4
  1310.         _Console On
  1311.         _Echo "Started " + m_ProgramName$
  1312.         _Echo "Debugging on..."
  1313.     End If
  1314.  
  1315.     ' INITIALIZE
  1316.     InitKeyboardButtonCodes
  1317.  
  1318.     ' OUTPUT MAPPING
  1319.     DebugPrint "Controller mapping:"
  1320.     DebugPrint "Player#  Input      Device#  Type     Code     Value"
  1321.     '      1        button #2  x        unknown  x        x
  1322.     '      9        11         9        9        9        9
  1323.     '      12345678912345678901123456789123456789123456789123456789
  1324.     '      12345678901234567890123456789012345678901234567890123456789012345678901234567890
  1325.     For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  1326.         iCount = 0
  1327.         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1328.             If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1329.                 iCount = iCount + 1
  1330.             End If
  1331.         Next iWhichInput
  1332.         If iCount > 0 Then
  1333.             For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1334.                 If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1335.                     sLine = IntPadRight$(iPlayer, 9)
  1336.                     sLine = sLine + StrPadRight$(InputToString$(iWhichInput), 11)
  1337.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).device, 9)
  1338.                     sLine = sLine + StrPadRight$(InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ), 9)
  1339.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).code, 9)
  1340.                     sLine = sLine + IntPadRight$(m_arrControlMap(iPlayer, iWhichInput).value, 9)
  1341.                     DebugPrint sLine
  1342.                 End If
  1343.             Next iWhichInput
  1344.         Else
  1345.             sLine = IntPadRight$(iPlayer, 9) + "(NONE)"
  1346.             DebugPrint sLine
  1347.         End If
  1348.     Next iPlayer
  1349.  
  1350.     ' WAIT FOR USER
  1351.     Cls
  1352.     Print "Controller mapping written to console window."
  1353.     Input "PRESS <ENTER> TO CONTINUE"; in$
  1354.  
  1355.     ' DEACTIVATE DEBUGGING WINDOW (IF IT WAS NOT ACTIVATED BEFORE)
  1356.     If bTesting = FALSE Then
  1357.         m_bTesting = FALSE
  1358.  
  1359.         _Console Off
  1360.     End If
  1361.  
  1362. End Sub ' DumpControllerMap1
  1363.  
  1364. ' /////////////////////////////////////////////////////////////////////////////
  1365.  
  1366. Function LoadMappings1$
  1367.     Dim sResult As String: sResult = ""
  1368.  
  1369.     ' INITIALIZE
  1370.     InitKeyboardButtonCodes
  1371.  
  1372.     ' Try loading map
  1373.     sResult = LoadControllerMap1$
  1374.  
  1375.     LoadMappings1$ = sResult
  1376. End Function ' LoadMappings1$
  1377.  
  1378. ' /////////////////////////////////////////////////////////////////////////////
  1379.  
  1380. Function SaveMappings1$
  1381.     Dim sResult As String: sResult = ""
  1382.     Dim sError As String: sError = ""
  1383.  
  1384.     ' INITIALIZE
  1385.     InitKeyboardButtonCodes
  1386.  
  1387.     ' Try saving map
  1388.     sResult = SaveControllerMap1$
  1389.  
  1390.     SaveMappings1$ = sResult
  1391. End Function ' SaveMappings1$
  1392.  
  1393.  
  1394. ' /////////////////////////////////////////////////////////////////////////////
  1395.  
  1396. Function ViewMappings2$
  1397.     ' INITIALIZE
  1398.     InitKeyboardButtonCodes
  1399.  
  1400.     PrintControllerMap2
  1401.     Print
  1402.     Input "PRESS <ENTER> TO CONTINUE", in$
  1403.     Print
  1404.     ViewMappings2$ = ""
  1405. End Function ' ViewMappings2$
  1406.  
  1407. ' /////////////////////////////////////////////////////////////////////////////
  1408. ' TODO: test this
  1409.  
  1410. Function EditMappings1$
  1411.     Dim RoutineName As String: RoutineName = "EditMappings1$"
  1412.     Dim in$
  1413.     Dim iPlayer As Integer
  1414.     Dim iWhichInput As Integer
  1415.     Dim iDevice As Integer
  1416.     Dim iType As Integer
  1417.     Dim iCode As Integer
  1418.     Dim iValue As Integer
  1419.     Dim iRepeat As Integer
  1420.     Dim iItem As Integer
  1421.     Dim sResult As String: sResult = ""
  1422.     Dim bContinue1 As Integer: bContinue1 = TRUE
  1423.     Dim bContinue2 As Integer: bContinue2 = TRUE
  1424.     Dim bContinue3 As Integer: bContinue3 = TRUE
  1425.     Dim bContinue4 As Integer: bContinue4 = TRUE
  1426.  
  1427.     ' INITIALIZE
  1428.     InitKeyboardButtonCodes
  1429.  
  1430.     ' EDIT
  1431.     Do
  1432.         PrintControllerMap2
  1433.         Print "To edit a mapping, enter a player number: " _
  1434.             "1-" + cstr$(cMaxPlayers) + ", " + _
  1435.             cstr$(cMaxPlayers+1) + ") or q to exit."
  1436.         Input "Edit mapping for player"; in$
  1437.         If IsNum%(in$) Then
  1438.             iPlayer = Val(in$)
  1439.             If iPlayer > 0 And iPlayer <= cMaxPlayers Then
  1440.                 bContinue2 = TRUE
  1441.                 Do
  1442.                     Print "Editing mappings for player " + cstr$(iPlayer) + "."
  1443.                     For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1444.                         'Print right$("  " + cstr$(iWhichInput), 2) + ". " + InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ)
  1445.                         Print Right$("  " + cstr$(iWhichInput), 2) + ". " + InputToString$(iWhichInput)
  1446.                     Next iWhichInput
  1447.                     Input "Type # of control to edit or q to quit editing player"; in$
  1448.                     If IsNum%(in$) Then
  1449.                         iWhichInput = Val(in$)
  1450.                         If iWhichInput >= LBound(m_arrControlMap, 2) And m_arrControlMap <= UBound(m_arrControlMap, 2) Then
  1451.                             bContinue3 = TRUE
  1452.                             Do
  1453.                                 Print "Settings for " + InputToString$(iWhichInput) + ":"
  1454.                                 Print "1. Device #     : " + cstr$(m_arrControlMap(iPlayer, iWhichInput).device)
  1455.                                 Print "2. Device type  : " + InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ)
  1456.  
  1457.                                 If m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey Then
  1458.                                     Print "3. Input code   : " + GetKeyboardButtonCodeText$(m_arrControlMap(iPlayer, iWhichInput).code) + _
  1459.                                         " (" + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).code)) + ")"
  1460.                                 Else
  1461.                                     Print "3. Input code   : " + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).code))
  1462.                                 End If
  1463.  
  1464.                                 Print "4. Input value  : " + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).value))
  1465.                                 Print "5. Enable repeat: " + TrueFalse$(m_arrControlMap(iPlayer, iWhichInput).repeat)
  1466.                                 Input "Change item? (1-5 or q to quit editing control)"; in$
  1467.                                 If IsNum%(in$) Then
  1468.                                     iItem = Val(in$)
  1469.                                     Select Case iItem
  1470.                                         Case 1:
  1471.                                             Print "Change the device number."
  1472.                                             Input "Type a new device #, 0 for none (disabled), or blank to leave it unchanged"; in$
  1473.                                             If IsNum%(in$) Then
  1474.                                                 iDevice = Val(in$)
  1475.                                                 m_arrControlMap(iPlayer, iWhichInput).device = iDevice
  1476.                                                 Print "Updated device number. Remember to save mappings when done."
  1477.                                             Else
  1478.                                                 Print "(No change.)"
  1479.                                             End If
  1480.                                         Case 2:
  1481.                                             bContinue4 = TRUE
  1482.                                             Do
  1483.                                                 Print "Change the device type."
  1484.                                                 Print cstr$(cInputKey) + "=keyboard"
  1485.                                                 Print cstr$(cInputButton) + "=game controller button"
  1486.                                                 Print cstr$(cInputAxis) + "=game controller joystick/axis"
  1487.                                                 Print cstr$(cInputNone) + "=none"
  1488.                                                 Input "Device type or blank to leave it unchanged"; in$
  1489.                                                 If IsNum%(in$) Then
  1490.                                                     iType = Val(in$)
  1491.                                                     if iType=cInputKey or iType=cInputButton or _
  1492.                                                         iType=cInputAxis or iType=cInputNone then
  1493.  
  1494.                                                         m_arrControlMap(iPlayer, iWhichInput).typ = iType
  1495.                                                         Print "Updated device type. Remember to save mappings when done."
  1496.                                                         bContinue4 = FALSE: Exit Do
  1497.                                                     Else
  1498.                                                         Print "Please choose one of the listed values."
  1499.                                                     End If
  1500.                                                 Else
  1501.                                                     Print "(No change.)"
  1502.                                                     bContinue4 = FALSE: Exit Do
  1503.                                                 End If
  1504.                                             Loop Until bContinue4 = FALSE
  1505.                                         Case 3:
  1506.                                             Print "Change the input code."
  1507.                                             Input "Type a new input code, or blank to leave it unchanged"; in$
  1508.                                             If IsNum%(in$) Then
  1509.                                                 iCode = Val(in$)
  1510.                                                 m_arrControlMap(iPlayer, iWhichInput).code = iCode
  1511.                                                 Print "Updated input code. Remember to save mappings when done."
  1512.                                             Else
  1513.                                                 Print "(No change.)"
  1514.                                             End If
  1515.                                         Case 4:
  1516.                                             Print "Change the input value."
  1517.                                             Input "Type a new input value, or blank to leave it unchanged"; in$
  1518.                                             If IsNum%(in$) Then
  1519.                                                 iValue = Val(in$)
  1520.                                                 m_arrControlMap(iPlayer, iWhichInput).value = iValue
  1521.                                                 Print "Updated input value. Remember to save mappings when done."
  1522.                                             Else
  1523.                                                 Print "(No change.)"
  1524.                                             End If
  1525.                                         Case 5:
  1526.                                             Print "Change the repeat setting."
  1527.                                             Input "Type 1 to enable or 0 to disable, or blank to leave it unchanged"; in$
  1528.                                             If IsNum%(in$) Then
  1529.                                                 iRepeat = Val(in$)
  1530.                                                 If iRepeat = 0 Then
  1531.                                                     m_arrControlMap(iPlayer, iWhichInput).repeat = FALSE
  1532.                                                     Print "Repeat disabled. Remember to save mappings when done."
  1533.                                                 ElseIf iRepeat = 1 Then
  1534.                                                     m_arrControlMap(iPlayer, iWhichInput).repeat = TRUE
  1535.                                                     Print "Repeat enabled. Remember to save mappings when done."
  1536.                                                 Else
  1537.                                                     Print "(No change.)"
  1538.                                                 End If
  1539.                                             Else
  1540.                                                 Print "(No change.)"
  1541.                                             End If
  1542.                                         Case Else:
  1543.                                             Print "Please choose a number between 1 and 4."
  1544.                                     End Select
  1545.                                 Else
  1546.                                     bContinue3 = FALSE: Exit Do
  1547.                                 End If
  1548.                             Loop Until bContinue3 = FALSE
  1549.                         Else
  1550.                             Print "Please choose a number between " + cstr$(LBound(m_arrControlMap, 2)) + " and " + cstr$(UBound(m_arrControlMap, 2)) + "."
  1551.                         End If
  1552.                     Else
  1553.                         bContinue2 = FALSE: Exit Do
  1554.                     End If
  1555.                 Loop Until bContinue2 = FALSE
  1556.                 If bContinue1 = FALSE Then Exit Do
  1557.             Else
  1558.                 Print "Please choose a number between 1 and " + cstr$(cMaxPlayers) + "."
  1559.             End If
  1560.         Else
  1561.             If Len(sResult) = 0 Then sResult = "(Cancelled.)"
  1562.             bContinue1 = FALSE: Exit Do
  1563.         End If
  1564.     Loop Until bContinue1 = FALSE
  1565.  
  1566.     _KeyClear: _Delay 1
  1567.  
  1568.     EditMappings1$ = sResult
  1569. End Function ' EditMappings1$
  1570.  
  1571. ' /////////////////////////////////////////////////////////////////////////////
  1572.  
  1573. Function ResetMapping1$
  1574.     Dim RoutineName As String: RoutineName = "ResetMapping1$"
  1575.     Dim in$
  1576.     Dim iPlayer As Integer
  1577.     Dim sResult As String: sResult = ""
  1578.  
  1579.     ' INITIALIZE
  1580.     InitKeyboardButtonCodes
  1581.  
  1582.     ' RESET
  1583.     Do
  1584.         PrintControllerMap2
  1585.  
  1586.         Print "To delete mapping, enter a player number: " _
  1587.             "1-" + cstr$(cMaxPlayers) + ", " + _
  1588.             cstr$(cMaxPlayers+1) + " for all, or 0 to exit."
  1589.         Input "Delete mapping for player? "; iPlayer
  1590.  
  1591.         If iPlayer > 0 And iPlayer <= cMaxPlayers Then
  1592.             Print "Delete mappings for player " + cstr$(iPlayer) + "."
  1593.             Input "Delete (y/n)"; in$: in$ = LCase$(_Trim$(in$))
  1594.             If in$ = "y" Then
  1595.                 For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1596.                     If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1597.                         m_arrControlMap(iPlayer, iWhichInput).device = 0
  1598.                         m_arrControlMap(iPlayer, iWhichInput).typ = 0
  1599.                         m_arrControlMap(iPlayer, iWhichInput).code = 0
  1600.                         m_arrControlMap(iPlayer, iWhichInput).value = 0
  1601.                         m_arrControlMap(iPlayer, iWhichInput).repeat = 0 ' GetGlobalInputRepeatSetting%(iWhichInput)
  1602.                     End If
  1603.                 Next iWhichInput
  1604.                 sResult = "Mappings deleted for player " + cstr$(iPlayer) + "."
  1605.                 Print sResult
  1606.             End If
  1607.         ElseIf iPlayer = (cMaxPlayers + 1) Then
  1608.             Input "Delete all mappings (y/n)"; in$: in$ = LCase$(_Trim$(in$))
  1609.             If in$ = "y" Then
  1610.                 For iPlayer = 1 To cMaxPlayers
  1611.                     For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  1612.                         If InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) <> "unknown" Then
  1613.                             m_arrControlMap(iPlayer, iWhichInput).device = 0
  1614.                             m_arrControlMap(iPlayer, iWhichInput).typ = 0
  1615.                             m_arrControlMap(iPlayer, iWhichInput).code = 0
  1616.                             m_arrControlMap(iPlayer, iWhichInput).value = 0
  1617.                             m_arrControlMap(iPlayer, iWhichInput).repeat = 0 ' GetGlobalInputRepeatSetting%(iWhichInput)
  1618.                         End If
  1619.                     Next iWhichInput
  1620.                 Next iPlayer
  1621.                 sResult = "All mappings deleted."
  1622.                 Print sResult
  1623.             End If
  1624.         Else
  1625.             If Len(sResult) = 0 Then sResult = "(Cancelled.)"
  1626.             Exit Do
  1627.         End If
  1628.     Loop
  1629.     ResetMapping1$ = sResult
  1630. End Function ' ResetMapping1$
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.  
  1654.  
  1655.  
  1656. ' /////////////////////////////////////////////////////////////////////////////
  1657.  
  1658. ' Usage:
  1659. ' Dim StringArray(1 To 48, 1 To 128) As String
  1660. ' StringToArray StringArray(), GetMap$
  1661.  
  1662. ' version 2 with indexed array(row, columm)
  1663.  
  1664. Sub StringToArray (MyArray() As String, MyString As String)
  1665.     Dim sDelim As String
  1666.     ReDim arrLines(0) As String
  1667.     Dim iRow As Integer
  1668.     Dim iCol As Integer
  1669.     Dim sChar As String
  1670.     Dim iDim1 As Integer
  1671.     Dim iDim2 As Integer
  1672.     Dim iIndex1 As Integer
  1673.     Dim iIndex2 As Integer
  1674.  
  1675.     iDim1 = LBound(MyArray, 1)
  1676.     iDim2 = LBound(MyArray, 2)
  1677.     sDelim = Chr$(13)
  1678.     split MyString, sDelim, arrLines()
  1679.     For iRow = LBound(arrLines) To UBound(arrLines)
  1680.         If iRow <= UBound(MyArray, 1) Then
  1681.             For iCol = 1 To Len(arrLines(iRow))
  1682.                 If iCol <= UBound(MyArray, 2) Then
  1683.                     sChar = Mid$(arrLines(iRow), iCol, 1)
  1684.  
  1685.                     If Len(sChar) > 1 Then
  1686.                         sChar = Left$(sChar, 1)
  1687.                     Else
  1688.                         If Len(sChar) = 0 Then
  1689.                             sChar = "."
  1690.                         End If
  1691.                     End If
  1692.  
  1693.                     iIndex1 = iRow + iDim1
  1694.                     iIndex2 = (iCol - 1) + iDim2
  1695.                     MyArray(iIndex1, iIndex2) = sChar
  1696.                     'DebugPrint "MyArray(" + cstr$(iIndex1) + ", " + cstr$(iIndex2) + " = " + chr$(34) + sChar + chr$(34)
  1697.                 Else
  1698.                     ' Exit if out of bounds
  1699.                     Exit For
  1700.                 End If
  1701.             Next iCol
  1702.         Else
  1703.             ' Exit if out of bounds
  1704.             Exit For
  1705.         End If
  1706.     Next iRow
  1707. End Sub ' StringToArray
  1708.  
  1709. ' /////////////////////////////////////////////////////////////////////////////
  1710. ' Size of array:
  1711. '
  1712. ' Resolution    Cols   Rows
  1713. ' 1024 x  768   128    48
  1714.  
  1715. ' 48 total available # of rows
  1716. ' -2 rows for title
  1717. ' -1 row for headings
  1718. ' -1 for player #1 info
  1719. ' -1 for player #2 info
  1720. ' -1 for player #3 info
  1721. ' -1 for player #4 info
  1722. ' -- --------------------------
  1723. ' 41 rows available
  1724.  
  1725. Function GetMap$
  1726.     Dim m$
  1727.     m$ = ""
  1728.     '                                                                                                             11111111111111111111111111111
  1729.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1730.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1731.     m$ = m$ + "         CONTROLLER #1         #                               #                               #                               X" + Chr$(13) ' 1
  1732.     m$ = m$ + "               UP              #                               #                               #                               #" + Chr$(13) ' 2
  1733.     m$ = m$ + "        button dev  10         #                               #                               #                               #" + Chr$(13) ' 3
  1734.     m$ = m$ + "        code 329 rep=Y         #                               #                               #                               #" + Chr$(13) ' 4
  1735.     m$ = m$ + "        value       -1         #                               #                               #                               #" + Chr$(13) ' 5
  1736.     m$ = m$ + " LEFT           RIGHT          #                               #                               #                               #" + Chr$(13) ' 6
  1737.     m$ = m$ + " button dev  10 button dev  10 #                               #                               #                               #" + Chr$(13) ' 7
  1738.     m$ = m$ + " code 332 rep=N code 334 rep=N #                               #                               #                               #" + Chr$(13) ' 8
  1739.     m$ = m$ + " value       -1 value       -1 #                               #                               #                               #" + Chr$(13) ' 9
  1740.     m$ = m$ + "              DOWN             #                               #                               #                               #" + Chr$(13) ' 10
  1741.     m$ = m$ + "        button dev= 10         #                               #                               #                               #" + Chr$(13) ' 11
  1742.     m$ = m$ + "        code 337 rep=Y         #                               #                               #                               #" + Chr$(13) ' 12
  1743.     m$ = m$ + "        value=      -1         #                               #                               #                               #" + Chr$(13) ' 13
  1744.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 14
  1745.     m$ = m$ + " BUTTON #1      BUTTON #3      #                               #                               #                               #" + Chr$(13) ' 15
  1746.     m$ = m$ + " button dev   1 none   dev   0 #                               #                               #                               #" + Chr$(13) ' 16
  1747.     m$ = m$ + " code 286 rep=N code     rep=N #                               #                               #                               #" + Chr$(13) ' 17
  1748.     m$ = m$ + " value       -1 value        0 #                               #                               #                               #" + Chr$(13) ' 18
  1749.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 19
  1750.     m$ = m$ + " BUTTON #2      BUTTON #4      #                               #                               #                               #" + Chr$(13) ' 20
  1751.     m$ = m$ + " none   dev   0 none   dev   0 #                               #                               #                               #" + Chr$(13) ' 21
  1752.     m$ = m$ + " code     rep=N code     rep=N #                               #                               #                               #" + Chr$(13) ' 22
  1753.     m$ = m$ + " value        0 value        0 #                               #                               #                               #" + Chr$(13) ' 23
  1754.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 24
  1755.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 25
  1756.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 26
  1757.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 27
  1758.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 28
  1759.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 29
  1760.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 30
  1761.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 31
  1762.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 32
  1763.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 33
  1764.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 34
  1765.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 35
  1766.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 36
  1767.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 37
  1768.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 38
  1769.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 39
  1770.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 40
  1771.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 41
  1772.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 42
  1773.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 43
  1774.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 44
  1775.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 45
  1776.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 46
  1777.     m$ = m$ + "c                              #                               #                               #                               #" + Chr$(13) ' 47
  1778.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 48
  1779.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1780.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1781.     '                                                                                                             11111111111111111111111111111
  1782.     GetMap$ = m$
  1783. End Function ' GetMap$
  1784.  
  1785. Function GetMap2$
  1786.     Dim m$
  1787.     m$ = ""
  1788.     '                                                                                                             11111111111111111111111111111
  1789.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1790.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1791.     m$ = m$ + "         CONTROLLER #1         #                               #                               #                               #" + Chr$(13) ' 1
  1792.     m$ = m$ + "             UP                #                               #                               #                               #" + Chr$(13) ' 2
  1793.     m$ = m$ + "      button dev  10           #                               #                               #                               #" + Chr$(13) ' 3
  1794.     m$ = m$ + "      code 329 rep=Y           #                               #                               #                               #" + Chr$(13) ' 4
  1795.     m$ = m$ + "      value       -1           #                               #                               #                               #" + Chr$(13) ' 5
  1796.     m$ = m$ + " LEFT           RIGHT          #                               #                               #                               #" + Chr$(13) ' 6
  1797.     m$ = m$ + " button dev  10 button dev  10 #                               #                               #                               #" + Chr$(13) ' 7
  1798.     m$ = m$ + " code 332 rep=N code 334 rep=N #                               #                               #                               #" + Chr$(13) ' 8
  1799.     m$ = m$ + " value       -1 value       -1 #                               #                               #                               #" + Chr$(13) ' 9
  1800.     m$ = m$ + "            DOWN               #                               #                               #                               #" + Chr$(13) ' 10
  1801.     m$ = m$ + "      button dev= 10           #                               #                               #                               #" + Chr$(13) ' 11
  1802.     m$ = m$ + "      code 337 rep=Y           #                               #                               #                               #" + Chr$(13) ' 12
  1803.     m$ = m$ + "      value=      -1           #                               #                               #                               #" + Chr$(13) ' 13
  1804.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 14
  1805.     m$ = m$ + " BUTTON #1      BUTTON #3      #                               #                               #                               #" + Chr$(13) ' 15
  1806.     m$ = m$ + " button dev   1 none   dev   0 #                               #                               #                               #" + Chr$(13) ' 16
  1807.     m$ = m$ + " code 286 rep=N code     rep=N #                               #                               #                               #" + Chr$(13) ' 17
  1808.     m$ = m$ + " value       -1 value        0 #                               #                               #                               #" + Chr$(13) ' 18
  1809.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 19
  1810.     m$ = m$ + " BUTTON #2      BUTTON #4      #                               #                               #                               #" + Chr$(13) ' 20
  1811.     m$ = m$ + " none   dev   0 none   dev   0 #                               #                               #                               #" + Chr$(13) ' 21
  1812.     m$ = m$ + " code     rep=N code     rep=N #                               #                               #                               #" + Chr$(13) ' 22
  1813.     m$ = m$ + " value        0 value        0 #                               #                               #                               #" + Chr$(13) ' 23
  1814.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 24
  1815.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 25
  1816.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 26
  1817.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 27
  1818.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 28
  1819.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 29
  1820.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 30
  1821.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 31
  1822.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 32
  1823.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 33
  1824.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 34
  1825.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 35
  1826.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 36
  1827.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 37
  1828.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 38
  1829.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 39
  1830.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 40
  1831.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 41
  1832.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 42
  1833.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 43
  1834.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 44
  1835.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 45
  1836.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 46
  1837.     m$ = m$ + "                               #                               #                               #                               #" + Chr$(13) ' 47
  1838.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 48
  1839.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1840.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1841.     '                                                                                                             11111111111111111111111111111
  1842.     GetMap2$ = m$
  1843. End Function ' GetMap2$
  1844.  
  1845. Function GetMap1$
  1846.     Dim m$
  1847.     m$ = ""
  1848.     '                                                                                                             11111111111111111111111111111
  1849.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1850.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1851.     m$ = m$ + ".........CONTROLLER.#1.........#...............................#...............................#...............................#" + Chr$(13) ' 1
  1852.     m$ = m$ + ".............UP................#...............................#...............................#...............................#" + Chr$(13) ' 2
  1853.     m$ = m$ + "......button.dev..10...........#...............................#...............................#...............................#" + Chr$(13) ' 3
  1854.     m$ = m$ + "......code.329.rep=Y...........#...............................#...............................#...............................#" + Chr$(13) ' 4
  1855.     m$ = m$ + "......value.......-1...........#...............................#...............................#...............................#" + Chr$(13) ' 5
  1856.     m$ = m$ + ".LEFT...........RIGHT..........#...............................#...............................#...............................#" + Chr$(13) ' 6
  1857.     m$ = m$ + ".button.dev..10.button.dev..10.#...............................#...............................#...............................#" + Chr$(13) ' 7
  1858.     m$ = m$ + ".code.332.rep=N.code.334.rep=N.#...............................#...............................#...............................#" + Chr$(13) ' 8
  1859.     m$ = m$ + ".value.......-1.value.......-1.#...............................#...............................#...............................#" + Chr$(13) ' 9
  1860.     m$ = m$ + "............DOWN...............#...............................#...............................#...............................#" + Chr$(13) ' 10
  1861.     m$ = m$ + "......button.dev=.10...........#...............................#...............................#...............................#" + Chr$(13) ' 11
  1862.     m$ = m$ + "......code.337.rep=Y...........#...............................#...............................#...............................#" + Chr$(13) ' 12
  1863.     m$ = m$ + "......value=......-1...........#...............................#...............................#...............................#" + Chr$(13) ' 13
  1864.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 14
  1865.     m$ = m$ + ".BUTTON.#1......BUTTON.#3......#...............................#...............................#...............................#" + Chr$(13) ' 15
  1866.     m$ = m$ + ".button.dev...1.none...dev...0.#...............................#...............................#...............................#" + Chr$(13) ' 16
  1867.     m$ = m$ + ".code.286.rep=N.code.....rep=N.#...............................#...............................#...............................#" + Chr$(13) ' 17
  1868.     m$ = m$ + ".value.......-1.value........0.#...............................#...............................#...............................#" + Chr$(13) ' 18
  1869.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 19
  1870.     m$ = m$ + ".BUTTON.#2......BUTTON.#4......#...............................#...............................#...............................#" + Chr$(13) ' 20
  1871.     m$ = m$ + ".none...dev...0.none...dev...0.#...............................#...............................#...............................#" + Chr$(13) ' 21
  1872.     m$ = m$ + ".code.....rep=N.code.....rep=N.#...............................#...............................#...............................#" + Chr$(13) ' 22
  1873.     m$ = m$ + ".value........0.value........0.#...............................#...............................#...............................#" + Chr$(13) ' 23
  1874.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 24
  1875.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 25
  1876.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 26
  1877.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 27
  1878.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 28
  1879.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 29
  1880.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 30
  1881.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 31
  1882.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 32
  1883.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 33
  1884.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 34
  1885.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 35
  1886.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 36
  1887.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 37
  1888.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 38
  1889.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 39
  1890.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 40
  1891.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 41
  1892.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 42
  1893.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 43
  1894.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 44
  1895.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 45
  1896.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 46
  1897.     m$ = m$ + "...............................#...............................#...............................#...............................#" + Chr$(13) ' 47
  1898.     m$ = m$ + "################################################################################################################################" + Chr$(13) ' 48
  1899.     '          12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
  1900.     '                   11111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222
  1901.     '                                                                                                             11111111111111111111111111111
  1902.     GetMap1$ = m$
  1903. End Function ' GetMap1$
  1904.  
  1905. ' /////////////////////////////////////////////////////////////////////////////
  1906.  
  1907. Function ArrayToString$ (MyArray( 1 To 32 , 1 To 32) As String)
  1908.     Dim MyString As String
  1909.     Dim iY As Integer
  1910.     Dim iX As Integer
  1911.     Dim sLine As String
  1912.     MyString = ""
  1913.     For iY = LBound(MyArray, 1) To UBound(MyArray, 1)
  1914.         sLine = ""
  1915.         For iX = LBound(MyArray, 2) To UBound(MyArray, 2)
  1916.             sLine = sLine + MyArray(iY, iX)
  1917.         Next iX
  1918.         MyString = MyString + sLine + Chr$(13)
  1919.     Next iY
  1920.     ArrayToString$ = MyString
  1921. End Function ' ArrayToString$
  1922.  
  1923. ' /////////////////////////////////////////////////////////////////////////////
  1924.  
  1925. Function ArrayToStringTest$ (MyArray() As String)
  1926.     Dim MyString As String
  1927.     Dim iY As Integer
  1928.     Dim iX As Integer
  1929.     Dim sLine As String
  1930.     MyString = ""
  1931.  
  1932.     MyString = MyString + "           11111111112222222222333" + Chr$(13)
  1933.     MyString = MyString + "  12345678901234567890123456789012" + Chr$(13)
  1934.     For iY = LBound(MyArray, 1) To UBound(MyArray, 1)
  1935.         sLine = ""
  1936.         sLine = sLine + Right$("  " + cstr$(iY), 2)
  1937.         For iX = LBound(MyArray, 2) To UBound(MyArray, 2)
  1938.             sLine = sLine + MyArray(iY, iX)
  1939.         Next iX
  1940.         sLine = sLine + Right$("  " + cstr$(iY), 2)
  1941.         MyString = MyString + sLine + Chr$(13)
  1942.     Next iY
  1943.     MyString = MyString + "  12345678901234567890123456789012" + Chr$(13)
  1944.     MyString = MyString + "           11111111112222222222333" + Chr$(13)
  1945.     ArrayToStringTest$ = MyString
  1946. End Function ' ArrayToStringTest$
  1947.  
  1948.  
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971. ' /////////////////////////////////////////////////////////////////////////////
  1972.  
  1973. Sub AddScreenArea (NewValue As ScreenAreaType, MyArray() As ScreenAreaType)
  1974.     ReDim _Preserve MyArray(1 To UBound(MyArray) + 1) As ScreenAreaType
  1975.     MyArray(UBound(MyArray)).item = NewValue.item
  1976.     MyArray(UBound(MyArray)).name = NewValue.name
  1977.     MyArray(UBound(MyArray)).typ = NewValue.typ
  1978.     MyArray(UBound(MyArray)).player = NewValue.player
  1979.     MyArray(UBound(MyArray)).x1 = NewValue.x1
  1980.     MyArray(UBound(MyArray)).y1 = NewValue.y1
  1981.     MyArray(UBound(MyArray)).x2 = NewValue.x2
  1982.     MyArray(UBound(MyArray)).y2 = NewValue.y2
  1983.     'MyArray(ubound(MyArray)).index = NewValue.index
  1984. End Sub ' AddScreenArea
  1985.  
  1986. ' /////////////////////////////////////////////////////////////////////////////
  1987.  
  1988. Sub AddTextButton (NewValue As TextButtonType, MyArray() As TextButtonType)
  1989.     ReDim _Preserve MyArray(1 To UBound(MyArray) + 1) As TextButtonType
  1990.     MyArray(UBound(MyArray)).item = NewValue.item
  1991.     MyArray(UBound(MyArray)).typ = NewValue.typ
  1992.     MyArray(UBound(MyArray)).x1 = NewValue.x1
  1993.     MyArray(UBound(MyArray)).y1 = NewValue.y1
  1994.     MyArray(UBound(MyArray)).x2 = NewValue.x2
  1995.     MyArray(UBound(MyArray)).y2 = NewValue.y2
  1996.     'MyArray(ubound(MyArray)).index = NewValue.index
  1997. End Sub ' AddTextButton
  1998.  
  1999. ' /////////////////////////////////////////////////////////////////////////////
  2000.  
  2001. Sub AddTextLabel (NewValue As TextLabelType, MyArray() As TextLabelType)
  2002.     ReDim _Preserve MyArray(1 To UBound(MyArray) + 1) As TextLabelType
  2003.     MyArray(UBound(MyArray)).item = NewValue.item
  2004.     MyArray(UBound(MyArray)).name = NewValue.name
  2005.     MyArray(UBound(MyArray)).row = NewValue.row
  2006.     MyArray(UBound(MyArray)).column = NewValue.column
  2007.     MyArray(UBound(MyArray)).width = NewValue.width
  2008.     MyArray(UBound(MyArray)).justify = NewValue.justify
  2009.     MyArray(UBound(MyArray)).caption = NewValue.caption
  2010.     MyArray(UBound(MyArray)).fgcolor = NewValue.fgcolor
  2011.     MyArray(UBound(MyArray)).bgcolor = NewValue.bgcolor
  2012.     'MyArray(ubound(MyArray)).index = NewValue.index
  2013. End Sub ' AddTextLabel
  2014.  
  2015. ' /////////////////////////////////////////////////////////////////////////////
  2016.  
  2017. Sub AddTextField (NewValue As TextFieldType, MyArray() As TextFieldType)
  2018.     ReDim _Preserve MyArray(1 To UBound(MyArray) + 1) As TextFieldType
  2019.     MyArray(UBound(MyArray)).item = NewValue.item
  2020.     MyArray(UBound(MyArray)).name = NewValue.name
  2021.     MyArray(UBound(MyArray)).row = NewValue.row
  2022.     MyArray(UBound(MyArray)).column = NewValue.column
  2023.     MyArray(UBound(MyArray)).width = NewValue.width
  2024.     MyArray(UBound(MyArray)).justify = NewValue.justify
  2025.     MyArray(UBound(MyArray)).value = NewValue.value
  2026.     MyArray(UBound(MyArray)).fgcolor = NewValue.fgcolor
  2027.     MyArray(UBound(MyArray)).bgcolor = NewValue.bgcolor
  2028.     'MyArray(ubound(MyArray)).index = NewValue.index
  2029. End Sub ' AddTextField
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046. ' /////////////////////////////////////////////////////////////////////////////
  2047.  
  2048. Sub SetupScreenAreas
  2049.     Dim NewScreenArea As ScreenAreaType
  2050.     Dim x1 As Integer
  2051.     Dim y1 As Integer
  2052.     Dim x2 As Integer
  2053.     Dim y2 As Integer
  2054.  
  2055.     x1 = 1
  2056.     y1 = 1
  2057.    
  2058.     NewScreenArea.item = "Control1"
  2059.     NewScreenArea.name = "Controller #1"
  2060.     NewScreenArea.typ = cTextGuiSection
  2061.     NewScreenArea.player = 1
  2062.     NewScreenArea.x1 = x1
  2063.     NewScreenArea.y1 = y1
  2064.     NewScreenArea.x2 = x1 + 30
  2065.     NewScreenArea.y2 = y1 + 22
  2066.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2067.  
  2068.     x1 = x1 + 32
  2069.  
  2070.     NewScreenArea.item = "Control2"
  2071.     NewScreenArea.name = "Controller #2"
  2072.     NewScreenArea.typ = cTextGuiSection
  2073.     NewScreenArea.player = 2
  2074.     NewScreenArea.x1 = x1
  2075.     NewScreenArea.y1 = y1
  2076.     NewScreenArea.x2 = x1 + 30
  2077.     NewScreenArea.y2 = y1 + 22
  2078.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2079.  
  2080.     x1 = x1 + 32
  2081.  
  2082.     NewScreenArea.item = "Control3"
  2083.     NewScreenArea.name = "Controller #3"
  2084.     NewScreenArea.typ = cTextGuiSection
  2085.     NewScreenArea.player = 3
  2086.     NewScreenArea.x1 = x1
  2087.     NewScreenArea.y1 = y1
  2088.     NewScreenArea.x2 = x1 + 30
  2089.     NewScreenArea.y2 = y1 + 22
  2090.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2091.  
  2092.     x1 = x1 + 32
  2093.  
  2094.     NewScreenArea.item = "Control4"
  2095.     NewScreenArea.name = "Controller #4"
  2096.     NewScreenArea.typ = cTextGuiSection
  2097.     NewScreenArea.player = 4
  2098.     NewScreenArea.x1 = x1
  2099.     NewScreenArea.y1 = y1
  2100.     NewScreenArea.x2 = x1 + 30
  2101.     NewScreenArea.y2 = y1 + 22
  2102.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2103.  
  2104.     x1 = 1
  2105.     y1 = y1 + 24
  2106.  
  2107.     NewScreenArea.item = "Control5"
  2108.     NewScreenArea.name = "Controller #5"
  2109.     NewScreenArea.typ = cTextGuiSection
  2110.     NewScreenArea.player = 5
  2111.     NewScreenArea.x1 = x1
  2112.     NewScreenArea.y1 = y1
  2113.     NewScreenArea.x2 = x1 + 30
  2114.     NewScreenArea.y2 = y1 + 22
  2115.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2116.  
  2117.     x1 = x1 + 32
  2118.  
  2119.     NewScreenArea.item = "Control6"
  2120.     NewScreenArea.name = "Controller #6"
  2121.     NewScreenArea.typ = cTextGuiSection
  2122.     NewScreenArea.player = 6
  2123.     NewScreenArea.x1 = x1
  2124.     NewScreenArea.y1 = y1
  2125.     NewScreenArea.x2 = x1 + 30
  2126.     NewScreenArea.y2 = y1 + 22
  2127.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2128.  
  2129.     x1 = x1 + 32
  2130.  
  2131.     NewScreenArea.item = "Control7"
  2132.     NewScreenArea.name = "Controller #7"
  2133.     NewScreenArea.typ = cTextGuiSection
  2134.     NewScreenArea.player = 7
  2135.     NewScreenArea.x1 = x1
  2136.     NewScreenArea.y1 = y1
  2137.     NewScreenArea.x2 = x1 + 30
  2138.     NewScreenArea.y2 = y1 + 22
  2139.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2140.  
  2141.     x1 = x1 + 32
  2142.  
  2143.     NewScreenArea.item = "Control8"
  2144.     NewScreenArea.name = "Controller #8"
  2145.     NewScreenArea.typ = cTextGuiSection
  2146.     NewScreenArea.player = 8
  2147.     NewScreenArea.x1 = x1
  2148.     NewScreenArea.y1 = y1
  2149.     NewScreenArea.x2 = x1 + 30
  2150.     NewScreenArea.y2 = y1 + 22
  2151.     AddScreenArea NewScreenArea, m_arrScreenArea()
  2152. End Sub ' SetupScreenAreas
  2153.  
  2154. ' /////////////////////////////////////////////////////////////////////////////
  2155.  
  2156. Sub SetupButtons
  2157.     Dim NewTextButton As TextButtonType
  2158.  
  2159.     NewTextButton.item = "Up"
  2160.     NewTextButton.typ = cInputUp ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2161.     NewTextButton.x1 = 9
  2162.     NewTextButton.y1 = 2
  2163.     NewTextButton.x2 = 22
  2164.     NewTextButton.y2 = 5
  2165.     AddTextButton NewTextButton, m_arrButton()
  2166.  
  2167.     NewTextButton.item = "Down"
  2168.     NewTextButton.typ = cInputDown ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2169.     NewTextButton.x1 = 9
  2170.     NewTextButton.y1 = 10
  2171.     NewTextButton.x2 = 22
  2172.     NewTextButton.y2 = 13
  2173.     AddTextButton NewTextButton, m_arrButton()
  2174.  
  2175.     NewTextButton.item = "Left"
  2176.     NewTextButton.typ = cInputLeft ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2177.     NewTextButton.x1 = 2
  2178.     NewTextButton.y1 = 6
  2179.     NewTextButton.x2 = 15
  2180.     NewTextButton.y2 = 9
  2181.     AddTextButton NewTextButton, m_arrButton()
  2182.  
  2183.     NewTextButton.item = "Right"
  2184.     NewTextButton.typ = cInputRight ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2185.     NewTextButton.x1 = 17
  2186.     NewTextButton.y1 = 6
  2187.     NewTextButton.x2 = 30
  2188.     NewTextButton.y2 = 9
  2189.     AddTextButton NewTextButton, m_arrButton()
  2190.  
  2191.     NewTextButton.item = "Button1"
  2192.     NewTextButton.typ = cInputButton1 ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2193.     NewTextButton.x1 = 2
  2194.     NewTextButton.y1 = 15
  2195.     NewTextButton.x2 = 15
  2196.     NewTextButton.y2 = 18
  2197.     AddTextButton NewTextButton, m_arrButton()
  2198.  
  2199.     NewTextButton.item = "Button2"
  2200.     NewTextButton.typ = cInputButton2 ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2201.     NewTextButton.x1 = 2
  2202.     NewTextButton.y1 = 20
  2203.     NewTextButton.x2 = 15
  2204.     NewTextButton.y2 = 23
  2205.     AddTextButton NewTextButton, m_arrButton()
  2206.  
  2207.     NewTextButton.item = "Button3"
  2208.     NewTextButton.typ = cInputButton3 ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2209.     NewTextButton.x1 = 17
  2210.     NewTextButton.y1 = 15
  2211.     NewTextButton.x2 = 30
  2212.     NewTextButton.y2 = 18
  2213.     AddTextButton NewTextButton, m_arrButton()
  2214.  
  2215.     NewTextButton.item = "Button4"
  2216.     NewTextButton.typ = cInputButton4 ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  2217.     NewTextButton.x1 = 17
  2218.     NewTextButton.y1 = 20
  2219.     NewTextButton.x2 = 30
  2220.     NewTextButton.y2 = 23
  2221.     AddTextButton NewTextButton, m_arrButton()
  2222. End Sub ' SetupButtons
  2223.  
  2224. ' /////////////////////////////////////////////////////////////////////////////
  2225.  
  2226. Sub SetupTextLabels
  2227.     Dim NewLabel As TextLabelType
  2228.     ' -----------------------------------------------------------------------------
  2229.     NewLabel.item = "Section"
  2230.     NewLabel.name = "caption"
  2231.     NewLabel.row = 1
  2232.     NewLabel.column = 1
  2233.     NewLabel.width = 31
  2234.     NewLabel.justify = cJustifyCenter
  2235.     NewLabel.caption = "CONTROLLER #{p}"
  2236.     NewLabel.fgcolor = cCyan
  2237.     NewLabel.bgcolor = cBlack
  2238.     AddTextLabel NewLabel, m_arrTextLabel()
  2239.     ' -----------------------------------------------------------------------------
  2240.     NewLabel.item = "Up"
  2241.     NewLabel.name = "caption"
  2242.     NewLabel.row = 2
  2243.     NewLabel.column = 9
  2244.     NewLabel.width = 14
  2245.     NewLabel.justify = cJustifyCenter
  2246.     NewLabel.caption = "UP"
  2247.     NewLabel.fgcolor = cYellow
  2248.     NewLabel.bgcolor = cRed
  2249.     AddTextLabel NewLabel, m_arrTextLabel()
  2250.  
  2251.     NewLabel.item = "Up"
  2252.     NewLabel.name = "type"
  2253.     NewLabel.row = 3
  2254.     NewLabel.column = 0
  2255.     NewLabel.width = -1
  2256.     NewLabel.justify = cJustifyLeft
  2257.     NewLabel.caption = ""
  2258.     NewLabel.fgcolor = cBlack
  2259.     NewLabel.bgcolor = cRed
  2260.     AddTextLabel NewLabel, m_arrTextLabel()
  2261.  
  2262.     NewLabel.item = "Up"
  2263.     NewLabel.name = "device"
  2264.     NewLabel.row = 3
  2265.     NewLabel.column = 16
  2266.     NewLabel.width = -1
  2267.     NewLabel.justify = cJustifyLeft
  2268.     NewLabel.caption = "dev "
  2269.     NewLabel.fgcolor = cBlack
  2270.     NewLabel.bgcolor = cRed
  2271.     AddTextLabel NewLabel, m_arrTextLabel()
  2272.  
  2273.     NewLabel.item = "Up"
  2274.     NewLabel.name = "code"
  2275.     NewLabel.row = 4
  2276.     NewLabel.column = 9
  2277.     NewLabel.width = -1
  2278.     NewLabel.justify = cJustifyLeft
  2279.     NewLabel.caption = "code "
  2280.     NewLabel.fgcolor = cBlack
  2281.     NewLabel.bgcolor = cRed
  2282.     AddTextLabel NewLabel, m_arrTextLabel()
  2283.  
  2284.     NewLabel.item = "Up"
  2285.     NewLabel.name = "repeat"
  2286.     NewLabel.row = 4
  2287.     NewLabel.column = 17
  2288.     NewLabel.width = -1
  2289.     NewLabel.justify = cJustifyNone
  2290.     NewLabel.caption = " rep="
  2291.     NewLabel.fgcolor = cBlack
  2292.     NewLabel.bgcolor = cRed
  2293.     AddTextLabel NewLabel, m_arrTextLabel()
  2294.  
  2295.     NewLabel.item = "Up"
  2296.     NewLabel.name = "value"
  2297.     NewLabel.row = 5
  2298.     NewLabel.column = 9
  2299.     NewLabel.width = -1
  2300.     NewLabel.justify = cJustifyNone
  2301.     NewLabel.caption = "value  "
  2302.     NewLabel.fgcolor = cBlack
  2303.     NewLabel.bgcolor = cRed
  2304.     AddTextLabel NewLabel, m_arrTextLabel()
  2305.     ' -----------------------------------------------------------------------------
  2306.     NewLabel.item = "Down"
  2307.     NewLabel.name = "caption"
  2308.     NewLabel.row = 10
  2309.     NewLabel.column = 9
  2310.     NewLabel.width = 14
  2311.     NewLabel.justify = cJustifyCenter
  2312.     NewLabel.caption = "DOWN"
  2313.     NewLabel.fgcolor = cYellow
  2314.     NewLabel.bgcolor = cGreen
  2315.     AddTextLabel NewLabel, m_arrTextLabel()
  2316.  
  2317.     NewLabel.item = "Down"
  2318.     NewLabel.name = "type"
  2319.     NewLabel.row = 11
  2320.     NewLabel.column = 0
  2321.     NewLabel.width = -1
  2322.     NewLabel.justify = cJustifyLeft
  2323.     NewLabel.caption = ""
  2324.     NewLabel.fgcolor = cBlack
  2325.     NewLabel.bgcolor = cGreen
  2326.     AddTextLabel NewLabel, m_arrTextLabel()
  2327.  
  2328.     NewLabel.item = "Down"
  2329.     NewLabel.name = "device"
  2330.     NewLabel.row = 11
  2331.     NewLabel.column = 16
  2332.     NewLabel.width = -1
  2333.     NewLabel.justify = cJustifyLeft
  2334.     NewLabel.caption = "dev "
  2335.     NewLabel.fgcolor = cBlack
  2336.     NewLabel.bgcolor = cGreen
  2337.     AddTextLabel NewLabel, m_arrTextLabel()
  2338.  
  2339.     NewLabel.item = "Down"
  2340.     NewLabel.name = "code"
  2341.     NewLabel.row = 12
  2342.     NewLabel.column = 9
  2343.     NewLabel.width = -1
  2344.     NewLabel.justify = cJustifyLeft
  2345.     NewLabel.caption = "code "
  2346.     NewLabel.fgcolor = cBlack
  2347.     NewLabel.bgcolor = cGreen
  2348.     AddTextLabel NewLabel, m_arrTextLabel()
  2349.  
  2350.     NewLabel.item = "Down"
  2351.     NewLabel.name = "repeat"
  2352.     NewLabel.row = 12
  2353.     NewLabel.column = 17
  2354.     NewLabel.width = -1
  2355.     NewLabel.justify = cJustifyLeft
  2356.     NewLabel.caption = " rep="
  2357.     NewLabel.fgcolor = cBlack
  2358.     NewLabel.bgcolor = cGreen
  2359.     AddTextLabel NewLabel, m_arrTextLabel()
  2360.  
  2361.     NewLabel.item = "Down"
  2362.     NewLabel.name = "value"
  2363.     NewLabel.row = 13
  2364.     NewLabel.column = 9
  2365.     NewLabel.width = -1
  2366.     NewLabel.justify = cJustifyLeft
  2367.     NewLabel.caption = "value  "
  2368.     NewLabel.fgcolor = cBlack
  2369.     NewLabel.bgcolor = cGreen
  2370.     AddTextLabel NewLabel, m_arrTextLabel()
  2371.     ' -----------------------------------------------------------------------------
  2372.     NewLabel.item = "Left"
  2373.     NewLabel.name = "caption"
  2374.     NewLabel.row = 6
  2375.     NewLabel.column = 2
  2376.     NewLabel.width = 14
  2377.     NewLabel.justify = cJustifyCenter
  2378.     NewLabel.caption = "LEFT"
  2379.     NewLabel.fgcolor = cYellow
  2380.     NewLabel.bgcolor = cBlue
  2381.     AddTextLabel NewLabel, m_arrTextLabel()
  2382.  
  2383.     NewLabel.item = "Left"
  2384.     NewLabel.name = "type"
  2385.     NewLabel.row = 7
  2386.     NewLabel.column = 0
  2387.     NewLabel.width = -1
  2388.     NewLabel.justify = cJustifyLeft
  2389.     NewLabel.caption = ""
  2390.     NewLabel.fgcolor = cBlack
  2391.     NewLabel.bgcolor = cBlue
  2392.     AddTextLabel NewLabel, m_arrTextLabel()
  2393.  
  2394.     NewLabel.item = "Left"
  2395.     NewLabel.name = "device"
  2396.     NewLabel.row = 7
  2397.     NewLabel.column = 9
  2398.     NewLabel.width = -1
  2399.     NewLabel.justify = cJustifyLeft
  2400.     NewLabel.caption = "dev "
  2401.     NewLabel.fgcolor = cBlack
  2402.     NewLabel.bgcolor = cBlue
  2403.     AddTextLabel NewLabel, m_arrTextLabel()
  2404.  
  2405.     NewLabel.item = "Left"
  2406.     NewLabel.name = "code"
  2407.     NewLabel.row = 8
  2408.     NewLabel.column = 2
  2409.     NewLabel.width = -1
  2410.     NewLabel.justify = cJustifyLeft
  2411.     NewLabel.caption = "code "
  2412.     NewLabel.fgcolor = cBlack
  2413.     NewLabel.bgcolor = cBlue
  2414.     AddTextLabel NewLabel, m_arrTextLabel()
  2415.  
  2416.     NewLabel.item = "Left"
  2417.     NewLabel.name = "repeat"
  2418.     NewLabel.row = 8
  2419.     NewLabel.column = 10
  2420.     NewLabel.width = -1
  2421.     NewLabel.justify = cJustifyLeft
  2422.     NewLabel.caption = " rep="
  2423.     NewLabel.fgcolor = cBlack
  2424.     NewLabel.bgcolor = cBlue
  2425.     AddTextLabel NewLabel, m_arrTextLabel()
  2426.  
  2427.     NewLabel.item = "Left"
  2428.     NewLabel.name = "value"
  2429.     NewLabel.row = 9
  2430.     NewLabel.column = 2
  2431.     NewLabel.width = -1
  2432.     NewLabel.justify = cJustifyLeft
  2433.     NewLabel.caption = "value  "
  2434.     NewLabel.fgcolor = cBlack
  2435.     NewLabel.bgcolor = cBlue
  2436.     AddTextLabel NewLabel, m_arrTextLabel()
  2437.     ' -----------------------------------------------------------------------------
  2438.     NewLabel.item = "Right"
  2439.     NewLabel.name = "caption"
  2440.     NewLabel.row = 6
  2441.     NewLabel.column = 17
  2442.     NewLabel.width = 14
  2443.     NewLabel.justify = cJustifyCenter
  2444.     NewLabel.caption = "RIGHT"
  2445.     NewLabel.fgcolor = cYellow
  2446.     NewLabel.bgcolor = cOrange
  2447.     AddTextLabel NewLabel, m_arrTextLabel()
  2448.  
  2449.     NewLabel.item = "Right"
  2450.     NewLabel.name = "type"
  2451.     NewLabel.row = 7
  2452.     NewLabel.column = 0
  2453.     NewLabel.width = -1
  2454.     NewLabel.justify = cJustifyLeft
  2455.     NewLabel.caption = ""
  2456.     NewLabel.fgcolor = cBlack
  2457.     NewLabel.bgcolor = cOrange
  2458.     AddTextLabel NewLabel, m_arrTextLabel()
  2459.  
  2460.     NewLabel.item = "Right"
  2461.     NewLabel.name = "device"
  2462.     NewLabel.row = 7
  2463.     NewLabel.column = 24
  2464.     NewLabel.width = -1
  2465.     NewLabel.justify = cJustifyLeft
  2466.     NewLabel.caption = "dev "
  2467.     NewLabel.fgcolor = cBlack
  2468.     NewLabel.bgcolor = cOrange
  2469.     AddTextLabel NewLabel, m_arrTextLabel()
  2470.  
  2471.     NewLabel.item = "Right"
  2472.     NewLabel.name = "code"
  2473.     NewLabel.row = 8
  2474.     NewLabel.column = 17
  2475.     NewLabel.width = -1
  2476.     NewLabel.justify = cJustifyLeft
  2477.     NewLabel.caption = "code "
  2478.     NewLabel.fgcolor = cBlack
  2479.     NewLabel.bgcolor = cOrange
  2480.     AddTextLabel NewLabel, m_arrTextLabel()
  2481.  
  2482.     NewLabel.item = "Right"
  2483.     NewLabel.name = "repeat"
  2484.     NewLabel.row = 8
  2485.     NewLabel.column = 25
  2486.     NewLabel.width = -1
  2487.     NewLabel.justify = cJustifyLeft
  2488.     NewLabel.caption = " rep="
  2489.     NewLabel.fgcolor = cBlack
  2490.     NewLabel.bgcolor = cOrange
  2491.     AddTextLabel NewLabel, m_arrTextLabel()
  2492.  
  2493.     NewLabel.item = "Right"
  2494.     NewLabel.name = "value"
  2495.     NewLabel.row = 9
  2496.     NewLabel.column = 17
  2497.     NewLabel.width = -1
  2498.     NewLabel.justify = cJustifyLeft
  2499.     NewLabel.caption = "value  "
  2500.     NewLabel.fgcolor = cBlack
  2501.     NewLabel.bgcolor = cOrange
  2502.     AddTextLabel NewLabel, m_arrTextLabel()
  2503.     ' -----------------------------------------------------------------------------
  2504.     NewLabel.item = "Button1"
  2505.     NewLabel.name = "caption"
  2506.     NewLabel.row = 15
  2507.     NewLabel.column = 2
  2508.     NewLabel.width = 14
  2509.     NewLabel.justify = cJustifyCenter
  2510.     NewLabel.caption = "BUTTON #1"
  2511.     NewLabel.fgcolor = cYellow
  2512.     NewLabel.bgcolor = cRed
  2513.     AddTextLabel NewLabel, m_arrTextLabel()
  2514.  
  2515.     NewLabel.item = "Button1"
  2516.     NewLabel.name = "type"
  2517.     NewLabel.row = 16
  2518.     NewLabel.column = 0
  2519.     NewLabel.width = -1
  2520.     NewLabel.justify = cJustifyLeft
  2521.     NewLabel.caption = ""
  2522.     NewLabel.fgcolor = cBlack
  2523.     NewLabel.bgcolor = cRed
  2524.     AddTextLabel NewLabel, m_arrTextLabel()
  2525.  
  2526.     NewLabel.item = "Button1"
  2527.     NewLabel.name = "device"
  2528.     NewLabel.row = 16
  2529.     NewLabel.column = 9
  2530.     NewLabel.width = -1
  2531.     NewLabel.justify = cJustifyLeft
  2532.     NewLabel.caption = "dev "
  2533.     NewLabel.fgcolor = cBlack
  2534.     NewLabel.bgcolor = cRed
  2535.     AddTextLabel NewLabel, m_arrTextLabel()
  2536.  
  2537.     NewLabel.item = "Button1"
  2538.     NewLabel.name = "code"
  2539.     NewLabel.row = 17
  2540.     NewLabel.column = 2
  2541.     NewLabel.width = -1
  2542.     NewLabel.justify = cJustifyLeft
  2543.     NewLabel.caption = "code "
  2544.     NewLabel.fgcolor = cBlack
  2545.     NewLabel.bgcolor = cRed
  2546.     AddTextLabel NewLabel, m_arrTextLabel()
  2547.  
  2548.     NewLabel.item = "Button1"
  2549.     NewLabel.name = "repeat"
  2550.     NewLabel.row = 17
  2551.     NewLabel.column = 10
  2552.     NewLabel.width = -1
  2553.     NewLabel.justify = cJustifyLeft
  2554.     NewLabel.caption = " rep="
  2555.     NewLabel.fgcolor = cBlack
  2556.     NewLabel.bgcolor = cRed
  2557.     AddTextLabel NewLabel, m_arrTextLabel()
  2558.  
  2559.     NewLabel.item = "Button1"
  2560.     NewLabel.name = "value"
  2561.     NewLabel.row = 18
  2562.     NewLabel.column = 2
  2563.     NewLabel.width = -1
  2564.     NewLabel.justify = cJustifyLeft
  2565.     NewLabel.caption = "value  "
  2566.     NewLabel.fgcolor = cBlack
  2567.     NewLabel.bgcolor = cRed
  2568.     AddTextLabel NewLabel, m_arrTextLabel()
  2569.     ' -----------------------------------------------------------------------------
  2570.     NewLabel.item = "Button2"
  2571.     NewLabel.name = "caption"
  2572.     NewLabel.row = 20
  2573.     NewLabel.column = 2
  2574.     NewLabel.width = 14
  2575.     NewLabel.justify = cJustifyCenter
  2576.     NewLabel.caption = "BUTTON #2"
  2577.     NewLabel.fgcolor = cYellow
  2578.     NewLabel.bgcolor = cGreen
  2579.     AddTextLabel NewLabel, m_arrTextLabel()
  2580.  
  2581.     NewLabel.item = "Button2"
  2582.     NewLabel.name = "type"
  2583.     NewLabel.row = 21
  2584.     NewLabel.column = 0
  2585.     NewLabel.width = -1
  2586.     NewLabel.justify = cJustifyLeft
  2587.     NewLabel.caption = ""
  2588.     NewLabel.fgcolor = cBlack
  2589.     NewLabel.bgcolor = cGreen
  2590.     AddTextLabel NewLabel, m_arrTextLabel()
  2591.  
  2592.     NewLabel.item = "Button2"
  2593.     NewLabel.name = "device"
  2594.     NewLabel.row = 21
  2595.     NewLabel.column = 9
  2596.     NewLabel.width = -1
  2597.     NewLabel.justify = cJustifyLeft
  2598.     NewLabel.caption = "dev "
  2599.     NewLabel.fgcolor = cBlack
  2600.     NewLabel.bgcolor = cGreen
  2601.     AddTextLabel NewLabel, m_arrTextLabel()
  2602.  
  2603.     NewLabel.item = "Button2"
  2604.     NewLabel.name = "code"
  2605.     NewLabel.row = 22
  2606.     NewLabel.column = 2
  2607.     NewLabel.width = -1
  2608.     NewLabel.justify = cJustifyLeft
  2609.     NewLabel.caption = "code "
  2610.     NewLabel.fgcolor = cBlack
  2611.     NewLabel.bgcolor = cGreen
  2612.     AddTextLabel NewLabel, m_arrTextLabel()
  2613.  
  2614.     NewLabel.item = "Button2"
  2615.     NewLabel.name = "repeat"
  2616.     NewLabel.row = 22
  2617.     NewLabel.column = 10
  2618.     NewLabel.width = -1
  2619.     NewLabel.justify = cJustifyLeft
  2620.     NewLabel.caption = " rep="
  2621.     NewLabel.fgcolor = cBlack
  2622.     NewLabel.bgcolor = cGreen
  2623.     AddTextLabel NewLabel, m_arrTextLabel()
  2624.  
  2625.     NewLabel.item = "Button2"
  2626.     NewLabel.name = "value"
  2627.     NewLabel.row = 23
  2628.     NewLabel.column = 2
  2629.     NewLabel.width = -1
  2630.     NewLabel.justify = cJustifyLeft
  2631.     NewLabel.caption = "value  "
  2632.     NewLabel.fgcolor = cBlack
  2633.     NewLabel.bgcolor = cGreen
  2634.     AddTextLabel NewLabel, m_arrTextLabel()
  2635.     ' -----------------------------------------------------------------------------
  2636.     NewLabel.item = "Button3"
  2637.     NewLabel.name = "caption"
  2638.     NewLabel.row = 15
  2639.     NewLabel.column = 17
  2640.     NewLabel.width = 14
  2641.     NewLabel.justify = cJustifyCenter
  2642.     NewLabel.caption = "BUTTON #3"
  2643.     NewLabel.fgcolor = cYellow
  2644.     NewLabel.bgcolor = cBlue
  2645.     AddTextLabel NewLabel, m_arrTextLabel()
  2646.  
  2647.     NewLabel.item = "Button3"
  2648.     NewLabel.name = "type"
  2649.     NewLabel.row = 16
  2650.     NewLabel.column = 0
  2651.     NewLabel.width = -1
  2652.     NewLabel.justify = cJustifyLeft
  2653.     NewLabel.caption = ""
  2654.     NewLabel.fgcolor = cBlack
  2655.     NewLabel.bgcolor = cBlue
  2656.     AddTextLabel NewLabel, m_arrTextLabel()
  2657.  
  2658.     NewLabel.item = "Button3"
  2659.     NewLabel.name = "device"
  2660.     NewLabel.row = 16
  2661.     NewLabel.column = 24
  2662.     NewLabel.width = -1
  2663.     NewLabel.justify = cJustifyLeft
  2664.     NewLabel.caption = "dev "
  2665.     NewLabel.fgcolor = cBlack
  2666.     NewLabel.bgcolor = cBlue
  2667.     AddTextLabel NewLabel, m_arrTextLabel()
  2668.  
  2669.     NewLabel.item = "Button3"
  2670.     NewLabel.name = "code"
  2671.     NewLabel.row = 17
  2672.     NewLabel.column = 17
  2673.     NewLabel.width = -1
  2674.     NewLabel.justify = cJustifyLeft
  2675.     NewLabel.caption = "code "
  2676.     NewLabel.fgcolor = cBlack
  2677.     NewLabel.bgcolor = cBlue
  2678.     AddTextLabel NewLabel, m_arrTextLabel()
  2679.  
  2680.     NewLabel.item = "Button3"
  2681.     NewLabel.name = "repeat"
  2682.     NewLabel.row = 17
  2683.     NewLabel.column = 25
  2684.     NewLabel.width = -1
  2685.     NewLabel.justify = cJustifyLeft
  2686.     NewLabel.caption = " rep="
  2687.     NewLabel.fgcolor = cBlack
  2688.     NewLabel.bgcolor = cBlue
  2689.     AddTextLabel NewLabel, m_arrTextLabel()
  2690.  
  2691.     NewLabel.item = "Button3"
  2692.     NewLabel.name = "value"
  2693.     NewLabel.row = 18
  2694.     NewLabel.column = 17
  2695.     NewLabel.width = -1
  2696.     NewLabel.justify = cJustifyLeft
  2697.     NewLabel.caption = "value  "
  2698.     NewLabel.fgcolor = cBlack
  2699.     NewLabel.bgcolor = cBlue
  2700.     AddTextLabel NewLabel, m_arrTextLabel()
  2701.     ' -----------------------------------------------------------------------------
  2702.     NewLabel.item = "Button4"
  2703.     NewLabel.name = "caption"
  2704.     NewLabel.row = 20
  2705.     NewLabel.column = 17
  2706.     NewLabel.width = 14
  2707.     NewLabel.justify = cJustifyCenter
  2708.     NewLabel.caption = "BUTTON #4"
  2709.     NewLabel.fgcolor = cYellow
  2710.     NewLabel.bgcolor = cOrange
  2711.     AddTextLabel NewLabel, m_arrTextLabel()
  2712.  
  2713.     NewLabel.item = "Button4"
  2714.     NewLabel.name = "type"
  2715.     NewLabel.row = 21
  2716.     NewLabel.column = 0
  2717.     NewLabel.width = -1
  2718.     NewLabel.justify = cJustifyLeft
  2719.     NewLabel.caption = ""
  2720.     NewLabel.fgcolor = cBlack
  2721.     NewLabel.bgcolor = cOrange
  2722.     AddTextLabel NewLabel, m_arrTextLabel()
  2723.  
  2724.     NewLabel.item = "Button4"
  2725.     NewLabel.name = "device"
  2726.     NewLabel.row = 21
  2727.     NewLabel.column = 24
  2728.     NewLabel.width = -1
  2729.     NewLabel.justify = cJustifyLeft
  2730.     NewLabel.caption = "dev "
  2731.     NewLabel.fgcolor = cBlack
  2732.     NewLabel.bgcolor = cOrange
  2733.     AddTextLabel NewLabel, m_arrTextLabel()
  2734.  
  2735.     NewLabel.item = "Button4"
  2736.     NewLabel.name = "code"
  2737.     NewLabel.row = 22
  2738.     NewLabel.column = 17
  2739.     NewLabel.width = -1
  2740.     NewLabel.justify = cJustifyLeft
  2741.     NewLabel.caption = "code "
  2742.     NewLabel.fgcolor = cBlack
  2743.     NewLabel.bgcolor = cOrange
  2744.     AddTextLabel NewLabel, m_arrTextLabel()
  2745.  
  2746.     NewLabel.item = "Button4"
  2747.     NewLabel.name = "repeat"
  2748.     NewLabel.row = 22
  2749.     NewLabel.column = 25
  2750.     NewLabel.width = -1
  2751.     NewLabel.justify = cJustifyLeft
  2752.     NewLabel.caption = " rep="
  2753.     NewLabel.fgcolor = cBlack
  2754.     NewLabel.bgcolor = cOrange
  2755.     AddTextLabel NewLabel, m_arrTextLabel()
  2756.  
  2757.     NewLabel.item = "Button4"
  2758.     NewLabel.name = "value"
  2759.     NewLabel.row = 23
  2760.     NewLabel.column = 17
  2761.     NewLabel.width = -1
  2762.     NewLabel.justify = cJustifyLeft
  2763.     NewLabel.caption = "value  "
  2764.     NewLabel.fgcolor = cBlack
  2765.     NewLabel.bgcolor = cOrange
  2766.     AddTextLabel NewLabel, m_arrTextLabel()
  2767. End Sub ' SetupTextLabels
  2768.  
  2769. ' /////////////////////////////////////////////////////////////////////////////
  2770.  
  2771. Sub SetupTextFields
  2772.     Dim NewField As TextFieldType
  2773.     ' -----------------------------------------------------------------------------
  2774.     NewField.item = "Up"
  2775.     NewField.name = "type"
  2776.     NewField.row = 3
  2777.     NewField.column = 9
  2778.     NewField.width = 7
  2779.     NewField.justify = cJustifyLeft
  2780.     NewField.value = ""
  2781.     NewField.fgcolor = cWhite
  2782.     NewField.bgcolor = cRed
  2783.     AddTextField NewField, m_arrTextField()
  2784.  
  2785.     NewField.item = "Up"
  2786.     NewField.name = "device"
  2787.     NewField.row = 3
  2788.     NewField.column = 20
  2789.     NewField.width = 3
  2790.     NewField.justify = cJustifyRight
  2791.     NewField.value = ""
  2792.     NewField.fgcolor = cWhite
  2793.     NewField.bgcolor = cRed
  2794.     AddTextField NewField, m_arrTextField()
  2795.  
  2796.     NewField.item = "Up"
  2797.     NewField.name = "code"
  2798.     NewField.row = 4
  2799.     NewField.column = 14
  2800.     NewField.width = 3
  2801.     NewField.justify = cJustifyLeft
  2802.     NewField.value = ""
  2803.     NewField.fgcolor = cWhite
  2804.     NewField.bgcolor = cRed
  2805.     AddTextField NewField, m_arrTextField()
  2806.  
  2807.     NewField.item = "Up"
  2808.     NewField.name = "repeat"
  2809.     NewField.row = 4
  2810.     NewField.column = 22
  2811.     NewField.width = 1
  2812.     NewField.justify = cJustifyLeft
  2813.     NewField.value = ""
  2814.     NewField.fgcolor = cWhite
  2815.     NewField.bgcolor = cRed
  2816.     AddTextField NewField, m_arrTextField()
  2817.  
  2818.     NewField.item = "Up"
  2819.     NewField.name = "value"
  2820.     NewField.row = 5
  2821.     NewField.column = 16
  2822.     NewField.width = 7
  2823.     NewField.justify = cJustifyRight
  2824.     NewField.value = ""
  2825.     NewField.fgcolor = cWhite
  2826.     NewField.bgcolor = cRed
  2827.     AddTextField NewField, m_arrTextField()
  2828.     ' -----------------------------------------------------------------------------
  2829.     NewField.item = "Down"
  2830.     NewField.name = "type"
  2831.     NewField.row = 11
  2832.     NewField.column = 9
  2833.     NewField.width = 7
  2834.     NewField.justify = cJustifyLeft
  2835.     NewField.value = ""
  2836.     NewField.fgcolor = cWhite
  2837.     NewField.bgcolor = cGreen
  2838.     AddTextField NewField, m_arrTextField()
  2839.  
  2840.     NewField.item = "Down"
  2841.     NewField.name = "device"
  2842.     NewField.row = 11
  2843.     NewField.column = 20
  2844.     NewField.width = 3
  2845.     NewField.justify = cJustifyRight
  2846.     NewField.value = ""
  2847.     NewField.fgcolor = cWhite
  2848.     NewField.bgcolor = cGreen
  2849.     AddTextField NewField, m_arrTextField()
  2850.  
  2851.     NewField.item = "Down"
  2852.     NewField.name = "code"
  2853.     NewField.row = 12
  2854.     NewField.column = 14
  2855.     NewField.width = 3
  2856.     NewField.justify = cJustifyLeft
  2857.     NewField.value = ""
  2858.     NewField.fgcolor = cWhite
  2859.     NewField.bgcolor = cGreen
  2860.     AddTextField NewField, m_arrTextField()
  2861.  
  2862.     NewField.item = "Down"
  2863.     NewField.name = "repeat"
  2864.     NewField.row = 12
  2865.     NewField.column = 22
  2866.     NewField.width = 1
  2867.     NewField.justify = cJustifyLeft
  2868.     NewField.value = ""
  2869.     NewField.fgcolor = cWhite
  2870.     NewField.bgcolor = cGreen
  2871.     AddTextField NewField, m_arrTextField()
  2872.  
  2873.     NewField.item = "Down"
  2874.     NewField.name = "value"
  2875.     NewField.row = 13
  2876.     NewField.column = 16
  2877.     NewField.width = 7
  2878.     NewField.justify = cJustifyRight
  2879.     NewField.value = ""
  2880.     NewField.fgcolor = cWhite
  2881.     NewField.bgcolor = cGreen
  2882.     AddTextField NewField, m_arrTextField()
  2883.     ' -----------------------------------------------------------------------------
  2884.     NewField.item = "Left"
  2885.     NewField.name = "type"
  2886.     NewField.row = 7
  2887.     NewField.column = 2
  2888.     NewField.width = 7
  2889.     NewField.justify = cJustifyLeft
  2890.     NewField.value = ""
  2891.     NewField.fgcolor = cWhite
  2892.     NewField.bgcolor = cBlue
  2893.     AddTextField NewField, m_arrTextField()
  2894.  
  2895.     NewField.item = "Left"
  2896.     NewField.name = "device"
  2897.     NewField.row = 7
  2898.     NewField.column = 13
  2899.     NewField.width = 3
  2900.     NewField.justify = cJustifyRight
  2901.     NewField.value = ""
  2902.     NewField.fgcolor = cWhite
  2903.     NewField.bgcolor = cBlue
  2904.     AddTextField NewField, m_arrTextField()
  2905.  
  2906.     NewField.item = "Left"
  2907.     NewField.name = "code"
  2908.     NewField.row = 8
  2909.     NewField.column = 7
  2910.     NewField.width = 3
  2911.     NewField.justify = cJustifyLeft
  2912.     NewField.value = ""
  2913.     NewField.fgcolor = cWhite
  2914.     NewField.bgcolor = cBlue
  2915.     AddTextField NewField, m_arrTextField()
  2916.  
  2917.     NewField.item = "Left"
  2918.     NewField.name = "repeat"
  2919.     NewField.row = 8
  2920.     NewField.column = 15
  2921.     NewField.width = 1
  2922.     NewField.justify = cJustifyLeft
  2923.     NewField.value = ""
  2924.     NewField.fgcolor = cWhite
  2925.     NewField.bgcolor = cBlue
  2926.     AddTextField NewField, m_arrTextField()
  2927.  
  2928.     NewField.item = "Left"
  2929.     NewField.name = "value"
  2930.     NewField.row = 9
  2931.     NewField.column = 9
  2932.     NewField.width = 7
  2933.     NewField.justify = cJustifyRight
  2934.     NewField.value = ""
  2935.     NewField.fgcolor = cWhite
  2936.     NewField.bgcolor = cBlue
  2937.     AddTextField NewField, m_arrTextField()
  2938.     ' -----------------------------------------------------------------------------
  2939.     NewField.item = "Right"
  2940.     NewField.name = "type"
  2941.     NewField.row = 7
  2942.     NewField.column = 17
  2943.     NewField.width = 7
  2944.     NewField.justify = cJustifyLeft
  2945.     NewField.value = ""
  2946.     NewField.fgcolor = cWhite
  2947.     NewField.bgcolor = cOrange
  2948.     AddTextField NewField, m_arrTextField()
  2949.  
  2950.     NewField.item = "Right"
  2951.     NewField.name = "device"
  2952.     NewField.row = 7
  2953.     NewField.column = 28
  2954.     NewField.width = 3
  2955.     NewField.justify = cJustifyRight
  2956.     NewField.value = ""
  2957.     NewField.fgcolor = cWhite
  2958.     NewField.bgcolor = cOrange
  2959.     AddTextField NewField, m_arrTextField()
  2960.  
  2961.     NewField.item = "Right"
  2962.     NewField.name = "code"
  2963.     NewField.row = 8
  2964.     NewField.column = 22
  2965.     NewField.width = 3
  2966.     NewField.justify = cJustifyLeft
  2967.     NewField.value = ""
  2968.     NewField.fgcolor = cWhite
  2969.     NewField.bgcolor = cOrange
  2970.     AddTextField NewField, m_arrTextField()
  2971.  
  2972.     NewField.item = "Right"
  2973.     NewField.name = "repeat"
  2974.     NewField.row = 8
  2975.     NewField.column = 30
  2976.     NewField.width = 1
  2977.     NewField.justify = cJustifyLeft
  2978.     NewField.value = ""
  2979.     NewField.fgcolor = cWhite
  2980.     NewField.bgcolor = cOrange
  2981.     AddTextField NewField, m_arrTextField()
  2982.  
  2983.     NewField.item = "Right"
  2984.     NewField.name = "value"
  2985.     NewField.row = 9
  2986.     NewField.column = 24
  2987.     NewField.width = 7
  2988.     NewField.justify = cJustifyRight
  2989.     NewField.value = ""
  2990.     NewField.fgcolor = cWhite
  2991.     NewField.bgcolor = cOrange
  2992.     AddTextField NewField, m_arrTextField()
  2993.     ' -----------------------------------------------------------------------------
  2994.     NewField.item = "Button1"
  2995.     NewField.name = "type"
  2996.     NewField.row = 16
  2997.     NewField.column = 2
  2998.     NewField.width = 7
  2999.     NewField.justify = cJustifyLeft
  3000.     NewField.value = ""
  3001.     NewField.fgcolor = cWhite
  3002.     NewField.bgcolor = cRed
  3003.     AddTextField NewField, m_arrTextField()
  3004.  
  3005.     NewField.item = "Button1"
  3006.     NewField.name = "device"
  3007.     NewField.row = 16
  3008.     NewField.column = 13
  3009.     NewField.width = 3
  3010.     NewField.justify = cJustifyRight
  3011.     NewField.value = ""
  3012.     NewField.fgcolor = cWhite
  3013.     NewField.bgcolor = cRed
  3014.     AddTextField NewField, m_arrTextField()
  3015.  
  3016.     NewField.item = "Button1"
  3017.     NewField.name = "code"
  3018.     NewField.row = 17
  3019.     NewField.column = 7
  3020.     NewField.width = 3
  3021.     NewField.justify = cJustifyLeft
  3022.     NewField.value = ""
  3023.     NewField.fgcolor = cWhite
  3024.     NewField.bgcolor = cRed
  3025.     AddTextField NewField, m_arrTextField()
  3026.  
  3027.     NewField.item = "Button1"
  3028.     NewField.name = "repeat"
  3029.     NewField.row = 17
  3030.     NewField.column = 15
  3031.     NewField.width = 1
  3032.     NewField.justify = cJustifyLeft
  3033.     NewField.value = ""
  3034.     NewField.fgcolor = cWhite
  3035.     NewField.bgcolor = cRed
  3036.     AddTextField NewField, m_arrTextField()
  3037.  
  3038.     NewField.item = "Button1"
  3039.     NewField.name = "value"
  3040.     NewField.row = 18
  3041.     NewField.column = 9
  3042.     NewField.width = 7
  3043.     NewField.justify = cJustifyRight
  3044.     NewField.value = ""
  3045.     NewField.fgcolor = cWhite
  3046.     NewField.bgcolor = cRed
  3047.     AddTextField NewField, m_arrTextField()
  3048.     ' -----------------------------------------------------------------------------
  3049.     NewField.item = "Button2"
  3050.     NewField.name = "type"
  3051.     NewField.row = 21
  3052.     NewField.column = 2
  3053.     NewField.width = 7
  3054.     NewField.justify = cJustifyLeft
  3055.     NewField.value = ""
  3056.     NewField.fgcolor = cWhite
  3057.     NewField.bgcolor = cGreen
  3058.     AddTextField NewField, m_arrTextField()
  3059.  
  3060.     NewField.item = "Button2"
  3061.     NewField.name = "device"
  3062.     NewField.row = 21
  3063.     NewField.column = 13
  3064.     NewField.width = 3
  3065.     NewField.justify = cJustifyRight
  3066.     NewField.value = ""
  3067.     NewField.fgcolor = cWhite
  3068.     NewField.bgcolor = cGreen
  3069.     AddTextField NewField, m_arrTextField()
  3070.  
  3071.     NewField.item = "Button2"
  3072.     NewField.name = "code"
  3073.     NewField.row = 22
  3074.     NewField.column = 7
  3075.     NewField.width = 3
  3076.     NewField.justify = cJustifyLeft
  3077.     NewField.value = ""
  3078.     NewField.fgcolor = cWhite
  3079.     NewField.bgcolor = cGreen
  3080.     AddTextField NewField, m_arrTextField()
  3081.  
  3082.     NewField.item = "Button2"
  3083.     NewField.name = "repeat"
  3084.     NewField.row = 22
  3085.     NewField.column = 15
  3086.     NewField.width = 1
  3087.     NewField.justify = cJustifyLeft
  3088.     NewField.value = ""
  3089.     NewField.fgcolor = cWhite
  3090.     NewField.bgcolor = cGreen
  3091.     AddTextField NewField, m_arrTextField()
  3092.  
  3093.     NewField.item = "Button2"
  3094.     NewField.name = "value"
  3095.     NewField.row = 23
  3096.     NewField.column = 9
  3097.     NewField.width = 7
  3098.     NewField.justify = cJustifyRight
  3099.     NewField.value = ""
  3100.     NewField.fgcolor = cWhite
  3101.     NewField.bgcolor = cGreen
  3102.     AddTextField NewField, m_arrTextField()
  3103.     ' -----------------------------------------------------------------------------
  3104.     NewField.item = "Button3"
  3105.     NewField.name = "type"
  3106.     NewField.row = 16
  3107.     NewField.column = 17
  3108.     NewField.width = 7
  3109.     NewField.justify = cJustifyLeft
  3110.     NewField.value = ""
  3111.     NewField.fgcolor = cWhite
  3112.     NewField.bgcolor = cBlue
  3113.     AddTextField NewField, m_arrTextField()
  3114.  
  3115.     NewField.item = "Button3"
  3116.     NewField.name = "device"
  3117.     NewField.row = 16
  3118.     NewField.column = 28
  3119.     NewField.width = 3
  3120.     NewField.justify = cJustifyRight
  3121.     NewField.value = ""
  3122.     NewField.fgcolor = cWhite
  3123.     NewField.bgcolor = cBlue
  3124.     AddTextField NewField, m_arrTextField()
  3125.  
  3126.     NewField.item = "Button3"
  3127.     NewField.name = "code"
  3128.     NewField.row = 17
  3129.     NewField.column = 22
  3130.     NewField.width = 3
  3131.     NewField.justify = cJustifyLeft
  3132.     NewField.value = ""
  3133.     NewField.fgcolor = cWhite
  3134.     NewField.bgcolor = cBlue
  3135.     AddTextField NewField, m_arrTextField()
  3136.  
  3137.     NewField.item = "Button3"
  3138.     NewField.name = "repeat"
  3139.     NewField.row = 17
  3140.     NewField.column = 30
  3141.     NewField.width = 1
  3142.     NewField.justify = cJustifyLeft
  3143.     NewField.value = ""
  3144.     NewField.fgcolor = cWhite
  3145.     NewField.bgcolor = cBlue
  3146.     AddTextField NewField, m_arrTextField()
  3147.  
  3148.     NewField.item = "Button3"
  3149.     NewField.name = "value"
  3150.     NewField.row = 18
  3151.     NewField.column = 24
  3152.     NewField.width = 7
  3153.     NewField.justify = cJustifyRight
  3154.     NewField.value = ""
  3155.     NewField.fgcolor = cWhite
  3156.     NewField.bgcolor = cBlue
  3157.     AddTextField NewField, m_arrTextField()
  3158.     ' -----------------------------------------------------------------------------
  3159.     NewField.item = "Button4"
  3160.     NewField.name = "type"
  3161.     NewField.row = 21
  3162.     NewField.column = 17
  3163.     NewField.width = 7
  3164.     NewField.justify = cJustifyLeft
  3165.     NewField.value = ""
  3166.     NewField.fgcolor = cWhite
  3167.     NewField.bgcolor = cOrange
  3168.     AddTextField NewField, m_arrTextField()
  3169.  
  3170.     NewField.item = "Button4"
  3171.     NewField.name = "device"
  3172.     NewField.row = 21
  3173.     NewField.column = 28
  3174.     NewField.width = 3
  3175.     NewField.justify = cJustifyRight
  3176.     NewField.value = ""
  3177.     NewField.fgcolor = cWhite
  3178.     NewField.bgcolor = cOrange
  3179.     AddTextField NewField, m_arrTextField()
  3180.  
  3181.     NewField.item = "Button4"
  3182.     NewField.name = "code"
  3183.     NewField.row = 22
  3184.     NewField.column = 22
  3185.     NewField.width = 3
  3186.     NewField.justify = cJustifyLeft
  3187.     NewField.value = ""
  3188.     NewField.fgcolor = cWhite
  3189.     NewField.bgcolor = cOrange
  3190.     AddTextField NewField, m_arrTextField()
  3191.  
  3192.     NewField.item = "Button4"
  3193.     NewField.name = "repeat"
  3194.     NewField.row = 22
  3195.     NewField.column = 30
  3196.     NewField.width = 1
  3197.     NewField.justify = cJustifyLeft
  3198.     NewField.value = ""
  3199.     NewField.fgcolor = cWhite
  3200.     NewField.bgcolor = cOrange
  3201.     AddTextField NewField, m_arrTextField()
  3202.  
  3203.     NewField.item = "Button4"
  3204.     NewField.name = "value"
  3205.     NewField.row = 23
  3206.     NewField.column = 24
  3207.     NewField.width = 7
  3208.     NewField.justify = cJustifyRight
  3209.     NewField.value = ""
  3210.     NewField.fgcolor = cWhite
  3211.     NewField.bgcolor = cOrange
  3212.     AddTextField NewField, m_arrTextField()
  3213. End Sub ' SetupTextFields
  3214.  
  3215. ' /////////////////////////////////////////////////////////////////////////////
  3216. ' Looks in MyArray for the first element
  3217. ' whose .item matches sItem and .name matches sName
  3218. ' and returns the index, or MyArray's lbound-1 if not found.
  3219.  
  3220. Function GetTextLabel% (MyArray() As TextLabelType, sItem As String, sName As String)
  3221.     Dim iResult As Integer: iResult = LBound(MyArray) - 1
  3222.     Dim iLoop As Integer
  3223.     For iLoop = LBound(MyArray) To UBound(MyArray)
  3224.         If MyArray(iLoop).item = sItem Then
  3225.             If MyArray(iLoop).name = sName Then
  3226.                 iResult = iLoop
  3227.                 Exit For
  3228.             End If
  3229.         End If
  3230.     Next iLoop
  3231.     GetTextLabel% = iResult
  3232. End Function ' GetTextLabel%
  3233.  
  3234. ' /////////////////////////////////////////////////////////////////////////////
  3235. ' Looks in MyArray for the first element
  3236. ' whose .item matches sItem and .name matches sName
  3237. ' and returns the index, or MyArray's lbound-1 if not found.
  3238.  
  3239. Function GetTextField% (MyArray() As TextFieldType, sItem As String, sName As String)
  3240.     Dim iResult As Integer: iResult = LBound(MyArray) - 1
  3241.     Dim iLoop As Integer
  3242.     For iLoop = LBound(MyArray) To UBound(MyArray)
  3243.         If MyArray(iLoop).item = sItem Then
  3244.             If MyArray(iLoop).name = sName Then
  3245.                 iResult = iLoop
  3246.                 Exit For
  3247.             End If
  3248.         End If
  3249.     Next iLoop
  3250.     GetTextField% = iResult
  3251. End Function ' GetTextField%
  3252.  
  3253. ' /////////////////////////////////////////////////////////////////////////////
  3254. ' The following must be initialized and populated before calling:
  3255. ' ReDim arrColor(-1) As ColorType
  3256. ' Dim MapArray(1 To 48, 1 To 128) As String ' FOR SCREEN 1024 x  768: 128 x 48
  3257. ' ReDim ScreenArray(1 To 48, 1 To 128) As TextCellType ' FOR SCREEN 1024 x  768: 128 x 48
  3258.  
  3259. ' This was an experiment in rolling your own "GUI",
  3260. ' - what a pain it turned out to be
  3261. ' - next time maybe we would use InForm and be done with it!
  3262.  
  3263. ' TODO:
  3264. ' * clean up and remove all the variable definitions left over
  3265. '   from the main routine MapInput2$ this was moved out of.
  3266.  
  3267. Sub UpdateDisplayMapInput2( _
  3268.     arrColor() As ColorType, _
  3269.     MapArray() As String, _
  3270.     ScreenArray() As TextCellType _
  3271.     )
  3272.    
  3273.     Dim RoutineName As String: RoutineName = "UpdateDisplayMapInput2"
  3274.    
  3275.     Dim iDeviceCount As Integer ' count # of devices connected to system (keyboard, mouse, game controllers)
  3276.     Dim iPlayer As Integer ' same as iController, which of the 8 controllers
  3277.     Dim iWhichInput As Integer ' one of: cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  3278.    
  3279.     Dim iCount As Integer
  3280.    
  3281.     Dim sResult As String
  3282.     Dim sError As String
  3283.     Dim sLine As String
  3284.    
  3285.     Dim iForeColor As Integer
  3286.     Dim iBackColor As Integer
  3287.    
  3288.     Dim sName As String
  3289.     Dim sItem As String
  3290.     Dim iLoop As Integer
  3291.     Dim iX As Integer
  3292.     Dim iY As Integer
  3293.     Dim iCol As Integer
  3294.     Dim iRow As Integer
  3295.    
  3296.     Dim iStartX As Integer
  3297.     Dim iStartY As Integer
  3298.     Dim iEndX As Integer
  3299.     Dim iEndY As Integer
  3300.     Dim iLabel As Integer
  3301.     Dim iField As Integer
  3302.     Dim iButton As Integer
  3303.     Dim iWidth As Integer
  3304.     Dim bContinue As Integer
  3305.     Dim sValue As String
  3306.     Dim iNextWidth As Integer
  3307.     Dim iType As Integer
  3308.     Dim iIndex As Integer
  3309.    
  3310.     Dim in$
  3311.    
  3312.     ' MOUSE VARIABLES
  3313.     Dim iX1 As Integer: iX1 = 0
  3314.     Dim iY1 As Integer: iY1 = 0
  3315.     Dim iOldX1 As Integer: iOldX1 = 0
  3316.     Dim iOldY1 As Integer: iOldY1 = 0
  3317.     Dim bLeftClick As Integer: bLeftClick = FALSE
  3318.     Dim bOldLeftClick As Integer: bOldLeftClick = FALSE
  3319.    
  3320.     Dim sZone1 As String ' text description of which controller
  3321.     Dim sZone2 As String ' text description of which input
  3322.     Dim iMapPlayer As Integer ' like iController, which of the 8 controllers
  3323.    
  3324.     ' WHICH PORTION OF THE SCREEN USER CLICKED ON
  3325.     Dim iTempX As Integer
  3326.     Dim iTempY As Integer
  3327.     Dim iTextX As Integer
  3328.     Dim iTextY As Integer
  3329.     Dim iOffsetX As Integer
  3330.     Dim iOffsetY As Integer
  3331.    
  3332.     ' BOUNDARIES OF BUTTON CLICKED ON
  3333.     Dim iMapX1 As Integer
  3334.     Dim iMapX2 As Integer
  3335.     Dim iMapY1 As Integer
  3336.     Dim iMapY2 As Integer
  3337.    
  3338.     ' FOR MAPPING CONTROLLER INPUT
  3339.     Dim arrButton(32, 16) As Integer ' number of buttons on the joystick
  3340.     Dim arrButtonNew(32, 16) As Integer ' tracks when to initialize values
  3341.     Dim arrAxis(32, 16) As Double ' number of axis on the joystick
  3342.     Dim arrAxisNew(32, 16) As Integer ' tracks when to initialize values
  3343.     'Dim iPlayer As Integer
  3344.     Dim iController As Integer ' to loop through devices
  3345.     Dim iDevice As Integer
  3346.     Dim iValue As Integer
  3347.     Dim bMoveNext As Integer
  3348.     'Dim iLoop As Integer
  3349.     Dim iCode As Integer
  3350.     Dim bHaveInput As Integer
  3351.     'Dim iWhichInput As Integer
  3352.     Dim iNextInput As Integer
  3353.     Dim sPrompt As String
  3354.     Dim dblNextAxis As Double
  3355.    
  3356.     Dim ExitX As Integer
  3357.     Dim ExitY As Integer
  3358.    
  3359.     ' DISPLAY BORDERS
  3360.     Cls
  3361.     For iRow = LBound(MapArray, 1) To UBound(MapArray, 1)
  3362.         For iCol = LBound(MapArray, 2) To UBound(MapArray, 2)
  3363.             Color cRed, cBlack
  3364.             PrintString2 iRow, iCol, MapArray(iRow, iCol), ScreenArray()
  3365.         Next iCol
  3366.     Next iRow
  3367.    
  3368.     ' DISPLAY CONTROL MAPPINGS
  3369.     For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  3370.         ' Get top left screen coordinates for this controller
  3371.         iStartX = m_arrScreenArea(iPlayer).x1
  3372.         iStartY = m_arrScreenArea(iPlayer).y1
  3373.         iEndX = m_arrScreenArea(iPlayer).x2
  3374.         iEndY = m_arrScreenArea(iPlayer).y2
  3375.         iWidth = (iEndX - iStartX) + 1
  3376.        
  3377.         sItem = "Section"
  3378.         iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "caption")
  3379.         If iIndex >= LBound(m_arrTextLabel) Then
  3380.             iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3381.             iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3382.             sValue = m_arrTextLabel(iIndex).caption
  3383.             sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3384.             iNextWidth = m_arrTextLabel(iIndex).width
  3385.             If iNextWidth > 0 Then
  3386.                 Select Case m_arrTextLabel(iIndex).justify
  3387.                     Case cJustifyLeft:
  3388.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3389.                     Case cJustifyRight:
  3390.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3391.                     Case cJustifyCenter:
  3392.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3393.                     Case Else:
  3394.                         ' (DO NOTHING)
  3395.                 End Select
  3396.                 Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3397.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3398.             ElseIf iNextWidth < 0 Then
  3399.                 Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3400.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3401.             Else
  3402.                 ' (IGNORE)
  3403.             End If
  3404.         End If
  3405.        
  3406.         ' POPULATE EACH INPUT FOR THIS PLAYER/CONTROLLER:
  3407.         ' up,down,left,right,button #1,button #2,button #3,button #4
  3408.         ' iWhichInput is one of: cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  3409.         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  3410.            
  3411.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3412.             ' BEGIN ITEM
  3413.            
  3414.             ' get value to match against m_arrTextField(iField).item
  3415.             sItem = InputToItem$(iWhichInput)
  3416.             'InputToString$(iWhichInput) returns up,down,left,right,button #1,button #2,button #3,button #4
  3417.            
  3418.             ' find the layout for each field for this input
  3419.             ' m_arrTextField(iField).name = type,device,code,repeat,value
  3420.            
  3421.             ' END ITEM
  3422.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3423.            
  3424.            
  3425.            
  3426.            
  3427.            
  3428.            
  3429.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3430.             ' BEGIN CAPTION
  3431.            
  3432.             ' LABEL
  3433.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "caption")
  3434.             If iIndex >= LBound(m_arrTextLabel) Then
  3435.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3436.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3437.                 sValue = m_arrTextLabel(iIndex).caption
  3438.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3439.                 iNextWidth = m_arrTextLabel(iIndex).width
  3440.                 If iNextWidth > 0 Then
  3441.                     Select Case m_arrTextLabel(iIndex).justify
  3442.                         Case cJustifyLeft:
  3443.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3444.                         Case cJustifyRight:
  3445.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3446.                         Case cJustifyCenter:
  3447.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3448.                         Case Else:
  3449.                             ' (DO NOTHING)
  3450.                     End Select
  3451.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3452.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3453.                 ElseIf iNextWidth < 0 Then
  3454.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3455.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3456.                 Else
  3457.                     ' (IGNORE)
  3458.                 End If
  3459.             End If
  3460.             ' END CAPTION
  3461.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3462.            
  3463.            
  3464.            
  3465.            
  3466.            
  3467.            
  3468.            
  3469.            
  3470.            
  3471.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3472.             ' BEGIN TYPE
  3473.             '           values are cInputNone,cInputKey,cInputButton,cInputAxis
  3474.             '           InputTypeToString$ returns none,key,button,axis,unknown
  3475.            
  3476.             ' VALUE
  3477.             iIndex = GetTextField%(m_arrTextField(), sItem, "type")
  3478.             If iIndex >= LBound(m_arrTextField) Then
  3479.                 iRow = (iStartY + m_arrTextField(iIndex).row) - 1
  3480.                 iCol = (iStartX + m_arrTextField(iIndex).column) - 1
  3481.                 sValue = InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ)
  3482.                 iNextWidth = m_arrTextField(iIndex).width
  3483.                 Select Case m_arrTextField(iIndex).justify
  3484.                     Case cJustifyLeft:
  3485.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3486.                     Case cJustifyRight:
  3487.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3488.                     Case cJustifyCenter:
  3489.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3490.                     Case Else:
  3491.                         ' (DO NOTHING)
  3492.                 End Select
  3493.                 Color m_arrTextField(iIndex).fgcolor, m_arrTextField(iIndex).bgcolor
  3494.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3495.             End If
  3496.            
  3497.             ' LABEL
  3498.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "type")
  3499.             If iIndex >= LBound(m_arrTextLabel) Then
  3500.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3501.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3502.                 sValue = m_arrTextLabel(iIndex).caption
  3503.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3504.                 iNextWidth = m_arrTextLabel(iIndex).width
  3505.                 If iNextWidth > 0 Then
  3506.                     Select Case m_arrTextLabel(iIndex).justify
  3507.                         Case cJustifyLeft:
  3508.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3509.                         Case cJustifyRight:
  3510.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3511.                         Case cJustifyCenter:
  3512.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3513.                         Case Else:
  3514.                             ' (DO NOTHING)
  3515.                     End Select
  3516.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3517.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3518.                 ElseIf iNextWidth < 0 Then
  3519.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3520.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3521.                 Else
  3522.                     ' (IGNORE)
  3523.                 End If
  3524.             End If
  3525.             ' END TYPE
  3526.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3527.            
  3528.            
  3529.            
  3530.            
  3531.            
  3532.            
  3533.            
  3534.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3535.             ' BEGIN DEVICE
  3536.            
  3537.             ' VALUE
  3538.             iIndex = GetTextField%(m_arrTextField(), sItem, "device")
  3539.             If iIndex >= LBound(m_arrTextField) Then
  3540.                 iRow = (iStartY + m_arrTextField(iIndex).row) - 1
  3541.                 iCol = (iStartX + m_arrTextField(iIndex).column) - 1
  3542.                 sValue = cstr$(m_arrControlMap(iPlayer, iWhichInput).device)
  3543.                 iNextWidth = m_arrTextField(iIndex).width
  3544.                 Select Case m_arrTextField(iIndex).justify
  3545.                     Case cJustifyLeft:
  3546.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3547.                     Case cJustifyRight:
  3548.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3549.                     Case cJustifyCenter:
  3550.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3551.                     Case Else:
  3552.                         ' (DO NOTHING)
  3553.                 End Select
  3554.                 Color m_arrTextField(iIndex).fgcolor, m_arrTextField(iIndex).bgcolor
  3555.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3556.             End If
  3557.            
  3558.             ' LABEL
  3559.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "device")
  3560.             If iIndex >= LBound(m_arrTextLabel) Then
  3561.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3562.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3563.                 sValue = m_arrTextLabel(iIndex).caption
  3564.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3565.                 iNextWidth = m_arrTextLabel(iIndex).width
  3566.                 If iNextWidth > 0 Then
  3567.                     Select Case m_arrTextLabel(iIndex).justify
  3568.                         Case cJustifyLeft:
  3569.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3570.                         Case cJustifyRight:
  3571.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3572.                         Case cJustifyCenter:
  3573.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3574.                         Case Else:
  3575.                             ' (DO NOTHING)
  3576.                     End Select
  3577.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3578.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3579.                 ElseIf iNextWidth < 0 Then
  3580.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3581.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3582.                 Else
  3583.                     ' (IGNORE)
  3584.                 End If
  3585.             End If
  3586.             ' END DEVICE
  3587.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3588.            
  3589.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3590.             ' BEGIN CODE
  3591.            
  3592.             ' VALUE
  3593.             iIndex = GetTextField%(m_arrTextField(), sItem, "code")
  3594.             If iIndex >= LBound(m_arrTextField) Then
  3595.                 iRow = (iStartY + m_arrTextField(iIndex).row) - 1
  3596.                 iCol = (iStartX + m_arrTextField(iIndex).column) - 1
  3597.                
  3598.                 If m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey Then
  3599.                     sValue = GetKeyboardButtonCodeText$(m_arrControlMap(iPlayer, iWhichInput).code)
  3600.                 Else
  3601.                     sValue = cstr$(m_arrControlMap(iPlayer, iWhichInput).code)
  3602.                 End If
  3603.                
  3604.                 iNextWidth = m_arrTextField(iIndex).width
  3605.                 Select Case m_arrTextField(iIndex).justify
  3606.                     Case cJustifyLeft:
  3607.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3608.                     Case cJustifyRight:
  3609.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3610.                     Case cJustifyCenter:
  3611.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3612.                     Case Else:
  3613.                         ' (DO NOTHING)
  3614.                 End Select
  3615.                 Color m_arrTextField(iIndex).fgcolor, m_arrTextField(iIndex).bgcolor
  3616.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3617.             End If
  3618.            
  3619.             ' LABEL
  3620.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "code")
  3621.             If iIndex >= LBound(m_arrTextLabel) Then
  3622.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3623.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3624.                 sValue = m_arrTextLabel(iIndex).caption
  3625.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3626.                 iNextWidth = m_arrTextLabel(iIndex).width
  3627.                 If iNextWidth > 0 Then
  3628.                     Select Case m_arrTextLabel(iIndex).justify
  3629.                         Case cJustifyLeft:
  3630.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3631.                         Case cJustifyRight:
  3632.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3633.                         Case cJustifyCenter:
  3634.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3635.                         Case Else:
  3636.                             ' (DO NOTHING)
  3637.                     End Select
  3638.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3639.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3640.                 ElseIf iNextWidth < 0 Then
  3641.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3642.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3643.                 Else
  3644.                     ' (IGNORE)
  3645.                 End If
  3646.             End If
  3647.             ' END CODE
  3648.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3649.            
  3650.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3651.             ' BEGIN VALUE
  3652.            
  3653.             ' VALUE
  3654.             iIndex = GetTextField%(m_arrTextField(), sItem, "value")
  3655.             If iIndex >= LBound(m_arrTextField) Then
  3656.                 iRow = (iStartY + m_arrTextField(iIndex).row) - 1
  3657.                 iCol = (iStartX + m_arrTextField(iIndex).column) - 1
  3658.                 sValue = cstr$(m_arrControlMap(iPlayer, iWhichInput).value)
  3659.                 iNextWidth = m_arrTextField(iIndex).width
  3660.                 Select Case m_arrTextField(iIndex).justify
  3661.                     Case cJustifyLeft:
  3662.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3663.                     Case cJustifyRight:
  3664.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3665.                     Case cJustifyCenter:
  3666.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3667.                     Case Else:
  3668.                         ' (DO NOTHING)
  3669.                 End Select
  3670.                 Color m_arrTextField(iIndex).fgcolor, m_arrTextField(iIndex).bgcolor
  3671.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3672.             End If
  3673.            
  3674.             ' LABEL
  3675.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "value")
  3676.             If iIndex >= LBound(m_arrTextLabel) Then
  3677.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3678.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3679.                 sValue = m_arrTextLabel(iIndex).caption
  3680.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3681.                 iNextWidth = m_arrTextLabel(iIndex).width
  3682.                 If iNextWidth > 0 Then
  3683.                     Select Case m_arrTextLabel(iIndex).justify
  3684.                         Case cJustifyLeft:
  3685.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3686.                         Case cJustifyRight:
  3687.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3688.                         Case cJustifyCenter:
  3689.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3690.                         Case Else:
  3691.                             ' (DO NOTHING)
  3692.                     End Select
  3693.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3694.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3695.                 ElseIf iNextWidth < 0 Then
  3696.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3697.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3698.                 Else
  3699.                     ' (IGNORE)
  3700.                 End If
  3701.             End If
  3702.             ' END VALUE
  3703.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3704.            
  3705.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3706.             ' BEGIN REPEAT
  3707.            
  3708.             ' VALUE
  3709.             iIndex = GetTextField%(m_arrTextField(), sItem, "repeat")
  3710.             If iIndex >= LBound(m_arrTextField) Then
  3711.                 iRow = (iStartY + m_arrTextField(iIndex).row) - 1
  3712.                 iCol = (iStartX + m_arrTextField(iIndex).column) - 1
  3713.                 sValue = IIFSTR$(m_arrControlMap(iPlayer, iWhichInput).repeat, "Y", "N")
  3714.                 iNextWidth = m_arrTextField(iIndex).width
  3715.                 Select Case m_arrTextField(iIndex).justify
  3716.                     Case cJustifyLeft:
  3717.                         sValue = StrJustifyLeft$(sValue, iNextWidth)
  3718.                     Case cJustifyRight:
  3719.                         sValue = StrJustifyRight$(sValue, iNextWidth)
  3720.                     Case cJustifyCenter:
  3721.                         sValue = StrJustifyCenter$(sValue, iNextWidth)
  3722.                     Case Else:
  3723.                         ' (DO NOTHING)
  3724.                 End Select
  3725.                 Color m_arrTextField(iIndex).fgcolor, m_arrTextField(iIndex).bgcolor
  3726.                 PrintString2 iRow, iCol, sValue, ScreenArray()
  3727.             End If
  3728.            
  3729.             ' LABEL
  3730.             iIndex = GetTextLabel%(m_arrTextLabel(), sItem, "repeat")
  3731.             If iIndex >= LBound(m_arrTextLabel) Then
  3732.                 iRow = (iStartY + m_arrTextLabel(iIndex).row) - 1
  3733.                 iCol = (iStartX + m_arrTextLabel(iIndex).column) - 1
  3734.                 sValue = m_arrTextLabel(iIndex).caption
  3735.                 sValue = Replace$(sValue, "{p}", cstr$(iPlayer))
  3736.                 iNextWidth = m_arrTextLabel(iIndex).width
  3737.                 If iNextWidth > 0 Then
  3738.                     Select Case m_arrTextLabel(iIndex).justify
  3739.                         Case cJustifyLeft:
  3740.                             sValue = StrJustifyLeft$(sValue, iNextWidth)
  3741.                         Case cJustifyRight:
  3742.                             sValue = StrJustifyRight$(sValue, iNextWidth)
  3743.                         Case cJustifyCenter:
  3744.                             sValue = StrJustifyCenter$(sValue, iNextWidth)
  3745.                         Case Else:
  3746.                             ' (DO NOTHING)
  3747.                     End Select
  3748.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3749.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3750.                 ElseIf iNextWidth < 0 Then
  3751.                     Color m_arrTextLabel(iIndex).fgcolor, m_arrTextLabel(iIndex).bgcolor
  3752.                     PrintString2 iRow, iCol, sValue, ScreenArray()
  3753.                 Else
  3754.                     ' (IGNORE)
  3755.                 End If
  3756.             End If
  3757.             ' END REPEAT
  3758.             ' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3759.            
  3760.         Next iWhichInput
  3761.     Next iPlayer
  3762.    
  3763.     ' ADD CLOSE BUTTON
  3764.     ExitX = (_Width(0) \ _FontWidth) - 4
  3765.     ExitY = 1 ' _Height(0) \ _FontHeight
  3766.     Color cBlack, cRed
  3767.     PrintString2 ExitY, ExitX+0, "C", ScreenArray()
  3768.     PrintString2 ExitY, ExitX+1, "L", ScreenArray()
  3769.     PrintString2 ExitY, ExitX+2, "O", ScreenArray()
  3770.     PrintString2 ExitY, ExitX+3, "S", ScreenArray()
  3771.     PrintString2 ExitY, ExitX+4, "E", ScreenArray()
  3772.    
  3773. End Sub ' UpdateDisplayMapInput2
  3774.  
  3775. ' /////////////////////////////////////////////////////////////////////////////
  3776.  
  3777. Function MapInput2$
  3778.     Dim RoutineName As String: RoutineName = "MapInput2$"
  3779.    
  3780.     Dim iDeviceCount As Integer ' count # of devices connected to system (keyboard, mouse, game controllers)
  3781.     Dim iPlayer As Integer ' same as iController, which of the 8 controllers
  3782.     Dim iWhichInput As Integer ' one of: cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  3783.    
  3784.     Dim bFinished As Integer
  3785.     Dim iCount As Integer
  3786.    
  3787.     Dim sResult As String
  3788.     Dim sError As String : sError = ""
  3789.     Dim sLine As String
  3790.    
  3791.     ReDim arrColor(-1) As ColorType
  3792.     Dim iForeColor As Integer
  3793.     Dim iBackColor As Integer
  3794.    
  3795.     ' VARIABLES FOR SCREEN
  3796.     ' 1024 x  768: 128 x 48
  3797.     Dim MapArray(1 To 48, 1 To 128) As String
  3798.     ReDim ScreenArray(1 To 48, 1 To 128) As TextCellType
  3799.    
  3800.     Dim sName As String
  3801.     Dim sItem As String
  3802.     Dim iLoop As Integer
  3803.     Dim iX As Integer
  3804.     Dim iY As Integer
  3805.     Dim iCol As Integer
  3806.     Dim iRow As Integer
  3807.    
  3808.     Dim iStartX As Integer
  3809.     Dim iStartY As Integer
  3810.     Dim iEndX As Integer
  3811.     Dim iEndY As Integer
  3812.     Dim iLabel As Integer
  3813.     Dim iField As Integer
  3814.     Dim iButton As Integer
  3815.     Dim iWidth As Integer
  3816.     Dim bContinue As Integer
  3817.     Dim sValue As String
  3818.     Dim iNextWidth As Integer
  3819.     Dim iType As Integer
  3820.     Dim iIndex As Integer
  3821.    
  3822.     Dim in$
  3823.    
  3824.     ' MOUSE VARIABLES
  3825.     Dim iX1 As Integer: iX1 = 0
  3826.     Dim iY1 As Integer: iY1 = 0
  3827.     Dim iOldX1 As Integer: iOldX1 = 0
  3828.     Dim iOldY1 As Integer: iOldY1 = 0
  3829.     Dim bLeftClick As Integer: bLeftClick = FALSE
  3830.     Dim bOldLeftClick As Integer: bOldLeftClick = FALSE
  3831.    
  3832.     Dim sZone1 As String ' text description of which controller
  3833.     Dim sZone2 As String ' text description of which input
  3834.     Dim iMapPlayer As Integer ' like iController, which of the 8 controllers
  3835.    
  3836.     ' WHICH PORTION OF THE SCREEN USER CLICKED ON
  3837.     Dim iTempX As Integer
  3838.     Dim iTempY As Integer
  3839.     Dim iTextX As Integer
  3840.     Dim iTextY As Integer
  3841.     Dim iOffsetX As Integer
  3842.     Dim iOffsetY As Integer
  3843.    
  3844.     ' BOUNDARIES OF BUTTON CLICKED ON
  3845.     Dim iMapX1 As Integer
  3846.     Dim iMapX2 As Integer
  3847.     Dim iMapY1 As Integer
  3848.     Dim iMapY2 As Integer
  3849.    
  3850.     ' FOR MAPPING CONTROLLER INPUT
  3851.     Dim arrButton(32, 16) As Integer ' number of buttons on the joystick
  3852.     Dim arrButtonNew(32, 16) As Integer ' tracks when to initialize values
  3853.     Dim arrAxis(32, 16) As Double ' number of axis on the joystick
  3854.     Dim arrAxisNew(32, 16) As Integer ' tracks when to initialize values
  3855.     'Dim iPlayer As Integer
  3856.     Dim iController As Integer ' to loop through devices
  3857.     Dim iDevice As Integer
  3858.     Dim iValue As Integer
  3859.     Dim bMoveNext As Integer
  3860.     'Dim iLoop As Integer
  3861.     Dim iCode As Integer
  3862.     Dim bHaveInput As Integer
  3863.     'Dim iWhichInput As Integer
  3864.     Dim iNextInput As Integer
  3865.     Dim sCaption As String
  3866.     Dim sPrompt As String
  3867.     Dim CloseX As Integer
  3868.     Dim CloseY As Integer
  3869.     Dim dblNextAxis As Double
  3870.     Dim bHitEsc As Integer
  3871.     Dim bHitEnter As Integer
  3872.     Dim bMapMode As Integer ' if TRUE then look for control mapping input
  3873.     Dim ExitX As Integer
  3874.     Dim ExitY As Integer
  3875.    
  3876.     ' =============================================================================
  3877.     ' INITIALIZE
  3878.     if len(sError)=0 then
  3879.         InitKeyboardButtonCodes
  3880.         AddColors arrColor()
  3881.         StringToArray MapArray(), GetMap$
  3882.         SetupScreenAreas
  3883.         SetupButtons
  3884.         SetupTextLabels
  3885.         SetupTextFields
  3886.     end if
  3887.    
  3888.     ' =============================================================================
  3889.     ' MAKE SURE WE HAVE DEVICES
  3890.     if len(sError)=0 then
  3891.         ' 1 is the keyboard
  3892.         ' 2 is the mouse
  3893.         ' 3 is the joystick
  3894.         ' unless someone has a strange setup with multiple mice/keyboards/ect...
  3895.         ' In that case, you can use _DEVICE$(i) to look for "KEYBOARD", "MOUSE", "JOYSTICK", if necessary.
  3896.         ' I've never actually found it necessary, but I figure it's worth mentioning, just in case...
  3897.        
  3898.         iDeviceCount = _Devices ' Find the number of devices on someone's system
  3899.         'If iDeviceCount < 3 Then
  3900.         If iDeviceCount < 1 Then
  3901.             sError = "Enough devices not found."
  3902.         End If
  3903.     end if
  3904.    
  3905.     ' =============================================================================
  3906.     ' COUNT # OF JOYSTICKS
  3907.     ' TODO: find out the right way to count joysticks
  3908.     If Len(sError) = 0 Then
  3909.         ' D= _DEVICES ' MUST be read in order for other 2 device functions to work!
  3910.         iDeviceCount = _Devices ' Find the number of devices on someone's system
  3911.  
  3912.         If iDeviceCount > 2 Then
  3913.             ' LIMIT # OF DEVICES, IF THERE IS A LIMIT DEFINED
  3914.             iNumControllers = iDeviceCount - 2
  3915.             If cMaxControllers > 0 Then
  3916.                 If iNumControllers > cMaxControllers Then
  3917.                     iNumControllers = cMaxControllers
  3918.                 End If
  3919.             End If
  3920.         Else
  3921.             ' ONLY 2 FOUND (KEYBOARD, MOUSE)
  3922.             'sError = "No game controllers found."
  3923.             iNumControllers = 0
  3924.         End If
  3925.     End If
  3926.  
  3927.     ' =============================================================================
  3928.     ' INITIALIZE CONTROLLER DATA
  3929.     If Len(sError) = 0 Then
  3930.         For iController = 1 To iNumControllers
  3931.             m_arrController(iController).buttonCount = cMaxButtons
  3932.             m_arrController(iController).axisCount = cMaxAxis
  3933.             For iLoop = 1 To cMaxButtons
  3934.                 arrButtonNew(iController, iLoop) = TRUE
  3935.             Next iLoop
  3936.             For iLoop = 1 To cMaxAxis
  3937.                 arrAxisNew(iController, iLoop) = TRUE
  3938.             Next iLoop
  3939.         Next iController
  3940.     End If
  3941.  
  3942.     ' =============================================================================
  3943.     ' INITIALIZE CONTROLLER INPUT
  3944.     If Len(sError) = 0 Then
  3945.         _KeyClear: _Delay 1
  3946.         For iController = 1 To iNumControllers
  3947.             iDevice = iController + 2
  3948.             While _DeviceInput(iDevice) ' clear and update the device buffer
  3949.                 For iLoop = 1 To _LastButton(iDevice)
  3950.                     If (iLoop > cMaxButtons) Then Exit For
  3951.                     m_arrController(iController).buttonCount = iLoop
  3952.                     arrButton(iController, iLoop) = FALSE
  3953.                 Next iLoop
  3954.                 For iLoop = 1 To _LastAxis(iDevice) ' this loop checks all my axis
  3955.                     If (iLoop > cMaxAxis) Then Exit For
  3956.                     m_arrController(iController).axisCount = iLoop
  3957.                     arrAxis(iController, iLoop) = 0
  3958.                 Next iLoop
  3959.             Wend ' clear and update the device buffer
  3960.         Next iController
  3961.     End If
  3962.    
  3963.     ' =============================================================================
  3964.     ' INIT SCREEN
  3965.     if len(sError)=0 then
  3966.         Screen _NewImage(1024, 768, 32): _ScreenMove 0, 0
  3967.         UpdateDisplayMapInput2 arrColor(), MapArray(), ScreenArray()
  3968.     end if
  3969.    
  3970.     ' =============================================================================
  3971.     ' MAIN LOOP
  3972.     if len(sError)=0 then
  3973.         ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3974.         ' BEGIN MOUSE #MOUSE
  3975.         ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3976.         bFinished = FALSE
  3977.         bHitEsc = FALSE
  3978.         bHitEnter = FALSE
  3979.         bMapMode = FALSE
  3980.         CloseX = 0
  3981.         CloseY = 0
  3982.        
  3983.         ExitX = (_Width(0) \ _FontWidth) -4
  3984.         ExitY = 1 ' _Height(0) \ _FontHeight
  3985.        
  3986.         _MouseHide ' hide OS mouse pointer
  3987.         Do
  3988.             ' READ MOUSE
  3989.             Do While _MouseInput: Loop
  3990.            
  3991.             ' ERASE CURSOR
  3992.             If iOldX1 <> iX1 Or iOldY1 <> iY1 Then
  3993.                 if iOldX1 > 0 and iOldY1 > 0 then
  3994.                     iTextY = iOldY1 \ _FontHeight
  3995.                     iTextX = iOldX1 \ _FontWidth
  3996.                     Color ScreenArray(iTextY, iTextX).fgColor, ScreenArray(iTextY, iTextX).bgColor
  3997.                     PrintString1 iTextY, iTextX, ScreenArray(iTextY, iTextX).value
  3998.                 end if
  3999.             End If
  4000.            
  4001.             ' SAVE OLD POSITION
  4002.             iOldY1 = iY1
  4003.             iOldX1 = iX1
  4004.             iTempY = iOldY1 \ _FontHeight
  4005.             iTempX = iOldX1 \ _FontWidth
  4006.            
  4007.             ' GET NEW POSITION
  4008.             iY1 = ((_MouseY \ _FontHeight)+1) * _FontHeight
  4009.             iX1 = ((_MouseX \ _FontWidth)+1) * _FontWidth
  4010.             iTextY = iY1 \ _FontHeight
  4011.             iTextX = iX1 \ _FontWidth
  4012.            
  4013.             ' DRAW CURSOR
  4014.             Color cBlack, cMagenta
  4015.             PrintString1 iTextY, iTextX, " "
  4016.            
  4017.             ' LEFT CLICK
  4018.             bLeftClick = _MouseButton(1)
  4019.             If bLeftClick Then
  4020.                 If bOldLeftClick = FALSE Then
  4021.                     ' (CLICK ACTION HERE)
  4022.                    
  4023.                     ' IS SELECTING A CONTROL TO MAP, OR MAPPING A CONTROL?
  4024.                     If CloseX=0 Or CloseY=0 Then
  4025.                        
  4026.                         ' DID THEY CLOSE?
  4027.                         If (iTextY = ExitY) And (iTextX >= ExitX) Then
  4028.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4029.                             ' USER CLICKED EXIT SCREEN
  4030.                             bFinished = True
  4031.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4032.                         Else
  4033.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4034.                             ' BEGIN USER IS SELECTING A CONTROL TO MAP
  4035.                            
  4036.                             ' WHICH CONTROLLER?
  4037.                             for iIndex = lbound(m_arrScreenArea) to ubound(m_arrScreenArea)
  4038.                                 if iTextY >= m_arrScreenArea(iIndex).y1 then
  4039.                                     if iTextY <= m_arrScreenArea(iIndex).y2 then
  4040.                                         if iTextX >= m_arrScreenArea(iIndex).x1 then
  4041.                                             if iTextX <= m_arrScreenArea(iIndex).x2 then
  4042.                                                 iMapPlayer = m_arrScreenArea(iIndex).player
  4043.                                                 sZone1 = m_arrScreenArea(iIndex).item
  4044.                                                 iOffsetX = m_arrScreenArea(iIndex).x1 - 1
  4045.                                                 iOffsetY = m_arrScreenArea(iIndex).y1 - 1
  4046.                                                 exit for
  4047.                                             end if
  4048.                                         end if
  4049.                                     end if
  4050.                                 end if
  4051.                             next iIndex
  4052.                            
  4053.                             ' WHICH BUTTON?
  4054.                             for iIndex = lbound(m_arrButton) to ubound(m_arrButton)
  4055.                                 if iTextY >= m_arrButton(iIndex).y1+iOffsetY then
  4056.                                     if iTextY <= m_arrButton(iIndex).y2+iOffsetY then
  4057.                                         if iTextX >= m_arrButton(iIndex).x1+iOffsetX then
  4058.                                             if iTextX <= m_arrButton(iIndex).x2+iOffsetX then
  4059.                                                
  4060.                                                 iWhichInput = m_arrButton(iIndex).typ ' cInputUp, cInputDown, cInputLeft, cInputRight, cInputButton1, cInputButton2, cInputButton3, cInputButton4
  4061.                                                 sZone2 = m_arrButton(iIndex).item
  4062.                                                
  4063.                                                 DebugPrint "clicked " + sZone1 + ", " + sZone2
  4064.                                                
  4065.                                                 'iMapX1 = m_arrButton(iIndex).x1+iOffsetX
  4066.                                                 'iMapX2 = m_arrButton(iIndex).x2+iOffsetX
  4067.                                                 'iMapY1 = m_arrButton(iIndex).y1+iOffsetY
  4068.                                                 'iMapY2 = m_arrButton(iIndex).y2+iOffsetY
  4069.                                                 '
  4070.                                                 'sPrompt = ""
  4071.                                                 'sPrompt = sPrompt + "Move control" + chr$(13)
  4072.                                                 'sPrompt = sPrompt + "or press key " + chr$(13)
  4073.                                                 'sPrompt = sPrompt + "for " + InputToString$(iWhichInput) + chr$(13)
  4074.                                                 'sPrompt = sPrompt + "<ESC> + <ENTER>" + chr$(13)
  4075.                                                 'sPrompt = sPrompt + "to cancel."
  4076.                                                 'MapInputPrompt sPrompt, iMapX1, iMapX2, iMapY1, iMapY2, cBlack, cWhite
  4077.                                                
  4078.                                                 sCaption = "Map " + InputToString$(iWhichInput) + " for " + cstr$(iMapPlayer)
  4079.                                                 sPrompt = ""
  4080.                                                 sPrompt = sPrompt + "Move controller or press key" + chr$(13)
  4081.                                                 sPrompt = sPrompt + "or click close 'x' to cancel."
  4082.                                                 MapInputPopup sCaption, cWhite, cGray, sPrompt, cBlack, cWhite, CloseX, CloseY, ScreenArray()
  4083.                                                
  4084.                                             end if
  4085.                                         end if
  4086.                                     end if
  4087.                                 end if
  4088.                             next iIndex
  4089.                             ' END USER IS SELECTING A CONTROL TO MAP
  4090.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4091.                         End If
  4092.                     Else
  4093.                         ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4094.                         ' BEGIN USER CLICKED TO CANCEL MAP MODE
  4095.                         If iTextY = ExitY And iTextX = ExitX Then
  4096.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4097.                             ' USER CLICKED EXIT SCREEN
  4098.                             bFinished = True
  4099.                             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4100.                            
  4101.                         ElseIf iTextY = CloseY And iTextX = CloseX Then
  4102.                             ' USER CLICKED "CANCEL"
  4103.                            
  4104.                             ' EXIT MAP MODE
  4105.                             CloseX = 0
  4106.                             CloseY = 0
  4107.                            
  4108.                             ' REFRESH SCREEN
  4109.                             UpdateDisplayMapInput2 arrColor(), MapArray(), ScreenArray()
  4110.                            
  4111.                         End If
  4112.                         ' END USER CLICKED TO CANCEL MAP MODE
  4113.                         ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4114.                        
  4115.                     End If                    
  4116.                     bOldLeftClick = TRUE
  4117.                 End If
  4118.             Else
  4119.                 ' USER RELEASED MOUSE BUTTON
  4120.                 bOldLeftClick = FALSE
  4121.                 sZone1 = ""
  4122.                 sZone2 = ""
  4123.                 iOffsetX = 0
  4124.                 iOffsetY = 0
  4125.             End If
  4126.            
  4127.             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4128.             ' BEGIN LOOK FOR MAPPING INPUT
  4129.             If CloseX > 0 And CloseY > 0 Then
  4130.                 ' =============================================================================
  4131.                 ' BEGIN LOOK FOR NEXT INPUT
  4132.                 bMoveNext = FALSE
  4133.                
  4134.                 ' -----------------------------------------------------------------------------
  4135.                 ' BEGIN CHECK FOR CONTROLLER INPUT
  4136.                 For iController = 1 To iNumControllers
  4137.                     iDevice = iController + 2
  4138.                    
  4139.                     ' Check all devices
  4140.                     While _DeviceInput(iDevice)
  4141.                        
  4142.                         ' Check each button
  4143.                         If bMoveNext = FALSE Then
  4144.                             For iLoop = 1 To _LastButton(iDevice)
  4145.                                 If (iLoop > cMaxButtons) Then Exit For
  4146.                                 'm_arrController(iController).buttonCount = iLoop
  4147.                                
  4148.                                 ' update button array to indicate if a button is up or down currently.
  4149.                                 If _ButtonChange(iLoop) Then
  4150.                                     iValue = _Button(iLoop)
  4151.                                     If iValue <> arrButton(iController, iLoop) Then
  4152.                                         ' *****************************************************************************
  4153.                                         ' PRESSED BUTTON
  4154.                                        
  4155.                                         ' make sure this isn't already mapped
  4156.                                         bHaveInput = TRUE
  4157.                                         If iWhichInput > LBound(m_arrControlMap, 2) Then
  4158.                                             ' is input unique?
  4159.                                             For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4160.                                                 If m_arrControlMap(iMapPlayer, iNextInput).device = iDevice Then
  4161.                                                     If m_arrControlMap(iMapPlayer, iNextInput).typ = cInputButton Then
  4162.                                                         If m_arrControlMap(iMapPlayer, iNextInput).code = iLoop Then
  4163.                                                             If m_arrControlMap(iMapPlayer, iNextInput).value = iValue Then
  4164.                                                                 bHaveInput = FALSE
  4165.                                                             End If
  4166.                                                         End If
  4167.                                                     End If
  4168.                                                 End If
  4169.                                             Next iNextInput
  4170.                                         End If
  4171.                                        
  4172.                                         If bHaveInput Then
  4173.                                             m_arrControlMap(iMapPlayer, iWhichInput).device = iDevice
  4174.                                             m_arrControlMap(iMapPlayer, iWhichInput).typ = cInputButton
  4175.                                             m_arrControlMap(iMapPlayer, iWhichInput).code = iLoop
  4176.                                             m_arrControlMap(iMapPlayer, iWhichInput).value = iValue
  4177.                                             bMoveNext = TRUE
  4178.                                             Exit For
  4179.                                         End If
  4180.                                        
  4181.                                     End If
  4182.                                 End If
  4183.                             Next iLoop
  4184.                         End If
  4185.                        
  4186.                         ' Check each axis
  4187.                         If bMoveNext = FALSE Then
  4188.                             For iLoop = 1 To _LastAxis(iDevice)
  4189.                                 If (iLoop > cMaxAxis) Then Exit For
  4190.                                 'm_arrController(iController).axisCount = iLoop
  4191.                                
  4192.                                 dblNextAxis = _Axis(iLoop)
  4193.                                 dblNextAxis = RoundUpDouble#(dblNextAxis, 3)
  4194.                                
  4195.                                 ' I like to give a little "jiggle" resistance to my controls, as I have an old joystick
  4196.                                 ' which is prone to always give minute values and never really center on true 0.
  4197.                                 ' A value of 1 means my axis is pushed fully in one direction.
  4198.                                 ' A value greater than 0.1 means it's been partially pushed in a direction (such as at a 45 degree diagional angle).
  4199.                                 ' A value of less than 0.1 means we count it as being centered. (As if it was 0.)
  4200.                                
  4201.                                 'These are way too sensitive for analog:
  4202.                                 'IF ABS(_AXIS(iLoop)) <= 1 AND ABS(_AXIS(iLoop)) >= .1 THEN
  4203.                                 'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .01 THEN
  4204.                                 'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .001 THEN
  4205.                                
  4206.                                 'For digital input, we'll use a big picture:
  4207.                                 If Abs(dblNextAxis) <= 1 And Abs(dblNextAxis) >= 0.75 Then
  4208.                                     If dblNextAxis <> arrAxis(iController, iLoop) Then
  4209.                                         ' *****************************************************************************
  4210.                                         ' MOVED STICK
  4211.                                        
  4212.                                         ' convert to a digital value
  4213.                                         If dblNextAxis < 0 Then
  4214.                                             iValue = -1
  4215.                                         Else
  4216.                                             iValue = 1
  4217.                                         End If
  4218.                                        
  4219.                                         ' make sure this isn't already mapped
  4220.                                         bHaveInput = TRUE
  4221.                                         If iWhichInput > LBound(m_arrControlMap, 2) Then
  4222.                                             ' is input unique?
  4223.                                             For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4224.                                                 If m_arrControlMap(iMapPlayer, iNextInput).device = iDevice Then
  4225.                                                     If m_arrControlMap(iMapPlayer, iNextInput).typ = cInputAxis Then
  4226.                                                         If m_arrControlMap(iMapPlayer, iNextInput).code = iLoop Then
  4227.                                                             If m_arrControlMap(iMapPlayer, iNextInput).value = iValue Then
  4228.                                                                 bHaveInput = FALSE
  4229.                                                             End If
  4230.                                                         End If
  4231.                                                     End If
  4232.                                                 End If
  4233.                                             Next iNextInput
  4234.                                         End If
  4235.                                        
  4236.                                         If bHaveInput Then
  4237.                                             m_arrControlMap(iMapPlayer, iWhichInput).device = iDevice
  4238.                                             m_arrControlMap(iMapPlayer, iWhichInput).typ = cInputAxis
  4239.                                             m_arrControlMap(iMapPlayer, iWhichInput).code = iLoop
  4240.                                             m_arrControlMap(iMapPlayer, iWhichInput).value = iValue
  4241.                                             bMoveNext = TRUE
  4242.                                             Exit For
  4243.                                         End If
  4244.                                        
  4245.                                     End If
  4246.                                 End If
  4247.                             Next iLoop
  4248.                         End If
  4249.                        
  4250.                     Wend ' clear and update the device buffer
  4251.                    
  4252.                 Next iController
  4253.                 ' END CHECK FOR CONTROLLER INPUT
  4254.                 ' -----------------------------------------------------------------------------
  4255.                
  4256.                 ' -----------------------------------------------------------------------------
  4257.                 ' BEGIN CHECK FOR KEYBOARD INPUT #1
  4258.                 If bMoveNext = FALSE Then
  4259.                     '_KEYCLEAR: _DELAY 1
  4260.                     While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  4261.                    
  4262.                     ' Detect changed key state
  4263.                     For iLoop = LBound(m_arrButtonCode) To UBound(m_arrButtonCode)
  4264.                         iCode = m_arrButtonCode(iLoop)
  4265.                         If _Button(iCode) <> FALSE Then
  4266.                             ' *****************************************************************************
  4267.                             ' PRESSED KEYBOARD
  4268.                             'PRINT "PRESSED " + m_arrButtonKey(iLoop)
  4269.                            
  4270.                             ' make sure this isn't already mapped
  4271.                             bHaveInput = TRUE
  4272.                             If iWhichInput > LBound(m_arrControlMap, 2) Then
  4273.                                 ' is input unique?
  4274.                                 For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4275.                                     If m_arrControlMap(iMapPlayer, iNextInput).device = 1 Then ' .device 1 = keyboard
  4276.                                         If m_arrControlMap(iMapPlayer, iNextInput).typ = cInputKey Then
  4277.                                             If m_arrControlMap(iMapPlayer, iNextInput).code = iCode Then
  4278.                                                 'if m_arrControlMap(iMapPlayer, iNextInput).value = TRUE then
  4279.                                                 bHaveInput = FALSE
  4280.                                                 'end if
  4281.                                             End If
  4282.                                         End If
  4283.                                     End If
  4284.                                 Next iNextInput
  4285.                             End If
  4286.                            
  4287.                             If bHaveInput Then
  4288.                                 m_arrControlMap(iMapPlayer, iWhichInput).device = 1 ' .device 1 = keyboard
  4289.                                 m_arrControlMap(iMapPlayer, iWhichInput).typ = cInputKey
  4290.                                 m_arrControlMap(iMapPlayer, iWhichInput).code = iCode
  4291.                                 m_arrControlMap(iMapPlayer, iWhichInput).value = TRUE
  4292.                                 bMoveNext = TRUE
  4293.                                
  4294.                                 ' CLEAR KEYBOARD BUFFER
  4295.                                 _KEYCLEAR: _DELAY 1
  4296.                                
  4297.                                 Exit For
  4298.                             End If
  4299.                            
  4300.                         End If
  4301.                     Next iLoop
  4302.                 End If
  4303.                 ' END CHECK FOR KEYBOARD INPUT #1
  4304.                 ' -----------------------------------------------------------------------------
  4305.                
  4306.                 If bMoveNext = TRUE Then
  4307.                     ' WE HAVE MAPPED SOMETHING
  4308.                m_bHaveMapping = TRUE
  4309.                
  4310.                ' EXIT MAPPING MODE
  4311.                     CloseX = 0
  4312.                     CloseY = 0
  4313.                     iOffsetX = 0
  4314.                     iOffsetY = 0
  4315.                    
  4316.                     ' REFRESH SCREEN
  4317.                     UpdateDisplayMapInput2 arrColor(), MapArray(), ScreenArray()
  4318.                 End If
  4319.                
  4320.                 ' END LOOK FOR NEXT INPUT
  4321.                 ' =============================================================================
  4322.                
  4323.             End If
  4324.             ' END LOOK FOR MAPPING INPUT
  4325.             ' @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  4326.            
  4327.             _Limit 30
  4328.         Loop Until bFinished
  4329.        
  4330.         _MouseShow "default": _Delay 0.5
  4331.         ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4332.         ' END MOUSE @MOUSE
  4333.         ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  4334.     End If
  4335.    
  4336.     ' CLEAR KEYBOARD BUFFER
  4337.     _KeyClear
  4338.    
  4339.     ' CLEAR SCREEN
  4340.     Color cWhite, cBlack
  4341.     Cls
  4342.    
  4343.     ' DONE
  4344.     MapInput2$ = sResult
  4345.    
  4346. End Function ' MapInput2$
  4347.  
  4348. ' /////////////////////////////////////////////////////////////////////////////
  4349. ' Displays a popup with a close button "X" in the upper right,
  4350. ' with text in MyString.
  4351.  
  4352. ' Returns the x,y position of the close button in parameters CloseX, CloseY.
  4353.  
  4354. ' Resolution    Cols   Rows
  4355. ' 1024 x  768   128    48
  4356.  
  4357. ' MapInputPopup sCaption, cBlack, cGray, sText, cBlack, cWhite, CloseX, CloseY
  4358.  
  4359. Sub MapInputPopup( _
  4360.     sCaption2 As String, fgCaptionColor  As _Unsigned Long, bgCaptionColor As _Unsigned Long, _
  4361.     sText As String, fgTextColor As _Unsigned Long, bgTextColor As _Unsigned Long, _
  4362.     CloseX As Integer, CloseY As Integer, ScreenArray() As TextCellType _
  4363.     )
  4364.    
  4365.     ReDim arrLines(-1) As String
  4366.     Dim sCaption As String
  4367.     Dim iCols As Integer
  4368.     Dim iRows As Integer
  4369.     Dim iColCount As Integer
  4370.     Dim iRowCount As Integer
  4371.     Dim iLoopRows As Integer
  4372.     Dim iWidth As Integer
  4373.    
  4374.     Dim x1 As Integer
  4375.     Dim x2 As Integer
  4376.     Dim y1 As Integer
  4377.     Dim y2 As Integer
  4378.     Dim iY As Integer
  4379.    
  4380.     ' Figure out window size
  4381.     sCaption = sCaption2
  4382.     iCols = _Width(0) \ _FontWidth
  4383.     iRows = _Height(0) \ _FontHeight
  4384.     iColCount = len(sCaption)+1
  4385.     iRowCount = 0
  4386.     split sText, chr$(13), arrLines()
  4387.     For iLoopRows = lbound(arrLines) to ubound(arrLines)
  4388.         iRowCount = iRowCount + 1
  4389.         if len(arrLines(iLoopRows)) > iColCount then
  4390.             iColCount = len(arrLines(iLoopRows))
  4391.         end if
  4392.     Next iLoopRows
  4393.    
  4394.     ' Draw window as long as there is text
  4395.     If iColCount > 0 Then
  4396.         ' Make sure popup is not wider than screen
  4397.         If iColCount > iCols Then iColCount = iCols
  4398.         If iRowCount > iRows Then iRowCount = iRows
  4399.         If len(sCaption) > (iCols-1) Then sCaption = left$(sCaption, iCols-1)
  4400.        
  4401.         ' Center the popup
  4402.         x1 = (iCols - iColCount) \ 2
  4403.         y1 = (iRows - iRowCount) \ 2
  4404.         x2 = x1 + (iColCount - 1)
  4405.         y2 = y1 + (iRowCount - 1)
  4406.        
  4407.         ' Draw the caption
  4408.         Color fgCaptionColor, bgCaptionColor
  4409.         'PrintString1 y1, x1, left$(sCaption + string$(iColCount, " "), iColCount)
  4410.         PrintString2 y1, x1, left$(sCaption + string$(iColCount, " "), iColCount), ScreenArray()
  4411.        
  4412.         ' Draw the close button
  4413.         Color fgTextColor, bgTextColor
  4414.         'PrintString1 y1, x2, "X"
  4415.         PrintString2 y1, x2, "X", ScreenArray()
  4416.         CloseX = x2 :CloseY = y1
  4417.        
  4418.         ' Get width
  4419.         iWidth = (x2 - x1) + 1
  4420.        
  4421.         ' Draw the popup
  4422.         iY = y1
  4423.         Color fgTextColor, bgTextColor
  4424.         For iLoopRows = lbound(arrLines) to ubound(arrLines)
  4425.             iY = iY + 1 : if iY > y2 then exit for
  4426.             PrintString2 iY, x1, left$(arrLines(iLoopRows) + String$(iWidth, " "), iWidth), ScreenArray()
  4427.         Next iLoopRows
  4428.         For iLoopRows = iY to y2
  4429.             'PrintString1 iY, x1, String$(iColCount, " ")
  4430.             PrintString2 iLoopRows, x1, String$(iWidth, " "), ScreenArray()
  4431.         Next iLoopRows
  4432.     Else
  4433.         CloseX = 0 : CloseY = 0
  4434.     End If
  4435. End Sub ' MapInputPopup
  4436.  
  4437. ' /////////////////////////////////////////////////////////////////////////////
  4438. ' MapInputPrompt MyString, iMapX1, iMapX2, iMapY1, iMapY2, cBlack, cWhite
  4439.  
  4440. Sub MapInputPrompt(MyString As String, x1 As Integer, x2 As Integer, y1 As Integer, y2 As Integer, fgColor As _Unsigned Long, bgColor As _Unsigned Long)
  4441.     ReDim arrLines(-1) As String
  4442.     Dim iLoopRows As Integer
  4443.     Dim iMaxLen As Integer
  4444.     Dim iY As Integer
  4445.     if x2 >= x1 then
  4446.         if y2 >= y1 then
  4447.             iMaxLen = (x2 - x1)+1
  4448.             split MyString, chr$(13), arrLines()
  4449.             iLine = 0
  4450.             iY = y1
  4451.             For iLoopRows = lbound(arrLines) to ubound(arrLines)
  4452.                 Color fgColor, bgColor
  4453.                 if len(arrLines(iLoopRows)) > iMaxLen then
  4454.                     PrintString1 iY, x1, left$(arrLines(iLoopRows), iMaxLen)
  4455.                 else
  4456.                     PrintString1 iY, x1, left$(arrLines(iLoopRows) + String$(iMaxLen, " "), iMaxLen)
  4457.                 end if
  4458.                 iY = iY + 1
  4459.                 if iY > y2 then
  4460.                     exit for
  4461.                 end if
  4462.             Next iLoopRows
  4463.             For iLoopRows = iY to y2
  4464.                 PrintString1 iY, x1, String$(iMaxLen, " ")
  4465.             Next iLoopRows
  4466.         end if
  4467.     end if
  4468. End Sub ' MapInputPrompt
  4469.  
  4470. ' /////////////////////////////////////////////////////////////////////////////
  4471.  
  4472. Sub DebugPause (sPrompt As String, iRow As Integer, iColumn As Integer, fgColor As _Unsigned Long, bgColor As _Unsigned Long)
  4473.     Color fgColor, bgColor
  4474.    
  4475.     PrintString iRow, iColumn, String$(128, " ")
  4476.    
  4477.     PrintString iRow, iColumn, sPrompt
  4478.     Sleep
  4479.     '_KEYCLEAR: _DELAY 1
  4480.     'DO
  4481.     'LOOP UNTIL _KEYDOWN(13) ' leave loop when ENTER key pressed
  4482.     '_KEYCLEAR: _DELAY 1
  4483. End Sub ' DebugPause
  4484.  
  4485. ' /////////////////////////////////////////////////////////////////////////////
  4486.  
  4487. Sub DebugOut (sPrompt As String, iRow As Integer, iColumn As Integer, fgColor As _Unsigned Long, bgColor As _Unsigned Long)
  4488.     Color fgColor, bgColor
  4489.     PrintString iRow, iColumn, String$(128, " ")
  4490.     PrintString iRow, iColumn, sPrompt
  4491. End Sub ' DebugOut
  4492.  
  4493. ' /////////////////////////////////////////////////////////////////////////////
  4494.  
  4495. Function TestMouseXYButton$
  4496.     Dim RoutineName As String: RoutineName = "TestMouseXYButton$"
  4497.     Dim iX1 As Integer: iX1 = 0
  4498.     Dim iY1 As Integer: iY1 = 0
  4499.     Dim iOldX1 As Integer: iOldX1 = 0
  4500.     Dim iOldY1 As Integer: iOldY1 = 0
  4501.     Dim bLeftClick As Integer: bLeftClick = FALSE
  4502.     Dim bRightClick As Integer: bRightClick = FALSE
  4503.     Dim bMiddleClick As Integer: bMiddleClick = FALSE
  4504.     Dim bOldLeftClick As Integer: bOldLeftClick = FALSE
  4505.     Dim bOldRightClick As Integer: bOldRightClick = FALSE
  4506.     Dim bOldMiddleClick As Integer: bOldMiddleClick = FALSE
  4507.     Dim iX2 As Integer: iX2 = _Width / 2
  4508.     Dim iY2 As Integer: iY2 = _Height / 2
  4509.     Dim iOldX2 As Integer: iOldX2 = 0
  4510.     Dim iOldY2 As Integer: iOldY2 = 0
  4511.     Dim iColor1 As _Unsigned Long: iColor1 = cRed
  4512.     Dim iColor2 As _Unsigned Long: iColor2 = cLime
  4513.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  4514.     Cls
  4515.  
  4516.     _MouseHide ' hide OS mouse pointer
  4517.     Do
  4518.         Color cWhite, cBlack
  4519.         If iOldX1 <> iX1 Or iOldY1 <> iY1 Then _PrintString (iOldX1, iOldY1), " "
  4520.         If iOldX2 <> iX2 Or iOldY2 <> iY2 Then _PrintString (iOldX2, iOldY2), " "
  4521.  
  4522.         Color cWhite, cEmpty
  4523.         PrintString 0, 0, "_MOUSEX        ="
  4524.         PrintString 1, 0, "_MOUSEY        ="
  4525.         PrintString 2, 0, "_MOUSEBUTTON(1)="
  4526.         PrintString 3, 0, "_MOUSEBUTTON(2)="
  4527.         PrintString 4, 0, "_MOUSEBUTTON(3)="
  4528.         PrintString 5, 0, "_MOUSEWHEEL X  ="
  4529.         PrintString 6, 0, "_MOUSEWHEEL Y  ="
  4530.         PrintString 8, 0, "PRESS <ESC> TO EXIT"
  4531.  
  4532.         Color cWhite, cBlack
  4533.         PrintString 0, 16, Left$(cstr$(iX1) + "     ", 5)
  4534.         PrintString 1, 16, Left$(cstr$(iY1) + "     ", 5)
  4535.         PrintString 2, 16, Left$(TrueFalse$(bLeftClick) + "     ", 5)
  4536.         PrintString 3, 16, Left$(TrueFalse$(bRightClick) + "     ", 5)
  4537.         PrintString 4, 16, Left$(TrueFalse$(bMiddleClick) + "     ", 5)
  4538.         PrintString 5, 16, Left$(cstr$(iX2) + "     ", 5)
  4539.         PrintString 6, 16, Left$(cstr$(iY2) + "     ", 5)
  4540.  
  4541.         Color cBlack, iColor1: _PrintString (iX1, iY1), " "
  4542.         iOldX1 = iX1: iOldY1 = iY1
  4543.  
  4544.         Color cBlack, iColor2: _PrintString (iX2, iY2), " "
  4545.         iOldX2 = iX2: iOldY2 = iY2
  4546.  
  4547.         iX1 = (_MouseX \ _FontWidth) * _FontWidth
  4548.         iY1 = (_MouseY \ _FontHeight) * _FontHeight
  4549.  
  4550.         bLeftClick = _MouseButton(1)
  4551.         If bLeftClick Then
  4552.             If bOldLeftClick = FALSE Then
  4553.                 If iColor1 = cOrangeRed Then
  4554.                     iColor1 = cRed
  4555.                 ElseIf iColor1 = cRed Then
  4556.                     iColor1 = cMagenta
  4557.                 Else
  4558.                     iColor1 = cOrangeRed
  4559.                 End If
  4560.                 bOldLeftClick = TRUE
  4561.             End If
  4562.         Else
  4563.             bOldLeftClick = FALSE
  4564.         End If
  4565.  
  4566.         bRightClick = _MouseButton(2)
  4567.         If bRightClick Then
  4568.             If bOldRightClick = FALSE Then
  4569.                 If iColor2 = cBlue Then
  4570.                     iColor2 = cLime
  4571.                 ElseIf iColor2 = cLime Then
  4572.                     iColor2 = cYellow
  4573.                 Else
  4574.                     iColor2 = cBlue
  4575.                 End If
  4576.                 bOldRightClick = TRUE
  4577.             End If
  4578.         Else
  4579.             bOldRightClick = FALSE
  4580.         End If
  4581.  
  4582.         bMiddleClick = _MouseButton(3)
  4583.  
  4584.         Do While _MouseInput
  4585.             If bMiddleClick Then
  4586.                 iY2 = iY2 + (_MouseWheel * _FontHeight) ' -1 up, 0 no movement, 1 down
  4587.             Else
  4588.                 iX2 = iX2 + (_MouseWheel * _FontWidth) ' -1 up, 0 no movement, 1 down
  4589.             End If
  4590.         Loop
  4591.  
  4592.         If iY2 < 1 Then iY2 = 1
  4593.         If iY2 > (_Height - _FontHeight) Then iY2 = (HEIGHT - _FontHeight)
  4594.  
  4595.     Loop Until _KeyDown(27)
  4596.     _KeyClear
  4597.  
  4598.     _MouseShow "default": _Delay 0.5
  4599.     Screen 0
  4600.     TestMouseXYButton$ = ""
  4601. End Function ' TestMouseXYButton$
  4602.  
  4603. ' /////////////////////////////////////////////////////////////////////////////
  4604.  
  4605. Function MapInput1$
  4606.     Dim RoutineName As String: RoutineName = "MapInput1$"
  4607.     Dim in$
  4608.     Dim iDeviceCount As Integer
  4609.     Dim iPlayer As Integer
  4610.     Dim sResult As String
  4611.     Dim sError As String
  4612.  
  4613.     ' INITIALIZE
  4614.     InitKeyboardButtonCodes
  4615.  
  4616.     ' SET UP SCREEN
  4617.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  4618.  
  4619.     ' MAKE SURE WE HAVE DEVICES
  4620.     ' 1 is the keyboard
  4621.     ' 2 is the mouse
  4622.     ' 3 is the joystick
  4623.     ' unless someone has a strange setup with multiple mice/keyboards/ect...
  4624.     ' In that case, you can use _DEVICE$(i) to look for "KEYBOARD", "MOUSE", "JOYSTICK", if necessary.
  4625.     ' I've never actually found it necessary, but I figure it's worth mentioning, just in case...
  4626.     iDeviceCount = _Devices ' Find the number of devices on someone's system
  4627.     If iDeviceCount > 2 Then
  4628.         '' Try loading map
  4629.         'sError = LoadControllerMap1$
  4630.         'if len(sError) = 0 then
  4631.         '    print "Previous controller mapping loaded."
  4632.         'else
  4633.         '    print "*******************************************************************************"
  4634.         '    print "There were errors loading the controller mapping file:"
  4635.         '    print sError
  4636.         '    print
  4637.         '    print "Try remapping - a new file will be created."
  4638.         '    print "*******************************************************************************"
  4639.         'end if
  4640.         Do
  4641.             PrintControllerMap2
  4642.             Print "To edit mapping, enter a player number (1-" + cstr$(cMaxPlayers) + ") or 0 to exit."
  4643.             Input "Get input for player? "; iPlayer
  4644.             If iPlayer > 0 And iPlayer <= cMaxPlayers Then
  4645.                 sResult = MapInput1b$(iPlayer)
  4646.                 If Len(sResult) = 0 Then
  4647.                     Print "Remember to save mappings when done."
  4648.                 Else
  4649.                     Print sResult
  4650.                 End If
  4651.             Else
  4652.                 sResult = "(Cancelled.)"
  4653.                 Exit Do
  4654.             End If
  4655.         Loop
  4656.     Else
  4657.         sResult = "No controller devices found."
  4658.         Input "PRESS <ENTER> TO CONTINUE", in$
  4659.     End If
  4660.     MapInput1$ = sResult
  4661.  
  4662. End Function ' MapInput1$
  4663.  
  4664. ' /////////////////////////////////////////////////////////////////////////////
  4665. ' Detect controls
  4666. ' THIS VERSION SUPPORTS UPTO 8 JOYSTICKS, WITH UPTO 2 BUTTONS AND 2 AXES EACH
  4667. ' (THIS IS FOR ATARI 2600 JOYSTICKS)
  4668.  
  4669. ' The following shared arrays must be declared:
  4670. '     ReDim Shared m_arrButtonCode(1 To 99) As Long
  4671. '     ReDim Shared m_arrButtonKey(1 To 99) As String
  4672.  
  4673. Function MapInput1b$ (iPlayer As Integer)
  4674.     Dim RoutineName As String:: RoutineName = "MapInput1b$"
  4675.     Dim sResult As String: sResult = ""
  4676.     Dim sError As String: sError = ""
  4677.  
  4678.     Dim in$
  4679.  
  4680.     Dim iDeviceCount As Integer
  4681.     Dim iDevice As Integer
  4682.     Dim iNumControllers As Integer
  4683.     Dim iController As Integer
  4684.  
  4685.     Dim iLoop As Integer
  4686.     Dim strValue As String
  4687.     Dim strAxis As String
  4688.     Dim dblNextAxis As Double
  4689.     Dim iCount As Long
  4690.     Dim iValue As Integer
  4691.     Dim iCode As Integer
  4692.  
  4693.     Dim arrButton(32, 16) As Integer ' number of buttons on the joystick
  4694.     Dim arrButtonNew(32, 16) As Integer ' tracks when to initialize values
  4695.     Dim arrAxis(32, 16) As Double ' number of axis on the joystick
  4696.     Dim arrAxisNew(32, 16) As Integer ' tracks when to initialize values
  4697.  
  4698.     'Dim arrInput(1 To 8) As ControlInputType
  4699.     Dim iWhichInput As Integer
  4700.     Dim bFinished As Integer
  4701.     Dim bHaveInput As Integer
  4702.     Dim bMoveNext As Integer
  4703.     Dim bCancel As Integer
  4704.     Dim iNextInput As Integer
  4705.  
  4706.     ' FOR PRINTING OUTPUT
  4707.     Dim iDigits As Integer ' # digits to display (values are truncated to this length)
  4708.     Dim iColCount As Integer
  4709.     Dim iGroupCount As Integer
  4710.     Dim sLine As String
  4711.     Dim iCols As Integer
  4712.     Dim iRows As Integer
  4713.     Dim iMaxCols As Integer
  4714.  
  4715.     ' INITIALIZE
  4716.     If Len(sError) = 0 Then
  4717.         iDigits = 4 ' 11
  4718.         iColCount = 3
  4719.         iGroupCount = 0 ' re-initialized at the top of every loop
  4720.         iCols = _Width(0) \ _FontWidth
  4721.         iRows = _Height(0) \ _FontHeight
  4722.     End If
  4723.  
  4724.     ' COUNT # OF JOYSTICKS
  4725.     ' TODO: find out the right way to count joysticks
  4726.     If Len(sError) = 0 Then
  4727.         ' D= _DEVICES ' MUST be read in order for other 2 device functions to work!
  4728.         iDeviceCount = _Devices ' Find the number of devices on someone's system
  4729.  
  4730.         If iDeviceCount > 2 Then
  4731.             ' LIMIT # OF DEVICES, IF THERE IS A LIMIT DEFINED
  4732.             iNumControllers = iDeviceCount - 2
  4733.             If cMaxControllers > 0 Then
  4734.                 If iNumControllers > cMaxControllers Then
  4735.                     iNumControllers = cMaxControllers
  4736.                 End If
  4737.             End If
  4738.         Else
  4739.             ' ONLY 2 FOUND (KEYBOARD, MOUSE)
  4740.             sError = "No game controllers found."
  4741.         End If
  4742.     End If
  4743.  
  4744.     ' INITIALIZE CONTROLLER DATA
  4745.     If Len(sError) = 0 Then
  4746.         For iController = 1 To iNumControllers
  4747.             m_arrController(iController).buttonCount = cMaxButtons
  4748.             m_arrController(iController).axisCount = cMaxAxis
  4749.             For iLoop = 1 To cMaxButtons
  4750.                 arrButtonNew(iController, iLoop) = TRUE
  4751.             Next iLoop
  4752.             For iLoop = 1 To cMaxAxis
  4753.                 arrAxisNew(iController, iLoop) = TRUE
  4754.             Next iLoop
  4755.         Next iController
  4756.     End If
  4757.  
  4758.     ' INITIALIZE CONTROLLER INPUT
  4759.     If Len(sError) = 0 Then
  4760.         Cls
  4761.         Print "We will now detect controllers."
  4762.         Print "Do not touch any keys or game controllers during detection."
  4763.         Input "Press <ENTER> to begin"; in$
  4764.         _KeyClear: Print
  4765.         sLine = "Initializing controllers": Print sLine;
  4766.         iMaxCols = (iCols - Len(sLine)) - 1
  4767.         iCount = 0
  4768.         Do
  4769.             iCount = iCount + 1
  4770.             If iCount < iMaxCols Then
  4771.                 Print ".";
  4772.             Else
  4773.                 Print ".": Print sLine: iCount = 0
  4774.             End If
  4775.             For iController = 1 To iNumControllers
  4776.                 iDevice = iController + 2
  4777.                 While _DeviceInput(iDevice) ' clear and update the device buffer
  4778.                     For iLoop = 1 To _LastButton(iDevice)
  4779.                         If (iLoop > cMaxButtons) Then Exit For
  4780.                         m_arrController(iController).buttonCount = iLoop
  4781.                         'IF _BUTTONCHANGE(iLoop) THEN
  4782.                         '    arrButton(iController, iLoop) = _BUTTON(iLoop)
  4783.                         'END IF
  4784.                         arrButton(iController, iLoop) = FALSE
  4785.                     Next iLoop
  4786.                     For iLoop = 1 To _LastAxis(iDevice) ' this loop checks all my axis
  4787.                         If (iLoop > cMaxAxis) Then Exit For
  4788.                         m_arrController(iController).axisCount = iLoop
  4789.                         arrAxis(iController, iLoop) = 0
  4790.                     Next iLoop
  4791.                 Wend ' clear and update the device buffer
  4792.             Next iController
  4793.             _Limit 30
  4794.         Loop Until iCount > 60 ' quit after 2 seconds
  4795.         Print: Print
  4796.     End If
  4797.  
  4798.     ' WAIT FOR INPUT
  4799.     If Len(sError) = 0 Then
  4800.         Cls
  4801.         Print "Press <ESCAPE> to cancel at any time."
  4802.         Print
  4803.  
  4804.         _KeyClear: _Delay 1
  4805.         bCancel = FALSE
  4806.         bFinished = FALSE
  4807.         iLastPressed = 0
  4808.         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  4809.             'print "iWhichInput=" + cstr$(iWhichInput)
  4810.             Print "Player #" + cstr$(iPlayer) + " press control for " + InputToString$(iWhichInput) + " or ESC to skip: ";
  4811.  
  4812.             ' =============================================================================
  4813.             ' BEGIN LOOK FOR NEXT INPUT
  4814.             bMoveNext = FALSE
  4815.             Do
  4816.                 ' -----------------------------------------------------------------------------
  4817.                 ' BEGIN CHECK FOR CONTROLLER INPUT
  4818.                 For iController = 1 To iNumControllers
  4819.                     iDevice = iController + 2
  4820.  
  4821.                     ' Check all devices
  4822.                     While _DeviceInput(iDevice)
  4823.  
  4824.                         ' Check each button
  4825.                         If bMoveNext = FALSE Then
  4826.                             For iLoop = 1 To _LastButton(iDevice)
  4827.                                 If (iLoop > cMaxButtons) Then Exit For
  4828.                                 'm_arrController(iController).buttonCount = iLoop
  4829.  
  4830.                                 ' update button array to indicate if a button is up or down currently.
  4831.                                 If _ButtonChange(iLoop) Then
  4832.                                     iValue = _Button(iLoop)
  4833.                                     If iValue <> arrButton(iController, iLoop) Then
  4834.                                         ' *****************************************************************************
  4835.                                         ' PRESSED BUTTON
  4836.  
  4837.                                         ' make sure this isn't already mapped
  4838.                                         bHaveInput = TRUE
  4839.                                         If iWhichInput > LBound(m_arrControlMap, 2) Then
  4840.                                             ' is input unique?
  4841.                                             For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4842.                                                 If m_arrControlMap(iPlayer, iNextInput).device = iDevice Then
  4843.                                                     If m_arrControlMap(iPlayer, iNextInput).typ = cInputButton Then
  4844.                                                         If m_arrControlMap(iPlayer, iNextInput).code = iLoop Then
  4845.                                                             If m_arrControlMap(iPlayer, iNextInput).value = iValue Then
  4846.                                                                 bHaveInput = FALSE
  4847.                                                             End If
  4848.                                                         End If
  4849.                                                     End If
  4850.                                                 End If
  4851.                                             Next iNextInput
  4852.                                         End If
  4853.  
  4854.                                         If bHaveInput Then
  4855.                                             m_arrControlMap(iPlayer, iWhichInput).device = iDevice
  4856.                                             m_arrControlMap(iPlayer, iWhichInput).typ = cInputButton
  4857.                                             m_arrControlMap(iPlayer, iWhichInput).code = iLoop
  4858.                                             m_arrControlMap(iPlayer, iWhichInput).value = iValue
  4859.                                             bMoveNext = TRUE
  4860.                                         End If
  4861.  
  4862.                                     End If
  4863.                                 End If
  4864.                             Next iLoop
  4865.                         End If
  4866.  
  4867.                         ' Check each axis
  4868.                         If bMoveNext = FALSE Then
  4869.                             For iLoop = 1 To _LastAxis(iDevice)
  4870.                                 If (iLoop > cMaxAxis) Then Exit For
  4871.                                 'm_arrController(iController).axisCount = iLoop
  4872.  
  4873.                                 dblNextAxis = _Axis(iLoop)
  4874.                                 dblNextAxis = RoundUpDouble#(dblNextAxis, 3)
  4875.  
  4876.                                 ' I like to give a little "jiggle" resistance to my controls, as I have an old joystick
  4877.                                 ' which is prone to always give minute values and never really center on true 0.
  4878.                                 ' A value of 1 means my axis is pushed fully in one direction.
  4879.                                 ' A value greater than 0.1 means it's been partially pushed in a direction (such as at a 45 degree diagional angle).
  4880.                                 ' A value of less than 0.1 means we count it as being centered. (As if it was 0.)
  4881.  
  4882.                                 'These are way too sensitive for analog:
  4883.                                 'IF ABS(_AXIS(iLoop)) <= 1 AND ABS(_AXIS(iLoop)) >= .1 THEN
  4884.                                 'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .01 THEN
  4885.                                 'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .001 THEN
  4886.  
  4887.                                 'For digital input, we'll use a big picture:
  4888.                                 If Abs(dblNextAxis) <= 1 And Abs(dblNextAxis) >= 0.75 Then
  4889.                                     If dblNextAxis <> arrAxis(iController, iLoop) Then
  4890.                                         ' *****************************************************************************
  4891.                                         ' MOVED STICK
  4892.  
  4893.                                         ' convert to a digital value
  4894.                                         If dblNextAxis < 0 Then
  4895.                                             iValue = -1
  4896.                                         Else
  4897.                                             iValue = 1
  4898.                                         End If
  4899.  
  4900.                                         ' make sure this isn't already mapped
  4901.                                         bHaveInput = TRUE
  4902.                                         If iWhichInput > LBound(m_arrControlMap, 2) Then
  4903.                                             ' is input unique?
  4904.                                             For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4905.                                                 If m_arrControlMap(iPlayer, iNextInput).device = iDevice Then
  4906.                                                     If m_arrControlMap(iPlayer, iNextInput).typ = cInputAxis Then
  4907.                                                         If m_arrControlMap(iPlayer, iNextInput).code = iLoop Then
  4908.                                                             If m_arrControlMap(iPlayer, iNextInput).value = iValue Then
  4909.                                                                 bHaveInput = FALSE
  4910.                                                             End If
  4911.                                                         End If
  4912.                                                     End If
  4913.                                                 End If
  4914.                                             Next iNextInput
  4915.                                         End If
  4916.  
  4917.                                         If bHaveInput Then
  4918.                                             m_arrControlMap(iPlayer, iWhichInput).device = iDevice
  4919.                                             m_arrControlMap(iPlayer, iWhichInput).typ = cInputAxis
  4920.                                             m_arrControlMap(iPlayer, iWhichInput).code = iLoop
  4921.                                             m_arrControlMap(iPlayer, iWhichInput).value = iValue
  4922.                                             bMoveNext = TRUE
  4923.                                         End If
  4924.  
  4925.                                     End If
  4926.                                 End If
  4927.                             Next iLoop
  4928.                         End If
  4929.  
  4930.                     Wend ' clear and update the device buffer
  4931.  
  4932.                 Next iController
  4933.                 ' END CHECK FOR CONTROLLER INPUT
  4934.                 ' -----------------------------------------------------------------------------
  4935.  
  4936.                 ' -----------------------------------------------------------------------------
  4937.                 ' BEGIN CHECK FOR KEYBOARD INPUT #1
  4938.                 If bMoveNext = FALSE Then
  4939.                     '_KEYCLEAR: _DELAY 1
  4940.                     While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  4941.  
  4942.                     ' Detect changed key state
  4943.                     For iLoop = LBound(m_arrButtonCode) To UBound(m_arrButtonCode)
  4944.                         iCode = m_arrButtonCode(iLoop)
  4945.                         If _Button(iCode) <> FALSE Then
  4946.                             ' *****************************************************************************
  4947.                             ' PRESSED KEYBOARD
  4948.                             'PRINT "PRESSED " + m_arrButtonKey(iLoop)
  4949.  
  4950.                             ' make sure this isn't already mapped
  4951.                             bHaveInput = TRUE
  4952.                             If iWhichInput > LBound(m_arrControlMap, 2) Then
  4953.                                 ' is input unique?
  4954.                                 For iNextInput = LBound(m_arrControlMap, 2) To iWhichInput - 1
  4955.                                     If m_arrControlMap(iPlayer, iNextInput).device = 1 Then ' .device 1 = keyboard
  4956.                                         If m_arrControlMap(iPlayer, iNextInput).typ = cInputKey Then
  4957.                                             If m_arrControlMap(iPlayer, iNextInput).code = iCode Then
  4958.                                                 'if m_arrControlMap(iPlayer, iNextInput).value = TRUE then
  4959.                                                 bHaveInput = FALSE
  4960.                                                 'end if
  4961.                                             End If
  4962.                                         End If
  4963.                                     End If
  4964.                                 Next iNextInput
  4965.                             End If
  4966.  
  4967.                             If bHaveInput Then
  4968.                                 m_arrControlMap(iPlayer, iWhichInput).device = 1 ' .device 1 = keyboard
  4969.                                 m_arrControlMap(iPlayer, iWhichInput).typ = cInputKey
  4970.                                 m_arrControlMap(iPlayer, iWhichInput).code = iCode
  4971.                                 m_arrControlMap(iPlayer, iWhichInput).value = TRUE
  4972.                                 bMoveNext = TRUE
  4973.                             End If
  4974.  
  4975.                         End If
  4976.                     Next iLoop
  4977.                 End If
  4978.                 ' END CHECK FOR KEYBOARD INPUT #1
  4979.                 ' -----------------------------------------------------------------------------
  4980.  
  4981.                 If bMoveNext = TRUE Then Exit Do
  4982.                 _Limit 30
  4983.             Loop Until _KeyHit = 27 ' ESCAPE to quit
  4984.             ' END LOOK FOR NEXT INPUT
  4985.             ' =============================================================================
  4986.  
  4987.             If bMoveNext = TRUE Then
  4988.                 Print "Device #" + cstr$(m_arrControlMap(iPlayer, iWhichInput).device) + " " + _
  4989.                     InputTypeToString$(m_arrControlMap(iPlayer, iWhichInput).typ) + " " + _
  4990.                     cstr$(m_arrControlMap(iPlayer, iWhichInput).code) + " = " + _
  4991.                     cstr$(m_arrControlMap(iPlayer, iWhichInput).value)
  4992.  
  4993.                 ' Only ask user to select repeat if no override.
  4994.                 If m_bRepeatOverride = FALSE Then
  4995.                     Input "Enable repeat (y/n)"; in$: in$ = LCase$(_Trim$(in$))
  4996.                     If in$ = "y" Then
  4997.                         m_arrControlMap(iPlayer, iWhichInput).repeat = TRUE
  4998.                     Else
  4999.                         m_arrControlMap(iPlayer, iWhichInput).repeat = FALSE
  5000.                     End If
  5001.                 Else
  5002.                     m_arrControlMap(iPlayer, iWhichInput).repeat = GetGlobalInputRepeatSetting%(iWhichInput)
  5003.                 End If
  5004.             Else
  5005.                 Print "(Skipped)"
  5006.                 bCancel = TRUE
  5007.                 bFinished = TRUE
  5008.             End If
  5009.  
  5010.             If bFinished = TRUE Then Exit For
  5011.         Next iWhichInput
  5012.     End If
  5013.  
  5014.     If Len(sError) = 0 Then
  5015.         m_bHaveMapping = TRUE
  5016.     Else
  5017.         sResult = "ERRORS: " + sError
  5018.     End If
  5019.  
  5020.     _KeyClear: _Delay 1
  5021.     MapInput1b$ = sResult
  5022. End Function ' MapInput1b$
  5023.  
  5024. ' /////////////////////////////////////////////////////////////////////////////
  5025. ' Receives which input contstant and returns a text description
  5026.  
  5027. Function InputToString$ (iWhich As Integer)
  5028.     Select Case iWhich
  5029.         Case cInputUp:
  5030.             InputToString$ = "up"
  5031.         Case cInputDown:
  5032.             InputToString$ = "down"
  5033.         Case cInputLeft:
  5034.             InputToString$ = "left"
  5035.         Case cInputRight:
  5036.             InputToString$ = "right"
  5037.         Case cInputButton1:
  5038.             InputToString$ = "button #1"
  5039.         Case cInputButton2:
  5040.             InputToString$ = "button #2"
  5041.         Case cInputButton3:
  5042.             InputToString$ = "button #3"
  5043.         Case cInputButton4:
  5044.             InputToString$ = "button #4"
  5045.         Case Else:
  5046.             InputToString$ = "unknown"
  5047.     End Select
  5048. End Function ' InputToString$
  5049.  
  5050. ' /////////////////////////////////////////////////////////////////////////////
  5051. ' Receives which input contstant and returns a text description
  5052. ' that matches the TextFieldType and TextLabelType ".item" member.
  5053.  
  5054. Function InputToItem$ (iWhich As Integer)
  5055.     Select Case iWhich
  5056.         Case cInputUp:
  5057.             InputToItem$ = "Up"
  5058.         Case cInputDown:
  5059.             InputToItem$ = "Down"
  5060.         Case cInputLeft:
  5061.             InputToItem$ = "Left"
  5062.         Case cInputRight:
  5063.             InputToItem$ = "Right"
  5064.         Case cInputButton1:
  5065.             InputToItem$ = "Button1"
  5066.         Case cInputButton2:
  5067.             InputToItem$ = "Button2"
  5068.         Case cInputButton3:
  5069.             InputToItem$ = "Button3"
  5070.         Case cInputButton4:
  5071.             InputToItem$ = "Button4"
  5072.         Case Else:
  5073.             InputToItem$ = ""
  5074.     End Select
  5075. End Function ' InputToItem$
  5076.  
  5077. ' /////////////////////////////////////////////////////////////////////////////
  5078. ' Receives which input contstant and returns its global "repeat" setting
  5079.  
  5080. ' usage:
  5081. '     m_arrControlMap(iPlayer, iWhichInput).repeat = GetGlobalInputRepeatSetting%(cInputUp)
  5082.  
  5083. Function GetGlobalInputRepeatSetting% (iWhich As Integer)
  5084.     Select Case iWhich
  5085.         Case cInputUp:
  5086.             GetGlobalInputRepeatSetting% = m_bRepeatUp
  5087.         Case cInputDown:
  5088.             GetGlobalInputRepeatSetting% = m_bRepeatDown
  5089.         Case cInputLeft:
  5090.             GetGlobalInputRepeatSetting% = m_bRepeatLeft
  5091.         Case cInputRight:
  5092.             GetGlobalInputRepeatSetting% = m_bRepeatRight
  5093.         Case cInputButton1:
  5094.             GetGlobalInputRepeatSetting% = m_bRepeatButton1
  5095.         Case cInputButton2:
  5096.             GetGlobalInputRepeatSetting% = m_bRepeatButton2
  5097.         Case cInputButton3:
  5098.             GetGlobalInputRepeatSetting% = m_bRepeatButton3
  5099.         Case cInputButton4:
  5100.             GetGlobalInputRepeatSetting% = m_bRepeatButton4
  5101.         Case Else:
  5102.             GetGlobalInputRepeatSetting% = FALSE
  5103.     End Select
  5104. End Function ' GetGlobalInputRepeatSetting%
  5105.  
  5106. ' /////////////////////////////////////////////////////////////////////////////
  5107.  
  5108. Function InputTypeToString$ (iCode As Integer)
  5109.     Select Case iCode
  5110.         Case cInputNone:
  5111.             InputTypeToString$ = "none"
  5112.         Case cInputKey:
  5113.             InputTypeToString$ = "key"
  5114.         Case cInputButton:
  5115.             InputTypeToString$ = "button"
  5116.         Case cInputAxis:
  5117.             InputTypeToString$ = "axis"
  5118.         Case Else:
  5119.             InputTypeToString$ = "unknown"
  5120.     End Select
  5121. End Function ' InputTypeToString$
  5122.  
  5123. ' /////////////////////////////////////////////////////////////////////////////
  5124. ' METHOD v2 = faster
  5125.  
  5126. Function GetKeyboardButtonCodeText$ (iCode As Integer)
  5127.     Dim sResult As String: sResult = ""
  5128.     If LBound(m_arrButtonKeyDesc) <= iCode Then
  5129.         If UBound(m_arrButtonKeyDesc) >= iCode Then
  5130.             sResult = m_arrButtonKeyDesc(iCode)
  5131.         End If
  5132.     End If
  5133.     If Len(sResult) = 0 Then
  5134.         sResult = _Trim$(Str$(iCode)) + " (?)"
  5135.     End If
  5136.     GetKeyboardButtonCodeText$ = sResult
  5137. End Function ' GetKeyboardButtonCodeText$
  5138.  
  5139. ' /////////////////////////////////////////////////////////////////////////////
  5140. ' METHOD v2 = faster
  5141.  
  5142. Function GetKeyboardButtonCodeShortText$ (iCode As Integer)
  5143.     Dim sResult As String: sResult = ""
  5144.     If LBound(m_arrButtonKeyDesc) <= iCode Then
  5145.         If UBound(m_arrButtonKeyDesc) >= iCode Then
  5146.             sResult = m_arrButtonKeyDesc(iCode)
  5147.         End If
  5148.     End If
  5149.     If Len(sResult) = 0 Then
  5150.         sResult = _Trim$(Str$(iCode)) + " (?)"
  5151.     End If
  5152.     GetKeyboardButtonCodeShortText$ = sResult
  5153. End Function ' GetKeyboardButtonCodeText$
  5154.  
  5155. ' /////////////////////////////////////////////////////////////////////////////
  5156. ' METHOD v2
  5157. ' Faster lookup - a dictionary with a hash lookup would be best
  5158. ' but this is a quick way to do it since the values never change.
  5159.  
  5160. ' The following shared arrays must be declared:
  5161. '     ReDim Shared m_arrButtonCode(1 To 99) As Long
  5162. '     ReDim Shared m_arrButtonKey(1 To 99) As String
  5163. '     ReDim Shared m_arrButtonKeyDesc(0 To 512) As String
  5164. '     ReDim Shared m_arrButtonKeyShortDesc(0 To 512) As String
  5165.  
  5166. Sub InitKeyboardButtonCodes ()
  5167.     Dim iLoop As Integer
  5168.  
  5169.     If m_bInitialized = FALSE Then
  5170.         ' CODE(S) DETECTED WITH _BUTTON:
  5171.         m_arrButtonCode(1) = 2: m_arrButtonKey(1) = "Esc"
  5172.         m_arrButtonCode(2) = 60: m_arrButtonKey(2) = "F1"
  5173.         m_arrButtonCode(3) = 61: m_arrButtonKey(3) = "F2"
  5174.         m_arrButtonCode(4) = 62: m_arrButtonKey(4) = "F3"
  5175.         m_arrButtonCode(5) = 63: m_arrButtonKey(5) = "F4"
  5176.         m_arrButtonCode(6) = 64: m_arrButtonKey(6) = "F5"
  5177.         m_arrButtonCode(7) = 65: m_arrButtonKey(7) = "F6"
  5178.         m_arrButtonCode(8) = 66: m_arrButtonKey(8) = "F7"
  5179.         m_arrButtonCode(9) = 67: m_arrButtonKey(9) = "F8"
  5180.         m_arrButtonCode(10) = 68: m_arrButtonKey(10) = "F9"
  5181.         m_arrButtonCode(11) = 88: m_arrButtonKey(11) = "F11"
  5182.         m_arrButtonCode(12) = 89: m_arrButtonKey(12) = "F12"
  5183.         m_arrButtonCode(13) = 42: m_arrButtonKey(13) = "Tilde"
  5184.         m_arrButtonCode(14) = 3: m_arrButtonKey(14) = "1"
  5185.         m_arrButtonCode(15) = 4: m_arrButtonKey(15) = "2"
  5186.         m_arrButtonCode(16) = 5: m_arrButtonKey(16) = "3"
  5187.         m_arrButtonCode(17) = 6: m_arrButtonKey(17) = "4"
  5188.         m_arrButtonCode(18) = 7: m_arrButtonKey(18) = "5"
  5189.         m_arrButtonCode(19) = 8: m_arrButtonKey(19) = "6"
  5190.         m_arrButtonCode(20) = 9: m_arrButtonKey(20) = "7"
  5191.         m_arrButtonCode(21) = 10: m_arrButtonKey(21) = "8"
  5192.         m_arrButtonCode(22) = 11: m_arrButtonKey(22) = "9"
  5193.         m_arrButtonCode(23) = 12: m_arrButtonKey(23) = "0"
  5194.         m_arrButtonCode(24) = 13: m_arrButtonKey(24) = "Minus"
  5195.         m_arrButtonCode(25) = 14: m_arrButtonKey(25) = "Equal"
  5196.         m_arrButtonCode(26) = 15: m_arrButtonKey(26) = "BkSp"
  5197.         m_arrButtonCode(27) = 16: m_arrButtonKey(27) = "Tab"
  5198.         m_arrButtonCode(28) = 17: m_arrButtonKey(28) = "Q"
  5199.         m_arrButtonCode(29) = 18: m_arrButtonKey(29) = "W"
  5200.         m_arrButtonCode(30) = 19: m_arrButtonKey(30) = "E"
  5201.         m_arrButtonCode(31) = 20: m_arrButtonKey(31) = "R"
  5202.         m_arrButtonCode(32) = 21: m_arrButtonKey(32) = "T"
  5203.         m_arrButtonCode(33) = 22: m_arrButtonKey(33) = "Y"
  5204.         m_arrButtonCode(34) = 23: m_arrButtonKey(34) = "U"
  5205.         m_arrButtonCode(35) = 24: m_arrButtonKey(35) = "I"
  5206.         m_arrButtonCode(36) = 25: m_arrButtonKey(36) = "O"
  5207.         m_arrButtonCode(37) = 26: m_arrButtonKey(37) = "P"
  5208.         m_arrButtonCode(38) = 27: m_arrButtonKey(38) = "BracketLeft"
  5209.         m_arrButtonCode(39) = 28: m_arrButtonKey(39) = "BracketRight"
  5210.         m_arrButtonCode(40) = 44: m_arrButtonKey(40) = "Backslash"
  5211.         m_arrButtonCode(41) = 59: m_arrButtonKey(41) = "CapsLock"
  5212.         m_arrButtonCode(42) = 31: m_arrButtonKey(42) = "A"
  5213.         m_arrButtonCode(43) = 32: m_arrButtonKey(43) = "S"
  5214.         m_arrButtonCode(44) = 33: m_arrButtonKey(44) = "D"
  5215.         m_arrButtonCode(45) = 34: m_arrButtonKey(45) = "F"
  5216.         m_arrButtonCode(46) = 35: m_arrButtonKey(46) = "G"
  5217.         m_arrButtonCode(47) = 36: m_arrButtonKey(47) = "H"
  5218.         m_arrButtonCode(48) = 37: m_arrButtonKey(48) = "J"
  5219.         m_arrButtonCode(49) = 38: m_arrButtonKey(49) = "K"
  5220.         m_arrButtonCode(50) = 39: m_arrButtonKey(50) = "L"
  5221.         m_arrButtonCode(51) = 40: m_arrButtonKey(51) = "Semicolon"
  5222.         m_arrButtonCode(52) = 41: m_arrButtonKey(52) = "Apostrophe"
  5223.         m_arrButtonCode(53) = 29: m_arrButtonKey(53) = "Enter"
  5224.         m_arrButtonCode(54) = 43: m_arrButtonKey(54) = "ShiftLeft"
  5225.         m_arrButtonCode(55) = 45: m_arrButtonKey(55) = "Z"
  5226.         m_arrButtonCode(56) = 46: m_arrButtonKey(56) = "X"
  5227.         m_arrButtonCode(57) = 47: m_arrButtonKey(57) = "C"
  5228.         m_arrButtonCode(58) = 48: m_arrButtonKey(58) = "V"
  5229.         m_arrButtonCode(59) = 49: m_arrButtonKey(59) = "B"
  5230.         m_arrButtonCode(60) = 50: m_arrButtonKey(60) = "N"
  5231.         m_arrButtonCode(61) = 51: m_arrButtonKey(61) = "M"
  5232.         m_arrButtonCode(62) = 52: m_arrButtonKey(62) = "Comma"
  5233.         m_arrButtonCode(63) = 53: m_arrButtonKey(63) = "Period"
  5234.         m_arrButtonCode(64) = 54: m_arrButtonKey(64) = "Slash"
  5235.         m_arrButtonCode(65) = 55: m_arrButtonKey(65) = "ShiftRight"
  5236.         m_arrButtonCode(66) = 30: m_arrButtonKey(66) = "CtrlLeft"
  5237.         m_arrButtonCode(67) = 348: m_arrButtonKey(67) = "WinLeft"
  5238.         m_arrButtonCode(68) = 58: m_arrButtonKey(68) = "Spacebar"
  5239.         m_arrButtonCode(69) = 349: m_arrButtonKey(69) = "WinRight"
  5240.         m_arrButtonCode(70) = 350: m_arrButtonKey(70) = "Menu"
  5241.         m_arrButtonCode(71) = 286: m_arrButtonKey(71) = "CtrlRight"
  5242.         m_arrButtonCode(72) = 339: m_arrButtonKey(72) = "Ins"
  5243.         m_arrButtonCode(73) = 328: m_arrButtonKey(73) = "Home"
  5244.         m_arrButtonCode(74) = 330: m_arrButtonKey(74) = "PgUp"
  5245.         m_arrButtonCode(75) = 340: m_arrButtonKey(75) = "Del"
  5246.         m_arrButtonCode(76) = 336: m_arrButtonKey(76) = "End"
  5247.         m_arrButtonCode(77) = 338: m_arrButtonKey(77) = "PgDn"
  5248.         m_arrButtonCode(78) = 329: m_arrButtonKey(78) = "Up"
  5249.         m_arrButtonCode(79) = 332: m_arrButtonKey(79) = "Left"
  5250.         m_arrButtonCode(80) = 337: m_arrButtonKey(80) = "Down"
  5251.         m_arrButtonCode(81) = 334: m_arrButtonKey(81) = "Right"
  5252.         m_arrButtonCode(82) = 71: m_arrButtonKey(82) = "ScrollLock"
  5253.         m_arrButtonCode(83) = 326: m_arrButtonKey(83) = "NumLock"
  5254.         m_arrButtonCode(84) = 310: m_arrButtonKey(84) = "KeypadSlash"
  5255.         m_arrButtonCode(85) = 56: m_arrButtonKey(85) = "KeypadMultiply"
  5256.         m_arrButtonCode(86) = 75: m_arrButtonKey(86) = "KeypadMinus"
  5257.         m_arrButtonCode(87) = 72: m_arrButtonKey(87) = "Keypad7Home"
  5258.         m_arrButtonCode(88) = 73: m_arrButtonKey(88) = "Keypad8Up"
  5259.         m_arrButtonCode(89) = 74: m_arrButtonKey(89) = "Keypad9PgUp"
  5260.         m_arrButtonCode(90) = 79: m_arrButtonKey(90) = "KeypadPlus"
  5261.         m_arrButtonCode(91) = 76: m_arrButtonKey(91) = "Keypad4Left"
  5262.         m_arrButtonCode(92) = 77: m_arrButtonKey(92) = "Keypad5"
  5263.         m_arrButtonCode(93) = 78: m_arrButtonKey(93) = "Keypad6Right"
  5264.         m_arrButtonCode(94) = 80: m_arrButtonKey(94) = "Keypad1End"
  5265.         m_arrButtonCode(95) = 81: m_arrButtonKey(95) = "Keypad2Down"
  5266.         m_arrButtonCode(96) = 82: m_arrButtonKey(96) = "Keypad3PgDn"
  5267.         m_arrButtonCode(97) = 285: m_arrButtonKey(97) = "KeypadEnter"
  5268.         m_arrButtonCode(98) = 83: m_arrButtonKey(98) = "Keypad0Ins"
  5269.         m_arrButtonCode(99) = 84: m_arrButtonKey(99) = "KeypadPeriodDel"
  5270.  
  5271.         ' not sure if this works:
  5272.         '' CODE(S) DETECTED WITH _KEYDOWN:
  5273.         'm_arrButtonCode(100) = -1 : m_arrButtonCode(100) = "F10"
  5274.  
  5275.         ' not sure if this works:
  5276.         '' CODE(S) DETECTED WITH _KEYHIT:
  5277.         'm_arrButtonCode(101) = -2 : m_arrButtonCode(101) = "AltLeft"
  5278.         'm_arrButtonCode(102) = -3 : m_arrButtonCode(102) = "AltRight"
  5279.  
  5280.         ' DESCRIPTIONS BY KEYCODE
  5281.         For iLoop = LBound(m_arrButtonKeyDesc) To UBound(m_arrButtonKeyDesc)
  5282.             m_arrButtonKeyDesc(iLoop) = ""
  5283.         Next iLoop
  5284.         m_arrButtonKeyDesc(2) = "Esc"
  5285.         m_arrButtonKeyDesc(60) = "F1"
  5286.         m_arrButtonKeyDesc(61) = "F2"
  5287.         m_arrButtonKeyDesc(62) = "F3"
  5288.         m_arrButtonKeyDesc(63) = "F4"
  5289.         m_arrButtonKeyDesc(64) = "F5"
  5290.         m_arrButtonKeyDesc(65) = "F6"
  5291.         m_arrButtonKeyDesc(66) = "F7"
  5292.         m_arrButtonKeyDesc(67) = "F8"
  5293.         m_arrButtonKeyDesc(68) = "F9"
  5294.         m_arrButtonKeyDesc(88) = "F11"
  5295.         m_arrButtonKeyDesc(89) = "F12"
  5296.         m_arrButtonKeyDesc(42) = "Tilde"
  5297.         m_arrButtonKeyDesc(3) = "1"
  5298.         m_arrButtonKeyDesc(4) = "2"
  5299.         m_arrButtonKeyDesc(5) = "3"
  5300.         m_arrButtonKeyDesc(6) = "4"
  5301.         m_arrButtonKeyDesc(7) = "5"
  5302.         m_arrButtonKeyDesc(8) = "6"
  5303.         m_arrButtonKeyDesc(9) = "7"
  5304.         m_arrButtonKeyDesc(10) = "8"
  5305.         m_arrButtonKeyDesc(11) = "9"
  5306.         m_arrButtonKeyDesc(12) = "0"
  5307.         m_arrButtonKeyDesc(13) = "Minus"
  5308.         m_arrButtonKeyDesc(14) = "Equal"
  5309.         m_arrButtonKeyDesc(15) = "BkSp"
  5310.         m_arrButtonKeyDesc(16) = "Tab"
  5311.         m_arrButtonKeyDesc(17) = "Q"
  5312.         m_arrButtonKeyDesc(18) = "W"
  5313.         m_arrButtonKeyDesc(19) = "E"
  5314.         m_arrButtonKeyDesc(20) = "R"
  5315.         m_arrButtonKeyDesc(21) = "T"
  5316.         m_arrButtonKeyDesc(22) = "Y"
  5317.         m_arrButtonKeyDesc(23) = "U"
  5318.         m_arrButtonKeyDesc(24) = "I"
  5319.         m_arrButtonKeyDesc(25) = "O"
  5320.         m_arrButtonKeyDesc(26) = "P"
  5321.         m_arrButtonKeyDesc(27) = "BracketLeft"
  5322.         m_arrButtonKeyDesc(28) = "BracketRight"
  5323.         m_arrButtonKeyDesc(44) = "Backslash"
  5324.         m_arrButtonKeyDesc(59) = "CapsLock"
  5325.         m_arrButtonKeyDesc(31) = "A"
  5326.         m_arrButtonKeyDesc(32) = "S"
  5327.         m_arrButtonKeyDesc(33) = "D"
  5328.         m_arrButtonKeyDesc(34) = "F"
  5329.         m_arrButtonKeyDesc(35) = "G"
  5330.         m_arrButtonKeyDesc(36) = "H"
  5331.         m_arrButtonKeyDesc(37) = "J"
  5332.         m_arrButtonKeyDesc(38) = "K"
  5333.         m_arrButtonKeyDesc(39) = "L"
  5334.         m_arrButtonKeyDesc(40) = "Semicolon"
  5335.         m_arrButtonKeyDesc(41) = "Apostrophe"
  5336.         m_arrButtonKeyDesc(29) = "Enter"
  5337.         m_arrButtonKeyDesc(43) = "ShiftLeft"
  5338.         m_arrButtonKeyDesc(45) = "Z"
  5339.         m_arrButtonKeyDesc(46) = "X"
  5340.         m_arrButtonKeyDesc(47) = "C"
  5341.         m_arrButtonKeyDesc(48) = "V"
  5342.         m_arrButtonKeyDesc(49) = "B"
  5343.         m_arrButtonKeyDesc(50) = "N"
  5344.         m_arrButtonKeyDesc(51) = "M"
  5345.         m_arrButtonKeyDesc(52) = "Comma"
  5346.         m_arrButtonKeyDesc(53) = "Period"
  5347.         m_arrButtonKeyDesc(54) = "Slash"
  5348.         m_arrButtonKeyDesc(55) = "ShiftRight"
  5349.         m_arrButtonKeyDesc(30) = "CtrlLeft"
  5350.         m_arrButtonKeyDesc(348) = "WinLeft"
  5351.         m_arrButtonKeyDesc(58) = "Spacebar"
  5352.         m_arrButtonKeyDesc(349) = "WinRight"
  5353.         m_arrButtonKeyDesc(350) = "Menu"
  5354.         m_arrButtonKeyDesc(286) = "CtrlRight"
  5355.         m_arrButtonKeyDesc(339) = "Ins"
  5356.         m_arrButtonKeyDesc(328) = "Home"
  5357.         m_arrButtonKeyDesc(330) = "PgUp"
  5358.         m_arrButtonKeyDesc(340) = "Del"
  5359.         m_arrButtonKeyDesc(336) = "End"
  5360.         m_arrButtonKeyDesc(338) = "PgDn"
  5361.         m_arrButtonKeyDesc(329) = "Up"
  5362.         m_arrButtonKeyDesc(332) = "Left"
  5363.         m_arrButtonKeyDesc(337) = "Down"
  5364.         m_arrButtonKeyDesc(334) = "Right"
  5365.         m_arrButtonKeyDesc(71) = "ScrollLock"
  5366.         m_arrButtonKeyDesc(326) = "NumLock"
  5367.         m_arrButtonKeyDesc(310) = "KeypadSlash"
  5368.         m_arrButtonKeyDesc(56) = "KeypadMultiply"
  5369.         m_arrButtonKeyDesc(75) = "KeypadMinus"
  5370.         m_arrButtonKeyDesc(72) = "Keypad7Home"
  5371.         m_arrButtonKeyDesc(73) = "Keypad8Up"
  5372.         m_arrButtonKeyDesc(74) = "Keypad9PgUp"
  5373.         m_arrButtonKeyDesc(79) = "KeypadPlus"
  5374.         m_arrButtonKeyDesc(76) = "Keypad4Left"
  5375.         m_arrButtonKeyDesc(77) = "Keypad5"
  5376.         m_arrButtonKeyDesc(78) = "Keypad6Right"
  5377.         m_arrButtonKeyDesc(80) = "Keypad1End"
  5378.         m_arrButtonKeyDesc(81) = "Keypad2Down"
  5379.         m_arrButtonKeyDesc(82) = "Keypad3PgDn"
  5380.         m_arrButtonKeyDesc(285) = "KeypadEnter"
  5381.         m_arrButtonKeyDesc(83) = "Keypad0Ins"
  5382.         m_arrButtonKeyDesc(84) = "KeypadPeriodDel"
  5383.  
  5384.         ' SHORT DESCRIPTIONS BY KEYCODE
  5385.         For iLoop = LBound(m_arrButtonKeyShortDesc) To UBound(m_arrButtonKeyShortDesc)
  5386.             m_arrButtonKeyShortDesc(iLoop) = ""
  5387.         Next iLoop
  5388.         m_arrButtonKeyShortDesc(2) = "Esc"
  5389.         m_arrButtonKeyShortDesc(60) = "F1"
  5390.         m_arrButtonKeyShortDesc(61) = "F2"
  5391.         m_arrButtonKeyShortDesc(62) = "F3"
  5392.         m_arrButtonKeyShortDesc(63) = "F4"
  5393.         m_arrButtonKeyShortDesc(64) = "F5"
  5394.         m_arrButtonKeyShortDesc(65) = "F6"
  5395.         m_arrButtonKeyShortDesc(66) = "F7"
  5396.         m_arrButtonKeyShortDesc(67) = "F8"
  5397.         m_arrButtonKeyShortDesc(68) = "F9"
  5398.         m_arrButtonKeyShortDesc(88) = "F11"
  5399.         m_arrButtonKeyShortDesc(89) = "F12"
  5400.         m_arrButtonKeyShortDesc(42) = "Tilde"
  5401.         m_arrButtonKeyShortDesc(3) = "1"
  5402.         m_arrButtonKeyShortDesc(4) = "2"
  5403.         m_arrButtonKeyShortDesc(5) = "3"
  5404.         m_arrButtonKeyShortDesc(6) = "4"
  5405.         m_arrButtonKeyShortDesc(7) = "5"
  5406.         m_arrButtonKeyShortDesc(8) = "6"
  5407.         m_arrButtonKeyShortDesc(9) = "7"
  5408.         m_arrButtonKeyShortDesc(10) = "8"
  5409.         m_arrButtonKeyShortDesc(11) = "9"
  5410.         m_arrButtonKeyShortDesc(12) = "0"
  5411.         m_arrButtonKeyShortDesc(13) = "Minus"
  5412.         m_arrButtonKeyShortDesc(14) = "Equal"
  5413.         m_arrButtonKeyShortDesc(15) = "BkSp"
  5414.         m_arrButtonKeyShortDesc(16) = "Tab"
  5415.         m_arrButtonKeyShortDesc(17) = "Q"
  5416.         m_arrButtonKeyShortDesc(18) = "W"
  5417.         m_arrButtonKeyShortDesc(19) = "E"
  5418.         m_arrButtonKeyShortDesc(20) = "R"
  5419.         m_arrButtonKeyShortDesc(21) = "T"
  5420.         m_arrButtonKeyShortDesc(22) = "Y"
  5421.         m_arrButtonKeyShortDesc(23) = "U"
  5422.         m_arrButtonKeyShortDesc(24) = "I"
  5423.         m_arrButtonKeyShortDesc(25) = "O"
  5424.         m_arrButtonKeyShortDesc(26) = "P"
  5425.         m_arrButtonKeyShortDesc(27) = "BrktLeft"
  5426.         m_arrButtonKeyShortDesc(28) = "BrktRight"
  5427.         m_arrButtonKeyShortDesc(44) = "Backslash"
  5428.         m_arrButtonKeyShortDesc(59) = "CapsLock"
  5429.         m_arrButtonKeyShortDesc(31) = "A"
  5430.         m_arrButtonKeyShortDesc(32) = "S"
  5431.         m_arrButtonKeyShortDesc(33) = "D"
  5432.         m_arrButtonKeyShortDesc(34) = "F"
  5433.         m_arrButtonKeyShortDesc(35) = "G"
  5434.         m_arrButtonKeyShortDesc(36) = "H"
  5435.         m_arrButtonKeyShortDesc(37) = "J"
  5436.         m_arrButtonKeyShortDesc(38) = "K"
  5437.         m_arrButtonKeyShortDesc(39) = "L"
  5438.         m_arrButtonKeyShortDesc(40) = "Semicolon"
  5439.         m_arrButtonKeyShortDesc(41) = "Apostrophe"
  5440.         m_arrButtonKeyShortDesc(29) = "Enter"
  5441.         m_arrButtonKeyShortDesc(43) = "ShiftLeft"
  5442.         m_arrButtonKeyShortDesc(45) = "Z"
  5443.         m_arrButtonKeyShortDesc(46) = "X"
  5444.         m_arrButtonKeyShortDesc(47) = "C"
  5445.         m_arrButtonKeyShortDesc(48) = "V"
  5446.         m_arrButtonKeyShortDesc(49) = "B"
  5447.         m_arrButtonKeyShortDesc(50) = "N"
  5448.         m_arrButtonKeyShortDesc(51) = "M"
  5449.         m_arrButtonKeyShortDesc(52) = "Comma"
  5450.         m_arrButtonKeyShortDesc(53) = "Period"
  5451.         m_arrButtonKeyShortDesc(54) = "Slash"
  5452.         m_arrButtonKeyShortDesc(55) = "ShiftRight"
  5453.         m_arrButtonKeyShortDesc(30) = "CtrlLeft"
  5454.         m_arrButtonKeyShortDesc(348) = "WinLeft"
  5455.         m_arrButtonKeyShortDesc(58) = "Spacebar"
  5456.         m_arrButtonKeyShortDesc(349) = "WinRight"
  5457.         m_arrButtonKeyShortDesc(350) = "Menu"
  5458.         m_arrButtonKeyShortDesc(286) = "CtrlRight"
  5459.         m_arrButtonKeyShortDesc(339) = "Ins"
  5460.         m_arrButtonKeyShortDesc(328) = "Home"
  5461.         m_arrButtonKeyShortDesc(330) = "PgUp"
  5462.         m_arrButtonKeyShortDesc(340) = "Del"
  5463.         m_arrButtonKeyShortDesc(336) = "End"
  5464.         m_arrButtonKeyShortDesc(338) = "PgDn"
  5465.         m_arrButtonKeyShortDesc(329) = "Up"
  5466.         m_arrButtonKeyShortDesc(332) = "Left"
  5467.         m_arrButtonKeyShortDesc(337) = "Down"
  5468.         m_arrButtonKeyShortDesc(334) = "Right"
  5469.         m_arrButtonKeyShortDesc(71) = "ScrollLock"
  5470.         m_arrButtonKeyShortDesc(326) = "NumLock"
  5471.         m_arrButtonKeyShortDesc(310) = "KeypadSlash"
  5472.         m_arrButtonKeyShortDesc(56) = "KeypadMult"
  5473.         m_arrButtonKeyShortDesc(75) = "KeypadMinus"
  5474.         m_arrButtonKeyShortDesc(72) = "Keypad7Home"
  5475.         m_arrButtonKeyShortDesc(73) = "Keypad8Up"
  5476.         m_arrButtonKeyShortDesc(74) = "Keypad9PgUp"
  5477.         m_arrButtonKeyShortDesc(79) = "KeypadPlus"
  5478.         m_arrButtonKeyShortDesc(76) = "Keypad4Lf"
  5479.         m_arrButtonKeyShortDesc(77) = "Keypad5"
  5480.         m_arrButtonKeyShortDesc(78) = "Keypad6Rt"
  5481.         m_arrButtonKeyShortDesc(80) = "Keypad1End"
  5482.         m_arrButtonKeyShortDesc(81) = "Keypad2Dn"
  5483.         m_arrButtonKeyShortDesc(82) = "Keypad3PgDn"
  5484.         m_arrButtonKeyShortDesc(285) = "KeypadEnter"
  5485.         m_arrButtonKeyShortDesc(83) = "Keypad0Ins"
  5486.         m_arrButtonKeyShortDesc(84) = "KeypadPerDel"
  5487.  
  5488.         m_bInitialized = TRUE
  5489.     End If
  5490. End Sub ' InitKeyboardButtonCodes
  5491.  
  5492. ' /////////////////////////////////////////////////////////////////////////////
  5493. ' not sure if this works
  5494.  
  5495. ' Returns TRUE if the F10 key is held down.
  5496. ' We use _KEYDOWN for this because _BUTTON doesn't detect F10.
  5497.  
  5498. ' Constant must be declared globally:
  5499. ' Const c_iKeyDown_F10 = 17408
  5500.  
  5501. Function KeydownF10%
  5502.     Dim iCode As Long
  5503.     '_KEYCLEAR: _DELAY 1
  5504.     If _KeyDown(c_iKeyDown_F10) = TRUE Then
  5505.         KeydownF10% = TRUE
  5506.     Else
  5507.         KeydownF10% = FALSE
  5508.     End If
  5509.     '_KEYCLEAR
  5510. End Function ' KeydownF10%
  5511.  
  5512. ' /////////////////////////////////////////////////////////////////////////////
  5513. ' not sure if this works
  5514.  
  5515. ' Returns TRUE if the left ALT key is held down.
  5516. ' We use _KEYHIT for this because _BUTTON doesn't detect ALT.
  5517.  
  5518. ' Constant must be declared globally:
  5519. ' Const c_iKeyHit_AltLeft = -30764
  5520.  
  5521. Function KeyhitAltLeft%
  5522.     '_KEYCLEAR: _DELAY 1
  5523.     If _KeyHit = c_iKeyHit_AltLeft Then
  5524.         KeyhitAltLeft% = TRUE
  5525.     Else
  5526.         KeyhitAltLeft% = FALSE
  5527.     End If
  5528.     '_KEYCLEAR
  5529. End Function ' KeyhitAltLeft%
  5530.  
  5531. ' /////////////////////////////////////////////////////////////////////////////
  5532. ' not sure if this works
  5533.  
  5534. ' Returns TRUE if the right ALT key is held down.
  5535. ' We use _KEYHIT for this because _BUTTON doesn't detect ALT.
  5536.  
  5537. ' Constant must be declared globally:
  5538. ' Const c_iKeyHit_AltRight = -30765
  5539.  
  5540. Function KeyhitAltRight%
  5541.     '_KEYCLEAR: _DELAY 1
  5542.     If _KeyHit = c_iKeyHit_AltRight Then
  5543.         KeyhitAltRight% = TRUE
  5544.     Else
  5545.         KeyhitAltRight% = FALSE
  5546.     End If
  5547.     '_KEYCLEAR
  5548. End Function ' KeyhitAltRight%
  5549.  
  5550. ' /////////////////////////////////////////////////////////////////////////////
  5551. ' DEVICES Button
  5552. ' _LASTBUTTON(1) keyboards will normally return 512 buttons. One button is read per loop through all numbers.
  5553. ' _BUTTONCHANGE(number) returns -1 when pressed, 1 when released and 0 when there is no event since the last read.
  5554. ' _BUTTON(number) returns -1 when a button is pressed and 0 when released
  5555.  
  5556. ' Detects most keys (where the codes are documented?)
  5557.  
  5558. ' However, does not seem to detect:
  5559. ' Key             Use
  5560. ' ---             ---
  5561. ' F10             Function KeydownF10%
  5562. ' Left Alt        Function KeyhitAltLeft%
  5563. ' Right Alt       Function KeyhitAltRight%
  5564. ' Print Screen    (system API call?)
  5565. ' Pause/Break     (system API call?)
  5566.  
  5567. Function KeyPressed% (iCode As Integer)
  5568.     '_KEYCLEAR: _DELAY 1
  5569.     While _DeviceInput(1): Wend ' clear and update the keyboard buffer
  5570.     If _Button(iCode) <> FALSE Then
  5571.         KeyPressed% = TRUE
  5572.     Else
  5573.         KeyPressed% = FALSE
  5574.     End If
  5575.     '_KEYCLEAR
  5576. End Function ' KeyPressed%
  5577.  
  5578. ' /////////////////////////////////////////////////////////////////////////////
  5579.  
  5580. Function TestJoysticks1$
  5581.     Dim RoutineName As String: RoutineName = "TestJoysticks1$"
  5582.     Dim iDeviceCount As Integer
  5583.     Dim sResult As String
  5584.  
  5585.     ' 1 is the keyboard
  5586.     ' 2 is the mouse
  5587.     ' 3 is the joystick
  5588.     ' unless someone has a strange setup with multiple mice/keyboards/ect...
  5589.     ' In that case, you can use _DEVICE$(i) to look for "KEYBOARD", "MOUSE", "JOYSTICK", if necessary.
  5590.     ' I've never actually found it necessary, but I figure it's worth mentioning, just in case...
  5591.  
  5592.     iDeviceCount = _Devices ' Find the number of devices on someone's system
  5593.     If iDeviceCount > 2 Then
  5594.         TestJoysticks1b
  5595.         sResult = ""
  5596.     Else
  5597.         sResult = "No joysticks found."
  5598.     End If
  5599.  
  5600.     _KeyClear
  5601.  
  5602.     TestJoysticks1$ = sResult
  5603. End Function ' TestJoysticks1$
  5604.  
  5605. ' /////////////////////////////////////////////////////////////////////////////
  5606. ' Reads controllers and displays values on screen.
  5607.  
  5608. ' Currently this is set up to support up to 8 joysticks,
  5609. ' with upto 4 buttons and 2 axes each
  5610. ' Testing with an old USB Logitech RumblePad 2
  5611. ' and Atari 2600 joysticks plugged into using
  5612. ' iCode Atari Joystick, Paddle, Driving to USB Adapter 4 ports
  5613.  
  5614. ' BASED ON CODE BY SMcNeill FROM:
  5615. '     Simple Joystick Detection and Interaction  (Read 316 times)
  5616. '     https://www.qb64.org/forum/index.php?topic=2160.msg129051#msg129051
  5617. '     https://qb64forum.alephc.xyz/index.php?topic=2160.msg129083#msg129083
  5618.  
  5619. Sub TestJoysticks1b ()
  5620.     Dim RoutineName As String:: RoutineName = "TestJoysticks1b"
  5621.  
  5622.     Dim in$
  5623.     Dim iDeviceCount As Integer
  5624.     Dim iDevice As Integer
  5625.  
  5626.     Dim arrButton(32, 16) As Integer ' number of buttons on the joystick
  5627.     Dim arrButtonMin(32, 16) As Integer ' stores the minimum value read
  5628.     Dim arrButtonMax(32, 16) As Integer ' stores the maximum value read
  5629.     Dim arrAxis(32, 16) As Double ' number of axis on the joystick
  5630.     Dim arrAxisMin(32, 16) As Double ' stores the minimum value read
  5631.     Dim arrAxisMax(32, 16) As Double ' stores the maximum value read
  5632.     Dim arrAxisAvg(32, 16) As Double ' stores the average value read in the last few measurements
  5633.     Dim arrButtonNew(32, 16) As Integer ' tracks when to initialize values
  5634.     Dim arrAxisNew(32, 16) As Integer ' tracks when to initialize values
  5635.  
  5636.     Dim arrController(8) As ControllerType ' holds info for each player
  5637.     Dim iNumControllers As Integer
  5638.     Dim iController As Integer
  5639.     Dim iNextY As Integer
  5640.     Dim iNextX As Integer
  5641.     Dim iNextC As Integer
  5642.     Dim iLoop As Integer
  5643.     Dim iDigits As Integer ' # digits to display (values are truncated to this length)
  5644.     Dim strValue As String
  5645.     Dim strAxis As String
  5646.     Dim dblNextAxis As Double
  5647.     'DIM iMeasureCount AS INTEGER
  5648.     Dim dblAverage As Double
  5649.     Dim sngAverage As Single
  5650.     Dim sLine As String
  5651.     Dim iX As Integer
  5652.     Dim iY As Integer
  5653.  
  5654.     Dim iCol As Integer
  5655.     Dim iRow As Integer
  5656.     Dim iCols As Integer
  5657.     Dim iRows As Integer
  5658.     Dim iColWidth As Integer
  5659.     Dim iColCount As Integer
  5660.     Dim iGroupCount As Integer
  5661.  
  5662.     ' SET UP SCREEN
  5663.     Screen _NewImage(1280, 1024, 32): _ScreenMove 0, 0
  5664.  
  5665.     ' INITIALIZE
  5666.     iDigits = 4 ' 11
  5667.     iColCount = 3
  5668.     iCols = _Width(0) \ _FontWidth
  5669.     iRows = _Height(0) \ _FontHeight
  5670.     iColWidth = iCols \ iColCount
  5671.  
  5672.     ' COUNT # OF JOYSTICKS
  5673.     ' D= _DEVICES ' MUST be read in order for other 2 device functions to work!
  5674.     iDeviceCount = _Devices ' Find the number of devices on someone's system
  5675.     If iDeviceCount < 3 Then
  5676.         Cls
  5677.         Print "NO JOYSTICKS FOUND, EXITING..."
  5678.         Input "PRESS <ENTER>"; in$
  5679.         Exit Sub
  5680.     End If
  5681.  
  5682.     ' BASE # OF PLAYERS ON HOW MANY CONTROLLERS FOUND
  5683.     iNumControllers = iDeviceCount - 2 ' TODO: find out the right way to count joysticks
  5684.     If iNumControllers > cMaxControllers Then
  5685.         iNumControllers = cMaxControllers
  5686.     End If
  5687.  
  5688.     ' INITIALIZE PLAYER COORDINATES AND SCREEN CHARACTERS
  5689.     iNextY = 1
  5690.     iNextX = -3
  5691.     iNextC = 64
  5692.     For iController = 1 To iNumControllers
  5693.         iNextX = iNextX + 4
  5694.         If iNextX > 80 Then
  5695.             iNextX = 1
  5696.             iNextY = iNextY + 4
  5697.         End If
  5698.         iNextC = iNextC + 1
  5699.         arrController(iController).buttonCount = cMaxButtons
  5700.         arrController(iController).axisCount = cMaxAxis
  5701.  
  5702.         For iLoop = 1 To cMaxButtons
  5703.             arrButtonNew(iController, iLoop) = TRUE
  5704.         Next iLoop
  5705.         For iLoop = 1 To cMaxAxis
  5706.             arrAxisNew(iController, iLoop) = TRUE
  5707.             arrAxisAvg(iController, iLoop) = 0
  5708.         Next iLoop
  5709.     Next iController
  5710.  
  5711.     ' CLEAR THE SCREEN
  5712.     'iMeasureCount = 0
  5713.     Do
  5714.         For iController = 1 To iNumControllers
  5715.             iDevice = iController + 2
  5716.  
  5717.             While _DeviceInput(iDevice) ' clear and update the device buffer
  5718.                 ''IF _DEVICEINPUT = 3 THEN ' this says we only care about joystick input values
  5719.  
  5720.                 ' check all the buttons
  5721.                 For iLoop = 1 To _LastButton(iDevice)
  5722.                     If (iLoop > cMaxButtons) Then
  5723.                         Exit For
  5724.                     End If
  5725.                     arrController(iController).buttonCount = iLoop
  5726.  
  5727.                     ' update button array to indicate if a button is up or down currently.
  5728.                     If _ButtonChange(iLoop) Then
  5729.                         '' _BUTTON(number) returns -1 when a button is pressed and 0 when released.
  5730.                         ''arrButton(iLoop) = NOT arrButton(iLoop)
  5731.                         arrButton(iController, iLoop) = _Button(iLoop)
  5732.                     End If
  5733.  
  5734.                     '' SAVE MINIMUM VALUE
  5735.                     'if arrButton(iController, iLoop) < arrButtonMin(iController, iLoop) then
  5736.                     '    arrButtonMin(iController, iLoop) = arrButton(iController, iLoop)
  5737.                     '
  5738.                     '    ' INITIALIZE THE MAX TO THE MINIMUM VALUE
  5739.                     '    IF arrButtonNew(iController, iLoop) = TRUE THEN
  5740.                     '        arrButtonMax(iController, iLoop) = arrButtonMin(iController, iLoop)
  5741.                     '        arrButtonNew(iController, iLoop) = FALSE
  5742.                     '    END IF
  5743.                     'end if
  5744.                     '
  5745.                     '' SAVE MAXIMUM VALUE
  5746.                     'if arrButton(iController, iLoop) > arrButtonMax(iController, iLoop) then
  5747.                     '    arrButtonMax(iController, iLoop) = arrButton(iController, iLoop)
  5748.                     'end if
  5749.  
  5750.                 Next iLoop
  5751.  
  5752.                 For iLoop = 1 To _LastAxis(iDevice) ' this loop checks all my axis
  5753.                     If (iLoop > cMaxAxis) Then
  5754.                         Exit For
  5755.                     End If
  5756.                     arrController(iController).axisCount = iLoop
  5757.  
  5758.                     ' I like to give a little "jiggle" resistance to my controls, as I have an old joystick
  5759.                     ' which is prone to always give minute values and never really center on true 0.
  5760.                     ' A value of 1 means my axis is pushed fully in one direction.
  5761.                     ' A value greater than 0.1 means it's been partially pushed in a direction (such as at a 45 degree diagional angle).
  5762.                     ' A value of less than 0.1 means we count it as being centered. (As if it was 0.)
  5763.                     'IF ABS(_AXIS(iLoop)) <= 1 AND ABS(_AXIS(iLoop)) >= .1 THEN
  5764.  
  5765.                     dblNextAxis = _Axis(iLoop)
  5766.                     dblNextAxis = RoundUpDouble#(dblNextAxis, 3)
  5767.                     'IF ABS(dblNextAxis) <= 1 AND ABS(dblNextAxis) >= .01 THEN
  5768.                     If Abs(dblNextAxis) <= 1 And Abs(dblNextAxis) >= .001 Then
  5769.                         arrAxis(iController, iLoop) = dblNextAxis
  5770.                     Else
  5771.                         arrAxis(iController, iLoop) = 0
  5772.                     End If
  5773.  
  5774.                     '' SAVE MINIMUM VALUE
  5775.                     'if arrAxis(iController, iLoop) < arrAxisMin(iController, iLoop) then
  5776.                     '    arrAxisMin(iController, iLoop) = arrAxis(iController, iLoop)
  5777.                     '
  5778.                     '    ' INITIALIZE THE MAX TO THE MINIMUM VALUE
  5779.                     '    IF arrAxisNew(iController, iLoop) = TRUE THEN
  5780.                     '        arrAxisMax(iController, iLoop) = arrAxisMin(iController, iLoop)
  5781.                     '        arrAxisNew(iController, iLoop) = FALSE
  5782.                     '    END IF
  5783.                     'end if
  5784.                     '
  5785.                     '' SAVE MAXIMUM VALUE
  5786.                     'if arrAxis(iController, iLoop) > arrAxisMax(iController, iLoop) then
  5787.                     '    arrAxisMax(iController, iLoop) = arrAxis(iController, iLoop)
  5788.                     'end if
  5789.                     '
  5790.                     '' ADD CURRENT VALUE TO AVERAGE SUM
  5791.                     'arrAxisAvg(iController, iLoop) = arrAxisAvg(iController, iLoop) + arrAxis(iController, iLoop)
  5792.  
  5793.                 Next iLoop
  5794.             Wend ' clear and update the device buffer
  5795.  
  5796.         Next iController
  5797.  
  5798.         'PRINT "*** iNumControllers=" + cstr$(iNumControllers) + " ***"
  5799.         'iMeasureCount = iMeasureCount + 1
  5800.         'if iMeasureCount = 10 then
  5801.         'iMeasureCount = 0
  5802.  
  5803.         ' And below here is just the simple display routine which displays our values.
  5804.         ' If this was for a game, I'd choose something like arrAxis(1) = -1 for a left arrow style input,
  5805.         ' arrAxis(1) = 1 for a right arrow style input, rather than just using _KEYHIT or INKEY$.
  5806.  
  5807.         InitColumns iColCount
  5808.         m_StartRow = 6
  5809.         m_EndRow = iRows - 2
  5810.         'm_StartCol
  5811.         'm_EndCol
  5812.  
  5813.         Cls
  5814.         PrintStringCR1 1, 1, "Game controller test program."
  5815.         PrintStringCR1 1, 2, "This program is free to use and distribute per GNU GPLv3 license."
  5816.         PrintStringCR1 1, 3, "Tests up to 4 controllers with 2 axes / 2 buttons each."
  5817.         PrintStringCR1 1, 4, "Plug in controllers and move them & press buttons."
  5818.         PrintStringCR1 1, 5, "-------------------------------------------------------------------------------"
  5819.  
  5820.         iGroupCount = 0
  5821.  
  5822.         For iController = 1 To iNumControllers
  5823.             For iLoop = 1 To arrController(iController).axisCount ' A loop for each axis
  5824.                 strAxis = Right$("  " + cstr$(iLoop), 2)
  5825.  
  5826.                 sLine = ""
  5827.  
  5828.                 ' display their status to the screen
  5829.                 sLine = sLine + "Player " + cstr$(iController)
  5830.  
  5831.                 strValue = FormatNumber$(arrAxis(iController, iLoop), iDigits)
  5832.                 sLine = sLine + ",   Axis #" + strAxis + " = " + strValue
  5833.  
  5834.                 'strValue = FormatNumber$(arrAxisMin(iController, iLoop), iDigits)
  5835.                 'sLine = sLine + ", Min=" + strValue
  5836.                 '
  5837.                 'strValue = FormatNumber$(arrAxisMax(iController, iLoop), iDigits)
  5838.                 'sLine = sLine + ", Max=" + strValue
  5839.                 '
  5840.                 '' COMPUTE AVERAGE
  5841.                 'dblAverage = arrAxisAvg(iController, iLoop) / 10
  5842.                 'dblAverage = RoundUpDouble# (dblAverage, 3)
  5843.                 'strValue = FormatNumber$(dblAverage, iDigits)
  5844.                 'sLine = sLine + ", Avg=" + strValue
  5845.                 '
  5846.                 '' CLEAR THE AVERAGE
  5847.                 'arrAxisAvg(iController, iLoop) = 0
  5848.  
  5849.                 PrintColumn sLine
  5850.             Next iLoop
  5851.             For iLoop = 1 To arrController(iController).buttonCount ' A loop for each button
  5852.                 strAxis = Right$("  " + cstr$(iLoop), 2)
  5853.  
  5854.                 sLine = ""
  5855.  
  5856.                 ' display their status to the screen
  5857.                 sLine = sLine + "Player " + cstr$(iController)
  5858.  
  5859.                 strValue = FormatNumber$(arrButton(iController, iLoop), iDigits)
  5860.                 sLine = sLine + ", Button #" + strAxis + " = " + strValue
  5861.  
  5862.                 'strValue = FormatNumber$(arrButtonMin(iController, iLoop), iDigits)
  5863.                 'sLine = sLine + ", Min=" + strValue
  5864.                 '
  5865.                 'strValue = FormatNumber$(arrButtonMax(iController, iLoop), iDigits)
  5866.                 'sLine = sLine + ", Max=" + strValue
  5867.  
  5868.                 PrintColumn sLine
  5869.             Next iLoop
  5870.  
  5871.             iGroupCount = iGroupCount + 1
  5872.             If iGroupCount = 2 Then
  5873.                 ColumnBreak
  5874.                 iGroupCount = 0
  5875.             End If
  5876.  
  5877.         Next iController
  5878.  
  5879.         PrintStringCR1 1, iRows - 1, "-------------------------------------------------------------------------------"
  5880.         PrintStringCR1 1, iRows - 0, "PRESS <ESC> TO EXIT"
  5881.  
  5882.         'end if
  5883.  
  5884.         _Limit 30
  5885.     Loop Until _KeyHit = 27 ' ESCAPE to quit
  5886.  
  5887.     ' RETURN TO TEXT SCREEN
  5888.     Screen 0
  5889. End Sub ' TestJoysticks1b
  5890.  
  5891. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5892. ' BEGIN FILE FUNCTIONS
  5893. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5894.  
  5895. ' /////////////////////////////////////////////////////////////////////////////
  5896. ' File format is comma-delimited
  5897. ' containing controller info for one action per line
  5898. ' where each line contains the following in this order:
  5899.  
  5900. ' TAB ORDER   INFO             TYPE      DESCRIPTION
  5901. ' 1           {player #}       Integer   player # this mapping is for
  5902. ' 2           {which action}   Integer   which action this mapping is for (up/down/right/left/button 1/button 2, etc.)
  5903. ' 3           {device #}       Integer   number of the device this is mapped to
  5904. ' 4           {type}           Integer   type of input (one of: cInputKey, cInputButton, cInputAxis)
  5905. ' 5           {code}           Integer   if button the _BUTTON #, if axis the _AXIS #, if keyboard the _BUTTON #
  5906. ' 6           {value}          Integer   if axis, the value (-1 or 1), else can be ignored
  5907. ' 7           {repeat}         Integer   if TRUE, and repeating keys not controlled by global values (when m_bRepeatOverride=TRUE), controls repeating keys for this control
  5908.  
  5909. ' These need to be declared globally and populated:
  5910. '     ReDim Shared m_arrControlMap(1 To 8, 1 To 8) As ControlInputType
  5911. '     Dim Shared m_ControlMapFileName$: m_ControlMapFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "map.txt"
  5912. '     Dim Shared m_bRepeatOverride As Integer
  5913.  
  5914. ' If there is an error, returns error message,
  5915. ' else returns blank string.
  5916.  
  5917. Function SaveControllerMap1$
  5918.     Dim RoutineName As String:: RoutineName = "SaveControllerMap1$"
  5919.     Dim sResult As String: sResult = ""
  5920.     Dim sError As String: sError = ""
  5921.     Dim sFile As String
  5922.     Dim in$
  5923.     Dim iPlayer As Integer
  5924.     Dim iWhichInput As Integer
  5925.     Dim sLine As String
  5926.     Dim iCount As Long: iCount = 0
  5927.     'Dim iError As Long: iError = 0
  5928.     Dim sDelim As String: sDelim = "," ' CHR$(9)
  5929.  
  5930.     'DebugPrint "--------------------------------------------------------------------------------"
  5931.     'DebugPrint "Started " + RoutineName
  5932.     'DebugPrint "--------------------------------------------------------------------------------"
  5933.  
  5934.     ' Get file name
  5935.     If Len(m_ControlMapFileName$) = 0 Then
  5936.         m_ControlMapFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "map.txt"
  5937.     End If
  5938.     sFile = Mid$(m_ControlMapFileName$, _InStrRev(m_ControlMapFileName$, "\") + 1)
  5939.  
  5940.     '_KeyClear
  5941.     'Cls
  5942.     'Print "SAVE CONTROLLER MAPPING:"
  5943.     'Print "Default file name is " + Chr$(34) + m_ControlMapFileName$ + Chr$(34) + "."
  5944.     'Input "Type save file name, or blank for default: ", in$
  5945.     'in$ = _Trim$(in$)
  5946.     'If Len(in$) > 0 Then
  5947.     '    m_ControlMapFileName$ = in$
  5948.     'End If
  5949.     'sFile = m_ProgramPath$ + m_ControlMapFileName$
  5950.  
  5951.     'DebugPrint "m_ControlMapFileName$=" + CHR$(34) + m_ControlMapFileName$ + CHR$(34)
  5952.  
  5953.     ' Save mapping to file
  5954.     Open m_ControlMapFileName$ For Output As #1
  5955.  
  5956.     For iPlayer = LBound(m_arrControlMap, 1) To UBound(m_arrControlMap, 1)
  5957.         For iWhichInput = LBound(m_arrControlMap, 2) To UBound(m_arrControlMap, 2)
  5958.             sLine = ""
  5959.  
  5960.             sLine = sLine + _Trim$(Str$(iPlayer))
  5961.             sLine = sLine + sDelim
  5962.  
  5963.             sLine = sLine + _Trim$(Str$(iWhichInput))
  5964.             sLine = sLine + sDelim
  5965.  
  5966.             sLine = sLine + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).device))
  5967.             sLine = sLine + sDelim
  5968.  
  5969.             sLine = sLine + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).typ))
  5970.             sLine = sLine + sDelim
  5971.  
  5972.             sLine = sLine + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).code))
  5973.             sLine = sLine + sDelim
  5974.  
  5975.             sLine = sLine + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).value))
  5976.             sLine = sLine + sDelim
  5977.  
  5978.             sLine = sLine + _Trim$(Str$(m_arrControlMap(iPlayer, iWhichInput).repeat))
  5979.  
  5980.             Print #1, sLine
  5981.             iCount = iCount + 1
  5982.         Next iWhichInput
  5983.     Next iPlayer
  5984.  
  5985.     Close #1
  5986.  
  5987.     'DebugPrint "Wrote   " + _Trim$(Str$(iCount)) + " lines."
  5988.     'Print "Skipped " + _Trim$(Str$(iError)) + " lines."
  5989.     'DebugPrint ""
  5990.     'Input "PRESS <ENTER> TO CONTINUE", in$
  5991.  
  5992.     If Len(sError) = 0 Then
  5993.         sResult = "Saved mapping file " + Chr$(34) + sFile + Chr$(34) + "."
  5994.     Else
  5995.         sResult = "ERRORS: " + sError
  5996.     End If
  5997.  
  5998.     SaveControllerMap1$ = sResult
  5999. End Function ' SaveControllerMap1$
  6000.  
  6001. ' /////////////////////////////////////////////////////////////////////////////
  6002.  
  6003. Function LoadControllerMap1$
  6004.     Dim RoutineName As String:: RoutineName = "LoadControllerMap1$"
  6005.     Dim sResult As String: sResult = ""
  6006.     Dim sError As String: sError = ""
  6007.     Dim sNextErr As String
  6008.  
  6009.     Dim sFile As String
  6010.     Dim sText As String
  6011.     Dim iTotal As Long: iTotal = 0
  6012.  
  6013.     Dim iRead As Long: iRead = 0
  6014.     Dim iValid As Long: iValid = 0
  6015.     Dim iBad As Long: iBad = 0
  6016.     Dim iBlank As Long: iBlank = 0
  6017.  
  6018.     Dim sLine As String
  6019.     ReDim arrNextLine(-1) As String
  6020.     Dim iNumValues As Integer
  6021.     Dim iAdjust As Integer
  6022.  
  6023.     Dim iPlayer As Integer
  6024.     Dim iWhichInput As Integer
  6025.     Dim iDevice As Integer
  6026.     Dim iType As Integer
  6027.     Dim iCode As Integer
  6028.     Dim iValue As Integer
  6029.     Dim bRepeat As Integer
  6030.     'Dim sDebugLine As String
  6031.  
  6032.     'DebugPrint "--------------------------------------------------------------------------------"
  6033.     'DebugPrint "Started " + RoutineName
  6034.     'DebugPrint "--------------------------------------------------------------------------------"
  6035.  
  6036.     ' Get file name
  6037.     If Len(sError) = 0 Then
  6038.         If Len(m_ControlMapFileName$) = 0 Then
  6039.             m_ControlMapFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "map.txt"
  6040.         End If
  6041.         sFile = Mid$(m_ControlMapFileName$, _InStrRev(m_ControlMapFileName$, "\") + 1)
  6042.     End If
  6043.  
  6044.     '' Get file name
  6045.     'If Len(sError) = 0 Then
  6046.     '    Cls
  6047.     '    If Len(m_ControlMapFileName$) = 0 Then
  6048.     '        m_ControlMapFileName$ = Left$(m_ProgramName$, _InStrRev(m_ProgramName$, ".")) + "map.txt"
  6049.     '    End If
  6050.     '    Print "LOAD CONTROLLER MAPPING:"
  6051.     '    Print "Default file name is " + Chr$(34) + m_ControlMapFileName$ + Chr$(34) + "."
  6052.     '    Input "Type name of file to open, or blank for default: ", in$
  6053.     '    in$ = _Trim$(in$)
  6054.     '    If Len(in$) > 0 Then
  6055.     '        m_ControlMapFileName$ = in$
  6056.     '    End If
  6057.     '    sFile = m_ProgramPath$ + m_ControlMapFileName$
  6058.     'End If
  6059.  
  6060.     ' Make sure file exists
  6061.     If Len(sError) = 0 Then
  6062.         If _FileExists(m_ControlMapFileName$) = FALSE Then
  6063.             sError = "File not found: " + Chr$(34) + m_ControlMapFileName$ + Chr$(34)
  6064.         Else
  6065.             'DebugPrint "Found file: " + chr$(34) + m_ControlMapFileName$ + chr$(34)
  6066.         End If
  6067.     End If
  6068.  
  6069.     ' Read data from file
  6070.     If Len(sError) = 0 Then
  6071.         'DebugPrint "OPEN m_ControlMapFileName$ FOR BINARY AS #1"
  6072.  
  6073.         Open m_ControlMapFileName$ For Binary As #1
  6074.         sText = Space$(LOF(1))
  6075.         Get #1, , sText
  6076.         Close #1
  6077.         iTotal = Len(sText) - Len(Replace$(sText, Chr$(13), ""))
  6078.         sText = ""
  6079.  
  6080.         Open m_ControlMapFileName$ For Input As #1
  6081.         While Not EOF(1)
  6082.             'INPUT #1, sLine
  6083.             Line Input #1, sLine ' read entire text file line
  6084.  
  6085.             iRead = iRead + 1
  6086.             'DebugPrint "Parsing line " + _Trim$(Str$(iRead)) + _
  6087.             '    " of " + _Trim$(Str$(iTotal))
  6088.  
  6089.             sLine = Replace$(sLine, " ", "") ' Remove spaces
  6090.             sLine = Replace$(sLine, Chr$(9), "") ' Remove tabs
  6091.             sLine = Replace$(sLine, Chr$(10), "") ' Remove line breaks
  6092.             sLine = Replace$(sLine, Chr$(13), "") ' Remove carriage returns
  6093.             'DebugPrint "    Trimmed=" + chr$(34) + sLine + chr$(34)
  6094.  
  6095.             If Len(sLine) > 0 Then
  6096.                 split sLine, ",", arrNextLine()
  6097.                 'DebugPrint "split into arrNextLine()"
  6098.                 'DebugPrint "    lbound =" + _Trim$(Str$(lbound(arrNextLine))) '+ CHR$(10)
  6099.                 'DebugPrint "    ubound =" + _Trim$(Str$(ubound(arrNextLine))) '+ CHR$(10)
  6100.  
  6101.                 iNumValues = (UBound(arrNextLine) - LBound(arrNextLine)) + 1
  6102.                 If iNumValues > 5 Then
  6103.                     iAdjust = -1 '- lbound(arrNextLine)
  6104.  
  6105.                     If Len(sNextErr) = 0 Then
  6106.                         If IsNum%(arrNextLine(1 + iAdjust)) = TRUE Then
  6107.                             iPlayer = Val(arrNextLine(1 + iAdjust))
  6108.                         Else
  6109.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 1: not a number"
  6110.                         End If
  6111.                     End If
  6112.  
  6113.                     If Len(sNextErr) = 0 Then
  6114.                         If IsNum%(arrNextLine(2 + iAdjust)) = TRUE Then
  6115.                             iWhichInput = Val(arrNextLine(2 + iAdjust))
  6116.                         Else
  6117.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 2: not a number"
  6118.                         End If
  6119.                     End If
  6120.  
  6121.                     If Len(sNextErr) = 0 Then
  6122.                         If IsNum%(arrNextLine(3 + iAdjust)) = TRUE Then
  6123.                             iDevice = Val(arrNextLine(3 + iAdjust))
  6124.                         Else
  6125.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 3: not a number"
  6126.                         End If
  6127.                     End If
  6128.  
  6129.                     If Len(sNextErr) = 0 Then
  6130.                         If IsNum%(arrNextLine(4 + iAdjust)) = TRUE Then
  6131.                             iType = Val(arrNextLine(4 + iAdjust))
  6132.                         Else
  6133.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 4: not a number"
  6134.                         End If
  6135.                     End If
  6136.  
  6137.                     If Len(sNextErr) = 0 Then
  6138.                         If IsNum%(arrNextLine(5 + iAdjust)) = TRUE Then
  6139.                             iCode = Val(arrNextLine(5 + iAdjust))
  6140.                         Else
  6141.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 5: not a number"
  6142.                         End If
  6143.                     End If
  6144.  
  6145.                     If Len(sNextErr) = 0 Then
  6146.                         If IsNum%(arrNextLine(6 + iAdjust)) = TRUE Then
  6147.                             iValue = Val(arrNextLine(6 + iAdjust))
  6148.                         Else
  6149.                             sNextErr = "Error on line " + cstr$(iRead) + ", value 6: not a number"
  6150.                         End If
  6151.                     End If
  6152.  
  6153.                     ' validate iPlayer
  6154.                     If Len(sNextErr) = 0 Then
  6155.                         If iPlayer < LBound(m_arrControlMap, 1) Then
  6156.                             sNextErr = "Player value " + _Trim$(Str$(iPlayer)) + _
  6157.                                 " is outside lbound(m_arrControlMap, 1) " + _
  6158.                                 " which is " + _Trim$(Str$(lbound(m_arrControlMap, 1))) + "."
  6159.                         ElseIf iPlayer > UBound(m_arrControlMap, 1) Then
  6160.                             sNextErr = "Player value " + _Trim$(Str$(iPlayer)) + _
  6161.                                 " is outside ubound(m_arrControlMap, 1) " + _
  6162.                                 " which is " + _Trim$(Str$(ubound(m_arrControlMap, 1))) + "."
  6163.                         End If
  6164.                     End If
  6165.  
  6166.                     ' validate iWhichInput
  6167.                     If Len(sNextErr) = 0 Then
  6168.                         If iWhichInput < LBound(m_arrControlMap, 2) Then
  6169.                             sNextErr = "WhichInput value " + _Trim$(Str$(iWhichInput)) + _
  6170.                                 " is outside lbound(m_arrControlMap, 2) " + _
  6171.                                 " which is " + _Trim$(Str$(lbound(m_arrControlMap, 2))) + "."
  6172.                         ElseIf iWhichInput > UBound(m_arrControlMap, 2) Then
  6173.                             sNextErr = "WhichInput value " + _Trim$(Str$(iWhichInput)) + _
  6174.                                 " is outside ubound(m_arrControlMap, 2) " + _
  6175.                                 " which is " + _Trim$(Str$(ubound(m_arrControlMap, 2))) + "."
  6176.                         End If
  6177.                     End If
  6178.  
  6179.                     ' validate repeat setting
  6180.                     If iNumValues > 6 Then
  6181.                         If Len(sNextErr) = 0 Then
  6182.                             If IsNum%(arrNextLine(7 + iAdjust)) = TRUE Then
  6183.                                 bRepeat = Val(arrNextLine(7 + iAdjust))
  6184.                             Else
  6185.                                 sNextErr = "Error on line " + cstr$(iRead) + ", value 7: not a number"
  6186.                             End If
  6187.                         End If
  6188.                     Else
  6189.                         ' get values from global
  6190.                         'if m_bRepeatOverride = TRUE then
  6191.                         bRepeat = GetGlobalInputRepeatSetting%(iWhichInput)
  6192.                         'end if
  6193.                     End If
  6194.                 Else
  6195.                     sNextErr = "Error on line " + cstr$(iRead) + ": detected " + cstr$(iNumValues) + " values, expected 6."
  6196.                 End If
  6197.  
  6198.                 If Len(sNextErr) = 0 Then
  6199.                     iValid = iValid + 1
  6200.                     m_arrControlMap(iPlayer, iWhichInput).device = iDevice
  6201.                     m_arrControlMap(iPlayer, iWhichInput).typ = iType
  6202.                     m_arrControlMap(iPlayer, iWhichInput).code = iCode
  6203.                     m_arrControlMap(iPlayer, iWhichInput).value = iValue
  6204.                     m_arrControlMap(iPlayer, iWhichInput).repeat = bRepeat
  6205.                 Else
  6206.                     iBad = iBad + 1
  6207.                     DebugPrint sNextErr
  6208.                 End If
  6209.             Else
  6210.                 'DebugPrint "    Line is blank: skipped"
  6211.                 iBlank = iBlank + 1
  6212.             End If ' LEN(sLine) > 0
  6213.  
  6214.         Wend
  6215.         Close #1
  6216.     End If
  6217.  
  6218.     'DebugPrint ""
  6219.     'DebugPrint "Lines read: " + _Trim$(Str$(iRead))
  6220.     'DebugPrint "Valid     : " + _Trim$(Str$(iValid))
  6221.     'DebugPrint "Invalid   : " + _Trim$(Str$(iErrors))
  6222.     'DebugPrint "Blank     : " + _Trim$(Str$(iBlank))
  6223.     'DebugPrint ""
  6224.     'Input "PRESS <ENTER> TO CONTINUE", in$
  6225.  
  6226.     If Len(sError) = 0 Then
  6227.         sResult = "Loaded mapping file " + Chr$(34) + sFile + Chr$(34) + "."
  6228.         m_bHaveMapping = TRUE
  6229.     Else
  6230.         sResult = "ERRORS: " + sError
  6231.     End If
  6232.  
  6233.     LoadControllerMap1$ = sResult
  6234. End Function ' LoadControllerMap1$
  6235.  
  6236. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6237. ' END FILE FUNCTIONS
  6238. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6239.  
  6240.  
  6241.  
  6242.  
  6243.  
  6244.  
  6245.  
  6246.  
  6247.  
  6248.  
  6249.  
  6250.  
  6251.  
  6252.  
  6253.  
  6254. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6255. ' BEGIN GRAPHIC PRINTING ROUTINES
  6256. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6257.  
  6258. ' /////////////////////////////////////////////////////////////////////////////
  6259. ' A way to automatically print to columns.
  6260.  
  6261. Sub ColumnBreak ()
  6262.     m_PrintRow = m_StartRow
  6263.     m_PrintCol = m_PrintCol + 1
  6264.     If m_PrintCol > m_NumColumns Then
  6265.         'TODO: options for when we go past the last column (stop printing, wrap around)
  6266.     End If
  6267. End Sub ' ColumnBreak
  6268.  
  6269. ' /////////////////////////////////////////////////////////////////////////////
  6270. ' A way to automatically print to columns.
  6271.  
  6272. Sub InitColumns (iNumColumns As Integer)
  6273.     Dim iCols As Integer
  6274.     Dim iRows As Integer
  6275.     iCols = _Width(0) \ _FontWidth
  6276.     iRows = _Height(0) \ _FontHeight
  6277.     If iNumColumns < 1 Or iNumColumns > iCols Then
  6278.         m_NumColumns = 1
  6279.     Else
  6280.         m_NumColumns = iNumColumns
  6281.     End If
  6282.  
  6283.     If m_StartRow < 1 Or m_StartRow > iRows Then
  6284.         m_StartRow = 1
  6285.     End If
  6286.     If m_EndRow < m_StartRow Or m_EndRow > iRows Then
  6287.         m_EndRow = iRows
  6288.     End If
  6289.     If m_StartCol < 1 Or m_StartCol > m_NumColumns Then
  6290.         m_StartCol = 1
  6291.     End If
  6292.     If m_EndCol < m_StartCol Or m_EndCol > m_NumColumns Then
  6293.         m_EndCol = m_NumColumns
  6294.     End If
  6295.  
  6296.     m_PrintRow = 1
  6297.     m_PrintCol = 1
  6298. End Sub ' InitColumns
  6299.  
  6300. ' /////////////////////////////////////////////////////////////////////////////
  6301. ' A way to automatically print to columns.
  6302.  
  6303. ' Depends on the following shared variables:
  6304. '     Dim Shared m_NumColumns As Integer : m_NumColumns = 1
  6305. '     Dim Shared m_PrintRow As Integer : m_PrintRow = 0
  6306. '     Dim Shared m_PrintCol As Integer : m_PrintCol = 0
  6307. '     Dim Shared m_StartRow As Integer : m_StartRow = 0
  6308. '     Dim Shared m_EndRow As Integer : m_EndRow = 0
  6309. '     Dim Shared m_StartCol As Integer : m_StartCol = 0
  6310. '     Dim Shared m_EndCol As Integer : m_EndCol = 0
  6311.  
  6312. ' InitColumns 2
  6313. ' m_PrintRow = 5
  6314. ' m_PrintCol = 2
  6315. ' PrintColumn "Col 2, Row 5"
  6316. ' PrintColumn "m_NumColumns=" + cstr$(m_NumColumns)
  6317.  
  6318. Sub PrintColumn (MyString As String)
  6319.     Dim iCols As Integer
  6320.     Dim iRows As Integer
  6321.     Dim iX As Integer
  6322.     Dim iY As Integer
  6323.  
  6324.     ReDim arrLines(-1) As String
  6325.     Dim iRow As Integer
  6326.     Dim iCol As Integer
  6327.     Dim sChar As String
  6328.     Dim sLine As String
  6329.     Dim iColWidth As Integer
  6330.  
  6331.     iCols = _Width(0) \ _FontWidth
  6332.     iRows = _Height(0) \ _FontHeight
  6333.  
  6334.     If m_NumColumns < 1 Or m_NumColumns > iCols Then
  6335.         m_NumColumns = 1
  6336.     End If
  6337.  
  6338.     If m_StartRow < 1 Or m_StartRow > iRows Then
  6339.         m_StartRow = 1
  6340.     End If
  6341.     If m_EndRow < m_StartRow Or m_EndRow > iRows Then
  6342.         m_EndRow = iRows
  6343.     End If
  6344.     If m_StartCol < 1 Or m_StartCol > m_NumColumns Then
  6345.         m_StartCol = 1
  6346.     End If
  6347.     If m_EndCol < m_StartCol Or m_EndCol > m_NumColumns Then
  6348.         m_EndCol = m_NumColumns
  6349.     End If
  6350.  
  6351.     If m_PrintRow < m_StartRow Then
  6352.         m_PrintRow = m_StartRow
  6353.     End If
  6354.     If m_PrintCol < m_StartCol Then
  6355.         m_PrintCol = m_StartCol
  6356.     End If
  6357.  
  6358.     iColWidth = iCols \ m_NumColumns
  6359.  
  6360.     If m_PrintRow <= m_EndRow Then
  6361.         If m_PrintCol <= m_EndCol Then
  6362.             split MyString, Chr$(13), arrLines()
  6363.             For iRow = 0 To UBound(arrlines)
  6364.                 sLine = Left$(arrLines(iRow), iColWidth)
  6365.                 'TODO: wrap remaining text
  6366.                 iX = _FontWidth * ((m_PrintCol - 1) * iColWidth)
  6367.                 iY = _FontHeight * (m_PrintRow - 1)
  6368.                 _PrintString (iX, iY), sLine
  6369.  
  6370.                 m_PrintRow = m_PrintRow + 1
  6371.                 If m_PrintRow > m_EndRow Then
  6372.                     m_PrintRow = m_StartRow
  6373.                     m_PrintCol = m_PrintCol + 1
  6374.                     If m_PrintCol > m_NumColumns Then
  6375.                         'TODO: options for when we reach the bottom of the last column (stop printing, wrap around)
  6376.                         m_PrintCol = 1
  6377.                     End If
  6378.                 End If
  6379.             Next iRow
  6380.         End If
  6381.     End If
  6382. End Sub ' PrintColumn
  6383.  
  6384. ' /////////////////////////////////////////////////////////////////////////////
  6385. ' Eliminates the math.
  6386.  
  6387. ' Text resolution:
  6388. '  648 x  480:  80 x 30
  6389. '  720 x  480:  90 x 30
  6390. '  800 x  600: 100 x 37
  6391. ' 1024 x  768: 128 x 48
  6392. ' 1280 x 1024: 160 x 64
  6393. ' 1920 x 1080: 240 x 67
  6394. ' 2048 x 1152: 256 x 72 (truncated after 70 rows, 255 columns)
  6395. ' 3840 x 2160: 480 x135 (truncated after 133 rows, 479 columns)
  6396.  
  6397. Sub PrintStringCR1 (iCol As Integer, iRow As Integer, MyString As String)
  6398.     Dim iCols As Integer
  6399.     Dim iRows As Integer
  6400.     Dim iX As Integer
  6401.     Dim iY As Integer
  6402.     iCols = _Width(0) \ _FontWidth
  6403.     iRows = _Height(0) \ _FontHeight
  6404.     iX = _FontWidth * (iCol - 1)
  6405.     iY = _FontHeight * (iRow - 1)
  6406.     _PrintString (iX, iY), MyString
  6407. End Sub ' PrintStringCR1
  6408.  
  6409. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6410. ' END GRAPHIC PRINTING ROUTINES
  6411. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6412.  
  6413. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6414. ' BEGIN DEBUGGING ROUTINES #DEBUGGING
  6415. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6416.  
  6417. Sub DebugPrint (s$)
  6418.     If m_bTesting = TRUE Then
  6419.         _Echo s$
  6420.         'ReDim arrLines$(0)
  6421.         'dim delim$ : delim$ = Chr$(13)
  6422.         'split MyString, delim$, arrLines$()
  6423.     End If
  6424. End Sub ' DebugPrint
  6425.  
  6426. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6427. ' END DEBUGGING ROUTINES @DEBUGGING
  6428. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6429.  
  6430. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6431. ' BEGIN GENERAL PURPOSE ROUTINES #GEN
  6432. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6433.  
  6434. ' /////////////////////////////////////////////////////////////////////////////
  6435. ' Convert a value to string and trim it (because normal Str$ adds spaces)
  6436.  
  6437. Function cstr$ (myValue)
  6438.     'cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  6439.     cstr$ = _Trim$(Str$(myValue))
  6440. End Function ' cstr$
  6441.  
  6442. ' /////////////////////////////////////////////////////////////////////////////
  6443. ' Convert a Long value to string and trim it (because normal Str$ adds spaces)
  6444.  
  6445. Function cstrl$ (myValue As Long)
  6446.     cstrl$ = _Trim$(Str$(myValue))
  6447. End Function ' cstrl$
  6448.  
  6449. ' /////////////////////////////////////////////////////////////////////////////
  6450. ' Convert a Single value to string and trim it (because normal Str$ adds spaces)
  6451.  
  6452. Function cstrs$ (myValue As Single)
  6453.     ''cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  6454.     cstrs$ = _Trim$(Str$(myValue))
  6455. End Function ' cstrs$
  6456.  
  6457. ' /////////////////////////////////////////////////////////////////////////////
  6458. ' Convert an unsigned Long value to string and trim it (because normal Str$ adds spaces)
  6459.  
  6460. Function cstrul$ (myValue As _Unsigned Long)
  6461.     cstrul$ = _Trim$(Str$(myValue))
  6462. End Function ' cstrul$
  6463.  
  6464. ' /////////////////////////////////////////////////////////////////////////////
  6465. ' Scientific notation - QB64 Wiki
  6466. ' https://www.qb64.org/wiki/Scientific_notation
  6467.  
  6468. ' Example: A string function that displays extremely small or large exponential decimal values.
  6469.  
  6470. Function DblToStr$ (n#)
  6471.     value$ = UCase$(LTrim$(Str$(n#)))
  6472.     Xpos% = InStr(value$, "D") + InStr(value$, "E") 'only D or E can be present
  6473.     If Xpos% Then
  6474.         expo% = Val(Mid$(value$, Xpos% + 1))
  6475.         If Val(value$) < 0 Then
  6476.             sign$ = "-": valu$ = Mid$(value$, 2, Xpos% - 2)
  6477.         Else valu$ = Mid$(value$, 1, Xpos% - 1)
  6478.         End If
  6479.         dot% = InStr(valu$, "."): L% = Len(valu$)
  6480.         If expo% > 0 Then add$ = String$(expo% - (L% - dot%), "0")
  6481.         If expo% < 0 Then min$ = String$(Abs(expo%) - (dot% - 1), "0"): DP$ = "."
  6482.         For n = 1 To L%
  6483.             If Mid$(valu$, n, 1) <> "." Then num$ = num$ + Mid$(valu$, n, 1)
  6484.         Next
  6485.     Else DblToStr$ = value$: Exit Function
  6486.     End If
  6487.     DblToStr$ = _Trim$(sign$ + DP$ + min$ + num$ + add$)
  6488. End Function ' DblToStr$
  6489.  
  6490. ' /////////////////////////////////////////////////////////////////////////////
  6491.  
  6492. Function FormatNumber$ (myValue, iDigits As Integer)
  6493.     Dim strValue As String
  6494.     strValue = DblToStr$(myValue) + String$(iDigits, " ")
  6495.     If myValue < 1 Then
  6496.         If myValue < 0 Then
  6497.             strValue = Replace$(strValue, "-.", "-0.")
  6498.         ElseIf myValue > 0 Then
  6499.             strValue = "0" + strValue
  6500.         End If
  6501.     End If
  6502.     FormatNumber$ = Left$(strValue, iDigits)
  6503. End Function ' FormatNumber$
  6504.  
  6505. ' /////////////////////////////////////////////////////////////////////////////
  6506. ' From: Bitwise Manipulations By Steven Roman
  6507. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  6508.  
  6509. ' Returns the 8-bit binary representation
  6510. ' of an integer iInput where 0 <= iInput <= 255
  6511.  
  6512. Function GetBinary$ (iInput1 As Integer)
  6513.     Dim sResult As String
  6514.     Dim iLoop As Integer
  6515.     Dim iInput As Integer: iInput = iInput1
  6516.  
  6517.     sResult = ""
  6518.  
  6519.     If iInput >= 0 And iInput <= 255 Then
  6520.         For iLoop = 1 To 8
  6521.             sResult = LTrim$(RTrim$(Str$(iInput Mod 2))) + sResult
  6522.             iInput = iInput \ 2
  6523.             'If iLoop = 4 Then sResult = " " + sResult
  6524.         Next iLoop
  6525.     End If
  6526.  
  6527.     GetBinary$ = sResult
  6528. End Function ' GetBinary$
  6529.  
  6530. ' /////////////////////////////////////////////////////////////////////////////
  6531. ' wonderfully inefficient way to read if a bit is set
  6532. ' ival = GetBit256%(int we are comparing, int containing the bits we want to read)
  6533.  
  6534. ' See also: GetBit256%, SetBit256%
  6535.  
  6536. Function GetBit256% (iNum1 As Integer, iBit1 As Integer)
  6537.     Dim iResult As Integer
  6538.     Dim sNum As String
  6539.     Dim sBit As String
  6540.     Dim iLoop As Integer
  6541.     Dim bContinue As Integer
  6542.     'DIM iTemp AS INTEGER
  6543.     Dim iNum As Integer: iNum = iNum1
  6544.     Dim iBit As Integer: iBit = iBit1
  6545.  
  6546.     iResult = FALSE
  6547.     bContinue = TRUE
  6548.  
  6549.     If iNum < 256 And iBit <= 128 Then
  6550.         sNum = GetBinary$(iNum)
  6551.         sBit = GetBinary$(iBit)
  6552.         For iLoop = 1 To 8
  6553.             If Mid$(sBit, iLoop, 1) = "1" Then
  6554.                 'if any of the bits in iBit are false, return false
  6555.                 If Mid$(sNum, iLoop, 1) = "0" Then
  6556.                     iResult = FALSE
  6557.                     bContinue = FALSE
  6558.                     Exit For
  6559.                 End If
  6560.             End If
  6561.         Next iLoop
  6562.         If bContinue = TRUE Then
  6563.             iResult = TRUE
  6564.         End If
  6565.     End If
  6566.  
  6567.     GetBit256% = iResult
  6568. End Function ' GetBit256%
  6569.  
  6570. ' /////////////////////////////////////////////////////////////////////////////
  6571. ' From: Bitwise Manipulations By Steven Roman
  6572. ' http://www.romanpress.com/Articles/Bitwise_R/Bitwise.htm
  6573.  
  6574. ' Returns the integer that corresponds to a binary string of length 8
  6575.  
  6576. Function GetIntegerFromBinary% (sBinary1 As String)
  6577.     Dim iResult As Integer
  6578.     Dim iLoop As Integer
  6579.     Dim strBinary As String
  6580.     Dim sBinary As String: sBinary = sBinary1
  6581.  
  6582.     iResult = 0
  6583.     strBinary = Replace$(sBinary, " ", "") ' Remove any spaces
  6584.     For iLoop = 0 To Len(strBinary) - 1
  6585.         iResult = iResult + 2 ^ iLoop * Val(Mid$(strBinary, Len(strBinary) - iLoop, 1))
  6586.     Next iLoop
  6587.  
  6588.     GetIntegerFromBinary% = iResult
  6589. End Function ' GetIntegerFromBinary%
  6590.  
  6591. ' /////////////////////////////////////////////////////////////////////////////
  6592.  
  6593. Function IIF (Condition, IfTrue, IfFalse)
  6594.     If Condition Then IIF = IfTrue Else IIF = IfFalse
  6595.  
  6596. ' /////////////////////////////////////////////////////////////////////////////
  6597.  
  6598. Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
  6599.     If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
  6600.  
  6601. ' /////////////////////////////////////////////////////////////////////////////
  6602. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  6603.  
  6604. Function IsEven% (n)
  6605.     If n Mod 2 = 0 Then
  6606.         IsEven% = TRUE
  6607.     Else
  6608.         IsEven% = FALSE
  6609.     End If
  6610. End Function ' IsEven%
  6611.  
  6612. ' /////////////////////////////////////////////////////////////////////////////
  6613. ' https://slaystudy.com/qbasic-program-to-check-if-number-is-even-or-odd/
  6614.  
  6615. Function IsOdd% (n)
  6616.     If n Mod 2 = 1 Then
  6617.         IsOdd% = TRUE
  6618.     Else
  6619.         IsOdd% = FALSE
  6620.     End If
  6621. End Function ' IsOdd%
  6622.  
  6623. ' /////////////////////////////////////////////////////////////////////////////
  6624. ' By sMcNeill from https://www.qb64.org/forum/index.php?topic=896.0
  6625.  
  6626. Function IsNum% (text$)
  6627.     Dim a$
  6628.     Dim b$
  6629.     a$ = _Trim$(text$)
  6630.     b$ = _Trim$(Str$(Val(text$)))
  6631.     If a$ = b$ Then
  6632.         IsNum% = TRUE
  6633.     Else
  6634.         IsNum% = FALSE
  6635.     End If
  6636. End Function ' IsNum%
  6637.  
  6638. ' /////////////////////////////////////////////////////////////////////////////
  6639. ' Re: Does a Is Number function exist in QB64?
  6640. ' https://www.qb64.org/forum/index.php?topic=896.15
  6641.  
  6642. ' MWheatley
  6643. ' « Reply #18 on: January 01, 2019, 11:24:30 AM »
  6644.  
  6645. ' returns 1 if string is an integer, 0 if not
  6646. Function IsNumber (text$)
  6647.     Dim i As Integer
  6648.  
  6649.     IsNumber = 1
  6650.     For i = 1 To Len(text$)
  6651.         If Asc(Mid$(text$, i, 1)) < 45 Or Asc(Mid$(text$, i, 1)) >= 58 Then
  6652.             IsNumber = 0
  6653.             Exit For
  6654.         ElseIf Asc(Mid$(text$, i, 1)) = 47 Then
  6655.             IsNumber = 0
  6656.             Exit For
  6657.         End If
  6658.     Next i
  6659. End Function ' IsNumber
  6660.  
  6661. ' /////////////////////////////////////////////////////////////////////////////
  6662. ' Split and join strings
  6663. ' https://www.qb64.org/forum/index.php?topic=1073.0
  6664.  
  6665. 'Combine all elements of in$() into a single string with delimiter$ separating the elements.
  6666.  
  6667. Function join$ (in$(), delimiter$)
  6668.     Dim result$
  6669.     Dim i As Long
  6670.     result$ = in$(LBound(in$))
  6671.     For i = LBound(in$) + 1 To UBound(in$)
  6672.         result$ = result$ + delimiter$ + in$(i)
  6673.     Next i
  6674.     join$ = result$
  6675. End Function ' join$
  6676.  
  6677. ' /////////////////////////////////////////////////////////////////////////////
  6678. ' ABS was returning strange values with type LONG
  6679. ' so I created this which does not.
  6680.  
  6681. Function LongABS& (lngValue As Long)
  6682.     If Sgn(lngValue) = -1 Then
  6683.         LongABS& = 0 - lngValue
  6684.     Else
  6685.         LongABS& = lngValue
  6686.     End If
  6687. End Function ' LongABS&
  6688.  
  6689. ' /////////////////////////////////////////////////////////////////////////////
  6690. ' Writes sText to a debug file in the EXE folder.
  6691. ' Debug file is named the same thing as the program EXE name with ".txt" at the end.
  6692. ' For example the program "C:\QB64\MyProgram.BAS" running as
  6693. ' "C:\QB64\MyProgram.EXE" would have an output file "C:\QB64\MyProgram.EXE.txt".
  6694. ' If the file doesn't exist, it is created, otherwise it is appended to.
  6695.  
  6696. Sub DebugPrintFile (sText As String)
  6697.     Dim sFileName As String
  6698.     Dim sError As String
  6699.     Dim sOut As String
  6700.  
  6701.     sFileName = ProgramPath$ + ProgramName$ + ".txt"
  6702.     sError = ""
  6703.     If _FileExists(sFileName) = FALSE Then
  6704.         sOut = ""
  6705.         sOut = sOut + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + Chr$(13) + Chr$(10)
  6706.         sOut = sOut + "PROGRAM : " + ProgramName$ + Chr$(13) + Chr$(10)
  6707.         sOut = sOut + "RUN DATE: " + CurrentDateTime$ + Chr$(13) + Chr$(10)
  6708.         sOut = sOut + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + Chr$(13) + Chr$(10)
  6709.         sError = PrintFile$(sFileName, sOut, FALSE)
  6710.     End If
  6711.     If Len(sError) = 0 Then
  6712.         sError = PrintFile$(sFileName, sText, TRUE)
  6713.     End If
  6714.     If Len(sError) <> 0 Then
  6715.         Print CurrentDateTime$ + " DebugPrintFile FAILED: " + sError
  6716.     End If
  6717. End Sub ' DebugPrintFile
  6718.  
  6719. ' /////////////////////////////////////////////////////////////////////////////
  6720.  
  6721. Function IntPadRight$ (iValue As Integer, iWidth As Integer)
  6722.     IntPadRight$ = Left$(_Trim$(Str$(iValue)) + String$(iWidth, " "), iWidth)
  6723. End Function ' IntPadRight$
  6724.  
  6725. ' /////////////////////////////////////////////////////////////////////////////
  6726. ' Returns blank if successful else returns error message.
  6727.  
  6728. Function PrintFile$ (sFileName As String, sText As String, bAppend As Integer)
  6729.     'x = 1: y = 2: z$ = "Three"
  6730.  
  6731.     Dim sError As String: sError = ""
  6732.  
  6733.     If Len(sError) = 0 Then
  6734.         If (bAppend = TRUE) Then
  6735.             If _FileExists(sFileName) Then
  6736.                 Open sFileName For Append As #1 ' opens an existing file for appending
  6737.             Else
  6738.                 sError = "Error in PrintFile$ : File not found. Cannot append."
  6739.             End If
  6740.         Else
  6741.             Open sFileName For Output As #1 ' opens and clears an existing file or creates new empty file
  6742.         End If
  6743.     End If
  6744.     If Len(sError) = 0 Then
  6745.         ' WRITE places text in quotes in the file
  6746.         'WRITE #1, x, y, z$
  6747.         'WRITE #1, sText
  6748.  
  6749.         ' PRINT does not put text inside quotes
  6750.         Print #1, sText
  6751.  
  6752.         Close #1
  6753.  
  6754.         'PRINT "File created with data. Press a key!"
  6755.         'K$ = INPUT$(1) 'press a key
  6756.  
  6757.         'OPEN sFileName FOR INPUT AS #2 ' opens a file to read it
  6758.         'INPUT #2, a, b, c$
  6759.         'CLOSE #2
  6760.  
  6761.         'PRINT a, b, c$
  6762.         'WRITE a, b, c$
  6763.     End If
  6764.  
  6765.     PrintFile$ = sError
  6766. End Function ' PrintFile$
  6767.  
  6768. ' /////////////////////////////////////////////////////////////////////////////
  6769. ' Does a _PrintString at the specified row+column.
  6770.  
  6771. ' iRow and iCol are 0-based.
  6772.  
  6773. Sub PrintString (iRow As Integer, iCol As Integer, MyString As String)
  6774.     Dim iX As Integer
  6775.     Dim iY As Integer
  6776.     iX = _FontWidth * iCol
  6777.     iY = _FontHeight * iRow ' (iRow + 1)
  6778.     _PrintString (iX, iY), MyString
  6779. End Sub ' PrintString
  6780.  
  6781. ' /////////////////////////////////////////////////////////////////////////////
  6782. ' Does a _PrintString at the specified row+column.
  6783.  
  6784. ' iRow and iCol are 1-based.
  6785.  
  6786. Sub PrintString1 (iRow As Integer, iCol As Integer, MyString As String)
  6787.     Dim iX As Integer
  6788.     Dim iY As Integer
  6789.     iX = _FontWidth * (iCol-1)
  6790.     iY = _FontHeight * (iRow-1)
  6791.     _PrintString (iX, iY), MyString
  6792. End Sub ' PrintString1
  6793.  
  6794. ' /////////////////////////////////////////////////////////////////////////////
  6795. ' Does a _PrintString at the specified row+column,
  6796. ' and saves value and color info to ScreenArray.
  6797.  
  6798. ' PrintString2 iRow, iCol, MyString, ScreenArray()
  6799.  
  6800. ' iRow and iCol are 1-based.
  6801.  
  6802. Sub PrintString2 (iRow As Integer, iCol As Integer, MyString As String, ScreenArray() As TextCellType)
  6803.     Dim iX As Integer
  6804.     Dim iY As Integer
  6805.     Dim iLoop As Integer
  6806.    
  6807.     iX = _FontWidth * (iCol-1)
  6808.     iY = _FontHeight * (iRow-1)
  6809.     _PrintString (iX, iY), MyString
  6810.    
  6811.     if (iRow >= lbound(ScreenArray, 1) ) then
  6812.         if (iRow <= ubound(ScreenArray, 1) ) then
  6813.             if (iCol >= lbound(ScreenArray, 2) ) then
  6814.                 if (iCol <= ubound(ScreenArray, 2) ) then
  6815.                     iX = iCol
  6816.                     iY = iRow
  6817.                     for iLoop = 1 to len(MyString)
  6818.                         if iX > ubound(ScreenArray, 2) then
  6819.                             exit for
  6820.                         else
  6821.                             ScreenArray(iY, iX).value = mid$(MyString, iLoop, 1)
  6822.                             ScreenArray(iY, iX).fgColor = _DEFAULTCOLOR
  6823.                             ScreenArray(iY, iX).bgColor = _BACKGROUNDCOLOR
  6824.                             iX = iX + 1
  6825.                         end if
  6826.                     next iLoop
  6827.                 end if
  6828.             end if
  6829.         end if
  6830.     end if
  6831. End Sub ' PrintString2
  6832.  
  6833. ' /////////////////////////////////////////////////////////////////////////////
  6834. ' Generate random value between Min and Max.
  6835. Function RandomNumber% (Min%, Max%)
  6836.     Dim NumSpread%
  6837.  
  6838.     ' SET RANDOM SEED
  6839.     'Randomize ' Initialize random-number generator.
  6840.  
  6841.     ' GET RANDOM # Min%-Max%
  6842.     'RandomNumber = Int((Max * Rnd) + Min) ' generate number
  6843.  
  6844.     NumSpread% = (Max% - Min%) + 1
  6845.  
  6846.     RandomNumber% = Int(Rnd * NumSpread%) + Min% ' GET RANDOM # BETWEEN Max% AND Min%
  6847.  
  6848. End Function ' RandomNumber%
  6849.  
  6850. ' /////////////////////////////////////////////////////////////////////////////
  6851.  
  6852. Sub RandomNumberTest
  6853.     Dim iCols As Integer: iCols = 10
  6854.     Dim iRows As Integer: iRows = 20
  6855.     Dim iLoop As Integer
  6856.     Dim iX As Integer
  6857.     Dim iY As Integer
  6858.     Dim sError As String
  6859.     Dim sFileName As String
  6860.     Dim sText As String
  6861.     Dim bAppend As Integer
  6862.     Dim iMin As Integer
  6863.     Dim iMax As Integer
  6864.     Dim iNum As Integer
  6865.     Dim iErrorCount As Integer
  6866.     Dim sInput$
  6867.  
  6868.     sFileName = "c:\temp\maze_test_1.txt"
  6869.     sText = "Count" + Chr$(9) + "Min" + Chr$(9) + "Max" + Chr$(9) + "Random"
  6870.     bAppend = FALSE
  6871.     sError = PrintFile$(sFileName, sText, bAppend)
  6872.     If Len(sError) = 0 Then
  6873.         bAppend = TRUE
  6874.         iErrorCount = 0
  6875.  
  6876.         iMin = 0
  6877.         iMax = iCols - 1
  6878.         For iLoop = 1 To 100
  6879.             iNum = RandomNumber%(iMin, iMax)
  6880.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  6881.             sError = PrintFile$(sFileName, sText, bAppend)
  6882.             If Len(sError) > 0 Then
  6883.                 iErrorCount = iErrorCount + 1
  6884.                 Print Str$(iLoop) + ". ERROR"
  6885.                 Print "    " + "iMin=" + Str$(iMin)
  6886.                 Print "    " + "iMax=" + Str$(iMax)
  6887.                 Print "    " + "iNum=" + Str$(iNum)
  6888.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  6889.                 Print "    " + sError
  6890.             End If
  6891.         Next iLoop
  6892.  
  6893.         iMin = 0
  6894.         iMax = iRows - 1
  6895.         For iLoop = 1 To 100
  6896.             iNum = RandomNumber%(iMin, iMax)
  6897.             sText = Str$(iLoop) + Chr$(9) + Str$(iMin) + Chr$(9) + Str$(iMax) + Chr$(9) + Str$(iNum)
  6898.             sError = PrintFile$(sFileName, sText, bAppend)
  6899.             If Len(sError) > 0 Then
  6900.                 iErrorCount = iErrorCount + 1
  6901.                 Print Str$(iLoop) + ". ERROR"
  6902.                 Print "    " + "iMin=" + Str$(iMin)
  6903.                 Print "    " + "iMax=" + Str$(iMax)
  6904.                 Print "    " + "iNum=" + Str$(iNum)
  6905.                 Print "    " + "Could not write to file " + Chr$(34) + sFileName + Chr$(34) + "."
  6906.                 Print "    " + sError
  6907.             End If
  6908.         Next iLoop
  6909.  
  6910.         Print "Finished generating numbers. Errors: " + Str$(iErrorCount)
  6911.     Else
  6912.         Print "Error creating file " + Chr$(34) + sFileName + Chr$(34) + "."
  6913.         Print sError
  6914.     End If
  6915.  
  6916.     Input "Press <ENTER> to continue", sInput$
  6917. End Sub ' RandomNumberTest
  6918.  
  6919. ' /////////////////////////////////////////////////////////////////////////////
  6920. ' FROM: String Manipulation
  6921. ' found at abandoned, outdated and now likely malicious qb64 dot net website
  6922. ' http://www.qb64.[net]/forum/index_topic_5964-0/
  6923. '
  6924. 'SUMMARY:
  6925. '   Purpose:  A library of custom functions that transform strings.
  6926. '   Author:   Dustinian Camburides (dustinian@gmail.com)
  6927. '   Platform: QB64 (www.qb64.org)
  6928. '   Revision: 1.6
  6929. '   Updated:  5/28/2012
  6930.  
  6931. 'SUMMARY:
  6932. '[Replace$] replaces all instances of the [Find] sub-string with the [Add] sub-string within the [Text] string.
  6933. 'INPUT:
  6934. 'Text: The input string; the text that's being manipulated.
  6935. 'Find: The specified sub-string; the string sought within the [Text] string.
  6936. 'Add: The sub-string that's being added to the [Text] string.
  6937.  
  6938. Function Replace$ (Text1 As String, Find1 As String, Add1 As String)
  6939.     ' VARIABLES:
  6940.     Dim Text2 As String
  6941.     Dim Find2 As String
  6942.     Dim Add2 As String
  6943.     Dim lngLocation As Long ' The address of the [Find] substring within the [Text] string.
  6944.     Dim strBefore As String ' The characters before the string to be replaced.
  6945.     Dim strAfter As String ' The characters after the string to be replaced.
  6946.  
  6947.     ' INITIALIZE:
  6948.     ' MAKE COPIESSO THE ORIGINAL IS NOT MODIFIED (LIKE ByVal IN VBA)
  6949.     Text2 = Text1
  6950.     Find2 = Find1
  6951.     Add2 = Add1
  6952.  
  6953.     lngLocation = InStr(1, Text2, Find2)
  6954.  
  6955.     ' PROCESSING:
  6956.     ' While [Find2] appears in [Text2]...
  6957.     While lngLocation
  6958.         ' Extract all Text2 before the [Find2] substring:
  6959.         strBefore = Left$(Text2, lngLocation - 1)
  6960.  
  6961.         ' Extract all text after the [Find2] substring:
  6962.         strAfter = Right$(Text2, ((Len(Text2) - (lngLocation + Len(Find2) - 1))))
  6963.  
  6964.         ' Return the substring:
  6965.         Text2 = strBefore + Add2 + strAfter
  6966.  
  6967.         ' Locate the next instance of [Find2]:
  6968.         lngLocation = InStr(1, Text2, Find2)
  6969.  
  6970.         ' Next instance of [Find2]...
  6971.     Wend
  6972.  
  6973.     ' OUTPUT:
  6974.     Replace$ = Text2
  6975. End Function ' Replace$
  6976.  
  6977. ' /////////////////////////////////////////////////////////////////////////////
  6978.  
  6979. Sub ReplaceTest
  6980.     Dim in$
  6981.  
  6982.     Print "-------------------------------------------------------------------------------"
  6983.     Print "ReplaceTest"
  6984.     Print
  6985.  
  6986.     Print "Original value"
  6987.     in$ = "Thiz iz a teZt."
  6988.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6989.     Print
  6990.  
  6991.     Print "Replacing lowercase " + Chr$(34) + "z" + Chr$(34) + " with " + Chr$(34) + "s" + Chr$(34) + "..."
  6992.     in$ = Replace$(in$, "z", "s")
  6993.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6994.     Print
  6995.  
  6996.     Print "Replacing uppercase " + Chr$(34) + "Z" + Chr$(34) + " with " + Chr$(34) + "s" + Chr$(34) + "..."
  6997.     in$ = Replace$(in$, "Z", "s")
  6998.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  6999.     Print
  7000.  
  7001.     Print "ReplaceTest finished."
  7002. End Sub ' ReplaceTest
  7003.  
  7004. ' /////////////////////////////////////////////////////////////////////////////
  7005. ' https://www.qb64.org/forum/index.php?topic=3605.0
  7006. ' Quote from: SMcNeill on Today at 03:53:48 PM
  7007. '
  7008. ' Sometimes, you guys make things entirely too  complicated.
  7009. ' There ya go!  Three functions to either round naturally,
  7010. ' always round down, or always round up, to whatever number of digits you desire.
  7011. ' EDIT:  Modified to add another option to round scientific,
  7012. ' since you had it's description included in your example.
  7013.  
  7014. Function Round## (num##, digits%)
  7015.     Round## = Int(num## * 10 ^ digits% + .5) / 10 ^ digits%
  7016.  
  7017. Function RoundUp## (num##, digits%)
  7018.     RoundUp## = _Ceil(num## * 10 ^ digits%) / 10 ^ digits%
  7019.  
  7020. Function RoundDown## (num##, digits%)
  7021.     RoundDown## = Int(num## * 10 ^ digits%) / 10 ^ digits%
  7022.  
  7023. Function Round_Scientific## (num##, digits%)
  7024.     Round_Scientific## = _Round(num## * 10 ^ digits%) / 10 ^ digits%
  7025.  
  7026. Function RoundUpDouble# (num#, digits%)
  7027.     RoundUpDouble# = _Ceil(num# * 10 ^ digits%) / 10 ^ digits%
  7028.  
  7029. Function RoundUpSingle! (num!, digits%)
  7030.     RoundUpSingle! = _Ceil(num! * 10 ^ digits%) / 10 ^ digits%
  7031.  
  7032. ' /////////////////////////////////////////////////////////////////////////////
  7033. ' fantastically inefficient way to set a bit
  7034.  
  7035. ' example use: arrMaze(iX, iY) = SetBit256%(arrMaze(iX, iY), cS, FALSE)
  7036.  
  7037. ' See also: GetBit256%, SetBit256%
  7038.  
  7039. ' newint=SetBit256%(oldint, int containing the bits we want to set, value to set them to)
  7040. Function SetBit256% (iNum1 As Integer, iBit1 As Integer, bVal1 As Integer)
  7041.     Dim sNum As String
  7042.     Dim sBit As String
  7043.     Dim sVal As String
  7044.     Dim iLoop As Integer
  7045.     Dim strResult As String
  7046.     Dim iResult As Integer
  7047.     Dim iNum As Integer: iNum = iNum1
  7048.     Dim iBit As Integer: iBit = iBit1
  7049.     Dim bVal As Integer: bVal = bVal1
  7050.  
  7051.     If iNum < 256 And iBit <= 128 Then
  7052.         sNum = GetBinary$(iNum)
  7053.         sBit = GetBinary$(iBit)
  7054.         If bVal = TRUE Then
  7055.             sVal = "1"
  7056.         Else
  7057.             sVal = "0"
  7058.         End If
  7059.         strResult = ""
  7060.         For iLoop = 1 To 8
  7061.             If Mid$(sBit, iLoop, 1) = "1" Then
  7062.                 strResult = strResult + sVal
  7063.             Else
  7064.                 strResult = strResult + Mid$(sNum, iLoop, 1)
  7065.             End If
  7066.         Next iLoop
  7067.         iResult = GetIntegerFromBinary%(strResult)
  7068.     Else
  7069.         iResult = iNum
  7070.     End If
  7071.  
  7072.     SetBit256% = iResult
  7073. End Function ' SetBit256%
  7074.  
  7075. ' /////////////////////////////////////////////////////////////////////////////
  7076. ' Scientific notation - QB64 Wiki
  7077. ' https://www.qb64.org/wiki/Scientific_notation
  7078.  
  7079. ' Example: A string function that displays extremely small or large exponential decimal values.
  7080.  
  7081. Function SngToStr$ (n!)
  7082.     value$ = UCase$(LTrim$(Str$(n!)))
  7083.     Xpos% = InStr(value$, "D") + InStr(value$, "E") 'only D or E can be present
  7084.     If Xpos% Then
  7085.         expo% = Val(Mid$(value$, Xpos% + 1))
  7086.         If Val(value$) < 0 Then
  7087.             sign$ = "-": valu$ = Mid$(value$, 2, Xpos% - 2)
  7088.         Else valu$ = Mid$(value$, 1, Xpos% - 1)
  7089.         End If
  7090.         dot% = InStr(valu$, "."): L% = Len(valu$)
  7091.         If expo% > 0 Then add$ = String$(expo% - (L% - dot%), "0")
  7092.         If expo% < 0 Then min$ = String$(Abs(expo%) - (dot% - 1), "0"): DP$ = "."
  7093.         For n = 1 To L%
  7094.             If Mid$(valu$, n, 1) <> "." Then num$ = num$ + Mid$(valu$, n, 1)
  7095.         Next
  7096.     Else SngToStr$ = value$: Exit Function
  7097.     End If
  7098.     SngToStr$ = _Trim$(sign$ + DP$ + min$ + num$ + add$)
  7099. End Function ' SngToStr$
  7100.  
  7101. ' /////////////////////////////////////////////////////////////////////////////
  7102. ' Split and join strings
  7103. ' https://www.qb64.org/forum/index.php?topic=1073.0
  7104. '
  7105. ' FROM luke, QB64 Developer
  7106. ' Date: February 15, 2019, 04:11:07 AM »
  7107. '
  7108. ' Given a string of words separated by spaces (or any other character),
  7109. ' splits it into an array of the words. I've no doubt many people have
  7110. ' written a version of this over the years and no doubt there's a million
  7111. ' ways to do it, but I thought I'd put mine here so we have at least one
  7112. ' version. There's also a join function that does the opposite
  7113. ' array -> single string.
  7114. '
  7115. ' Code is hopefully reasonably self explanatory with comments and a little demo.
  7116. ' Note, this is akin to Python/JavaScript split/join, PHP explode/implode.
  7117.  
  7118. 'Split in$ into pieces, chopping at every occurrence of delimiter$. Multiple consecutive occurrences
  7119. 'of delimiter$ are treated as a single instance. The chopped pieces are stored in result$().
  7120. '
  7121. 'delimiter$ must be one character long.
  7122. 'result$() must have been REDIMmed previously.
  7123.  
  7124. ' Modified to handle multi-character delimiters
  7125.  
  7126. Sub split (in$, delimiter$, result$())
  7127.     Dim start As Integer
  7128.     Dim finish As Integer
  7129.     Dim iDelimLen As Integer
  7130.     ReDim result$(-1)
  7131.  
  7132.     iDelimLen = Len(delimiter$)
  7133.  
  7134.     start = 1
  7135.     Do
  7136.         'While Mid$(in$, start, 1) = delimiter$
  7137.         While Mid$(in$, start, iDelimLen) = delimiter$
  7138.             'start = start + 1
  7139.             start = start + iDelimLen
  7140.             If start > Len(in$) Then
  7141.                 Exit Sub
  7142.             End If
  7143.         Wend
  7144.         finish = InStr(start, in$, delimiter$)
  7145.         If finish = 0 Then
  7146.             finish = Len(in$) + 1
  7147.         End If
  7148.  
  7149.         ReDim _Preserve result$(0 To UBound(result$) + 1)
  7150.  
  7151.         result$(UBound(result$)) = Mid$(in$, start, finish - start)
  7152.         start = finish + 1
  7153.     Loop While start <= Len(in$)
  7154. End Sub ' split
  7155.  
  7156. ' /////////////////////////////////////////////////////////////////////////////
  7157.  
  7158. Sub SplitTest
  7159.     Dim in$
  7160.     Dim delim$
  7161.     ReDim arrTest$(0)
  7162.     Dim iLoop%
  7163.  
  7164.     delim$ = Chr$(10)
  7165.     in$ = "this" + delim$ + "is" + delim$ + "a" + delim$ + "test"
  7166.     Print "in$ = " + Chr$(34) + in$ + Chr$(34)
  7167.     Print "delim$ = " + Chr$(34) + delim$ + Chr$(34)
  7168.     split in$, delim$, arrTest$()
  7169.  
  7170.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  7171.         Print "arrTest$(" + LTrim$(RTrim$(Str$(iLoop%))) + ") = " + Chr$(34) + arrTest$(iLoop%) + Chr$(34)
  7172.     Next iLoop%
  7173.     Print
  7174.     Print "Split test finished."
  7175. End Sub ' SplitTest
  7176.  
  7177. ' /////////////////////////////////////////////////////////////////////////////
  7178.  
  7179. Sub SplitAndReplaceTest
  7180.     Dim in$
  7181.     Dim out$
  7182.     Dim iLoop%
  7183.     ReDim arrTest$(0)
  7184.  
  7185.     Print "-------------------------------------------------------------------------------"
  7186.     Print "SplitAndReplaceTest"
  7187.     Print
  7188.  
  7189.     Print "Original value"
  7190.     in$ = "This line 1 " + Chr$(13) + Chr$(10) + "and line 2" + Chr$(10) + "and line 3 " + Chr$(13) + "finally THE END."
  7191.     out$ = in$
  7192.     out$ = Replace$(out$, Chr$(13), "\r")
  7193.     out$ = Replace$(out$, Chr$(10), "\n")
  7194.     out$ = Replace$(out$, Chr$(9), "\t")
  7195.     Print "in$ = " + Chr$(34) + out$ + Chr$(34)
  7196.     Print
  7197.  
  7198.     Print "Fixing linebreaks..."
  7199.     in$ = Replace$(in$, Chr$(13) + Chr$(10), Chr$(13))
  7200.     in$ = Replace$(in$, Chr$(10), Chr$(13))
  7201.     out$ = in$
  7202.     out$ = Replace$(out$, Chr$(13), "\r")
  7203.     out$ = Replace$(out$, Chr$(10), "\n")
  7204.     out$ = Replace$(out$, Chr$(9), "\t")
  7205.     Print "in$ = " + Chr$(34) + out$ + Chr$(34)
  7206.     Print
  7207.  
  7208.     Print "Splitting up..."
  7209.     split in$, Chr$(13), arrTest$()
  7210.  
  7211.     For iLoop% = LBound(arrTest$) To UBound(arrTest$)
  7212.         out$ = arrTest$(iLoop%)
  7213.         out$ = Replace$(out$, Chr$(13), "\r")
  7214.         out$ = Replace$(out$, Chr$(10), "\n")
  7215.         out$ = Replace$(out$, Chr$(9), "\t")
  7216.         Print "arrTest$(" + cstr$(iLoop%) + ") = " + Chr$(34) + out$ + Chr$(34)
  7217.     Next iLoop%
  7218.     Print
  7219.  
  7220.     Print "SplitAndReplaceTest finished."
  7221. End Sub ' SplitAndReplaceTest
  7222.  
  7223. ' /////////////////////////////////////////////////////////////////////////////
  7224.  
  7225. Function StrPadLeft$ (sValue As String, iWidth As Integer)
  7226.     StrPadLeft$ = Right$(String$(iWidth, " ") + sValue, iWidth)
  7227. End Function ' StrPadLeft$
  7228.  
  7229. ' /////////////////////////////////////////////////////////////////////////////
  7230.  
  7231. Function StrJustifyRight$ (sValue As String, iWidth As Integer)
  7232.     StrJustifyRight$ = Right$(String$(iWidth, " ") + sValue, iWidth)
  7233. End Function ' StrJustifyRight$
  7234.  
  7235. ' /////////////////////////////////////////////////////////////////////////////
  7236.  
  7237. Function StrPadRight$ (sValue As String, iWidth As Integer)
  7238.     StrPadRight$ = Left$(sValue + String$(iWidth, " "), iWidth)
  7239. End Function ' StrPadRight$
  7240.  
  7241. ' /////////////////////////////////////////////////////////////////////////////
  7242.  
  7243. Function StrJustifyLeft$ (sValue As String, iWidth As Integer)
  7244.     StrJustifyLeft$ = Left$(sValue + String$(iWidth, " "), iWidth)
  7245. End Function ' StrJustifyLeft$
  7246.  
  7247. ' /////////////////////////////////////////////////////////////////////////////
  7248. ' div: int1% = num1% \ den1%
  7249. ' mod: rem1% = num1% MOD den1%
  7250.  
  7251. Function StrJustifyCenter$ (sValue As String, iWidth As Integer)
  7252.     Dim iLen0 As Integer
  7253.     Dim iLen1 As Integer
  7254.     Dim iLen2 As Integer
  7255.     Dim iExtra As Integer
  7256.  
  7257.     iLen0 = Len(sValue)
  7258.     If iWidth = iLen0 Then
  7259.         ' no extra space: return unchanged
  7260.         StrJustifyCenter$ = sValue
  7261.     ElseIf iWidth > iLen0 Then
  7262.         If IsOdd%(iWidth) Then
  7263.             iWidth = iWidth - 1
  7264.         End If
  7265.  
  7266.         ' center
  7267.         iExtra = iWidth - iLen0
  7268.         iLen1 = iExtra \ 2
  7269.         iLen2 = iLen1 + (iExtra Mod 2)
  7270.         StrJustifyCenter$ = String$(iLen1, " ") + sValue + String$(iLen2, " ")
  7271.     Else
  7272.         ' string is too long: truncate
  7273.         StrJustifyCenter$ = Left$(sValue, iWidth)
  7274.     End If
  7275. End Function ' StrJustifyCenter$
  7276.  
  7277. ' /////////////////////////////////////////////////////////////////////////////
  7278.  
  7279. Function TrueFalse$ (myValue)
  7280.     If myValue = TRUE Then
  7281.         TrueFalse$ = "TRUE"
  7282.     Else
  7283.         TrueFalse$ = "FALSE"
  7284.     End If
  7285. End Function ' TrueFalse$
  7286.  
  7287. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7288. ' END GENERAL PURPOSE ROUTINES
  7289. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7290.  
  7291.  
  7292.  
  7293.  
  7294.  
  7295.  
  7296.  
  7297. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7298. ' BEGIN COLOR ARRAY FUNCTIONS
  7299. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7300.  
  7301. ' /////////////////////////////////////////////////////////////////////////////
  7302.  
  7303. Sub AddColor (ColorValue As _Unsigned Long, ColorName As String, arrColor() As ColorType)
  7304.     ReDim _Preserve arrColor(0 To UBound(arrColor) + 1) As ColorType
  7305.     arrColor(UBound(arrColor)).name = ColorName
  7306.     arrColor(UBound(arrColor)).value = ColorValue
  7307. End Sub ' AddColor
  7308.  
  7309. ' /////////////////////////////////////////////////////////////////////////////
  7310.  
  7311. Sub AddColors (arrColor() As ColorType)
  7312.     AddColor cBlack, "cBlack", arrColor()
  7313.     ''AddColor cDarkGray, "cDarkGray", arrColor()
  7314.     ''AddColor cDimGray, "cDimGray", arrColor()
  7315.     AddColor cGray, "cGray", arrColor()
  7316.     AddColor cSilver, "cSilver", arrColor()
  7317.     ''AddColor cLightGray, "cLightGray", arrColor()
  7318.     AddColor cWhite, "cWhite", arrColor()
  7319.  
  7320.     AddColor cRed, "cRed", arrColor()
  7321.     AddColor cOrangeRed, "cOrangeRed", arrColor()
  7322.     'AddColor cDarkOrange, "cDarkOrange", arrColor()
  7323.     'AddColor cOrange, "cOrange", arrColor()
  7324.     'AddColor cGold, "cGold", arrColor()
  7325.     AddColor cYellow, "cYellow", arrColor()
  7326.     'AddColor cOliveDrab1, "cOliveDrab1", arrColor()
  7327.     AddColor cLime, "cLime", arrColor()
  7328.     'AddColor cMediumSpringGreen, "cMediumSpringGreen", arrColor()
  7329.     AddColor cCyan, "cCyan", arrColor()
  7330.     'AddColor cDeepSkyBlue, "cDeepSkyBlue", arrColor()
  7331.     AddColor cDodgerBlue, "cDodgerBlue", arrColor()
  7332.     'AddColor cSeaBlue, "cSeaBlue", arrColor()
  7333.     AddColor cBlue, "cBlue", arrColor()
  7334.     'AddColor cBluePurple, "cBluePurple", arrColor()
  7335.     AddColor cDeepPurple, "cDeepPurple", arrColor()
  7336.     'AddColor cPurple, "cPurple", arrColor()
  7337.     'AddColor cPurpleRed, "cPurpleRed", arrColor()
  7338.  
  7339.     ''AddColor cGainsboro, "cGainsboro", arrColor()
  7340.     ''AddColor cWhiteSmoke, "cWhiteSmoke", arrColor()
  7341.  
  7342.     'AddColor cDarkRed, "cDarkRed", arrColor()
  7343.     ''AddColor cBrickRed, "cBrickRed", arrColor()
  7344.  
  7345.     AddColor cDarkGreen, "cDarkGreen", arrColor()
  7346.     'AddColor cGreen, "cGreen", arrColor()
  7347.     ''AddColor cOliveDrab, "cOliveDrab", arrColor()
  7348.     ''AddColor cLightPink, "cLightPink", arrColor()
  7349.     AddColor cMagenta, "cMagenta", arrColor()
  7350.     AddColor cHotPink, "cHotPink", arrColor()
  7351.     'AddColor cDeepPink, "cDeepPink", arrColor()
  7352.  
  7353.     AddColor cDarkBrown, "cDarkBrown", arrColor()
  7354.     'AddColor cLightBrown, "cLightBrown", arrColor()
  7355.     'AddColor cKhaki, "cKhaki", arrColor()
  7356.  
  7357.     AddColor cEmpty, "cEmpty", arrColor()
  7358. End Sub ' AddColors
  7359.  
  7360. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7361. ' END COLOR ARRAY FUNCTIONS
  7362. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7363.  
  7364.  
  7365.  
  7366.  
  7367. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7368. ' BEGIN COLOR FUNCTIONS
  7369. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7370.  
  7371. ' NOTE: these are mostly negative numbers
  7372. '       and have to be forced to positive
  7373. '       when stored in the dictionary
  7374. '       (only cEmpty should be negative)
  7375.  
  7376. Function cRed~& ()
  7377.     cRed = _RGB32(255, 0, 0)
  7378.  
  7379. Function cOrangeRed~& ()
  7380.     cOrangeRed = _RGB32(255, 69, 0)
  7381. End Function ' cOrangeRed~&
  7382.  
  7383. Function cDarkOrange~& ()
  7384.     cDarkOrange = _RGB32(255, 140, 0)
  7385. End Function ' cDarkOrange~&
  7386.  
  7387. Function cOrange~& ()
  7388.     cOrange = _RGB32(255, 165, 0)
  7389. End Function ' cOrange~&
  7390.  
  7391. Function cGold~& ()
  7392.     cGold = _RGB32(255, 215, 0)
  7393. End Function ' cGold~&
  7394.  
  7395. Function cYellow~& ()
  7396.     cYellow = _RGB32(255, 255, 0)
  7397. End Function ' cYellow~&
  7398.  
  7399. ' LONG-HAIRED FRIENDS OF JESUS OR NOT,
  7400. ' THIS IS NOT YELLOW ENOUGH (TOO CLOSE TO LIME)
  7401. ' TO USE FOR OUR COMPLEX RAINBOW SEQUENCE:
  7402. Function cChartreuse~& ()
  7403.     cChartreuse = _RGB32(127, 255, 0)
  7404. End Function ' cChartreuse~&
  7405.  
  7406. ' WE SUBSTITUTE THIS CSS3 COLOR FOR INBETWEEN LIME AND YELLOW:
  7407. Function cOliveDrab1~& ()
  7408.     cOliveDrab1 = _RGB32(192, 255, 62)
  7409. End Function ' cOliveDrab1~&
  7410.  
  7411. Function cLime~& ()
  7412.     cLime = _RGB32(0, 255, 0)
  7413. End Function ' cLime~&
  7414.  
  7415. Function cMediumSpringGreen~& ()
  7416.     cMediumSpringGreen = _RGB32(0, 250, 154)
  7417. End Function ' cMediumSpringGreen~&
  7418.  
  7419. Function cCyan~& ()
  7420.     cCyan = _RGB32(0, 255, 255)
  7421. End Function ' cCyan~&
  7422.  
  7423. Function cDeepSkyBlue~& ()
  7424.     cDeepSkyBlue = _RGB32(0, 191, 255)
  7425. End Function ' cDeepSkyBlue~&
  7426.  
  7427. Function cDodgerBlue~& ()
  7428.     cDodgerBlue = _RGB32(30, 144, 255)
  7429. End Function ' cDodgerBlue~&
  7430.  
  7431. Function cSeaBlue~& ()
  7432.     cSeaBlue = _RGB32(0, 64, 255)
  7433. End Function ' cSeaBlue~&
  7434.  
  7435. Function cBlue~& ()
  7436.     cBlue = _RGB32(0, 0, 255)
  7437. End Function ' cBlue~&
  7438.  
  7439. Function cBluePurple~& ()
  7440.     cBluePurple = _RGB32(64, 0, 255)
  7441. End Function ' cBluePurple~&
  7442.  
  7443. Function cDeepPurple~& ()
  7444.     cDeepPurple = _RGB32(96, 0, 255)
  7445. End Function ' cDeepPurple~&
  7446.  
  7447. Function cPurple~& ()
  7448.     cPurple = _RGB32(128, 0, 255)
  7449. End Function ' cPurple~&
  7450.  
  7451. Function cPurpleRed~& ()
  7452.     cPurpleRed = _RGB32(128, 0, 192)
  7453. End Function ' cPurpleRed~&
  7454.  
  7455. Function cDarkRed~& ()
  7456.     cDarkRed = _RGB32(160, 0, 64)
  7457. End Function ' cDarkRed~&
  7458.  
  7459. Function cBrickRed~& ()
  7460.     cBrickRed = _RGB32(192, 0, 32)
  7461. End Function ' cBrickRed~&
  7462.  
  7463. Function cDarkGreen~& ()
  7464.     cDarkGreen = _RGB32(0, 100, 0)
  7465. End Function ' cDarkGreen~&
  7466.  
  7467. Function cGreen~& ()
  7468.     cGreen = _RGB32(0, 128, 0)
  7469. End Function ' cGreen~&
  7470.  
  7471. Function cOliveDrab~& ()
  7472.     cOliveDrab = _RGB32(107, 142, 35)
  7473. End Function ' cOliveDrab~&
  7474.  
  7475. Function cLightPink~& ()
  7476.     cLightPink = _RGB32(255, 182, 193)
  7477. End Function ' cLightPink~&
  7478.  
  7479. Function cHotPink~& ()
  7480.     cHotPink = _RGB32(255, 105, 180)
  7481. End Function ' cHotPink~&
  7482.  
  7483. Function cDeepPink~& ()
  7484.     cDeepPink = _RGB32(255, 20, 147)
  7485. End Function ' cDeepPink~&
  7486.  
  7487. Function cMagenta~& ()
  7488.     cMagenta = _RGB32(255, 0, 255)
  7489. End Function ' cMagenta~&
  7490.  
  7491. Function cBlack~& ()
  7492.     cBlack = _RGB32(0, 0, 0)
  7493. End Function ' cBlack~&
  7494.  
  7495. Function cDimGray~& ()
  7496.     cDimGray = _RGB32(105, 105, 105)
  7497. End Function ' cDimGray~&
  7498.  
  7499. Function cGray~& ()
  7500.     cGray = _RGB32(128, 128, 128)
  7501. End Function ' cGray~&
  7502.  
  7503. Function cDarkGray~& ()
  7504.     cDarkGray = _RGB32(169, 169, 169)
  7505. End Function ' cDarkGray~&
  7506.  
  7507. Function cSilver~& ()
  7508.     cSilver = _RGB32(192, 192, 192)
  7509. End Function ' cSilver~&
  7510.  
  7511. Function cLightGray~& ()
  7512.     cLightGray = _RGB32(211, 211, 211)
  7513. End Function ' cLightGray~&
  7514.  
  7515. Function cGainsboro~& ()
  7516.     cGainsboro = _RGB32(220, 220, 220)
  7517. End Function ' cGainsboro~&
  7518.  
  7519. Function cWhiteSmoke~& ()
  7520.     cWhiteSmoke = _RGB32(245, 245, 245)
  7521. End Function ' cWhiteSmoke~&
  7522.  
  7523. Function cWhite~& ()
  7524.     cWhite = _RGB32(255, 255, 255)
  7525.     'cWhite = _RGB32(254, 254, 254)
  7526. End Function ' cWhite~&
  7527.  
  7528. Function cDarkBrown~& ()
  7529.     cDarkBrown = _RGB32(128, 64, 0)
  7530. End Function ' cDarkBrown~&
  7531.  
  7532. Function cLightBrown~& ()
  7533.     cLightBrown = _RGB32(196, 96, 0)
  7534. End Function ' cLightBrown~&
  7535.  
  7536. Function cKhaki~& ()
  7537.     cKhaki = _RGB32(240, 230, 140)
  7538. End Function ' cKhaki~&
  7539.  
  7540. Function cEmpty~& ()
  7541.     'cEmpty~& = -1
  7542.     cEmpty = _RGB32(0, 0, 0, 0)
  7543. End Function ' cEmpty~&
  7544.  
  7545. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7546. ' END COLOR FUNCTIONS
  7547. ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7548.  
  7549. ' #END
  7550. ' ################################################################################################################################################################
  7551.  
« Last Edit: January 28, 2022, 04:06:02 pm by madscijr »