Hello again, and welcome to my wonderful world of tech tinkerings. I’m going to be documenting my continuing progress in learning QBASIC here. If you want to read about my past progress and see the code I’ve written so far, you can visit my first post here.
I was up all night teaching myself QBASIC the other night. The next day I had an annual physical first thing in the morning, which was really important because my health has been suffering lately, mostly as a result of my getting so engrossed in personal projects that I lose track of everything else and simply stop taking care of myself. Afterward I spent the rest of the day reviewing what I had learned in QBASIC and also learning more of the language, as well as making sure I exercised and showered and did all the other things I’ve been neglecting to do lately, just trying to get myself back up to optimum health. I then slept for 12 hours that night. Not exactly ideal conditions for learning, but somehow I still managed to retain all the information.
I started off by teaching myself functions and subroutines. I found the syntax to be less like that used by Commodore BASIC and more like that used by Fortran. In fact the syntax is almost exactly like Fortran. Here is a trivial example of a function in both Fortran 77 and QBASIC:
FUNCTION LARGER ( A, B ) INTEGER A, B IF ( A .GT. B ) THEN LARGER = A ELSE LARGER = B END IF RETURN END FUNCTION
FUNCTION LARGER (A%, B%) IF A% > B% THEN LARGER = A% ELSE LARGER = B% END IF END FUNCTION
Notice how in both Fortran and QBASIC the return value is set by setting a variable with the same name as the function. This is pretty much a hallmark of Fortran. Subroutines are similar, though they don’t have return values, and you use the
CALL statement in both Fortran and QBASIC to transfer control to a subroutine. By comparison, a subroutine written in a classic form of BASIC like that used for the Commodore computers would implement transfer of control using primitive
RET constructs similar to those used in assembly language.
As a proof of concept I wrote a factorial function in QBASIC, since the factorial is more or less the standard stock example used to illustrate recursion.
1 DECLARE FUNCTION FACT! (NUM#) 2 INPUT "Enter an integer:"; N# 3 PRINT "Factorial:"; FACT(N#) 4 5 FUNCTION FACT (NUM#) 6 IF NUM# = 0 THEN 7 FACT = 1 8 ELSE 9 FACT = NUM# * FACT(NUM# - 1) 10 END IF 11 END FUNCTION
The way QBASIC handles functions and subroutines is rather interesting, because it treats all subprograms as separate modules, which are viewed in different windows, and you have to switch between them manually. I guess that makes for a cleaner interface overall.
I also did some more with graphics in QBASIC. Specifically I learned about the
PSET (pixel set) statement used to set a certain pixel to a certain color, as well as the
DATA statement, which is used to feed data into
PSET in a more convenient array format.
PSET only operates on individual pixels, I found it lacking when it came to drawing large images. I figured I’d do some experimenting and try to draw an image with
PSET and then blow it up so it occupies the entire screen. So instead of operating in 1-pixel units it operates in chunks of 20 x 15 pixels, making the geometric figures it draws 20 x 15 times larger. Here’s the program I wrote to accomplish this:
1 REM DEMO OF DRAWING WITH THE DATA STATEMENT 2 SCREEN 13 3 FOR Y% = 1 TO 10 4 FOR X% = 1 TO 10 5 READ Z% 6 REM TWO INNERMOST FOR LOOPS STRETCH OUT THE IMAGE 7 FOR I% = X% * 20 TO X% * 20 + 20 8 FOR J% = Y% * 15 TO Y% * 15 + 15 9 PSET (I%, J%), Z% 10 NEXT: NEXT: NEXT: NEXT 11 REM THE IMAGE: 12 DATA 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 13 DATA 40, 00, 00, 00, 00, 00, 00, 00, 00, 40 14 DATA 40, 00, 55, 55, 55, 55, 55, 55, 00, 40 15 DATA 40, 00, 55, 00, 00, 00, 00, 55, 00, 40 16 DATA 40, 00, 55, 00, 05, 05, 00, 55, 00, 40 17 DATA 40, 00, 55, 00, 05, 05, 00, 55, 00, 40 18 DATA 40, 00, 55, 00, 00, 00, 00, 55, 00, 40 19 DATA 40, 00, 55, 55, 55, 55, 55, 55, 00, 40 20 DATA 40, 00, 00, 00, 00, 00, 00, 00, 00, 40 21 DATA 40, 40, 40, 40, 40, 40, 40, 40, 40, 40 22 END
When run, the program draws the following image on the screen:
I can see that the possibilities for this construct are endless. I could create a maze game, or a dungeon crawler game using tiles constructed in this fashion. I still haven’t entirely figured out how the
DATA statement works or how I would be able to reuse that data for something like determining what squares in a grid are legal for the character to move to, etc. I’ll need to study this thing some more so I can figure out how to utilize its full potential to write retro QBASIC games for DOS.