QuickBasic Tips and Tricks
Beginner - Beginner+ - Intermediate - Advanced
Level 5 Expert. To top
Tip #LevelShort Description
Tip #49   5 Turning Numlock on/off
Tip #43   5 debugging a library written in asm. seeing what is happening
Tip #38   5 Long Filenames / EMS. See example downloads on the Files page.
Tip #33   5 Bloading color images in screen 12.
Tip #31   5 Translucency. How to do it.
Tip #26   5 Here's a way to have 16 color background in text mode.
Tip #16   5 An excellent routine for clearing a portion of the screen without clearing
screen. Fast and easy to implement. (also used for vertical scrolling)
Tip #10   5 Using Bload and Bsave to create tile based programs.
Level 4 Advanced. Up one Level or Top
Tip #LevelShort Description
Tip #46  4 How can I print in color on my printer
Tip #45  4 How can I print text in graphics and not have a black background color
Tip #41  4 Using 2 libraries
Tip #39  4 Change Text mode colors
Tip #34  4 Using com3 or com4 in QB (without a library).
Tip #30  4 Faster alternative for PSET
Tip #17  4 Placing sprites without erasing the background.
Tip #14   4 Flicker-free animation in Screen 13
Tip #13   4 Accessing ctrl and alt keys.
Tip #11   4 Changing the palette and stuff.
Tip #5   4 Making sub names shorter so they are easier to use.
Level 3 Intermediate. Up one Level or Top
Tip #LevelShort Description
Tip #51  3 Dollar and Cents manipulation
Tip #47  3 Accessing arrow and other keys
Tip #44  3 Clear a portion or all of a graphics mode screen quickly
Tip #32   3 Want a Quick and dirty way to play Wave files in Basic? (any size)
Tip #35   3 Another perhaps quicker way to play a wav
Tip #22   3 Just started using 4.5 and call absolute doesn't work ?
Tip #20   3 Horizontal scrolling made easy.
Tip #15   3 Using extended keys, ctrl, alt, shift, ect.
Tip #12   3 Clearing the keyboard buffer. Very usefull!
Tip #9   3 Disabling ctrl + break & ctrl + c.
Tip #7   3 Using commands to the Communications Port (modem) .
Level 2 Beginner + Up one Level or Top
Tip #LevelShort Description
Tip #48  2 Place markers for editing programs
Tip #42   2 Using Files
Tip #40   2 Centering Text
Tip #37   2 Speeding up your programs. For loops
Tip #28   2 Speeding up your programs. More
Tip #27   2 Is there a way to "hide" input ?
Tip #25   2 Program template. Organize your program
Tip #24   2 Close your files.
Tip #21   2 Speeding up your programs.
Tip #8   2 Rebooting the computer.
Tip #6   2 An easier way of telling if a number is divisible by another number.
Tip #4   2 Organizing numbers from least to greatest.
Tip #3   2 Faster and more efficient suppliment for inkey$.
Tip #1   2 Checking to see if a number is divisible by another number.
Level 1 Beginner. Up one Level or Top
Tip #LevelShort Description
Tip #50   1 Why do i get "Bad File Mode" when I try to load certain programs ?
Tip #36   1 Speed up your math by using variable types.
Tip #29   1 Correct spelling of statements
Tip #23   1 Using GOTO.
Tip #2   1 Shortcut for print.
Tip #18   1 Debugging your programs.
Tip #19   1 Search for what you need.

Tip #19
 Use Alt+S to Search for whatever you  need. You can  do this in the
 Help also. Just Shift+F1 then Alt+S and enter the search word. Then
 F3 to find the next occurrance. (Of course you can use the mouse if
 you like). You can even copy code from the help with shift+(down/up
 arrow) then Ctrl+Insert.Then position the cursor where you want the
 code copied and press Shift +insert.

Tip by Buff 

Click here to goto the top.

Tip #18
 Use Function keys for quick debugging. F9 will highlight a line and
 the program will pause when it gets to that line. F8 will allow you
 to step through the program one line at a time, F5, of course, runs
 the program.See the other debugging tools with Alt+D like Add Watch
 so you can see the value of variables as you step through the prog.

Tip by Buff 

Click here to goto the top.

Tip #46
 Printing in color to a printer is not difficult.
 For simplicity, I will only describe text printing in color here.
 Under Windows, the printer port should provide DOS capture which
 essentially means the windows driver is bypassed.

 The most common codes for printing in color on printers are:
 1) Epson codes and 2) PCL for HP compatible inkjets, etc.

EPSON:
======
 For epson the code sequence Esc r color is sent to the printer
 to change colors. print #printer%, CHR$(27)+"r"+CHR$(colour)
 where colour is 1-6 >>0=black, 1=magenta 2=cyan 3=violet
 4=yellow 5=orange 6=green.
 (there may be more).
 Example code:
 open "LPT1:" for output as #16
 width #16,255
 print #16,chr$(27)+"r"+chr$(1)
 print "This Text is magenta i.e. a red"
 
