Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 308
» Latest member: Donaldvem
» Forum threads: 1,741
» Forum posts: 17,901

Full Statistics

Latest Threads
The QB64 IDE shell
Forum: Utilities
Last Post: JasonPag
09-16-2024, 05:37 PM
» Replies: 9
» Views: 762
Importance regarding Ches...
Forum: Utilities
Last Post: JasonPag
09-01-2024, 06:34 PM
» Replies: 0
» Views: 31
Chess and Analysis and En...
Forum: Utilities
Last Post: JasonPag
08-28-2024, 02:37 PM
» Replies: 0
» Views: 32
DAY 009:_PutImage
Forum: Keyword of the Day!
Last Post: grymmjack
09-02-2023, 02:57 PM
» Replies: 54
» Views: 2,034
Fall Banner Contest?
Forum: Site Suggestions
Last Post: grymmjack
08-31-2023, 11:50 PM
» Replies: 36
» Views: 1,261
ColorPicker - Function th...
Forum: Dav
Last Post: Dav
08-31-2023, 11:04 PM
» Replies: 3
» Views: 315
Goals(1) = New Tile()
Forum: Works in Progress
Last Post: RhoSigma
08-31-2023, 09:45 PM
» Replies: 3
» Views: 127
micro(A)v11
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:14 PM
» Replies: 90
» Views: 3,589
Updating The Single Most ...
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:13 PM
» Replies: 7
» Views: 254
QBJS Image Question
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 05:49 PM
» Replies: 5
» Views: 155

 
  The Dungeon
Posted by: eoredson - 12-08-2022, 05:05 AM - Forum: Utilities - Replies (2)

The link to The Dungeon still remains at:

https://bit.ly/EriksDungeon

For Dngeon12.zip the following is:

   Note: Tasm 4.1 can be found on vetusware

   The Dungeon contains assembly to trap ctrl-break and can be removed from the source by deleting Call Setint/Call Restint.

   This program and source are completely 16-bit and won't load in QB64 because it contains arrays in UDTs..

For Dungeon_v12_QB64.zip it contains no assembly.

Attached is:

   Dngeon12.zip for VB10.

   Dungeon_v12_QB64.zip for QB64.

The readme.txt is:



Code: (Select All)
Program:

  Welcome to The Dungeon Adventure Game v12.0 r3.0. These files, documents,
  and  programs are public domain.  Anyone  may use, rewrite, or distribute
  them  without any fee, charge for use, or packaging requirements.

Files:

  Separate the .zip file with the PKWare utility into the directory:

    c:
    cd \
    md dngeon12
    cd \dngeon12
    copy \temp\dngeon12.zip \dngeon12

  with the command

    pkunzip dngeon12.zip

  The .zip file contains the files:

    ansi.bas    --  opening screen source
    ansi.exe    --  opening screen program
    compile.bat  --  compiling batch program
    compile.txt  --  compile instructions
    desc.sdi    --  program description
    dungeon.bas  --  main dungeon source
    dungeon.doc  --  short documentation
    dungeon.exe  --  main dungeon program
    edit.bas    --  edit utility source
    edit.exe    --  edit utility program
    file_id.diz  --  program description
    features.txt --  list of features
    go.bat      --  startup batch file
    help.bas    --  help menu source
    help.exe    --  help menu program
    keytrap.asm  --  assembly utility source
    list.bat    --  lists source to printer
    mapedit.bas  --  map edit utility source
    mapedit.exe  --  map edit utility program
    page.com    --  display utility
    print.bat    --  prints documentation
    program.txt  --  description of program
    readme.bat  --  displays readme file
    readme.txt  --  readme text file
    swapbas.asm  --  assembly utility source
    util.bas    --  display utility
    util.exe    --  display utility source

Dungeon creates the files:

    datafile.00x --  player data file
    players.dat  --  player data file
    ranklist.dat --  ranking list bulletin

Requirements:

  The  Dungeon is designed  to operate  on any  standard PC, XT, or AT with
  minimum of  256K memory,  a floppy or fixed disk,  and any color graphics
  adapter.




    The DUNGEON v12.0 r3.0 Documentation                          Page  i



Starting the game:

  Enter one of the following commands at the DOS prompt:

    go    -- read documentation and start the program
    print  -- print the documentation
    readme -- display the readme text file

Instructions:

  Playing  is done by  entry on the numeric keypad.  Keys 0, 1, .., 9,  and
  other  symbols  like -, +, and = are used for commands.  Be sure you have
  turned  on numlock before game play.  The Dungeon  also recognizes cursor
  keys for moving in the game without numlock.

Program compiling:

  This disk contains the compile batch files, BASIC source,  and additional
  utility for  the dungeon v12.0.  These files, documents, and programs are
  public domain.  Anyone may use, rewrite,  or distribute them  without any
  fee, charge for use, or packaging requirements.

Compiling requirements:

  The compile program  is designed to operate on any standard PC, XT, or AT
  with 512K, fixed disk, and any monitor.

Starting the compiler:

  Enter one of the following commands at the DOS prompt:

    compile  -- start the compiling process
    list    -- print the source

Compiling instructions:

  Compiling  is done by entering  the subprogram name to  create  with  the
  compile.bat  program.  You should have  the required compiler and library
  listed in the compile.txt file. Example to start: compile dungeon.  Also,
  the  dungeon comes with a makefile  containing instructions for nmake.exe
  to compile the dungeon programs by date of .exe files.

Maintenance release v12.0 r2.0 Fixed/added:

  Alt-Tab to add the globe of power to player inventory.
  Clearing monster array between changing dungeon levels.
  Dungeon level replenish to avoid placing items in rooms.
  Overflow error in info screen for levels greater than 50.
  More than eight monsters attacking player at once.
  Distance to monsters for evade/approach fixed.
  Count loops inside searching for empty dungeon cell.
  Timer beyond midnight pause loop corrected.
  Bulletin report utility display cleaned.
  Added F11/F12 display/clear dungeon symbols.
  Fixed page length in util display.
  Eat keystrokes in second timer pause routine.
  Remove monsters beyond player from attack array.
  Update some counting variables during player movement.
  Trapped interrupt service error during program shells.
  Error with trapped control-break being returned as two-byte null.
  Problem restoring current directory during shells.

    The DUNGEON v12.0 r3.0 Documentation                          Page  ii
[Image: screen1.jpg]



post pictures



Attached Files
.zip   DNGEON12.ZIP (Size: 305.37 KB / Downloads: 35)
.zip   DUNGEON_v12_QB64.zip (Size: 354.78 KB / Downloads: 38)
.zip   dngscrns.zip (Size: 969.18 KB / Downloads: 32)
Print this item

  I just made the 10,000th post!
Posted by: Pete - 12-07-2022, 08:34 PM - Forum: General Discussion - Replies (3)

Wooohooo!

Print this item

  Day 026: ERASE
Posted by: Pete - 12-07-2022, 07:24 AM - Forum: Keyword of the Day! - Replies (12)

ERASE probably should be renamed ARRase, because all it erases is the values stored in a specified array.

ERRASE makes the strings assigned to an array null or makes the numeric values assigned to a numeric array zero.

ERASE ArrayName [, others...]

Example:

Code: (Select All)
DIM Pete(10) AS STRING, var(100) AS INTEGER, cnt(20) AS LONG
ERASE Pete, var, cnt

ERASE can be used with STATIC or DYNAMIC arrays, but there is an important difference. Try running the two following code snippets. 

Code: (Select All)
DIM Pete(1 TO 20) AS INTEGER ' DIM makes Pete a STATIC array.
FOR i = 1 TO 20
    Pete(i) = -i
NEXT

FOR i = 1 TO UBOUND(Pete)
    PRINT Pete(i)
NEXT
SLEEP

ERASE Pete

' All zeros will now be output.
CLS
FOR i = 1 TO 20
    PRINT Pete(i)
NEXT
PRINT " ubound(Pete) is still ="; UBOUND(Pete)
Pete(15) = 101
PRINT: PRINT " Pete(15) ="; Pete(15)

Note: This routine will error out unless we Re-initialize the Pete array.
Code: (Select All)
REDIM Pete(1 TO 20) AS INTEGER ' REDIM makes Pete a DYNAMIC array.
FOR i = 1 TO 20
    Pete(i) = -i
NEXT

FOR i = 1 TO UBOUND(Pete)
    PRINT Pete(i)
NEXT
SLEEP

ERASE Pete

' This will error out unless we do a REDIM Pete(1 TO 20) here.
CLS
FOR i = 1 TO 20
    PRINT Pete(i)
NEXT
PRINT " ubound(Pete) is still ="; UBOUND(Pete)
Pete(15) = 101
PRINT: PRINT " Pete(15) ="; Pete(15)

So ERASE appears to have more value and versatility when used with STATIC arrays, if you consider not de-initialing your array as a benefit.

And what makes an array either static or dynamic? Well...

DIM makes the array static.

REDIM makes the array dynamic

And this important note...

REM $DYNAMIC makes ALL arrays dynamic. So even...

Code: (Select All)
REM $DYNAMIC
DIM Pete(1 to 20)
ERASE Pete
REDIM Pete(1 to 20)

...makes the otherwise static DIM array, of Pete, dynamic. So if you use REM $DYNAMIC at the top of your code, use REDIM because a DIM statement after an ERASE statement won't work with REM DYNAMIC in your code.

REM $STATIC makes ALL arrays static. but...

Code: (Select All)
REM $STATIC
REDIM Pete(1 to 20) ' Change to DIM to get this to work.
ERASE Pete
PRINT Pete(15) ' Errors out because even though we used REM $STATIC REDIM messed it up.

So we've kicked the tires quite a bit here. Anyone want to add anything more?

Pete

Print this item

  Color Valuenator(tm) by Steve the Awesome(tm)(c)
Posted by: SMcNeill - 12-07-2022, 06:40 AM - Forum: Utilities - Replies (12)

This...  This was something to work up... 

I thought I was starting with a simple little idea for a quick project, and then I ended up over-engineering the BLEEP out of this little booger!


Code: (Select All)
_Title "Color Valuenator(tm) by Steve the Awesome(tm)(c)"

$Color:32
Color 15
Print "Hello World!  Be in awe of my Color Valuenator!!(tm)"


Print ColorValue("_RGB32(128,128,128)"), _RGB32(128, 128, 128)
Print ColorValue("15"), 15
Print ColorValue("RGB(255,0,0)"), _RGB(255, 0, 0)
Print ColorValue("Black"), Black
Print ColorValue("Red"), Red
Print ColorValue("_RGB32(37)"), _RGB32(37)
Print ColorValue("Frog"), Frog, "<-- -1 says invalid color value"




