issue #10

Want to print? Use this version

Back issues are in the Archive

Go back to the main site

Download a zip version

Don't like frames? Kill 'em.

REM 'Letter from the Editor
Welcome to Issue 10 of Qbasic: The Magazine
ON KEY 'Hot List
This month's latest news
INPUT 'Your Stuff
Survey, Letters, Must Downloads and more!
LINE 'The Gallery
syn nine's "Vampira" is featured this month
PRINT '3d: Part V
More on programming voxels by Alias
VARSEG 'Graphical Tricks
Seav hopes to touch up your skill in graphics tricks
LOOP 'Spacewar Review
How does Bill McDonald's SpaceWar stack up?
OPEN 'Hall of Fame 3
Who's the 3rd inductee to the hallowed hall?
DRAW 'Art Basics
Gavan, the DA2 artist, gives you some helpful hints
END 'Next Issue
A thrill-packed preview of next month!

 

Letter from the Editor

By ZKman

What are those "specials" all about?

Heya! For those of you who don't usually visit in between issues, you may have noticed something new on our homepage. What are these new-fangled "specials"? Like I said last month, from now on you should expect a couple of articles a month in the weeks in between each issue, exclusive to then! The Letter from the Editor will then go over them, as I am here. Firstly, I compiled Petter's huge assembly series into a Word .doc and it weighs in at a heavy 72 pages of single spacing. You can find it here. In addition, I've written a pretty thick article on the palette, and some neat tricks for it, which is located right here. These should both open in a new window.

 

Who's our third hall of famer?

In addition to that, on a recommendation from Entropy, you can now kill the frame when you're reading, so that you can get a "full-screen" experience. Mind you, the graphics might looks sorta off if you do this and have a monitor at 1024x768 or higher, but your decision now ^_^. The link for that is right up with the Table of contents.

In the content of the mag, we hope we've got a good selection for you guys this month. With Petter's assembly series over, we were hoping to hit off with a bang, and possibly some of the stuff inside will do that for you. Gavan has also started a new article, one on some basic tile-drawing techniques. Gavan is, of course, the tile artist for Dark Ages 2, and if anyone knows art, it's him.

That's not all, either. Seav has an article on all sorts of graphical coding techniques and speedups, some common and some pretty unknown, in the start of his "Power Programming" series, which is perfectly based for the 99% of coders in the beginner/intermediate category. Alias has completed another selection from his series on Voxels, this time gettin' deep into the coding. I myself have a review of Bill McDonald's SpaceWar. This title was 2nd in Qlympics voting in the very challenging Adventure category at press time, and we tell you if it deserves it, especially since the title is in the same vein as upcoming games like FreeLancer and Space-a-Roo 2. syn nine's excellent looking Vampira is in the Gallery this month, and we also have a third addition to the hallowed hall of QB hall of Fame. Who will join DarkDread and Angelo Mottola? You'll soon find out.

In design related issues, the cgi voting version of the Survey has been delayed at least another month, mostly due my bad code ^_^. If anyone wants to help me make a cgi based form, that would send the results to my mailbox, contact me here. Also, you may have noticed we have a slightly different look over the entire website, with smaller pages. Would you guys like each article on it's own "page" in the magazine? It would probably look better, but printing would be more of a pain. Let me know your opinion!