for more epson codes
HP compatible: -------------- For HP compatible printers the idea is the same, just the code sequece that is different. Try one or all of the following to see if it prints in color on your PRINT #16, CHR$(27) + "&v1S1) 1200/1600 Series"; CHR$(27) + "&v0S" PRINT #16, CHR$(27) + "*v1S2) 500 Series "; CHR$(27) + "*v0S" PRINT #16, CHR$(27) + "*v12S3) 600 Series "; CHR$(27) + "*v0S" PRINT #16, CHR$(27) + "*r-4U" + CHR$(27) + "*v1S" + "4) PCL 5"; CHR$(27) + "*v0S" ----------------------------------------------------------------------- The color number follows the lowercase v and before the uppercase S. ----------------------------------------------------------------------- Other possibilities for the lead-in sequence are: chr$(27)+"*r3U"+chr$(27)+"*v1S" chr$(27)+"*r-3U"+chr$(27)+"*v1S" chr$(27)+"*r2U"+chr$(27)+"*v1S" chr$(27)+"*r4U"+chr$(27)+"*v1S" ------------------------------------------------------------------------ IMPORTANT !!! : PCL is very case Sensitive. A capital letter in an escape sequence designates the end of the sequence. A lowercase letter means it's not the end of the sequence. If you try a sequence and it doesn't work, you should probably reset the printer before trying a different sequence. For more on PCL click here ------------------------------------------------------------------------ Tip by Buff

Click here to goto the Advancved list.
Tip #45
 There are several ways to print text on a graphics screen while
 retaining the background color. Here are two of them.

 Using a font routine.
 You can use the Draw command and make your own font to print characters
 on the screen. You will need to call the routine for each character in
 the string. In the font routine, you can have a select case routine for
 each character required and under the case use a draw command.

 Using a call interrupt. You can also xor the characters onto the screen
 using call interrupt. This will however be limited to the default font.
 See the explanations of interrupts on the download page. Interrupt &H10
 AX=1300H or see my instald6 installation demo on the download page and
 look at the colrprnt subroutine

Tip by Buff 

Click here to goto the Advancved list.

Tip #41

You don't combine two (or more) .QLB files.
However, you may have regular libraries (.LIB files) associated with
your quick libraries. Let's say you have LIB1.LIB and LIB2.LIB (and
they're associated, respectively, with LIB1.QLB and LIB2.QLB).
First, combine the two .LIB files into COMB.LIB (use whatever names
that suit your situation):

LIB COMB +LIB1.LIB +LIB2.LIB;

Now that you've got COMB.LIB, you can make COMB.QLB:

LINK /Q COMB.LIB, COMB,, BQLB45;

(the semicolons are important)

Tip by Glenn 

Click here to goto the Advanced list.

Tip #39
  You can change the screen color 0-15 even in screen 0 using Palette
  This makes it possible to do black on bright white without using
  an interrupt call (of course one color will change).
  screen 0
  palette 7,63
  color 0,7
  print "this is a test"
  (palette color,number)
  color or attribute is 0-15 number is 0-63

Tip by Buff 

Click here to goto the Advancved list.

Tip #34
 This is kinda controversial in that some say it works and some say it
 doesn't. Personally I never got it to work, but have talked to and seen
 posts from people who said it does. so here it is.
 Basically you are changing the memory value in the bios. This should be
 done with caution because it needs to be reset to the original values
 when the program is done or encounters an error.
   
    IF i.peeked% = 0 THEN
        DEF SEG = &H40
        Oldport1H = PEEK(&H0)
        Oldport1L = PEEK(&H1)
        Oldport2H = PEEK(&H2)
        Oldport2L = PEEK(&H3)
        DEF SEG
        i.peeked% = -1
'Sets up the comport by swapping the address for com4 with com2 and
'com3 with com1 if necessary
        DEF SEG=&H40
        POKE &H0, &HE8
        POKE &H1, 3
'these above replace com1 value with com3
        POKE &H2, &HE8
        POKE &H3, 2
'these above replace com2 value with com4
        DEF SEG
    END IF
Now open com1 or com2 as before and it should use com3 or com4.
Be sure to restore the old values (Oldport...) before exiting !!
Tip from Buff (several sources) 
Click here to goto the Advanced list.

Tip #30
Here's the fast way of doing PSET:

DEF SEG = &HA000 
POKE y * 320& + x, colour 
DEF SEG 

The DEF SEG switches the segment over to the graphics
buffer, and the POKE places the pixel of color "colour"
at position x,y. This is up to twice as fast as PSET. 

Tip from http://qbtm.quickbasic.com/ 
Click here to goto the Advanced list.

Tip #17
To use sprites, but avoid erasing the background, use 3 sprites for the
character, as follows:
Buffer%() - This stores the previous screen contents< Mask%() - This is a mask sprite. All visible areas of actual sprite must be black on mask. All invisible areas must be highest colour available (255 in SCREEN 13, 16 in SCREEN 12, etc.) Sprite%() - This is the sprite. Make all background black, as well as black parts of sprite.
Then put them into your program, as follows: WAIT &H3DA,8 -Wait for vertical refresh PUT (oldx,oldy),buffer%,PSET -Replace old screen location GET (x1,y1)-(x2,y2),buffer% -Get new buffer sprite PUT (x,y),mask%,AND -AND the mask with the new background, 'creating a black 'hole' PUT (x,y),sprite%,OR -OR the sprite with the hole, leaving 'background intact. Tip by Craig Andrews Courtesy QBtop50
Click here to goto the Advanced list.

