issue #9

Want to print? Use this version

Back issues are in the Archive

Go back to the main site

Download a zip version

REM 'Letter from the Editor
Welcome to Issue 9 of Qbasic: The Magazine
ON KEY 'Hot List
This month's latest news
INPUT 'Your Stuff
Survey, Letters, Must Downloads and more!
! mov 'asm Intro: part 6
*sniff sniff*...the last part of Petter's series!
LINE 'The Gallery
Check out Lost Sock's new "Killerz"
PRINT '3d: Part IV
MA*SNART and Alias team up to show you voxels
LOOP 'Learn to Program Basic review
Pete tells you if it's da bomb or a bomb
REM 'RPG StoryWriting
Your main ami sez Generic Fantasy SUCKS!
PRINT 'Memory Handling
Mandrake gives the newbies some memory use tips
END 'Next Issue
A thrill-packed preview of next month!


Letter from the Editor

By ZKman

This issue is tres bien!

C'est de la bombe, mes amis! This issue is going to be beaucoup cool, so..umm..don't leave or anything. And if you're wondering why French is suddently de riguere to insert into my commentary, scroll on down to the mighty letters section. Just what is it that has us up in arms with joy? Why, it's five suprakeen articles by the best in the business, baby! First up to the plate is the edicion final of Petter Holmberg's seemingly never-to-end assembly series. Next week or so, we're starting a series or "in between articles" between issues, to begin with the .doc compilation of Petter's 6 month series! woo hoo!


Indian people read us, so there!

On top of that oh-so-tasty morsel is the 4th part of the 3d Series. This time, MA*SNART and Alias have worked together to demonstrate voxel based 3d, a series that will encompass 3 issues and show you some of the totally radical speed-ups they've worked out. Up at trois is Pete to review Interplay's "Learn to Program BASIC". Does it have an easy to use interface and super-speed to make it a must-use for qb newbies, or does it blow more than certain presedential accomplices?

Yours truly is writing about how much most of you suck at writing RPG plots ^_^. My first game was your traditional "save the prince/king/princess in the midevil world" kinda story, too. But you can do better! Would you rather be playing a game with the story of Xenogears or the story of Gauntlet? Finally, Mandrake is here to present an article for beginner's on a common way of saving memory for your program. You probably won't learn much if you're a qb god, but you haven't seen as much newbie qbasic code as I probably have, and ta'int a pretty sight.

In other unrelated information, I was looking thru the "Database o' contacts" and didja know that our *sniff sniff* magazine is read in 19 countries on 5 continents by more than 1000 people a month! Right now, I know of readers in: The Good ol' US of A, That Canada country where we buy our trees from, the Dominican Republic, England, Scotland, Germany, Holland, Switzerland, Italy, Finland, Sweden, the United Arab Emirates, Egypt, Thailand, India, Australia, China, the Phillipines and New Zealand. Are you from another country? Worship us Americans, uhh, I mean, contact me and let me know! Especially if you're from Kyrgyzstan or something.

Next on the agenda concerns the QBTimes (see the Hot List). A letter written to them suggested that the two of us "combine into a bigger, better magazine". Unfortunately, that won't happen. Here's why:

  • Two Editors on one magazine! Uyyy! Wait, I can't say "uyyy" anymore.
  • We both have sort of a different focus. Here at qb:tm the focus is on game development, not necessarily qb coding. That's why we have assembly, game design, exclusive info on big new games, and midi creation articles, and will have art articles, in addition to only technical articles. I believe that QBTimes is trying to present themselves much like the old Basix Fanzine, with an emphasis on technical articles.
  • Finally, with their writers like Mike Hoopman and Blackbird writing along side some of our guys like Petter and 19Day, there'd be nothing but articles like "Why MazeRPG will whip DA2" or "JumP is a much better game than Project rt ever will be". ^_^

Also, mebbe it's jus' me, but some of your aren't really the most perceptive little readers, cuz a few of you didn't seem to get our April Fools joke last month. I dunno, mebbe other countries don't have April Fools, but here all the media put in little joke stories just to annoy everyone, and we felt obligated to join them! Anyways, Cuby and Coby will not be using their pincers on various enemies in the first level of the "action strategy RPG" Project RT. It was a joke. Har dee har har ^_^.




Back to top

qbasic Hot List

Compiled by ZKman


MOTG Project going on
Soom Primal's SVGA rpg, Masters of the Galaxy, will be features on Hanson worship si...I mean, teen-based website This hit a lotta times every day site is featuring MOTG as part of their "Teen Programmer" special in an effort to get more guys to go to the site.

Even though half of the hits gets is probably from perverted old men, any qbasic game featured on a megasite such as this is sure to drive interest towards the game and our language. Check the site in the next month or so when the article will be posted.

MOTG on, a new LibSet, and Viruses



Attack of the Virii!
Well it's not the name of a bad biology film, a virus scourge has been hitting the qb world in the last few months. From neozones qboard to over the icq, many programmers have been hit by one virus or worm recently, including Angelo Mottola and myself. As some of you remember, a similar plague of viruses disguised as qb .exe's came about 9 months ago.

The most common virus found circulating in qb circles in called NetBus. This program allows others full access to your computer while you're online and runs hidden in the background, using a file called Patch.exe and altering your registry. Although it's fairly easy to get rid of, potentially more dangerous programs might be hidden within any .exe you download. The moral of the story? If you download or recieve a program from an untrusted source, make sure you get a .bas version, and check the .bas for any SHELL or similar metacommands that might invoke unwanted symptoms. If you must take an .exe version, run it through the latest virus checker just to be sure.


What's Rems up to?
The word on the street is that Martin Rampersad (Rems) is working on a Blast! style library set coded in straight assembly that, while retaining PUT speeds about that of DirectQB, is in code form and not in the form of a .qlb. Information on this one hasn't leaked out fast, but we'll try and bring you more next month.


WoS granted FREEdom
Lost Sock Software, formerly known as KSG, has announced that Wrath of Sona will remain free in it's entirety as opposed to the shareware for the final version that was first proposed. A betatest program of great breadth and depth is also underway for the title, which should insure a balanced and bug-free final version.


A Competitor enters the ring
Joining qb:tm, the Qbasic Gazette, and the now defunct QB Voice, QNews, and Basix Fanzine, is a new publication from Nightwolf Productions: The QB Times. Two issues strong as we headed into press, this magazine looks like some good competition ^_^. Featuring articles by well-known figures in the qb community such as Michael Hoopman and @bionnon and a small bit of news each ish, be sure and point your browser over to their site... once you finish the new qb:tm issue, of course =P.


DA to become open-source
According to recent webboard posts, Mike Hoopman's perennial RPG favourite, Dark Ages 1, will be released in an open source code version. Joining the qb tradition of releasing full source to your games, a tradition including Wetspot 2 and Probe, among others, expect the fully commented proggy to be released "sometime after Dark Ages 2 is completed."


The latest on the libs
Big changes for DirectQB this month, in what could be the library's final update, barring bug fixes. The well-recieved dqb1.5, after nearly a month delay, was released, including among many speed-increases, extra goodies such as an ultra-fast .fli player! As many of you know, .fli is a format similar to avi or QuickTime in that it stores movies. Can you say beaucoup cutscenes? Additional patches were released in dqb1.51, and will be included in the soon to be released dqb1.52. Dqb1.52 will also allow custom EMS use for storing any data type!

As for the other libraries, Dash production came to a bit of a standstill in recent months; however, a new SUB was added involving Palette manipulation. Don't count Dash out yet, though. XMS is already being integrated into Dash, and "Dash2", and should be ready in not that long. Also, in a move surprising no one, there weren't any updates to Blast! this month.


Qlympics leaderboard
Before we get to the leaders as of yet for the 1999 Qlympics, a special message from our main man Sonicblue: Despite how clever you might think you are, Sonicblue *is* noticing people who vote themselves a 10 and everyone else a 1, or vote multiple times. So you might as well not try. Also, if your votes seem to be an attempt to cheat, all of your votes will be discredited. Sonic is working hard to avoid the mistakes of last year's competition and make this one the best yet.