Function ColorValue&& (text$)
    ReDim values(1000) As String
    ColorValue = -1 'This is to report a failed attempt to get a valid color.
    '                All valid colors will be greater than -1, so be certain the return variable is an _INTEGER64 type
    '                so that this -1 value doesn't overflow and become bright white (most likely), or some other color

    If IsNum(text$) Then 'our color is either in plain number form (COLOR 15, for example), or hex form (&HFFFFFFFF, for example)
        temp&& = Val(text$)
        If temp&& >= 0 Then
            ColorValue = temp&&
        Else
            If temp&& >= -2147483648 Then 'it's probably a color, but in LONG (signed) format.  Let's convert it automagically and roll with it.
                temp& = temp&&
                ColorValue = temp&
            End If
        End If
    Else
        temp$ = _Trim$(UCase$(text$))
        If Left$(temp$, 7) = "_RGBA32" Or Left$(temp$, 6) = "RGBA32" Then 'It's in RGBA32 format
            If ParseValues(text$, values()) <> 4 Then ColorValue = -1: Exit Function
            r% = Val(values(1))
            g% = Val(values(2))
            b% = Val(values(3))
            a% = Val(values(4))
            ColorValue = _RGBA32(r%, g%, b%, a%)
        ElseIf Left$(temp$, 5) = "_RGBA" Or Left$(temp$, 4) = "RGBA" Then 'It's in RGBA format
            p = ParseValues(text$, values())
            If p < 4 Or p > 5 Then ColorValue = -1: Exit Function
            r% = Val(values(1))
            g% = Val(values(2))
            b% = Val(values(3))
            a% = Val(values(4))
            If p = 5 Then
                d% = Val(values(5)) 'the destination of the screen whose palette we're matching against
                ColorValue = _RGBA(r%, g%, b%, a%, d%)
            Else
                ColorValue = _RGBA(r%, g%, b%, a%) 'note that this value will change depending upon the screen that it's called from
                'RGBA tries to match the called value to the closest possible color match that the existing palette has.
            End If
        ElseIf Left$(temp$, 6) = "_RGB32" Or Left$(temp$, 5) = "RGB32" Then 'It's in RGB32 format
            p = ParseValues(text$, values())
            Select Case p
                Case 4 '_RGB32(num, num2, num3, num4) <-- this is RGBA format
                    r% = Val(values(1))
                    g% = Val(values(2))
                    b% = Val(values(3))
                    a% = Val(values(4))
                    ColorValue = _RGBA32(r%, g%, b%, a%)
                Case 3 ' _RGB32(num, num2, num3) <-- this is RGB format
                    r% = Val(values(1))
                    g% = Val(values(2))
                    b% = Val(values(3))
                    ColorValue = _RGB32(r%, g%, b%)
                Case 2 ' _RGB32(num, num2) <-- Grayscale with alpha
                    r% = Val(values(1))
                    g% = Val(values(2))
                    ColorValue = _RGB32(r%, g%)
                Case 1 ' _RGB32(num) <-- Grayscale alone
                    r% = Val(values(1))
                    ColorValue = _RGB32(r%)
                Case Else
                    ColorValue = -1: Exit Function '<-- can not return a valid color value
            End Select
        ElseIf Left$(temp$, 4) = "_RGB" Or Left$(temp$, 3) = "RGB" Then 'It's in RGB format
            p = ParseValues(text$, values())
            If p < 3 Or p > 4 Then ColorValue = -1: Exit Function
            r% = Val(values(1))
            g% = Val(values(2))
            b% = Val(values(3))
            If p = 4 Then
                d% = Val(values(4)) 'the destination of the screen whose palette we're matching against
                ColorValue = _RGB(r%, g%, b%, d%)
            Else
                ColorValue = _RGB(r%, g%, b%) 'note that this value will change depending upon the screen that it's called from
                'RGBA tries to match the called value to the closest possible color match that the existing palette has.
            End If
        Else 'check to see if it's a color name value
            ReDim kolor$(1000), value(1000) As _Integer64
            count = count + 1: kolor$(count) = "AliceBlue": value(count) = 4293982463
            count = count + 1: kolor$(count) = "Almond": value(count) = 4293910221
            count = count + 1: kolor$(count) = "AntiqueBrass": value(count) = 4291663221
            count = count + 1: kolor$(count) = "AntiqueWhite": value(count) = 4294634455
            count = count + 1: kolor$(count) = "Apricot": value(count) = 4294826421
            count = count + 1: kolor$(count) = "Aqua": value(count) = 4278255615
            count = count + 1: kolor$(count) = "Aquamarine": value(count) = 4286578644
            count = count + 1: kolor$(count) = "Asparagus": value(count) = 4287080811
            count = count + 1: kolor$(count) = "AtomicTangerine": value(count) = 4294943860
            count = count + 1: kolor$(count) = "Azure": value(count) = 4293984255
            count = count + 1: kolor$(count) = "BananaMania": value(count) = 4294633397
            count = count + 1: kolor$(count) = "Beaver": value(count) = 4288643440
            count = count + 1: kolor$(count) = "Beige": value(count) = 4294309340
            count = count + 1: kolor$(count) = "Bisque": value(count) = 4294960324
            count = count + 1: kolor$(count) = "Bittersweet": value(count) = 4294802542
            count = count + 1: kolor$(count) = "Black": value(count) = 4278190080
            count = count + 1: kolor$(count) = "BlanchedAlmond": value(count) = 4294962125
            count = count + 1: kolor$(count) = "BlizzardBlue": value(count) = 4289521134
            count = count + 1: kolor$(count) = "Blue": value(count) = 4278190335
            count = count + 1: kolor$(count) = "BlueBell": value(count) = 4288848592
            count = count + 1: kolor$(count) = "BlueGray": value(count) = 4284914124
            count = count + 1: kolor$(count) = "BlueGreen": value(count) = 4279081146
            count = count + 1: kolor$(count) = "BlueViolet": value(count) = 4287245282
            count = count + 1: kolor$(count) = "Blush": value(count) = 4292763011
            count = count + 1: kolor$(count) = "BrickRed": value(count) = 4291510612
            count = count + 1: kolor$(count) = "Brown": value(count) = 4289014314
            count = count + 1: kolor$(count) = "BurlyWood": value(count) = 4292786311
            count = count + 1: kolor$(count) = "BurntOrange": value(count) = 4294934345
            count = count + 1: kolor$(count) = "BurntSienna": value(count) = 4293557853
            count = count + 1: kolor$(count) = "CadetBlue": value(count) = 4284456608
            count = count + 1: kolor$(count) = "Canary": value(count) = 4294967193
            count = count + 1: kolor$(count) = "CaribbeanGreen": value(count) = 4280079266
            count = count + 1: kolor$(count) = "CarnationPink": value(count) = 4294945484
            count = count + 1: kolor$(count) = "Cerise": value(count) = 4292691090
            count = count + 1: kolor$(count) = "Cerulean": value(count) = 4280134870
            count = count + 1: kolor$(count) = "ChartReuse": value(count) = 4286578432
            count = count + 1: kolor$(count) = "Chestnut": value(count) = 4290534744
            count = count + 1: kolor$(count) = "Chocolate": value(count) = 4291979550
            count = count + 1: kolor$(count) = "Copper": value(count) = 4292711541
            count = count + 1: kolor$(count) = "Coral": value(count) = 4294934352
            count = count + 1: kolor$(count) = "Cornflower": value(count) = 4288335595
            count = count + 1: kolor$(count) = "CornflowerBlue": value(count) = 4284782061
            count = count + 1: kolor$(count) = "Cornsilk": value(count) = 4294965468
            count = count + 1: kolor$(count) = "CottonCandy": value(count) = 4294950105
            count = count + 1: kolor$(count) = "CrayolaAquamarine": value(count) = 4286110690
            count = count + 1: kolor$(count) = "CrayolaBlue": value(count) = 4280251902
            count = count + 1: kolor$(count) = "CrayolaBlueViolet": value(count) = 4285753021
            count = count + 1: kolor$(count) = "CrayolaBrown": value(count) = 4290013005
            count = count + 1: kolor$(count) = "CrayolaCadetBlue": value(count) = 4289771462
            count = count + 1: kolor$(count) = "CrayolaForestGreen": value(count) = 4285378177
            count = count + 1: kolor$(count) = "CrayolaGold": value(count) = 4293379735
            count = count + 1: kolor$(count) = "CrayolaGoldenrod": value(count) = 4294760821
            count = count + 1: kolor$(count) = "CrayolaGray": value(count) = 4287992204
            count = count + 1: kolor$(count) = "CrayolaGreen": value(count) = 4280069240
            count = count + 1: kolor$(count) = "CrayolaGreenYellow": value(count) = 4293978257
            count = count + 1: kolor$(count) = "CrayolaIndigo": value(count) = 4284315339
            count = count + 1: kolor$(count) = "CrayolaLavender": value(count) = 4294751445
            count = count + 1: kolor$(count) = "CrayolaMagenta": value(count) = 4294337711
            count = count + 1: kolor$(count) = "CrayolaMaroon": value(count) = 4291311706
            count = count + 1: kolor$(count) = "CrayolaMidnightBlue": value(count) = 4279912566
            count = count + 1: kolor$(count) = "CrayolaOrange": value(count) = 4294931768
            count = count + 1: kolor$(count) = "CrayolaOrangeRed": value(count) = 4294912811
            count = count + 1: kolor$(count) = "CrayolaOrchid": value(count) = 4293306583
            count = count + 1: kolor$(count) = "CrayolaPlum": value(count) = 4287513989
            count = count + 1: kolor$(count) = "CrayolaRed": value(count) = 4293795917
            count = count + 1: kolor$(count) = "CrayolaSalmon": value(count) = 4294941610
            count = count + 1: kolor$(count) = "CrayolaSeaGreen": value(count) = 4288668351
            count = count + 1: kolor$(count) = "CrayolaSilver": value(count) = 4291675586
            count = count + 1: kolor$(count) = "CrayolaSkyBlue": value(count) = 4286634731
            count = count + 1: kolor$(count) = "CrayolaSpringGreen": value(count) = 4293716670
            count = count + 1: kolor$(count) = "CrayolaTann": value(count) = 4294616940
            count = count + 1: kolor$(count) = "CrayolaThistle": value(count) = 4293642207
            count = count + 1: kolor$(count) = "CrayolaViolet": value(count) = 4287786670
            count = count + 1: kolor$(count) = "CrayolaYellow": value(count) = 4294764675
            count = count + 1: kolor$(count) = "CrayolaYellowGreen": value(count) = 4291158916
            count = count + 1: kolor$(count) = "Crimson": value(count) = 4292613180
            count = count + 1: kolor$(count) = "Cyan": value(count) = 4278255615
            count = count + 1: kolor$(count) = "Dandelion": value(count) = 4294826861
            count = count + 1: kolor$(count) = "DarkBlue": value(count) = 4278190219
            count = count + 1: kolor$(count) = "DarkCyan": value(count) = 4278225803
            count = count + 1: kolor$(count) = "DarkGoldenRod": value(count) = 4290283019
            count = count + 1: kolor$(count) = "DarkGray": value(count) = 4289309097
            count = count + 1: kolor$(count) = "DarkGreen": value(count) = 4278215680
            count = count + 1: kolor$(count) = "DarkKhaki": value(count) = 4290623339
            count = count + 1: kolor$(count) = "DarkMagenta": value(count) = 4287299723
            count = count + 1: kolor$(count) = "DarkOliveGreen": value(count) = 4283788079
            count = count + 1: kolor$(count) = "DarkOrange": value(count) = 4294937600
            count = count + 1: kolor$(count) = "DarkOrchid": value(count) = 4288230092
            count = count + 1: kolor$(count) = "DarkRed": value(count) = 4287299584
            count = count + 1: kolor$(count) = "DarkSalmon": value(count) = 4293498490
            count = count + 1: kolor$(count) = "DarkSeaGreen": value(count) = 4287609999
            count = count + 1: kolor$(count) = "DarkSlateBlue": value(count) = 4282924427
            count = count + 1: kolor$(count) = "DarkSlateGray": value(count) = 4281290575
            count = count + 1: kolor$(count) = "DarkTurquoise": value(count) = 4278243025
            count = count + 1: kolor$(count) = "DarkViolet": value(count) = 4287889619
            count = count + 1: kolor$(count) = "DeepPink": value(count) = 4294907027
            count = count + 1: kolor$(count) = "DeepSkyBlue": value(count) = 4278239231
            count = count + 1: kolor$(count) = "Denim": value(count) = 4281035972
            count = count + 1: kolor$(count) = "DesertSand": value(count) = 4293905848
            count = count + 1: kolor$(count) = "DimGray": value(count) = 4285098345
            count = count + 1: kolor$(count) = "DodgerBlue": value(count) = 4280193279
            count = count + 1: kolor$(count) = "Eggplant": value(count) = 4285419872
            count = count + 1: kolor$(count) = "ElectricLime": value(count) = 4291755805
            count = count + 1: kolor$(count) = "Fern": value(count) = 4285643896
            count = count + 1: kolor$(count) = "FireBrick": value(count) = 4289864226
            count = count + 1: kolor$(count) = "Floralwhite": value(count) = 4294966000
            count = count + 1: kolor$(count) = "ForestGreen": value(count) = 4280453922
            count = count + 1: kolor$(count) = "Fuchsia": value(count) = 4290995397
            count = count + 1: kolor$(count) = "FuzzyWuzzy": value(count) = 4291585638
            count = count + 1: kolor$(count) = "Gainsboro": value(count) = 4292664540
            count = count + 1: kolor$(count) = "GhostWhite": value(count) = 4294506751
            count = count + 1: kolor$(count) = "Gold": value(count) = 4294956800
            count = count + 1: kolor$(count) = "GoldenRod": value(count) = 4292519200
            count = count + 1: kolor$(count) = "GrannySmithApple": value(count) = 4289258656
            count = count + 1: kolor$(count) = "Gray": value(count) = 4286611584
            count = count + 1: kolor$(count) = "Green": value(count) = 4278222848
            count = count + 1: kolor$(count) = "GreenBlue": value(count) = 4279329972
            count = count + 1: kolor$(count) = "GreenYellow": value(count) = 4289593135
            count = count + 1: kolor$(count) = "Grey": value(count) = 4286611584
            count = count + 1: kolor$(count) = "HoneyDew": value(count) = 4293984240
            count = count + 1: kolor$(count) = "HotMagenta": value(count) = 4294909390
            count = count + 1: kolor$(count) = "HotPink": value(count) = 4294928820
            count = count + 1: kolor$(count) = "Inchworm": value(count) = 4289915997
            count = count + 1: kolor$(count) = "IndianRed": value(count) = 4291648604
            count = count + 1: kolor$(count) = "Indigo": value(count) = 4283105410
            count = count + 1: kolor$(count) = "Ivory": value(count) = 4294967280
            count = count + 1: kolor$(count) = "JazzberryJam": value(count) = 4291442535
            count = count + 1: kolor$(count) = "JungleGreen": value(count) = 4282101903
            count = count + 1: kolor$(count) = "Khaki": value(count) = 4293977740
            count = count + 1: kolor$(count) = "LaserLemon": value(count) = 4294901282
            count = count + 1: kolor$(count) = "Lavender": value(count) = 4293322490
            count = count + 1: kolor$(count) = "LavenderBlush": value(count) = 4294963445
            count = count + 1: kolor$(count) = "LawnGreen": value(count) = 4286381056
            count = count + 1: kolor$(count) = "LemonChiffon": value(count) = 4294965965
            count = count + 1: kolor$(count) = "LemonYellow": value(count) = 4294964303
            count = count + 1: kolor$(count) = "LightBlue": value(count) = 4289583334
            count = count + 1: kolor$(count) = "LightCoral": value(count) = 4293951616
            count = count + 1: kolor$(count) = "LightCyan": value(count) = 4292935679
            count = count + 1: kolor$(count) = "LightGoldenRodYellow": value(count) = 4294638290
            count = count + 1: kolor$(count) = "LightGray": value(count) = 4292072403
            count = count + 1: kolor$(count) = "LightGreen": value(count) = 4287688336
            count = count + 1: kolor$(count) = "LightPink": value(count) = 4294948545
            count = count + 1: kolor$(count) = "LightSalmon": value(count) = 4294942842
            count = count + 1: kolor$(count) = "LightSeaGreen": value(count) = 4280332970
            count = count + 1: kolor$(count) = "LightSkyBlue": value(count) = 4287090426
            count = count + 1: kolor$(count) = "LightSlateGray": value(count) = 4286023833
            count = count + 1: kolor$(count) = "LightSteelBlue": value(count) = 4289774814
            count = count + 1: kolor$(count) = "LightYellow": value(count) = 4294967264
            count = count + 1: kolor$(count) = "Lime": value(count) = 4278255360
            count = count + 1: kolor$(count) = "LimeGreen": value(count) = 4281519410
            count = count + 1: kolor$(count) = "Linen": value(count) = 4294635750
            count = count + 1: kolor$(count) = "MacaroniAndCheese": value(count) = 4294950280
            count = count + 1: kolor$(count) = "Magenta": value(count) = 4294902015
            count = count + 1: kolor$(count) = "MagicMint": value(count) = 4289392849
            count = count + 1: kolor$(count) = "Mahogany": value(count) = 4291643980
            count = count + 1: kolor$(count) = "Maize": value(count) = 4293775772
            count = count + 1: kolor$(count) = "Manatee": value(count) = 4288125610
            count = count + 1: kolor$(count) = "MangoTango": value(count) = 4294935107
            count = count + 1: kolor$(count) = "Maroon": value(count) = 4286578688
            count = count + 1: kolor$(count) = "Mauvelous": value(count) = 4293892266
            count = count + 1: kolor$(count) = "MediumAquamarine": value(count) = 4284927402
            count = count + 1: kolor$(count) = "MediumBlue": value(count) = 4278190285
            count = count + 1: kolor$(count) = "MediumOrchid": value(count) = 4290401747
            count = count + 1: kolor$(count) = "MediumPurple": value(count) = 4287852763
            count = count + 1: kolor$(count) = "MediumSeaGreen": value(count) = 4282168177
            count = count + 1: kolor$(count) = "MediumSlateBlue": value(count) = 4286277870
            count = count + 1: kolor$(count) = "MediumSpringGreen": value(count) = 4278254234
            count = count + 1: kolor$(count) = "MediumTurquoise": value(count) = 4282962380
            count = count + 1: kolor$(count) = "MediumVioletRed": value(count) = 4291237253
            count = count + 1: kolor$(count) = "Melon": value(count) = 4294818996
            count = count + 1: kolor$(count) = "MidnightBlue": value(count) = 4279834992
            count = count + 1: kolor$(count) = "MintCream": value(count) = 4294311930
            count = count + 1: kolor$(count) = "MistyRose": value(count) = 4294960353
            count = count + 1: kolor$(count) = "Moccasin": value(count) = 4294960309
            count = count + 1: kolor$(count) = "MountainMeadow": value(count) = 4281383567
            count = count + 1: kolor$(count) = "Mulberry": value(count) = 4291120012
            count = count + 1: kolor$(count) = "NavajoWhite": value(count) = 4294958765
            count = count + 1: kolor$(count) = "Navy": value(count) = 4278190208
            count = count + 1: kolor$(count) = "NavyBlue": value(count) = 4279858386
            count = count + 1: kolor$(count) = "NeonCarrot": value(count) = 4294943555
            count = count + 1: kolor$(count) = "OldLace": value(count) = 4294833638
            count = count + 1: kolor$(count) = "Olive": value(count) = 4286611456
            count = count + 1: kolor$(count) = "OliveDrab": value(count) = 4285238819
            count = count + 1: kolor$(count) = "OliveGreen": value(count) = 4290426988
            count = count + 1: kolor$(count) = "Orange": value(count) = 4294944000
            count = count + 1: kolor$(count) = "OrangeRed": value(count) = 4294919424
            count = count + 1: kolor$(count) = "OrangeYellow": value(count) = 4294497640
            count = count + 1: kolor$(count) = "Orchid": value(count) = 4292505814
            count = count + 1: kolor$(count) = "OuterSpace": value(count) = 4282468940
            count = count + 1: kolor$(count) = "OutrageousOrange": value(count) = 4294929994
            count = count + 1: kolor$(count) = "PacificBlue": value(count) = 4280068553
            count = count + 1: kolor$(count) = "PaleGoldenRod": value(count) = 4293847210
            count = count + 1: kolor$(count) = "PaleGreen": value(count) = 4288215960
            count = count + 1: kolor$(count) = "PaleTurquoise": value(count) = 4289720046
            count = count + 1: kolor$(count) = "PaleVioletRed": value(count) = 4292571283
            count = count + 1: kolor$(count) = "PapayaWhip": value(count) = 4294963157
            count = count + 1: kolor$(count) = "Peach": value(count) = 4294954923
            count = count + 1: kolor$(count) = "PeachPuff": value(count) = 4294957753
            count = count + 1: kolor$(count) = "Periwinkle": value(count) = 4291154150
            count = count + 1: kolor$(count) = "Peru": value(count) = 4291659071
            count = count + 1: kolor$(count) = "PiggyPink": value(count) = 4294827494
            count = count + 1: kolor$(count) = "PineGreen": value(count) = 4279599224
            count = count + 1: kolor$(count) = "Pink": value(count) = 4294951115
            count = count + 1: kolor$(count) = "PinkFlamingo": value(count) = 4294735101
            count = count + 1: kolor$(count) = "PinkSherbet": value(count) = 4294414247
            count = count + 1: kolor$(count) = "Plum": value(count) = 4292714717
            count = count + 1: kolor$(count) = "PowderBlue": value(count) = 4289781990
            count = count + 1: kolor$(count) = "Purple": value(count) = 4286578816
            count = count + 1: kolor$(count) = "PurpleHeart": value(count) = 4285809352
            count = count + 1: kolor$(count) = "PurpleMountainsMajesty": value(count) = 4288512442
            count = count + 1: kolor$(count) = "PurplePizzazz": value(count) = 4294856410
            count = count + 1: kolor$(count) = "RadicalRed": value(count) = 4294920556
            count = count + 1: kolor$(count) = "RawSienna": value(count) = 4292250201
            count = count + 1: kolor$(count) = "RawUmber": value(count) = 4285614883
            count = count + 1: kolor$(count) = "RazzleDazzleRose": value(count) = 4294920400
            count = count + 1: kolor$(count) = "Razzmatazz": value(count) = 4293076331
            count = count + 1: kolor$(count) = "Red": value(count) = 4294901760
            count = count + 1: kolor$(count) = "RedOrange": value(count) = 4294923081
            count = count + 1: kolor$(count) = "RedViolet": value(count) = 4290790543
            count = count + 1: kolor$(count) = "RobinsEggBlue": value(count) = 4280274635
            count = count + 1: kolor$(count) = "RosyBrown": value(count) = 4290547599
            count = count + 1: kolor$(count) = "RoyalBlue": value(count) = 4282477025
            count = count + 1: kolor$(count) = "RoyalPurple": value(count) = 4286075305
            count = count + 1: kolor$(count) = "SaddleBrown": value(count) = 4287317267
            count = count + 1: kolor$(count) = "Salmon": value(count) = 4294606962
            count = count + 1: kolor$(count) = "SandyBrown": value(count) = 4294222944
            count = count + 1: kolor$(count) = "Scarlet": value(count) = 4294715463
            count = count + 1: kolor$(count) = "ScreaminGreen": value(count) = 4285988730
            count = count + 1: kolor$(count) = "SeaGreen": value(count) = 4281240407
            count = count + 1: kolor$(count) = "SeaShell": value(count) = 4294964718
            count = count + 1: kolor$(count) = "Sepia": value(count) = 4289030479
            count = count + 1: kolor$(count) = "Shadow": value(count) = 4287265117
            count = count + 1: kolor$(count) = "Shamrock": value(count) = 4282764962
            count = count + 1: kolor$(count) = "ShockingPink": value(count) = 4294672125
            count = count + 1: kolor$(count) = "Sienna": value(count) = 4288696877
            count = count + 1: kolor$(count) = "Silver": value(count) = 4290822336
            count = count + 1: kolor$(count) = "SkyBlue": value(count) = 4287090411
            count = count + 1: kolor$(count) = "SlateBlue": value(count) = 4285160141
            count = count + 1: kolor$(count) = "SlateGray": value(count) = 4285563024
            count = count + 1: kolor$(count) = "Snow": value(count) = 4294966010
            count = count + 1: kolor$(count) = "SpringGreen": value(count) = 4278255487
            count = count + 1: kolor$(count) = "SteelBlue": value(count) = 4282811060
            count = count + 1: kolor$(count) = "Sunglow": value(count) = 4294954824
            count = count + 1: kolor$(count) = "SunsetOrange": value(count) = 4294794835
            count = count + 1: kolor$(count) = "Tann": value(count) = 4291998860
            count = count + 1: kolor$(count) = "Teal": value(count) = 4278222976
            count = count + 1: kolor$(count) = "TealBlue": value(count) = 4279805877
            count = count + 1: kolor$(count) = "Thistle": value(count) = 4292394968
            count = count + 1: kolor$(count) = "TickleMePink": value(count) = 4294740396
            count = count + 1: kolor$(count) = "Timberwolf": value(count) = 4292597714
            count = count + 1: kolor$(count) = "Tomato": value(count) = 4294927175
            count = count + 1: kolor$(count) = "TropicalRainForest": value(count) = 4279730285
            count = count + 1: kolor$(count) = "Tumbleweed": value(count) = 4292782728
            count = count + 1: kolor$(count) = "Turquoise": value(count) = 4282441936
            count = count + 1: kolor$(count) = "TurquoiseBlue": value(count) = 4286045671
            count = count + 1: kolor$(count) = "UnmellowYellow": value(count) = 4294967142
            count = count + 1: kolor$(count) = "Violet": value(count) = 4293821166
            count = count + 1: kolor$(count) = "VioletBlue": value(count) = 4281486002
            count = count + 1: kolor$(count) = "VioletRed": value(count) = 4294398868
            count = count + 1: kolor$(count) = "VividTangerine": value(count) = 4294942857
            count = count + 1: kolor$(count) = "VividViolet": value(count) = 4287582365
            count = count + 1: kolor$(count) = "Wheat": value(count) = 4294303411
            count = count + 1: kolor$(count) = "White": value(count) = 4294967295
            count = count + 1: kolor$(count) = "Whitesmoke": value(count) = 4294309365
            count = count + 1: kolor$(count) = "WildBlueYonder": value(count) = 4288851408
            count = count + 1: kolor$(count) = "WildStrawberry": value(count) = 4294919076
            count = count + 1: kolor$(count) = "WildWatermelon": value(count) = 4294732933
            count = count + 1: kolor$(count) = "Wisteria": value(count) = 4291667166
            count = count + 1: kolor$(count) = "Yellow": value(count) = 4294967040
            count = count + 1: kolor$(count) = "YellowGreen": value(count) = 4288335154
            count = count + 1: kolor$(count) = "YellowOrange": value(count) = 4294946370
            ReDim _Preserve kolor$(count), value(count)
            For i = 1 To count
                If UCase$(temp$) = UCase$(kolor$(i)) Then ColorValue = value(i): Exit Function
            Next
        End If
    End If