Tip #49
 Turning the Numlock key on and off.

'  Small code for switching NUMLOCK on and off
'  
'  by Rolf Genster on 01/19/96
'
'  Bit 6 : Caps Lock
'  Bit 5 : Num Lock           1 = active, 0 = off
'  Bit 4 : Scroll Lock


'  Code for MS-Basics would look like:
       POKE &H417, PEEK(&H417) OR 32       'NUM-Lock on
'     or
       POKE &H417, PEEK(&H417) AND NOT 32  'NUM-Lock off

Click here to goto the top.

Tip #43
   Here is a quick tip which everyone who writes ASM for QB should know!
   If you put an INT 3h into you're code, you can use DEBUG to watch
   exactly what you're code is doing. Just load QB like this:

        DEBUG C:\QB\QB.EXE /L YOURLIB.LIB

   Then write you're code and run it. As soon as INT 3h is called,
   DEBUG will be loaded and from there you can use the P command to go
   through all you're code. To start you're code running again, just hit G.

   Terminator_Z's super tips, you're easier guide to a better life...

Tip from Terminator_Z

Click here to goto the top.

Tip #33
  Whenever I bload an image in screen 12, it is in black
  and white.  what can i  do to change this ? Screen 12
  and others load a red, green and blue layer. These together
  make a black and white image. Try playing with the following
  code. I havent mastered it yet, but some more information
  on it can be found at Pete Swinkels page (see below or links
  page). The addresses should remain the same, just change the
  numbers at the right. I will update this as i learn more about
  it. Keep a backup copy of your bload file in case.

        DEF SEG = &HA000

        OUT 964, 2
        OUT 965, 9'1
    'these first 2 have to do with writting i think whereas the
    'next 2 have to do with reading.
        OUT 974, 4
        OUT 975, 1' bit plane number .
      
        BLOAD "picture.nam", offset%
        DEF SEG
    You may be able to load it by just using the 975 address and
    varying  the number so you get the color you want.
    You may also be able to use the translucency tip since the
    addresses are similar. (one hex and above decimal).

Tip from Buff
Pete's info on screen 12 bload

Click here to goto the top.

Tip #31
'So how do we do translucency?
'Rather than waste a lot of memory on something like alpha blending,
'we can simply use a look-up  table. Here's how it works, and  why
'gradients are so important.

DIM SHARED transluc(256) 

'Create the array for the look up table 

FOR i = 0 TO 255 
  boog = 0 

'Start the FOR/NEXT to go through all the colors. "boog" is just a
'sloppy placeholder to know if we've already got something in the array.
'There are better ways to code this =). 
  OUT &H3C7, i 
  rd = INP(&H3C9) 
  gr = INP(&H3C9) 
  bl = INP(&H3C9) 

'&H3C7 gives me access to the palette at number i (which is specified in
'the loop as something from 0 to 255). rd, gr, and bl are the RGB values
'for the said number. 

  IF rd >= bl AND rd >= gr THEN 
    transluc(i) = FIX(rd / 4) 
    boog = 1 
  END IF 

'Is the value for Red the highest of the three RGB's? We're trying
'to find the highest RGB value. If it is, we add the Red value to
'the array, and set boog to 1 so it's not overwritten. 

  IF bl >= AND boog <> 1 THEN 
    transluc(i) = FIX(bl / 4) 
    boog = 1 

'Is blue the highest? Then add it to the array. 

  ELSEIF boog <> 1 THEN 
    transluc(i) = FIX(gr / 4) 
  END IF 
NEXT 

'If green is highest, add it to the array, and go to the next color. 

'You only need to do this once, at the start of your program.
'The number in the array for each color now is from 0 to 15
'(16 colors, which is why I said to divide your palette's
'main colors into blocks of 16). So now, we need to decide
'what the "translucent color" will be. The picture above
'used white, but you can make it blue, green, brown, whatever.
'Here's how:

transcol = POINT(x,y) 
DEF SEG = &HA000 
POKE y * 320& + x, transluc(transcol + start_of_col) 
DEF SEG 

'So, what are we doing here? We're simply getting the color of a
'point we want to put the translucency over, then poke psetting
'from the array we created earlier a new color. So, for instance,
'let's say colors 30 to 45 were dark grey to white. We'd simply
'use 30 as "start_of_col" and there we go! Translucency for 256
'bytes!

Tip from http://qbtm.quickbasic.com/

Click here to goto the top.

Tip #26
 Here's a way to have 16 BACKGROUND colors in TEXT mode. Only 1 catch.
 You cannot use PRINT. PRINT will  change High intensity  background
 (9-15) to blinking low intensity. So, included is a printstring sub
 to  print text/ textgraphics with this high intensity background
 