Finally, we grabbed another two countries on to our list of where our readers are from (see last month's letter from the editor). Readers from Japan and Slovenia wrote in to tell us of their homeland! 21 countries are now on the board, which is super-cool. So, scroll down and enjoy...Issue 10.

Laters!

zkman

 

Back to top

qbasic Hot List

Compiled by ZKman

 

The future of the QB4.5 IDE
A couple bits of huge news hit qb:tm earlier this month, concerning replacements for the antiquated DOS Qbasic IDE, or "blue screen". The IDE eats about 1/2 of your memory when it's in use, and that leaves you only about 320kb to run your .bas file, and causes those annoying "Not enough memory to show help" errors, among others.

What can be done? How about 2 new projects; one from Blackbird and one by Leroy. Both aim at taking qbasic into Windows, with the window mode run-times and extra speed that could be derived therein. Firstly, BlackBird is working on a project called "WinQB". It's a pure Windows port of the Qbasic IDE, which will give you full code compatibility and the extra memory to run your program with. It will also allow you to do stuff like run 2 programs at once windowed, etc..

Leroy is taking another route with his program, which will "translate" your qbasic code into DJGPP code, giving you run-time increases of up to 30 times, and allowing you to use Windows memory. Downsides do exist on this option, though, as well. For one, most assembly will have to be redone due to the differences in the way DJGPP will handle the code vs. Qbasic. Also, certain things like machine code and CALL ABSOLUTE won't work, because of differences in calls in the Windows environment vs. the DOS environment. Also, qb:tm suspects that the majority of coders will not recognize such programs as QB programs.

Although both of these projects are a ways from completion, they both look to move qbasic forward into the next era for the language, and luck is wished to both!

WindowsQB?, Demo Scenes, and more

 

 

The QB Demo Scene resurgence
On the heels of the announcement of new demo scene pages by Entropy (www.uslink.net/~insty) and Terminator_Z (tz.quickbasic.com), a veritable renaissance of demos in the qbasic scene has begun. Demos are a form of small "graphical showoff" that is popular in many circles, with demo events, and Intro contests (for programs under 64k and 4k) very renowned throughout the world.

Demos started in the early 1980's when cracked programs (games with the security removed) appeared, with the cracker usually putting some kind of graphics show as a symbol of who cracked it. The demo scene then broke off from the cracker scene, and many professional coders have got their start with the graphically advanced demo.

 

DirectQB 1.6 and Dash2
As we reported last month, "Dash2", the XMS and SVGA library, is supposed to be out in coming months. No new news on this as of recent, though.

Angelo Mottola has been nice enough to give us your first look at the specs for Directqb1.6. Here y'are!

  • Free EMS for personal use
  • Up to 10 blender maps at a time
  • Sound Quality now BWSB level!
  • Font routines have been improved
  • Memory management is better
  • Bilinear Filtering added to 3d routines!
  • Encrypted Datafile support module
  • Fast matrix based calculation module
  • "layer copy" with support for collision layers and color blending!
Only the last 2 on that list still need to be completed, but with this announcement, dqb is basically all you need to do qb. Image loading, animation playing, BWSB sound quality, and graphical routines! Uyyy!

 

Qlympics report
Qlympics Final results are right around the corner! At last report, they should be formally announced and awarded on the 15th, the day this issue comes out. While these results may change after cheaters voting is adjusted out, here is the "informal" winners of Qlympics '99!

  • Fake OS Artechos
  • Action 1st, SB bricks. 2nd, TF Tetris. 3rd, Tetris2.
  • Adventure 1st, Wetspot2. 2nd, Peanut Patrol. 3rd, SpaceWar.
  • RPG 1st, Dark Ages. 2nd, Mystical Journey. 3rd, Warrior of the ChiChi
  • Strategy 1st, TF Checkers. 2nd, MineSweeper. 3rd, Puz.
  • Text-based Guess Phrase
  • Graphics PB3d
  • File Handlers GIF Converter
  • Libraries RPGDK2
  • Paint Shops 1st, Spritedm. 2nd, SpriteShop.
  • Miscellaneous Jpost
The results seem pretty good this year, with a few notable exceptions. SFB2, one of our must downloads, was only 4th in the Adventure category (it scored a 9.1 in our review). Puz, another must download, was a mere #3 in the Strategy section. Also, Yousuf Phillips' great series of programs like OpenAVI and OpenBMP won no awards.

Oh, and maybe Majiko should look up his titles in Spanish (heh...ChiChi).

 

Is Killerz Strip Fighter?
Since Killerz was in the gallery last month, we've recieved quite a few reports stating the graphics contained therein were ripped from a Super Nintendo ROM called Strip Fighter, a parody of the mega-popular Street Fighter. This pertains only to the character graphics, not the backgrounds.

However, to our regret, we failed to mention that, yes, Nekrophidius knows that he is using these images. They are from a TurboGrafx16 game called Strip Fighter II, and will probably not end up as final art.

 

Dorothy, We're home again
Future Software and the Qbasic RPG's homepage have both got new pages over the last month. Future is now located at the oh-so easy to remember qb45.com, and QBasic RPG's is now at members.xoom.com/qbasic_rpgs.

 

Vertical Scroller named
Pasco's previously named vertical shooter which was going ubiquitously as the cleverly named "Pasco's Vertical Shooter" has been christened Freelancer. For more news on this and the ultra-cool other space shooters....

 

...Beam me up, Scotty
Last month, it was all about the side-scrollers, which has surged in interest primarily due to DirectQB. But that's not the only non-RPG genre to suddenly surge in popularity: the space shooter is now all the rage. Bill McDonald's "SpaceWar" is currently racking up high-score over at the Qlympics (and is reviewed later in this issue), touting features such as very realistic explosions, good sound, and firm gameplay.

The question is, will it hold up to the other 2 competitors? Pasco's Freelancer features squad-based enemies with nice AI, in a very fast, smooth-scrolling, and easy on the eyes graphics in that title, with a great demo released recently here. SonicBlue is taking a slightly different approach, with 8-level instead of vertical scrolling for Space-a-Roo2, and this is already shaping up as one of the most interesting titles of 1999, with a great physics model and some nicely varied enemy types, as well as the promise of much more. In qb:tm's opinion, SaR2 looks to be the most difficult of the bunch, with Freelancer winning in the style category. Sar2 can be picked up here.

 

Qbasic Review News
JP Zorilla recently started a new page devoted to reviewing qbasic games and utilities and went off to a fast start with many reviews in the first few days. Possibly to become the Programs section answer to Future's Site Review page, check it out for yourself at this long Geocities address.

 

The Qbasic Internet Age
Qbasic made one of it's first big jumps towards online gaming with a MUD program near it's final stages by NetherGoth. MUD, of course, stands for Multi-User Dimension, and can be anything from a very basic Ultima Online to a graphical chat room. Be sure to look for news as to the page this MUD will go live on.

 

Voxel Crazyness
Voxels are suddenly en vogue here in the qbasic community this recently. Firstly, Alias (the writer of our voxel series) has shown off a demo of his fairly fast voxel renderer that features some amazing dynamic lighting, and is to be the backbone of a future (hush hush) title. Also, Synnine (of Vampira fame) has a voxel renderer in the works for a full screen player vs. player shooting minigame (he also has incorporated voxel characters into vampira).

Want to know more about voxels? Check out the newest part of that series down below...

 

 

prt demo?, More Footie, Bubble Fighters, and more

 

Latest Game updates:
The biggest news to come our way as of late was that a Project rt demo was, very possibly, coming our way in the coming month. While we didn't learn exactly what would be shown in the said demo, we hear that, if they decide to release it, it would be ready in the next month. This would be the first new game demo/final to come out of Enhanced since more than a year ago with Wetspot2. Also, word is that the engine might add colored lighting! This is pure hope at this point, but is a very real possibility.

 
 

 

Last minute news came in about Dark Ages 2. Firstly, a couple-hour demo with story, battles, the works, plus Gavan's great art, could be here within the month! DA2 progress is flying along with Finals over for most of the crew, and one 96tile by 96tile map is already done, an area larger than the entire DA1 game! And the plan is for up to 100 maps!

Pyrus, coder of Simpire, among others, has joined the all-star cast of DA2 to help work on the battles. Hopefully his asm handiness and sense of design will help speed up this great game. On top of that, a Dark Ages 3 to begin "after a sabbatical" has been all but confirmed to us by Mike Hoopman, and there is great hope that the entire game can be finished by the end of the summer! Also of interesting note is the Unofficial Dark Ages Homepage, a great site entirely devoted to Dark Ages!

JP Zorilla is working on a new title by the name of Football '99. Presumably his answer to Pasco's France Soccer, this title has some fairly smooth animation in the graphics, and is looking almost as good as Pasco's title. More on the gameplay should be coming soon.

qb:tm was recently shown a new screenshot from Bubble Fighters, Enigma's fighting game, and to say it looked nice was an understatement. Although it was only the 3d arena, the poly count was fairly high for a qb game (it seemed about 50 poly's or more just in the background), and, with the asm in the title and DirectQB under the hood, this title is sure to challenge XENO for the best 3d engine in qbasic.

Speakin' about Pasco's Soccer, there has been a lot of speculation as to the fate of that title recently. Says the man himself, the movement is now fully rotational instead of characters only being able to go left, right, up, and down. However, this has meant the entire AI module has had to be recoded, significantly slowing down production. Groov Buggies 2, a title that was announced way back, has had some work recently, with some "neato special effects"; technical difficulties with the speed of the texture-mapper have slowed work on this too. However, expect to see a few new demos of Freelancer in the near future.

Last of the Legends, Magik's RPG, went into beta this past month, and should go to a final release very soon. As the first full RPG since Dark Ages, no doubt anticipation will continue to drum up for this game as it nears release.

Now this month's shorts: The game which was being called "The Brain's Side Scroller" has been confirmed as Peanut Patrol 2, as we'd speculated last month. With NutzBoy and The_brain, both with projects already behind them, working on the title, it's sure to be good...Mandrake's new game AnnWynnNnn had a screenshot posted of it recently, and it's looking above-average in the graphics department; hopefully the story will be to boot...Jaws-V's partner Change-V, with games such as Cookie Delivery, MiniRPG, and more to his credit, has posted news on his website about a new side-scrolling shooter. Check it out for yourself here

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

 

Back to Top

Input: Your Stuff

By ZKman

 

 

Here's what you had to say about last month. Be sure and send us more letters soon!

Attack of the virii? Nice little article.