End Function

Function ParseValues (text$, values() As String)
    ReDim values(1000) As String

    temp$ = text$ 'preserve without changing our text
    lp = InStr(temp$, "("): temp$ = Mid$(temp$, lp + 1) 'strip off any left sided parenthesis, such as _RGB32(
    rp = _InStrRev(temp$, ")"): If rp Then temp$ = Left$(temp$, rp - 1) 'strip off the right sided parenthesis )

    Do
        p = InStr(temp$, ",")
        If p Then
            eval$ = Left$(temp$, p - 1)
            If IsNum(eval$) = 0 Then ParseValues = -1: Exit Function
            count = count + 1
            If count > UBound(values) Then ReDim _Preserve values(UBound(values) + 1000) As String
            values(count) = eval$
            temp$ = Mid$(temp$, p + 1)
        Else
            eval$ = temp$
            If IsNum(eval$) = 0 Then ParseValues = -1: Exit Function
            count = count + 1
            If count > UBound(values) Then ReDim _Preserve values(UBound(values) + 1) As String
            values(count) = eval$
            temp$ = ""
        End If
    Loop Until temp$ = ""
    ReDim _Preserve values(count) As String
    ParseValues = count
End Function


Function IsNum%% (PassedText As String)
    text$ = _Trim$(PassedText)
    special$ = UCase$(Left$(text$, 2))
    Select Case special$
        Case "&H", "&B", "&O"
            'check for symbols on right side of value
            r3$ = Right$(text$, 3)
            Select Case r3$
                Case "~&&", "~%%", "~%&" 'unsigned int64, unsigned byte, unsigned offset
                    text$ = Left$(text$, Len(text$) - 3)
                Case Else
                    r2$ = Right$(text$, 2)
                    Select Case r2$
                        Case "~&", "##", "%&", "%%", "~%", "&&" 'unsigned long, float, offset, byte, unsigned integer, int64
                            text$ = Left$(text$, Len(text$) - 2)
                        Case Else
                            r$ = Right$(text$, 1)
                            Select Case r$
                                Case "&", "#", "%", "!" 'long, double, integer, single
                                    text$ = Left$(text$, Len(text$) - 1)
                            End Select
                    End Select
            End Select
            check$ = "0123456789ABCDEF"
            If special$ = "&O" Then check$ = "01234567"
            If special$ = "&B" Then check$ = "01"
            temp$ = Mid$(UCase$(text$), 2)
            For i = 1 To Len(temp$)
                If InStr(check$, Mid$(temp$, i, 1)) = 0 Then Exit For
            Next
            If i <= Len(temp$) Then IsNum = -1
        Case Else
            If _Trim$(Str$(Val(text$))) = text$ Then IsNum = -1
    End Select