So, who's leading? Here ya go, as of press time:
Fake OS: ArtechOS
Action: SB Bricks
Adventure: 1st- Wetspot 2, 2nd- Peanut Patrol, 3rd- SpaceWar
RPG's: Dark Ages
Strategy: 1st- TF Checkers, 2nd- Puz, 3rd- MineSweeper
Text: AGS
Graphics: PB3d
File Util: FontPro
Libraries: RPGDK2
Misc: Install
PaintShops: SpriteShop

According to the results thus far (these are before adjustments are made to cheaters), it seems that the voting is pretty much what we'd expect. SFB2, one of our must downloads, is a mere 5th in the hotly contested Adventure group, and the Libraries section does not have Blast!, Dash, or dqb.


Future seizes the...IP
With taken and now Dark Elf over at, what's a qb site wanting some qbasic related domain name to do? If you were thinkin' of nabbing, it's too late now. Jorden Chamid of Future confided to us that during the coming month, future will move out of their temporary Hypermart account and over to

Enhanced also shifted websites this month, joining the fold at


Strummin' on the ol' banjo...
Virtual banjo, that is. MOD players seem to be flourishing at current, with quite a few in development for those un-midi renegades including Bill McDonald. Offering ultra-super-high quality instrumentals, expect this surge to lead to an increase in MOD usage in future qb games. Don't be surprised if you see an increase in download size to hold those .mod's either.


Das Deutschlanders!
Ich nun Deutsch...or something like that. Anyway, was also snatched up recently by Actlab and now serves to provide a good amount of German qbasic news. Sporting a spiffed up and professional looking layout, be sure and check it out if you...umm...don't know English ^_^. Actlab, of course, did a test German translation of qb:tm waaaay back there in Issue 3, so you know the site will be high quality ^_^.


LTPB Sales
Last month, we promised to bring you sales figures on Interplay's Learn to Program BASIC. Unfortunately, the sales and PR departments have decided not to release sales or predicted sell-in numbers for this title. However, they were more than willing to give figures for the top-selling Baldur's Gate. Draw your own conclusions.


Mwahaha! We ain't not be never not making none mistakes last month! At least that you guys told me about ^_^. PARTY! hehe, chalk up another first on the blackboard, and don't expect to see this message again for a loooong while.


Dark Crown, DA2, and more


Latest Game updates:
Dakrdread and Mystt have begun a "remix" of sorts for the perennial qb favourite " the Dark Crown". Featuring an updated graphics set, some gameplay changes, and an improved storyline, this looks like a game to keep your eye on. Of course, this project shouldn't cause much change in the plans for Eternal Frost, the "Story RPG" which should have a demo coming out soon.



Angelo and Petter over at Enhanced have buckled down to work on Project RT. Although the most interesting new news on the project was requested not to be revealed yet (don't worry...we'll force it out if we have to!), a possible artist for the game has been found, a prospective quasi-adventure style story has been written up, and the code is now speeding 100% bug free. On top of that, the engine is currently slated to be 100% script-based, so that every object moves following their own scripts, which would make the game fully customizable! With dqb Final Version coming this month, expect work on Project rt to progress more rapidly. Oh, and a side note to Petter and Angelo: You guys' secret projects are one and the same!

Nekrophidius and the guys over at Lost Sock have started serious work on the next project "Killerz". A 2d fighter featuring superbig sprites (see the screenshot in this month's gallery), nekro has indicated that this title will be an 18 and over title only due to heavy violence and nudity. Despite that, recent indications show a deadly cool game that could challenge SFB2 in qbasic fighter supremacy.

A few sidescrollers are making a name for themselves this month:
Firstly, Greg MacAusland's new game Agent Squeak is coming along nicely. You star as a mouse and the objective is to gather as much cheese as you can and reach the goal. Featuring 8 directional scrolling, be sure and check out the demo.

Nutzboy (Peanut Patrol) and Jason Gould (Puz, SpriteShop) have teamed up to work on the sequel to PP, aptly named Peanut Patrol 2. To feature super-speedy 8 directional scrolling and improved gameplay and graphics over the original, we'll keep you up to date on this title from 2 of qbasic's big names.

BlackBird's sidescroller JumP is also making waves for having assembly P*P scrolling approaching or faster than that of dqb's! We'll try and grab you some more info on this for next month (source: QBTimes)

SonicBlue's Space-a-Roo 2 has been seeing daily updates as of late, including such things as a full physics engine, digital sound, and MOD music. Running with DirectQB under the hood, the realistic physics means that all objects are inertia based, and unlike in some games, you can't run into a bullet you've just fired. SB also tells us that "it has REALLY good error checking" =).

The 5 member Bizzare Creations is working on an svga rpg named Kalderan. Featuring a tile by tile engine with p*p scrolling that Bizzare claims "is in some ways better than Dark Ages 2's". Dig up some more juicy info on Kalderan at Bizzare Creations.

Here's this month's Quick news...A demo was released for MOTG Project this month. Featuring zelda-style scrolling and fab full-screen graphics, it demoed the p*p walk, clipping, and collision nicely...Tomahawk and Marcade are working on a new RPG. Not much has been revealed about the gameplay, but Toma's character designs and artwork should at least make the game easy on the eyes...A C+C style game called Arrakis looks promising. With 256 color graphics, and an engine pretty far into development, this is the closest strat game on the horizon as of yet...Speaking about strat games, another c+c style game Shell Shock had a second demo released this month. Many parts of the final gameplay are already incorporated into this title...Last of the Legends is nearing completion and could be this year's first major release. All that's left is some of the scripts and beta tests...A game called SpaceWar has been generating a lot of publicity this month; more on this hot title next issue...A demo was released for Of Hell and Magic this month, and it looks very nice. Check out the smooth zelda-style gameplay...Dark Ages 2 suffered a bit of a setback due to a computer failure, in which object scripts and the map editor were lost. Expect this to move back the release for about a month.

That's all the latest news for this month. Remember, if you have any news or rumours, send them along to Qbasic: The Magazine


Back to Top

Input: Your Stuff

By ZKman



Here's another oh-so-tender feedback section...

Hey, great job on Issue #8! I'm going to have to read it again to download all the new files and stuff. Good job!

Here's my rant: You use a little too much spanish in qb:tm lately. (You also switch to some native language with 'boogle boo' and such, but I don't mind that.) For the sake of the people who are not fluent in Spanish, cut down on it a little bit. I don't really mind it (I take spanish), but I'm bored after reading issue #8 and wanted to complain to somebody.

Well, anyways, no more 'Por Que' and 'como estas'.


No te gusta cuando yo usando muchisimo espanol? Mwahaha, espanol es chevere! dije mucho ya en este lengua, ahora edicion nueve tiene palabras en frances...justo para tu!

Adios! revoir!



From last issue: "Another update occured with Seav's "The Labyrinth". This "first person tile engine" (think Legend of Lith 2, but as smooth scrolling as Doom) went to v1.7 with the latest update, which added 5 groovy tilesets and a better interface. We're looking forward to the version with the guns though."

First of all, did you download the demo and read the text file? Everything is explained there.

"5...tilesets?" What do you mean? I said I have a total of 4 wall tilesets and a tileset for the Player graphics. (You can now see each other in the 3D screen)

"version with guns"? This is the version with guns. I'm adapting a laser gun style of play. You know, see who's the better shooter by racking up points shooting your laser guns so don't expect fireworks in the game. The reason for why I didn't use conventional warfare type of guns is that it's going to be a bit complicated to program in the graphics and my primary goal is to *finish* the game.

Ver1.7 is already a playable version. Go play it with your friends and see who's the better shooter!


Hmm...about the 5 tilesets, I meant to say 5. It's 4 wall plus 1 player, for a total of 5. It should've been mentioned, though, as Seav said, that this is already a playable version, although what, again, I mean by "the version with guns" was a version where you could see the guns on screen. See for yourself at Seav's site.





