| 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
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:
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 ^_^.
Compiled by ZKman
MOTG Project going on teen.com
Even though half of the hits teen.com 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 teen.com, a new LibSet, and Viruses
Attack of the Virii!
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?
WoS granted FREEdom
A Competitor enters the ring
DA to become open-source
The latest on the libs
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.
So, who's leading? Here ya go, as of press time:
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
Enhanced also shifted websites this month, joining the quickbasic.com fold at ec.quickbasic.com.
Strummin' on the ol' banjo...
Dark Crown, DA2, and more
Latest Game updates:
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:
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
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! Pues...si dije mucho ya en este lengua, ahora edicion nueve tiene palabras en frances...justo para tu!
Adios! O...au 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!
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:
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:
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.
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
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 quickbasic.com, 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:
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
A puzzle game by The Brain where you must flip numbers in rectangular groups until you get them in order. Decievingly addictive!
Lianne...in the Dark Crown
Wetspot & Wetspot 2
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. SonicBlue.com 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, Sonicblue.com is this month's qb:tm Site of the Month.
Home of the Qlympics
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:
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:
SUB AX, 0
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:
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:
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
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:
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.
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.
MOV CX, AX ; Store value of AX temporarily in CX
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!
MOV CL, 4
But what's actually happening when the computer executes this code? Well, this is how the computer sees it:
Set CL to 4
Now suppose that we rewrote the code into this:
When this code is executed, this is what the computer does:
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.
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
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.
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:
This month in the gallery is "Killerz" by Nekrophidius. Although early in dev, it looks pretty freakin' cool, dontcha think?
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, 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.
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!
Download the voxel editor!
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.
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 way...to 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:
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.
The LTPB IDE
90mhz processor, 40mb hard drive, Win95 or Mac7.5+, 16mb ram, svga monitor, directx
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
2.) Graphics and Sound
3.) Features / Flexibility
5.) Overall Impression
| ||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
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...
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?
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!
Free up some 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, edit.com 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!)
OPEN tile$ FOR INPUT AS #1
'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
OPEN tile$ FOR INPUT AS #1
'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!
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