BTW, NetBus isn't a "virus"...it's a RAT (remote access trojan). And I, I mean we, have been spreading more than just NetBus. Since I program in more than just QB, I had the luxury of making my own RATs, some that aren't as f***ing obvious as "patch.exe", but still have a tendency to get into the Windoze registry and disguise themselves as system philes (sic).

And what's running a RAT through an anti-virus tool going to do? You'll get an "okay" message. Mine go undetected, mabe 'cause Mc"@$$hole" and Norton haven't seen mine.

DP

I usually don't put the email address on a letter, but I figured it'd be fun here. Heh, admit it, this guy is asking for it ^_^.

 

 

First of all, what's the correct capitalization of your name? zkman or Zkman or ZKman...?

Seav

whatever makes you guys happy, chicos. Never really thought of that, but I usually use....umm...all three! yeah!

 

 

 

A couple of points to ponder...

1) I live in Kyrgyzstan, so add me to the list!

2) I hate French and anyone that types it all over online magazines. I despise Spanish also.

3)LTP: BASIC, believe it or not, is Interplay's fourth most popular software title at this moment in time. Baldur's Gate is second, some Redneck Rampage game is first, and LTPB is third. No numbers were given, just a list.

4) According to Roald Dahl, the BFG spells scrumpdiddlyumptious like that, not scrumm-didlyumptious.

5) The title picture didn't load for me this issue.

P.S. What are you going to do without the monthly asm tutorials? They took up half of it!

Pete

You've got comments, we've got answers!

1) ^_^. Read last month's Letter from the Editor if you have no idea what he's talking about

2) No te gusta espanol y frances? Por que no? heheh

3) Also, believe it or not, Interplay lost $25 million in Spring '98, says Next Generation.

4) Close Enough =)

5) Eek! It's fixed now...

And about Petter's articles, they were about 4 pages out of an average 48 page issue, so we're still staying about the same size.

 

 

 

Killerz...umm...don't see what all the fuss is about.

Looks too grainy, things clash, like someone slapped hand-drawn sprites onto a blurry photograph. Things don't mix. I just think it looks a bit bland at this stage. Whatever, heh. If Nek makes the energy bars cooler looking, maybe do hand-drawn bg's that mix, the game could rule.

[crawls under floorboards, back when he came]

Enigma

Looked pretty cool to me. Wasn't Mortal Kombat also sprites on a blurry background? Oh yeah, Mortal Kombat sucked. =)

 

 

 

I always thought the Qbasic world was a good, clean, bunch of programmers. UNTIL I read the last issue of QB:tm. I am shocked at lost sock's game (to say the least). I mean, isn't there enough crud and junk in the game world that he has to create some in the qbasic world. A fighting game is fine, his graphics look really good quality EXCEPT the content of the game. To sum the whole thing up: that game isn't worth the memory it uses. It's a stain and a scar on the Qb world. And I almost wish we could disown it as a Qbasic game!

Timothy

Uf! The Killerz backlash is hitting hard this month. Of course, nekrophidius is never one to change the style of his game based on what others say. Perhaps nek would comment?

 

 

 

My first experience with voxels must have been in watching Future Crew's awesome demo "Second Reality" back when I was in high school. It had a dynamic sinusoidal heightfield that the camera panned around in. I was so impressed with the fluidity of the voxels, that I downloaded some more demos and found even cooler landscape voxels

So I went ahead and wrote my first landscape voxel renderer. It looked pretty good, but I had the screen centering code before the perspective transformation done incorrectly, so my voxels were skewed into a circular shape. Nonetheless, it was a successful attempt, and it motivated me to pursue my voxel research even further.

I pored over every 3D tutorial, article and source code I could get my hands on, to increase my knowledge of this new world of 3d voxel-based rendering. I was at first baffled at how voxels could be rendered in only 4 lines of C code in the inner loop, but later understood how all those precalculated tables containg the critical data to determine the projected height of each voxel at each scanline of the screen. From that knowledge, I made a voxel demo (with source) that you can download here.

It's not fancy, but is shows how it can work. It uses a "real" perspective transformation to project the voxels to the screen, so they will not look like tiles.

I'm glad that Alias has decided to write a voxel tutorial for Qb: the magazine. Maybe you too will become interested in voxels, and seek tutelage on how to speedily render complicated 3D objects using such techniques as raycasting, voxel sprites, and octree traversal. If you need help on that stuff, email me and I'll help you out. Good luck!

Toshihiro Horie

toshiman@uclink-4.berkeley.edu

I don't care if you think this guy is bragging, Toshi is the man. His programs rule. Download that voxel program. Now.

 

 

 

I would just like to know if it would be possible to get a screenshot of the game another DEP member and I are working on into the next qb:tm. Of course, we don't have them ready yet, because i am waiting for some of the GFX to be made, but soon as that happens, I will take screenshots and send them over, if that is okay with you.

Yoda

A lot of people send me similar stuff, usually about being in the gallery. Although I might not have heard of your game, if it rules, I probably have. So DON'T send screenshots, and send a note like Yoda here if you want to (or, even better, a url).

And speaking of Yoda, I was only in line for an hour to get my Star Wars tickets. Some people I know camped out for 5 days, so I don't feel THAT bad =).

 

 

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              2(t)        <>
 3. Mono. Shooter (t)      2(t)        D1
 3. Groov Buggies (t)      --          --
 3. Of Hell and Magic (t)  2(t)        D1
 3. Agent Squeak (t)       --          --
  
 Comments: Some variety on Best Game this month,
  with Agent Squeak and Oham on the list for the
  first time ever.

 Favourite Utility  |  Last Month  | Change
 1. DirectQB               1           <>
 2. QMIDI                  2           <>
 3. GIF2BSV (t)            --          --
 3. SvgaLib                3(t)        <>

 Comments: DirectQB dominates the voting, and
  PP256 and Spriteshop fail to crack the top 4.
  Speaking of which, Dash is off the list for
  the 3rd month in a row.

 Best Upcoming      |  Last Month  | Change
 1. Dark Ages 2            1           <>
 1. Last...Legends         2           U1
 3. "Project RT" (t)       --          --
 3. Eternal Frost (t)      --          --
 3. Dash2 (t)              --          --
 3. Xeno (t)               3(t)        <>
 3. FoX (t)                --          --
 3. Future Library (t)     --          --

 Comments: Project RT rejoins the Best Upcoming
  list.  The large amount of promising titles
  coming soon has led to a variety of titles on
  the Best Upcoming this month.

Vote today by emailing your votes for:
favourite game
favourite utility
Game/utility that you're most looking forward to.
Send your vote here

 

You need this stuff!

Must Downloads returns for another showing. Two new games were added this month! Firstly, QBTetris, and excellent puzzler, and SpaceWar, the current king of the space shooter crop. 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!

 
SpaceWar
Bill McDonald's space shooter featuring excellent sound and explosions, along with some fair, 1980's style gameplay.

QBTetris
This version of tetris features not only a complete version of the Soviet puzzler, but a variety of variations on the theme. By Dominik Kaspar.

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

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

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