I don't konw anything about the WinJammer program, but from what I've heard, it's very much over-complicated for what it needs to be. My experience with the midi composer I use, NoteWorthy, has been very good. Their interface is great and the registration fee is a mere $39 (one of the few things I've actually registered).

Respect, and keep up the good work


The reason that 19Day uses WinJammer in the examples for his tutorials is that that is the program which him, myself, and most of the major qb game composers are using right now. You can probably apply the basics from the article to the composer of your choice, though.





I just read the latest issue of qb:tm. As always, it was a pleasure!

Now I wonder about some things:
1) Where can I find the homepages for those people responsible for the NES emulators you're talking about? I wanna see them!!!

2) What's the address to Pasco's page?

3) Where did you get the idea that Project rt was going to be some sort of Wetspot 3d starring Cuby+Coby? I've certainly not discussed this with him. I think we'll have to sort this out in the next issue...

4) Where can I find DarkDread's new home page? I'd sure like to see it!!!


Nothin' like hearing from one of our beloved writers, especially one who organizes his letter nice and neat for us! ^_^

Here's some answers:
1) Go to and click on NES Emulators. DDR-NES and uNESs are done in qbasic.


3) April Fools! Bwahaha!





I was wondering if the Qbasic Magazine was printed or just an online magazine, and if printed where I might be able to subscribe. It looks very interesting. I've just started working with qbasic and am very interested in doing some programming.

Jay Weemhoff

Many people ask for you to send qbtm over email, and I know that wouldn't work. That's why I think you should actually make it into a magazine and send it out! People would pay for a subscription and everyone would love it! Just an idea^^!


If you want the newsstand edition, just send a box of M+M Peanut Butter to... heheh, actually, we don't have a print edition as of now. Unfortuanately, dynamics such as money would mean I'd probably needa sell a good 5,000 copies a month to afford the die cuts, etc., needed to print. Also, .pdf and preflighting is alot more time-consuming that html, and I don't have that kind of time now. Thanks for the words of support, though!


  I am using QuickBasic 4.5 on my work station. Now, my question is, will it pass from 31-12-1999 to 01-01-2000 without any problem when powered up and down?

I thank you for your time!


As far as I know, qbasic .exe's themselves are unaffected by the Y2k bug, and you can do a quick test for yourself by setting your computer clock ahead to Jan 1, 2000 and running Wetspot 2 or something similar. Of course, as Seav pointed out, qb program's using TIMER *will* crash if you're using them on midnight 01-01-2000 due to a midnight rollover overflow.


  You should get a forum. Your (sic) being hosted by, so you have it installed for you.

Why a forum? Well, qb:tm is every programmer's news source. A forum will allow us to discuss ideas, thoughts, whatever gets me off my um...."booty". If you already have a forum, where is it?

Also, I love the Grand Scimitar studios slogan..."Creating Fantasy, Inspiring Reality", beautiful!



Good suggestion! The reason we don't have a forum is that I *strongly* dislike that every qb site, even brand new ones, have a "general qb" forum. No one uses them when others such as the QBoard already have many users. However, much like Dark Ages Hint Board, I think a board for discussion about qbasic news could be pretty cool, especially since qb:tm has quite a bit more than 1000 visitors a month nowadays. What does everyone else think?

And thanks for the comments on my slogan.



qbasic: the magazine reserves the right to edit any letter recieved for purposes of clarity and space. But you already knew that.


Here's the results of the Issue 7 survey from Qbasic: The Magazine! We need more people to Vote! So do it!

 Favourite Game     |  Last Month  | Change    
 1. Wetspot 2              1           <> 
 2. Dark Ages (t)          2(t)        <>
 2. Mono. Shooter (t)      2(t)        <>
 2. SFB2 (t)               --          --
 2. Of Hell & Magic (t)    --          --
 Comments: The best game list stays similar to
   last month's compilation. SFB2 rejoins the
   top ranks.

 Favourite Utility  |  Last Month  | Change
 1. DirectQB               1           <>
 2. QMIDI                  2           <>
 3. SpriteShop (t)         3(t)        <>
 3. Svgalib (t)            5           U2
 3. Dash (t)               --          --
 3. GifLoad (t)            --          --

 Comments: Dash makes it back into the top, and
   dqb and Qmidi continue their hold on the first
   2 positions. PP256 drops off the list.

 Best Upcoming      |  Last Month  | Change
 1. Dark Ages 2            1           <>
 2. Last...Legends         --          --
 3. Xeno (t)               --          --
 3. Peanut Patrol 2 (t)    --          --
 Comments: Only Dark Ages 2 survives the shakeup
   in Best Upcoming. Project RT, MOTG and TheifGame
   all fail to make the top 4. Last of the Legends
   performed very well.

Vote today by emailing your votes for:
favourite game
favourite utility
Game/utility that you're most looking forward to.
Send your vote here. We should have form-based voting by next month.


You need this stuff!

Must Downloads returns for another showing. Nothing new made it to the list this month. Mebbe next time. Everyone knows that there are a god-awful amount of qb games out there, but what's worth downloading? These, my friend. Here, you'll find a list of the best of the best in QB progs. See something that should be here? Tell us and we'll check it out. You HAVE to have this stuff!

A puzzle game by The Brain where you must flip numbers in rectangular groups until you get them in order. Decievingly addictive!

Absolute Assembly
Petter Holmberg of Enhanced Creations's assembly converter. By typing in normal asm, this proggy will convert the asm into goods that qb will understand. Super-spiffy!

Dark Ages
One of the most engaging QB games ever, as well as one of the only complete rpg's. This was featured in PC Gamer! Check it out!

Groov Buggies
The best QB racer ever. Although it has some control problems and some clipping glitches, this wireframer set a new standard. the Dark Crown
Darkdread best and most complete game. Many hours of gameplay, and featuring a battle system that's been imitated in countless qb projects since. Not to mention you get cat food from the enemies!

Monospace Shooter
Gradius' 2 color side-scrolling space shooter. Featuring very detailed enemies, flickerless animation and a devious AI, this game is a classic

Wetspot & Wetspot 2
Wetspot, the bubble-bobble like block-pushing action game was one of the best QB games when it came out, but W2 is just incredible. Super midi sound, great fast graphics, tons of variety, an insane number of levels...everything you could want. GET this game. Now.

The BEST qbasic fighter. Ever. Even though it's wireframe, it has cool particles and smooth animation as well as rippin' gameplay.

Called the best tile editor in QB ever, PP256 has loads of tile-editing options at your disposal. If you use tiles in your game, you can't live without this.

These 3 sets of libraries take QB graphics to the extreme. They all have strenghts and weaknesses, but you should check them all out before you start a big project. You'll save a lot of coding plus get a big speed increase (and in DQB's case, save memory). Try these now.

This is the best version of Qmidi. Play .mid's in your game! The new qmidi4.1 rules! It has tons of features and a "light" version. Get it now!

Marko Dokic's 3d routines. Phong shading, gourard shading, environment mapping, you name it- it's here. If you want to see how to do good 3d, come here!

Longtime readers know that the Site of the Month is always chosen as a site that can provide something utterly unique in a well presented way, and is not just a file archive. is one of those places. Well known as the home of this year's Qlympics, this site also offers in-depth reviews of the files that they have, a well-designed homepage, and lots of blue, which we like ^_^. For these reasons, is this month's qb:tm Site of the Month.

Home of the Qlympics

Back to Top

assembly tutorial

By Petter Holmberg

It's the end of the series as we know it

Hello and welcome to the sixth part of my assembly tutorial series. This part is also the very last one. No!!! I hear you screaming ;-) But the reason for this is basically that I have covered almost all of the important aspects of assembly programming. There's more to learn- there's always more to learn, but I think you'll have more use of other documents from now on. This series has been concentrating on the general aspects of asm programming. Now you are ready to start exploring stuff that interests you in particular. Maybe you want to learn more about interrupts, or you may be interested only in I/O port programming. There are lots of good documents to download about every aspect of assembly programming. It's not necessary for me to explain everything.


Grab Absolute Assembly 2.1


