Confusing Chr$ explanation
#11
(07-07-2023, 01:52 AM)Space_Ghost Wrote: So....CHR$(a) was/is a string, but (a) was a SINGLE in your code so you need to convert it to a string so you can use PRINT at the same time for both (a) and CHR$(a).

I mean this sincerely, BASIC in general is one of the most powerful languages for string manipulations (along with Perl).

Here is the code
:
Here is the output to the console

It really depends which console, or it might be a thing only on Windows. I do this now on Spiral Linux KDE, which is based on Debian v11 (now the "old stable" release) and I get a bunch of question-diamonds, the character that it pulls out when one cannot be represented by the font the terminal is using. The Konsole has to be set to use IBM850 character set, or it won't work as explained.

For those of you who want to try this actually, open Konsole, then from the menu choose "View/Set Encoding/Western European/IBM850". Do not clear the screen nor scrollback or it gets reset to Unicode UTF-8. Probably a profile could be created with the encoding but this has been a PITA because sometimes it ignores the request or it messes up when the user wishes for it to become the default profile, and KDE is taking a long time to fix it.

At other times the Windows-1258 set is chosen such as Notepad++ on Windows, in which CHR$(255) is the lowercase "Y" with dieresis on top of it.

I don't care about Perl but I do know Lua, which also has powerful string manipulations and garbage collection like BASIC does. In addition it has tables which I deeply wish a free dialect of BASIC possessed. I was supposed to look into creating a virtual machine for Lua so a QB64 program could take advantage of Lua regular expressions and associative arrays. Smile
Reply
#12
A simple ASCII Table.
ESC - End Program
Arrow keys to select the character

Code: (Select All)
' instructs the compiler to require variable declaration
OPTION _EXPLICIT

' Control function off to set all characters
_CONTROLCHR OFF

' dimension variables
DIM winX AS _UNSIGNED INTEGER
DIM winY AS _UNSIGNED INTEGER
DIM i AS _UNSIGNED _BYTE
DIM x AS _UNSIGNED _BYTE
DIM y AS _UNSIGNED _BYTE
DIM selx AS _UNSIGNED _BYTE
DIM sely AS _UNSIGNED _BYTE
DIM keyin AS STRING

' Create window area with colors
COLOR 4, 7
winX = 14
winY = 4
FOR y = winY + 0 TO winY + 16
  FOR x = winX + 0 TO winX + 16 * 3
    LOCATE y, x: PRINT SPACE$(2);
  NEXT x
NEXT y

' Create table info
FOR i = 0 TO 15
  LOCATE winY, winX + (i * 3) + 3: PRINT "0" + HEX$(i);
  LOCATE winY + i + 1, winX: PRINT HEX$(i) + "0";
NEXT i

' Create ASCII characters
' Init values for the table of ASCII chars
COLOR 0, 7
winX = winX + 1
winY = winY + 1

DO
  ' Output of all ASCII characters in the table
  x = 0
  y = winY
  FOR i = 0 TO 255
    IF selx = x AND sely = y - winY THEN COLOR 7, 2 ELSE COLOR 0, 7
    LOCATE y, winX + (x * 3) + 3: PRINT CHR$(i);
    x = x + 1
    IF x = 16 THEN
      x = 0
      y = y + 1
    END IF
  NEXT i

  ' Output of decimal and hex value of current char
  COLOR 0, 7
  LOCATE winY + 16, winX - 1: PRINT SPACE$(25);
  LOCATE winY + 16, winX - 1: PRINT "ASCII:  DEC(" + LTRIM$(STR$(sely * 16 + selx)) + ")  HEX(" + HEX$(sely * 16 + selx) + ")";

  ' Key Input
  DO
    keyin = INKEY$
  LOOP WHILE keyin = ""

  ' Arrow keys to select the current char
  IF keyin = CHR$(0) + CHR$(77) THEN IF selx >= 15 THEN selx = 0 ELSE selx = selx + 1
  IF keyin = CHR$(0) + CHR$(75) THEN IF selx <= 0 THEN selx = 15 ELSE selx = selx - 1
  IF keyin = CHR$(0) + CHR$(80) THEN IF sely >= 15 THEN sely = 0 ELSE sely = sely + 1
  IF keyin = CHR$(0) + CHR$(72) THEN IF sely <= 0 THEN sely = 15 ELSE sely = sely - 1

  ' ESC to end the program