Groov Buggies
The best QB racer ever. Although it has some control problems and some clipping glitches, this wireframer set a new standard.

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!

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

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

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

PP256
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.

DirectQB/DashX/Blast!
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.

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

Pb3d
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!

 

Future Software
 

Uniqueness is what we use to determine who gets the Site of the Month. If a page has a ton of links, or a program library with no original stuff, it won't be here. qb45.com (Future Software) is not that place.

The creator of the QFinder (basically a qbasic search utility), and home of the best site reviews in the qbasic world, along with some original programs, and a good interface, qb45.com is our Issue 10 Site of the Month.

We like uniqueness

Back to Top

Gallery

By Zkman

 

Some amazing isometric tilework and voxel characters set Vampira away from the pack this month!

 

Vampira

 

Back to Top

3d: Part V

By Alias

 

Alright, has everyone here heard of a landscape engine? No?!?! Well, we'll see about that!

Last issue we covered voxels, which are 3D versions of pixels, and can be used to create stunningly high-detail sprites without too much overhead or loss of speed. As nice as they are, they are not as fast as they could be if we remove some abstraction.

Voxel-based landscapes...

 

The voxel model we presented last time was an incredibly general model - too general for a lot of purposes, in fact. If you're making, say, a flight sim, or a game like Delta Force, you want to have a big, broad voxel map the size of Rhode Island, but you don't have that much memory. The ability to have true-3D voxels is useless, so if we could just find a way to do a height-map, we could completely forget our previous method and have whatever kind of terrain we want.

Wait a minute! We CAN do a height map! Look at programs like 3D-Lands and the voxel.bas. They are prime examples of simple height maps at work. Since there are so many programs like that out there, I will not bother to write one. Have a look at them and see what you think. Keep in mind that there are many different kinds of landscape voxels. I will go through a simple list and description of the most prominent kinds:

  • 3D Landscape - This is like the example program VOXEL.BAS. All the 3D points are calculated based on their height and drawn as enlarged pixels, the same way as the example program last month. This has the advantage of speed, but it is still very general and can have gaps in places with great height difference.

 

 

Check out this 3d landscape!

 
 
  • Ray-tracing - Yes, the same method as Wolfenstein, only backwards. A ray is sent out to the edge of the map or the farthest visible point - whichever's nearer - and is traced back to the player. As it is traced, the heights of the map where the beam lies are drawn. This is much more accurate than the simple 3D landscape, but it is much slower. Usually, there is reduced image quality to compensate for the slow speed.
  • Filtered (or weighted) ray-tracing - Same method as above, but weighted averages are taken to make the landscape less blocky and more accurate, with less jumping.
  • Precalculation - This method uses VERY specialized arrays to precalculate the exact location of each pixel. This is not the fastest method but it is EXTREMELY accurate. The downsde is that by the time you have the tables in place, you have no memory left for anything less, unless you reduce image quality, leaving you where you would be with any other method.
  • True Fake - 3D Lands is a True Fake landscape engine. It does not use isometric projection but simply skews the image so that it looks kind of 3D. The height illusion is acheived by changing the Y values. the big advantage here is that it's really fast and has next to no overhead, but quality is very limited and rotation is impossible.
  • Isometric - I have not seen this method used in a true landscape program yet. It involves isometric projection (covered in the last installment of this article) of the points and simple height adjustment. It is slightly slower than a True Fake, but has rotation and can properly scale.

Phew! that's a lot to cover. I know I said I would cover list voxels this time, but I have been awfully busy, and have not been able to prepare. As for the DQB version of the voxel editor, I won't be doing it. All of the mail I recieved about it said that I should not port it to directQB, and since there is no demand for it, I will just let it stay the way it is. See you next time, with list voxels, and finally, in the fourth installment, isometric projection!

What the heck does sinusodial mean anyway? Find out from Alias here.

Download the voxel landscape generator

Back to Top

Power Programming

By Seav

Welcome to the Power Programming series

All right, you know about GET and PUT. Maybe even made a few games with them. And with the introduction of such libraries as Blast!, Dash, and DirectQB, you have powerful graphics routines at your disposal.

 

But, nobody has really addressed the issue of managing all those tiles and sprites you have. Well, fortunately for you, I wrote this article just for that! In this article, you'll learn how to calculate array sizes for your sprites— explanations included so you don't have to memorize stupid formulas that don't help at all. You'll also learn how to store multiple sprites in an array—and how to use two-dimensional arrays for all your same-sized tiles. You'll also know how to save all your sprites into files and simply load them up straight into your PUT arrays! No more hacks of drawing your sprites at the start of your program.

This will be a first in an informal series of articles that deal with power programming.

Array Sizes
How do you calculate what size the array needs to be in order to contain the graphic you intend to capture with GET? If you've ever asked this question, you'll probably get a formula like this for an answer:

ArraySize = (Width * Height + 4) / 2 - 1

But what does it all mean? Well, let's suppose that we have a 16x16 tree sprite to GET to an array. Since we're in Screen 13, each pixel is a byte in size (can take any of the 256 possible colors). So, we would need 16 * 16 = 256 bytes to store the image alone. But because GET needs space to store the sprite's width and height, each of which, being WORD values, occupy two bytes, we need an additional 4 bytes for a total of 256 + 4 = 260 bytes. That's what the plus 4 in the formula means.

If we are dimensioning an INTEGER array (where each element is two bytes in size), we would need an array with 130 elements (260 / 2 = 130), hence the divide by 2 in the formula. Here's the code to dimension the tree sprite array:

DIM Tree(129)

