We need QBCM to be available on as many Qbasic related websites as possible. That way ALL Qbasic coders can benefit from it. If you have a website dedicated to Qbasic then please become a host of QBCM too!
All you have to do to become a host is email me telling me the URL of your site, and then I'll send you the new issues every month, and your site will be listed on the QBCM host list!
Copyright (C), 2000, All rights reserved worldwide. QB Cult Magazine is the exclusive property and copyright of Matthew River Knight. The HTML coding and magazine design is the exclusive property and copyright of Christopher Steffan Charabaruk.
Welcome to yet another rockin' issue of QB Cult Magazine!!!
We get lots of readers complaining about all the "jargon" in the computer industry, so when I found this little descriptive bit of text, I had to share it with you (it's been blatantly purloined off the internet, with a few modifications and additions). Here goes:
In the 1980's, I heard a lot of words like "data input" and "beta version." They confused me. I wanted desperately to know what people were talking about, and what big secrets were being guarded in the computer industry. Now that I've worked in the computer industry for ten years or so, I've gained an insider's perspective, so I've decided to share my knowledge with the uninitiated by creating the following brief, handy glossary:
Alpha version: Software undergoes alpha testing as a first step in getting user feedback. Alpha is latin for "doesn't work."
Beta version: Software undergoes beta testing shortly before it's released. Beta is latin for "it still doesn't work."
Gold version: After undergoing beta testing, software is said to "go gold" and is then released to the market. Gold is what the software company's bank account rating suddenly becomes as good as.
Computer: Instrument of torture. The first computer was invented by Bob "Dim" Crossthwaite, a British scientist. In a plot to overthrow Adolf Hitler, Dim disguised himself as a German and offered his invention as a gift to the surly dictator. The plot worked. On April 8, 1945, Adolf became so enraged at the "Incompatible File Format" error messages that he shot himself. The war ended soon after Hitler's death, and Dim began working for IBM.
CPU: Central Propulsion Unit. The CPU is the computer's engine. It consists of a hard drive, an interface card and a tiny spinning wheel that's powered by a running rodent - a gerbil if the machine is a 486, a ferret if it's a Pentium and a ferret on speed if it's a Pentium II/III. (If it's an XT, it's a dormouse - as in "dead as a...")
Default Directory: Black hole. The default directory is where all files that you need disappear to.
Error message: Any terse, baffling remark used by programmers to place blame on users inability to use a PC for the program's shortcomings.
File: A document that has been saved with an unidentifiable name. It helps to think of a file as something stored in a file cabinet - except when you try to remove the file, the cabinet makes a rude noise and tells you that the file format is unknown.
Hammer: Heavy, hand-held tool that has increased immeasurably in popularity amongst PC technicians since Windows was invented. No PC owner should be without this vital tool. A few hefty whacks are more than enough to sort out any problem.
Hardware: Collective term for any computer-related object that can be kicked or battered.
Help: The feature that assists in generating more questions. When the help feature is used correctly, users are able to navigate through a series of help screens and end up where they started from without learning anything.
Input/Output: Information is inputted through the keyboard as intelligible data and then output to the printer as unrecognisable junk.
Interim Release: A programmer's feeble attempt at repentance.
Printer: A printer consists of three main parts: the case, the jammed paper tray and the blinking red light.
Programmers: Computer avengers. Once members of that group of high school nerds who wore tape on their glasses, played Dungeons and Dragons, and memorised Star Trek episodes; now millionaires who create "user-friendly" software to get revenge on whoever teased them at school.
Reference Manual: Object that raises the monitor to eye level. Also used to compensate for that short table leg.
User-Friendly: Of or pertaining to any feature, device or concept that makes perfect sense to a programmer.
Users: Collective term for those who stare vacantly at a monitor. Users are divided into three types: novice, intermediate and expert:
Novice Users: People who are afraid that simply pressing a key might break their computer.
Intermediate Users: People who don't know how to fix their computer after they've just pressed the key that broke it.
Expert User: People who break other people's computers.
Windows: The deadliest and most feared computer virus that has yet been created. It was coded by an evil circle of hackers identifying themselves as Microsoft, in an effort to take over the world.
That's it for now. If you have something you would like added to this list, then please email it to me and it'll be printed in the next issue of QBCM. Your name will of course also be mentioned.
As you can see there's some major changes once again in QBCM. It seems to happen every month! Chris Charabaruk is QBCM's new HTML guy. Thanks again for doing this Chris! You will also notice that the BASIC MUSEUM has been replaced by README.TXT - it will contain similar articles to the past, though it won't always be specific to BASIC, and won't necessarily be historic either.
An enormous thank-you is owed to everyone who has contributed in any way to QBCM. Without this huge support QBCM simply wouldn't be the same. As always, I ask that you please please please contribute some articles! In addition to that, all you readers out there must please email me and say what you would like to see published in the mag. What do y'all want to read about? Lemme know! ^_^
Whew! My longest editorial note yet! Happy reading QBCM4!!! ^_^
-Matthew River Knight
QBCM takes a lot of time and work to complete every month, and I am thus always delighted to hear from its readership. Please write to QBCM at email@example.com with your comments and suggestions, or basically anything you have on your mind to do with Qbasic ^_^
Here's a few of the letters we recieved last month:
I know this message isn't of any real importance, but I just wanted to point
out that the QB Cult Magazine is by far the best QB magazine I have ever
read! Sometimes programmers have problems communicating outside of their
language of choice. All too often, this language of choice happens to be a
PROGRAMMING language rather than English. But I am happy to see that this
magazine does not suffer from this at all! The articles are easy to read,
and are both entertaining and informative. I particularily enjoyed the
history section, especially the article on the evolution of 3D programming.
I don't always remain perfectly up-to-date in the QB scene, and so what you
included in the HISTORY section was completely new to me! Partciularily that
little 3D frog game, the screen-shot of which was incredible! As well, a
long time ago I tried my hand at 3D in QB which was a complete failure... so
I turned to raytracing with better results. But thanks to issue #3 with the
easy-to-understand 3D tutorial, I've been re-inspired to learn the art of
3D-creation in QuickBASIC!!! Needless to say- you're magazine is incredible.
Thank-you for all the work you've put into it... and I'm looking forward to
MORE great work in future issues!
Wow! Thanks for the compliments! It's really nice to hear that people enjoyed my article on the history of 3d in Qbasic...it did take a long time to find all that information, and even longer to put it all together into one article. It's great to hear that the 3d tut series is helping you...my aim with these tuts is to make it as easy to understand as possible. I have read far too many 3d tutorials that are simply too difficult to understand, so I thought it was about time I put an end to that ^_^
Let's see, issue 3's OOP article was pretty interesting. The assembler
article was well-written too. And the DarkDread and Dunric interviews were
fun. I have some suggestions for issue 4. Please format it like issue 2, and
don't use any DHTML/CSS. Formatting can make a huge difference in perceived
quality. For example, I personally like "Arial" font and 10 point Courier for
code, and well-defined section headings and subheadings.
As for article ideas, I think a "how to make a reader program out of file format specs" might be useful. Another article might cover the "QB demo scene" (by Entropy) partly because there are some nice screenshots you can show. I also think that articles on clever algorithms like dynamic programming and certain AI algorithms might be interesting as well.
As for the program reviews, I like colorful screenshots that are put into nice tables along with the article in Arial font or something. I would also like to see more well-drawn (preferably antialiased) diagrams embedded in the articles.
I know I'm asking a lot and being somewhat overcritical, but that's because I like QBCM and I want QBCM to be even better.
Thanks for the comments. About the HTML and design...well, as you can see,
this has completely changed since the previous two issues now that Chris
Charabaruk is doing it, so I won't discuss that further. Hope ya like the
new look :)
Thank you for your suggestions of articles. I really wish more people would write some tuts/articles for QBCM though (hint hint)...
I saw your post on the GDR about the Qbasic Cult Magazine, and (of course) I
can't resist checking out new qb magazines. How many have there been now?
The one Rems did, QB news, Qb:tm, QbTimes, Basic Basix, Qb Scene, Razor,
Qubed, QBCM, others I'm sure. Yours, actually, was the best one I've come
across since I stopped doing qb:tm last September. QBCM is sitting in my
bookmark file right now. Ironically, Qb:tm Issue 13 was slated to have an
article about Modem Progging, and a "Must Learn" about Cold/Warm boots. You
I'm really into the qb history, so the article in Issue 2 about Battlezone and other BASIC classics was a good read.
The only complaint I can level is that, possibly, the layout, text color, and site design make the mag a touch difficult to read. I *highly* recommend Black (or dark grey) text on white bg. Also, you may want a poll or something similar that changes every week or so, and possibly "in-between" articles which will help you boost your hits. Some ad banners (460x60 I believe is the standard size, but you should check) couldn't hurt either.
Oh, one other complaint is that possibly the mag's issues are too long. You should either break the pages up into individual articles or divide the mag into more than one. After about 30-40 printed pages of content, it gets a touch hard on the eyes.
If you ever need any help with a tut or contacts or site design, lemme know.
PS. I noticed that my posting on a webboard made news? What's up with that? Actually, I'm still lurking about the scene, although the only boards I actively check out anymore are the GDR and the Open Forum.
Wow! Thanks for the compliments! I was actually a HUGE fan of QB:TM...it was
a great magazine and I was sad to see it go. Actually, that's the main
reason why I started QBCM.
It's nice to hear that you liked the article on the history of 3d in BASIC. I have actually recieved a lot of compliments on that article, which is great because it took a lot of time, effort and research to get completed.
About the complaints on the mag design...argh...I have had so many complaints about it, you would not believe it (or maybe you would ^_^). Well, Chris Charabaruk has taken over that department...hopefully people will be happy with the new look.
The suggestion about in-between articles is an interesting one, but it really isn't possible at this stage. I am currently writing most of the tuts and articles myself...this already consumes a huge amount of my time. If more people start contributing articles/tuts, then I will probably do this, though. If only I got some article/tut contributions (hint hint)...
I like the idea about the polls. I remember you had something like this in QB:TM and it seemed to work quite nicely...I'll probably add this in soon!
Your other complaint...about the mag issues being too long...well, sorry but it seems that this issue is even longer! In fact, to my knowledge this is the biggest issue of a QB magazine in history! ^_^
Thanks for the offer of help! As I have said MANY times before, I really need people to contribute articles/tutorials, so if you can do something like this then please let me know!!! ^_^
Heheheh, yeah, I mentioned about your posting on that webboard mainly because A LOT of people told me that you had left the QB scene. I thought I should let them know that you're still around.
Don't you just hate it when you are really stuck on something in Qbasic and no matter how hard you try you just can't figure it out? Doesn't it drive you completely nuts? Yep, I thought so, so that's why I included this section in the mag for ya! If you get stuck on anything in Qbasic, just send an email to me at firstname.lastname@example.org and you'll get a reply within three days. In addition to that, your problem will be printed here in QBCM, along with my reply, so it can help other coders too! ^_^
This question isn't related to programming, but I would really appreciate
your help. Last week I bought a game for my PC, and it came with a circular,
silver disk. However, it was clearly too wide to fit into my disk drive - it
was about five inches in diameter, while my disk drive is only 3.5 inches
wide. What am I supposed to do with it?
You need to perform a simple upgrade on your existing drive. You require an ordinary hammer and chisel, and what you have to do is chip away an inch on each side of the drive. Once you've done that you can insert these modern silver disks with ease. If it doesn't fit first time, chip some more away. It's that simple!
I have a really stupid question. I'm sure every Qbasic programmer in the
world knows how to do this except me. How do I use two libraries in Qbasic?
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;
And that's it! Problem solved! A big thank-you goes to Glenn who taught me how to do this.
|* Hmmm...we have some great news about 3*D, being coded by Badjas of Future Software, however, he won't let us print it this month! So you are just gonna have to be patient and wait another month...argh...I'll just give you a little info anyway! ^_^ I'll just say that the engine is now running at a truly AMAZING pace...but that's all I'm gonna say for now. For those of you who have been living under a huge cyber rock for the past few months, 3*D is a library with which it will be possible to create high quality 3d games in Qbasic. Visit the Future Software website (which just happens to be the best QB website on the planet!!!) at: http://www.qb45.com|
* Flexibal is working on four, count 'em, four projects:|
VMS Pro 2.0: Virtual Memory System. Store up to 9 GB of data on HardDisk, and save a lot of conventional memory.
The OMS: Object Management System. It's an Object Oriented GUI.
VectorScape 3D: A 3D-World game engine that uses vectors, so you can zoom in/out, rotate the image, and many other cool things. You create objects (trees, mountains, etc. and of course - the characters) with VectorEditor and a world-map (locate of objects) with Object Allocator. Then, just set up the game.
The Hobbit: This game will be made in VectorScape 3D, based on the story by JRR Tolkien.
QBCM will keep you up to date on the progress of these projects, as it arrives.
* Liquidex has announced that he has three projects that he intends to
complete this summer: Syraphage Build 5, Liquid3D and LiquidGL (yes, this
project is comin' back! ^_^)|
LiquidGL will most likely have its first mamoth release this summer. It has also been stated that the name may change to Liquid at some point.
|* And while we're talkin' about Liquidex...we have recently recieved some very sad news from him...QuickBASIC RPGs, the website which has without a doubt been the center of the QB RPG universe for the last 3 years, has shut down. Fortunately, however, Nekrophidius will be opening a similar website, the URL of which has yet to be released...we'll keep you informed. Contrary to popular belief, Liquidex is NOT, I repeat, NOT quitting Qbasic - from what we have heard, Liquidex is just tired of maintaining the site. However, QuickBASIC RPGs will remain online, so you will still be able to get all the old downloads and use its very active discussion board. Surf to: http://members.xoom.com/qbasic_rpgs|
|* justBASIC are developing (or should I say have developed) a fully menu driven library manager called Multi-Lib, which allows the user to have up to nine libraries open at a time. It supports cut, copy and pasting between libraries, you can create new libraries, combine libraries, add, extract, and/or delete modules with ease. For further information and downloads, surf to: http://www.rainbowtel.net/~pitman/multilib.html|
* Well, as it has been said time and time again, Qbasic isn't getting any
younger, and sooner or later we will need to convert to some other
implementation of BASIC. Countless QB addicts around the world are busily
beavering away as we speak, trying to make something similar to QB, but
with more power. Pherhaps the most promising of these projects is
QuickPower by Nekrophidius - arguably one of the most gifted BASIC coders
in the world today. Nek's objectives for the project have changed a great
deal over the past month or so. Here's what he had to say:|
"QuickPower is now more broad-based. Instead of just supporting realmode DOS, it's being set up to support FIVE platforms. Realmode DOS, pmode DOS, Win32, Unix, and V2 OS. I have done away with the "plugins" idea and am instead using "standard" libraries. Of course, the option for external libraries still exists, but the standard libraries will be more than enough for building projects on ANY platforms, since the code will be identical =)
Now...for realmode compilation like most people will probably do at first, libs will still be supported, but rewriting in standard QB or PB will be required for compiling on other platforms. BUT...you will be able to, of course, use native stuff also...imagine using the Windows API through "qb" =)
For both DOS compilers and the Win32 compiler, the output will be an actual EXE. For unix and v2 os, the output will be source code you can compile on those systems."
Well that sounds godly eh QBers?! A large percentage of the Qmunity has shown interest in converting to QP once it is released...so it seems that our QB community will soon be called the QP community! And this mag will be called QP Cult Magazine!!! ^_^ Look out C/C++, BASIC LIVES!!!
|* And while we're talking about Nekrophidius, we might as well mention that he's bringing back...QB ON ACID!!! QBOA had a hugely successful run last year, and then mysteriously stopped. But we are, needless to say, delighted that it's back. Check out: http://lss.zext.net/qbonacid|
|* Another excellent raycaster hits the scene! But not just any raycaster... Kaboom is a complete game development environment for QB programmers, in which a game much like Doom can easily be made!!! A fully playable game comes with the engine, and it is without a doubt the best (if only) of its kind in the QB arena today. Interestingly, the entire thing has been written in 100% QB!!! I honestly didn't think think this was possible in QB without ASM until now! Needless to say, you have to get Kaboom right away! It's available at: http://www.angelfire.com/id2/qbkaboom|
|* Remember Pasco? Y'know...the guy who made Groov Buggies? Anyway, him (and a few other prominent QB coders) have recently (at last!) released a demo of Subshock - another Raycaster (is the lastest QB craze Raycasters or what?! ^_^). The demo is extremely fast, and interestingly, other than the keyboard handler, it is written in pure QB!!! It is a very early demo however, and much still has to be added, but it's worth a look anyways. Get the first Subshock demo from: http://subshock.tekscode.com|
|* Terry Cavanagh has delevoped an addictive and original puzzle game called Black Hole. It is available for download at: http://www.darklegends.com|
|* http://alienqb.cjb.net, free to good home! Sadly, AlienQB no longer wishes to work on the website any further, and will glady give it away to anyone who wants it. AlienQB is now doing darklegends.com, and is doing a damn good job of it at that! Check it out...now!!! ^_^|
|* QBCC (QuickBASIC Compatible Compiler), another very promising QB-like compiler, has gone open source!!! For more information on this, check out: http://qbcc.tekscode.com|
|* Soom Primal has been working on a very promising project, Tori No Otaku, for some time now. It has some very interesting elements to it, and it's certainly worth keeping an eye on. A small demo is available for download at: http://www.swoo.net/~soomprimal/Tori_Test_1.ZIP|
|* Community is working on a Galaga (remember that old game? Sigh, how I miss the good old days! ^_^) style vertical-scroller. A very early demo of this game is available at: http://community.zext.net|
|* Hitech software has released an interesting lib called WinDOS. It is up for download at: http://www.homeqbasic.8m.com|
|* Marcade has announced his retirement from the QB world :( Fear not however, NeoBASIC is still around - admins have been appointed to maintain the site. Check out this rockin' website at: http://www.neozones.com|
* Innocent Bystander Productions is working on an RPG called Fatism. Here's
a little clip from their design document:|
"independent speech algorithm - befitting the character's automatic speech to the attitude you've formed for him: For instance, there is a scale of generally good and bad + & - attitude. It's your loa (level of attitude). Every time you choose the dialog, a loa point is recorded in your loa log. The choice can vary in how many good or how many bad points it's worth. When it comes time for automatic scripted sequences when the player cannot choose the dialog, the phrase most befitting to his loa will be said by the character. For instance instead of saying I think you and your skanky pink dress can go to hell, a player with a positive loa's character would say, yes, it looks great on you! This way the character can seem more realistic to the player, and he can interact more with his character than just more experience points for saying specific dialog; consequences in their best nature."
Needless to say, these guys have some great idea's here! QBCM hopes that this RPG won't end up like other promising QB RPG's of the past...making one demo, and then leaving the project at that.
|* QBVet recently founded #QBChat on DALnet. He intends to do for IRC chatters with this channel, what the Game Developers Refuge did for the Discussion Boarders. For this he is to be commended.|
That's all the news we got for you this issue. Please send any news or rumours to us at email@example.com
Writer: Gabriel Fernandez
(Check out COMPILER.BAS which is a part of this tutorial -ed)
Hi, welcome to the first Part of the my compiler tutorial. I made this tutorial to help the 'QB Cult Magazine', which, I think is the best qbasic magazine.
Well, I think you know Gabasic, it is a basic compiler I made in qbasic, check http://gab_soft.tripod.com to download it, I hope this tut is going to leave you ready to create a compiler like(or maybe better) than Gabasic in QB.
I'm going to teach how to make a compiler that works in RealMode, because this is the mode that everyone knows how it works.
You must have assembler knowledge to read this tutorial.
Well, let's start the tutorial.
|First, make:||- A string using DIM SHARED called Text$|
- A variable using DIM SHARED called linen&
Here are the most important subs and functions (if you don't understend something, don't worry because all the subs will be explained later):
- A sub to show program errors|
'SUB ShowError (ErrorNumber)'
- A lot of subs for Keywords|
'SUB Keyword.NAME (Parameters)'
Example: SUB Keyword.CLS ()
- Functions to return words, and full sentences|
'FUNCTION GetWord$ ()'
'FUNCTION GetFullWord$ ()'
- The math Parser(more info later)|
'SUB Parser.Math (Mode)'
- The string Parser|
'SUB Parser.String ()' *
- A function that will check if a text must be parse using the
math parser or the string parser. This is needed for IF, LOOP|
'FUNCTION Gettexttype ()' *
The main program should look like this:
DIM SHARED text$ DIM SHARED linen& OPEN Inputfile$ FOR INPUT AS #1 OPEN Outasm$ FOR OUTPUT AS #2 DO WHILE NOT EOF(1) Line input #1, text$ linen& = linen& + 1 ; Here we will check keywords, subs, etc. LOOP CLOSE
The main program is very simple, it just read each line of the InputFile$ and it adds one to linen&(which has the number of the current line read), until we reach the end of the file. Of course we are going to add a lot of stuff to this program.
Now, I will explain what a 'Parser' is.
Parser: A parser analize and generates assembler (not necesary assembler) code for math or string operations. A Parser is the 50% of the compiler.
A math parser will read and generate code of a text that only has math operations on it, like "1 + 2 / 3 + 4".
The math Parser that we will create will parse text and leave the result in AX, so, if i use the math parser with the following text:
"5 + 4 * 2 / 6"
it will leave the result('3') in AX.
Our parser will support two modes of work, the 16 bit mode(integer mode) and the 32 bit mode(long mode), when our parser works in integer mode, the asm code will use 16 bit registers(AX, BX,...), when it works in long mode, it will use 32 bit registers(EAX, EBX,...)
The Parser is very usefull to parse keywords parameters, and leave the result of the math operations on the CPU registers(AX, BX, CX, ...), to call an assembly function later. So if my text is "LOCATE 12 + 1, 2 - 1" , I will call the parser with the first parameter("12 + 1"), and the parser will leave the result in AX, then I PUSH this value(on the stack), and then I call my parser with the second parameter("2 - 1"), it will leave the result again in AX, now I POP the pushed value into BX, and now i call the "LOCATE" asm function. Here's the code that will be generated with "LOCATE 12 + 1, 2 - 1":
Mov ax, 12 Add ax, 1 PUSH AX Mov ax, 2 Sub ax, 1 POP BX CALL Locate
Here's the Keyword.LOCATE sub:
SUB Keyword.LOCATE () a$ = getfullword$ b$ = getfullword$ IF a$ = "eof" OR b$ = "eof" THEN ShowError 1 Math.Parser a$ END SUB
I'm going to explain the STRING Parser later, when we finish the Math parser(this will take a long time).
The show error sub will be called when an error is found on the program, this will make the compiler programming a lot easier.
' ShowError sub SUB ShowError (Errornumber) Print "An error was found in the line: ", linen& SELECT CASE Errornumber CASE 1: PRINT "Argument-count mismatch" CASE 2: PRINT "Unkown command" END SELECT END END SUB
Getword$ will be a function that will return each word of Text$
- Example of Getword$:
Text$ = "PRINT A$ + B$ + 'Hello'"
Each call to Getword$ will return the next word. Here is what Getword$ will return on each call:
|1st call: Getword$ will return "PRINT"|
|2nd call: Getword$ will return "A$"|
|3rd call: Getword$ will return "+"|
|4th call: Getword$ will return "B$"|
|5th call: Getword$ will return "+"|
|6th call: Getword$ will return "'Hello'"|
|7th call: Getword$ will return 'eof'|
GetFullWord$ will return a full sentence, a sentence will be all the text before a comma (",").
So, if text$ = "LOCATE 13 + 2, 12 - col%", it will return on each call:
|1st call: "LOCATE 13 + 2"|
|2nd call: "12 - col%"|
|3rd call: the text 'eof'|
All this functions must return the text "eof" when the end of the line is reached. Also, when it finds a '(comment char), it must return 'eof' too, becuase there is where a comment starts.
Well, now we are going to add the following commands to our compiler:
|- CLS (Clears the screen)|
|- WAITKEY (Waits until a key is pressed)|
|- END (Finish the program)|
You must have the Getword$ and Getfullword$ functions finished, check the 'compiler.bas' for this functions.
To add keywords, we will add the code like this one to our main program:
keyword$ = getword$ SELECT CASE UCASE$(Keyword$) CASE AnyKeyword: Keyword.ANYKEYWORD END SELECT
Check now the main program with the above code added:
DO WHILE NOT EOF(1) Line input #1, text$ linen& = linen& + 1 keyword$ = getword$ SELECT CASE UCASE$(Keyword$) ' Keywords list CASE "CLS": Keyword.CLS CASE "END": Keyword.END CASE "WAITKEY": Keyword.WAITKEY END SELECT LOOP
Let's build the subs for CLS, END, WAITKEY:
SUB Keyword.CLS () PRINT #2, "CALL CLS" END SUB SUB Keyword.END () Print #2, "MOV AX, 4C00h" Print #2, "INT 21h" END SUB SUB Keyword.WAITKEY () Print #2, "XOR AX, AX" Print #2, "INT 16h" END SUB
Great! Now our compiler can do CLS, END and WAITKEY.
Of course you have to add the CLS asm routine, a CLS routine will look like this:
CLS: ; - CLS routine PUSH ES mov ax, 0B800h mov es, ax mov di, 0 mov cx, 2000 mov ax, 0 REP STOSW POP ES RET
Let's create a SUB called Addasmroutines, this sub will add the asm routines at the end of our Outasm$ file.
SUB Addasmroutines () ' Cls routine PRINT #2, "CLS:" PRINT #2, " PUSH ES" PRINT #2, " mov ax, 0B800h" PRINT #2, " mov es, ax" PRINT #2, " mov di, 0" PRINT #2, " mov cx, 2000" PRINT #2, " mov ax, 0" PRINT #2, " REP STOSW" PRINT #2, " POP ES" PRINT #2, "RET" END SUB
We will call the sub Addasmroutines when our main program ends, add 'Addasmroutines' before the Closing all the file in our main program.
It is very easy to add keywords that doesn't use parameters.
We are going to make a very simple math parser right now, it will support +, *, /, -, and numbers, we aren't going to add variable support in this part of the tutorial.
Our parser will work in the following way:
* Load the first number in the text to AX, and set CurrentOp(eration) to 1 [-- Loop _ Use a$ = Getword$ _ If a$ returns 'eof', exit the sub * Compare CurrentOp with 1, if CurrentOp = 1 then - Set CurrentOp to 2 - Get the operation type(+,-,/,*) * If not one - Get number from a$ - Do the math operation - Set CurrentOp to 1 * END the IF block Loop --]
Now, this is the SUB Parser.MATH, this parser is going to support only integer mode (for now).
DEFINT A-Z SUB Parser.Math () a$ = getword$ Print #2, "MOV AX," + a$ CurrentOp = 1 DO a$ = getword$ IF a$ = "eof" THEN Exit Sub IF CurrentOp = 1 THEN CurrentOp = 2 SELECT CASE a$ Case "+": MathOp = Add: Goto label1 Case "-": MathOp = Subs: Goto label1 Case "/": MathOp = Div: Goto label1 Case "*": MathOp = Mul: Goto label1 END Select ShowError 3 ELSE SELECT CASE MathOp Case Add: PRINT #2, "ADD AX, " + a$ Case Subs: PRINT #2, "SUB AX, " + a$ Case Mul: PRINT #2, "MOV DX, 0" PRINT #2, "MOV BX, " + a$ PRINT #2, "MUL BX" Case Div: PRINT #2, "MOV DX, 0" PRINT #2, "MOV BX, " + a$ PRINT #2, "DIV BX" END SELECT CurrentOp = 1 END IF label1: LOOP END SUB
That was a very simple math parser, but it does the work. Now, you can create keywords that use parameters.
Now, let's create the LOCATE keyword.
SUB Keyword.LOCATE () parameter1$ = getfullword$ parameter2$ = getfullword$ Text$ = parameter1$ Getcharpos = 0 Parser.Math PRINT #2, "MOV [Textx], ax" Text$ = parameter2$ Getcharpos = 0 Parser.Math PRINT #2, "MOV [Texty], ax" END SUB
Don't worry about the getcharpos variable, look the compiler.bas to understand that.
Here ends the first part of my tutorial. I hope you like it. In next part, we are going to create a great math parser, and maybe we are going to add variables support.
Among the legions of programming languages, BASIC has long stood out as THE first stop in a long ride of programming convertibles. With dependable tires, chrome wheels, and a paint job worthy of the Louvre, BASIC has introduced thousands of computer users to the world of programming.
Back in the days of 64K computers, 16 colors and 32K limited arrays, BASIC was a good language to use if one wanted to solve fractions, determine the right HAM radio frequency, and play small adventure games.
Then along came Mr. Gates with QBASIC.
With VGA graphics, 64K "huge" arrays, unlimited sprites, and a highly impressive GUI (Graphical User Interface), QBASIC made all previous versions of BASIC obsolete.
In 1995, there were roughly three or four dozen Qbasic games available on the internet. Today -- almost 5 years later -- you could fill a small library with the number of Action, RPG, and Sports games stamped with the familiar Qbasic feel.
But as good as Qbasic has been, perhaps its time has finally passed, along with vinyl records, tape recorders and Jimmy Buffet memorialbilia.
Which begs the question: Is (Q)basic dead?
Hardly. Judging from the continued support on bulletin boards across the internet, Qbasic is alive and well. Programs are still being written at an amazing clip, with some fledgling projects even making it big on places such as ZDNet and Tucows.
But with the advent of the next Windows operating system, Qbasic's days are clearly numbered. Make no mistake, Microsoft has desired to kill off BASIC since 1991 (Visual Basic -- though there's hardly a resemblance between the two).
With the Death of DOS, Qbasic will no doubt end up alongside "orphaned" programs like Visicalc, Wordstar and King's Quest.
However, don't expect this once prominent language to go quietly into the night. With emulators and other platforms such as Linux, QBasic will be around for a long time to come.
Writer: Matthew River Knight
Welcome back! Are you ready to get back into action and break the barriers of the third dimension? Yes? Let's get crackin' then! ^_^
We covered some very simple stuff last issue. We learned how to define our 3d world coordinates, how to convert these world coordinates into camera coordinates, and finally how to convert the 3d camera coordinates into 2d screen coordinates. You will recall that we also covered some of the problems that you are likely to encounter, and we fixed them :)
There is a lot that we have to cover this issue. Firstly, we need to learn how to make our 3d world rotate. Another thing is that thus far we have only dealt with wireframe 3d. You are unlikely to come across a wireframe 3d game in the shop, so why should we do it with Qbasic?! Pardon? Did I hear you say that Qbasic is possibly too slow? Oh nonsense! I'll teach you how to get rid of any possible slowdown...so you can't blame Qbasic! And anway, a bad workman always blames his tools! So we are going to push the wireframe aside, and learn how to generate filled polygons in QB! Yep, it's possible! ^_^
Before we start learning anything new, it is necessary that I mention one little thing. You may have read some other 3d tutorials before, and you then will have noticed that the formulae they use are very different to the one's we have been using in this tutorial. This requires some explaining. There are MANY different methods of doing 3d. I know of about five different methods myself...I'm sure there are many more that have yet to be descovered. In just about every 3d tutorial I have ever read, they use a different method of doing 3d. It actually starts to get quite confusing...you are left wondering which writer you should believe...which method is best, and so on. Well, push all your worries aside, because the methods of doing 3d that are described in this tutorial series are ALWAYS the best methods I know of, and in most cases, are easier to understand and generally more logical.
Okay, I'm done extrapolating...let's get down to business!!!
To start with, we are going to cover 3d rotation. Rotation is a very important elemant of any 3d program. In any 3d game you may have, notice that in order to look around, the world seems to rotate around you. Now believe it or not, the 3d world really is rotating around you! Well...not exactly...but we'll get to that just now...let's take this one step at a time.
In order to make your 3d world/object rotate, you have to rotate all of the world coordinates around a point. But which point? Simple. The formulae which we are about to descover will ALWAYS rotate the world coordinates around the center of the world (0,0,0). Simple! ^_^
Now for the formulae!!! Hmmmm...before I say anything else, I have to explain one simple thing. In order to understand these formulae, it is necessary that you have a knowledge of trigonometry. The trig that you'll need to know isn't that difficult...you will only need to know the most elementary concepts of it...but I am no math teacher, so I am not going to explain it to you. I'm sure you will be able to find a decent book at your nearest public library with information on simple trig. What? Did you say that math is so boring? Rubbish! As I have said time and time again, mathematics is only boring if you don't have a use for it. I also used to find math boring...but when I started programming, I suddenly realised how much I needed to know math, and so the subject suddenly became utterly facinating. It will for you too!
Once you have mastered the basics of trigonometry, it will immediately become clear how to do rotation in 3d. You'll understand right away. But for those of you who are too lazy to figure out the formulae on your own, I have listed them here for you! You don't need to know how we came up with the formulae in order to use them...however, I personally like to learn these sorts of things...maybe you will too...so it is worth looking into understanding the formulae. Note that in these formulae, x', y' and z' represent the values of x, y and z, respectively, prior to transformation. Let me also just remind you that these formulae work with the world coordinates.
The first set of algorithms is for rotation about the x axis:
x = x' y = (sin(angle) * z') + (cos(angle) * y') z = (cos(angle) * z') - (sin(angle) * y')
The second set of algorithms is for rotation about the y axis:
x = (cos(angle) * x') - (sin(angle) * z') y = y' z = (sin(angle) * x') + (cos(angle) * z')
The third set of algorithms is for rotation about the z axis:
x = (cos(angle) * x') + (sin(angle) * y') y = (cos(angle) * y') - (sin(angle) * x') z = z'
By using these three sets of algorithms, it is possible to rotate a 3d object in literally any direction!!! Cool huh?! ^_^
Oh yeah...very important point...the trigonometric functions provided by Qbasic (SIN, COS, etc) require the angle argument to be in radians. Because it is easier and more natural to think in degrees, a simple conversion can be used to convert degrees to radians:
Radians = Degrees * .017453 Degrees = Radians * 57.29577
Simple! With what you now know, you can create a 3d object/world, and rotate it in any direction you want! Now that wasn't so hard was it?! ;)
Now it's time to discuss some optimizations! The SIN, COS, etc. functions are quite slow. In order to get your program running faster, it would be wise to create what is known as trig tables. But what the heck is a trig table?! Heh, it is basically a very grand sounding name for something that is actually very simple. What you do is create two arrays. In the one array you save all the values of COS. In the next you save all the values of SIN. Now instead of using the SIN and COS functions in your calculations, work with the array values instead! Simple! The result will be a program that is MUCH faster than it would otherwise have been!!! ^_^
Okay, so now we have a rotating 3d object...but wouldn't it be awesome if we could 'walk' around inside that 3d object, as seen in games like Quake?! Heh, well, it is actually very simple to do that!
Now there are A LOT of ways to do this, but I am going to describe the method which I find easiest to understand. Basically, although it may seem logical to move the camera around in order to 'walk' in your 3d world, it doesn't work that way. Try it. You'll see what I mean. So what do we do? It's easy... imagine you have a flat piece of ground in space...you are facing in any given direction, and are standing roughly in the center of this piece of ground...now, in order to move forward, you could add 1 to each of the Z values in the world coordinates! Then you would be further forward on that piece of ground! To move backwards, all you have to do is subtract 1 from each of the Z values of the world coordinates! Could life possibly be any easier?! ^_^
For an example of everything that you have learned so far, check out 3DPROGGY.BAS which has been included with this issue of QBCM! It is fully commented, and will help you develop an even greater insight into the totally awesome world of 3d in Qbasic!!! ^_^
Three-dimensional drawing can become very complex. Most three-dimensional models are created with a series of planes that represent the shell of the object. If the planes are filled, then the plane is considered to be nontransparent. Similarly, if the plane is not filled, the plane is considered to be transparent.
When rotating or moving three-dimensional objects, it is often necessary to remove parts of objects, or even entire objects, in order to provide realistic representations of the environment. The method by which these objects are altered is called hidden surface removal. The most common types of hidden surface removal are discussed in this tutorial.
There are two basic types of hidden surface removal. These are object-space methods and image-space methods. Three-dimensional information is used with object-space methods to decide which surfaces should be hidden and which surfaces should overlay others. Image-space methods use two-dimensional information to determine the hidden surfaces.
The most common method of hidden surface removal for personal computers is probably the plane equation method, which is an object-space method. In general terms, the plane equation method determines if a point is in front of, on, or behind a specified plane. By testing each point against the viewing position, always (0,0,0), the visible and hidden planes are determined.
The equation of a plane is:
Ax + By + Cz + D
where x, y, and z define a point on the surface of the plane. The A, B, C, and D values are constants and are derived as follows when three points on the plane are specified (x1,y1,z1 ; x2,y2,z2 ; x3,y3,z3).
A = y1(z2-z3) + y2(z3-z1) + y3(z1-z2) B = z1(x2-x3) + z2(x3-x1) + z3(x1-x2) C = x1(y2-y3) + x2(y3-y1) + x3(y1-y2) D = -x1(y2z3-y3z2) - x2(y3z1-y1z3) - x3(y1z2-y2z1)
By identifying three points on a plane, solving for A, B, C, and D, substituting A, B, C, and D into the plane equation, and passing each object point through the new plane equation, you can determine whether or not each point is on, in front of, or behind the defined plane. If the plane equation evaluates to a positive value, the point is hidden. If the plane equation evaluates to zero, the point is on the plane and is usually defined as visible. If the equation evaluates to a negative value, the point is visible.
When using this method it is important that the points used to derive the equations are plotted in a counterclockwise direction and can be viewed as part of a convex polyhedron. A convex polyhedron is a figure that has many faces and is curved outward, such as a cube.
Whew! What a huge entry into the series this has been! With what you now know, it will be possible for you to do some really cool stuff. If you make anything cool then please send me a copy! This entry is the last in this 3d programming series. I had originally intended it to continue for at least another month, however, it seems that I have covered everything I wished to discuss already! There is still more to learn...there's always more to learn, but I think this information is more than enough to get you up and running.
Good luck with your 3d programming! ^_^
Writer: William Moores
Hello! This is my first ever tutorial and lets hope it's a good one! Wanna make a game like DOOM? Well, with this tutorial, I will explain the basics of RAYCASTING, which will, hopefully, lead on to greater things... The concept of raycasting is actually very simple, imagine you had a laser pointer, which had a little screen on the back saying the colour and the distance of the thing you where pointing at. Well, raycasting is just that! (I worked all this out on my paper round! ^_^) Anyway, in QB, this is much easier than it sounds! In this tutorial, I will explain how to make a Doom style demo. Firstly, for our doom demo we would need a map. Like this:
DIM map%(1 TO 20, 1 TO 20)
As you can see, this would make a little level that was 20 * 20 blocks big. Each array element is a wall in our demo (eg. map%(3, 4) = 10, this would make a wall at 3, 4 be the colour ten). "This is just 2D rubbish!" I hear you say? Well, yes and no. In the demo it doesn't have any true 3D calculations, but it looks 3D. Anyway, before we start our 3D demo, let me show you a program that demonstrates a 3D veiw, which isn't actually in 3D, but it does help explain raycasting... The demo is a top veiw of our map, and it has a little cone that you can rotate and move. Well, in our 3D demo, this is the 'camera', the 2D one shows the camera and its RAYS coming out of it.
The 2D demo is <2DRAY.BAS>
Before we go any further, I'll explian the RAY bit. In a raycaster, the 'camera' emits rays, and when the ray hits a wall in our map, the 'camera' returns:
And the ray stops going.
Another way to explain this. Imagine you had a radar, the radar emits radio waves, the radar detects the radio waves that have bounced of the wall that they have hit, somehow(I don't know how) the radar calculates how far away the solid is that the radio waves have bounced of.
When you have understood all that, lets make our 3d(ish) camera! Remember that just now we made a map (DIM map%(1 to 20, 1 to 20)). Well, the camera is in the 2D demo as well, but the program doesn't draw in 3D (style).
All our 3D demo does is this: Instead of drawing the ray, it draws a lines along the screen corresponding to the ray it's fired (if you looked at the 2D demo, it sorta 'scans' along with lots of rays). The colour of the line is of what it's hit. To make it look 3D, we take away the distants of what it's hit from the vertical length of the line. This gives a very good effect. The only problem with this method is that you get a 'fish-eye' effect on your view. If you want you could work out a rule that gets rid of it.
I admit that the demos are slow, but you can easily modify them to suit you needs. If you don't quite understand this tutorial, study the examples hard. (If you want that is)
Now with your new knowledge of RAYCASTING, you could do some really cool stuff! I hope you enjoy your new skill and improve your knowledge of it, further than mine. Think about it, you could add lights! All you would have to do is the opposite of a camera! Instead of reading the colour, you could write the colour!
Writer: Avi Miller
They say the road to hell is paved with good intentions. They are wrong. It is paved with upgrades. As an innocent lad of 13, I was presented with an IBM-compatible PC, or as I should call it, my Serpent of Eden. This mono- lith of innovation contained 640Kb RAM, a 20Mb hard drive and a monochrome (amber) screen. I remember the warm glow of anticipation when it was powered up for the first time. Good old MS-DOS v3.30. A vintage car lover will tell you that there is no sound more pleasing than the roar of a well-tuned engine. A computer lover will tell you that the same sound emanating from your hard drive is less appealing. However, at least the hard drive made a noise, which is more than I can say about the PC. Still, it was a good machine and didn't deserve the treatment it recieved.
My first good intention was sparked by man's innate need for speed. Let's face it, an XT running at 4.77 MHz is not going to win any benchmark tests. I had heard about the NEC v20 chip which was a replacement processor that would boost your speed to 12MHz! Kind of like a baby-Overdrive chip. It cost me around $50, which for a kid of 13 (back in the Eighties) was a lot of money. Using all my skill and manual dexterity, I removed the existing 8088 chip from the motherboard. When I attempted to use that same skill and dexterity again, I managed to break off 12 of the 16 legs of the NEC chip, and while rendering it completely useless in the computer field, I instantaneously transformed it into an elegant and sophisticated light- weight paper weight. In tears, I ran to my father, the tiny paper weight in my hand and demanded that he take the horrible PC out of my house. I never wanted to see it again. My hard-earned $50 had disappeared before my eyes in under a second. My father, to his future amusement and my future agony, did not fulfill my request and the PC remained. He did, however, replace the NEC chip. He also inserted it into the motherboard for me. In my defense, I must also tell you that 3 NEC chips were bought in total. Another point in proving that skill and dexterity are hereditary.
The second good intention was incited by man's aesthetic desire for color. An amber monitor, while perfect for business use, rendered most games unplayable to childish eyes. Having seen the resolution of CGA on my friend's computer, I decided to push for the latest technology: EGA (Enhan- ced Graphics Adapter). None of this messing about with 4 colors. I went directly from black and white (well, amber) to 64 brilliant colors. In fact, I managed to get a Super EGA card. It not only supported 64 colors, but also supported a resolution of 800x600. A feat previously unheard of. Needless to say, none of my games would work with the new card. Devastated, I removed the card, and it died of old age in a drawer a few years later.
The third step to eternal damnation was not my fault. The blame for this one lies squarely with my father. By this time, my PC had been upgraded to an AT or 80286. It had also been upgraded to VGA. Two steps which had passed almost unnoticed by the Imp of the Perverse and were thus trouble-free. In his dealings with computer people, my father was introduced to a package called Microsoft Windows - and he was hooked. He knew that my PC did not have the necessary hardware to run Windows, and so a specialist was called in. He recommended a course of action and the motherboard was removed from its casing. The specialist sat for two hours soldering SIMM sockets onto the motherboard. Into these sockets went four 1 mb SIMMs. The motherboard was replaced into its casing and the power was switched on. The smoke alarm went off and the fire brigade arrived. After the smoke cleared, the specialist turned to us, remarked that he didn't think the motherboard supported the extra RAM, handed us the bill and left. We were able to scrape most of the fused components off my mother's dining room table and the rest were covered with place mats. Devoid of a working PC, my father shamefacedly, had to buy a new one. The new one could run Windows, but lacked the sentimental value.
The next few upgrades were uneventful and lulled us into a false sense of security. The PC now had a 386 processor, a 210 Mb hard drive, 4 Mb RAM, an SVGA screen, a mouse, Windows and a printer. During an overseas holiday, I bought a SoundBlaster 1.0 in Zurich. I'll admit, I circled the display ten times, wondering if the expense was worth it. Of course it was worth it! So what if I couldn't eat in the next 3 countries? That the card survived the trip through Europe in a backpack is a miracle in itself. My sense of security was enhanced by the SoundBlaster's painless installation. I was (I believed) ready for anything.
But I was wrong. Such a simple device, is a modem. Essentially, it allows you to communicate with other computers using a normal telephone line. It plugs into the back of your PC and sits harmlessly to the side, its red status LEDs prepared for action. The first modem was not the problem. It was a standard 2400 baud modem. The problem was that I made the mistake of upgrading it. I sent it back to the manufacturers and requested that it be upgraded to utilise MNP 5 compression and error-correction. When it returned, it looked the same and so, unsuspectingly, I plugged it in. Somewhere behind me, a fan was switched on in preparation to be hit. Nine excruciating hours later, and 21 faxed pages of documentation, I finally got the commands I needed to disable the newly aquired features, as the modem would no longer connect to any of the sites it previously could. I know I heard my EGA card laughing from inside the drawer.
Undaunted, I prepared for the next major upgrade. The 486 chip had been on the market for a while and I felt that my 386 lacked the power I desperately needed. What I needed this extra power for, I could not say, but I knew that I needed it. I went out and found the most powerful 486 on the market: an IBM 486 3/75. A true-blue IBM processor. Clock-Tripled! At the same time, I fell hopelessly in love with OS/2 v2.1. A combination I was later going to regret. You would think that an IBM processor would be able to run IBM software. Unfortunately, this was not the case. This problem took over two weeks to solve and included four overseas telephone calls. The solution? Turn off all the 486 features of the motherboard. OK, so now OS/2 ran like a dream, but my machine was back in the 386 realm. My processor, modem and EGA card were now discussing unionisation.
At the moment I have a Pentium II 350 MHz, 64 Mb RAM, a 6.4 Gigabyte hard drive, a 21" monitor, a 40x CD-ROM drive, a Sound Blaster AWE 64, a 56 K internal modem, and have never bought a new PC. I have merely upgraded it, component by component. Not a task I would suggest for the feint-hearted. In my adventures, I have come to a startling realisation. While it is more exciting to take the road less travelled by, at least on the highway you know where the service stations are.