REM 'Letter from the Editor
Welcome to Issue 4 of Qbasic: The Magazine
ON KEY 'Hot List
News from the QB world
INPUT 'Your Stuff
Survey results plus yer letters!
! mov //Asm Intro
Petter Holmberg presents the start of a new asm series
OPEN 'Welcome to QBASIC!
New to QB? Your PRINT and LINE is right 'ere!
REM 'Lib or not to Lib
Should you use progs like dqb or Dash?
PRINT 'Too Much qb
Seav tells us "You know you've had TOO much qb when...
PRINT 'Memory Limits
What are qb's memory limits? How can you get around them? END 'Next Issue
What's up in our next issue?
Hello, and welcome to the biggest Qbasic magazine EVER! This month, there has been a LOT of news...check out the Hot List and you'll see what I mean. From the passing of Milo to the announcement of a Mario World clone, there's a lot to feast your eyes on this time around.
But what do have in the way of features? TONS! 19day enthusiastically endorses DirectQB1.1 in his review; what can you say about an ASM lib that natively uses EMS? NetherGoth brings us another article for beginners with GET...PUT; everything from masks to BSAVE can be found in this article. Pete presents us with an article about the RPG glut; why do so many QB rpg's look the same?...but are still gobbled up by the handful. Aaron Severn's wonderfully extensive SVGA tutuorial comes to an end this issue with Part III. Here you'll find some ASM samples for SVGA as well as a program that shows you how to do SVGA. Hal_8900 tells us about the biggest battle in QB today...QB4.5 vs C++. Here's what's good and bad with both, and how C++ stacks up against our beloved QB. Finally, I review the BIGGEST release this month for QB, and probably the biggest since Wetspot 2....SFB2 by Lbt1st. Find out why this game is mucho cool.
In other news, I'd like to wonder why people put down RPG's so much. As soon as some people hear about an RPG, they immediately thrash it... just because it's an RPG doesn't mean it's a copy...have an open mind!
Back to top
Compiled by ZKman
09.24.98 1:00AM: Milo has passed away
Last month, Qbasic: the magazine reported that Milo (aka Gradius) had fallen into a coma and had been given only 2 days to live. Although the entire QB community prayed for his recovery, Milo passed away on September 24, 1998 at 1:00 AM. "Milo Seldacek's memorial Guestbook" has been set up at Neozones. Be sure to visit and check out what others have said about Milo and his contributions to Qbasic. Milo will be remembered most for the way he helped anyone who needed it and also for 2 of his games: Monospace Shooter, a 2 color, super fun, superbly animated, space shooter with a deadly AI and NitroFire EX, one of the First hi-color racers in QB and still considered one of the best in that genre.
Microsoft cracks down on Qb piracy
According to a recent leader from the manager of the QB top 50, The Interactive Digital Software Association (IDSA) is working with Microsoft to shut down and possibly seek legal action against web pages that offer a free download of Qbasic 4.5, PDS7.1 or Visual Basic on the grounds of piracy. The Qbt50 urged sites to remove qb4.5 from their site so they aren't shut down. Many members of the QB community continue their fight to make QB4.5 free, however, and, although it is tougher now, you can still find qb4.5 on some smaller sites if you've lost your "one and only copy (wink)".
No more QB? Enhanced Creations new hobby
Based on reports from the Enhanced Creations website, it is rumoured that Enhanced, creators of Wetspot, Wetspot 2, and DirectQB will be lowering their QB output in favor of coding with DJCPP, a C compiler. It is presumed that this will not affect future versions of DirectQB. Based on the site, it seems that Petter Holmberg is the one more interested in this new platform and Angelo Mottola has many more Qb products lined up.
Tsugumo's The Game: CANCELLED!
The Game, whose demo released last year by Tsugumo was hailed as one of the greatest graphical achievements in Qb of all time, has been Cancelled. The demo was basically just a showoff of the graphics engine and Tsu apparently thought that the gameplay just wasn't original enough to continue. Other than Darkdread's "lianne and the dark crown", no qb game has been more influential that "the Game". It's graphic style has been used in many upcoming RPG's, such as Eldim, Marconian Dreams and Relics, and it's cancellation is sad news for all those awaiting the ambitious full version.
Pb3d: Qbasic's new dimension
Marko Dokic's latest release of his 3d engine must be seen. This engine does some stuff in 3d that has never been done before, like Bilinear Filtering, Phong Shading, and Environment Maps. The package comes with many 3d objects to feast your eyes on and can be had from quixoft
Analogue: Leaving QB forever?
Analogue (aka Apester) posted a webboard message recently that, in effect, the QB scene is not fun for him anymore, and he was done with it. According to the post, at least for now, the next version of the great ApeDraw tile editor and his RPG, Marconian Dreams, have been indefinitely put on hold. We hope that Analogue changes his mind and comes back to the best coding community in the world!
SFB2: Lbt1st releases his super cool fighter
SFB2, the wireframe fighter built using Lbt1st's Slash engine, (see the full review), was released on the 4th of October to much acclaim. Hailed as the greatest fighter of all time by many (replacing the aging Sphere Fighter), Lbt1st sets a new benchmark for Qb games and offers many interesting gameplay ideas like the awareness bar, and also features a super-cool particle engine. Check it out!
Minigames: The next big thing?
An insane number of Minigames have been released this past month, leading many to wonder whether mini games are the wave of the future. These games, usually made in a weekend, have offered such topics as Bus-driving and pizza delivery. Qbasic: the Magazine doesn't think that minigames will ever totally supplant the current crop of big projects, but some of them look to be very interesting.
Neo's Qboard: Should it be members only?
Due to the increasing amount of flaming and pornography posts on Neozones' Qboard, many are suggesting that he implement a "members only" setup. Basically, you would have to sign in before you posted and if you posted porn or something like that, it would be easier to track and keep you from coming back to the board. Neo has already started tracking IP addresses, so a members only board seems a logical next step.
Latest Game updates:
Quite a bit this month in the way of announcements... Super Mario World clone: Danny Gump of VirtuaSoft (DashX, The Mystical Journey) has announced that he will be develop- ing a Super Mario World clone for QB! The demo shown on his site shows the game to use the exact music and graphics as SMW for the Super NES, but the animation is a bit choppy at this point. Other than that, the game looks INCREDIBLE! SMW clone uses the Dash set of libraries to do the double layering that Shigeru Miyamoto's classic is known for. We look forward to it! Go check out the demo now at Danny's site,VirtuaSoft. Slash Development Kit: Lbt1st (SFB2) has announced that he will be releasing a Slash Developers Kit sometime in the next few months. Slash is the wireframe and particle engine that is used in SFB2 and animates objects VERY smoothly, so this could usher in a new wave of wireframe games. What kind of tutorials will be included in SDK is not known, but if you're starting a 3d product, be sure and check this one out. Yousuf Philips is in the process of creating some stuff we've never seen in terms of graphic loading for QB. You can see early versions of OPENPCX, OPENBMP, and OPENAVI, which is the first avi opener in QB! Right now, the bmp opener only does 8 bit and the avi player only does 24-bit in black and white, but Qbasic: The Magazine has learnt that a 24-bit fast- loading, perfect bmp opener has already been completed and that a 24-bit color .avi opener is nearly finished! Be sure and check them out. Late Breaking game announcements...Marcade is developing a C+C type game called Low Radiation. Not much about it is known, but strat games are severely underrepresented in QB now, and this game should help alleviate the problem...QMIDI 4.0 has been released by Jesse Dorland! More on this next issue... A new RPG announcement that looks like it might have potential is "Beyond Destiny". More on this later...
Okay, we admit, there were a couple...umm...mistakes in last issue. First, the address for alternate logic was printed wrong. Be sure and check out their wonderful stack of tutorials at this address. Also, we mentioned that Zapbatz' upcoming "colony" was a Space Combat sim: it is in fact a futuristic SimCity like game. Sorry!
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
Here's what you had to say about last month. Be sure and send us more letters soon!
I visited your page and noticed you have an area for upcoming stuff. Could you put WoodLands on there? Thanks. Really good page, by the way.
Pyrus is referring to the "Visionaries Exchange". This is a collection of all the QB dev houses and their current pro- jects. We want all to join! Find out what to send us by going to the submit page.
Hello, Grand Scimitar Studios,
I just want to tell you how good Qbasic Magazine is. I decided to write an article for the October issue. You don't have to put it in, I would understand. I like to write, and I like QBASIC, so here you go: (enclosed article: Why the QBASIC RPG craze won't die - editor)
As you can see, Pete's article is included in this issue. If you can write or just want to get somethin' off you mind, send it in to Qbasic: The Magazine. We'll publish most articles we recieve.
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 first survey from Qbasic: The Magazine!
Favourite Game | Favourite utility | Looking forward to 1. Wetspot 2 1. DirectQB 1. Pasco Soccer (t) 2. Dark Ages 2. DashX 1. Dark Ages 2 (t) 3. Star Wrek (t) 3. PP 256 (t) 1. Wanderlust (t) 3. M. Shooter (t) 3. Qmidi (t) 1. Vampira (t) 3. Wrath of S. (t) 3. QBsvga (t) 1. SVGA dash (t) 3. Sfb2 (t) 1. Space-a-roo 2 (t) 1. Woodlands (t)
Help us break the tie! Vote today by emailing your votes for:
Game/utility that you're most looking forward to.
Send your vote here
Welcome to our new section: Must Downloads. 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!
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!
The best QB racer ever. Although it has some control problems and some clipping glitches, this wireframer set a new standard.
Lianne...in 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!
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.
One of only 2 fighters in QB (the other being Sphere Fighter) this newly released game is Super-fab. 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! And version 2.0 only has a footprint of a few KB's, so this is super cool.
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!
For everything you can say about the site being updated about once a millenium and how the webboard has had lots of problems (you need only look on the Hot List every month to find out what they are), you can't deny what a great resource Neo's site is. The QCity collection of programs is very extensive (although it is missing some of the newer stuff). The Ask Tek section has answers to near every question that newbies ask...if you're stuck on something, be sure and check ask tek first. And the webboard...this thing is alive! Tons of posts (more than any other Qb board that I know of) and most people there are willing to help you with any problem you need. Qbasic: The Magazine is proud to present Neozones with the very first "Site of The Month" award. Check it out.
Back to Top
(Editor's Note: This article uses techniques for SCREEN 13. They may not work in other screen modes)
The following is what I have found out through trial and error (as well as a bit of logical guesswork). While I have found it to work on every machine I have tried it with, do not assume it is so for your machine. Instead, pro- ceed with caution. While none of this should cause major problems (ie. I do not believe it will trash your machine or anything), a wrong step could cause your machine to lock up, forcing you to reboot. Anyway, this is intended for informational purposes only. I cannot be held responsible for the use/abuse of the information contained herein, nor can I be held responsible for any damage done to the person or the machine on which the examples contained in this document are run upon. Just the standard disclaimer to CMA!
If you find this information useful, and choose to include the techniques in your own code, please be kind and mention my name. You don't have to do this (hell, if I mentioned everyone's name I have learned from, that list would be a mile long!), but it would be nice.
I wish to thank Jason Grooms - for guiding my first steps into the wonderful world of assembler (back then, 6809), and to Brent Dill, for showing me how to do strange and crazy stuff with GET/PUT, and a host of other tips. Brent, if your read this, contact me. I'm on the 'Net. I know you are worth your salt to find me. L8r!
Calculating the buffer size for GET/PUT in mode 13:
1. Take the width of the area you are getting (in pixels) and multiply it by the height (in lines). This will give you the total number of bytes in the area for the buffer.
2. Find the total number of WORDs to use by dividing the number of bytes by two. We need the total number of WORDs because the smallest variable type we can use is an integer, which is WORD size (2 bytes).
3. We now have the amount of space needed to store the area we want to GET. But BASIC needs a couple of more pieces of information in order for GET and PUT to operate correctly. These two pieces of information are the width and the height of the image! It needs these two items in order for the PUT routine to know when to stop drawing. So, the width and the height of the image area must be stored with the image data itself. These two values are placed into their own WORDs at the start of the buffer. We must add on two WORDs to accomodate this.
4. We now have the total number of WORDs needed to DIMension an integer array to hold our image data. Because the base of the array starts at zero, we will subtract one from our total number of WORDs to DIMension our array:
DIM buffer%(# of WORDs)
5. Our buffer data layout looks like so:
WORD DESCRIPTION ---- -------------------------------------------------- 0 Width, contained in the high byte of the WORD. This value is in bits (!), and so must be divided by 8 to find out the number of pixels (bytes). 1 Height, contained in the high byte of the WORD. Value in number of lines. 2 Start of data... . . . XX End of data...
1. We have a 16x16 sprite. So we need 256 bytes in order to hold an area this big.
2. We need the number of WORDs, so we divide by 2, giving us 128 WORDs.
3. We add two words to accomodate the width and height values needed by PUT, giving us a total of 130 WORDs.
4. We subtract 1, and dimension our array:
5. Our buffer data layout looks like so:
WORD DESCRIPTION ---- -------------------------------------------------- 0 Width, contained in the high byte of the WORD. This value is in bits (!), and so must be divided by 8 to find out the number of pixels (bytes). 1 Height, contained in the high byte of the WORD. Value in number of lines. 2 Start of data... . . . 129 End of data...
Multiple Image Buffers for GET/PUT:
What was shown above was an example for a simple buffer to hold a single image to be used in GET/PUT. Using the above simple example, we would just do the following
in order to GET/PUT a single simple image. But what if we needed 30 sprites (say for a game)? We could do this
DIM buffer1%(129), buffer2%(129),...,buffer30%(129)
then use GET/PUT to move everything around, but this is wasteful, and not very easy to work with. What if we wanted animation? What then?
Fortunately, there is an easy way out, using what is called offsetting. We have a buffer of a set size we are GETing and PUTing with. What isn't being shown is what is called the offset. An offset is a number added to a fixed value to obtain a new start value. When we dimension an array, the start of that array is obtained and kept by BASIC (we can use VARSEG and VARPTR to find it if we wanted to). If we say DIM a%(20), then say a%(2)=15, we have used an offset of 2 from the start of the array and placed 15 at that pos- ition in memory. A similar thing is done by GET/PUT. Note the following:
DIM buffer%(129) GET(0,0)-(15,15),buffer%
is the same as:
DIM buffer%(129) GET(0,0)-(15,15),buffer%(0)
We just didn't use the offset of zero in the first example! What would happen if we did the following?:
DIM buffer%(129) GET(0,0)-(15,15),buffer%(10)
We would get an error. This is because we need 130 WORDs of space for the area we are trying to GET, and we only have a total of 130 WORDs to play with. By trying to put an offset of 10 into the mix, we overrun the end of the array by 10 WORDs! The following would work:
DIM buffer%(139) GET(0,0)-(15,15),buffer%(10)
Now WORD number 10 would hold our width and WORD number 11 our height, and 12 through 139 would hold our data. We could then PUT(100,100),buffer%(10),PSET and everything would work fine. Now what would happen if we PUT(100,100), buffer%(0),PSET? We would either get an error or garbage, because PUT wouldn't have the correct width and height info in the first two WORDs! So, we need to keep track of the size so we know what offsets we can use when GETing and PUTing our images.
Our example is a 16x16 sprite. We would like to have 30 of these for our ultra cool game we are writing. We need 130 WORDs for each of these sprites (2 for width/height, 128 for data), and we want 30 sprites, so we need a buffer that is 3900 WORDs long (130 WORDs x 30 sprites). We know that every 130 WORDs is a new sprite, so that will be our offset. If we set our offset to 0, then we are on the first sprite, 130 is the second, 260 is the third, and so on. The following shows how:
DIM sprite%(3899) spritenum%=2 GET(0,0)-(15,15),sprite%(spritenum%*130) spritenum%=5 PUT(100,100),sprite%(spritenum%*130),PSET
Before you can put a sprite, you obviously need to GET it, so that PUT has the width/height info to work with. So lines 4 and 5 wouldn't work in our example unless we changed line 2 to "spritenum%=5".
We now have an easy way to GET/PUT a whole mess of sprites on the screen using a single buffer that is easily accessible. We could do simple animation with this system. Say our first five sprites were already in the buffer and they were an animation of some type. To flip through them, we would do the following:
FOR spritenum%=0 TO 4 PUT(100,100),sprite%(spritenum%*130),PSET NEXT spritenum%
It is that easy.
Our buffer layout now looks like this, for those interested:
WORD DESCRIPTION ---- -------------------------------------------------- 0 Width, contained in the high byte of the WORD. This value is in bits (!), and so must be divided by 8 to find out the number of pixels (bytes). 1 Height, contained in the high byte of the WORD. Value in number of lines. 2 Start of sprite0 data... . . . 129 End of sprite0 data... 130 Width, contained in the high byte of the WORD. This value is in bits (!), and so must be divided by 8 to find out the number of pixels (bytes). 131 Height, contained in the high byte of the WORD. Value in number of lines. 132 Start of sprite1 data... . . . 259 End of sprite1 data... 260 Width, contained in the high byte of the WORD. This value is in bits (!), and so must be divided by 8 to find out the number of pixels (bytes). 261 Height, contained in the high byte of the WORD. Value in number of lines. 262 Start of sprite2 data... . . . 389 End of sprite2 data...
And so on...
The only other thing you need to keep in mind is buffer size versus sprite size. As noted before, a 16x16 sprite needs 130 WORDs in order to store it completely in an array. When you have multiple sprites in an array, there is a limit to the size of your array you can have. This limit is 64K - 65536 bytes, or 32768 WORDs. To find out how many sprites you can store in a single array, divide 32768 by the number of WORDs required for each sprite. Drop any values after the decimal (that is, take the integer, drop the remainder), and this is the maximum number of sprites you can store. For our example of a 16x16 sprite (130 WORDs), this works out to be 252 sprites. Take that number and multiple by the number of WORDs per sprite, subtracting 1, to use for DIMensioning the array: DIM buffer%(32759).
The following table breaks down common sprite sizes and array dimensions:
Sprite Size Number Array Size (in WORDs) ----------- ------ --------------------------------- 8 x 8 963 34 for sprite, 32741 for array 16 x 16 252 130 for sprite, 32759 for array 32 x 32 63 514 for sprite, 32381 for array 64 x 64 15 2050 for sprite, 30749 for array
If you need more sprites, you can split them over two arrays. Animation and such becomes more difficult to handle, but it can be done.
Also remember, the larger the sprite, the more data the computer has to shove around. Stay away from the 64 x 64 sprites, except for maybe big bosses or such. These things are memory HOGS. The only other limit to be aware of is QBASIC's 160K limit on program AND code size. One buffer of sprites (252 sprites) will eat almost 64K, leaving you with less than 100K to put the rest of your code in! QuickBASIC and PowerBASIC users shouldn't have any problem though. Some of these problems may be overcome by using EMS routines to shove the sprite data into extended memory, though.
GETing and PUTing without The BOX:
If you have ever used GET and PUT, you know that when you PUT, a "box" is left around your image obliterating anything under and around your sprite. This looks very ugly and unprofessional in a game. The following shows the best way to get rid of this problem, using a method called sprite masking.
1. First, for each and every sprite you create, create a "mask" for it. This mask is the same size and shape as the original sprite, only it consists of only two colors, 0 and 255 (or &H0 and &HFF for you hex folks). Color all visible portions of the sprite (those portions you want to obscure the background) with color 0. Color all invisible portions of the sprite (those protions you want the background to show through) with color 255. Remember, you need one mask for each sprite, and this will knock your sprite count down by half, so keep it in mind when designing your game.
2. To display your sprite, simply PUT the mask image down using the AND op- erator, then place the sprite image down using the OR operator. The AND and OR operators are called bitwise boolean operators, and have the following truth tables:
AND OR ------------------- ------------------- IN1 IN2 OUT IN1 IN2 OUT ------------------- ------------------- 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 1 1 1 1 1 1 1 1
These tables basically mean the following. If you take two bits and AND or OR them together, the result equals a 1 or a 0 depending on the inputs and the relationship between them in the truth tables for the operator in question. If you understand this - read on. If you understand this and are 10 - 14 years old, you don't need college (just kidding ;).
Now, for what we are doing, we have a background of different byte values (which consist of a series of bits). Our mask only has two values in it, the byte 0 (00000000 in binary) and the byte 255 (11111111 in binary). Let me show you how the magic works:
A. Our Background Image AND Mask = Result 11110110 11111111 11110110 11110110 11000011 11000010 11110110 11000011 11000010 11110110 11000011 11000010 11110110 11111111 11110110 B. Our Result OR Sprite = Result 11110110 00000000 11110110 11000010 00111100 11222210 11000010 00111100 11222210 11000010 00111100 11222210 11110110 00000000 11110110
If you notice, I have used 2s in place of 1s on the final result to show the example better. Those 2s should really be 1s, so don't let that throw you. Suffice to say, if you look carefully, we have placed our 8 x 5 sprite on the background, without the border showing.
GETing and PUTing without The BOX, method 2:
The next best way to GET and PUT without the box showing, is to simply not draw those pixels in the first place. The only way to do that (short of mod- ifying BASIC itself) is to write your own PUT routine, to skip over any pixel of a defined color (0 in our case). This would have two advantages: Number one, your sprite could be drawn faster because you only set the pixels you need, and number two, you wouldn't double your buffer requirements for sprites because you would only need the sprites, and could eliminate the masks! All sounds good until you try to write the thing in BASIC...it is horribly slow (ok, on a fast system, it runs at an acceptable pace). The only way to get around this is to code it in a lower level language (or at least one that can compile down to a faster version). I have done this, and you can find the results of my labor in the ABC Packets. It is called the Blast! library. It allows you to do the above, and much more. Check it out!
Back to Top
Since about January first, the QBASIC community has gone crazy about Sprite based RPG's. Ever since Dark Crown has been released, everyone's wanted to make an RPG. Everyone from newbies to experienced programmers all want to make the all-new epic RPG to take the QBASIC community by storm. Very few RPG's have been finished since the infamous Darkdread disapeared. The reason is that a lot of programmers are very lazy, and have other things to do. RPG's get put on hold, because programmers don't have time, or get too frusterated by "Out of Memory"or other errors to continue. They are usually not taken off of hold, and the idea of the RPG fades in the programmers mind, after a few hours of work, a demo, and ten screenshots are completed. It's pathetic that programmers with so much potential can fail...
We've talked about why RPG's fail, but not why they are started. I think the reason that RPG's are started, and why programmers like to play them so much is because programmers like to do things themselves. They like to figure out puzzles, make goals, and most of them like epic, (mostly fantasy) stories. And of course, all programmers have a passion for playing video games. If you mix these ingredients together, you've got a person that wants to make their own game with a long, epic fantasy story, make their own decisions, not go through some C++ programmer's courses that he lays out in his order, with a story that can't be different every time you play.
What I'm trying to say is that programmers have personalities and hobbies, and are not copies of the other people in their school that do have personalities. They can make their own decisions, and don't depend on someone else to do things for them. They want to play role playing games because they want to play the role of a character, just like they want to play the role of their lives. They want to make an RPG for the same reason: they want make an epic story where you (the player) make the choices for him or her, and make their own story. And they want to do it on QuickBASIC-their hobby.
Now, if you would excuse me, I have to go work on my brand new, epic RPG that's going to take the world by storm. Or not...
Back to Top
SFB2, a wireframe fighter released on October 4th by Lbt1st is the BEST qbasic fighting game ever. Admittenly, it only was going against fairly old titles like "Stick Fighter" and "Sphere Fighter" (which, when released, was one of the best looking qbasic games!). The engine works very well, the graphics, although improvable, do the job, and the help (Dojo Master) is fairly good.
This game offers quite a lot in the way of new gameplay ideas in a fighter; some have not even been seen in professional titles. The basic way to kill a guy (the object of the game is to kill all 12 other fighters) is to punch and kick him till his health goes down, but that's not the only way to win. Each player has an awareness bar...making a big hit on the opponent causes his bar to go down, but it you try a special move (of which there are many!), your awareness will drop. So, if you just use special "super-attacks" and don't fight up-close, you'll kill yourself before you kill the opponent! Also, you can kill your enemy by knocking him into spikes on the wall or ceiling in some levels. Mucho cool!
Graphically, the game looks ok, but has some problems. First, the engine (SLASH) is an all wireframe (like Groov Buggies). Although doing flat-shading might decrease the speed, Qbasic: the Magazine is sure that the game would still play at a good-framerate with the lambert shading, especially if it was done with the asm codes. Also, the wireframe causes some clipping problems; occasionally, it seems as if you're walking right thru the enemy! The final problem is the text...it's regular, background-destroying SCREEN 12 text...it doesn't look pretty. On the other hand, the animation of the characters is supreme, they look very natural when they punch and kick, almost like mo-cap! The particle engine looks very cool too; lots of little red bloods come out of a guy when you pop 'im (heheh).
SFB2 offers alot in the way of customizability. You can assign attributes to your players hand strength, leg strength, etc. (which changes what specials you have available to you). You can even give your guy a big swinging ponytail! The interface is sort of clunky, though, so it might be hard to figure out the first time around.
SFB2 is a fun QB game, and a must download for anyone interested in seeing how to do a good Qbasic game. It's not the greatest ever, but it's sure to eat up a bit of your time, especially considering the amount of strat guides/cheat codes that are being released for it. A very commendable effort; be sure and pick it up.
Back to Top
With the recent releases of Dash and the evidant obsolesance of Blast!, one might wonder if things could get any more confusing, but alas, Angelo Mottola of Enhanced Creations (WS2) has brought into the scene, his own lib, called DIRECTQB.
This lib is actually quite good, not to mention to auto EMS handling with saves mucho mem, but most of it's functions are quite good, and are basically the same as Dash's.
Dash has a sprite scaler and rotator, and DirectQB is going to have them soon, and you can see the two of them playing catch-up against the other, each making versions of the others' subs. DirectQB's flaw though, is in this newest version, 1.1, where it continually crashed on me when trying to play sounds (but from EMS no less) but I'm sure those will be ironed out in no time.
How does DQB stack up against DASH, well, rather nicely really. The EMS support pushes it's rank up high, and it's potential is staggering, but DASH, I'm sure, will meet the challenge.
But in a direct comparison, here is a small test I preformed, this is not to represent the entire lib's preformance, just a hint of info...
I compared the putting of sprites with DirectQB and DashX, I made an ALL.QLB than contained DQB and DASHX in one. I made a simple 30*30 sprite that was GET'ed normally, and put it at 1,1 using DQB and then DASHX. The loop was similar for both...
a! = timer for k% = 1 to 20000 'the put, whichever one was being tested next k% b! = timer times! = b! - a!
Both were identical, and both just pasted the sprite directly to the screen, as this was just a test of sprite speed. And here are the results on my P2 MMX 233 comp...
DirectQB: 3.621094 seconds
DashX : 3.132813 seconds
This may be different on other comps, but this is what I got, and since TIMER would have been equally inefficient for both, I regard the results as accurate. I tried running it a few times, and the results were basically the same, with only a changed in the 5th sigdig.
I give, DirectQB a rating of 9 out of 10, and I'm sure it will get that extra point when it has been completed.
(Editors Note: This is a review of Version 1.1: Version 1.11 fixed the bug in the sound player and a font maker is in development independently by 19day)
Back to Top
First things first
QB and C++ can't really be compared one next to the other. Obviously, there hasn't been a new version of QB since the early 90's. C++, however, is still constantly updated, which automatically puts it ahead of QB. This wouldn't be that much of a problem, except 386s were still common in 1992, but nowadays, with processors like the K6-2, QB doesn't have the same built-in capabilities as the new versions of C++ that appear regularly.
Another point that should be recognized, is that C++ ISN'T an acronym for Beginners All-purpose Instruction Code. BASIC is.And since Quick BASIC is an obvious derivative of BASIC, it will be inherently easier to learn. Some people would also take this to mean that it is not as powerful as other languages, but this is not necessarily true. I'm not saying that C++ ISN'T easy to learn, but the beginning programmer would generally find it easier to use QB first. This ease-of-use is one thing that's a definite plus for QB. Well, enough of the jabbering, back to the point. Just because QB may be an EASIER language to learn, that doesn't mean that it is less powerful than c++. There has been a lot debate about the power of QB and the power of C++, but I still believe that QB IS as powerful as C++, it just isn't as easy to access that power. I remember way back when, a lot of people thought that you couldn't access EMS or XMS in QB. Nowadays, there are quite a few methods to go about accessing the two. Other people thought that SVGA Color (16-bit, 24-bit) wasn't easily accessible in QB. That's what I thought too while making some SVGA color routines of my own. One day, however, I stumbled across Aaron Severn's QB site and found his SVGA routines for high-res and 15 and 16 bit color. There are quite a few other myths about what QB "can't" do, but I am too tired to think of them hehe. The point is, there are a lot of things QB CAN do, if the programmer really puts his mind to it.
To lib or not to lib
As of late, there has been A LOT of discussion on whether or not libraries should be used in QB. Right now, though, I'll talk about C++. One of the big points for the "QB IS BETTER THAN C++" group is that C++ can't operate without it's precious libraries. While this is true to an extent, those people have their facts kind of mixed up. You can't make a decent C++ program without using any of the built-in .h files, *BUT* this actually helps C++ more than it hinders it. When you want to make a simple text program, you really only need the IOSTREAM.H file and the STRING.H file. In QB, when you make a simple little text program, you get all the text functions, and all the input functions, and all the math functions, and all the graphics functions, and so on included. This is why programs made in QB are generally a little larger than other programs. Now, back to libs in QB. I think libraries like DirectQB are great. They help the programmer make a 2-week game look like they spent a lot more time on it, without 1 months worth of effort. Although I talk to Drew Vogel on IRC once in a while, I disagree with his opinion that "libs suck!" Not everyone wants to spend two months working in assembly to make the routines to make their pac-man game awesome, especially if there's someone out there who's already made the routines they need, AND they're giving 'em away! Of course, there is always 1 rule that goes along with using libs: Give credit where it's due - Don't say, yeah, I did EVERYTHING in this game myself! I'm sure it wouldn't kill ya to let the world know that you used BLAST!.
To sum it all up
I know I didn't get a lot accomplished through this little paper. Really, you are the only person that can decide whether or not QB is as good as C++. But before you go rant and rave about how QB is better than C++ or vice versa, make sure you know the ins and outs of each language. I still have the opinion that you can do anything in QB that you can do in C++ or any other language, but, it may be just is a little harder to do it in QB.
Back to Top
By Aaron Severn
(This article is continued from Issue 2. This is all the appendixes and they show you EXACTLY what everything does....also look for an 'svgalib' program at the bottom of this article)
Appendix A - Required TYPE definitions and descriptions
VgaInfoBlock, returned by VESA function &H00. TYPE VgaInfoBlock VESASignature AS STRING * 4 VESAVersion AS INTEGER OEMStringPtr AS LONG Capabilities AS STRING * 4 VideoModePtr AS LONG TotalMemory AS INTEGER Reserved AS STRING * 236 END TYPE
VESASignature - contains the characters "VESA".
VESAVersion - specifies what version of the VESA standard is in use. The higher byte specifies the major version number. The lower byte specifies the minor version number. Features of older versions are guaranteed to work in later versions.
OEMStringPtr - a far pointer to a null terminated OEM-defined string which may be used to identify the video chip, video board, memory configuration, etc. to hardware specific display drivers.
Capabilities - describes what general features are supported. The bits are defined as follows.
0 - DAC is switchable 0 - DAC is fixed width, with 6-bits per primary color. 1 - DAC width is switchable. 1-31 - Reserved
ModeInfoBlock, returned by VESA function &H01.
TYPE ModeInfoBlock ModeAttributes AS INTEGER WinAAttributes AS STRING * 1 WinBAttributes AS STRING * 1 WinGranularity AS INTEGER WinSize AS INTEGER WinASegment AS INTEGER WinBSegment AS INTEGER WinFuncPtr AS LONG BytesPerScanLine AS INTEGER XResolution AS INTEGER YResolution AS INTEGER XCharSize AS STRING * 1 YCharSize AS STRING * 1 NumberOfPlanes AS STRING * 1 BitsPerPixel AS STRING * 1 NumberOfBanks AS STRING * 1 MemoryModel AS STRING * 1 BankSize AS STRING * 1 NumberOfImagePages AS STRING * 1 Rsvd AS STRING * 1 RedMaskSize AS STRING * 1 RedFieldPosition AS STRING * 1 GreenMaskSize AS STRING * 1 GreenFieldPosition AS STRING * 1 BlueMaskSize AS STRING * 1 BlueFieldPosition AS STRING * 1 RsvdMaskSize AS STRING * 1 DirectColorModeInfo AS STRING * 1 Reserved AS STRING * 216 END TYPE
ModeAttributes - describes certain characteristics of the video mode. Bits are defined as follows.
0 - Mode supported in hardware 0 - Mode not supported 1 - Mode is supported 1 - 1 (Reserved) 2 - Output functions supported by BIOS 0 - Output functions not supported 1 - Output functions are supported 3 - Monochrome/colour mode 0 - Monochrome mode 1 - Colour mode 4 - Mode type 0 - Text mode 1 - Graphics mode 5-15 - Reserved
0 - Window supported 0 - Window is not supported 1 - Window is supported 1 - Window readable 0 - Window is not readable 1 - Window is readable 2 - Window writeable 0 - Window is not writeable 1 - Window is writeable 3-7 - Reserved
&H00 - Text mode &H01 - CGA graphics &H02 - Hercules graphics &H03 - 4-plane planar &H04 - Packed pixel &H05 - Non-chain 4, 256 colour &H06 - Direct colour &H07 - YUV &H08-&H0F - Reserved, to be defined by VESA &H10-&HFF - To be defined by OEM
0 - Colour ramp is fixed/programmable 0 - Colour ramp is fixed 1 - Colour ramp is programmable 1 - Bits in Rsvd field are usable/reserved 0 - Bits in Rsvd field are reserved 1 - Bits in Rsvd field are usable
Appendix B - VESA defined screen modes
GRAPHICS MODES TEXT MODES Mode number Resolution Colours Mode number Columns Rows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ &H100 640x400 256 &H108 80 60 &H101 640x480 256 &H109 132 25 &H102 800x600 16 &H10A 132 43 &H103 800x600 256 &H10B 132 50 &H104 1024x768 16 &H10C 132 60 &H105 1024x768 256 &H106 1280x1024 16 &H107 1280x1024 256 &H10D 320x200 32k (1:5:5:5) &H10E 320x200 64k (5:6:5) &H10F 320x200 16.8M (8:8:8) &H110 640x480 32k (1:5:5:5) &H111 640x480 64k (5:6:5) &H112 640x480 16.8M (8:8:8) &H113 800x600 32k (1:5:5:5) &H114 800x600 64k (5:6:5) &H115 800x600 16.8M (8:8:8) &H116 1024x768 32k (1:5:5:5) &H117 1024x768 64k (5:6:5) &H118 1024x768 16.8M (8:8:8) &H119 1280x1024 32k (1:5:5:5) &H11A 1280x1024 64k (5:6:5) &H11B 1280x1024 16.8M (8:8:8)
Appendix C - VESA VGA BIOS Extension function reference
Function &H00 - Return Super VGA Information
Provides information to the calling program about the general capabilities of the SVGA environment. The function fills an information block of type VgaIngoBlock at the address specified by the caller.
Input - AH = &H4F AL = &H00 ES:DI = Pointer to buffer Output - AX = Status (&H4F if successful) (All other registers are preserved)
Function &H01 - Return Super VGA Mode Information
Returns information about a specific SVGA video mode. Fills a mode information block of type ModeInfoBlock at the address specified by the caller.
Input - AH = &H4F AL = &H01 CX = SVGA video mode ES:DI = Pointer to buffer Output - AX = Status (&H4F if successful) (All other registers are preserved)
Function &H02 - Set Super VGA Video Mode
Initializes a video mode.
Input - AH = &H4F AL = &H02 BX = Video mode Bits 0-14 - Video mode 15 - Clear memory flag 0 - Clear video memory 1 - Don't clear video memory Output - AX = Status (&H4F if successful) (All other registers are preserved)
Function &H03 - Return Current Video Mode
Returns the current video mode in BX. Not limited to SVGA modes, will also return any other video mode.
Input - AH = &H4F AL = &H03 Output - AX = Status (&H4F if successful) BX = Current video mode (All other registers are preserved)
Function &H04 - Save/Restore Super VGA Video State
Provides a mechanism to save and restore the SVGA video state.
Input - AH = &H4F AL = &H04 DL = &H00 Return save/restore state buffer size CX = Requested states Bit 0 - Save/restore video hardware state 1 - Save/restore video BIOS state 2 - Save/restore video DAC state 3 - Save/restore SVGA state Output - AX = Status (&H4F if successful) BX = Number of 64 byte blocks to hold the state buffer (All other registers are preserved) Input - AH = &H4F AL = &H04 DL = &H01 Save SVGA video state CX = Requested states (see above) ES:BX = Pointer to buffer Output - AX = Status (&H4F if successful) (All other registers are preserved) Input - AH = &H4F AL = &H04 DL = &H02 Restore SVGA video state CX = Requested states (see above) ES:BX = Pointer to buffer Output - AX = Status (&H4F if successful) (All other registers are preserved)
Function &H05 - CPU Video Memory Window Control
Sets or gets the position of the specified window in the video memory. The function allows direct access to the hardware paging registers.
Input - AH = &H4F AL = &H05 BH = &H00 Select SVGA video memory window BL = Window number 0 - Window A 1 - Window B DX = Window position in video memory (in window granularity units) Output - AX = Status (&H4F if successful) Input - AH = &H4F AL = &H05 BH = &H01 Return SVGA video memory window BL = Window number (see above) Output - AX = Status (&H4F if successful) DX = Window position in video memory (in window granularity units)
Function &H06 - Set/Get Logical Scan Line Length
Sets or gets the length of a logical scan line. This function allows an application to set up a logical video memory buffer that is wider than the displayed area.
Input - AH = &H4F AL = &H06 BL = &H00 Select scan line length CX = Desired width in pixels Output - AX = Status (&H4F if successful) BX = Bytes per scan line CX = Actual pixels per scan line DX = Maximum number of scan lines Input - AH = &H4F AL = &H06 BL = &H01 Return scan line length Output - AX = Status (&H4F if successful) BX = Bytes per scan line CX = Actual pixels per scan line DX = Maximum number of scan lines
Function &H07 - Set/Get Display Start
Selects the pixel to be displayed in the upper left corner of the display from the logical page. This function can be used to pan and scroll around logical screens that are larger than the displayed screen. This function can also be used to rapidly switch between two different displayed screens for double buffered animation effects.
Input - AH = &H4F AL = &H07 BH = &H00 BL = &H00 Select display start CX = First displayed pixel in scan line DX = First displayed scan line Output - AX = Status (&H4F if successful) Input - AH = &H4F AL = &H07 BL = &H01 Return display start Output - AX = Status (&H4F if successful) BH = &H00 Reserved and will be 0 CX = First displayed pixel in scan line DX = First displayed scan line
Function &H08 - Set/Get DAC Palette Control
Queries and selects the operating mode of the DAC palette. Some DACs are configurable to provide 6-bits, 8-bits, or more of colour definition per red, green, and blue primary colour. The DAC palette width is assumed to be reset to standard VGA 6-bits per primary during a standard or VESA Set SVGA mode call.
Input - AH = &H4F AL = &H08 BL = &H00 Set DAC palette width BH = Desired number of bits of colour per primary Output - AX = Status (&H4F if successful) BH = Current number of bits of colour per primary Input - AH = &H4F AL = &H08 BL = &H01 Get DAC palette width Output - AX = Status (&H4F if successful) BH = Current number of bits of colour per primary
Appendix E - Suggested sources
The most useful source for programming VESA SVGA is probably the VESA
specification. There are many places where you can find it, I have uploaded
a copy on my website, use the address below.
Another good source on SVGA programming in the PC Game Programmers
Encyclopedia. It includes the VESA specification listed above. You can get
a copy from the following address.
Appendix F - Contact info
If you have questions, I'd prefer that you post them on the www board at my website, rather than e-mail me.
Until September 1998, I can be reached by e-mail at email@example.com After September 1998 I will have a different e-mail, I don't know what it will be yet so I can't tell you.
I can always be reached by posting a message on the www board at my website, the address is www.geocities.com/SiliconValley/Peaks/9572/ Also go there for more demo code on using SVGA in QuickBasic as well as many other useful routines and fun games.
Appendix G - Works Cited
Super VGA BIOS Extension, Standard #VS911022, October 22, 1991, Document Version 1.0, VBE Version 1.2.
The moment you've been waiting for!
HERE IT IS! the svga library that does all the stuff Aaron has documented the last couple of months.
SVGAlib by Aaron Severn