So, what should this last part be about? For the first time in this series, it hasn't been easy for me to decide. Therefore, this part will cover some miscellaneous stuff, mostly about some of the general aspects of assembly programming. I'll try to share my experiences of asm programming with you so you don't have to all the mistakes I've done.

Numbers in assembler:
When programming in assembler, it's very important to know how numbers are stored in the registers, the stack and the memory. It's especially important to know the difference between positive and negative numbers and how they are stored.

We begin by looking at positive integer values, i.e. the numbers 0,1,2,..,n: Positive integer values are the easiest ones to store. When you need to use a positive integer value in your asm code, the first thing you want to ask is: How high numbers do I need to store? It's easy to select the number of bits that needs to be used for storing a certain value. If you use n bits, the biggest number that can be stored is 2^n - 1, so if you use 8 bits, you can store any number from 0 up to 2^8 - 1 = 255. With 16 bits you can store any number up to 65535 and so forth. If you only need to use a number smaller than 100, you shouldn't use 16 bits to store it as 8 bits are enough.

The different bits in a binary number are numbered from right to left. The rightmost bit is called the least significant bit and it has the bit number 0. The leftmost bit is called the most significant bit. If it's an 8-bit numbered this bit is bit no. 7.

If you want to calculate what number you get if you set a certain bit to 1, you can calculate this with the following formula:

n = 2^b

where n is the number you want to know and b is the number of the bit. So if you set bit 5 to one, the number you get is 2^5 = 32.

Numbers that can only be positive are called unsigned values. A signed value is a value that can be both positive and negative. It's called signed numbers because the most significant bit of such numbers tell the sign of the number. If we have a positive value, the most significant bit is 0, but if we have a negative value, the most significant bit is 1. So 0 means + and 1 means -. This means that a signed number needs one extra bit just to store the sign of the number, so we get a lower maximum value with a certain amount of bits if we use signed numbers than an unsigned number. The biggest signed number that can be stored with n bits is 2^(n-1) - 1. So if we have an 8-bit signed number, it can have the maximum value of 2^(8-1) - 1 = 127.

The smallest signed number that can be stored with n bits is -(2^(n-1)), so with 8 bits, you can store any negative integer down to -(2^(8-1)) = -128. Thus, an 8-bit signed number can store all interger values from -128 to 127. Positive values are stored in the same way no matter if the number is signed or unsigned, but negative values are stored in an interesting form: The most significant bit is set to 1 to indicate it's a negative number, and the rest of the bits represents the maximum possible value with those bits plus one minus the absolute value of the negative number plus one. So if you have the 8-bit binary number -10, the most significant bit will be a 1 to indicate it's a negative number, and the rest of the bits will represent the number 127 + 1 - 10 = 118. This form of storing positive and negative numbers is called the two's complement.

If you want to convert a number from positive to negative or negative to positive, you could use the SUB instruction to subtract a value from 0, like this:


This would work fine for all numbers. But you could also use the special assembly instruction NEG. NEG works just in the same way, but it's faster, takes less place in the memory and it's easier to understand what happens when you see a NEG instruction than if you see a SUB instruction. The syntax for NEG is simply:

NEG destination

The destination operand can be either a register or a memory pointer. So if you have the number -10 in AL and execute the instruction NEG AL, AL will become 10.

Sometimes it's necessary to convert an 8-bit number to a 16-bit number or a 16-bit number to a 32-bit number. This is easy if you have a positive number. For example: If you have a positive integer in AL and you want that number to be treated as a 16-bit value in AX, you only need to make sure AH is 0. But what about negative numbers then? How do you convert a number in the two's complement form upwards? Luckily, there are two instructions that does this for you. They're called CBW and CWD, short for Convert Byte to Word and Convert Word to Doubleword. Their syntaxes are:


Note that they don't have any input/output operands. That's because these instructions only works with the AX register. If you have an 8-bit number that you want to convert to a 16-bit number, you should put it in AL, execute a CBW instruction, and you'll get the correct 16-bit value in AX, no matter if it's a positive or a negative integer you've converted.

If you want to convert a 16-bit value to 32 bits, you should put it in AX and execute a CWD instruction. The result will be stored in DX:AX.

When to create an assembly routine and how to do it:
A little assembly code can often mean a huge improvement for a BASIC program. However, it's important to know when to use it and when to avoid it. There's no use to rewrite everything in assembler. There are two reasons you may have to write an assembly routine: It will speed up your program, or it will enable you to do something that you cannot do in QuickBASIC.

The speed issue is the most common reason for using assembly code. It's a well known fact that in an average program, 90% of the execution time is used to execute 10% of the code. By rewriting those 10% of the code into assembler, 90% of the time, your program will run faster. It's important to learn how to find those 10% of source code. Usually, it's something that is repeatedly called by the main program loop and involves a lot of calculations. If you manage to pinpoint the part of your program that slows it down the most, you should consider rewriting it in assembler.

It's also a good idea to use assembler when you need to do something that is hard to handle in QuickBASIC. One example of this was the keyboard handling example in the previous part of this series. The keyboard functions in QuickBASIC doesn't let you control the keyboard at the level we often need for computer games, but with a little assembly, we get all the control we want.

When you know what you want to rewrite in assembler, you may think it's going to be easy to implement your idea into a working routine, but you may be surprised at how hard it is to write the routine. Transforming your ideas directly to assembler can be very hard because you have to take so many technical issues into account. You may find that you run out of registers, that you start writing really unstructured code or that you simply don't know how to do some things in assembly.

My experience in assembly programming has told me that the best way to go is this:
First, start writing your routine in BASIC. This way, you'll be sure that you know every step in the process of writing the routine, and you don't have to mind about registers and other low-level stuff.
Then, start optimizing your code. Try to push your BASIC code to its limits. Even if the code still is terribly slow, you will discover how you can make it faster and better. If you wrote everything in assembler from the beginning, you probably would have missed these enhancements. Put comments everywhere in your source code so that you know what each line does.
When you have an optimized BASIC version, start rewriting it in assembler. You shouldn't try to make the final version right from the beginning though. Start by writing a pseudo-version, where you use variable names instead of registers and skip some low-level stuff like setting the memory registers correctly when you want to get a number from the memory. Make your assembly code similar to the BASIC version, so that you know exactly what you're doing. Put LOTS of comments into the code so that you know what every line does.

When you have your pseudo-version finished, start transforming it into a working version. Change variable names into registers, use the correct code to get a number from the memory and so forth. Put in even more comments, as the code will get harder to understand. The commenting should be so extensive that you can tell what each line of assembly code does just from looking at the comments. Divide the source into separate parts by using spacing and commenting, so that you can isolate the different parts of the routine just by looking at the layout of the source code. Even if you know what you're doing right now, you may have forgotten it after a few days. Looking at your own asm source without understanding it is really frustrating. DO NOT try to optimize your assembly code yet, try to make it work first. You will probably have a lot of bugs when you first run your routine, and you must fix them all before continuing.

Now when you have a working assembly routine, you may want to try optimizing it even further by using smart assembly code. This should be the final step in the creation of your routine. If you start optimizing right away, you're risking to lose control over your coding, but if you have a working routine without optimizations to look back on, you will still know what you're doing and you know that your routine works even if you don't manage to optimize it so much.

Make sure your comments still explains what the routine does. Your optimized code will be harder to understand than the original version, so you need to watch out.

If you follow these steps, you stand a good chance of getting a really well- written and terribly fast assembly routine!

Optimizing your assembly code:
It's one thing to optimize a BASIC program by using assembly code, but you can also optimize your assembly code to gain even more speed.

Optimizing assembly code is a whole science itself, and I could probably write another tutorial series as long as this one just about asm optimization if I knew enough about it. There's so much to say about assembly optimization that I can only cover some of the basics here.
When optimizing an assembly routine, it's not enough to just make the separate instructions run faster by using smarter code. Many times you also need to look at the code as a whole and ask yourself what the code's actually doing. Your code may run at an near-optimal speed based on what it does, but maybe it's doing more than it has to. For example, you may have a routine that has a very time-consuming MUL instruction inside of a loop. You manage to make it run a lot faster by using a SHL instruction instead, and you think you've been very clever. But if you had taken another look, you might have discovered that you're actually doing the same multiplication over and over, and it would have been enough to do it once before the loop and save the result in a register for later use. By moving the MUL instruction above the loop you would probably have gained much more than by changing it to a SHL instruction.