We used 129 in the DIM statement bacause there is already an element 0 (the reason why we're subtracting 1 in the formula).

If the sprite's size in bytes were an odd value, we round up. For example, if we have a 15x15 sprite, the sprite would occupy 15 * 15 + 4 = 229 bytes which will occupy 229 / 2 = 114.5 or 115 INTEGER array elements. Thus, we dimension the array this way:

DIM Tree(114)

Storing Multiple Sprites In An Array
Have you ever seen code that looks like this?

DEFINT A-Z
DIM Player1(129), Player1Mask(129), Player2(129)
DIM Player2Mask(129), Tree(129), Grass(129), Rock(129)

The coder is obviously using one array per sprite. It would be better to store everything in as few arrays as possible so that everything would become clearer. Besides, this is especially suited for tile engines where each tile is the same size. This is also done so that we can store numerous sprites in one file using BSAVE and BLOAD.

The solution lies in the GET syntax. We can indicate in which element of the array to start storing the sprite by simply adding subscripts to the array name. For instance this code actually stores the sprite in the first element, 0.

GET (0, 0)-(15, 15), Tree

So it is the same thing as writing

GET (0, 0)-(15, 15), Tree(0)

If we dimension an array to have 260 elements (520 bytes), we can store two 16x16 sprites in it!

DIM TwoSprites(259)
GET (0, 16)-(15, 31), TwoSprites(0)
GET (0, 32)-(15, 47), TwoSprites(130)

You'll notice that we stored the second sprite starting in element 130 since the first sprite already occupies elements 0 to 129 (130 elements, 260 bytes). The second sprite would then occupy elements 130 to 259.

You can extend this concept to store as many sprites as you want in one array. However, the array cannot exceed 64K in size (good for 252 16x16 sprites) unless you use the /AH switch in QB4.5 and the $DYNAMIC metacommand. Also, be careful that you don't overlap sprites in the array. You can leave gaps, but never overlap them.

An Application: Tile Engine Drawing Routine
Storing multiple sprites in one array is especially useful in tile engines where every tile has the same size. If your map is stored in an array, you can use the tile numbers to calculate in which element of the sprite array that tile is located:

For example, we have a Map() array that contains the tile numbers of each part of the map:

  • 0 = Grass
  • 1 = Tree
  • 2 = Vertical path
  • 3 = Horizontal path
  • 4 = Rock
  • 5 = Water
  • etc.

So if Map(13, 14) contains a 4, then there's a rock at that position.

If we organize the sprite array so that the first tile is grass, the second tile is a tree, etc., we can simplify drawing the tiles: (Assume that we have 16x16 tiles)

' Draw a 10x10 portion of the map
' from (1,1) to (10,10)
'
FOR Y = 1 to 10
   FOR X = 1 to 10
     ' Calculate position on screen to place the tile
      XScreen = (X - 1) * 16
      YScreen = (Y - 1) * 16

      ' Calculate where the tile is stored
      Element = Map(X, Y) * 130

      ' Draw the tile on the screen
      PUT (XScreen, YScreen), Tiles(Element)
   NEXT
NEXT

It's very simple, isn't it?

If we're going to use two-dimensional arrays, accessing the tiles will become much, much easier. How do we do it? Instead of dimensioning a one-dimensional array, use a two-dimensional array where the size of the first dimension is the size of the sprite and the second dimension is the number of tiles. For example,

DIM Tiles(129, 19)

This statement will dimension an array that can hold 20 16x16 sprites (figure out why). To store the sprites, just use this

GET (...), Tiles(0, TileNumber)

where TileNumber is the number of the tile you're GETting. PUTing them works the same way.

This method of using two-dimensional array works because the first dimension elements, (0, x), (1, x), (2, x), etc., are contiguous in memory (i.e., they are next to each other).

THE GET FORMAT
I've said earlier that GET needs 4 bytes to store the sprite's width and height. Well, it puts this information at the front, before the image data. So, if you stored the sprite in an INTEGER array, the first element contains the sprite's width in bits (or pixels * 8). The next element contains the sprite's height in pixels. After that comes the sprite data (which are pixel color values). (SCREEN 13 only)

  Offset   Length   Description
  (bytes)  (bytes)
  -------  -------  ------------------
    00     02 WORD  width in bits
    02     02 WORD  height in pixels
    04     XX       sprite image data
The sprite data is arranged much like what you would expect. The pixels representing the top row in the sprite are first, followed by the pixels in the next row and so forth, down to the bottom row. Knowing the GET format is essential if you're planning on making your own sprite routines which are compatible to BASIC's GET and PUT routines.

BSAVE AND BLOAD
If you're the type of programmer who draws his sprites at the start of the program and GETS them, then it would be useful to know that you can do this once during development and load the sprites straight to the arrays in the actual program. You do this by using two of BASIC's useful commands: BSAVE and BLOAD.

BSAVE and BLOAD are two memory statements whose purpose is to transfer data between RAM and files. BSAVE lets you store parts of the memory to a file and BLOAD gets from the file and dumps it to the memory. To be able to fully use these commands, you first need to know all about Segments and Offsets, so if you don't know anything about these terms, don't read on until you do. (See the first part of Petter's ASM article in issue 4 for a nice introduction to Segments and Offsets)

Syntax:
   BSAVE filespec, offset, length
   BLOAD filespec, [offset]

   filespec Filename (path optional) of the file to save to or load from.
   offset Offset into the default data segment to save from or load to. This value is an unsigned integer (0 to 65535).
   length Length in bytes of the memory image to save. This value is an unsigned integer (0 to 65535).

An example, to quickly save the screen (in SCREEN 13) to a file, you can use the code below. When you run the code, you will now have a file, SCREEN.GFX, in the default directory containing the memory image of the screen. (The palette is not saved, BTW.)

DEF SEG = &HA000
BSAVE "screen.gfx", 0, 64000
DEF SEG

The Screen 13 pixels are stored in memory at the address A000:0000 and is 64000 bytes long (320 * 200 = 64000). The segment A000 is a hex value and thus, the value in the DEF SEG statement contains a prefix (&H) to indicate that it is in hexadecimal. DEF SEG is a command that changes the default data segment for use with such commands as PEEK, POKE, BSAVE, BLOAD, and CALL ABSOLUTE. It has this syntax:

DEF SEG [=segment]

It is usually a good idea to restore the original default segment by executing another DEF SEG without attributes. You can omit this if you know what you are doing.

There is a quirk with BSAVE that you should know. If you specify a file without an extension, BASIC automatically assumes a .BAS extension, which I would say is fairly stupid. Also, the if the file you specify in BSAVE exists, it is completely replaced, so beware!

To load the screen back use this code:

DEF SEG = &HA000
BLOAD "screen.gfx", 0
DEF SEG

If you omit the offset in the BLOAD statement, BASIC will assume the segment and offset you got the image from (with BSAVE). Omitting the offset is not recommended unless the location will not change. Since the video RAM is more or less fixed in location (it has to be), you can simply use this statement instead of the code above:

BLOAD "screen.gfx"

VARSEG And VARPTR
Since BASIC arrays are stored in memory, you can use BSAVE and BLOAD to save or load your graphics to the arrays. The only thing we need to know is where in memory the arrays are located. We can find out using these two functions, VARSEG and VARPTR.
VARSEG is a function that returns the segment in which the specified variable resides. Likewise, VARPTR returns the offset. Syntax

VARSEG(variablename)
VARPTR(variablename)

Example

Number% = 10
DEF SEG = VARSEG(Number%)
BSAVE "number.tmp", VARPTR(Number%), 2
DEF SEG

The example above stores the contents of the variable, Number%, into the file NUMBER.TMP.

You can specify any variable as the variablename. This includes array elements and record names. Some more examples using VARSEG:

DIM Map(1 to 10, 1 to 10)

' Get the segment of the first element of Map
Segment = VARSEG(Map(1, 1))

' Get the segment of the (3,4) element of Map
Segment = VARSEG(Map(3, 4))

TYPE RGB
R AS INTEGER
G AS INTEGER
B AS INTEGER
END TYPE

DIM Palette(255) as RGB

' Get the segment of the red attribute of color 100
Segment = VARSEG(Palette(100).R)

Since many variables change locations often, it is recommended that you use the values returned by VARSEG and VARPTR immediately.

Note: If you want to get the offset of a dynamic-length string variable, use SADD instead of VARPTR since using VARPTR returns the offset of the string's descriptor, not the string itself.

Saving Those Sprites
We have 20 tiles stored in one big array and we wish to save it to a file so that we can just load it when the game starts. We do this:

DIM Tiles(129, 19)
' 20 16x16 tiles (5200 bytes)
.
. (draw and GET the tiles)
.
DEF SEG = VARSEG(Tiles(0))
BSAVE "maptiles.gfx", VARPTR(Tiles(0)), 5200
DEF SEG

To load them back in the actual game, use this:

DIM Tiles(129, 19)
DEF SEG = VARSEG(Tiles(0))
BLOAD "maptiles.gfx", VARPTR(Tiles(0))
DEF SEG

You'll notice that we specified the offset in the BLOAD statement since it is not guaranteed that the array will be in the exact same location it was when we saved it.

The BSAVE File Format
The BSAVE statement stores the memory image in a special file format with a 7-byte header. As such, you cannot just BLOAD any file. (This information is presented for those who are interested.)

  BSAVE FILE HEADER

  Offset   Length   Description
  (bytes)  (bytes)
  -------  -------  -------------------
    00     01 BYTE  Special BSAVE value
    01     02 WORD  Original segment 
    03     02 WORD  Original offset
    05     02 WORD  Length of memory image 
The original segment:offset is the memory address the memory image was taken from. Immediately after the header comes the memory image.

SPECIAL WARNING
Since we are using BSAVE and BLOAD, the potential for disaster is great. You might accidentally lose a file with BSAVE or crash the computer using BLOAD. Always take care when you're using these two statements. Make sure that you don't interchange BLOAD with BSAVE, and VARSEG with VARPTR and always check that you have your DEF SEGs straightened up.

Conclusion
I hope that this article enlightened you with how to organize your graphics in your arrays and files. Look forward for more articles from me. For instance, in my next article, I will present better alternatives to BSAVE/BLOAD and TIMER. Happy programming, for now!

 
Pester Seav to tell you the secret of the elusive BEXIT, BSAVEAS and BPRINTPREVIEW at this address.

 

Back to Top

spacewar review

By Zkman

  SpaceWar, by Bill McDonald, was released relatively unknown just a few months ago, but in that time has jumped in popularity to a possible Bronze medal in the Qlympics, beating out high-class contenders like SFB2 and Super Mario World Clone. Does this space shooter, the first of a new crop this year that includes Freelancer and Space-a-Roo2, have what it takes to be a Qbasic classic? Maybe.

The first of the new space shooter crop

  First, the positives: This game uses sound better than nearly any qbasic in recent memory, with some nicely looping BWSB music pumping your adrenaline in the background, simple voice-overs like "Wave One" or "Game Over" at said points throughout the game. The problem sound-wise lies in the variety, or lack thereof. As far as I could percieve, there is only 1 .mod in the entire game! Whereas AAA titles such as Wetspot 2 had new music for every set of levels.

Another one of the winning points of this game is the explosions. They look, to put it simply, fabulous, up to the level of professional games. It's fairly obvious the explosions are a canned series of animation and not generated real-time a la Marko Dokic' routines, so they might get old after a while, but they do look good when you're flying around.

This game is also virtually bug-free, with zero slowdown, or graphical anomalies. It also is complete, if a little short (we'll touch on that a bit later).

 

 

Spaceship go boom-boom, Mommy!

 
 

However, there are some downsides to the game. As far as enemies and weapons go, this game doesn't have it going on. You'd expect a space shooter to have multiple weapons on each side (enemy and you), but this game has very few. The harder enemies are generally just harder to kill and faster shooting versions of the same enemies you'd already seen. There are no huge bosses like in G-Darius, or special weapons or anything of the sort.

Also, enemy AI leaves a LOT to be improved. Whereas even early demos of Freelancer had enemy formations like V-Wing and similar, this game's "AI" seems to be random movements to side and up/down. It not only makes the spaceships seem to fly in a "jerky" kind of manner, it also lessens the excitement.

In the graphics department, it's a mixed bag. The explosions, as I've said before, are great, but the rest is not so. Firstly is the heavy reliance of DirectQB tricks that end up not looking very good. The logo at the start does a horizontal scroll of itself, which looks sorta wierd, and various other menus sort of "scroll away" in various directions when you're through with them. Although it doesn't look bad, there have been much better examples such as fading done before. Also, the font choice for areas such as the Storyline is heavily blurred and is almost as unreadable as the font from Wrath of Sona's opening.

Our recommended specs:

100mhz processor, DirectQB, Open EMS

A more difficult enemy

 
 

The ships and enemy ships are above-average, although not in the same league as some of the more graphically advanced games of late, such as Freelancer, Dark Ages 2, or even Wetspot 2. They have only one frame of animation, and no little "extra touches" such as smoke carrading off the side of the ship if it's hit, or rockets manuevering you around. The background is also simply space, which, although well done for space, is not the most interesting backdrop for your fighting.

Don't get me wrong, this game is currently the top of the crop for space shooters, providing some decent gameplay, even if there are only 12 short levels of it that are not extraordinarly difficult. But it is simply lightyears behind SaR2 and Freelancer on all counts. Both of those games look and play better even at this early stage than SpaceWar. Maybe 2 years ago, this would've gotten the Qb:tm Seal, but today, with no defining hook, it is merely average.
So SpaceWar is your favorite game? Lemme know what a mistake at this address.

 

 

 

Qb:tm Verdict


PROS: Sound, explosion graphics

CONS: Nothing original, ho-hum gameplay

CONCLUSION: Maybe

5.6

Back to Top

Hall of Fame 3

By Zkman

 

M
o
l
n
a
r

M/K used to be the name as far as qbasic was concerned. Of course, we're talking about the (now defunct) Molnar/Kucalaba Productions, a group run by Luke Molnar and Luke Kucalaba, producers of some of Qb's most fondest memories, and the creators of many concepts still around today.

From the insatibaly violent Bob Sagat Killer 2000 and Fury to the quasi-strategic SubQuest, these 2 are some of qbasic's most prolific creators, back in the day when anything went. Imagine the ruckus if Ambush at South Range had come out today, a game about shooting at school! Utility-wise, these guys also broke new ground. MKJ was a common music format in games back before BWSB and QMIDI were even considered. MK's font routines were among the first to replace the PRINT font. And their games set a precedent for mouse use in qb.

For these reasons, we're proud to induct Luke Molnar and Luke Kucalaba to join DarkDread and Angelo Mottola in the Hall of Fame. The name M/K may not mean quite as much as more recent creators like Dark Knight, VirtuaSoft, and Enhanced, but these guys were among the pioneers, and their legacy will live on.

K
u
c
a
l
a
b
a

Back to Top

Art by Gavan

By Gavan

 

Does you game art, for lack of better words, suck? Do you have an overwhelming sense of despair because you think you can not draw? If your response to the above questions was yes, no, or what the hell is he talking about, then this tutorial might just be for you. The fact is that you don't need talent when it comes to digital art, because your computer can handle much of the work for you. I myself started out where many of you are, and I now am the artist for Dark Ages II. While I cannot say my art is sublime, it is adequate for game purposes (hey, don't judge my art yet, you haven't seen the top secret new stuff : ) ). Through just a few tricks, you can turn you lame sprites and such into glorious works of art that will make Da Vinci writhe with jealousy in his grave.

Yeah, Baby! The DA2 Artist is here to help ya!

 

Basics
First you will need to choose a paint program, if you do not already have one. Although it is a bit primitive by today's standards, I use Paint Shop Pro 4, which is completely free (Many good tile editors can do most of things presented within, so feel free to use those too - Ed). Know that not all Paint programs are created equal; some may not be well suited for drawing game art. Your paint program should be able to zoom in and work with individual pixels in an intuitive fashion, with precise control of everything. I may mention some concepts unfamiliar to you; in this event, you should consult your paint program's documentation. Also, you may want to copy the picture shown into a paint program so you can zoom in and see it in detail. Tiles within the bitmap shown will be referred to by their grid coordinates (column, row or x, y); thus the bitmap in the very upper left corner would be (1,1). First, before you draw anything, you must decide on a palette (as most of you basic programmers will be doing eight bit graphics). Since you are limited to 256 colors, no single color in your palette should be wasted. It follows then, that no two colors should look at all the same (with one exception, mentioned soon); every color must be distinguishable by not only its RGB values, but by how it is perceived to the eye as well. For example, two shades of red may have dramatically varied RGB values, but may look essentially the same to the eye. Note that you will definitely want a pure white shade (RGB value of 255,255,255) and a pure black shade (0,0,0). You will also probably need a "transparency color," a color to serve as the background and color to be dropped out in your sprites. I find that using a slightly off-white color works best for this (it can look the same as your other shade of white, but it should not have the same RGB values). Next you must wisely choose your hues, the basic color types that will compose your palette. Each hue should take up one or more rows of your palette (a square palette consists of 16 rows and 16 columns); these rows will be dedicated to varying shades (measure of brightness) of your hues. For example, you could dedicate a row to the color gray (hey, gray is not a color!); it should start out with a very dark gray, then each slot following should be successively brighter, until the very last slot in the row is very bright gray. (For more on this, see the special article on Palette creation. You will definitely want gray, red, orange, yellow, green, blue, brown, and peach (also called "flesh"; do not confuse this color with pink, it is very important for drawing, you guessed it, human skin), as these are some of the primary colors that have many applications. Other colors such as cyan (neon blue), purple, pink, to name a few, may not be entirely useful to you; it is necessary to consider what you will be drawing in your game to decide on the proper palette.

Try to consider rare colors, because you do not want to be stuck with a palette that is not capable of drawing something you need. Think of the colors required to draw snow (white alone will not make very good snow!), or sand (yellow does not work for sand!) for example. Do not waste palette space with useless colors just to fill up the palette; if you have thought of all the colors you need, dedicate another row to more shades of a useful color; example: I use many shades of blue, so I would want to make the first row consist of dark blue to blue, then the second row blue to bright blue. A note you might want to take in order to have a palette filled with distinguishable colors is that the normal intensities of a color are often less easily differentiated by the eye then the lighter and darker shades of a hue; this means that you may want to have more bright and dark shades of a particular hue than you have mid-ranged shades. An adequate example of a hue/intensity based palette structure is the one I use for DA2 (9,1). However, do not make the same mistake of having 32 similar shades of black and white, as this palette does!

 

 

Here're the example tiles, chico

 
 

Shading
Now that you have your palette, we can get to the fun stuff. But first, a quick note on structure. You will be drawing tiles (most likely 16x16,32x32, or 64x64 in dimension). These are essentially little square bitmaps that you can draw your sprites or tiles in. To keep these tiles separated, you will need borders, which are hollow boxes two larger in dimension than your actual tile size (so a 32x32 tile would be surrounded by a 34x34 border). Your border must be easily distinguished from the rest of your tile, hence you should choose a color not often used (a wussy color like pink :-) ) for the border. That said, there is a fairly simple concept that can turn your piece-of-crap-artwork into something beautiful: shading. Shading is the representation of how light affects an objects appearance; basically, it shows how your object reflects and obstructs rays of light. If you want to see an unshaded object, look at the flat apple (2,9). Not very flattering, eh? Its shaded counterpart (3,9), on the other hand, while not perfect (hey, I'm not THAT good!) probably looks better to most people. First, since we are dealing with 2D art and your lighting will most likely not be real time, you must choose a fixed "source of light" from which you can calculate how your objects are shaded (this light source will be referred to as a "hotspot").

I generally use somewhere around the upper right corner for my hot spot; you may also use the same, I will not sue : ) . Also note that my hotspot is located "in front" of the object (this is important not only because you want the visible part (front face) of the object to receive the most light, but it will cast shadows more towards the back, so that the shadows do not fall off the sides of the tile). Parts of your objects that receive the most light from your hotspot will be shaded by lighter colors of your chosen hue, while parts of your object that receive little light will be shaded darkly. Parts where your object completely obstructs the light will be represented by a shadow. This sounds like an incredibly difficult concept, but it really is not; furthermore, your shading does not have to flawlessly follow the physical laws of light; no body will nit-pick (except for me :^) ) if your shading is a bit off.

The first type of shading you will learn is called phong shading; it is simply how a normal, smooth surface is shaded. I usually start by shading the darkest regions of the object first, but you may start with the lightest regions (if you start with the mid sections, you are a freak). A sphere (1,1)-(4,1) is one of the simplest models to shade, so we will use it to start with. First you must draw the basic sillhouete of a sphere: a circle; the color you choose to draw the base circle for does not matter, because you will be shading over it with another color. Find the darkest regions, or lightest spots, if you prefer, and shade them. Then continue onwards by drawing a series of successively brighter/darker crescents, or curved regions, until you have a have a fully shaded sphere; each shaded region should surround the next. Finally you will want to draw the shadow, which is fairly simple. The side of your object that recieves the least light will cast a shadow in its respective direction. Just imagine where on the ground the imaginary rays of light cast by your hotspot cannot strike, the areas where light is blocked by the object.

You may also cast shadows on the object itself (only complex objects would do this), but it is rather difficult and I generally avoid it, although you may wish to impliment such techniques. Note that in phong shading, objects are not really shiny, so you should only use dark to medium shades of your hue, excluding the brighter shades. Not all objects have smooth surfaces; some objects will have flat surfaces, or a combination of the two. A cylinder (1,2)-(4,2), for example, has flat top and bottom surfaces, but its length is completely smooth. Because light is evenly distributed about the length of a cylinder, the shading can be formed by using a series of increasingly bright lines. Flat surfaces are shaded according to which angle the light strikes them at; if a face (flat suface) of an object is perpendicular to the rays of light cast by your hotspot, it is shaded fairly bright; if a surface is very slanted relative to the light, it recieves very little light and is thus shaded darkly. You should first separate the distinct faces of your object with random contrasting colors then shade accordingly. Thus a the side of a cube (1,3)-(4,3) facing the light will be shaded relatively light, and the other faces will be shaded medium or dark intensities, depending on how much light they receive. Flat shaded objects, the majority of the time, are shaded with no more than one color to a face.

Of course, in your game, you will probably be shading more than just primitives (simple objects such as cubes, spheres, and cylinders, to name a few), so you must master the shading of complex, or irregular (1,4)-(4,4), objects. First you must find the "dark spots" on your complex object, the places that receive the least light, then shade those accordingly. Next you shade outwards from those spots, with increasing lighter shades of your chosen hue. Wherever your shading converges (for example, the outwards shadings of two dark spots hit eachother) try to mold the two shading areas smoothly together, much like how two drops of water stick to one another as the distance between them lessens. Et voila (yes, I do speak Francais : 0 ), you have a beautifully shaded blob-thingy.

At this point, you may be asking yourself, why did I not just use a gradient (a flood fill that automatically blends from one color to another in a given direction and form)? Well, first of all, many programs can not perform gradients in eight bit modes (Do not work in 16 or 24 bit mode and try to convert down to 8 bit, I guaranty it WILL LOOK LIKE CRAP!). Secondly, hand shading pixel by pixel is much more versatile, and with practice, will produce far more accurate shading. It may seem tedious at first, but take it from me, it is a skill quickly learned, appreciated, and adapted to.

 

Geez! Look at these tiles!

 
 

Metallic and Chrome
The next type of shading is called metallic shading, which gives objects the quality of shininess (oooh, shiny :} ). It is essentially the same as phong shading, except for its color range and shading regions. The color range used to shade the object usually goes from a mid shade of its hue to the hue's very brightest shade, although occasionally you may use darker shades instead of mid range shades as your base intensity. The shading regions (sections of your object that have different light intensities) on shiny objects usually follow this pattern: the darkest regions take up the most space, and as the regions increase in lightness, there is gradually less and less space between them.

All shiny objects have what is called a highlight, which is in essence a reflection of your hotspot. Where light intensity on your object is highest, a highlight occurs. If you can find a really shiny object near you and there is only one light in your immediate area, you can probably see a shiny spot on the object; this is its highlight. So to shade a metallic sphere (1,5)-(4,5), you could draw a series of concentric circles (circles within circles) that gradually converge around your highlight. All the while, the distance between them should be shrinking, so it appears that the highlight gains in intensity as it is approached. Shiny cylindrical (1,6)-(4,6) objects are simple; where light is intensity is highest on the length, draw a very bright line (the highlight on a cylinder would be a line down the length, because -if you remember- light is evenly distributed on a cylinder's length).

If the top of the cylinder is perpendicular to your light rays, it should also be a very bright shade of the cylinder's hue. The same applies for flat objects (1,7)-(4,7); light is evenly distributed about a given face of the object, so where light strikes a face directly, the whole face is very shiny. As for irregular metallic objects (1,8)-(4,8), they follow the same general shading rules of phong shaded irregular objects, except that the shading regions must be spaced as the ones in the metallic sphere are, and eventually, where all the shading regions converge at their highest intensities, highlights form.

The next type of shading is called chrome shading, or reflective shading. As its name states, it is a type of shading used to depict very shiny, reflective objects such as those composed of polished silver or gold. Chrome shaded objects reflect not only light, but everything around them as well. For this reason, chrome objects are rather difficult to shade, and you may not want to use them often, especially if you have to animate a reflective object. Because we can not render real-time reflections on our two dimensional bitmaps, we must come up with a general scene that will serve as a pseudo-reflection map for our object. The most common way to do this is set up an imaginary plane (infinitely large flat surface) and an imaginary sky for our object to reflect. Any given part of a surface on a chrome shaded object reflects whatever it "sees" that is perpendicular to it. Thus, the bottom half of a sphere would "see" our imaginary plane, and the top half would "see" our imaginary sky.

To make a chrome shaded sphere (5,1)-(8,1), I recommend that you first make a metallic sphere. Then draw in the region where the plane would be reflected (you need not draw in a sky region, as that is represented by the top half automatically). The reflection of the plane will curve with the sphere, ultimately creating a crescent shape at the bottom of the sphere. To distinguish this crescent shape from the top half of the sphere (the "sky" reflection), you must shade it either relatively darker or lighter than the top half; shade this region like you would shade a phong object. For cylindrical objects (5,2)-(8,2), the planar reflection is also curved like the sphere; the two reflection types are virtually the same, unless the cylinder top slightly faces the plane, in which case it must also reflect accordingly. Flat surfaces (5,3)-(8,3) are rather easy to calculate reflections on, because they do not distort the reflection at all. The more downwards-tilted a face of a flat object is, the more of the plane it reflects; it may entirely reflect the plane. If a flat face is perpendicular or tilted upwards from a plane, it will usually reflect nothing. Thus, a reflection on a cube could be represented by simple flat regions being reflected on the appropriate faces of a metallic shaded cube. Irregular chrome objects (5,4)-(8,4) are very difficult to calculate reflections on. You must first shade the chrome object metallic, then find parts of the surface that can "see" the imaginary plane, or are tilted downwards. Then you finish it off by phong shading these regions a contrasting shade.

Texturing objects
Lastly, you must learn how to texture. So far, we have been shading objects with no patterns on them; to shade objects with patterns, we must first make a pattern mask (the process applies for all object types). A pattern mask is an unshaded version of your object with a pattern applied to it. Note that as objects curve, so do their patterns, so -for example- a cylinder's pattern would be squished at the edges and broad in the middle. The mask (5,5)-(5,8) will be composed of two or more colors depending on your pattern. Then as many colors as are in the pattern mask, single objects must be shaded for each color [(6,5)-(6,8);(7,5)-(7,8)], such that you would have two objects if your pattern contains two colors. Then the mask is applied to one of the shaded objects, with the opposite color dropped out (made transparent) of the mask (8,5)-(8,8); this should result in an object that is half shaded and half covered with a different color of the pattern mask. Then you finish it off by doing the same for the other color(s) (9,5)-(9,8). That is it! You should have a textured object, if you did not royally screw up.

This concludes the tutorial, but check back next month for more shading techniques, such as bump mapping and pseudo-transparency, as well as entirely new concepts such as tiling and others!

Tell Gavan about your days doing the art for Street Figher at this address.

 

Back to Top

next issue

By Zkman

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

Next issue is comin' your way on June 19. I'm not really sure what you should expect, but look for another voxel article, mebbe some more physics and art, and lotsa super-secret stuff! And don't forget to read the specials we post in between issues! Also, don't forget to register your QB company with the Visionaries Exchange. Till next time... END

 

Back to Top