End Function

Coming in at 440 lines of code, this awesome Colornator...  umm... well..  It gives you the color value of a text string, if possible.

/blush

Lots and lots of code, just to do something so simple -- but it's more complex than you'd first imagine!!

This works with plain numeric values for colors.  This works with _RGB, _RGBA, _RGB32, _RGBA32 values.  Hex values, Octal, and even Binary values are all fine!  (&H,  &O, &B prefaced values.)  This lets you specify a color NAME, and it returns the 32-bit color value back from that!!

It's THE COLORNATOR!!  Dr. Doofenshmirtz, eat your heart out!  I just out NATORed you!  Tongue

Print this item

  Picture to text converter
Posted by: MasterGy - 12-06-2022, 07:21 PM - Forum: MasterGy - Replies (15)

Hello !

Out of curiosity, I created a program for converting images to characters.
There are so many online, there are also online converters.

I tried to add something extra. It also works with variable character width, and the shades of the image can be adjusted.

Enter the image and font in the source code. You can change what characters it uses.

When the program starts, the optimal image can be adjusted with brightness/contrast.
It is possible to set how many lines the image is displayed.
Black characters on a white background or white characters on a black background.
The width of the letter can be adjusted. (1- original 0.5, half as wide, 2, double wide)
You can set the size of the map to work on. This is important when saving, because the image can be saved in very good quality.

The program does not require external files.
Give it a picture and start it.



Code: (Select All)
'MasterGy 2022
Dim Shared pic, contrast, brightness, contrast_ref, char_collection$


'CHANGES SETTING ! ----------------------------------------------------------------------------------------------------------------------


picture$ = "image1.jpg" ' <------ set a picture
char_collection$ = "'+0123456789.?!=:>()<%/-,ABCDEFGHIJKLMNOPQRSTVXYZUWabcdefghijklmnopqrstvxyzuw" '<----- charecters used
type_s$ = Environ$("systemroot") + "/fonts/arial.ttf" '<------ font type

'------------------------------------------------------------------------------------------------------------------------------











s$ = " Press S to save BMP file     , ESC to return menu ": _Font 16
mess = _NewImage(8 * Len(s$), 16, 32): _Dest mess: Cls , _RGB32(100, 0, 0, 100): Color _RGB32(255, 255, 255, 255), _RGB32(100, 0, 0, 100): Locate 1, 1: Print s$;

pic_size = 500

temp = _LoadImage(picture$, 32): _Source temp
If _Width(temp) > _Height(temp) Then x = pic_size: y = Int(x / _Width(temp) * _Height(temp)) Else y = pic_size: x = Int(y / _Height(temp) * _Width(temp))
pic = _NewImage(x, y, 32): _Dest pic: _PutImage: _FreeImage temp