Keep in mind though, that because your assembly code is so fast from the beginning compared to BASIC code, it's often unnecessary to mind about optimizing it. If your routine runs adequately fast for your program, it's better to leave it unoptimized since it's more readable that way. But it can also be really important to optimize your assembly code because it runs so often. Concentrate on optimizing loops and other assembly code that runs frequently. If you don't have room for all your variables within the registers, use the stack or the memory for the values you use the least, and save the free registers for the code inside loops.

Switching Registers:
Sometimes you need to exchange the values of two registers. If you only use MOV to exchange them, you will need a free register for temporary storage of one of the values. For example, if we have one value in AX and one value in BX and we want them to switch places, we could do this:

MOV CX, AX ; Store value of AX temporarily in CX
MOV BX, CX ; BX = CX (which is the old value of AX)

If you need to do this and you have no free register, the only solution seems to be to push a value to free a register, but there's a better way. You can use the instruction XCHG, short for eXCHanGe, to do it. The syntax for XCHG is:

XCHG destination, source

Where the source and destination operands can be registers or memory pointers. However, the source and the destination cannot both be memory pointers at the same time. With XCHG you won't need a temporary register, and thus the stack doesn't need to be used either.


Earlier parts of Petter Holmberg's assembly series can be found in the Archive. They are in issues 4 thru 8.


Remove your jumps!
Another way to make your code faster is to avoid jumps in the code. This includes loops. Let's suppose you want to increase the AL register four times. The following solution seems obvious:

LOOP IncLoop

But what's actually happening when the computer executes this code? Well, this is how the computer sees it:

Set CL to 4
Increase AL
Decrease CL
Is CL 0? No: Jump back one line
Increase AL
Decrease CL
Is CL 0? No: Jump back one line
Increase AL
Decrease CL
Is CL 0? No: Jump back one line
Increase AL
Decrease CL
Is CL 0? Yes: Continue execution

Now suppose that we rewrote the code into this:


When this code is executed, this is what the computer does:

Increase AL
Increase AL
Increase AL
Increase AL

As you can see, a loop isn't always the best choice. Replacing loops with repeated code is called unrolling. If the loop is executed so many times that it's not practical to unroll it completely, you can do a partial unrolling. For example, if you have a loop that executes 80 times, you can change it to a loop that executes 10 times with 8 copies of the loop code inside it.

It's not only certain instructions that makes an assembly routine slow: Wait states, bus transfers, the prefetch queue and dynamic RAM refreshes can also steal time, and avoiding these bad guys can be really hard.

For every new CPU that's released, assembly optimization becomes less important, not only because the processors get faster and faster, but also because they execute time consuming assembly instructions more efficiently. A MUL instruction for example, isn't as slow compared to an ADD instruction in a Pentium as it was on the 80286. On the other hand, the Pentium can execute several assembly instructions simultaneously if they fulfill certain requirements, so it's possible to optimize asm code for a Pentium by using these new features.

Finding errors:
One of the biggest pains of writing assembly code is to find and eliminate the bugs. Once you're done writing an assembly routine and tests it for the first time, it almost never works properly. Since the error often hangs your computer so that you have to restart it, you'll probably get no hint at where the error is. All there is to do is to start going through your code and search for bugs. This can be very hard and time-consuming. Here are a few ways to make the debugging easier:

First of all, "execute" the code in your head and try to see what the routine is actually doing. Write it down on paper and you may discover that you're doing something wrong.

If you still have problems finding the errors, try to execute only a part of your program. Take the first snippet of code, insert a JMP to the end of the routine and return the values that you're working with to the BASIC program so you can look at them and see if they're correct so far. Then, move down the JMP instruction a couple of lines and see if everything still is correct. If you continue doing this, you will eventually find out where the computer hangs and where the error is.

Keep in mind that some assembly instructions doesn't work with certain combinations of registers, memory pointers and direct values. if DEBUG won't accept an instruction that may seem correct, it may be because you're using a combination of input/output values that cannot be handled by that instruction.

Also, make sure the call to and return from the assembly routine is done correctly. Many times, I've struggled to find the errors in completely correct assembly code that won't run, just to find out that the error was in the CALL ABSOLUTE line in QuickBASIC. Check this before you start searching for errors in the assembly code.

There's an error in CALL ABSOLUTE assembly routines that's so common it's important that you know about it. It's very nasty because you don't have to write a single line incorrectly to get this error. It has to do with the DS register. Be VERY careful when you set the DS register. You already know that it's important to push the value of DS before you change it and POP it back at the end of your program, but there's another thing you have to know about DS. When you set it to another value than the original you won't be able to fetch values passed from QuickBASIC. Consider the following code snippet:

PUSH DS ; Preserve DS
MOV BX, A000 ; Set DS to A000h
MOV AX, [BP+08] ; Get a variable from QB
POP DS ; Restore DS

Even if this seems correct, AX won't get the value of a QB variable. The value it will recieve is the value at DS:BP+8, which isn't the correct address. You must make sure DS points to the segment address it points to from the beginning if you want to read from or write to QB variables.

Doing nothing:
If you feel an urge to do nothing for a while, the assembly language has an instruction just for that: NOP. The NOP instruction takes up one byte in the memory, and when it's executed... Well, nothing happens at all! The syntax for NOP is:


Even though it doesn't do anything, it takes up a little amount of time. Actually, NOP is equivalent to XCHG AL, AL, which, of course, doesn't change anyhing.

It may seem silly to have such an instruction in the assembly language, but there's actually some use for it sometimes, for example if you want to leave some empty space in a program for data to be initialized later on. The NOP instruction occupies one byte in the memory.

And that was the final thing I had to say. I hope you've enjoyed this tutorial series and that you've managed to understand everything. Thanks to everyone who's sent me emails with comments on and suggestions for this series. If you want to learn more about assembly programming, there's LOTS of good info to find on the Internet. For example, Check out:

I thought I could finish with a list of all the assembly instructions we've covered in this series. This list divides them into groups based on what they do and explains their different functions. Try to tell what they mean before looking at the explanations and see if you know them all!

Good luck with your assembly programming!

List of assembly instructions:

Name       Meaning

Data transfer:
MOV       Copy values between registers and the memory
PUSH      Put values on the stack
POP       Get values from the stack
LODS      Load string
STOS      Store string
MOVS      Move string
IN        Read values from I/O ports
OUT       Write values to I/O ports
NOP       Do nothing

CALL      Call subroutine
RET       Return from subroutine
RETF      Return from subroutine in another segment
JMP       Jump to another offset address
LOOP      Perform a loop
INT       Call interrupt routine
IRET      Return from interrupt routine

CMP       Compare two values
TEST      Compare two values
JB        Jump if Below
JBE       Jump if Below or Equal
JE        Jump if Equal
JAE       Jump if Above or Equal
JA        Jump if Above
JL        Jump if Less (signed)
JLE       Jump if Less or Equal (signed)
JGE       Jump if Greater or Equal (signed)
JG        Jump if Greater (signed)
JNB       Jump if Not Below
JNBE      Jump if Not Below or Equal
JNE        Jump if Not Equal
JNAE      Jump if Not Above or Equal
JNA       Jump if Not Above
JNL       Jump if Not Less (signed)
JNLE      Jump if Not Less or Equal (signed)
JNGE      Jump if Not Greater or Equal (signed)
JNG       Jump if Not Greater (signed)

