Posts: 50
Threads: 12
Joined: Nov 2023
Reputation:
3
10-05-2025, 12:25 AM
(This post was last modified: 10-05-2025, 12:26 AM by pmackay.)
Code: (Select All) Sub DisplayMapASCII2
Dim rowIndex As Integer, colIndex As Integer
Dim tileChar As String
_ControlChr Off
Screen 0
Width 80, 25
Cls
Print "Map "; CurrentMap
For rowIndex = 1 To MAP_HEIGHT
For colIndex = 1 To MAP_WIDTH
tileChar = Mid$(MapLines(rowIndex), colIndex, 1) ' Access directly
' Set color based on tile type
Select Case tileChar
Case "W" ' SteelWall
Color 4
tileChar = Chr$(219)
Case "w" ' BrickWall
Color 4
tileChar = Chr$(178)
Case "." ' Dirt
Color 6
tileChar = Chr$(176)
Case "R", "r" ' Rock
Color 7
tileChar = Chr$(9)
Case "D", "d" ' Diamond
Color 11
tileChar = Chr$(4)
Case "P" ' Exit Map
Color 10
tileChar = Chr$(10)
Case "X" ' Player
Color 15
tileChar = Chr$(2)
Case "B", "q"
Color 14
Case Else ' Empty / unknown
Color 0
End Select
Print tileChar;
Next colIndex
Print
Next rowIndex
Print "Press any key to continue..."
Do While InKey$ = ""
_Limit 30
Loop
End Sub
hey.. i am creating my displayascii.lnk file and when using '$include: 'displayascii.lnk' my file says 1st Function Argument requires a string on 14... I have DIM SHARED MapLines(1 To MAP_HEIGHT) As String IN MAINProgram and I cannot clear this error... if i put the Sub in my MAIN code the error Clears and all good. But i want this in a Include file to make it easy for me to change by swapping subs (a graphics routine instead of ascii by just swapping files rather then code in main.. Is this a Bug in the IDE that can be fixed, or have I done something I have not learnt yet. I want to Add if I just use Print MapLines(rowIndex) in the file the error is gone, but i cannot use color. so it must be recognizing the string with print but invalide to read the string with mid$ ??? thank you
Code: (Select All) Sub DisplayMapASCII
Dim rowIndex As Integer
Screen 0
Width 80, 25
Cls ' Clear screen for clean output
For rowIndex = 1 To MAP_HEIGHT
Print MapLines(rowIndex)
Next rowIndex
Print "Press any key to continue..."
Do While InKey$ = ""
_Limit 30 ' Limit CPU usage
Loop
End Sub
this code is good to go in the same file.. no error. the above is what i want but mid$ error stops me
Posts: 4,695
Threads: 222
Joined: Apr 2022
Reputation:
322
10-05-2025, 12:44 AM
(This post was last modified: 10-05-2025, 12:50 AM by bplus.)
Why not make a BI file to Dim Shared the String in there?
PS include .BI files at start of main and .BM or whatever you want to call them, the ones with sub and function routines below the end of main code, usu after all main code subs and functions.
Also what i call .BI is one that does UDT definitions, constants and yes, even Shared Variables! (Doesn't have to be called .BI the last I heard.)
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
DIM SHARED MapLines(whatever_number) AS STRING
Is your maplines shared? The issue might be reading it as a number and not a string, as per the bug report for MID$.
First function argument requires a string.
It isn't seeing MapLines() as a String.
Posts: 4,695
Threads: 222
Joined: Apr 2022
Reputation:
322
10-05-2025, 01:47 AM
(This post was last modified: 10-05-2025, 01:50 AM by bplus.)
Because he didn't include it in a BI file because the Sub is in an Included file, is what I am thinking.
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 50
Threads: 12
Joined: Nov 2023
Reputation:
3
PHP Code: ' ---------- Map Setup
Dim Shared MapRom(30, 1 To MAP_HEIGHT) As String Dim Shared CurrentMap
'$Include: 'Maps.lnk'
' ---------- Load Map Number
Dim Shared MapLines(1 To MAP_HEIGHT) As String
CurrentMap = 5
CopyMapFromRom
If TestPattern = 2 Then DisplayMapASCII End End If
this is in the Main Program Area, I use a '$include: 'filename.lnk' (I call it Link as It hooks inside the rest...)
Posts: 50
Threads: 12
Joined: Nov 2023
Reputation:
3
Code: (Select All) '---------- Characters Config
Const HumanPlay = "X"
Const LevelExit = "P"
Const SteelWall = "W"
Const BrickWall = "w"
Const MajicWall = "m"
Const MagicWall = "M"
Const DirtyTile = "."
Const EmptyTile = " "
Const Butterfly = "B"
Const Boxxerfly = "q"
Const Explodebt = "!"
Const explodebx = "@"
Const HumanEdie = "#"
'---------- Config Variables
Const TILEW = 16
Const TILEH = 16
Const SHEETCOLS = 8 ' adjust for your sprite sheet
Const SHEETROWS = 12
Const TILECOUNT = SHEETCOLS * SHEETROWS
Const MAP_WIDTH = 40
Const MAP_HEIGHT = 22
Const TOTAL_MAPS = 30
' ---------- Sprite Setup
Dim Shared SpriteTable
Dim Shared Sheet&
Dim Shared sprite&(0 To TILECOUNT - 1)
TestPattern = 2
SpriteTable = 3
LoadSpriteTable
Screen _NewImage(320, 224, 32)
$Resize:Smooth
Cls
If TestPattern = 1 Then
'$Include: 'TestScreenSprites.lnk'
_MouseMove 20, 40 'center mouse pointer on screen
End
End If
' ---------- Map Setup
Dim Shared MapRom(30, 1 To MAP_HEIGHT) As String
Dim Shared CurrentMap
'$Include: 'Maps.lnk'
' ---------- Load Map Number
Dim Shared MapLines(1 To MAP_HEIGHT) As String
CurrentMap = 5
CopyMapFromRom
If TestPattern = 2 Then
DisplayMapASCII
End
End If
this is the startup.. its set Dim MapLines(1 To MAP_HEIGHT) As String. It works if I just have the sub in the main but when its in the file it says it is trying to convert string from a number. but print will print as string and its correctly printed. mid$ says it cannot convert number.i am wanting to strip it to give chars colors. but i then dont understand how it can print a string thats 40 characters long but thinks it is a number at the same time.
Posts: 50
Threads: 12
Joined: Nov 2023
Reputation:
3
![[Image: error.png]](https://i.ibb.co/gMxS3WvF/error.png)
I have moved all my stuff like bplus has suggested, Still no fix... its a string in main, its a string in subs if printed, but its a numeric if using mid$... crashes out with error..
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
Your screen shots are of two different programs. Those programs aren't tied together in any way.
The second program has no DIM statement making the variable a STRING.
Try this
Code: (Select All)
PRINT "Hello"
Now try this:
Code: (Select All)
PRINT "World"
Did you get a single screen with "Hello World"?
Of course not! Those programs aren't tied together in any way and they're completely separate things.
But save the first one as "test.bas":
Code: (Select All)
PRINT "Hello"
And now for the second one, make it:
Code: (Select All)
$INCLUDE:'test.bas'
PRINT "World"
Run the first one, and again you just get "Hello". There's no command in it linking anything else into it.
Run the second one, however, and it will print "Hello World". The first program is linked into it with the $INCLUDE statement.
That's what you're seeing.
You're writing a DIM statement in one program.
Trying to use that same variable in a completely different, unrelated program. It's not DIMmed there, so it defaults to a SINGLE variable type.
Posts: 3,446
Threads: 376
Joined: Apr 2022
Reputation:
345
(10-05-2025, 04:21 AM)pmackay Wrote: PHP Code: ' ---------- Map Setup
Dim Shared MapRom(30, 1 To MAP_HEIGHT) As String Dim Shared CurrentMap
'$Include: 'Maps.lnk'
' ---------- Load Map Number
Dim Shared MapLines(1 To MAP_HEIGHT) As String
CurrentMap = 5
CopyMapFromRom
If TestPattern = 2 Then DisplayMapASCII End End If
this is in the Main Program Area, I use a '$include: 'filename.lnk' (I call it Link as It hooks inside the rest...)
The problem here is ORDER.
You basically have code like this:
Code: (Select All)
'$Include: 'Maps.lnk'
' ---------- Load Map Number
Dim Shared MapLines(1 To MAP_HEIGHT) As String
But break that down to how it processes, it's basically:
Code: (Select All)
PRINT Mid$(MapLines(foo),1,1)
DIM SHARED MapLines(1 to MAP_HEIGHT) AS STRING
You're trying to use a variable as a string BEFORE you've dimmed it as a string. Move that DIM statement up in your code, before the $INCLUDE statement, and see that error disappear.
Remember, the following is perfectly valid QBASIC code:
Code: (Select All)
x = 1
x$ = "foo"
PRINT x
PRINT x$
Before you have a DIM statement defining the variable in a program, it's going to be a default type of a SINGLE.
Posts: 50
Threads: 12
Joined: Nov 2023
Reputation:
3
this is a snippet, i have moved heaps about. i can get it to run in main sub no problem. but not in the other...
Code: (Select All) ' ---------- Varable Tables Start Here
Const Diamond_Ti = "d"
Const Diamond_Td = "D"
Const Rock_Fallt = "R"
Const Rock_Stati = "r"
Const HumanPlay = "X"
Const LevelExit = "P"
Const SteelWall = "W"
Const BrickWall = "w"
Const MajicWall = "m"
Const MagicWall = "M"
Const DirtyTile = "."
Const EmptyTile = " "
Const Butterfly = "B"
Const Boxxerfly = "q"
Const Explodebt = "!"
Const explodebx = "@"
Const HumanEdie = "#"
Const Levelopen = "z"
' ---------- Screen Size Settings and Sprites Setups
Const TILEW = 16 ' Tile Width
Const TILEH = 16 ' Tile Height
Const SHEETCOLS = 8 ' Sprite Counter X 8 sprites x 12 sprites on sheet
Const SHEETROWS = 12 ' Sprite Counter Y
Const TILECOUNT = SHEETCOLS * SHEETROWS
Const MAP_WIDTH = 40 ' Map Width
Const MAP_HEIGHT = 22 ' Map Height
Const TOTAL_MAPS = 30 ' Total Maps To load into Ram
' ---------- Dimension Arays Shared Vars
Dim Shared SpriteTable As Integer
Dim Shared Sheet As Long
Dim Shared sprite(0 To TILECOUNT - 1) As Long
Dim Shared TestPattern As Integer
Dim Shared MapRom(30, 1 To MAP_HEIGHT) As String
Dim Shared CurrentMap As Integer
Dim Shared MapLines(1 To MAP_HEIGHT) As String
Dim Shared MapComplete As Integer
Dim Shared DiamondFrameCounter As Single
Dim Shared DiamondAnimationSpeed As Single
Dim Shared DiamondCount As Integer
Dim Shared KeyBoardRepeat As Integer
Dim Shared SUBtileChar As String
Dim Shared PlayerX As Integer
Dim Shared PlayerY As Integer
' ---------- Startup Values
TestPattern = 0
SpriteTable = 3
CurrentMap = 5
DiamondAnimationSpeed = 0.05
KeyBoardRepeat = 0.05
MapComplete = 0
DiamondCount = 0
' ---------- Set Screen Mode
Screen _NewImage(320, 224, 32)
$Resize:Smooth
' Test Sprite Sheet
' -----------------------------
' Cross-hatch grid (MAME style)
' -----------------------------
For x = 0 To 320 Step 16
Line (x, 0)-(x, 223), _RGB(80, 80, 80)
Next
For y = 0 To 224 Step 16
Line (0, y)-(319, y), _RGB(80, 80, 80)
Next
' -----------------------------
' Draw all sprites in a grid
' -----------------------------
col = 0
row = 0
For i = 0 To TILECOUNT - 1
_PutImage (col * TILEW, row * TILEH), sprite&(i)
col = col + 1
If col >= 20 Then ' 320 / 16 = 20 tiles across
col = 0
row = row + 1
End If
Next
Dim clr&(5)
clr&(0) = _RGB(255, 0, 0)
clr&(1) = _RGB(0, 255, 0)
clr&(2) = _RGB(0, 0, 255)
clr&(3) = _RGB(255, 255, 255)
clr&(4) = _RGB(128, 128, 128)
clr&(5) = _RGB(0, 0, 0)
For i = 0 To 5
Line (i * 53, 188)-(i * 53 + 52, 223), clr&(i), BF
Next
' -----------------------------
' Corner labels
' -----------------------------
_PrintString (8, 8), "TOP LEFT"
_PrintString (240, 8), "TOP RIGHT"
_PrintString (8, 208), "BOTTOM LEFT"
_PrintString (216, 208), "BOTTOM RIGHT"
' -----------------------------
' Optional color bars (bottom row)
' -----------------------------
Do
_Limit 7
Loop While InKey$ <> " "
'---------- Timers For Player Field
DiamondTicker:
DiamondFrameCounter = (DiamondFrameCounter + 1) Mod 8
Return
' ==============================================
' Copies the current map from ROM to RAM
' ==============================================
Sub CopyMapFromRom
Dim rowIndex As Integer
' Copy the selected map from ROM into the working array
For rowIndex = 1 To MAP_HEIGHT
MapLines(rowIndex) = MapRom(CurrentMap, rowIndex)
Next rowIndex
End Sub
' ---------------- find player start, count diamonds
Sub DisplayMapASCII
Dim rowIndex As Integer
Screen 0
Width 80, 25
Cls ' Clear screen for clean output
For rowIndex = 1 To MAP_HEIGHT
Print MapLines(rowIndex)
Next rowIndex
Print "Press any key to continue..."
Do While InKey$ = ""
_Limit 30 ' Limit CPU usage
Loop
End Sub
Sub LoadSpriteTable
Dim tileIndex As Integer, row As Integer, col As Integer, x As Integer, y As Integer
' Free previous sheet if needed
If Sheet& <> 0 Then _FreeImage Sheet&
' === Load the sprite sheet based on SpriteTable ===
Select Case SpriteTable
Case 1 To 20
Sheet& = _LoadImage("l0_sprite_" + Right$("00" + LTrim$(Str$(SpriteTable)), 2) + ".png", 32)
Case Else
Print "Invalid SpriteTable number: "; SpriteTable
End
End Select
If Sheet& = -1 Then
Print "Error loading sprite sheet l0_sprite_"; Right$("00" + LTrim$(Str$(SpriteTable)), 2); ".png"
End
End If
' === Cut into individual sprites ===
tileIndex = 0
For row = 0 To SHEETROWS - 1
For col = 0 To SHEETCOLS - 1
x = col * TILEW
y = row * TILEH
' Free old tile if it exists
If sprite&(tileIndex) <> 0 Then _FreeImage sprite&(tileIndex)
' Insert New Sprites
sprite&(tileIndex) = _NewImage(TILEW, TILEH, 32)
_PutImage (0, 0)-(TILEW - 1, TILEH - 1), Sheet&, sprite&(tileIndex), (x, y)-(x + TILEW - 1, y + TILEH - 1)
tileIndex = tileIndex + 1
Next
Next
_FreeImage Sheet&
End Sub
'$Include: 'RamTable.bi'
SpriteTable = 3 ' Sprite Table / Color Map
LoadSpriteTable
Cls
TestPattern = 0
If TestPattern = 1 Then
'$Include: 'TestScreenSprites.lnk'
_MouseMove 20, 40 'center mouse pointer on screen
End
End If
'$Include: 'Maps.lnk'
' ---------- Load Map Number
CurrentMap = 5
CopyMapFromRom
If TestPattern = 2 Then
DisplayMapASCII
End
End If
' ---------- Timers
DiamondFrameCounter = _FreeTimer
On Timer(DiamondFrameCounter, DiamondAnimationSpeed) GoSub DiamondTicker
KeyBoardRepeat = _FreeTimer
On Timer(KeyBoardRepeat, KeyBoardRepeat) GoSub KeyBoardRoutine ' ticks turn on/off to synce as needed
_FullScreen
' ---------- Draw Screen
Timer(DiamondFrameCounter) On
For i = 1 To 300
DisplayMapGraphics
_Limit 30
Next i
Timer(KeyBoardRepeat) On
Do
DisplayMapGraphics
_Limit 30
GoSub KeyBoardRoutine:
Loop While InKey$ <> " "
'Timer(DiamondFrameCounter) Off
End
' ---------- KeyBoard Routine for movement
KeyBoardRoutine:
SHFT% = _KeyDown(100303) Or _KeyDown(100304)
QUIT% = _KeyDown(27)
KeyBoardUP% = _KeyDown(18432)
KeyBoardDN% = _KeyDown(20480)
KeyBoardLT% = _KeyDown(19200)
KeyBoardRT% = _KeyDown(19712)
If KeyBoardUP% = -1 Then
End If
If KeyBoardDN% = -1 Then
End If
If KeyBoardLT% = -1 Then
End If
If KeyBoardRT% = -1 Then
End If
Return
' ---------- All Sub Routines from Here.. Subs before Functions
''$Include: 'ConfigureMap.lnk'
'$Include: 'TimerCounter.lnk'
'$Include: 'LoadMapFromRom.lnk'
'$Include: 'DisplayMapAsAscii.lnk'
'$Include: 'Sprites.lnk'
' ---------- Display Screen Graphics
Sub DisplayMapGraphics
Dim camX As Integer, camY As Integer ' Player/camera position in tiles
Dim startCol As Integer, startRow As Integer
Dim endCol As Integer, endRow As Integer
Dim drawX As Integer, drawY As Integer
Dim rowIndex As Integer, colIndex As Integer
Dim tileChar As String
Dim spriteIndex As Integer
' -----------------------------
' Window size in tiles
' -----------------------------
Const WINDOW_WIDTH = 40
Const WINDOW_HEIGHT = 22
' -----------------------------
' Find player position in map
' -----------------------------
For rowIndex = 1 To MAP_HEIGHT
For colIndex = 1 To MAP_WIDTH
If Mid$(MapLines(rowIndex), colIndex, 1) = HumanPlay Then
camX = colIndex
camY = rowIndex
Exit For
End If
Next colIndex
Next rowIndex
' -----------------------------
' Determine visible window bounds
' -----------------------------
startCol = camX - (WINDOW_WIDTH \ 2)
startRow = camY - (WINDOW_HEIGHT \ 2)
endCol = startCol + WINDOW_WIDTH - 1
endRow = startRow + WINDOW_HEIGHT - 1
' Clamp to map edges
If startCol < 1 Then startCol = 1
If startRow < 1 Then startRow = 1
If endCol > MAP_WIDTH Then
endCol = MAP_WIDTH
startCol = endCol - WINDOW_WIDTH + 1
If startCol < 1 Then startCol = 1
End If
If endRow > MAP_HEIGHT Then
endRow = MAP_HEIGHT
startRow = endRow - WINDOW_HEIGHT + 1
If startRow < 1 Then startRow = 1
End If
' -----------------------------
' Draw visible map
' -----------------------------
For rowIndex = startRow To endRow
For colIndex = startCol To endCol
tileChar = Mid$(MapLines(rowIndex), colIndex, 1)
' Map character to sprite index
Select Case tileChar
Case HumanPlay
spriteIndex = 0
Case LevelExit
' You could animate or alternate between 48 and 49
spriteIndex = 49
Case Boxxerfly
spriteIndex = 72 + DiamondFrameCounter
Case Butterfly
spriteIndex = 88 + DiamondFrameCounter
Case "d", "D"
spriteIndex = 80 + DiamondFrameCounter
Case "r"
spriteIndex = 56
Case "M"
spriteIndex = 51
Case "m"
spriteIndex = 51 + DiamondFrameCounter Mod 4
Case DirtyTile
spriteIndex = 57
'Case "!", "@"
' spriteIndex = 1 + ((colIndex + rowIndex) Mod 3) ' 1-3
Case SteelWall
spriteIndex = 49
Case BrickWall
spriteIndex = 4
Case Else
spriteIndex = 48 ' fallback
End Select
' Draw tile
drawX = (colIndex - startCol) * TILEW
drawY = (rowIndex - startRow) * TILEH
_PutImage (drawX, drawY), sprite&(spriteIndex)
Next colIndex
Next rowIndex
End Sub
' ---------------- find player start, count diamonds
Sub LookforPlayerStartPosition:
For rowIndex = 2 To 21 ' Y
For colIndex = 2 To 38 ' X
SUBtileChar = Mid$(MapLines(rowIndex), colIndex, 1)
If SUBtileChar = Diamond_Ti Then DiamondCount = DiamondCount + 1
If SUBtileChar = HumanPlay Then
PlayerY = rowIndex
PlayerX = colIndex
End If
Next colIndex
Next rowIndex
End Sub
|