s_c = 7
s$(0) = "contrast": s(0, 0) = 1.5: s(0, 1) = 1: s(0, 2) = 7
s$(1) = "contrast_ref": s(1, 0) = 128: s(1, 1) = 0: s(1, 2) = 255
s$(2) = "brigthness": s(2, 0) = 0: s(2, 1) = -255: s(2, 2) = 255
s$(3) = "types rows": s(3, 0) = 75: s(3, 1) = 10: s(3, 2) = 200
s$(4) = "output picture size": s(4, 0) = _DesktopWidth: s(4, 1) = 300: s(4, 2) = 3000
s$(5) = "picture colors negate": s(5, 0) = 1: s(5, 1) = 0: s(5, 2) = 1
s$(6) = "type width-ratio": s(6, 0) = 1: s(6, 1) = .5: s(6, 2) = 4


s_sy = Int((y / 16) + 2): winx = x + 100: winy = (s_sy + s_c * 3 + 3) * 16 + 1: x_size = winx * .7
win = _NewImage(winx, winy, 32): Screen win: _FullScreen _SquarePixels , _Smooth

Do: _Limit 30


    k$ = InKey$
    Select Case k$
        Case Chr$(27): System
        Case "1", "2", "3": work_type = Val(k$): GoSub work
    End Select
    mousew = 0: While _MouseInput: mousew = mousew + _MouseWheel: Wend: If _MouseButton(1) = 0 Then mc = -1
    s(3, 0) = Int(s(3, 0))
    s(4, 0) = Int(s(4, 0))
    s(5, 0) = CInt(s(5, 0))
    s(7, 0) = CInt(s(7, 0))
    For sa = 0 To s_c - 1
        y1 = (s_sy + sa * 3 - 1) * 16 + 20: y2 = y1 + 14: x1 = (winx - x_size) / 2: x2 = x1 + x_size
        under2 = _MouseX > x1 And _MouseX < x2: under = under2 And _MouseY > y1 And _MouseY < y2
        mgrey = 128 + (CInt(s(5, 0)) * 2 - 1) * 127 * under
        Color _RGB(mgrey, mgrey, mgrey)
        s$ = s$(sa) + "  (" + LTrim$(Str$(Int(s(sa, 0) * 100) / 100)) + ")"
        If sa = 4 Then s$ = s$(sa) + "  (" + LTrim$(Str$(Int(s(sa, 0)))) + " x " + LTrim$(Str$(Int(s(sa, 0) / x * y))) + ")"
        Locate s_sy + sa * 3, (winx - Len(s$) * 8) / 16: Print UCase$(s$)
        Color _RGB(200, 40, 40): Line (x1, y1)-(x2, y2), , B
        x2 = x1 + x_size / (s(sa, 2) - s(sa, 1)) * (s(sa, 0) - s(sa, 1)): Line (x1, y1)-(x2, y2), , BF
        If under And _MouseButton(1) And mc = -1 Then mc = sa
    Next sa

    If mc <> -1 And under2 And mc <> 5 Then s(mc, 0) = (s(mc, 2) - s(mc, 1)) * (1 / x_size * (_MouseX - (winx - x_size) / 2)) + s(mc, 1)
    If mc = 5 And under2 And m5last = 0 Then s(5, 0) = 1 - s(5, 0): m5last = 1
    m5last = m5last And -_MouseButton(1)

    contrast = s(0, 0): contrast_ref = s(1, 0): brightness = s(2, 0)

    'statistic
    min = 999999: max = -min: _Dest mon: _Source pic
    For tx = 0 To x - 1: For ty = 0 To y - 1: grey = pic_read(tx, ty): If grey > max Then max = grey
        If grey < min Then min = grey
    Next ty, tx

    'draw
    temp = 255 / (max - min)
    sx = (winx - x) / 2: For tx = 0 To x - 1: For ty = 0 To y - 1: grey = temp * (pic_read(tx, ty) - min): PSet (sx + tx, ty), _RGB(grey, grey, grey): Next ty, tx


    _Display

    grey = 255 * CInt(s(5, 0))
    Cls , _RGB(grey, grey, grey)
    Color _RGB(50, 128, 50), 0
    Locate Int(winy / 16) - 3, 3: Print "-1- work variable character width";
    Locate Int(winy / 16) - 2, 3: Print "-2- work same character width";
    Locate Int(winy / 16) - 1, 3: Print "-3- work random character location";

Loop



'work
work:

Cls


_AutoDisplay
monx2 = Int(s(4, 0))
mony2 = Int(s(4, 0) / x * y)
t_height = Int(mony2 / s(3, 0))

temp = _LoadImage(picture$, 32): _Source temp: pic_work = _NewImage(monx2, mony2, 32): _Dest pic_work: _PutImage: _Source pic_work: _FreeImage temp
pic_out = _NewImage(monx2, mony2, 32)
temp = 255 / (max - min)
For tx = 0 To monx2 - 1: For ty = 0 To mony2 - 1: grey = temp * (pic_read(tx, ty) - min): PSet (tx, ty), _RGB(grey, grey, grey): Next ty, tx


mon2 = _NewImage(monx2, mony2, 32): Screen mon2


negate = CInt(s(5, 0))
ReDim Shared font_collection(255, 2): font_install type_s$, t_height * 2, negate, Abs(work_type = 2): _Font 16



_Dest pic_out
Cls , _RGB(255 * negate, 255 * negate, 255 * negate)
_FullScreen _SquarePixels , _Smooth


Select Case work_type
    Case 1, 2
        ReDim st(499, 1)
        Do: For a_row = 0 To Int(s(3, 0)) - 1
            _Source pic_out: _Dest mon2: _PutImage
            _Source mess: _PutImage (0, 0)-(_Width(mon2), _Width(mon2) / _Width(mess) * _Height(mess)): _Display
            _Dest pic_out
            a_col = 0
            Do
                _Source pic_work
                dif_ok = 99999
                For ac = 0 To Len(char_collection$) - 1

                Select Case LCase$(InKey$): Case Chr$(27): GoTo return_menu: Case "s": GoTo saving: End Select

                        x1 = a_col
                        stx = Int(t_height / _Height(font_collection(ac + 1, 0)) * _Width(font_collection(ac + 1, 0)))
                        x2 = x1 + Int(s(6, 0) * stx)
                        If x2 > monx2 Then Exit Do
                        y1 = a_row * t_height
                        y2 = y1 + t_height


                        If st(stx, 0) = a_col Then
                            st = st(stx, 1)
                        Else
                            sum = 0: c = 0: For tx = x1 To x2
                            For ty = y1 To y2: sum = sum + _Red(Point(tx, ty)): c = c + 1: Next ty, tx
                            st(stx, 0) = a_col
                            st = sum / (255 * c)
                            st(stx, 1) = st
                        End If

                        dif = Abs(st - font_collection(ac + 1, 2))
                        If dif < dif_ok Then dif_ok = dif: st_need = ac: x2_need = x2
                    Next ac

                    _Source font_collection(st_need + 1, 0)
                    _PutImage (x1, y1)-(x2_need, y2)
                    a_col = x2_need + 1
                Loop

        Next a_row: Loop

    Case 3
        Do
            cn = cn + 1: If cn > 100 Then
                _Source pic_out: _Dest mon2: _PutImage
                _Source mess: _PutImage (0, 0)-(_Width(mon2), _Width(mon2) / _Width(mess) * _Height(mess)): _Display
                cn = 0
            End If
            _Dest pic_out

        Select Case LCase$(InKey$): Case Chr$(27): GoTo return_menu: Case "s": GoTo saving: End Select
            xsize = Int(t_height * (1 + .5 * Rnd))
            ysize = Int(t_height * (1 + .5 * Rnd))
            xpos = Int((monx2 - xsize) * Rnd)
            ypos = Int((mony2 - ysize) * Rnd)

            sum = 0: c = 0: For tx = 0 To xsize - 1
                _Source pic_work
            For ty = 0 To ysize - 1: sum = sum + _Red(Point(tx + xpos, ty + ypos)): c = c + 1: Next ty, tx
            st = sum / (255 * c)
            dif_ok = 99999
            For ac = 0 To Len(char_collection$) - 1
                dif = Abs(st - font_collection(ac + 1, 2))
                If dif < dif_ok Then dif_ok = dif: st_need = ac
            Next ac
            _Source font_collection(st_need + 1, 0)
            _PutImage (xpos, ypos)-(xpos + xsize, ypos + ysize)
        Loop


End Select


saving: _AutoDisplay: Screen 0: _FullScreen _Off: Cls: Print "saving picture to SAVED.BMP...waiting": SaveImage pic_out, "saved.bmp": Sleep 2: System

return_menu: Screen win: _Dest win: _Source win: _Font 16: _FreeImage mon2: _FreeImage pic_work: _FreeImage pic_out: Return




Sub font_install (f$, fs, negate, mono)
    If mono Then af = _LoadFont(f$, fs, "monospace") Else af = _LoadFont(f$, fs)
    For ac = 0 To Len(char_collection$) - 1: ac$ = Mid$(char_collection$, ac + 1, 1): _Font af
        temp2 = _NewImage(_PrintWidth(ac$), fs, 32): _Dest temp2: Cls , _RGB(255 * negate, 255 * negate, 255 * negate)

        _Font af: Color _RGB(255 * (negate Xor 1), 255 * (negate Xor 1), 255 * (negate Xor 1)), 0
        _PrintString (0, 0), ac$: font_collection(ac + 1, 0) = _CopyImage(temp2, 32): _Source temp2

        c = 0: st = 0: For tx = 0 To _Width(temp2) - 1: For ty = 0 To _Height(temp2) - 1: c = c + 1: st = st + Abs(_Red(Point(tx, ty)) <> _Red(tc&&)): Next ty, tx
        font_collection(ac + 1, 2) = 1 / c * st: _FreeImage temp2
    font_collection(ac + 1, 1) = Asc(ac$): Next ac
    font_collection(0, 0) = af

    min_g = 99999: max_g = -min_g

    For t = 0 To Len(char_collection$) - 1 'find limits
        If font_collection(t + 1, 2) < min_g Then min_g = font_collection(t + 1, 2)
        If font_collection(t + 1, 2) > max_g Then max_g = font_collection(t + 1, 2)
    Next t

    For t = 0 To Len(char_collection$) - 1 'normalizing limits
        font_collection(t + 1, 2) = 1 / (max_g - min_g) * (font_collection(t + 1, 2) - min_g)
    Next t
End Sub


Function pic_read (tx, ty)
    p&& = Point(tx, ty): grey = (_Red(p&&) + _Green(p&&) + _Blue(p&&)) * .33333
    grey = contrast_ref + (grey - contrast_ref) * contrast + brightness
    If grey < 0 Then grey = 0
    If grey > 255 Then grey = 255
    pic_read = grey
End Function