Data manipulation:
ADD       Add two values together
SUB       Subtract value from another
INC       Increase value by one
DEC       Decrease value by one
MUL       Multiply to values together (unsigned)
IMUL      Multiply to values together (signed)
DIV       Divide value by another (unsigned)
IDIV      Divide value by another (unsigned)
NEG       Negate value (invert its sign)
SHL       Shift bits to the left (unsigned)
SHR       Shift bits to the right (unsigned)
SAL       Shift bits to the left (signed)
SAR       Shift bits to the right (signed)
ROL       Rotate bits to the left
ROR       Rotate bits to the right
AND       Logical AND (1 if both bits are 1)
OR        Logical OR (1 if one or both bits are 1)
XOR       Logical XOR (1 if one bit is 1 and one bit is 0)
NOT       Logical NOT (invert bit)
CBW       Convert byte value to word value (signed)
CWD       Convert word value to doubleword value (signed)

Tell Petter that Norwegians give better massages than Swedes at this address.


Back to Top


By Zkman


This month in the gallery is "Killerz" by Nekrophidius. Although early in dev, it looks pretty freakin' cool, dontcha think?



Back to Top

3d: Part IV

By Alias and MA*SNART


In Ma Snart's 3D articles, he describes many methods of making 3D polygons, textures, and such, the things that can be accelerated with 3D cards. There are many ways of drawing 3D objects, and thankfully, they are not all polygons. The one I am going to talk about in this series is the voxel method. Ma Snart mentioned these vaguely, saying he preferred them, but he's not planning on covering them, so I will.

Alternate 3d method: Voxels


A voxel is hard to describe, but I have one analogy that may work: in 2D space (screen space) we have PIXELS which are approximations of area. They are square, arranged in a grid, and can be set to any color possible.

A voxel, on the other hand, is an approximation of volume, in 3D space. They are arranged in 3D grids (more on this later) and can be set to any color OR transparent. This way, we can make a volume-based drawing of an object, as opposed to recreating the surface of the object, as we do with polygons.

The big analogy here is the 3D / 2D counterparts. For example, a cube is the 3D counterpart of a square, a line is the 2D counterpart of a plane, a sphere is the 3D counterpart of a circle, and a pixel is a 2D counterpart to a voxel.

Now we can really get into voxels. As I said, a voxel is an approximation of volume. The most effective way to simulate a volume is with a cube-shaped volume. This way, when your 3D grid is drawn, there are no gaps. However, drawing a cube is horribly slow, and drawing enough of them to simulate a small item would bring any Cray XMP to its knees, let alone actual PCs! So, we have to fudge a little. We cannot draw a full cube, but on any of the 6 sides of a cube, it looks just like a square. So, where there should be a cube, we will draw a square that is large enough to completely cover the visual area a cube would cover. With that in place, we can draw a voxel knowing that it will look alright, and that there will be no gaps between pixels.

By the way, if your voxels are too small you will get gaps between them, which are quite visible - and very ugly. If you experience gaps, increase the size of your voxels one or two, and see if that makes a difference. I have seen many people try to do just points for their voxels - it doesn't work. You have to use squares larger than one pixel, typically 3-5 pixels wide. Another good idea is to pick odd numbers for sizes, that way, the voxels will be evenly centered, instead of being biased half a pixel in one direction. Biasing is a serious problem, especially in small maps, as two adjacent voxels may go in opposite directions and leave an empty spot, or gap. As I cannot possibly emphasize enough, GAPS ARE BAD.


Voxel-based Rendering...


Alright, now we have the basics of how to draw a voxel, how do we make our really cool 3D object? Before we do that, we have to understand 3 different types of voxels: landscape, list, and grid. Landscapes are the most popular and the most useless. They are simply height maps of a ground level. The landscape that is drawn from them usually looks very realistic. We will not be covering landscapes yet. List and Grid voxels are basically the same thing, just organized differently. A grid voxel map is a 3-dimensional array that holds points in a 3D grid. When the voxel is drawn, every point is translated, projected, and drawn (or not drawn) in and according to its color. For the example in this series we will set color #0 to be transparent, and any voxels in color 0 will not be drawn. As for list types, this is a list of the x, y, z, and c values of each voxel. For this method, color 0 will be visible and drawn. List voxel maps are generally considered more versatile as they can be larger and more complex and faster, but they have the drawback of being more difficult to create and program.

The first example we will do is a grid voxel. First, we have to dimension our voxel (16 x 16 x 16 in this example; you can make yours whatever you want, should you choose to write your own code) and fill it with proper values. This is one of the biggest challenges in voxel technology, because there are not many ways to represent a 3D grid on a 2D screen very well. MA SNART has, conveniently enough, created a program that solves this problem elegantly. It is easy to use and powerful - a great combination! Have a look at voxeler.txt in the zip file for the documentation. Voxeler.bas is the actual program. It requires no special libraries.

Now we have to translate and project the voxels. Code for this is already in place in the editor (press D to turn on, < and > to rotate) so make a cool voxel and have a blast! The actual code is in there somewhere but MA SNART said he hadn't organized the code well, and, er, he was right. If you can separate the program into something more modifiable, send it here. Oh, yes, and if you make a really cool example voxel, send that here too!

Just for those of you REALLY curious, the voxels are not truly projected. They are translated in an isometric projection, but I will not cover that until article 3.

Included in the ZIP file are several example files. Loading them is easy, just look in the editor documentation for instructions on loading. Saving is equally easy, just be sure to send us your best work. A list of example files is in voxeler.txt.

Next time we are going to do alot - firstly, we are covering list voxels and landscapes, as well as a thorough revamp of our current editor, rewritten for flicker-free DirectQB. 'Till then!

Explain to alias that you already wrote a renderer that does 50,000 voxels/sec on a P100 here.

Download the voxel editor!

Back to Top

LTPB Review

By Pete

Beginner's Tool or Interplay crap?

Last year, Scott Mathews, Executive Producer of Presage Software came up with an idea. The idea wasn't to make the next full-length epic RPG or an action-packed first person shoot 'em up game. The idea hadn't been tried since the early 90's, in the world of 386's and Windows 3.1 . He planned to re-introduce BASIC to generation-X teenagers so that they could make their own games, be it a full-length epic RPG or an action-packed first person shoot 'em up game.



Mr. Mathews took his idea to Interplay, creator of games like Baldur's Gate, Redneck Rampage and Fallout 2, and told Brian Fargo, CEO of Interplay, of his plan. Brian approved, and soon, a team of programmers began to convert the non user friendly BASIC of the early 80's to an error-trapping, spiffed up and gutted-out BASIC of the 90's. They called it "Learn to Program: BASIC", and it was on store shelves within months.

This is where I come in. One day, while reading one of my sister's educational software order forms for school, I spotted a CD-ROM with the word "BASIC" written in huge letters on the side. The Scholastic book company does a horrible job describing their book order items, so I figured that the only way to investigate further would be to actually buy the CD.

Six to eight weeks later, my sister came home with a pile of Babysitter's Club books and Oregon Trail games, and handed the LTP: BASIC box over to me. I opened it up, finding a couple warranty papers, a manuel and a workbook, and of course, the CD. I popped it into my CD-ROM drive and was on my a world of "Game making made easy!"

Learn to Program: BASIC is a BASIC interpreter that takes BASIC programming to a new level. It is also a teaching aid that teaches you how to program in LTP: BASIC. It makes it user friendly, easier to learn and use, and is thoroughly documented to make it so that you will have absolutely no problems looking up help on a command or subject.



"Gonna go surfin'..."


How it works:
Learn to Program: BASIC has three main areas. They are the Lessons section, the Projects section and the Freestyle section.

The Lessons section has tutorials that teach you how to program in a step-by-step order, going from the very basics to much more complex commands and programming ideas. Each lesson is a movie where "Media Man" and his dog, "Goo", the cubist - like characters that teach you how to program teach you about that particular programming subject, and the commands associated with it. They explain things like variables and REM statements in a way that is ammusing and easier to understand than a plain old text tutorial. In these movies, you will be asked to perform tasks, while being guided by your two "teaching assistants". If you are having trouble understanding what they told you to do, pop-up windows and they will help you along until you understand it. If you ever don't understand something, you can press the back button to do that part of the lesson over again, or when you finish, you can start the whole tutorial from the beginning. At the end of every lesson, there is a text review section that is meant to be printed for later review, that discusses the high points and most important parts of the lesson you just went through.