'SUB bright (xxon%, xxoff%) STATIC
        SHARED inreg AS regtype
        SHARED outreg AS regtype
        SHARED cm$  'cm$="Y" if color monitor set in your program N=mono
        IF cm$ <> "Y" THEN EXIT SUB 'DEF
        inreg.AX = &H1200 : inreg.BX = &H10 : inreg.CX = &HFFFF
        CALL interrupt(&H10, inreg, outreg)
        IF outreg.CX = &HFFFF THEN
            cga% = -1
        ELSE
            ega% = -1
        END IF
        MODEREG = &H3D8:
        '  colorreg = &H3D9 'control registers
        MODESAVE = &H465
        ': colorsave = &H466 'BIOS saves the regs here
        IF xxon% THEN
            IF cga% THEN
                DEF SEG = 0
                smode = 9 'High resolution
                POKE MODESAVE, smode: OUT MODEREG, smode
                DEF SEG
            END IF
            IF ega% THEN
                inreg.AX = &H1003 : inreg.BX = &H0
                CALL INTERRUPTX(&H10, inreg, outreg)
            END IF
         END IF
         IF xxoff% THEN
            IF cga% THEN
                DEF SEG = 0
                smode = 41 'Blink restored
                POKE MODESAVE, smode: OUT MODEREG, smode
                DEF SEG
            END IF
            IF ega% THEN
                inreg.AX = &H1003 : inreg.BX = &H1
                CALL INTERRUPTX(&H10, inreg, outreg)
            END IF
         END IF
'INT 10 - VIDEO - TOGGLE INTENSITY/BLINKING BIT (EGA, VGA)
'    AX = 1003h  BL = 00h enable intensity  BL = 01h enable blink

'END SUB

'here is the printstring sub.Row,col(umn), st$=string to print
'bg%=background color, fg%=foreground color
DEFINT A-Z
'SUB printstring (st$, cm$, Row%, col%, cga%, ega%, scn%, _
 'bg%, fg%) STATIC