Sub SaveImage (image As Long, filename As String)
    bytesperpixel& = _PixelSize(image&)
    If bytesperpixel& = 0 Then Print "Text modes unsupported!": End
    If bytesperpixel& = 1 Then bpp& = 8 Else bpp& = 24
    x& = _Width(image&)
    y& = _Height(image&)
    b$ = "BM????QB64????" + MKL$(40) + MKL$(x&) + MKL$(y&) + MKI$(1) + MKI$(bpp&) + MKL$(0) + "????" + String$(16, 0) 'partial BMP header info(???? to be filled later)
    If bytesperpixel& = 1 Then
        For c& = 0 To 255 ' read BGR color settings from JPG image + 1 byte spacer(CHR$(0))
            cv& = _PaletteColor(c&, image&) ' color attribute to read.
            b$ = b$ + Chr$(_Blue32(cv&)) + Chr$(_Green32(cv&)) + Chr$(_Red32(cv&)) + Chr$(0) 'spacer byte
        Next
    End If
    Mid$(b$, 11, 4) = MKL$(Len(b$)) ' image pixel data offset(BMP header)
    lastsource& = _Source
    _Source image&
    If ((x& * 3) Mod 4) Then padder$ = String$(4 - ((x& * 3) Mod 4), 0)
    For py& = y& - 1 To 0 Step -1 ' read JPG image pixel color data
        r$ = ""
        For px& = 0 To x& - 1
            c& = Point(px&, py&) 'POINT 32 bit values are large LONG values
            If bytesperpixel& = 1 Then r$ = r$ + Chr$(c&) Else r$ = r$ + Left$(MKL$(c&), 3)
        Next px&
        d$ = d$ + r$ + padder$
    Next py&
    _Source lastsource&
    Mid$(b$, 35, 4) = MKL$(Len(d$)) ' image size(BMP header)
    b$ = b$ + d$ ' total file data bytes to create file
    Mid$(b$, 3, 4) = MKL$(Len(b$)) ' size of data file(BMP header)
    If LCase$(Right$(filename$, 4)) <> ".bmp" Then ext$ = ".bmp"
    f& = FreeFile
    Open filename$ + ext$ For Output As #f&: Close #f& ' erases an existing file
    Open filename$ + ext$ For Binary As #f&
    Put #f&, , b$
    Close #f&
End Sub

Print this item

  $RESIZE with Word-Wrap Routine.
Posted by: Pete - 12-06-2022, 02:39 PM - Forum: Utilities - Replies (9)

The Thread Subject title says it all...