The Projects section is a section with programming examples that cover every command somehow, and are meant to help you learn. They are by professional programmers, and are thoroughly commented and set up very nicely. Most are in the form of a game, and some are very fun. Read through all of the code and figure out what each line does. This will prove to be extremely helpful in learning about how to use code and developing algorithms. In each of these projects, there is a hint section where Media Man and Goo tell you what you should notice in the code, and how to modify it to make it more suitable to your taste.

The FreeStyle section is the section where you actually get to program. This is a complete BASIC interpreter with about 120 commands to choose from. Many commands are the same as the ones in the original BASIC, but others are new. LTP: BASIC has a built in .bmp and .gif loader, a built in .wav sound player, built in mouse commands, automatic sprite masking and background buffering, special graphics save and load formats, and, get this, a Quicktime movie player. All of these things are not standard issue in BASIC or QBASIC. LTP: BASIC runs at spectacular speeds, depending on your computer, and has no memory limitations, except until you fill your RAM completely. Yes, that's right, variables are saved directly to the EMS or XMS memory. LTP: BASIC has all of these complicated and hard-to-do in BASIC or QBASIC things done for you, so the programming is much less difficult.




System Specs

90mhz processor, 40mb hard drive, Win95 or Mac7.5+, 16mb ram, svga monitor, directx
















Qb:tm Verdict

PROS: Good documentation, fast, lots of added commands

CONS: No subroutines, no machine access, aimed at young kids



Your palette is permanently set, and can only be changed when you open a graphics file that has a special palette. Every color gets a number (like in QBASIC or BASIC), but also has a name like "Bunny Slippers" and "Autumnal Splendor", and the colors has a pop-up screen where you can pick the color, and it inserts the number. Also, along the top are drop down menus with every single command, organized in it's own category so that you can click on it and it will be inserted for you. If you ever use a command wrong, there are instant pop-up windows with hints and guides that are much more helpful than the error messages in QBASIC. This language seems perfect, but it does take a lot away from the actual coding process, with all of this done for you. You still, however, have to type out REM and LET, but the REM statements are made green in the text window so that you can notice them faster.

When you have your program finished and ready to run, just click on the "Run" button on the bottom of the screen, and your program will begin. The program runs in the small box beside the screen, but you can resize the program run area to the full screen. Also, if the program gives you trouble, you can just press the Stop button. It will terminate the program just like Control + Break does in QBASIC. No closed loops that will keep your computer in an endless cycle like in the original BASIC, forcing you to turn your computer off and start again. The graphics capabilities are limited to one screen, at 315*235 with 256 colors. The screen is squared down to fit the small run window beside the program window better.

The Workbook for LTP: BASIC is an excellent guide to programming. It goes over algorithms, gives you challenges with answers to test your programming skills and has a very good dictionary in the back, layed out not unlike the QBASIC help file. The Workbook goes over a few projects, and has many coding examples. Also included is the manuel that tells you how to use the program and what each menu and tool is for. Also included is a paper that has every LTP: BASIC command, with a small description and an example of how to use it. This proves very helpful if you are hacking away and forget the syntax of a command like "SetTextLayer" or "ResumeUpdate". These commands look more like subroutine names than actual commands. The CD-ROM also is loaded with tons of other coding examples, like the ever-famous Eliza, towers of Hammurabi, answers to the challenges in BASIC form so you don't have to type them in, examples of how to use every single command, and many other .BAS files are found there, many are very fun games.

However, there are some imperfections. Learn to Program: BASIC's features are faster and better, but much, much more limited. Half of the commands in QBASIC aren't in LTP: BASIC in any way, shape or form, and the commands in LTP: BASIC won't let you do a lot of things that make QBASIC great. You can't open any files except for LTP: BASIC graphics files or files with special commands meant for that file. There are less commands that you can use to build a subroutine that moves a mouse cursor or load a data file, and more that just do it for you, making it so that you can't do many things that are easily done in DOS-based languages.

The commands that they do give you have long, hard to remember names like "SetTextLayer" and "GetSpriteNumFrames" which will slow down the coding process and are annoying. The bar at the top with drop down menus to choose a command makes it hard to find the command that you want, and you spend twice as much time trying to find it as you would have spent typing it in. Media Man and Goo are SO annoying that it's not funny. They use humor that will only appeal to eight year olds, have dumb sound affects for no reason, and spend more time taking away from the lesson than teaching you. They dance, dress up, jump around, and act like Looney Tunes. The only thing that they're good for is to give a kid an epileptic seizure. The actual program is slow at some points, the sound is junk, and the only thing I find a bit appealing is the Freestyle mode without the two little cartoon characters running around on the screen.

1.) Menu / Layout
The menu and layout in this is pretty average. It's not set up completely illogically, and many parts of it can be rather helpful. The layout's pretty good too, and a lot of it's customizable. Some things are hard to find in the menu, especially in the FreeStyle section. There are animations that go with almost every part of the menu, and it is easy to use and abuse.

I liked the animations and general cleanliness of the menuing system, which was split up according to sections.

Some things were just too hard to find in the menus!

2.) Graphics and Sound
Very annoying in the case of Media Man and Goo, but the language's capabilities for sound and graphics are superior to QBASIC and BASIC's. It really depends on the section that you are in that determines the sound and graphics quality. The sheer number of graphics that are in the menu and in the lessons and projects is remarkable. I like the huge ammounts of graphics, but next time, they could use the CD's extra space on adding a couple more commands. The sound for the lessons and projects isn't as bad as the graphics in some places, but it's not top-notch.

Lots of graphics and sound affects, and the graphics and sound qualities of LTP: BASIC are far superior to QBASIC and BASIC's.

Goo and Media Man and their stupid stunts and comments. Much space devoted to this when it could have been used on the LTP: BASIC compiler.

3.) Features / Flexibility
Learn To Program: BASIC has many features, but little flexibility. The features are outstanding - imagine an automatic Quicktime movie player in QBASIC! The flexibility is low, however. You are limited to the commands that they gave to you. You can't even have subroutines outside of the main program! Your commands had a lot of features, but could only be used to do one thing, which should have been fixed. These two categories kind of cancel each other out.

The commands had LOTS of really neat features.

There just wasn't enough thought put into the language. Sure, there were a lot of nice features, but you're pretty much stuck having your game have lots of sound effects and graphics, but little else.

4.) Documentation
Superb documentation. Interplay did an excellent job on this! There is a workbook, a manual, a paper telling you each command in alphabetical order, plus tons of programming examples, built-in lessons, coding examples and a very good help menu. It doesn't get much better than this!

Everything! You'll never get stuck with so much user-friendly information at your fingertips!


5.) Overall Impression
This language is perfect for beginners and first time programmers. I wish I had this when I began programming. After you have programmed in other languages, though, you start to realize that this doesn't have nearly all of the flexibility and freedom that you want in it. If you are a newbie, I suggest getting this, otherwise, it's a waste of money.

Great language for first time programmers.

After you have programmed in higher class, more flexible languages, this is too easy and too "one - way oriented." This language is good for making simple action games, but not much else. If you would like to find out more about LTP: BASIC, go to their official site,

Hey, Pete! Back in my day, we learned qb4.5 in DOS...and we liked it! So there!.


Back to Top

RPG Story Writing

By Zkman

  Roleplaying games are by far the most popular breed of qbasic title in existence. From Lianne to Dark Ages II and the wealth of other rpg projects being worked on now. But, for many of these titles, story and plot seem an afterthought, instead of the majority of design that they should cloak. "SVGA color" and "an amazing battle system" can't make up for this lack. Within, qb:tm will discuss 3 points that are critical to any RPG's success: backstory, events, and character interaction. So sheath your sword and come in for the ride.

Story and Plot *can't* be an afterthought


We'll be blunt: "You're a fantasy prince on a mission to rescue a princess/brother/father" doesn't cut it anymore. Influences such as Advanced Dungeons and Dragons and the Ultima series seem to have made people think that an RPG means swords, taverns, and orcs. While not the worst possible story we can think of, generic fantasy is too often predictable, is overused, and (ask many veteran programmers) will often leave you too bored to finish your project.