REM -- remove the or ega% to test ega/vga mode
        SHARED inreg AS regtype
        SHARED outreg AS regtype
        IF cm$ <> "Y" THEN
            LOCATE Row%, col% + col.offset%: PRINT st$;
            EXIT SUB
        END IF
        inreg.AX = &H1300
        IF fg% + bg% <> 0 THEN
            inreg.BX = (scn% * 256) + (bg% * 16) + fg%
        ELSE
            inreg.BX = scn% * 256 + 240''240=&HF0 '''&H2F0
        END IF
        inreg.CX = LEN(st$) : inreg.ES = VARSEG(st$)
        inreg.BP = SADD(st$)
        inreg.DX = ((Row% - 1) * 256) + col% + col.offset% - 1
        CALL interrupt(&H10, inreg, outreg)
'END SUB

Tip by Buff 

Click here to goto the top.

Tip #16
 Want to clear a portion of the screen,  but for loops take
 too long ? try this:
 1) load qb (4.5) with the /Lqb.qlb option >QB /LQB.QLB
  (or just QB /L) this loads the default quick library
  containing interrupt routines, and absolute routines.
 2) in the main body of the program

 Define the type needed for INTERUPTX

 TYPE RegTypeX
  Ax AS INTEGER
  Bx AS INTEGER
  Cx AS INTEGER
  Dx AS INTEGER
  bp AS INTEGER
  si AS INTEGER
  di AS INTEGER
  flags AS INTEGER
  ds AS INTEGER
  es AS INTEGER
 END TYPE
 DIM Regs AS RegTypeX

 3) Now enter the following SUB (Alt-E New Subs)

 DEFINT A-Z
 SUB clearscreen (c%, R%, ec%, Br%, clr%,lns%) STATIC
  SHARED Regs AS RegTypeX
  Regs.Ax = &H600
  IF LNS%>0 then Regs.AX=Regs.AX+lns%
''Note by using 601-625 you can use it to scroll the number of lines
''AL=number of lines AH=6
''by using AH=7 AL=number of lines you can scroll down.
''either result in clearing the window if number of lines (AL) is 0.
  IF clr% < 1000 THEN
    cl& = clr%
    a& = cl& * 4096
    IF a& > 32767 THEN a = a& - 65536 ELSE a = a&
    Regs.Bx = a
  ELSE
    Regs.Bx = clr%
  END IF
  Regs.Cx = (R% * 256&) + c% - 257
  Regs.Dx = (Br% * 256&) + ec% - 257

  CALL INTERRUPTX(&H10, Regs, Regs)

 END SUB

 4) then to clear the portion of the screen
 CALL clearscreen colum%, Row%, endingcolum%, Bottomrow%, colour%, LNS%

 just be sure colum%,Row%,endingcolum%,
 Bottomrow%,and colour% and LNS% are defined. LNS%=0 clears the window.

Tip by Buff 

Click here to goto the top.

Tip #51

Dollars and Cents
-----------------
Rounding to Dollars and Cents can be a problem in Qbasic or QuickBasic
4.x and before. PDS (QuickBasic 7.x) has a currency floating point that
is a help in this (4 decimal places). When using a version prior to
PDS or even with PDS and wanting to be sure of 2 decimal places there
are several ways to go about it.

My personal preference is using variables call Dollar& and Cents&.
As can be seen, these are long integers. The way this works is to
enter a numeric string, lets call it AMT$.

Dollar&=Val(Amt$)
Cents&=(Val(Amt$)-Dollar&)*100
To print it:
print ltrim$(str$(Dollar&));".";right$("00"+ltrim$(str$(Cents&)),2)
or
print using "######.##";Dollar&+Cents&/100

To Store it in a file:

Be careful here, however, because cents& could conceivable be negative.

If Cents&<0 then
 Dollar&=Dollar&-1
 Cents&=Cents&+100
end if
st$=MKL$(Dollar&)+chr$(cents&)

after reading it in from a file:
Dollar&=CVL(mid$(st$,1,4))
Cents&=ASC(mid$(st$,5,1))

A function can be created to handle these or other way to deal with it,
including printing to a file with a using statement then reading it
back in.
Tip by Buff

Click here to return to Intermediate.

Tip #47

   Here is a simple snippet to access some of the major keys (nonalphanumeric).
   Many are chr$(0)+another character
   DO
     x$=inkey$
     if len(x$)=2 then
       if asc(left$(x$,1))=0 then    'is the left character chr$(0) ?
          test%=asc(right$(x$,1))    'yes so what is asc val of right chr$
          select case test%
           case 59 'F1
           case 60 'F2
           case 61 'F3
           case 62 'F4
           case 63 'F5
           case 64 'F6
           case 65 'F7
           case 66 'F8
           case 67 'F9
           case 68 'F10
           case 133 'F11
           case 134 'F12
           case 83 'Del
           case 82 'Insert
           case 71 'home
           case 79 'End
           case 73 'PGUP
           case 81 'PGDN
           case 80 'Down Arrow
           case 72 'Up Arrow
           case 75 'Left arrow
           case 77 'right arrow
           case else
          end select
       end if
     end if
  loop while x$<>chr$(27) 'while escape not pressed
'put any code for the particular key right after the case statement

Tip by Buff and Dan

Click here to return to Intermediate.

Tip #44

    Clear all or a portion of a graphics screen quickly
    LINE (topleft,toprow)-(bottomright,bottomrow),BF,colour

    topleft,toprow,bottomright,bottomrow are pixel points (dots position)
    0,0 is upper left of screen or window
    maximum for bottom will depend on graphics mode

    colour is the color number to paint the inside of the cleared area.
    BF is Box Filled
Tip by Buff

Click here to return to Intermediate.

Tip #32
    To play any wav file from bas

    SHELL "start /m sndrec32.exe /play /close [path\wavfile.wav]"

    (Win9x)
    where [path\wavefile.wav] is the folder/directory and name of
    the wave file to be played. You may have to tweak this
    depending on what your path environment contains. sndrec32
    should be in \windows folder.


Tip found (and tested) on a Qboard Post 1999

Click here to return to advanced.

Tip #35
    Here is another way to play any wav file from bas. Perhaps quicker
    than tip 32.

    first$ = "rundll mmsystem,sndPlaySound "
    wavfile$ = "C:\WINDOWS\MEDIA\TADA.WAV"
    SHELL first$ + wavfile

    (Win9x)
Tip found on a BlueTek Qboard Post 1999
from Vyrlngo (no email address)

Click here to return to advanced.

Tip #22
 For Call Absolute and Call Interrupt to work in QB 4.5 you
 must use a QLB (quick library) containing 1 or both of these
 procedures that you need. The default library QB.QLB can be
 loaded  by using >QB /LQB or, simply, >QB/L (> is the dos
 prompt). The type defs for call interrupt are in the QB.BI file.

Tip by Buff

Click here to return to advanced.

Tip #20
 For Horizontal scrolling the easy way use a variation of
 the following: text$="This is the text message I want
 to scroll across the screen."
  for k=1 to len(text$)
   locate 12,70-k
   print mid$(text$,1,k);" ";
   ''put a pause routine here to slow scrolling
 next k
'to scroll text off the page include the following also.
 for k=1 to len(text$)+1
    locate 12,70-len(text$)
    print mid$(text$+" ",k);space$(k);
    ''put a pause routine here to slow scrolling
 next k
 This can also be used for multiple lines by using several
 variables, and locating on a different line for each line
 of text. With today's fast computers, this will do the job
 well.

Tip by Buff

Click here to return to advanced.

Tip #15
Here's another way, perhaps easier, (at least to understand)
to access Ctl,Alt and other keys too (find if they've been
pressed)

'check key status for several keys 
    DEF SEG = 0
    KeyStatus = PEEK(1047) ''or &H417
'
'This is where the key status is stored. The values are:
'
'(INS 128  'CAPS 64  'NUM 32 'SCROLL 16
'ALT 8 'CTRL 4 'RSHIFT 2 'LSHIFT 1)
    IF KeyStatus > 127 THEN _
         KeyStatus = KeyStatus - 128: InsertStatus = 1
    IF KeyStatus > 63 THEN  _
         KeyStatus = KeyStatus - 64 : CapsStatus = 1
    IF KeyStatus > 31 THEN  _
         KeyStatus = KeyStatus - 32 : NumStatus = 1
    IF KeyStatus > 15 THEN  _
         KeyStatus = KeyStatus - 16 : ScrollStatus = 1
    IF KeyStatus > 7 THEN   _
         KeyStatus = KeyStatus - 8 : altstatus = 1
    IF KeyStatus > 3 THEN   _
         KeyStatus = KeyStatus - 4 : CtrlStatus = 1
    IF KeyStatus > 1 THEN   _
         KeyStatus = KeyStatus - 2 : RShiftStatus = 1
    IF KeyStatus = 1 THEN      _
         KeyStatus = KeyStatus - 1 : LShiftStatus = 1
    DEF SEG
_ indicates that the line continues on the next line
Tip by Buff

Click here to goto the top.

Tip #14
When doing sprite animation in screen 13, it can be tough
to avoid flicker because you can't do page flipping (because
basic only gives access to one page). But, it can be done!
By waiting for the monitor's verticle retrace. On my
486dx2-66 running Win95 (which slows down the DOS boxes),
I can have 6-7 15x15 sprites moving around at maximum speed
without flicker. Another advantage of waiting for the retrace
is that it makes your games/graphics programs universal--it
will run the same speed on all machines. Here's how it's done:

SCREEN 13
... Load your sprites ...

x=0:y=0
DO
    WAIT &H3DA, 8 '*** Wait for verticle retrace
    PUT(x, y), null '*** A blank black box the size
'*** of sprite() to wipe out our last location
    x = x + 1
    PUT(x, y), sprite '*** Move our sprite.
LOOP UNTIL INKEY$ = CHR$(27)

Tip by Jon Leger & Jorden Chamid
Click here to goto the top.

Tip #13
You know the problem, that you can't handle the ALT
or CTRL keys with QBasic. Now here is a solution for
all, who want access these special keys.


CLS
 DEF SEG = &H40

 WHILE INKEY$ <> CHR$(27)
    first% = PEEK(&H17)
    'read first statusbyte on offsetadress hex 17
    second% = PEEK(&H18)
    'and second on offset hex 18
    PRINT "First statusbyte: "; _
      first%, "Second statusbyte: "; second%
 WEND

 DEF SEG 'restore QBasic datasegment

 Don't quite understand this? Email the author Ingmar Neuwirth 


Tip by Ingmar Neuwirth

Click here to goto the top.

Tip #12
 Do you have a game or program where the user has to hold down the
 key for a long time and little beeps start? Or you have a game
 that you wish was more responsive to the keyboard? Here's the
 answer: clearing the keyboard buffer!! To do this type in:

 DEF SEG=0: POKE &H41A, PEEK (&H41C) : DEF SEG


Tip by Ross Taylor - Sir Taylor's Big Heap 'o Junk

Click here to goto the top.

Tip #11
Wanna Change the palette really fast....

don't use the PALETTE command.

EXAMPLE:

SCREEN 13
 FOR x = 0 TO 254 ' not 255 it's the default background color
    OUT &H3C7, x ' <-- is the Color Number
    OUT &H3C9, x * .25
    ' <-- This is the Red value for the above color Num
    OUT &H3C9, 0
    '<-- This is the Green value for the above color Number
    OUT &H3C9, 0
    '<-- This is the Blue value for the above color Number
 NEXT x

 FOR y = 0 TO 255
    LINE (y,0)-(y,200)
 NEXT y

If you multiply x * .25 like i did it makes a gradient fill
of the entire 254 colors in the palette in the example it
makes a Black to Red Gradient.

Didn't quite understand this? Email the author JavaJester 

Tip by JavaJester - Solstice Development
Click here to goto the top.

Tip #10
When creating Tile-Based Programs. BSAVE and BLOAD, this saves
HD space. And store tiles in one array.

    GET (0, 0)-(15, 15), tile
    DEF SEG=VARSEG(tile(0))
    BSAVE TileName$, VARPTR(tile(0)), arraysize x 2
'*******SAVE TILES

'*********** LOAD AND STORE TILES ************
    DIM SHARED Tiles%(arraysize, num of tiles) 
    DIM SHARED Tile(arraysize / 2)

    FOR Num%=1 to TileNum
        TilName$= "T"+ LTRIM$(STR$(Num%)) + ".til"
        DEF SEG=VARSEG(tile(0)):BLOAD TileName$, VARPTR(tile(0)) 
        PUT (0, 0), tile, PSET
        GET (0, 0)-(15, 15), Tiles%(arraysize / 2, Num%)
    NEXT Num%

Didn't quite understand this? Email the author Exodus 

Tip by Exodus - Excalibur Entertainment
Click here to goto the top.

Tip #9
 It will disable the CTRL+BREAK and CTRL+C functions. Remember to make
 some function to quit the program before starting it with this code.

    DEF SEG = 0
    FOR Z = 0 TO 3
        POKE (108 + Z), PEEK (112 + Z)
    NEXT 

Tip by Dave Stewart - Taken from The QBasic Site


Click here to goto the top.

Tip #48

Using placemarkers in text - editing hint

-----------------------------------------------------------

 I came across an interesting hint in my QuickBasic manual,
 in case you might not already know about it. It also works
 in QBasic. There's no message or other indication when you
 press CTRL+K to set it, but it jumps to your placemarker
 when you press CTRL+Q from another part of the text. The
 following passage is a direct quote from the manual:

 If you are working on different parts of a large program,
 you can tell QB to remember where in the program you are
 working (set a "placemarker"). This makes it possible to
 jump between different markers as needed. You can set up
 to four placemarkers, numbered 0-3, anywhere in your program.

 Follow these steps to use placemarkers:

 Put the cursor on the line you want to mark. Press CTRL+K and
 then n to set placemarker number n.

 Press CTRL+Q and then n to move to placemarker number n.

Tip from Solitaire
Click here to goto the top.

Tip #42

    ******USING FILES********
    open filename$ for [mode] as #file%
    filename can be a litteral or put in a variable as above. Using a
    variable has the advantage of easier to use in an error routine.
    the mode can be INPUT, OUTPUT or APPEND (others not discussed at
    this level). INPUT can only be used for "reading" with an input #
    or Line Input # statement and will result in an error if opened
    when it does not exist. Append will add any data to the end of the
    file "appending" while keeping what was in the file before.
    Output will clear the file of any data that was in the file previously.
    example program:
    ----------------
    open "my.txt" for ourput as #1
    print #1,"TESTing files"
    close #1
    open "my.txt" for input as #1
    input #1,LL$
    print LL$
    close #1
    input "",z$   : REM -- this used to stop the program so you can
                    REM   see the display.
    ------------------
    this will print "TESTing files" on the screen
Tip from Buff
Click here to goto the top.

Tip #40

     To center text on the screen use either
     x%=(LL%-len(text$))/2
     or
     x%=LL%/2 - len(text$)/2
     (x% is the x coordinate for your locate, LL% is
     line length  typically 80 for text mode).
     example:
     text$="THIS IS A TEST"
     x%=(80-len(text$))/2
     locate y%,x%:print text$
Tip from Buff
Click here to goto the top.

Tip #37

     When using for loops:
         for x% =1 to 100
            ....code...
         next
      is faster than
         for x% =1 to 100
            ....code...
         next x%
    However, it can be harder to debug.
    Also, using integers for for loops will speed up loops.
    that is, for x = 1 to 100
     If x is a single precision the loop will go slower than
             for x% = 1 to 100

Tip from simply qb

Click here to goto the top.

Tip #28
   It is said that using Select Case is faster than using multiple IF
   statements. We will Add more here as we find good ones for you.

Tip by Buff

Click here to goto the top.

Tip #27
 Concealing (hiding) input in QB.
 This is ideal for passwords or anything that needs to be hidden.
 This is a very simple routine as shown and can be embellished to
 check all kinds of things.
 ans$="":x$=""
 while x$=""
    x$=inkey$
    if x$>chr$(28) then ans$=ans$+x$:print "*";:x$=""
 wend
 (it does not check for backspace (chr$(8)) but that and anything else
 can be put in this routine as needed).

Tip by Buff

Click here to goto the top.

Tip #25
 Organize your program for easy reading/debugging with the following
 template.
 ----------
 DECLAREs     -
 COMMONs       |
 TYPE DEFs     | - start with these type statements if applicable.
 DIMs          |
 CONSTs        -

 MAIN.ROUTINE:
   gosub INIT 'initialize variables
   gosub SCREEN.DISPLAY
   gosub PROCESS.INFO
   gosub PRINT.REPORT
 END.ROUTINE:
   close
   chain/end/stop/system statment(s)

 INIT:
   on error goto error.routine
   MSK1$="##,###.##" 'example mask to be used with print using
   RETURN

 SCREEN.DISPLAY:
   'put your screen here
   RETURN

 PROCESS.INFO:
   'primary input or other routine
   RETURN

 PRINT.REPORT:
   'print any reports here
   RETURN

 ERROR.ROUTINE:
   SELECT CASE ERR
     case
     case else
   END SELECT
   'additional resumes/end close statements

Tip by Buff

Click here to goto the top.

Tip #24

 Be sure to Close all files when exiting a program either with
 the CLOSE statement by itself (closes all open files) or close
 #filenum for each file opened. This can be expecially critical
 if you have files opened for output, binary, or randomw.
 (Include an error routine that closes all files if there is no
 resume to a certain point in the program).

Tip by Buff

Click here to goto the top.

Tip #21
 If you have a program that uses the PRINT statement a lot,
 I found an interesting quirk. It isn't much by itself, but 
 with other optimizations it could help.

 PRINT STR$(A%) is faster than PRINT A%

 I was just toying about with QB, comparing it's speed to PB 
 and found that adding the STR$() function speeds QB up. It 
 makes no difference to PB, but QB increases speed by just 
 over 7.8%. As I said, it isn't much, but with other things 
 (like AND 255 instead of MOD 256) it helps.

Tip by qb_king@xoommail.com
NOTE: Here are some more ways to speed up your programs.
 Use DEFINT A-Z at the top of your program (and in all
 subs/functions). Use STATIC at the end of a sub call line
 (in the sub itself) whenever possibe. (non integer
 numerics can be redefined by using a DIM statement or
 appropriate ending character & ! # etc.) (from Buff)
Click here to goto the top.

Tip #8
 Making an RPG? Want to hurt someone if they type in a bad word?
 Use this command to make the computer reboot:

    OUT &H64, &HFE 

 Note: This only works in dos. In Win95/NT or 98 for those of you
 who have a bootleg copy it will only end the program.


Tip by Dave Stewart - Taken from The QBasic Site


Click here to goto the top.

Tip #7

 If you are using commands to the Communications Port (modem) -
 use the INPUT$ function as well as the PRINT # function.

 The communications port only uses 1-2 if you are not using imported
 libraries. It is still possible to create a functional terminal/BBS
 program using QB! Remember to open and close com ports when reading
 or writing.


Tip by Dana William Sherban
 (Note from Buff: If you use a random or binary file, you don't have
  open and close before read/writes only when ending the program.)

Click here to goto the top.

Tip #6
A better way to test if a number is divisible by another number is to
use the MOD function which returns the remainder of a division
operation:

    3 MOD 2 = 1 because 3 divided by two leaves a remainder of 1

Therefore, a number is divisible by another if the remainder is zero!!!
    IF A MOD 5 = 0 then A is divisible by 5!!! 


Tip by Eugene Villar - SEAV Softwares


Click here to goto the top.

Tip #5
 If you use a Quick Library (.QLB) file with difficult subnames,
 you can changes them in the (most used) .BI file.
 Example of old .BI file:

 DECLARE SUB DifficultNameForSub
 etc.
 If you want to call this sub, without typing in the subname (here
 DifficultNameForSub), you can use a ALIAS! Example:

 DECLARE SUB Diff ALIAS "DifficultNameForSub"


Tip by Jorden Chamid - Future Software Programming

Click here to goto the top.

Tip #4
 Need to order numbers or possibly letters?
 Use the SWAP command!
    SWAP var1, var2

example: 
    PRINT "This program will sort two numbers"
    INPUT "first number"; num1
    INPUT "second number"; num2
    IF num1 > num2 then
        SWAP num1, num2
    END IF 

    PRINT "the ordered numbers are:"; PRINT num1, num2 
    END


Tip by Randy Cicale

Click here to goto the top.

Tip #3
 Instead of using "INKEY$", you can use "INP(&H60)"
 This returns a code when a key is pressed, and thesame code + 128
 when released! This works much faster and is very useful!

 example:
    K = INP(&H60)
    IF K = 27 THEN PRINT "ESC PRESSED"
    IF K = 155 THEN PRINT "ESC RELEASED"


 Happy programming! 

 Tip by Jorden Chamid - Future Software

Click to goto the top.

Tip #29
  Check syntax of statments including correct spelling by
  positioning the cursor at the beginning up to the end of
  the statement and press F1. If it is supposed to be a
  basic statement and says it is a variable, you have
  misspelled it.

Tip by Buff


Click here to goto the top.

Tip #23
  Keep GOTO statements to a minimum. Some say never use them.
  My personal opinion is if they are only used within a small
  routine and kept to a minimum it is ok. Don't use them to
  call one sub routine from another. It makes debugging difficult,
  and almost always results in what is commonly called "spaghetti
  code". This is versus "structured" programming that uses
  subroutines (either gosub/return or QB subs/functions) to do
  tasks that are performed over and over.

Tip by Buff


Click here to goto the top.

Tip #2
 Instead of typing in PRINT every time use ?
 It will become PRINT automatically! 
 
Tip by Jorden Chamid - Future Software


Click here to goto the top.

Tip #50

   Probably because you are trying to load a program saved with (for 
   example) QuickBasic 4.5 in quick load format into Qbasic that only 
   loads text. Either load it in Quick Basic instead of Qbasic or have 
   someone who has Quick Basic save it in text format so you can load it.
   
Tip from fcb (Buff) Click here to goto Beginner list.

Tip #36

    When creating variables, try to always use the type identifier
    at the end of the variable. This can speed up mathematical
    problems up to 90% it is said, because QB doesn't have to use
    a lookup table to find out what kind of variable it is.
    Identifiers are: % (percent sign) for integers -32767 to +32767
      & (ampersand - and sign) for long integers +- 2.14 billion.
      ! (exclamation point) for single precision floating point.
      # (pound or number sign) for double precision floating point.
    (see the help in QB for limits of floating point numbers)
    Example: aninteger% = 1
             alongI& = 1
             asingle!=1.0
             adounle#=1.0
    
Tip from simply QB (see links page) Click here to goto Beginner list.

Tip #1
 Problem: 

 How do you check if a number is divisible by another number?
 Is 49 divisible by 7? 

 Solution: 

 All you have to do to check if a number is divisible by another
 number is divide them and check to see if its integer is the
 same as the actual dividend.

 The code: 
    INT(A/B) = A/B 
 Example: 
    CLS
    INPUT "Insert a number. "; a
    PRINT "Check"; a; "to see if it is divisible by";
    INPUT "divisor ",b
    IF INT(a / b) = a / b THEN ans$ = "YES" ELSE ans$ = "NO"
    PRINT "Is"; a; "divisible by"; b; "?"
    PRINT ans$
    
 (from Buff) especially for whole numbers you could also use MOD
   if 49 MOD 7=0 then ans$="YES" else ans$="NO"
   mod returns the remainder of one number divided by the second

Tip by Steve Martin - qbasic/quickbasic TOP 50
Click here to goto the top.
Thanks to Tek for his help.
Skill levels are rated on a scale of 1 to 5. 1 for beginers and 5 for experts.
Send me your tips and tricks to add to this page.
Please keep them as small as possible.
(1st 17 were included on QB top 50)(Currently we have 50 tips).

Beginner - Beginner+ - Intermediate - Advanced