QB-like ASCII table

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
counting_pine
Site Admin
Posts: 6157
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

QB-like ASCII table

Postby counting_pine » Sep 27, 2011 18:00

I've written a program to print the QB ASCII table in text/graphics modes. It wasn't quite as simple as I thought it would be:

Code: Select all

#define GFX
const CHAR_HEIGHT = 8 ' 8|14|16

data "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", "bs",  "tab", "lf"
data "vt",  "np",  "cr",  "so",  "si",  "dle", "dc1", "dc2", "dc3", "dc4", "nak"
data "syn", "etb", "can", "em",  "eof" ,"esc", "fs",  "gs",  "rs",  "us"

sub putstring(x as integer, y as integer, s as string, c as integer)
#ifdef GFX
    dim as integer h: screeninfo , h
    dim as integer rows = hiword(width())
    draw string (x*8, y*(h\rows)), s, c
#else
    for i as integer = 1 to len(s)
        if asc(s, i) < 32 then
            select case asc(s, i)
            case 7, 8
                c = 12
                mid(s, i, 1) = " "
            case 0, 9, 10, 13', 26
                c = 9
                mid(s, i, 1) = " "
            end select
        end if
    next i
    color c
    locate y+1, x+1
    print s;
#endif
end sub

dim as string altname(0 to 31)
for i as integer = 0 to 31
    read altname(i)
next i



#ifdef GFX
screenres 80*8, 35*CHAR_HEIGHT
windowtitle "8*" & CHAR_HEIGHT & " ASCII codes"
#endif
width 80, 35

for c as integer = 0 to 255
    dim as string s = right("00" & c, 3) & " "
    dim as integer x, y
    dim as integer i = c
   
    select case i
    case 0 to 31
        y = i mod 16
        x = (i \ 16) * 14
        select case altname(c)
        'case "nul", "tab", "lf", "cr", "eof"
        '    s &= "  (" & altname(c) & ")"
        'case "bel", "bs"
        '    s &= "  (" & altname(c) & ")"
        case else
            s &= chr(c) & " (" & altname(c) & ")"
        end select
       
       
    case 32 to 47
        i -= 32
        y = i mod 16
        x = 28 '14*2 + (i \ 16) * 9
        if c = 32 then
            s &= "sp"
        else
            s &= chr(c)
        end if
       
    case 48 to 127
        i -= 48
        y = i mod 16
        x = 14*2 + 1*9 + (i \ 16) * 8
        s &= chr(c)
   
    case 128 to 157 '128+15*2-1
        i -= 128
        y = i mod 15: y += 16 + 2
        x = 2 + (i \ 15) * 8
        s &= chr(c)
       
    case 158 to 255
        i -= 158
        y = i mod 14: y += 16 + 2
        x = 2 + 8*2 + (i \ 14) * 8
        s &= chr(c)
       
    end select
   
    putstring(x+3, y+1, s, 7)
   
next c
putstring(17, 0, "Regular ASCII Chart (character codes 0 - 127)", 15)
putstring(16, 1+16+1, "Extended ASCII Chart (character codes 128 - 255)", 15)

putstring(0, 1 + 16 + 2 + 15, "", 7)

sleep
Notes:
- The text mode can't print chr(7) or chr(8) (bell and backspace), instead either beeping or deleting. So instead of printing the char I change it to a space instead, and mark those entries as red.
- QB replaces some characters (0, 9, 10, 13, 26 - nul, tab, lf, cr, eof) with a space. I do the same in text mode (except for eof, which prints fine in FB) and mark them as blue.
- In gfx mode, I just "Draw String" all the characters, knowing it's not going to beep or do anything funny with the cursor. The result is pretty much the same as QB, except some characters have different glyphs (and eof is printed).
counting_pine
Site Admin
Posts: 6157
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » Sep 28, 2011 11:05

Screenshots:

QB
Image

FB console
Image

FB graphics mode 8*8
Image

FB graphics mode 8*14
Image

FB graphics mode 8*16
Image
Ryan
Posts: 695
Joined: Jun 10, 2005 2:13
Location: Louisville, KY
Contact:

Postby Ryan » Sep 28, 2011 13:28

Very handy! Many thanks. : )
TJF
Posts: 3443
Joined: Dec 06, 2009 22:27
Location: N47°, E15°

Postby TJF » Sep 28, 2011 13:44

The console output depends on the choosen character encoding. It will be different ie for UTF-8. Anywhere I red that some windows versions allow to adjust the character encoding for cmd.exe. On LINUX mostly UTF-8 is used.
counting_pine
Site Admin
Posts: 6157
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » Sep 29, 2011 12:33