Since the halycon days of computer design, great strides have been made on story design both on computer and on pencil and paper roleplaying. Instead of making a generic fantasy RPG, try looking at some of today's popular Roleplaying games for influence. What about Cyberpunk, where a form of the internet is more dangerous than weapons; or Fallout, where pimps and fantastic characters populate a post-apocalyptic scene; or Homeworld, where you are the last member of a spacefaring race trying to find it's home. Besides offering greater events and chances for character growth, these stories will seem more interesting to players of your game.

Instead of going sci-fi or generic fantasy, try looking at historical literature for rpg story ideas. How about a game set in renassaince era Italy, with ruling families, and lots of seafaring? Or what about a game where you play a pirate running from British galleons whilst trying to "salvage" some booty from passing mercantile ships? Possibly being an American GI on a mission to assassinate Hitler in 1944 could be interesting? Maybe the Salem Witch trials, Imperial Japan and China, or Ancient Babylon are more along your lines. There are infinitisimal different backgrounds to use for your game; don't limit yourself to "Orcs and Trolls" fantasy

Of course, if you really want fantasy, a background like Shadowrun's, where elves jack into networks, and cyborgs battle dragons could be more along your lines.


Non-Tolkein fantasy settings...


Events are the things that people will remember about your game years after they play it. They won't remember drinking beer at a tavern with Gehenna, but they might remember when a high-level NPC sacrifices himself muttering that "he will return...much stronger". They won't remember that they got 4032 gold in Dungeon 6B, but they might recall a Player Character dying, such as Aeris in FF7.

The things to remember when thinking up "events" are: Death, Explosions, and "Boss Fights". Many classic books feature one of the main character's dying, because this is something that will strike a player's heart. It's not enough just to have the character be struck down by an orc, though. Having a character sacrifice themselves, or die at the hands of an enemy who will reappear later in your game will inspire your character to keep playing. In non-fantasy settings, exploding something such as the main enemy's weapon, or having the enemy destroy the character's hometown, will have the same effect.

Remember that blindly fighting battle after battle can be tedious. Be sure that events are fairly frequent in your game, and the player will continue and enjoy it more.


Is your character in love?


Character Interaction
There are three main parts of character interaction to keep in mind: PC to PC, PC to NPC and PC to enemy. And by character interaction, I don't mean "Hello, MATT. Go left to my castle!". Watch some of your favourite movies or read some of your favourite books and see the qualities that occur between the characters. Is there a love interest between two of the main characters? Does the villain taunt the hero? You can apply all of these to RPG's.

Player Character to Player Character interaction is fairly important, as theoretically, a group of players will remain together throughout the entire game. After events, perhaps their "friendship" towards each other will grow better or more hostile. Maybe 2 of the characters will grow a dislike of each other and you have to sort it out. Perhaps one of your PC's will become depressed and it's up to you to cheer him up and keep him fighting. In a game featuring only one main character (such as Zelda), PC to NPC fills the void left by the non-interaction the main character will have with other PC's.

Love between two main characters has occured in nearly all famous literature and cinema because it adds more realism and depth to the monotonous enemy fighting. Many popular video games have drawn on this fountain, such as games in the Final Fantasy series, and even Super Mario Brothers, and you should definitely keep it in mind when designing your characters.

PC to Enemy Interaction is the final thing that we'll talk about. First, you should write down some words to describe your enemy. Is he an enigma to the PC's, well-known in the world, or does the main character know him as a childhood friend? The main enemy and his cohorts should appear regularly throughout the game and should have a well-defined mission that the characters will discover. Riddle Games and taunting are also effective gameplay and storyline elements.

Hopefully after reading this document, you guys' will be able to see the ways to create interesting and original Roleplaying storylines. And remember, Generic Fantasy sucks!

Do you wish there were no RPG's and all of us wrote Pong clones? Lemme know.


Back to Top

Memory for Beginners

By Mandrake

Free up some memory in your game

This is going to be really basic, so you experts out there probably won't need this. If you already know some of this stuff, again, don't complain to me, it's really simple. Not that it's something everyone uses or should use, it just frees up a bit more memory in your game.


Simple, yet effective

What is a memory handler, you ask? Well, it's a way of keeping memory at a stable level and still being able to import and export lots of information. Now, take your normal RPG in QB(there's alot of 'em). Most of them load ALL of the tiles at the begining of the game, using Bload. The problem with this is that you have to create an array for each tile, and DIM it for the memory size. Now with 20-30 tiles, at 16*16 it's not too bad, but, once you start getting to about 200 or 300 tiles, 20*20 x and y size. it takes up your whole program!

Now, what can we do to fix this problem? Take away alot of tiles? But then the scenery gets repetitive and you can't have really cool giant statues and the such. We could create an easy Memory handler for the tiles....but how do we do this? It's actaully quite simple. Say you have a total of 30 tiles for each map(which is quite alot, esp if you have 10 maps), DIM arrays for only 30 tiles then. Then for each map create a tileset consisting of a list of those thirty tiles. How do I do this, you ask? Easy! Open an asii editor(notepad, or QB) and type in the list of tiles like so:

"grass.pix","mountain.pix", and etc until you reach all 30.

Remember, you need to list 30 tiles always, and have each tilename in"" and seperated by a , ...if not, you'll get an EOF error(end of file). If I write a future article, it will show a more advanced procedure useing Dynamic memory and Def Types and arrays and such so that you can have a diffrent number of tiles for each map, each varying in size and such.

In your game, change the load tiles sub so that it loads the tiles for the map seperatly then the sprites, titlescreen, etc.. Now, make it so there is a tileloading sub that loads the tiles according to the tileset like so:

(warning! untested psuedocode!)
SUB tileload(tile$) 'tile$ is a variable used to hold the tilesetname.

INPUT #1, tile1$,tile2, etc,etc 'these are the variables used for tilenames

'now you Bload the tiles, by using the varaibles above. ie: load tile1$(the tile from the tileset listed first) into the array known as tile1 make sure the array and the variables are both shared

OK, to use it in your program, each time you load a new map load the tileset that goes with it like so:


Alot of you might be asking yourself "but, won't that slow down my game?" not if your only loading 20 or 30 tiles, the map loading will probably slow it down more than the tileloading(for an example on the speed of the loading, download the Project S demo. It uses a variation of this technique, and loads around thirty tiles per map, without more than .03 second delay on my ancient 486 sx!). And, a little bit of slowdown for a lot more memory is worth it(esp since you can have unlimited number of tilesets without lowering the memory).

You can also use a version of this for sprite loading, this way you can have diffrent sprite classes and some neat-o special effects without wasting any extra memory.

There, simplistic but it gets the job done. This is not the one I use in the upcoming Project S, that one is a alot more complicated and handles all the arrays, not just the tiles, and will use XMS when I'm done with it. If you guys would like to see a follow up article getting more complicated but having even more usefull and intellegent automatic memory handlers, then email me at:

I am also thinking about writing an article on Object Oriented programming in QB 4.5 using user Defined Types(not only is it possible, but really easy), email me if you would like to see this tutorial(I'm not going to waste my time writing it if no one is going to read it).

Until then, remember that we are all just a dream of the Red King!


Tell Mandrake that real men like getting Out of Memory errors.


Back to Top

next issue

By Zkman


Our next scrumm-didlyumptious issue will arrive on the 15th, in the very merry month of May, as Porky Pig says. Look for mind-booglingly good schtuff such as s'more Voxel excitement, and, should the deal fall through, an article by Terminator_Z which'll just be ultra-rad. On top of that, in our continuing goal of being the magazine of qb *games*, not just qb progging, we've brought in Gavan, the artist from Dark Ages 2 to give you some tips on making your art jus' as luscious as his. To brighten your day even more, we bring the 3rd inductee to the Qb:tm Hall of Fame, and we should have a form-voting method for the survey! Yeah! Also, don't forget to register your QB company with the Visionaries Exchange. Till next time... END

Ya don't hafta go home, but you can't stay here

Back to Top