LOOP WHILE keyin <> CHR$(27)
Reply
#13
You guys know there is a very handy Chart in IDE Under Tools Menu item:
   

But where the heck is that blue ink coming from in my screenshot??? The closest I use that color is for comments.
b = b + ...
Reply
#14
Roger that....I posted that in this thread (post #6) and mentioned it.  This confirms that the encoding during the "wild west period" which BASIC was alive well during, was a crap shoot as far as the platform/OS/program specific character mappings.  I resisted getting into this detail, but here are the issues one must "work through on their own" to learn this mess.
  • Chars vs. Bytes vs. u8's
  • ASC II vs. Extended ASC II
  • ANSI, IBM, etc.
  • Unicode (a messy savior)
  • Strings (a relative term)
  • Code point
  • Code unit UTF-16 (65,536 combos)
  • Surrogate pairs (ugh!)
  • Runes (yeah!...almost)
  • Regional indicator symbols (for flags, etc.)
  • Zero Width Joiner (ZWJ)
  • User-perceived character, aka Unicode extended grapheme cluster, aka Grapheme cluster

There is one saving grace.  One of the newest, and yet fully mature, languages, Dart, has in my humble opinion, one of the best sets of Documentation I have seen. Dart does a respectable job of explaining all this, and more importantly seamlessly deals with all the bullet items above - inherently.  Dart 3 is a masterpiece of language design and one can understand a lot about historic and modern programming from studying it.  BASIC is my first love (had a fling with PASCAL and FORTRAN), but I have learned more from digging deep into 'C' (not C++, that took me backwards with templates, etc.) and Dart than any other language except for BASIC.  On the BASIC side QB64 and Power Basic (and Pure Basic nearly so) have just outstanding Wiki/Help support.
Reply
#15
Here the QB4.5 equivalent of the QB64 code. (https://staging.qb64phoenix.com/showthre...6#pid17636)

This code is faster in DOS. Not in QB64.
In the DOS BOX is this code very fast.

Because the segment is not part of the native operating system in Windows 10 / 11.
Under Windows 10 / 11 is the QB64 code faster
Both examples are intended to show how characters and colors can be displayed at a specific position. And the interaction with the table itself should also be demonstrated in this way.

Both examples are intended for practice purposes.
And not to say that it already exists.  Rolleyes

Code: (Select All)
' Segment B800 is for text memory
' 1 Byte Char + 1 Byte Color (4 Bit Back- and 4 Bit Foreground)
DEF SEG = &HB800

' Screen Info for Screen 0
' max line  = 25
' max length = 80
' max colors = 16
' Screen Buffer =  25 * 80 = 2000
' + with colors = 2000 * 2 = 4000
DIM screenchar(1999) AS INTEGER
DIM screencol(1999) AS INTEGER

' dimension variables
DIM winx AS INTEGER
DIM winy AS INTEGER
DIM x AS INTEGER
DIM y AS INTEGER
DIM posi AS INTEGER
DIM keyin AS STRING

' Create window area with colors
winx = 14
winy = 4
FOR y = winy + 0 TO winy + 16
  FOR x = winx + 0 TO winx + 16 * 3
    screenchar(y * 80 + x) = &H20
    screencol(y * 80 + x) = &H70
  NEXT x
NEXT y

' Create table info
FOR i = 0 TO 15
  screenchar(winy * 80 + winx + (i * 3) + 2) = &H30
  screenchar(winy * 80 + winx + (i * 3) + 3) = ASC(HEX$(i))
  screencol(winy * 80 + winx + (i * 3) + 2) = &H74
  screencol(winy * 80 + winx + (i * 3) + 3) = &H74

  screenchar((winy + i + 1) * 80 + winx + 1) = &H30
  screenchar((winy + i + 1) * 80 + winx) = ASC(HEX$(i))
  screencol((winy + i + 1) * 80 + winx + 0) = &H74
  screencol((winy + i + 1) * 80 + winx + 1) = &H74
NEXT i

' Create ASCII characters
winx = winx + 1
winy = winy + 1
x = 0
y = winy
FOR i = 0 TO 255
  screenchar(y * 80 + (winx + (x * 3 + 2))) = i
  screencol(y * 80 + (winx + (x * 3 + 2))) = &H70
  x = x + 1
  IF x = 16 THEN
    x = 0
    y = y + 1
  END IF
NEXT i

' Draw all ASCII Chars in the table
FOR i = 0 TO 3999 STEP 2
  POKE i + 0, screenchar(i \ 2)
  POKE i + 1, screencol(i \ 2)
NEXT i

' Start of selectet character
posi = (winy + sely) * 80 + (winx + selx * 3)
screencol(posi) = &H27
POKE ((posi + 2) * 2) + 1, screencol(posi)

DO
  ' Color change by new position
  IF posi <> ((winy + sely) * 80 + (winx + selx * 3)) THEN
    ' Old position reset
    screencol(posi) = &H70
    POKE ((posi + 2) * 2) + 1, screencol(posi)

    ' New position set
    posi = (winy + sely) * 80 + (winx + selx * 3)
    screencol(posi) = &H27
    POKE ((posi + 2) * 2) + 1, screencol(posi)
  END IF
 
  ' Output of decimal and hex value of current char
  COLOR 0, 7
  LOCATE winy + 17, winx: PRINT SPACE$(25)
  LOCATE winy + 17, winx: PRINT "ASCII: DEC(" + LTRIM$(STR$(sely * 16 + selx)) + ") HEX(" + HEX$(sely * 16 + selx) + ")"

  ' Key Input
  DO
    keyin = INKEY$
  LOOP WHILE keyin = ""

  ' Arrow keys to select the current char
  IF keyin = CHR$(0) + CHR$(77) THEN IF selx >= 15 THEN selx = 0 ELSE selx = selx + 1
  IF keyin = CHR$(0) + CHR$(75) THEN IF selx <= 0 THEN selx = 15 ELSE selx = selx - 1
  IF keyin = CHR$(0) + CHR$(80) THEN IF sely >= 15 THEN sely = 0 ELSE sely = sely + 1
  IF keyin = CHR$(0) + CHR$(72) THEN IF sely <= 0 THEN sely = 15 ELSE sely = sely - 1

  ' ESC to end the program
LOOP WHILE keyin <> CHR$(27)
Reply
#16
(07-07-2023, 01:18 AM)PhilOfPerth Wrote: From the WIKI:        the CHR$ function returns the character associated with a certain character code as a STRING
                 and:        Valid ASCII code% numbers range from 0 to 255

So why does this not work:

For a = 129 To 255
Print a; Chr$(a)
Sleep 1: Cls: Next 

    Huh

Hi PhilOfPerth
after all these excellent answers to your question 
I add  my two cents about your code posted:

Code: (Select All)
For a = 129 To 255
    Print a; Chr$(a)
   Sleep 1: Cls:Next  '<--- here there is  your bug
' you wait 1 second or a keypress event and then clearscreen and then you make another cycle od Next loop
' so you get only one row of output for each second... 126 seconds to wait watching each second one character and when
' the program ends you see nothing because the last instruction is CLS
your same code without an unuseful pause (sleep 1) and an unuseful clearscreen (CLS) plus a better output settings (;" "Wink for PRINT statement you get this output


[Image: immagine-2023-07-08-232515349.png]

I must remember that some ASCII code are not printable but you can use ControlCHR to print 
ControlCHR wiki
That's all.

Thanks,  I am glad to see so professional posts.
Reply
#17
(07-08-2023, 09:30 PM)TempodiBasic Wrote: your same code without an unuseful pause (sleep 1) and an unuseful clearscreen (CLS) plus a better output settings (;" "Wink for PRINT statement you get this output

I was going to point that out earlier but perhaps Phil wanted to see each character alone. A better idea was to switch to a graphics screen and find a way to cause a character to dominate the screen, by printing it much larger.

Code: (Select All)

DIM AS LONG thiscr, charscr
DIM AS INTEGER wx, hy, tx, ty, scale, i, j
wx = 8
hy = 14
tx = 100
ty = 100
scale = 10

SCREEN 12
thiscr = _COPYIMAGE(0)
SCREEN thiscr
_TITLE "Press [ESC] to quit."
charscr = _NEWIMAGE(wx, hy, 12)
COLOR 15
FOR i = 129 TO 255
_DEST charscr
LOCATE 1, 1
PRINT CHR$(i);
_PUTIMAGE (tx, ty)-(tx + wx * scale - 1, ty + hy * scale - 1), charscr, thiscr, (0, 0)-(wx - 1, hy - 1)
FOR j = 1 TO 10
_DELAY 0.1
IF _KEYDOWN(27) THEN EXIT FOR
NEXT
CLS
IF _KEYDOWN(27) THEN EXIT FOR
NEXT
_DEST 0
SYSTEM
Reply
#18
(07-08-2023, 10:44 PM)mnrvovrfc Wrote:
(07-08-2023, 09:30 PM)TempodiBasic Wrote: your same code without an unuseful pause (sleep 1) and an unuseful clearscreen (CLS) plus a better output settings (;" "Wink for PRINT statement you get this output

I was going to point that out earlier but perhaps Phil wanted to see each character alone. A better idea was to switch to a graphics screen and find a way to cause a character to dominate the screen, by printing it much larger.

Code: (Select All)

DIM AS LONG thiscr, charscr
DIM AS INTEGER wx, hy, tx, ty, scale, i, j
wx = 8
hy = 14
tx = 100
ty = 100
scale = 10

SCREEN 12
thiscr = _COPYIMAGE(0)
SCREEN thiscr
_TITLE "Press [ESC] to quit."
charscr = _NEWIMAGE(wx, hy, 12)
COLOR 15
FOR i = 129 TO 255
    _DEST charscr
    LOCATE 1, 1
    PRINT CHR$(i);
    _PUTIMAGE (tx, ty)-(tx + wx * scale - 1, ty + hy * scale - 1), charscr, thiscr, (0, 0)-(wx - 1, hy - 1)
    FOR j = 1 TO 10
        _DELAY 0.1
        IF _KEYDOWN(27) THEN EXIT FOR
    NEXT
    CLS
    IF _KEYDOWN(27) THEN EXIT FOR
NEXT
_DEST 0
SYSTEM

Thanks Minerva, yes, that was why I had the Sleep and Cls in there. I had intended to tell TB this, but you beat me to it. 
There was an error in my original code that stopped it working, but I had precis-ed it for my question. It worked as intended when that was fixed.
I had also formatted the print for better display, but your larger characters  method was a good way to see the characters more clearly.
Thanks both.
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#19
I'm able to see characters for all the Alt values, but I'm unable to produce the Copyright (and some others). The Alt table says it should be Alt 0169,
but Alt + 0169 only produces the ┌ symbol (or something very similar).
When I enter  Alt + 0169  here, on the Forum, I get the © ok. Why not in my program?
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#20
(07-09-2023, 04:22 AM)PhilOfPerth Wrote: I'm able to see characters for all the Alt values, but I'm unable to produce the Copyright (and some others). The Alt table says it should be Alt 0169,
but Alt + 0169 only produces the ┌ symbol (or something very similar).
When I enter  Alt + 0169  here, on the Forum, I get the © ok. Why not in my program?
Hi PhilOfPerth,

If you are running windows test this for good measure:
  1. Here's how to enter ascii characters in the Windows PC
  2. Put your keyboard in number pad mode 
  3. Then hold down Alt key and type the ascii code
  4. Then let go of the Alt Key
  5. Alt +   169: ⌐
  6. Alt + 0169: ©

If you are on Linux or Mac OS I am not sure of the implications.

When I try to PRINT CHR$(0169) in the QB64pe IDE it removes the leading zero and prints ⌐

I also saved the code as a .bas file with notepad++; and compiled and run from the command line (without the IDE), it also prints out ⌐ and not ©.

My guess is the ALT codes with leading zeros are not part of the QB64pe compilation options.....but someone with much more knowledge can chime in to confirm or not.

Cheers.
Reply




Users browsing this thread: 12 Guest(s)