Code: (Select All)
$RESIZE:SMOOTH
Sw = 60
Sh = 25
S& = _NEWIMAGE(Sw, Sh, 0)
SCREEN S&
DO: LOOP UNTIL _SCREENEXISTS
font& = _LOADFONT(ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf", 18, "MONOSPACE")
_FONT font&
PALETTE 0, 8
COLOR 15, 0
_SCREENMOVE 10, 10
_DELAY .2
ml = 0: mr = ml
w = _WIDTH - (ml + mr)
DO
    _LIMIT 30
    x$ = "In West          Los      Angeles born    and raised,    at                    the yacht club is where I spent most of my days, 'til a couple of coders who were up to no good, started making trouble in my neighborhood. I got booted off Discord and my vids wouldn't play, so I moved to the hills in the State of VA. I pulled up to the forum 'bout a week into April and I yelled to the browser, 'Save password log in later!' Now I'm able to post and my speech is still free as I sit on my throne as the Prince of P.E."
    x$ = "In West Los Angeles born and raised, at the yacht club is where I spent most of my days, 'til a couple of coders who were up to no good, started making trouble in my neighborhood. I got booted off Discord and my vids wouldn't play, so I moved to the hills in the State of VA. I pulled up to the forum 'bout a week into April and I yelled to the browser, 'Save password log in later!' Now I'm able to post and my speech is still free as I sit on my throne as the Prince of P.E."
    w2 = w - (ml + mr)
    CLS
    LOCATE 2
    DO
        WHILE -1
            t$ = MID$(x$, 1, w2)
            chop = 1
            IF w2 <> 1 THEN
                DO
                    IF LEFT$(t$, 1) = " " THEN
                        ' Only happens with more than 1 space between characters.
                        IF LTRIM$(t$) = "" THEN EXIT DO ELSE x$ = LTRIM$(x$): EXIT WHILE
                    END IF

                    IF MID$(x$, w2 + 1, 1) <> " " AND LTRIM$(t$) <> "" THEN ' Now we have to chop it.
                        IF INSTR(x$, " ") > 1 AND INSTR(t$, " ") <> 0 AND LEN(x$) > w2 THEN
                            t$ = MID$(t$, 1, _INSTRREV(t$, " ") - 1)
                            chop = 2
                        END IF
                    ELSE
                        chop = 2
                    END IF
                    EXIT DO
                LOOP
                x$ = MID$(x$, LEN(t$) + chop)
            ELSE
                x$ = MID$(x$, LEN(t$) + 1)
            END IF
            IF LEN(t$) AND CSRLIN < _HEIGHT - 1 THEN LOCATE , ml + 1: PRINT LTRIM$(t$)
            EXIT WHILE
        WEND
    LOOP UNTIL LEN(t$) AND LEN(LTRIM$(x$)) = 0
    oldsw = Sw: oldsh = Sh
    IF _RESIZE THEN
        Sw = _RESIZEWIDTH \ _FONTWIDTH
        Sh = _RESIZEHEIGHT \ _FONTHEIGHT
        IF oldsw <> Sw OR oldsh <> Sh THEN
            w = Sw
            S& = _NEWIMAGE(Sw, Sh, 0)
            SCREEN S&
            _FONT font&
            PALETTE 0, 8
        END IF
    ELSE
        DO
            _LIMIT 30
            IF _RESIZE THEN EXIT DO
            b$ = INKEY$
            IF LEN(b$) THEN
                IF b$ = CHR$(27) THEN SYSTEM
                SELECT CASE MID$(b$, 2, 1)
                    CASE "M"
                        IF ml < _WIDTH \ 2 THEN ml = ml + 1: mr = mr + 1
                        EXIT DO
                    CASE "K"
                        IF ml > 0 THEN ml = ml - 1: mr = mr - 1
                        EXIT DO
                END SELECT
            END IF
        LOOP
    END IF
LOOP

Now before you get too excited... and we'll pause a moment so Steve can change his pants... this little routine just clears the screen on each resize. That means if we added vertical scrolling we would also have to build an algorithm to handle vertical positioning so we don't just always return to the start of the document every time the window gets resized.

Oh, now that Steve's back, yo can use the arrow left and right keys to increase and decrease the page margins.

I need sleep. I'm having too much fun coding stuff from the past all over again... Big Grin [Search Fresh Prince of Bel Air for ref to text].

Pete

Print this item

Question Lost keywords displayed by v1.1 changelog
Posted by: mnrvovrfc - 12-06-2022, 11:50 AM - Forum: Wiki Discussion - Replies (7)

I'm reacting to visionmercer posting the changelogs of v1.1 and v1.2. I was unable to find the following keywords in the Wiki:

- _SCALEDWIDTH
- _SCALEDHEIGHT
- _MOUSEPIPEOPEN
- _MOUSEINPUTPIPE
- _MOUSEPIPECLOSE

Do they exist or they never did? That list of keywords "new" for v1.1 must have been rambling but I created this thread to help clear any doubts.

Print this item

  Day 025: _CLIPBOARD$
Posted by: Pete - 12-06-2022, 06:34 AM - Forum: Keyword of the Day! - Replies (3)

_CLIPBOARD$ captures the string contents of the operating system clipboard contents.

The neat thing about this platform cross-compatible feature is the ability to use it outside the immediate program. I'll explain...

_CLIPBOARD$ can be used to capture any copied text from any running application. Once captured, the string can be used inside your app, or transferred to another QB64 app. _CLIPBOARD$ is therefore one of a few ways we can communicate with other QB64 programs running simultaneously. Now as exciting as that may be, the use of _CLIPBOARD, for inter-program communications, is somewhat frowned upon by Microsoft. The preferred M$ method is to establish a TCP/IP communications, which will be discussed a bit later along with piping to the clipboard using Windows SHELL command.

Right now, let's take a look at a copying, parse and print text example.

For this demo, start the app and then come back to this page, do Ctrl + A to copy all the tet, and Ctrl + C to copy it to the clipboard. Upon copying, the app will parse and display the clipboard text capture.

Code: (Select All)
$CONSOLE:ONLY
_CLIPBOARD$ = ""
COLOR 15, 1
CLS
PRINT " Copy the Keyword of the Day page..."
DO: _LIMIT 1: LOOP UNTIL LEN(_CLIPBOARD$)
CLS
a$ = _CLIPBOARD$ + CHR$(13)
DO
    x$ = MID$(a$, 1, INSTR(a$, CHR$(13)))
    a$ = LTRIM$(MID$(a$, LEN(x$) + 2))
    x$ = _TRIM$(MID$(x$, 1, INSTR(x$, CHR$(13)) - 1))
    IF LEN(x$) THEN
        IF MID$(x$, 1, 11) = "IP Address:" OR INSTR(x$, "AM") AND LEFT$(x$, 1) = "(" OR INSTR(x$, "PM") AND LEFT$(x$, 1) = "(" THEN pon = 0: spacer = 0
        IF pon THEN
            w = _WIDTH - 2
            IF MID$(a$, 1, 2) = CHR$(13) + CHR$(10) AND last = 0 THEN spacer = 1
            IF w > 0 THEN
                DO
                    t$ = MID$(x$, 1, w)
                    chop = 1
                    IF MID$(x$, w + 1, 1) <> " " THEN ' Now we have to chop it.
                        IF INSTR(x$, " ") > 1 AND INSTR(t$, " ") <> 0 AND LEN(x$) > w THEN
                            t$ = MID$(t$, 1, _INSTRREV(t$, " ") - 1)
                            chop = 2
                        END IF
                    ELSE
                        chop = 2
                    END IF
                    IF w = 1 THEN chop = 1
                    x$ = MID$(x$, LEN(t$) + chop)
                    '-----------------------------------------------------------------------
                    IF LEN(t$) THEN LOCATE , 2: PRINT LTRIM$(t$): IF spacer = 0 THEN last = 0
                    '-----------------------------------------------------------------------
                LOOP UNTIL LEN(t$) AND LEN(LTRIM$(x$)) = 0
                IF spacer = 1 THEN PRINT: spacer = 0
            END IF
        END IF
        IF INSTR(x$, ",") <> 0 AND INSTR(x$, "-") <> 0 THEN
            IF INSTR(x$, "AM") OR INSTR(x$, "PM") AND LEFT$(x$, 1) <> "(" THEN
                pon = 1
            END IF
        END IF
    ELSE

    END IF
LOOP UNTIL a$ = ""

PRINT: PRINT "Click the 'X' in the title bar to close this window."
DO: _LIMIT 1: SLEEP: LOOP

Okay, now how about we have a look at using _CLIPBOARD$ to make a small chat app...

For this demo you will need to save the second app as: "myclip.exe" and run the first app to access it.

Code: (Select All)
_SCREENMOVE 0, 0 ' Set up this host window to the left of your desktop.
WIDTH 60, 25
IF NOT _FILEEXISTS("myclip.exe") THEN PRINT "Cannot find file: "; "myclip.exe. Ending...": END
a$ = "Opening as host." '
PRINT a$: PRINT
SHELL _HIDE "start myclip.exe" ' Open the client window.
_SCREENCLICK 30 * 8, 10
PRINT "Connection established.": PRINT
DO
    _CLIPBOARD$ = ""
    ' Okay, time to input something on the host that will be communicated to the client.
    INPUT "Input a message: "; msg$: PRINT
    _CLIPBOARD$ = msg$
    _KEYCLEAR
    _DELAY 2
    _CLIPBOARD$ = ""
    DO: _LIMIT 5: LOOP UNTIL LEN(_CLIPBOARD$)
    _SCREENCLICK 30 * 8, 10
    PRINT "Reply received: "; _CLIPBOARD$: PRINT
LOOP

Save this as "myclip.exe" but don't run it. Run the first app (it doesn't matter if it's named) to start the chat sequence.
Code: (Select All)
_SCREENMOVE 60 * 8 + 10, 0 ' Set up this client window to the right of host.
WIDTH 60, 25
_CLIPBOARD$ = ""
a$ = "Opening as host." '
PRINT a$: PRINT
PRINT "Connection established.": PRINT
DO
    DO: _LIMIT 5: LOOP UNTIL LEN(_CLIPBOARD$)
    _SCREENCLICK 90 * 8, 10: _DELAY .25
    PRINT "Message received: "; _CLIPBOARD$: PRINT
    ' Okay, time to input something on the client that will be communicated to the host.
    INPUT "Input a message: "; msg$: PRINT
    _CLIPBOARD$ = msg$
    _KEYCLEAR
    _DELAY 2
    _CLIPBOARD$ = ""
LOOP

So M$ recommends using TCP/IP to accomplish what we just demoed with _CLIPBOARD. This example covers how to do that, but it's much more involved. Also, because it uses TCP/IP, you will have to clear it with Windows Defender.

This is a Windows only demo. It uses min/restore to regain focus to each window, instead of _SCREENCLICK like the _CLIPBOARD demo above. Save, but don't run the second app as "messenger_client.exe" then run the first one. Clear for use with Windows Defender when the alert pops up on your screen.

Code: (Select All)
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION FindWindowA%& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
    FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
    FUNCTION SetForegroundWindow%& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
    FUNCTION GetForegroundWindow%& 'Find currently focused process handle
END DECLARE

_SCREENMOVE 0, 0
title$ = "Messenger_Host"
_TITLE (title$)
_DELAY .1

_SCREENMOVE 0, 0 ' Set up this host window to the left of your desktop.
WIDTH 60, 25
IF NOT _FILEEXISTS("messenger_client.exe") THEN PRINT "Cannot find file: messenger_client.exe. Ending...": END
DIM host_msg AS STRING, client_msg AS STRING
DO
    IF initiate = 0 THEN ' This only needs to be performed once, to open the client window.
        DO UNTIL x ' Stay in loop until window determines if it is the host or client window.
            x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
            IF x = 0 THEN
                x = _OPENHOST("TCP/IP:1234") ' Note the host and clinet must have the same 1234 I.D. number.
                a$ = "Opening as host." ' x channel is now open and this window becomes the host.
            ELSE
                a$ = "Opening as client." ' Should not go here for this demo.
            END IF
            PRINT a$
        LOOP
        SHELL _HIDE _DONTWAIT "messenger_client.exe" ' Open the client window.
        initiate = -1 ' Switches this block statement off for all subsequent loops.
    END IF

    IF z = 0 THEN ' Initiates an open channel number when zero.
        DO
            z = _OPENCONNECTION(x) ' Checks if host is available to transfer data.
        LOOP UNTIL z
        PRINT "Connection established."
        _DELAY 1
        LOCATE 2: PRINT SPACE$(_WIDTH * 2) ' Remove these lines.
        LOCATE 3, 1
        GOSUB focus ' Sends focus back to host window.
    END IF

    ' Okay, time to input something on the host that will be communicated to the client.
    LINE INPUT "Message to client: "; host_msg: PRINT

    PUT #z, , host_msg ' Input is now entered into TCP/IP routine.

    DO
        GET #z, , client_msg
    LOOP UNTIL LEN(client_msg) ' Exits loop when a return msg is received.

    PRINT "Message from client: "; client_msg: PRINT

    host_msg = "": PUT #z, , host_msg$ ' Now put our client value back into the routine. Failure to do so would result in the client not waiting in the GET #x DO/LOOP.
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus
LOOP

focus:
DO UNTIL hwnd%&
    _LIMIT 10
    hwnd%& = FindWindowA(0, title$)
LOOP
FGwin%& = GetForegroundWindow%& 'get current process in focus.
_DELAY .1
IF FGwin%& <> hwnd%& THEN
    y& = ShowWindow&(hwnd%&, 0)
    y& = ShowWindow&(hwnd%&, 2)
    y& = ShowWindow&(hwnd%&, 9)
    DO
        _LIMIT 10
        FGwin%& = GetForegroundWindow%&
    LOOP UNTIL FGwin%& = hwnd%&
END IF
RETURN

This client app must be saved as: messenger_client.exe Run the first app after this app is saved.
Code: (Select All)
DECLARE DYNAMIC LIBRARY "user32"
    FUNCTION FindWindowA%& (BYVAL ClassName AS _OFFSET, WindowName$) 'handle by title
    FUNCTION ShowWindow& (BYVAL hwnd AS _OFFSET, BYVAL nCmdShow AS LONG) 'maximize process
    FUNCTION SetForegroundWindow%& (BYVAL hwnd AS _OFFSET) 'set foreground window process(focus)
    FUNCTION GetForegroundWindow%& 'Find currently focused process handle
END DECLARE

title$ = "Messenger_Client"
_TITLE (title$)
_DELAY .1

DIM host_msg AS STRING, client_msg AS STRING
_SCREENMOVE 600, 0 ' Set up this client window next to your host window.
WIDTH 50, 25
x = _OPENCLIENT("TCP/IP:1234:localhost") ' Used to establish a TCP/IP routine.
PRINT "Opened as client.": PRINT
DO UNTIL x = 0 ' Prevents running if this app is opened without using host.
    DO
        _LIMIT 30
        GET #x, , host_msg ' Waits until it receives message sent from the host.
    LOOP UNTIL LEN(host_msg)

    PRINT "Message from host: "; host_msg
    PRINT
    _KEYCLEAR ' Prevents typing before ready.

    GOSUB focus

    LINE INPUT "Message to host: "; client_msg: PRINT

    PUT #x, , client_msg
LOOP
END

focus:
DO UNTIL hwnd%&
    _LIMIT 10
    hwnd%& = FindWindowA(0, title$)
LOOP
FGwin%& = GetForegroundWindow%& 'get current process in focus.
_DELAY .1
IF FGwin%& <> hwnd%& THEN
    y& = ShowWindow&(hwnd%&, 0)
    y& = ShowWindow&(hwnd%&, 2)
    y& = ShowWindow&(hwnd%&, 9)
    DO
        _LIMIT 10
        FGwin%& = GetForegroundWindow%&
    LOOP UNTIL FGwin%& = hwnd%&
END IF
RETURN

PIPING:

In Windows, _CLIPBOARD can be used with SHELL to extract the directory contents. This method avoids then need to make and read temp file, which would be: SHELL _HIDE "dir /b *.bas>temp.tmp"

Windows Piping Example:
Code: (Select All)
$CONSOLE:ONLY
SHELL _HIDE "dir /b *.bas | clip"
PRINT _CLIPBOARD$

For Windows users, _CLIPBOARD can also be used with Win32API SENDKEYS, which allows you to use your program to copy text from other apps, instead of manually doing a copy to the clipboard. See my Sam-Clip thread for more info: https://staging.qb64phoenix.com/showthre...t=sam-clip

Pete

Print this item

  Old QB64.rip change logs
Posted by: SMcNeill - 12-06-2022, 05:01 AM - Forum: Learning Resources and Archives - Replies (2)

Code: (Select All)
# QB64 v2.0.x - What's new?

## New features
### All platforms
- New `$Debug` metacommand, with added breakpoint/step abilities and real-time variable watching to the IDE.
- Quick reference for commands is now shown in the status bar when syntax errors are detected.
- `_Source` is now also set to `_Console` when `$Console:Only` is used.
- Allows `Ctrl+\` to be used as a shortcut to repeat search (legacy QBasic shortcut).
- Functions `_MK$` and `_CV` can now deal with `_OFFSET` values.
- New "View on Wiki" button on help panel (launches equivalent wiki page using the default browser).
- New `_EnvironCount` function to show how many environment variables are found.
- Color schemes can now be set/saved individually for each running instance of the IDE.

### Windows
- Automatically embeds a manifest file when compiling an exe with `$VersionInfo`, so that Common Controls v6.0 gets linked at runtime.
- Adds the %TEMP%, Program Files and Program Files (x86) directories to `_Dir$()` folder specifications.

<!---
### macOS

### Linux
--->

## Fixes
### All platforms
- Improved wiki parser.
- Contextual menu would crash when right-clicking a series of high-ascii characters.
- Fixes an issue with passing an array as a Sub/Function argument (missing parenthesis now properly detected).
- Fixes `Clear` making `$Console` mode invalid.
- Fixes a syntax highlighter issue regarding scientific notation.
- Fixes an issue in Windows Vista and up with incorrect resolution returned on a scaled desktop.
- Fixes `Const` parser accepting unsupported string functions and failing with some very specific const names.
- Explicitly sets x87 fpu to extended precision mode.
- Removes 255-character limit for `Input/Line Input` with strings.
- Fixes `Data` commands failing to compile in some circumstances.
- `$NoPrefix`, `Option _Explicit` and `Option _ExplicitArray` can now be placed anywhere in a program, no longer having to be the first statement.
- Fixes `MEM` reverting to `_MEM` as a sub parameter in `$NoPrefix` mode.
- Fixes case adjustment of array names in `UBound`/`LBound` calls.
- Prevents users from creating self-referencing `Type` blocks.
- Fixes issue that prevented loading file names beginning with numbers.
- Fixes file open/save dialogs issue with path navigation.
- Complete rewrite of the internals for `Environ$()`.
- Fixes evaluation of valid var/flag names for `$Let`/`$If` - same rules for variable names now apply.
- Fixes incorrect parsing of `Type` blocks with multiple elements using the `AS type element-list` syntax.
- Fixes issue with `Put #` and variable-length strings in UDTs (`Binary` files).
- Fixes issue with recursive functions without parameters.

#### Fixed in 2.0.1
- Fix "Duplicate definition" error with Static arrays in Subs/Functions with active On Error trapping.
- Fix internal UDT arrays not resetting when a new file is loaded.
- Fix issue preventing `$Debug` from working in Windows versions prior to Windows 10.

#### Fixed in 2.0.2
- Fix issue with `LBound`/`UBound` calls in complex expressions.

### Windows
- Allows `$Console:Only` programs to return `_WindowHandle`.
- Saving a file to the root of a drive would display double backslashes in the Recent Files list.

### macOS
- Flushes the console output so `Print` can properly display text even while retaining the cursor.

#### Fixed in 2.0.2
- Fix issue preventing compilation in macOS versions prior to Catalina.

### Linux
- `xmessage` added to dependency list (setup script).
- Fixes `InKey$` acting too slow.
- Fixes compilation error with `Data` statements on gcc 11.
- Detects non-x86 based architectures.
- Flushes the console output so `Print` can properly display text even while retaining the cursor.


Code: (Select All)
QB64 v1.5 - What's new?

New features

All platforms
New _MEMSOUND function, that allows you to access raw audio data decoded by the _SNDOPEN function.
Added tiling support to PAINT for legacy SCREEN modes.
Holding CTRL while dragging colors sliders in RGB mixer locks all sliders together (useful for generating gray scale values).
Adds OPTION _EXPLICITARRAY - like OPTION _EXPLICIT but only makes array declaration mandatory, not regular variables.
EXIT SELECT/CASE implemented to allow breaking out of a SELECT CASE block or out of a CASE block, in case it's used in a SELECT EVERYCASE block.
New <New Folder> button in open/save dialogs.
Ability to disable the Syntax Highlighter entirely (Options menu).
New default color scheme "Super dark blue".
Adds Alt+F3 as a shortcut to Search->Change...
Adds Ctrl+F2 as a shortcut to clicking the "back" arrow (quick navigation).
New CTRL+K shortcut that allows you to insert _KEYHIT and _KEYDOWN codes easily.
Find and Change dialogs (Search menu) now allow you to ignore text in comments and strings - or search exclusively in comments or strings.
SUBs dialog (F2 key) now shows how many lines each procedure contains.
Adds ability to change color/cursor position in $CONSOLE mode in macOS and Linux.
Extends contextual menu (right click) to the Help area.
Warnings dialog now displays the correct line number if a warning refers to an $INCLUDE file.
New colorized output for command-line compilation.
New -w switch for command-line compilation to show warnings.
Revamped ASCII Chart dialog.
Rewritten Math Evaluator dialog.
Added dialog to show progress of updating help pages (Help->Update All Pages).
Menu items reorganized for clearer grouping. New Tools menu.
Menu items descriptions are now shown in the status bar.
New _ERRORMESSAGE$ function, to return a human-readable description of the most recent runtime error.
New $ERROR metacommand, which prevents compilation depending on an $IF precompiler block condition.
New VERSION precompiler variable which can be used to check the current version of QB64 being used.
Setting $CONSOLE:ONLY now automatically switches _DEST to _CONSOLE.
New alternative syntax for DIM, REDIM, SHARED, STATIC, COMMON, TYPE, that allows for less typing by grouping variables of the same type (like DIM AS INTEGER a, b, c, d, e, f, g '...)
Ability to have the IDE format keywords in camel case like _FullScreen instead of _FULLSCREEN (opt-out feature, check Options->Code Layout).
Menus items now have brief descriptions that get displayed in the status bar.
File menu now shows more recent files and the full path is displayed in the status bar.
Cursor shapes "HELP" and "WAIT" can now be set via _MOUSESHOW.

Fixes

All platforms
Fixed the QB4.5 binary format converter to allow some syntax blocks to be properly recognized.
Fixed an error that would prevent the QB4.5 binary format converter from being launched.
Allows the RGB mixer to be invoked with Alt+Enter when $NOPREFIX is used.
RGB mixer now inserts new color values even if _RGB32 is used with less than three parameters.
Fixes syntax highlighter for some corner case non-numbers being colorized - as well as some numbers not being colorized properly (scientific notation).
Fixes $CHECKING:OFF bug related to arrays with non-zero lower bound.
Fixes ENVIRON$() not working in some scenarios.
Fixes issue that allowed code in a SELECT CASE block but before a CASE condition.
Syntax Highlighter gets automatically disabled if rendering a page takes longer than a second.
Fixes a bug that wouldn't display the recent search history if it was too long and a help page was active.
Fixes _MOUSEMOVEMENTX and _MOUSEMOVEMENTY in Windows systems. Implements both commands for macOS and Linux (limited to the program window area).
Fixes SEEK not resetting EOF().
END/EXIT SUB/FUNCTION get correctly changed, like in QB4.5 (e.g. use EXIT SUB in a FUNCTION and it'll become EXIT FUNCTION).
CONST evaluator fixed to allow using existing constants in equations reliably.
$LET lines would be incorrectly indented in some scenarios.
Allows DATA to contain numbers with trailing data type markers, for retrocompatibility with QB4.5.
The IDE will now let you know early on that labels placed between Subs/Functions are not valid, instead of just crashing at C++ compilation. CONST statements are no longer accepted between Subs/Functions either (they would be accepted in previous versions, but inaccessible).
Classic metacommands parsing adapted to more closely behave like QB4.5.

Windows
Fixes a _LOADFONT issue when attempting to load a font from C:\Windows\Fonts when no path is passed.

macOS
The IDE would segfault at startup if the clipboard contained an image.
Fixed an issue that prevented the IDE window size to be restored from previous sessions and kept defaulting to 80x25.
Replaced all g++ and gcc calls with clang++ and clang, to prevent failures in some scenarios.
Fixes scaling for UHD/5K resolution systems.
Fixes an issue with variable-length strings in TYPEs.
Enables _SCREENX and _SCREENY to return the window position on the desktop. The IDE now properly stores its last position too.

Linux
Programs written for $CONSOLE:ONLY no longer pull in GL/X11 libs

Code: (Select All)
QB64 Version 1.4 - Changelog
First things first, we have moved development to a new GitHub repository. Follow us at https://github.com/QB64Team/qb64.
Although we don't follow a strict schedule regarding updates to QB64, every once in a while a feature that's been requested gets implemented or a new bug is found and then fixed, and eventually we have enough for a new release.
$NOPREFIX

One big change worth mentioning first, since it affects QB64 code from now on in a big way, is the new $NOPREFIX metacommand.

QB64-specific keywords, those that expand on the original set of keywords from QBasic/QuickBASIC 4.5, which we aim to replicate, are those that start with an underscore. It has been designed that way so that, in the event that you want to load an older program you wrote back in the day that had variables or procedures with identical names, they would not collide with the new keywords, making it possible to use QB64 entirely as you did with QBasic but also add the new functionality without breaking anything.
However, we have over the years been following our userbase create more and more programs that have no dependency whatsoever on older code, which means these aren't just QBasic programs with benefits, but actually QB64-native programs, written from scratch with QB64 in mind.
All that said, the new $NOPREFIX metacommand allows you, for the first time ever, to write QB64 programs without having to add the leading underscore to use the modern keywords.
That will allow code like this:

SCREEN _NEWIMAGE(800, 600, 32)
COLOR _RGB32(255), _RGB32(255, 0, 255)
m$ = "Hello, world!"
_PRINTSTRING ((_WIDTH - _PRINTWIDTH(m$)) \ 2, (_HEIGHT - _FONTHEIGHT) \ 2), m$

DO
    _DISPLAY
    _LIMIT 30
LOOP UNTIL _KEYHIT
To be written as:
$NOPREFIX
SCREEN NEWIMAGE(800, 600, 32)
COLOR RGB32(255), RGB32(255, 0, 255)
m$ = "Hello, world!"
PRINTSTRING ((WIDTH - PRINTWIDTH(m$)) \ 2, (HEIGHT - FONTHEIGHT) \ 2), m$

DO
    DISPLAY
    LIMIT 30
LOOP UNTIL KEYHIT
With the new metacommand in use, a program can both use _DISPLAY and DISPLAY, for example. User variables and procedures still cannot start with a single underscore (double underscores are accepted).
Here's the complete changelog for v1.4:

New features

All platforms

New $NOPREFIX metacommand.
New _DEFLATE$() and _INFLATE$() functions, that can be used to compress and decompress text or data strings using zlib, which has been added to our parts system.
New $ASSERTS metacommand and _ASSERT macro.
More bit-related functionality has been added: _READBIT, _SETBIT, _RESETBIT and _TOGGLEBIT.
You can now use _PUTIMAGE to place a portion of an image onto itself (source and destination can now be the same).
New $COLOR metacommand, which adds preset color constants based on HTML color names (per program).
Enhanced support for &B prefixed numbers, so the notation can now also be used in DATA lines and read by INPUT (from file & keyboard).

Windows

Enhancements to $CONSOLE: you can now use statements and functions you are already familiar with for SCREEN 0 but for console output. CSRLIN, POS(0), LOCATE, COLOR, _WIDTH, _HEIGHT, WIDTH (statement), CLS, SLEEP and END have all been reworked to deal with terminal output.
It is now possible to read input while working in $CONSOLE windows using _CONSOLEINPUT (for both keyboard and mouse support) and _CINP (to read individual key strokes).
You can now read the states of _CAPSLOCK, _NUMLOCK and _SCROLLLOCK keys, as well as set their states.

macOS

Basic detection of Retina displays has been implemented and programs should now render properly.

Fixes and improvements

All platforms

The warnings functionality can now be disabled (Options menu).
Numbers expressed in scientific notation now get properly colorized.
Enhanced "Open" and "Save as..." dialogs with added file list (save dialog) and support for wildcard filtering (* and ?).
Fixes a bug that would cause $INCLUDE lines to be duplicated in some scenarios.
Fixes a bug that wouldn't restore VIEW PRINT settings when RUN was called.

Linux

The IDE won't become unresponsive when the mouse pointer leaves the window anymore.

Windows

Fixes a bug that would prevent compilation when $EXEICON was used with $CHECKING:OFF set.
Fixed $VERSIONINFO so the embedded data gets properly displayed in newer versions of Windows.

Print this item

  QBASIC book by Tony Hawken (and maybe other resources too)
Posted by: moon cresta - 12-05-2022, 01:24 PM - Forum: Works in Progress - Replies (26)

Hello, this is my first post on the forum I think!

I got a Colour Maximite computer a few years ago, but didn't use it much until recently. I like the MMBASIC on it but there don't seem to be that many resources for learning it that I know of. Then I found out that MMBASIC is similar to QBASIC so I've been learning that for now instead. I'm interested in various types of BASIC, such as Locomotive BASIC on the Amstrad CPC, Atari BASIC on the Atari 8-bit computers... not a massive fan of Commodore 64 BASIC so far lol, although apparently it was designed to be more efficient, plus there are other forms of Commodore BASIC. 

So anyway, I'm learning QBASIC mainly from this book at the moment: "A course in programming with QBASIC" by Tony Hawken. I'm mainly using QB45 via DOSBOX on a Linux PC.. hopefully I'm still welcome on this forum, come to think of it lol. 

Hoping that posting here will help motivate me to learn BASIC quicker!

Print this item