Thanks. Yeah, that's worth mentioning. I'll also mention that my screenshots were taken in Windows XP on codepage 850.
If anyone wants to post a Linux screenshot, that might be helpful.
angros47
Posts: 1439
Joined: Jun 21, 2005 19:04

Postby angros47 » Sep 29, 2011 15:21

Here they are:

Image
Image
Image
Image

Ubuntu Natty Narwhal

In graphic mode, it works in the same way as windows. In text mode, it makes a mess.
angros47
Posts: 1439
Joined: Jun 21, 2005 19:04

Postby angros47 » Sep 29, 2011 15:29

I forget...
One in dosbox, too (text mode)
Image
counting_pine
Site Admin
Posts: 6157
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » Sep 29, 2011 15:45

Thanks. Yeah, the graphics ones should be exactly the same (obviously apart from window decorations, etc.)
The console result is interesting. I can't tell whether the unprintable characters are messing it up, but Width() and Locate() could be the main culprits. I don't know how that would work with the scrollable Linux consoles.

(How) does Width() affect the console size?
angros47
Posts: 1439
Joined: Jun 21, 2005 19:04

Postby angros47 » Sep 29, 2011 17:53

It doesn't (tried it now).

Linux doesn't allow applications to change the console size.


http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgWidth
counting_pine
Site Admin
Posts: 6157
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Postby counting_pine » Sep 29, 2011 18:40

Good thinking, checking the wiki :)

OK, so I guess Width does nothing, and Locate does funny stuff, probably involving scrolling (given the titles end up in the wrong place - perhaps they should have been printed first).

So at a guess, untested, I would say Locate with high values causes scrolling, and not updating the row position, or something?

EDIT: OK, it looks like a combination of:
- Width doesn't work (so Locate won't go over 25)
- Locate doesn't touch the cursor position if the row count is too high
- Successive unrelocated prints will can hit the edge of the screen on the bottom row (bearing in mind the last successful Locate would have been on the bottom row) and cause scrolling
- And, to a more minor extent but worth mentioning, some unprintable characters apparently have a different width.
Last edited by counting_pine on Sep 29, 2011 23:52, edited 1 time in total.
marcov
Posts: 2733
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Postby marcov » Sep 29, 2011 19:16

Console UTF-8 maybe? Then outputing high ascii has,euh, special effects :_)
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Postby MichaelW » Sep 29, 2011 23:20

Under Windows the problem is likely to be the console output mode. This code works correctly on my Windows 2000 system, but note that in my console properties the Font selection is “Raster Fonts” and the selected font is “8514oem” (and after years of diddling with it I have no idea what the default was):

Code: Select all

''=============================================================================
#include "windows.bi"
''=============================================================================

dim as HANDLE hStdOut
dim as integer mode, charsWritten
dim as string buffer

for i as integer = 0 to 31
    buffer &= chr(i)
next

''=============================================================================

hStdOut = GetStdHandle( STD_OUTPUT_HANDLE )

print GetConsoleMode( hStdOut, @mode )
if mode and ENABLE_PROCESSED_OUTPUT then print "ENABLE_PROCESSED_OUTPUT"
if mode and ENABLE_WRAP_AT_EOL_OUTPUT then print "ENABLE_WRAP_AT_EOL_OUTPUT"
print
print WriteConsole( hStdOut, strptr(buffer), 32, @charsWritten, 0 )
print
print SetConsoleMode( hStdOut, ENABLE_WRAP_AT_EOL_OUTPUT )
print GetConsoleMode( hStdOut, @mode )
if mode and ENABLE_PROCESSED_OUTPUT then print "ENABLE_PROCESSED_OUTPUT"
if mode and ENABLE_WRAP_AT_EOL_OUTPUT then print "ENABLE_WRAP_AT_EOL_OUTPUT"
print
print WriteConsole( hStdOut, strptr(buffer), 32, @charsWritten, 0 )
print

sleep

I doubt that this method could be used to adapt the FB output functions, because I’m fairly certain that FB depends on the ENABLE_PROCESSED_OUTPUT mode, but it could be the basis of an alternative output function for Windows.

See MSDN: Console Functions.
angros47
Posts: 1439
Joined: Jun 21, 2005 19:04

Postby angros47 » Oct 04, 2011 16:00

I've made another test: I compiled it with the Win32 version of freebasic, under Wine. Graphic mode is ok, while console mode is even more quirky:

Image

This happened using linux console as output for Wine.

If I tell Wine to emulate a windows console (the command is wineconsole), the result is better, but still not perfect:

Image

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest