# QB Express

### Issue #12 ~ July 20, 2005

"A magazine by the QB community, for the QB community!"

### In This Issue

Contributors

- Pete (Editor)
- MystikShadows
- Na_th_an
- Lachie Dazdarian
- Adigun A. Polack
- SJ Zero
- Rattrapmax6
- Jacob Palm
- Moneo
- dumbledore
- Matt2Jones
- Nekrophidius
- Josiah Tobin
- NEWKid
- Kevin D.A.G.

- Regular Columns
  - From The Editor's Desk
  - Letters
  - Express Poll
  - News Briefs
  - Gallery - Wetspot 10th Anniversary Remix - Adigun A. Polack
  - Awards
  - Comics - QB Horse Humor, Lobster Comics
  - Final Word
- Articles & Editorials
  - QBasic GUI News - Jacob Palm
  - Searching For The Unknown: Trek by Brian Watson - Lachie Dazdarian
  - The Hidden Art of Game Development - SJ Zero
  - Behind the Screens: Interview with Dr.Robo - Rattrapmax6
  - Review of The Griffon Legend by Syn9 - Josiah Tobin
  - Why Doesn't The QBasic Forum Ever Make The QBasic News? - mennonite
  - Reflections on QBasic.com - NEWKid
  - Review of Pixel Snake Gem Hunt! by Steven Danglis - Adigun A. Polack
  - The Evolution of Graphical User Interfaces - MystikShadows
  - What Got Me Into QB - James Kinney
  - Interview with Nekrophidius - Pete
  - First Anniversary, So Many Spectactular Memories! - Adigun A. Polack
  - QB/FB Legends of the Year Awards 2004-2005 - Adigun A. Polack
- Tutorials
  - I.F. Games Chapter 6: "A Nice Scripts Interpreter" - Na_th_an
  - Using WX-C In FreeBasic: Part 2 - Printing - dumbledore
  - Music Composition, Part 3 - Matt2Jones
  - Useful QBasic / QuickBasic Algorithms - Edward F. Moneo
  - Database Design, A Complete Study: Part 1 - The Theory - MystikShadows
  - Coding a Parallax Scrolling Platformer: Chapter #2 - "Parallaxing" - Na_th_an

## From The Editor's Desk

### Written by Pete

Twelve issues.

One year.

Wow.

Last August when I started QB Express, I had no idea that it would become this huge and successful. One year later, QB Express has printed more articles than any other QB magazine ever.

And it's not like we just barely surpassed the record set by previous magazines. Every month, QB Express clocks in at between 100 and 145 pages. QB:TM averaged about 40-50 pages per issue back in the day, and those issues were considered HUGE. People that say the Qmunity is dying don't know what they're talking about.

On this special anniversary issue, some major congratulations are in order for everyone involved in the past year of QB Express. There have been over 100 contributors, and I thank each and every one of them. This month, Adigun A. Polack took it upon himself to write two articles congratulating QB Express contributors and legends from the past year. As you'd expect from articles by AAP, they're gushing with fanfare.

This issue isn't just a celebration of the last year of QB Express though -- it's still got all of the regular features and articles that you've come to expect from this mag. We've got six fresh new tutorials and a record twenty-two other articles for your reading pleasure. There's 312KB of text alone in this issue, and every bit of itching to be read. So I won't hold you any longer.

Enjoy this issue, and don't worry -- you can look forward to another great year of QB Express to come! Unlike QB:TM, the magazine which QB Express was heavily modelled after, we're not going to stop after just twelve issues. This is an exciting time for the QB/FB community, and QB Express intends to be here to cover it!

### Submit To QB Express

You all know the drill. This magazine can't exist without people SUBMITTING articles, editorials, tutorials, reviews, news and feedback. This is not just a solo effort by me... it's a group effort by people throughout the QB community. If you have anything to submit, or have time to write something, DO IT!

If you want to write about something, but can't think of a topic, or need inspiration, email me! I'm good at thinking of stuff to write about, and I know quite a bit about the QB community and about QB programming. If you're interested in getting your own monthly column or just want to write an article or two, by all means, do it! Anything that is submitted will be included!

I also want feedback and letters to the editor regarding this magazine. I want suggestions and critiques. What do you like? What don't you like? What could be done better? Let me know!

All submissions and feedback can be sent to pberg1@gmail.com. You can also PM me on the Pete's QB Site or QBasic News message forums. If QB Express is going to continue to be so good, YOU need to contribute!

-Pete

## Letters

### Letter From Lachie Dazdarian

It's been around two months since my last letter and the amount of things/events I wanted to comment and write about accumulated to gigantic proportions. This letter simply had to be written. I need to share these thoughts with others. It's a disease. I already had a letter written about issues #9 and #10 but continuing on that letter would be foolish since that letter was HUGE(4 pages in Notepad, in full screen window mode and in 800*600 resolution) and no one would read it(well, maybe you). Anyway, I'll try to wrap up my thoughts on issues #9 and #10 and mention the things I want to comment the most. I'm leaving the most current comments about issue #11 for the end.

The issue #9. Letters section, gallery and the awards section were excellent as usual. News brief section was brilliant as always and by my opinion, it's the backbone of the magazine. Your work on it is priceless! Space Invaders competition was really nicely featured and fun to read.

anarky's interview with Jorden Chamid was awfully fun to read. It's interesting to see how, by my opinion, Jorden has false ideas about the influence and quality of Future Library. Not all might agree but let's be honest, there aren't so many games made with Future Library compared to other libraries. And the VESA incompatibility. Ugh! I also never found QB45.com to be a community opened to newbies and/or very helpful. The number of files it hosted(and still hosts) is to admire but as of a community I don't have good memories of it. All help and friends I found in QBasic News forum. It's just my personal experience.

Rob Adam's(Deleter) article about keeping your project simple and fun to code was very interesting. He detected that apathy emotion so well and all programmers know it. On the other hand, I don't agree with his concept of making your game the simplest possible because how much over-detailing can be bad so much ruining a great concept with poor graphic and presentation is a shame. But it's nice to see people having a different approach to game design than yourself.

I must thank Vincent Peters for starting his "Writing a simple BASIC Interpreter" series. I thought that writing an interpreter is rocket science. That article was a real eye-opener for me.

Adigun's tutorial about implementing icons to FB exe files is simply great. I like programmers who can detect what pseudo-programmers like me want to know.

I was slightly disappointed with the tutorials section in the issue #9, after the first skimming through it, since I was under the impression of the new version of FreeBASIC(v.0.13) and the huge amount of new libraries it featured. I felt so impotent not knowing what 90%+ of them does nor I found the example programs useful. Although now I found most of the things I need to make the games I want in FreeBASIC, some of you elite programmers, and especially those who ported the libs in FreeBASIC, should take time to write more dummy level tutorials about using those libraries. More documentation, that's what FreeBASIC is dying for.

The issue #10. By my humble opinion, this issue what definitely premature and the update you did on it didn't changed my opinion. I really don't know why you had to release it on the 25th and not 5-6 days later(after you return from the long weekend). The main problem with the issue #10 is that it was released right after that QBasic News scandal, which I completely missed. Comments about the mentioned event couldn't have been written in the worst time since the comments will be completely different, more accurate and constructive only few days later. Now I'm glad that I'm online every 3 weeks or so and had missed the whole debacle. I just felt, reading the comments regarding the event, that most of the people(especially you Pete) went all too apocalyptic too soon. So instead of the regular A+ for editing I'm giving you B+ for this issue and you know you deserve it. Maybe we can all learn something from this. To be relaxed and to the do anything in haste. Haste is evil. :P Then again, I'm might be wrong which I realized after getting online again after 3 weeks(on June 23rd), reading the issue #11 and seeing the serious negative impact that QBN downtime had on the community. Uh, I'm so ambivalent. Still, I think it's a debate why the community is the way it is and what really is the problem. Think about it.

Other than QBasic News related, your other work in news brief, poll, gallery and awards section is great as usual and deserves all the compliments you get. Also, I think that in the issue #10 some of the text that shouldn't have been in bold was(Robert Hambly's AI tutorial and Na_th_an's "Coding A Parallax Scrolling Platformer" tutorial). But maybe that was done for a reason which I failed to notice. Or maybe the page was badly saved on my account(I always download QB Express and read it at home). Not really important.

Rattrapmax6's comic. The last thing I expected from you Rattrapmax6 is to go lower with the comic quality. I mean man, if drawing a comic to you is such a drag do something else. Scanning is ok, but at least try to write a readable text in the text bubbles. It looks like something it took you 30 minutes to do, if not less. I can't appreciate sloppy work.

Na_th_an, 1000 times thank you for starting "Coding A Parallax Scrolling Platformer" series. I was pondering on the idea of creating a neat platform game for quite some time, mostly inspired by great platform engines in QBasic like Space Commando, Fox or Martian Venture but was not keen in doing it all by myself. Now I can leach on your knowledge(evil laugher)!

I couldn't mention all the articles from issues #9 and #10 though I have written the comments on them. I just don't won't to turn this letter into a big drag(if that already didn't happened). Not that magazine contributors are especially needy for my feedback but I know how much I enjoy getting it.

Not about the issue #11. While being brilliant as usual this issue is also quite controversial and you can pretty much guess why, Pete.

I really have to mention the news section again. Sorry, I know you are tired of my compliments but your ability to keep it so great issue after issue amazes me. It always reminds me or informs me about the things I'm completely unaware. The fact I'm so seldom on the internet is probably another reason why I'm so impression with this section. I'm sad to admit that I still didn't downloaded any of QBXL Audio Editions. But after reading about it in the issue #11 back home I'm finally putting it on my to do list. Nice to see that QB45.com is back. I don't know how much I'll be frequent in their forum(it just doesn't sit well with me) but the fact it's updated and will continue to be is wonderful to hear. I just loved their first news after the relaunch. Very funny. I'm really sorry that TBN 1000 Line Platformer Compo failed but I personally never found attractive compos that limit you in the very programming. A lot of more useful news and things to download/check were added on my to do list.

Really nice work in the Gallery section. Made me very curious about The Griffon Legend. Looks like a very cool game. Can't wait for it's release.

Matthew R. Knight's and Gianfranco Berardi's stories about their QB history and life in general were terribly fun and interesting to read and are really something that give this issue that special mark.

Rattrapmax6 kind of pays off for the comic in the previous issue but more in the script department than in the art. PLEASE, try to write nicer in the text bubbles. I feel like you don't respect the people who will read it.

Very nice move with opening Project Updates section. It's nice to keep that kind of news on one place.

Now THAT interview with Sumo Jo, which I think will be remembered as quite controversial. Despite that it was a very enjoyable interview to read and gave me valuable insight on your thoughts regarding the current state of the community and the things that happened with QBN I think it will do more damage that good. Seeing you Pete criticizing someone so openly was quite a shock. Maybe that's just a problem with my subjective impression of you. I always pictured you as super-kind, all-friendly guy who can't comprehend the idea of a negative thought. Not that I force you to be like that but the very interview was, by my opinion, simply too harsh. I'm mainly talking here about your thoughts on Nek. Not that Sumo Jo wasn't equally harsh(if not more) but you as the editor have more responsibility toward the magazine. I just wouldn't like to see the community splitting into clans. I think this interview seriously opens a chance for some people to boycott his or her contribution to the magazine and starting some sort of negative campaign about QB Express. I'm not sure if the current situation in the community is the reason but where are Na_th_an's tutorials in this issue? The ones he announced in the issue #10. I've noticed him in TBN forum so I don't know if you ever had some sort of heat discussion with him about QBN and Nek which might have leaded to this. I sure hope you didn't and that this is not the reason why he didn't contributed anything for the issue #11. Then again, I'm not sure how big friend with Nek his is. Maybe I mixed it all up. As for Nek and his BIG friends/admirers I don't know how much they will be want to submit now. Also, Sumo Jo pointed out in the interview Nek's strange readiness to reopen TBN when QBN was down. This brings a fear in me that he might start releasing his old QB mag "QB ON ACID" again and try to be a competition to QB Express. Having in mind that we are not such a big community and the reason why QB ON ACID would be released again I don't think that kind of situation would be constructive. In fact, it could be devastating for the overall state of mind in the community. There are some other things that I didn't liked in the interview. I got the impression Pete that you think that most people who stayed in QBN forums are boring and not that worthy as the ones that left. I know you didn't thought that but it sounds like that. Not good. Like I said before, I fear that this interview will do more damage than good but I live in hope that most people will take it in good will and like adults.

The tutorials section in the issue #11 is a bit lacking. And I'm not talking about the quality of the very tutorials featured in it. I really think that community needs more FB, novice level, game design oriented tutorials to help us bring more flesh blood and energy in the FB game design scene. Also, there was couple of tutorial series that simply stopped to be released/written. The mentioned Na_th_an's series, Vincent Peters's "Writing a simple BASIC Interpreter" series, 19day's PHP series and couple of others. Some of these definitely stopped to be released while Na_th_an's and Vincent's might be just missing issue #11. I wish this wouldn't happen. Of course, this is not your fault. I'm just stating this sad fact. I must mention Deleter's "Ecosystem Simulation Through the Use of AI" tutorial. Amazing and very educational stuff. Thank you Deleter.

Anyway, that's it(for now :P). I hope everyone will take my comments and critics in good will since they were written in good will. I used the phrase "good will" 3 times in this letter. Well, 4 times now. FLAME ME! :P

Best wishes all,
Lachie "The AWARE Glory Hog" Dazdarian :P

> Thanks for the huge letter! You're pretty much the only person that ALWAYS gives *constructive* criticism on QB Express (instead of just being all happy and giving only positive feedback, heheh).

> First let me respond to your criticism of Issue #10 for being thrown together in haste and not covering the QBN debacle thoroughly and intelligently. You're right that it was thrown together right amid the QBN scandal when the community was in an uproar. However, that was precisely the reason why I released the issue early. I felt that it was important for somebody to cover the events surrounding the QBasic News shutdown, so I opted to release Issue #10 early while the scandal was still fresh in everybody's minds and everyone was still looking for answers.

> I do agree with you that the news coverage was pretty pathetic, but in the "news biz", being timely with a story is just as important as covering it well. Covering old news, no matter how thoroughly and intelligently you do it, just doesn't have the same resonance. However, I can understand why why you have a different opinion, having missed the shut down entirely. For those of us who were there during those few days, it really looked like the sky was falling. Now that everyone realizes we were all Chicken Littles for a few days, we can look back and see how silly the whole matter was in the first place.

> But, moving on...

> The interview with Sumo Jo in Issue #11 has been very controversial, but I think that your doomsday theories are a bit overblown. QB Express isn't going to lose any readers, and there's only one person who even considered not submitting to QB Express because of that interview (but it was also because he didn't like the formatting / gray boxes in the mag and didn't want his article messed up). Nekrophidius wasn't mad at all about the interview, as you can see by the counter interview he did in this issue. You'll also get a better idea of what I think about the matter too.

> What you have to realize is that that "interview" with Sumo Jo started as a private AIM chat. Sumo Jo mentioned that he wanted to post his opinion on the QBasic News shut down in the next issue of QB Express (since Issue #10 put a negative light on the site), and we got to talking about the Qmunity. Halfway through the conversation, after we had made all the disparaging remarks, I asked Sumo Jo if I could just publish that conversation as an "interview" in the next issue, since it contained most of his thoughts on the QBN shut down that he wanted to share anyway. Anyway, you can find the debate on this article, including responses from both Sumo Jo and myself, in this Basic Network thread.

> As for your fears of QB On Acid returning and stealing QB Express's thunder...I can't agree with you there either. Personally, I would *love* for that that magazine to come back. First of all, it was a great mag. Very fun to read, and had some unique editorials that you simply wouldn't find in other QB zines. Secondly, I want there to be as many QB magazines as possible -- that's the sign of a healthy community. I'm only doing QB Express to help breathe some life into the Qmunity. I mean, look how many tutorials, articles and reviews are published each month. Ninety percent of those would never have been written if this magazine didn't exist. If more magazines were running, even more articles would be published every month. The goal of QB Express is to get the Qmunity talking and sharing with each other...and if other magazines help me reach that goal, more power to them.

> As for your other praises and criticisms, thanks a lot! You were very, very thorough. Hopefully future QB Express writers will take your suggestions into account when they write their articles. (I know I will!)

> -Pete

### Letter From Na_th_an

Hi there, Pete. As always, congrats for running the best BASIC ezine of all time, without a doubt. Gray boxes/unindented code issues appart, this is one of the things I'm eager to get and read each month.

I'm writing this 'cause I think that some people would like to know my views about the recent debacle and why I am acting the way I am. I have read several statements that don't have to do with the truth at all, I know some people are calling me extremist, colourful or even part of Nekrophidius' sheep, in case of such a thing exists. Also, I'd like to make clear that this letter hasn't been spawned by your conversation with Sumo published in last issue of QBE only.

First of all: I never wanted glory. If there's such a thing as a "QB hall of fame", I don't want nor deserve to be in there. I don't hold a grudge against anybody nor I'm upset nor depressed nor anything like that. I think that we all, sane people, have true lifes outside the internet. But that doesn't mean that I haven't felt trashed.

About March 2001 I arrived to the QBasicNews forums from the VPlanet forums. Someone told me that QBN was much more populated and full of nice people. That turned to be true, and I began hanging around there trying to be helpful. I used to spend a lot of time coding my practical homework for college, so I kept a browser and posted from time to time to have a break. After one year or so, noticing that I kept searching for my own posts and reposting them to help people (who apparently didn't know how to use the search feature themselves, but meh), I suggested Wildcard to add some kind of wiki editable by a few, so we could add answers to the most common coding questions, then link to its entries in case someone asked for something covered in there. Haexadecimal Disaster kindly moded a simple yet efficient piece of software and Wildcard activated it, adding it to the forums. For some time, I dag in my posts to copy the text to the new FAQ, and everytime I answered a new question not covered in the FAQ I always added it as a new entry. My work, plus the work of many other contributors, helped building a good base of knowledge, awesomely organized by Agamemnus (this guy has a horrid coding style, but is an awesome coder and did a great work organizing the FAQ).

More recently, I found that the ABC packets, that huge collection of snippets which helped me learning both QB and MSDOS programming in general, were no longer available online. I thought that, as the packets were stored without compression and using a very simple (yet effective) encoding, it would be relatively easy to create a nice frontend to be able to view those snippets online and download them individually. I used Oracle's excellent GeShi to syntax-highligh the code and wrote the frontend using my humble php skills. I offered it to Wildcard and he accepted and uploaded it, placing a link to it in the forums.

The FAQ, the ABC viewer, and almost 7,000 posts made by me in three years were sent to the dust bin.

Now try to understand how I felt when I saw the QBN closure notice. I wasn't even posting in there, I was in some kind of hollidays from the forum 'cause some people got on my nerves and I began reacting violently, something which I dislike at all 'cause we log into the Internet to have fun, not to get angry. So it was something like "hey, QBN has closed!" in MSN Messenger and me noticing how just the freeBASIC forums were left up "temporally". The best thing of it all is that Wildcard didn't even bother on explaining what happened. His message was just a "I'm shutting this off".

Nice, thousands of bytes of my own work directly sent to shit. Now understand me. I got mad. Luckily, Nek was kind enough to reopen The Basic Network. I still can't understand how people look this action with bad eyes, 'cause he reopened the fucking site 'cause it was needed. He wasn't taking advantage of anything, he was offering people a place to express themselves. When a highly populated and active forum such as QBN suddenly shuts down without further explanations, people feel confused. I felt confused, and discovered TBN was on so I at least had a place to ask what the hell was happening.

TBN was opened some time ago for the first time. When Nekrophidius noticed that it was dead, that nobody but the admins posted, he closed it. When QBN was shut down, he was fast to reopen it. Is that taking advantage of the situation? What advantage? Does the government pay you for having people in your forum? There's some kind of QBN religion, or at least it seems so. Every attempt to open another forum is considered rebellion, or something like that. That's the most stupid thing I can think of, but since TBN was opened for the first time it was considered an attack against the almighty QBN. Attack my ass. Forum wars my ass.

I don't visit QBN anymore 'cause I feel bad when I think about all that happened. Not good mojo. I don't hold a grudge against the forum, as it is a bunch of bytes... it would be stupid to hold a grudge. But I just feel to calm down and ease my mind.

But people like to simplify things. There are some "dissidents", those guys who usually rambled and bitched against admins at QBN. Who are those? Many. How are the ones who shout more? Rhiannon, Nekrophidius, aetherFox, me, followed by some people who, while they disagree, maybe the are not as rude or as mean or as insistent. Who's the one who bitches most? Nekrophidius. Then, every other person who thinks alike does so 'cause Nek "convinced that QBN is evil and he knows all". That's 'cause the bandwagon culture people tends to have. It's easy to think about Nekrophidiusgnan and the Three Musketeers.

But that's not true. Nekrophidius hasn't convinced me of anything. I have my own ideas, my own thoughs and my own opinions. That my opinions very often are in the same ship than Nek's doesn't mean anything but that great minds think alike. There are tons of things upon which Nekrophidius and I disagree. As there are tons of things upon which aetherFox and I disagree, upon which Rhiannon and I disagree, and every other possible combination.

Nor other people who are TBN regulars aren't sheep. I don't think Nekrophidius convinced barok, cha0s, deleter, DrV, Frobozz, Josiah, KiZ, Lachie, lurah, Marzec or SJ Zero that QBN is evil and that they should come to TBN.

Luckily QBN is now being ruled by Sumo. I've always stated that I like his work as a webmaster and I know for sure that he's more than qualified to run QBN in the best of ways. I wish him luck as I do to Wildcard, whatever he's doing and whenever he is. He fucked up QBN with a childish action driven by pure angst, throwing thru' the window more than 5 years of excellent work. But I won't hold a grudge.

Cheers, keep this mag going and keep Lachie's reviews on, I love them. He's a great reviewer and goes straight to the point.

Na_th_an

> You know, when QBasic News shut down, I had the same exact reaction as you did -- "how could anyone delete all that work and destroy such a wealth of knowledge!?" Of course, that's coming from someone who had made fewer than 250 posts there and had only been really active in the Qmunity for a year (not counting 1997-2000). So I can only imagine how you must have felt, with 7000 posts, and the FAQ/Wiki and ABC Archives to your name. I've said it before and I'll say it again: Wildcard had no business shutting down the site like he did. He may have owned the server, but he didn't own the content -- and it was totally unfair for him to shut it down without warning. Had he given a few days' notice and offered a copy of the site archives to someone to back up on another server, I don't think anyone would have reacted like they did. Just because he wanted out, he didn't have to take the whole community with him.

> As for the Nek interview and the "sheep" thing, thanks for sharing your thoughts. I myself never really considered the TBN people to be "sheep", and I certainly didn't think anyone there worshipped Nek. I agree with you that everyone that has abandoned QBN for TBN feels kind of like you. The QBasic News "experience" was ruined by Wildcard's shenanigans, and now the community that was once there is a shadow of its former self. I do think it's kind of extreme to swear off posting there for good... but I also see another better reason not to post there -- "why bother?" QBasic News really doesn't have much to offer with all the people gone. Unless you're going there for reference, it's kind of ... dried up. It just isn't a fun or interesting forum anymore. And this is coming from someone who still posts there regularly.

> -Pete

### Letter From MystikShadows

Hi Pete,

I read QB Exress #11 this morning at 5:30 AM sipping my first coffee of the day. House is quiet at that time and it's the best time to soak up everything that QB Express has to offer. One thing I love about the magazine is not knowing what to expect when you first start reading. That's always a good different surprise from the typical computer related readings one gets to do in this world :-). Life really is full of surprises and a magazine that can add to that is a successful magazine. What can I say, QB Express delivers more than what a magazine is required to :-). And like you say in your introduction, it really is a particularly excellent issue. As they say in the X-Men movie, every now and then, evolution leaps forward. Sure they talk of mutants in that movie, but this quote applies to QB Express, I believe. It's evolving quite well and the contributors finding their ideas and writing them now is just proof of that. :-). And as for me being a mod now at QBasicNews, well Sumo posted the "help wanted" sign so to speak, and I applied :-) I guess they liked something about me to decide to make me a mod (what? I have NO idea LOL). But I'm proud to be a mod now, and I'll do my best, that's all that can be expected :-).

I have my own theory as to why GUIs are so popular in the Qmunnity. My first theory is of course people are gettting tired of Windows and any GUI that is similar to it. although the envelope the new releases are presented under look better and better, they contents they have inside the envelope stays the same. Let's face it, sonce 1996, when Windows 95 came out (that should tell you something right there ;-) Windows didn't really change much, it just broadened itself to reach more and more stuff (internet, document, gaming world, etc etc) All in all, Windows is still an Icon based system where you either double click on a file or on an application and start using it. I believe people are waiting for a breakthrough GUI that can really revolutionize the world as we know it. As such they are always hoping someone makes something that just works better. I really wish one representative from ATI and one from nVidia (and a couple printer manufacturers too) would get to read this. Windows isn't what it used to be. Alot of hardware vendors are now sold to Windows so to speak and I think they are sealing their faith with that, not their success. Over the years I've seen some great ideas and concepts dissapear (OS/2 being the more popular alternative (it's not a mainframe only product, and BeOS too has dissapeared completely). I always say if Windows was the real solution, people wouldn't be developing GUIs and I'm not just talking the Qmunity either. :-). windows is shooting itself in the foot, especially with all the trials they have to go to for copyright enfringments and all, but also by the fact that they seem to want to give users less and less control over their system. No user likes that cept the ones that have no idea what goes on in the windows registry.

As far as the Magazine contents go, I have to point out that I think I'm gonna enjoy the "Searching For The Unknown" series alot. It's very true that alot of games, tools utilities and others really don't get the recognition they deserve today or deserved back then. I think it's an excellent initiative made by Lachie Dazdarian. Also, The interview with Sumo Jo was interesting to read :-). I don't agree with everything that was mentionned about Nek however and I had to point that out :-). At least I don't agree with the fact it was mentionned in an interview with Sumo Jo. Maybe, if you can, you should have an Interview with Nek in the next issue ;-). I guess different people have different opinions about users. Nek an I represent the older side of the Qmunity (with a few others ;-) and with my dialogs, emails chats I've had with Nek weather for a project or for a simple conversation, my opinion of him is not the same as yours and Sumo's :-). Nek is blunt, no two ways about that, but aside that, I didn't recognize Nek in the little I've read about him in the interview. None The less, the interview was a good read, again some great points were made and I think it answered alot of questions alot of users had about QBasicNews and it's future. :-).

Like I mentionned in my previous letter to the editor, A.I. has always been a personal favorite subject of mine so needless to say, I really enjoyed "Ecosystem Simulation Through the Use of AI" by Deleter I really like his perspective on ecosystems and how he explained it for all to read. Great work there. Take a popular or hot Item in the Qmunity and put it in a horse humor comic and it's amazing how much better the comic turns out ;-). Good choice of subject Rattrap :-). I liked Moneo's view about "Data Validation Implementation" some good points were made in his article, you can tell research was put into this article :-). Pyrodap's tutorial on Roguelike RMG couldn't be better timed since there is the Roguelike Compo going on. Great timing on that and the tutorial was a good read :-). As for the Commercial and Professional development Series well they're mine so I guess it was good ;-). a 6 part series coming to an end, what will I write about next? ;-) Stay tuned to find out. There's definitaly more on the way ;-).

All this to say that all in all the whole Magazine took, yet again, a big leap forward and you, and the contributors are all to thank for that. Everyone knows the Qmunity wouldn't be where it's at if it wasn't for QB Express today. So shut up and take the flowers when we throw them at you man. Or i'm gonna be on the plane to where you are and i'll make sure you can't part with them ;-) LOL.

-MystikShadows (Stéphane Richard)

> Great letter again! Your enthusiasm for QB Express every month sure is flattering. :-)

> While I agree with you to a degree on your "why QB programmers love GUIs so much" theory, I'm not sure if the real reason is that people are getting "tired" of the Windows layout. The reason I say this is -- the vast majority of QB GUIs I've seen have been Windows clones! In fact, there have been dozens of them where the name is a derivative of "Windows"... Windos, Windoze, Win-Doze, Windoof, WinGUI, etc. You get the point. I think the majority of QB GUIs just copy established GUI formats, whether from Windows, Mac OS or some other OS.

> Also, thanks for the suggestion that I interview Nekrophidius. As you can tell from the table of contents, I did just that this month. But... I'm going to refrain from typing my thoughts on this issue again here, since I've already done it a half dozen times in this issue and I'm sure everyone's getting sick of it!

> -Pete

### Letter From Kevin D.A.G.

Dear QB Express, Pete, and mostly Lachie Dazdarian,

Kevin D.A.G. here. (Creator of Astral Worlds)

Thank you, Thank you!

I really appreciate the listing, review, and upgrade of my game engine. I know it’s sort of a weak program but I’m happy to hear that some enjoyment could be found in it. I made it as an example of what could be accomplished in Q-Basic for my twelve year old brother. I’m not much of a programmer but more of a bored hobbyist. Thank you both for all the time and effort spent. I especially enjoyed reading the game overview and Dojoepa walk through. I promise to submit a new, more stable program that I’m currently working on. It’s a two player dungeonering card game. It will be in raw basic, so I could really use the help to make it an Exe. File.

Thanks again.

A true fan of your page and work,

Kevin D.A.G

> Thanks for the kind words! Lachie's "Searching For The Unknown" column is one of the best things that we've had so far in QB Express in my opinion. After all, if he didn't write it, the majority of our readers would have never even heard of Astral Worlds.

> -Pete

Have a letter for the editor? Send all your rants, raves, ideas, comments and questions to pberg1@gmail.com.

## Express Poll

Every issue, QB Express holds a poll to see what QBers are thinking. The poll is located on the front page of Pete's QBasic Site, so that's where you go to vote. Make sure your voice is heard!

### What was the most devastating QB site shut down?

Shut Down | Votes | Percent | Graph
QBasic: The Magazine (1999) | 4 | 8.2% |
QBT50 (1999) | 1 | 2% |
QuickBasic RPGs (2000) | 3 | 6.1% |
Pete's QB Site (2000) | 7 | 14.3% |
Enhanced Creations (2000) | 1 | 2% |
NeoZones Productions (2001) | 5 | 10.2% |
QB45.com (2002) | 7 | 14.3% |
Darkness Ethereal (2002) | 6 | 12.2% |
QBasic News (2005) | 9 | 18.4% |
Other | 6 | 12.2% |
49 Total Votes

> Now that the Qmunity has recovered from the traumatic QBasic News shutdown in May, I thought I'd bring up some of the other "devastating" QB site shut downs that have happened in the past. There have been literally thousands of QB sites on the Internet over the past ten years, and most of them have lasted for only a couple years at the most. If there's anything we know about the Qmunity, we know that it's certainly not constant. The QB scene ebbs and flows, routinely switching forums, watching beloved websites come crashing down while fresh new ones sprout up and replace them. And somehow, every time a major QB hub comes has an unexpected closure, people panic and declare that the QB scene will never recover. And as we know, it always does.

> Nevertheless, I thought it would be interesting to look back over the years and find out what everyone else felt was the most devastating QB site shut down. After all, with ever QB site that goes down, the Qmunity loses something that will probably never recover, whether it's simply content, or a bustling forum community that will never truly be restored. When the votes came in, the recent QBasic News shut down came in first (predictable, since it was fresh in our minds and also the only shut down that many of the QB scene's newer members remember). Justifiably, QB45.com's 2002 crash came in 2nd, tied with my own site's abandonment in 2000. Other top vote getters were QBasic: The Magazine, NeoZones Productions and DarkDread's RPG group Darkness Ethereal. All of these sites had a strong and lasting effect on this community, and old QBers look back fondly on the golden days of these sites. It's a sad fact that the wonderful communities that inhabited these sites, and their pages upon pages of interesting content had to disappear into cyberspace. But don't worry -- what the stood for, the QB/FB community -- is here to stay.

## News Briefs

News from all around the QB community, about the latest games, site updates, program releases and more!

### QB Site News

QBasic.com Scare

  QBasic.com had a few days of downtime at the beginning of the month, which stirred the site's regular visitors into quite a frenzy. Meanwhile, the shutdown ignited talks of squatting the covetted domain name among many opportunistic webmasters. Many people saw the "loss" of QBasic.com as a devastating blow to the Qmunity, while many others said "good riddance", glad that we were finally rid of the decrepit haven of broken links and outdated software that would invariably greet new QBasic programmers when they looked up "QBasic" on the Internet.

  Anyway, it turns out that the ruckus was all in vain, because QBasic.com didn't shut down -- it just switched servers. The same old site is back up at http://www.qbasic.com . Take note of the "www." in the URL -- that's required now. If you want to see what QBasic.com looked like during its downtime, just visit http://qbasic.com.

FB Wiki Almost "Complete"

  FreeBasic's official documentation, the FreeBasic.net Wiki, is nearing "completion." Only a handful of commands are still missing entries. However, just because almost all the pages have had *something* written on them, they are by no means thorough. So all you FB coders out there -- get off your butts and add to the Wiki!

One Man Army site reopens

  Apparently one QB/FB site just isn't enough for SJ Zero. Now in addition to QBXL.net, SJ has re-launched the site for his game "company", One Man Army Games. The OMA development page is for his programming projects, while QBXL is for the "editorial side of things".

  The funny thing is that he announced the creation of the site by saying: "it's time to drop any pretenses and just create a site dedicated to One Man Army Games and the various projects we're working on.." Sounds like a contradiction to me, but I'll just pretend like I didn't catch it. :-) Anyway, visit the site to get Quest for a King or Star Phalanx or Rambo vs. Kitty Cat (pictured to the left), if any of them strikes your fancy.

QB45 Keeps Updated

  Over at the recently-relaunched QB45.com, Jofers has been keeping things fresh. The site gets regular QB news updates, all written with a healthy dose of Jofers' offbeat humor. Plus he's added a few dozen new programs to the File Downloads section in the past month, all of which he's highlighted on the front page. So... QB45.com and Jofers -- for your efforts, I salute you with a solitary clap. (Clap!)

Redesigns! Redesigns!

  This month, two relatively new QB sites have had major redesigns. First, Jacob Palm's GUI site JacobPalm.dk got a fresh new design, featuring brighter shades of blue and an overall more eye-pleasing appearance. Spiffy!

  QBasic Network, anarky's site, also got a redesign. Instead of the Blue Steel layout that many people detested, he switched the site to the Microsoft Frontpage "Highway" template. In addition to the new look, anarky relaunched "Blobworld Comics", the comic strip that Seph used to do before he left the scene. The thing I find unique about the QBasic Network redesign is that now this site doesn't have a single trace of "QBasic" content on it. In fact, anarky removed the QBasic forum from the site entirely. Meanwhile, there's quite a bit of FreeBasic stuff. Wouldn't "FreeBasic Network" be more appropriate?

Fling-master Passes On RPG-Dev.net, QBRPGs.com

  It seems that Fling-master is gradually pulling himself out of the QB RPG scene, letting his wide collection of RPG programming websites switch to new ownership.

  A few weeks ago, Fling-master posted the following message on RPG-Dev.net, his multi-language RPG coding site:

  > As you may have guessed, not much is happening with this site. It's not that I've lost interest in the site, it's just a lack of motivation combined with other projects on the go, combined with not a lot of free time for all of them. So, I'm cutting out a few projects, one of which is this site. So, that being said, if you would like to own this site AND are willing to put forth the work to keep it going (you MUST have proven PHP/SQL experience and be into RPG development of course... need to make sure that you CAN continue to run the site and that you are at least interested in it heh), then reply to this topic and we'll talk about it further.

  As of right now, nobody with the proper credentials (ie: their own server) has volunteered to take over the site, so if you're interested, drop in at the RPG-dev.net forums and plead your case.

  In other news, Fling-master has allowed the QBRPGs.com domain name to expire. That means that all of the sites that we used to access through a QBRPGs.com address -- QBRPGs.com, The QB RPG Top 50, QB Chronicles Magazine and Jocke The Beast's site -- are now only accessible through their alternate addresses on the QBasicNews.com server. Jocke The Beast has spoken to Fling-master about acquiring the domain name himself, but at the moment, QBRPGs.com points to nothing. Hopefully this will all get sorted out soon, and the hosted QBRPGs sites will get restored to their normal, *working* selves.

  Update at the last minute: Well, it appears that Jocke has already moved his site to a new host -- Plasma's PhatCode.net server! You can now access his site in all its glory at: http://jockethebeast.phatcode.net/

FBTK Roguelikes Compo Marches On

  Probably the most popular QB / FB competition of recent memory, the FBTK.net Roguelike Competition has continued to thrive this past month. You can find out all about it at the Rogue Compo Forum, which contains an official rules thread, a "messy discussion" thread and threads for many of the individual teams that have entered the competition. This month, there have been a few demos released, and a lot of discussion has gone on. I'm not gonna even begin to try to sort out and summarize it all. If you're interested, visit FBTK.net to check it out for yourself. Maybe next month we'll have a feature story about the competition that will cover it more substantially.

### Project News

Star Phalanx for... Xbox?

  Indeed! SJ Zero managed to compile and run his space shooter Star Phalanx on Microsoft's popular (and x86-based) game console Xbox. Check out the *photographic evidence* to the right. To my knowledge, this is the first time anyone has managed to run a FreeBasic game on an Xbox.

  What does the future hold for FreeBasic and Xbox? I don't know, but it sure does look promising.

  You can read all about SJ Zero's experiment in this thread.

Lachie Ports Rel's Pixel Scrolling Engine to FB

  Lachie Dazdarian has released a FreeBasic port of RelSoft's impressive QB pixel scrolling engine which he created to demonstrate the power of RelLib a few years ago. This could be a very useful start for a wide variety of FB games.

  > Lachie said: "I've notice quite few people, including me, having problem switching to FB so to help myself and others I decide to port this lovely engine and heavily comment it. It uses GFXLib 2 graphic statements and Eric's FB PUT file loader(Pixel Plus 256 standard file format). You can create any kind of ZELDA style game in it, from an action game to a RPG."

  The package comes complete with all the features of RelSoft's original, plus a lot of Lachie's own additions such as a lot of PP256 support. Also, you'll find two compiled demos by Lachie to show off his work. Download this useful package: FBScrollEd1.zip, and then check out Lachie's forum thread to find out what's in store for future versions and how you can help him out.

FreeBasic Joystick Support, Courtesy of AAP
  Adigun Azikiwe Polack released a program that supports up to simultaneous four game controllers in FreeBasic, with up to sixteen buttons each. In case you're wondering, Xbox controllers and many other modern gamepads have 16 buttons, so Adigun's routines could be very useful. You can download this program here.
Unstable/Testing FreeBasic v0.14b Released

  The title says it all. V1ctor announced the latest beta release of the FB compiler on July 16th. "The Windows version can now be used to compile and link DOS, Linux and Xbox apps (including the compiler itself for those platforms), if the proper GNU binutils for cross-compiling are available. " Yummy.

Robo Raider 3D Motion Test

  Rattrapmax6 is working on an updated 3D FreeBasic version of his QuickBasic game Robo Raider, and a few weeks ago he released a 3D test program that shows off one of the new polygonal robot models that will appear in this game. In the demo, you can drive around the Radio-Controlled robot from a fixed camera perspective. Nothing especially impressive yet, but it's nice to see that Rattrap's got some cool stuff in store for us in the future.

FBIde v0.5 Features Announced

  VonGodric's FBIde v0.4 is widely considered to be the best for FreeBasic, but the next version will be even more impressive. VonGodric announced the new features in this topic... and here they are:

  > - Full debugging support
  > - to enable/disbale the sub/function only view ( Yes to hide all other as in QB's IDE )
  > - Add function/sub Tree view
  > - Bookmarks
  > - Full project support -project templates, settings, ...
  > - Advanced global ( in all files, project, ... )search
  > - Support for automatic upper/lower/mixed case for the keywords.
  > - Write real FB syntax parser for scintilla ( so far I'v been using modified VB's parser )
  > - Support for single instance of FBIde ( instead of opening new IDE for every file that is loaded outside of teh FBIde )
  > - Documentation
  > - Help support, costomisible Help menu
  > - File history
  > - Support and SDK for plug-ins, but that's a bit utopic right now... or not?

  VonGodric also mentioned a possible Linux port sometime in the future. You can find out more about FBIde at the official website: http://fbide.sourceforge.net/

LoKing's Dungeon Maze Generator

  Roguelike programmers take notice: LoKing has released a very nice random dungeon generator for FreeBasic, which is available on his website. I could definitely see a quality Roguelike game being made from this engine. It generates very large maps, and also has a map-view feature that keeps track of which areas the player has visited. In an updated version, LoKing added a 3-level light radius feature that can make the dungeon even more dark and scary than it was to begin with. Nice!

Power ASCII Lib by Rattrapmax6

  Rattrapmax6 has begun work on a FreeBasic library that will "get some of the FreeBasic graphic commands as ASCII text, then some effects text commands!" So far, the commands include:
  Graphics -- ACSII_INIT, ASCII_LINE, ASCII_LINEB, ASCII_LINEBF, ASCII_PSET, and ASCII_CIRCLE,;
  Text Display -- ASCII_ALIGN, ASCII_TYPE, ASCII_ATYPE , ASCII_FADE and ASCII_AFADE.

  This reminds me of Nekrophidius' old Useless Sock textmode "graphics" library. You can check out Power ASCII Lib in this thread, or just download this early version directly from his Rattrapmax6's website.

Three More Demos at The Junkyard

  RelSoft has updated his website, Genso's Junkyard, with three spectacular new demos based on these tutorials. The demos look great. Here are some screenshots:

  Check out all three of the demos: Ascaris (An undulating fake tunnel) , Jejunum (Camera based movement inside the PQ torus) and Peristalsis (A torus and a PQ torus with fake textures)

Neo MD5 and Image Alteration/Effects Libraries

  Neo Deus Ex Machina has released early versions of two new libraries:

  > The First FreeBasic MD5 Implementation
  > Well... just like it says. Contains a routine you can use to digest a message of any size to 4 UINTs (128 bit checksum). Note that this will most probably not return the same checksums as e.g. the PHP MD5() because of the different startup values used (called Magic Numbers in the algorithm). Also note that the download on Plantasy seems to contain an older (inoperational) version.
  > FreeBasic Image Alteration and Effects Module
  > A nicely sized library containing routines to alter and modify BSV images in memory (PUT compatible). Contains most functions you could think of and probably some you didn't think of. Note that some functions are multi-usable, suitable for different purposes, so don't think it's missing something until you know what all routines can do. It contains a test program that takes some sample BMPs and executes each routine on 1 different way on them. (There's a lot more than the output shows tho). Usually considered very complex for the ones just taking a look at it. It isn't very suitable for realtime rendering either, more for preprocessing.

  What are you waiting for? Check 'em out!

Wallace Software wishes you a Merry Christmas

  Wallace of Wallace Software announced that his anticipated QB shooter Contact 2 will be released on Christmas Day of this year. In recent weeks, Wallace has done some updates to the game's engine, including making "it a little bit more gruesome. Now enemies die in more than one ways, if they are killed with a pistol then they simply fall to the ground, but a rocket will cause their bodies to explode and spray blood all over the place, pretty cool."

Lithium's Phone Dialer

  Lithium posted a very interesting FB phone dialing program at FBTK recently. Here's the story:

  > The phone at my home was broken in the way that the buttons wouldn't make any sound, so we couldn't call out -- so I wrote a program that dials for the phone.

  > I just looked up the frequencies for each button on the internet, made wav files for each and wrote a quick little FB program to dial the numbers.

  > You just have to type in the number, hold the reciever up to your speaker, and press enter.

  Talk about ingenuity! If you're living in an area that still uses old-fashioned, tone-based telephone systems, you should check this program out. (Click here to download it.)

The Griffon Legend Released

  After only about two months of development, Syn9 has released the final version of his FB action RPG The Griffon Legend (which I previewed in the last issue).

  In this issue, Josiah Tobin has reviewed TGL for us, plus Syn9 has gotten some other recognition from QB Express for this awesome game. :-)

  The Griffon Legend is the first finished RPG written in FreeBasic...and I'll get straight to the point: this game rocks. I implore you to check it out. You won't regret it. In my opinion, this is the best FreeBasic game that has been released to date.

Xerol Bombards us With Shooters

  In the past month, Xerol has released at least two different demos of two different shooters (of sorts). The first is called Bombard, which features you shooting bouncy balls through a bunch of rotating squares. This was an unfinished entry for one of SJ Zero's FB coding competitions a while back. (bombard-0_2.zip) The other shooter is called ... Shooter. It's still in its early stages, but Xerol's planning on finishing this shooter sometime in the future. Check the FBTK thread for more info about the development of this game. (shooter.zip)

### Other News

Hear QBers Sing!

  Aetherfox has begun a music "Cover Competition" over at The Basic Network where participants challenge each other to sing and play a song in a certain style, such as "Nekrophidius, I challenge you to sing a high energy Japanese pop song or Anime intro!" or "I challenge Aetherfox to sing any song performed by David Hasselhoff.". So far, Aetherfox, SJ Zero, Na_th_an and Cha0s have taken the challenge. So if you want to hear these guys stretch their vocal chords and show their...ahem...talent, check out the thread. It's an interesting thread to say the least.

## QBasic GUI News

### Written by Jacob Palm

I feel like writing an article. In fact, I really like writing articles. So, I'm gonna write you an article. Or, in fact, more of a news brief. Although QB Express already has a news brief, this one will only have GUI-related news. Below you'll find some information about new (and upcoming) GUI releases, GUI pages and everything else going on in the QBasic GUI community. So, I'll just get to it right away.

- Brandon Cornell launches GUI reviews
  The author of the fairly new GUI Fun500, Brandon Cornell, has begun rewriting GUI's at his homepage. He posted the following message at the JacobPalm.dk forum:
  "I am going to change my site a lot! I will review a few of the newer GUIs that work on my PC, if they don't work I can't review then."
  So far there's three reviews up. Since the link in the menu bar doesn't work (yet, he's page is brand new), here's the direct links to the reviews: Linster OS, Costa and Edge.
  The Fun500 homepage can be found here.
- New GUI by MystikShadows in the works
  MystikShadows has begun working on a new GUI, ErgonOS. It will be different from most other GUI's (including Windows) in a special way. But rather than trying to explain myself how it works, here's MystikShadows' description:
  "I'm in the process of creating a new GUI. I've been working on the backend of it (hardware and dos detection etc...) and I just now started the GUI design part. I'll have a screen shot today or tomorrow.
  As some might not expect however, the GUI is very different than what most are acustomed to. It wont be a file based GUI like windows/linux/mac etc etc....but a Task or Work based GUI. Hopefully the Screenshot, when it's done, will help clear this concept up a bit.
  Think of it this way. Windows and the likes are application based GUIs right? where everything is related to an application, and typically the application governs the file format and what the file (data) can do. In my case it's the document that decides things. This would mean that there's no single applications per se...only application features that are available for the given type of document (word processor would have a Font/formatting etc ... source file would have compiler and other programming related features available. Is this clear enough or are you all thinking I must be smoking some real damn good stuff? LOLOL"
  The screenshot was released the day after the post:
  The screenshot above was made in Paint. The GUI part hasn't been coded yet, since MystikShadows is waiting for VESA support in FreeBASIC for DOS.
  If you want to read more about ErgonOS read these two forum topics: First and second
  Good look to MystikShadows with this promising GUI!
- JacobPalm.dk gets new GUI review system
  The menus at my site was getting pretty long, and only showed the name of the GUI. I've written a PHP system to display an alphabetical list of GUI's with screenshot, name, author, short description and ranking. Also, reviews are now much more detailed (I'm currently re-writing all reviews to fit into the new system).
  A little while ago, my site also got a brand new forum. It's much easier to use and more pleasing to the eye.
  My site can be found at http://www.jacobpalm.dk.
- Kyle McInnes releases Edge 0.6
  It's actually been a while since Edge 0.6 was released, but I didn't see it pronounced anywhere but my own forum, so here goes anyway.
  Edge is a nice screen 12 GUI with moveable windows and a good scripting engine. It also has a nice boot screen (not that a boot screen makes it better, but I kind of like it, and... Oh well...).
  Kyle is currently working on Edge 0.7, which will be released soon.
  Go to http://www.edge.us.tt for more information on Edge and other programs by Kyle McInnes.
- New GUI review site
  A GUI programmer who calls himself MPN has launched a new GUI review site. The site currently has 3 reviews and a lot of screenshots of MPN's own GUI's. A lot more reviews will be coming up, and so far the site looks promising.
  Go check the site out at http://users.adelphia.net/~mjn99/
- Fun550 starts work on new GUI
  A new programming group, Fun500, have started their work on a new GUI. 550 consists of 4 members, including Brandon Cornell, Todd Suess, MystikShadows and Y12. The GUI will be named Pheonix, and is planned to have multitasking and full customization. They've also set a goal to keep the code size below 3 megabytes.
  Just days ago, a preview on the windowing engine was released and is available from Pheonix GUI's homepage: http://pheonix.us.tt/. Below is a screenshot from the preview.
  It looks very good so far, and I will be looking forward to seeing the final version.

It looks to me like the QBasic GUI community is really starting to blossom, right now I can think of 7 GUI pages. When I started my GUI page in February 2004 I only knew of 2 pages. There are not many GUI's still in development, but the few ones that still are being developed looks great. I think maybe if more GUI tutorials were available more GUI's would be developed. But maybe that's just me :) Anyway, I'm currently working on a tutorials series on GUI programming in QBasic. Maybe I'll submit them to QB Express, so keep your eyes open ;)
Well, I don't have much more for you this time. I hope you liked it, though it really nothing special. I just felt like writing something, so, well...

Visit Jacob Palm's GUI site at http://www.jacobpalm.dk/

## Gallery

### Written by Adigun Azikiwe Polack

> For that past eleven issues of QB Express, I've taken it upon myself to write the Gallery article. This month, however, we have a guest writer. Adigun A. Polack sent me a full already-written gallery article for his upcoming game Wetspot 10th Anniversary Remix, and I couldn't resist. Considering that I didn't have any game submitted yet for the gallery and that Adigun did such a great job on his own article, I present to you: this month's official QB Express Gallery article!

> -Pete

### Wetspot 10th Anniversary Remix

As we are now nearing the 10th anniversary of one of our most fondly beloved (and even greatest, too!) QB classics of all time, let us celebrate this by taking you back in the day in such grandest style possible! And the newest upcoming game entitled “Wetspot 10th Anniversary Remix” is just the perfect thing to do it!!! Are you really ready for this? !

You know, ever since I have actually been granted special permission by the game’s original creator Angelo Mottola (aka lillo) for me to make the new additions to the original Wetspot game ever since it has first been ported successfully from QuickBASIC to the rather hot FreeBASIC compiler from this past January of 2005, it has become such an absolute GRAND honor for me to work on one of the most powerfully splendid QB classics indeed, all as a surefire way of thanking him on such outstanding work he has done on both the game itself and the port thereof!! =b

And, just take a good whiff at *plenty* of the new awesome screenshots that are gonna be implemented for this very special edition of this classic QB game in FreeBASIC!!!

Now, for this 10th Anniversary Remix edition here, many of its classic game features will be faithfully retained, plus a dash of PLENTY of great new stuff that players everywhere are gonna really be shouting about in such sheer fun and excitement, including:

- An ALL-NEW score-chaining system where the more you take out the enemies brick by brick in a row without missing one, the higher and higher your score can get and then some!!! (This feature has never before been experienced in *any* Wetspot game yet!! ^_-=b ! )
- Improved and retouched graphics (while maintaining the style of the original game!), plus loads of all-new and amazing backgrounds!!
- Buy-in feature (for two-player simultaneous games).
- Lots and lots of original sounds and music carefully created by Adigun Azikiwe Polack himself!
- An arcade-style continue feature!
- Brand-new surprises and shocking bonuses await you (if you’re SO good at this new game!)!
- Up to two joysticks/gamepads are now FULLY supported!!
- So many opportunities to score big, so little time!!

Also, this new game combines all of the original excitement of Wetspot from 1996 with some cool features of Wetspot II from 1998, but with much better stuff than ever, I must tell ‘ya!! And I promise you, there is an extra-special surprise for those who think they can clear the game with all 21 of its original levels beaten, so stay tuned!!

Things that I plan to add to truly put the icing on this splendid anniversary cake here are the game’s true ending sequence, some new cinemas, and a lot more new sound coding and some other stuff to code for this one. So far, the completion of this game is over the 60% mark already, but if it gets done at last and all goes smoothly well, then expect this game to be released somewhere in (or just before!) 2006, just to ring in this most special anniversary of one of our most immortally precious QB relics of all time in FB!!! d==b

Just think of all this as a bit of Super Mario All-Stars in a sense, too, you know what I mean? Anyway, this will hold you *very* nicely until Wetspot III arrives!!

This is Adigun Azikiwe Polack, out!

Visit the AAP Official Projects Squad, or get the original QB versions of Wetspot 1 and Wetspot 2.

## Searching For The Unknown
Trek by Brian Watson, 1998

### Written by Lachie Dazdarian

### Introduction

Welcome to the second edition of Searching For The Unknown column. I'm not featuring Star Trek: The Capture in this issue as a promised. Unfortunately, this game ended up being too untested and buggy for my taste. I just hate when a game contains bugs that seriously influence on the plot development or the gameplay. The very designer of the mentioned game admitted in the documentation that he didn't find time to completely test his game(play it through). How nice. Taking wild guesses why I can't finish some part of the game, wondering is it because of the bug or me, I find very unappealing. Star Trek: The Capture might appear in one of the next issues but I doubt.

As you see from the title, this issue is dedicated to Trek by Brian Watson and it's a complete coincidence that this game happens in the Star Trek universe too. While I was cruising through my last scoop of games downloaded from www.qb45.com I've found 3-4 very good candidates for the column. Trek was one of those games and since it appealed to me the most I've decided to feature it in this second edition of the column.

### About Trek

Trek is, as it's designer calls it, Star Trek strategy turn based simulation and that's probably the best description of the game.

It's quite obvious that Trek isn't a result of an ambitious project since it doesn't feature a lot of content. Trek also isn't a very polished game though it's bug free, well coded and features balanced gameplay. It does have that mini-game charm but you'll notice more the places where the game looks unpolished.

Trek is not your typical turn based strategy game since you only control one(1) Federation ship while other Federation ships are computer controlled same as enemy ships. The objective of this game is very simple. You must destroy all Klingon and Borg ships on the level map and when I say "you" I'm referring to the entire Federation fleet. You are just a small wheel in the whole battle machine and that's what about Trek gameplay really is. Game controls are very intuitive and are done by mouse. You move your ship with right mouse button while with left mouse button you perform a function. You have seven function at disposal: set phasers, set torpedoes, ram, dock with a base, show map, pass a turn and self destruct. By moving the mouse cursor over any ship or base in your vicinity you can check it's status.

Both sides, Federation and Klingon, have bases and by docking on your bases you can repair and rearm your ship when needed. Playing Trek is pretty much consisted of attacking enemy ships, getting back to a Federation base for a quick fix(:P) and getting back to battle again. You fight against enemy ships with phasers and torpedoes. Your ship can carry only a limited amount of torpedoes and they are, of course, more powerful than phasers. All ships are equipped with shields and armor. When your shields are down your armor will decrease with enemy hits and your ship systems will receive damage too. Your shields are restored in each turn but can't go above the armor strength. If any of your systems gets heavily damaged you won't be able to shoot torpedoes, your phasers won't be effective, your crew will start to die and similar, depending on the damaged system(s). So once your shields are down get out of the battle! All this applies to other ships as well(Federation and Klingon).

Trek's graphics are average. The game is coded in SCREEN 12 mode and the designer didn't show any interest to work with more than 16 colors. Ship sprites are ok, as much they can be in 16 colors. I mean, they function perfectly in this game but they sure won't get praised for their quality. I did disliked the look of Klingon base which in the chosen graphic style should have been done better. Also, Borg cubes simply look wrong with them purple lines and they are too small compared to Federation and Klingon ships. If the designer took some trouble to code so that a Borg cube fills 4 sectors and decided to work in 256 colors Trek would look much better. Other objects that appear in the game are only suns and they are nothing but yellow circles. I don't want you to get the impression that the game graphic is bad. I'm just saying it leaves so much space for improvement. I wouldn't like to see someone making a remake of Trek and not taking that minimum effort to advance the look of the original.

Trek features nice sound effects, mostly speech messages which seem to be made with some sort of speech synthesizer. The game really benefits from having sound effects though some silent and non-intrusive background music would be cool too.

Since I already explained how the game is played I should say something more about the very gameplay. Like I said before, in Trek you only control one ship while other 15+ Federation ships are controlled by computer which makes you feel very insignificant in the whole conflict. The game is consisted of 10 levels and each level ends when all the enemy ships(both Borg and Klingon) get destroyed. A cool thing is that Borg attacks both Federation and Klingon ships. By destroying enemy ships and bases you get better ships with better shields, higher number of torpedoes and similar. If you destroy Federation ships you will get demoted and get weaker ships. I should warn you that your torpedoes can hit friendly Federation ships even if you have aimed one toward an enemy ship. A Federation ship mustn't be in your line of fire if you are shooting torpedoes on an enemy ship. Suns can also block your line of fire(this rule only applies on torpedoes).

There is four classes of Federation ships and you start with a class 2 ship. You will be mainly worried about getting "kills" in order to be promoted and to get better a better ship. Your ship is pretty much powerless against two enemy ships unless they are class 1(or class 2 if you have a class 4 ship) so you will be mostly attacking in groups. Once the enemy ship is damaged it will try to escape the battle in order to reach his base to repair. Federation ships follow the similar if not the same tactic. You will also find yourself in situations when you are heavily damaged and are trying to escape from 2 or more enemy ships. In these situation you won't hesitate from luring enemy ships onto another Federation ship so they would leave you alone and pick on another prey. A very cowardly and low thing to do but the only way to survive in this game. Don't get me wrong, the gameplay is highly addictive and fun just the whole way of playing the game feels weird. You will very rarely feel that you have participated in the final level victory and when you reach level 10 you will so wish you could somehow control the other Federation ships. I won't reveal it more but you won't like it.

Trek is one of those games which easily could have been so much more. Brian Watson was definitely on to something with Trek gameplay since this is a very fun game to play. Too bad he was not interested to expand it on so many possible ways. Trek would really benefit from things like a save game option, highscore/kills counter or send orders/messages feature. Emergency messages when in bad situations and ability to give orders to other Federation ships once you get promoted to class 4 ship would be so cool. And finally, the ability to play the game in the classic turn based strategy mode, where you control all the Federation ships. Still, how much we miss these things while playing Trek so much these flaws leave us, game designers, space for a BETTER remake. And that's another reason why I'm featuring this game. If you are looking for an idea for a new game Trek might help you. Or not. Not important. If nothing else, this game will definitely provide you several hours of top notch fun.

> Final score
> 5/10

Download: trek.zip

Run the INSTALL batch file first(unless you unpack the game in c:\trek directory) and then run the shortcut(RunMe!.pif).

That's it for this issue. Hope you enjoyed my article and will try out Trek. For the next issue I'm preparing something special, Lunatix. I think Na_th_an will especially like this game. ;)

I hope I'll be able to submit it before my summer break. I won't be able to get online during the summer(well, it's not very convenient) so I won't be able to submit anything from around middle of the July till somewhere in early September. Cheers!

Visit Lachie's site, KENTAURI.

## The Hidden Art of Game Development

### Written by SJ Zero

OK, now forget everything.

The *hidden* art of game development.

Today I'm going to let you onto the secret of how I manage to get game engines with art popped out in 24 hours for the QBXL competitions. It's such a simple secret, that the only reason you don't know it yet is that it's too simple.

Stop creating complex worlds with super complex, interrelated, interlocking systems!!

I know what you're thinking next: "But if I don't have super-complex, interrelated, interlocking systems, I can't make a game!". You're dead wrong. In fact, I'm a little disappointed in you. You should really know better by now. How long have you been programming? How often has the most painfully complex and experimental design been the most correct one? Do you use fractal linked lists to draw a sprite? Do you have built-in software to dynamically create all your textures? If not, why would you want to write a 100% accurate physical world simulator laced with AIs and metaphase bilateral pulse regulators?

That last one was made up, by the way.

The answer has stared you in the face if you've ever played a game for more than five seconds: Cheat. Make something that acts just like you'd expect it to, and that's more than enough to fool a gamer into thinking you've got some sort of big-ass behaviour system under the hood. Not that most gamers really give a damn! These are the same people who enjoyed Pac-Man. Do you think there was a lot of high level physical world simulation in that? Maybe if you're a raver, but otherwise there isn't much simulation involved in a game of Pac-Man.

The original Grand Theft Auto would play quite happily on a 486, and if it's all you had, it would play on a 386 a little slowly. Neither of these had more than 16 megabytes of RAM. Do you think that DMA Design modelled every person in the game world realistically, choosing way points, giving these individual people hopes and dreams and ambitions?

NO!!! They didn't have to! Once they left your screen, you stopped caring about them! The only reason you would care about a pedestrian is when you decide to run them over. The same happened in The Elder Scrolls: Daggerfall. Unless you're asking for directions or killing some guy to rack up experience and slaughter guards, odds are you really don't care that Celestia Tubthumpington painstakingly walks from her home at 7.00h to her workplace, The Groggy Sportsman, where she serves an average of 14 customers (who independently arrive at her shop) before she leaves at 20.00h! These people can appear randomly, follow simple rules to appear to be living their everyday lives, and nobody needs to care. Except you, because you just stopped yourself from accidentally coding a world simulator where you could have coded a game.

The same goes for space simulations. Unless you happen to be creating the next Astro Battle, odds are you don't need to individually model each booster rocket. Complex models for rockets? Why not save that CPU time for something useful? The same goes for car games. Unless you're planning on creating Gran Tourismo, odds are you won't have to model the traction of four tires to realistically react to the conditions below it. For an overhead 2d racing game, being able to move forwards, backwards, and turn left and right is a pretty damn good start. Even if you DO decide to use a complex driving model, that doesn't automatically mean that every object in the game world has to be capable of pulling a hand break turn only to be hit in the side by the car behind it. Only your car needs to be able to do that!

Imagine an RPG with great AI, capable of defeating you quite easily given the tools to do so. Would that REALLY be so fun? Given the balancing difficulties, would it be more fun than an enemy with a few powerful attacks who chooses them randomly? Would it be more fun? Would it be so much more fun that you want to get into complex AI routines just to pull it off? The final fantasy series Final Fantasy cheats and simply has a random set of complimentary attacks which it fires off at mostly random times. Is this less acceptable than telling your enemies to make complex decisions?

In platform games, Mario's dirty little secret is that his jump doesn't correspond to the laws of physics. I know! Difficult to believe! His enemies follow pre-established patterns which are so simple a beginner could have coded them! Don't hurt me! I speak only the truth!! The important thing is, rather than being a complex system of physics around which the game play is designed, there is no physics, and it's all just game play. And you are completely oblivious. Why? Because the game works the way it's supposed to.

Next time you're reading an article about volumetric fellatio shaders with scalar Von Godric compensators, or fully fleshed out NASA level AI to tell your space invade when to shoot, just ask yourself: "Do I really need to have this to make my game convincing?"

You may find the answer a bit suprising.

Visit SJ Zero's QBXL Magazine.

## Behind the Screens: Interview with Dr.Robo

### Written by Rattrapmax6

> Here is a different type of interview, it features characters from the games itself... Maybe something more enjoyable from me for this mag. How ever far I can take this before I run out of game characters I can gather information on, I dunno. Anyway, here it is.. Enjoy.. hopefully...

> ^_^

> -Rattrapmax6

> Rattra: Today I am with Dr.Robo from the simple Robo Raider game. So, Dr., tell us about yourself..
> Dr.Robo: Well, I have four years of Robotics Engineering, and Archaeology. I been using both skills in studying old ruins, and places that are hard for the average man to go. As you know I hire people to be my Robo Raiders, just because I build robots doesn’t mean I'm too skilled at driving them.
> Rattra: Right,.. What’s the story behind the whole dislike of crashed robots?
> Dr.Robo: Well, as much as I put into them, its very heartbreaking to seem them get destroyed. And I refuse to employ anyone that crashes one of my hard works!!!
> Rattra: How much work goes into these bots?
> Dr.Robo: Allot! I have to custom machine most of the parts I use. The motor, radio equipment, tracks, and cameras I can buy. Almost a month or two designing and building these robots. And they aren’t cheap, Scorpion in the end is worth over $1000, and the Dill-Bot well over $1500.
> Rattra: So, one crash can really hurt your wallet I see,. Does a Robo Raider build any points as they go, I mean, if they go years without a scratch, you’ll just drop them over one crash?
> Dr.Robo: Normally I don't keep the same Robo Raider for that long, most are just part time help, and soon leave for greater things, or what they consider great. To each their own.
> Rattra: So, what’s your favorite Robot?
> Dr.Robo: Ah, that would be, Super Bot, Scorpion’s big brother so to speak, but over all in use, Scorpion.
> Rattra: What happen to Super Bot?
> Dr.Robo: It lays deep below the earth in hundreds of pieces *cries*, It was the first case of faulty piloting in which I fired.
> Rattra: What made Super Bot so special?
> Dr.Robo: It had the functions I now have in two different bots.. An over head crane (Scorpion) and a grapple (Drop-Bot).. This made it more versatile.
> Rattra: What Robot was the hardest to fabricate?
> Dr.Robo: Drill-Bot, getting the drill to work, the camera to see, and the claws to work right was a great challenge. I think I might sew if someone crashed that machine.
> Rattra: Yeah, I remember that one, looks like a concrete drill bit with tracks... Do you plan to make another bot soon?
> Dr.Robo: Yes, a two piece bot. A track bot that carries a submarine bot. This will expand my exploring range past land and into wells and rivers in underground caves.
> Rattra: What will you name that one?
> Dr.Robo: Sub-Tracker maybe,. but I haven’t made any solid thoughts on it.
> Rattra: Oh well, I’ve probably taken too much of your time by now, and I’m out of things to ask, so I’ll wrap this up.
> Dr.Robo: Yes you have, but no, I enjoyed the talk.
> Rattra: Right..
> Dr.Robo: Thanks..
> Rattra: For finally leaving you alone, or for the interview?
> Dr.Robo: Both..
> Rattra: Heh

Visit the x.t.r.GRAPHICS FreeBasic Site or get Robo Raider.

## Review of The Griffon Legend by Syn9

### Written by Josiah Tobin

Well, where to start...

I suppose this is a somewhat anticipated title, even more so as it is developed almost entirely by Syn9, known most for his extremely impressive 3d demos. While this particular game is indeed 2d, Syn9 certainly doesn't let that stop him. The moment you encounter the first boss, a strange nearly cactus-like dragon-- bringing back memories of Zelda 3's Moldorm yet somehow being completely different as it bobbles and sways dangerously to and fro-- you catch a glimpse of just what the game is capable of.

The Griffon Legend makes extensive use of a chain-like style of animating large monsters (the 'proper' title I'm not sure of, though I've come to know it as bio-animation), linking many smaller sprites together to form massive, rather fearsome bosses and mini-bosses. Without revealing too much, I will say that if you think you've seen it all after the first boss, you are most definately quite wrong.

However, despite such impressive techniques, the rest of the game's graphics are at times somewhat... confusing. While some of the tilework certainly shows the skill of Syn9's capable hands (though there are some that seem a bit thrown together), it often becomes far too busy-- more than once I found myself wondering just why I couldn't leave the screen when it looked very much like I should be able to, or pausing for a moment to 'decipher' a room. Sometimes there is almost no difference in appearance between a 'high' floor and a 'low' floor, making it seem like there is simply an invisible barrier between the two.

The game's sprites do the job fairly well; while being nothing too flashy they certainly aren't dull either. Everything that isn't done through the chain-style of animating mentioned earlier is well enough animated; standard four-frame walk cycles and usually as many attack frames. Your character attacks by leaping forward and doing a mid-air flip with his blade out, effectively lunging at the enemy in a whirling ball of feathers and steel.

While I'm on the topic of characters, I might as well elaborate. There really isn't that much character development or even any other griffons or friendly characters in the game apart from the one you play, but to be honest that's really not a problem. I have a feeling the focus of the game is to be a fun experience, not to have an overly deep or compelling plot and characters. The only hints of a story you receive are in the intro and outro of the game, but they are sufficient to let you know what's going on. Both are fairly well-written, and while I did spot an error or two, they get their point across quite well, especially the ending.

There's nothing bland or drawn-out, really-- the moment you start a new game you are presented with the short intro text and are then immediately plunged into the game without further dialogue or hinderances, and left alone to battle your way past your foes, the Dragons. While some spots may seem a bit difficult, I never had too much of a problem after a few tries. Apart from a couple screens that are devoid of opposition, the action never really stops, so you can be assured it's far from a boring experience. However, such an approach does have its flaws. There were a couple rooms that seemed a bit crowded, reminding me slightly of some of the more... chaotic rooms of the later dungeons in the original Zelda for the NES. Of course, it's a small complaint really, hindering the game only slightly and occasionally.

I cannot comment on the music, as my computer's sound is currently not working all too well, so I can't say much about that aspect. However, I quite enjoyed the game without it, and if it's at least half-decent then I'm sure it will only enhance the experience.

Now, moving back to the more technical aspecs-- the actual mechanics of the game: For the most part it's simple. Below your character is a set of three (two at first, actually) bars: Health, Attack, and Magic. The 'attack' meter fully depletes itself each time you attack, and slowly charges back up again immediately afterwards. (it recharges faster as you gain levels) The higher it is, the more powerful the attack. The same applies to the magic meter, except for spells. The spells themselves are executed flawlessly; after beating the first boss you receive a crystal-- now, I'm not exactly sure of the usage, but 'using' this crystal (used just like a spell, which I'll get to in a moment) in either different areas or around different enemies (as I said, not sure exactly) causes you to 'find' spells. There are four spells in total, each of them quite useful. Be sure to discover them all! To cast a spell, you simply access the submenu (pausing the game) and choose your spell. You then choose your target (play is still frozen at this point, likely so the action doesn't get too chaotic) and select it to cast the spell, at which point the game resumes. Each spell has a meter that charges up after each use; you may only use the spell when this meter is full. This, coupled with the more general magic/attack meters, adds a good dose of strategy.

The game has its more subtle touches are well: when all its fellows are killed off, a single enemy can and will attempt to run from you and hide feebly in some protected corner of the map, only resorting to a futile final brawl when you approach to finish it off. Indeed, for the most part the enemy AI is quite well done, with the exception of some bosses-- as long as they do not posess ranged attacks you can usually 'trap' them by getting them up against an obstacle and hiding on the other side, repeatedly pummelling them with spells until they succumb. However, given the difficulty of the later bosses and mini-bosses, this often seems to be more of a blessing than anything.

As one final gripe before I conclude this review, I'd like to address the load time at the start of the game. The moment you open the .exe, you are presented with a small dialogue box in the center of the screen with a green bar inching its way across; I say 'inching' because it truly does seem to take an overly long time for such a game. Perhaps it's the .OGG soundtrack I never got to hear, or the sound effects, or even perhaps the initialization of the subtle graphical effects like the ambient fog or transparent flame that some of the stronger foes occasionally belch. Regardless, it is a bit of an annoyance, though thankfully it is the only load time in the entire game, and the rest of the experience is seamless.

While not being the longest game around (somewhat of a mini-rpg really, I beat it in roughly a couple hours), it offers a good chunk of some classic gameplay without any needless droning cutscenes or overly flashy bits. Of course, it's not the most polished game, lacking enemy death animations even for the larger baddies and bosses (which can look a bit odd at times, suddenly seeing them wink out of existence without any transition whatsoever) and posessing a fair share of bugs-- nothing too serious, though-- but it all has some sort of charming appeal. Maybe it's just me: perhaps it's the use of the wonderful chain-like animation, or the fact that the main character is a sword-wielding, tail-bearing griffon knight, or the direct and to-the-point gameplay... But regardless of personal opinions and preferences, I can see this becoming a fairly popular little game among the community. Despite its flaws, Syn9 has created quite a fun and entertaining experience.

> Graphics: | Sound / Music: | Gameplay / Fun Factor:
> | 6/10 | (didn't get a chance to hear either) | 8/10

> Overall rating:
> 7/10

> You can download The Griffon Legend at syn9.thingie.net.

## Why Doesn't The QBasic Forum Ever Make The QBasic News?

### Written by mennonite (and others)

> Despite six years of inactivity, QBasic.com still has an extremely active forum community, one of the most active in the QB scene. Its popularity can be attributed partially to the constant stream of visitors filtered to the forum from QBasic.com (still one of the most visited QB sites -- and number one on all the search engines), or its high search engine ranking in its own right (#6 on Google for a search of "QBasic"). But high search engine ranking is just a part of its popularity. The unique culture and QBasic programming-centered discussion keep people coming back to The QBasic Forum.

> And yet, despite the constant posts and huge number of visitors, The QBasic Forum barely ever makes it into the QB Express news briefs ... there's simply not much newsworthy going on at the site. I wondered why this was. How could such an active, programming-centric community produce so little? This month, mennonite, Mac (the forum administrator) and the rest of the forum commmunity answer this question.

> -Pete

i was talking with someone about the qbasic forum, and they were actually curious why there wasn't news from there, so as usual i wrote an entire article about it. for those who are curious, here is an article describing the forum...

and it's possible the purpose of the qbasic forum isn't really understood... that is, we aren't developing any big games or anything. for one, we aren't there to be developers, which isn't to say we don't have them. we get posts from relsoft, shadowwolf, z!re, and drv. jacob palm posts regularly unless i'm mistaken. (there are two "walrus"'s that post on the forum. goo goo ga joob.)

so what's it like in there?

well, ildûrest says there are 100 kinds of people there... "those who know binary, ... those who love programming but don't know binary quite yet, those who are willing to give it a go but probably won't get far enough to learn binary, and those who aren't going to learn anything because we do their homework for them. We like the first 3."

of course, it's where all the newbies come to, because if you type in "qbasic.com" you get the ancient site that we can't update (which i think is just as well, since it works on every browser on the planet) that leads you to us. this has a huge impact on the content and theme of the forum.

if you're looking for game-dev stuff, we mostly have newbies making their first rpg - which i think is cooler than cool... but it's possible i'm in the minority. i love helping newbies... i mean, newbies are the only people that eventually become programmers, get it?

whether any of this is "news" per se is really a matter of opinion, but we do have posts about everything. mac knows archaic system stuff even i don't know, i know a fair bit about dos, sometimes i'm amazed what i know about dos that they didn't know (i take it for granted that some of them really know everything.) and michael calkins knows asm, but yeah, it's a more humble site, that's what i like about it.

michael originally came in (i'd say more as a novice than a newbie) for help with a few things and stuck around for the community and amusement. (he's probably one of the most patient people on the forum too, he's a fantastic guy.) as he's mentioned, our love of qbasic is something that brings us together.

as far as the atmosphere, we've got no shortage... some of us even get an image in our minds of a clubhouse, coffee shop, or (personally,) a giant living room: it's got crappy old carpet, as opposed to new carpet that you can't get comfortable on anyway, where a bunch of people are hanging out and eating pizza and playing video games... and some of the geeks in the corner are working on some project. (damnit, i wish i had a pizza.) actually this sort of echoes computerghost's description of a walk-in tech support office: "Newbies walk in and get information then leave and come back next time they have a problem. When there are no people to help, [we] chat around snacking on junk food around the lounge."

we talk a fair bit about small fun projects, (which are usually smaller than the regulars are capable of, but we aren't really pushing for anything.) we get posts about errors and guis and games, and we have a sub forum for magazine info and other forums that pete posts to whenever the new qb express comes out.

but what we've always focused on is "how to write QBasic programs", not the programs themselves, but the techniques etc. that are appropriate to QBasic.

not too long ago, someone came in with a homework question, which we have a policy against unless the person has already shown an attempt. mac, our moderator, explained this policy. in one of the greatest qb quotes of all time, the poster replied something like "okay, i've got CLS. now what the fuck do i do?"

mac deleted it of course. i'd rather be able to use language like that in our forum, but i understand. lots of kids come in, too.

actually mac helps the forum the most by doing two important things: one is that he helps keep the forum uncluttered by occasionally nudging us towards the appropriate sub forum when we get way, way off topic. (he thinks i don't appreciate this, but it makes it easier to follow the threads, and it keeps the place looking nice and more like home.)

the other thing he does that's really important is he basically stays out of the way. he posts challenges and participates in some of our discussions, which is great, but it would take you a while to even guess he's the moderator. it probably takes a fair bit of restraint (more than i have) to not put your own two cents in on every post you agree or disagree with, but he's got it. the upshot of this is the forum feels like it's unmoderated, which is nice. but it isn't unmoderated, which is nice too.

so this is probably a lot more than you expected to hear anyone say about the forum: our big tech support office, as it were...

except for the difference, computerghost points out: "Instead of being paid, we have to pay rent for the office building. But that's okay. We enjoy doing it."

* Thanks to everyone from the forum who helped with this article. *

Visit The QBasic Forum or mennonite's site.

## Reflections on QBasic.com

### Written by NEWKid

Hi. I’m known as NEWKid on the Qbasic forum. I was the one who originally discovered that Qbasic.com was down and then when it went back up, I discovered it again. I guess I’m among the last people to actually use Qbasic.com frequently, so that’s why I am always the first to notice things about it. I don’t really like it when people talk about how much they hate qbasic.com. Even though it hasn’t been updated since the late 90’s, it still has some nice information and loads of downloads (no pun intended). And besides that, without Qbasic.com, how would new people (like me. I’m still quite a newbie.) find the Qbasic forum, which is still active. That’s how I found the Qbasic forum. So, I guess it still serves a purpose. And now, with out further ado, (its “ado”, right?) here’s the story of all my experiences with Qbasic.com!

### Discovering Qbasic.com

Before I had the internet, I had to go to my brother’s house and get on his computer to access the internet. Then this March, I had been programming in QB for almost a year when I came across Qbasic.com. It didn’t take me too long to realize that it hadn’t been updated for ages but I notice that the forum was alive and well, so I posted on it. Basically, my post said that I loved QB and that I didn’t have internet access so I wouldn’t be back for a while (You can go and see that original post.) So, around two months later, we finally got internet access and the very first site I visited was Qbasic.com. I downloaded all sorts of programs from the files archive on QBasic.com and ran them on my old DOS computer. (which I soon wouldn’t need because a few days later, I downloaded Qbasic 4.5 from a site somewhere.) I eventually killed that computer because I put a bad program on it. The people on the forum never really went to Qbasic.com , but nevertheless, I went there daily. After a bit, I even made it my homepage!

### The day that was lived in infamy.

And that is the reason that I noticed that it shut down first. I tried to get on the internet, but when Internet Explorer opened up, the first thing I saw was the “could not find server” message. So naturally, I assumed there was something wrong with my computer. But I connected and disconnected and did it again and again in fact, I even restarted my computer several times. But it was to no avail. At some point, I decided to go to another website and it worked that time. So I surfed the internet for a while before I decided to go to Qbasic.com and it still didn’t work! Then instead of typing the URL in, I tried Googleing “Qbasic” and clicking on the link to Qbasic.com that it inevitably provided. It still didn’t work! I tried accessing it several different ways, but I soon realized an awful truth, a truth that I thought for sure I would never have to face, a truth that was simply to horrible to even think about: Qbasic.com was shut down! I immediately put a post of the Qbasic forum. Here’s how it goes:

> “I just tries to get on to Qbasic.com and no matter how I try it, It still doesn't work! I wonder if it got shut down! Qbasic.com is actually my homepage so whenever I turned on my internet browser, the message saying that it couldn't get to the site came up, so I just assumed that my computer was broken, but I eventually discovered that it wasn't. Maybe its just my computer. I would like other people to check on it as well to determine if it is just my computer or not. Tell me if you can get on it because I honestly can't!
> May the Force be with you!
> -NEWKid”

So bp posted back saying:

> “its definitely down”

Then I posted once again:

> “I know it hasn't been updated for a while, but I still LOVED that site! All of the downloads! I never downloaded everything like I wanted to! Those were good tutorials too! Fortunately, I got all of them already. It was the original Qbasic site! How could this be! This is a sad day for all QB programmers.
> -NEWKid (In mourning)”

Then after that there was a flurry of posts that I couldn’t keep track of. Many thought that it would just come back online in a few days or weeks and would be upgraded! And even after the original thread was over, the subject kept popping up again and again in later threads. After several days, the subject interested less and less people. I don’t think a lot of them really cared about it anyway. Honestly, I wasn’t nearly as upset as I let you believe in those posts. It wasn’t like Qbasic in its entirety just decided to cease its existence right there! We still had the Forum, we still had Pete’s Qbasic Site, we didn’t lose anything that important. But I wasn’t kidding, I really wanted to get all of those downloads! Qbasic.com did have its upsides: without it, how would new people find the Forum? That’s how I found it, remember? And it still had some really nice tutorials! That Mallard guy must have worked his rear off for those Tutorials (although, I have seen much nicer Qbasic tutorials)! But for the most part, nobody gave a horses rear-end. Including me.

And that’s the way it was for several days. Discussion of the subject had totally ceased. We thought we were finally rid of Qbasic.com. We were wrong. Once again, it was me who made the next significant discovery about Qbasic. I accidentally clicked on it in my favorites list and before stopping I thought, “What the heck! Why not!?” so I continued, and lo and behold! Qbasic.com was back! So much for the “upgrade”! It was the some old Qbasic.com that we all grew to love (when we were new) and then eventually grew to hate. As for me, I don’t really know what to say about Qbasic.com. On one hand, it has lots of nice downloads, good resources, and it brings people to the Forum which hardly anybody would go to since it comes up either ninth or sometimes even tenth when you Google “Qbasic”, but on the other hand, I hasn’t been updated since the late 90’s, most (all?) of its links are dead, and no one has any idea what happened to Mallard, so when you email him an important question, it never gets to him. Whether I like it or not, I will continue using. Kind of like how a lot of people hate Windows XP, but they still use it.

Hopefully, someday Qbasic.com will be updated and made better. Or maybe, it will be shut down for god, and someone else can take that domain name. It is quite a shame that a domain name like that is wasted on an old dilapidated site. You don’t even have to Google “Qbasic”! A lot of people will just assume that there has to be a www.qbasic.com some where! So whatever happens. It appears that Qbasic.com is here to stay for a while. So we’ll just have to live with it! Don’t like it? Deal with it!

Happy coding, y’all!

-NEWKid, aka Nick Warren

Visit NEWKid's Website or The QBasic Forum.

## Review of Pixel Snake Gem Hunt! by Steven Danglis/My Pet Robot

### Written by Adigun Azikiwe Polack

Ever since FreeBASIC first came out late last year (2004), there have sadly not been very many new games released through QuickBASIC itself. But thankfully, few and far between are some really good new games in QB that are suddenly thrown into the spotlight and show their *truly* amazing colors to make players wanna come back to them over and over and over again! And Pixel Snake Gem Hunt! by Steven Danglis/My Pet Robot is one of the highly-promising ones right here, BUT, is it really as good as it looks? Keep reading now and find out!

### G A M E • S Y N O P S I S :

When this game is first running, you are instantly taken to a pretty cool-looking title screen and (if you run the game with sound!) are greeted with a some notes of simple chiptune-like music along with a robotic-like voice telling you what the name of this game is called. Press a key then, and you got five options to choose from, including a two-player “Versus” mode, a single-player “Practice” mode, and an opportunity to configure your keyboard controls for both players.

Now, once you have selected your game mode, you then have a choice of five (5) stages to select from, including Mud Flats, Grasslands, and the “experts-only” Ancient Ruins stage, to name just three. Once you decide here, the gem-hunting season is on!!

If you can remember the classic 1990 QB game called Nibbles by Microsoft (and I’m sure a *whole lot* of you do!! ! ), then you should know what you are in for right here. But this time, you are met with monstrously giant-sized playfields in which your snake(s) initially have plenty of breathing space. Also, instead of numbers, you have four different colored types of gems, which are these:

- Yellow Gem ::: Nets you 500 points a pop.
- Blue Gem ::: Gives you an extra five (5) seconds on the clock and 1,000 points.
- Purple Gem ::: Clears all of the paths that your snake has made, and yields you 2,000 points!
- Orange Gem ::: Awards you a *big* 5,000 point bonus instantly!!

In the “Versus” mode, the object here is to win all six (6) games against your opponent in order to become the top snake of them all!! To accomplish a game successfully, you must make deviously blocking paths for the opposing snake to collide on (just think of that famous lightcycle scene from the movie Tron, and you know *exactly* what I am talking about! =b ). The only way you can get a “draw” game, however, is if both snakes collide head-on with each other, so please be very careful about that! ! Also, do keep in mind also that some of the gems themselves — especially the purple ones — can even alter the whole outcome of the game itself, with some shocking results ( )!!

For solo players, it is recommendedly a good idea to try out the “Practice” mode first to get you into the taste for the real thing! You have unlimited lives in this mode, which is necessarily a good thing in itself for what this mode is designed for, really!

In both modes, the added challenge (and even a major obstacle as well!) is that the playfield slowly gets shorter and shorter as time elapses more and more, so be wary of that also!

### T H E • B R E A K D O W N :

First and foremost of all here, the idea and concept of Pixel Snake Gem Hunt! is *really awesome* stuff up front. But as you are playing the game though, picking up the the pixel-sized gems can sometimes be a hit-or-miss affair, making play a little frustrating at times. BUT, if you got a really sharp eye and careful keen instincts, you can gather them up more easily. It will take you some number of play-throughs to get used to it, believe me.

About the graphics, the problem I had with them is that they have an awful lot of dithering in them, especially in some of the digitized pictures, making them look pretty drab and boring at times. They could have truly been a lot better, with a lot less dithering and a few more amounts of custom colors to make the graphic details more and more realistic. On the plus side though, some of the graphics do look good, like the Mud Flats and Dungeon stages, for example.

The keyboard-based play control in this game is pretty good, but not great. It will take some time at first to get you used to the controls, but hey, once you got it all nailed down pat, then there is plenty of fun in store for you right here!

As for the huge playfields in this game, it can be both good and bad in a way, and here is why. While they themselves can present much advantage for the snakes to slither on, it can also make for quite a few bouts of frustration in the later stages if you are not even prepared for them. For example, when first starting the Ancient Ruins stage, this puts you in a sort of a *rather* small maze at first, just itching to get out and into tons of open space! ! Strong chances are that you will likely end up crashing and crashing into walls A LOT before you get out of that maze into the large space indeed where big points and other bonuses await you in the clear (warning: plenty of skill and extra-long patience is desperately required for this very task!). Fortunately though, from the earlier to later stages, I think they are balanced in a way in terms of the design of them, and they are pretty interesting in a way, too! I even liked the Grasslands stage where you have to avoid the three people in order to make your way through. Very nice!

If there is one MAJOR plus in this game I can think of, it is the player’s location marker, something that apparently *no* Nibbles-based clone in QB or FB has ever done before, and it is so masterfully used to great extent. What this does now is that it keeps close and accurate track of where you are so that you will never end up lost in your own trail at all, even if the game is paused by pressing the “ESC” key during play, too! I absolutely love it, and I personally think it should be implemented in all games of this kind in both FB and QB, I most strongly believe!!! d==b !

As for the sound effects, they are so *amazingly* good for a snake game fresh from good ‘ol QB! ! It puts you right in the thick of things here, and sets the mood well! The robotic-like voice even lets you know how much time is left, too. I think all of this is a VERY effective use of QB’s limited .wav capabilities, in my humble opinion.

Despite some misses here and there, I believe that Steven Danglis/My Pet Robot has done a very good job on this game. He stated in the game’s documentation that he has only tested the game on Windows XP Professional, but I have tested the game on Windows ME, and yet the game worked so marvelously well there as well!! =b So apparently, it should work on any operating system, even pure MS-DOS, too! Also, you can choose to play the game without sound as well, which is another plus even for people trying to get the game to work properly. Still, a pretty fun game overall! !

### T H E • F I N A L • V E R D I C T :

> 7.2/10

This game may not be the best Nibbles clone around, but it sure has some truly interesting concepts, inventively challenging stages, very large playfields, really fun sound effects, good control, and well-thought-out play modes to boost this game really much above average! Nicely done on this one, Steven! =b !

Download Pixel Snake Gem Hunt, or visit the AAP Official Projects Squad!

## The Evolution of Graphical User Interfaces

### Written by Stéphane Richard (Mystikshadows)

### INTRODUCTION:

Graphical User Interfaces (GUIs for short). One of the hottest topics today in the Qmunity. In my letter to the editor in this issue, I gave my vision as to why I believed GUI development was so popular and those reasons even goes beyond the Qmunity itself. The first official GUI was released back in 1973 by Xerox and since then, the competition has been on to bring forth the best Graphical User Interface to the users. GUI development is far from a new idea and still today GUI development is still a popular topic in the community and beyond.
In this article I'll review the GUIs that really made their marks in the GUI timeline. as well, will talk about their strong points to give you an idea of what made these GUIs as successful as they were when they came out. For all of you wanting or thinking about creating a GUI this should prove very informative. Note that I'll only be convering the commercially available GUIs of the time periods or this article would turn into a whole book.

### The Xerox Alto - 1973

The Xerox Alto was the first system to hold everything typical of a modern Graphical User Interface. At the time it was more of a collection of Graphical DOS programs that worked with a mouse. But it did however bring out the main characteristics that are still in use in today's Graphical User Interfaces. When you booted the Alto you ended up at a command prompt, not an interface however any programs available were mouse driven and featured lists, buttons and other GUI elements we all know and love today. When you think of the year it came out (1973) these applications were well ahead of their times. The link shows screenshots of the Xerox Alto and it's operating environment in detail.
This system wasn't available to just everyone, it's niche market was the big corporate world but it was a breakthrough in the way software would be created and used in the future. It's main strong point was ease of use and back then, since there was no standard by which to measure ease of use, it was a valiant attempt at giving something users could use in everyday work operations.

### The Xerox Star - 1977

The Xerox Star was the next version of GUI available from Xerox. If you click on the link provided and take a look at the screen shots, you can see a definate evolution from the Xerox Alto. For one thing, you didn't boot up in a command prompt anymore, hence the Xerox Star was the first official GUI based system and as such featured a very elegant interface to use. As quoted from the link: "It was based on 4 principles. Seeing and pointing, Progressive disclosure, uniformity in all applications and "what you see is what you get"." Now, which of these 4 principles is not in use in today's GUI? None of them.
They applied the 4 principles quite well in all the applications available. This sence of consistency really helped the users in learning to use all the applications and adapting to the new version of the Graphical User Interface it provided. That too was a very strong point. It marked an important point in time where ease of use also had to mean ease of learning.

### Apple Lisa - January 1983

The Apple Lisa today, needs absolutely no introductions. It's the pioneer of GUI environment for Apple Corporation, came out at the beginning of 1983 and has since remained the standard and el facto of GUIs on Apple Computers. Most of it's features are still in use in today's newer versions of Mac OS. One thing that was always a strong point to me was that Mac versions of PC applications always seemed to run faster and better on a Mac. Faster, less resource hungry and the likes.
All in all one of the things that made the Apple Lisa as good as it was was not only the GUI, but the available applications that ran in the Lisa's GUI. I think this is a key factor to any GUI projects even today.

### Visi On - 1983

Visi On was created by VisiCorp The main feature of Visi On was that it was the first, full featured GUi available for the IBM PC. Another great feature was in it's design. It was indeed designed to be poratable to other OSes. It used the principle they called the Visi Machine (Hmmm Java Ancestors perhaps?). Visi On definitaly got Microsoft quite nervous when they saw it as a demo in 1982 and realized that they had nothing close to that even in the project bench. So Bill Gates went back to Microsoft, after seeing this demo, and got a team on started on what we would come to know as Windows.
Assuming it was borrowed from the Xerox Star, the key strength was the consistent user interface it presented the user throught the many applications that were built for it (I see a pattern emmerging here). As you can see from the screenshots in the link, it was a very tightly integrated environment and offered many advantages by design.

### Apple Macintosh - 1984

the Apple Macintosh Was the next evolutionary step in Apple's effort to bring the microcomputer to the general public. The computer itself had a mouse like the Lisa, it had the monitor integrated into the main casing however, it was about 1/2 the size of the Apple Lisa. One of the goals was to make the computer more affordable while keeping the materials used of equal quality. The Monitor on the Macintosh was small however it offered the clearest and crispiest display of the time and that helped alot in it's success.
Like the Lisa, the GUI on the Macintosh offered some very advanced GUI functionality that really contributed to setting the macintosh in it's own category of a "graphically oriented" computer. as such, it quickly made it's mark in such places as newspaper editing companies, magazine publishers and the likes just because of it's Document oriented user interface it presented the user with. Likewise, it's ease of learning (hence ease of use) was unmatched at the time which also made the macintosh a very good computer to use business wise and for the common individual.

### GEM - 1985

GEM (Graphical Environment Manager), which is known today as the GUI for 16/32 bit series of Atari home computers (atari 520ST and above) actually had it's debut in the PC market. GEM and Windows 1.0 came out in the same year and indeed they both offered their own set of distinctive features that set them apart from each other while bringing them both in the GUI scene. Most of you will notice many similarities between GEM and the Apple GUI. Apple brought them to court because of this and if you look at gem 2.0 and up screenshots you'll see they had to change alot of things that made up their original GUI features.
GEM was one of the best GUIs to be created, it was very efficient even on the machines of it's time, it featured mouse and keyboard support, it had the ability to run GEM and DOS applications and it's interface was so lightweight compared to Windows which also came out that year it would basically run circles around it. Shortly after its release programs were made available to GEM fthat made it a very usable GUI alternative to Windows.

### Amiga WorkBench - 1985

The Amiga Workbench GUI had alot to brag about at the time. it was the first truely multitasking GUI avaiable to home computers. Of course the Amiga series of computers, with their very rich list of features helped in making the Workbench a popular GUI. It cale with ABasic originally (AmigaBasic shortly after) and those BASIC languages could multi task as well. Everything on the amiga workbench, including the applications developped for it were remarkably fast for 8 mHz motorolla 68000 CPU.
Today, the Amiga OS is still being developed (Version 4.0 just recently came out) and it looks like This but you can still see that the essence of the amiga workbench hasn't really changed. Looking at these two links you can see that the Workbench had many GUI features that are still not found in today's popular GUIs. The Workbench set a new set of standards by which other GUIs would be measured against and compared.

### DESQview/X - 1985

DESQview/X originally came out in 1985 but it wasn't really before 1994, when it's version 2 came out, that it was truely recognized as a popular GUI. DESQview/X is a multitasking GUI for DOS, yes, essentially it served to multitask DOS and DOS applications which it did quite effectively. With it's second version on the shelfs DESQview/X now had it's GUI and when you look at the screenshots on the link it's easy to see why it became so popular, so quickly. It's main feature was it's ability to start applications remotely on other computers on a network. That was, in itself, a remarkable feat of strength considering the technology of the era.
Some linux or Solaris users might recognize it's similarities with the Motif GUI. That also played a very big role since now Motif users would start looking at DESQview/X and start thinking maybe there's something there we didn't know about. It got many computer users, PC and Mac alike, curious about what it could do and that was how you could hope to gain success back then, to get people curious about what you had to offer. That and of course efficiency and stability both of which DESQview offered.

### GEOS - 1986

GEOS (Graphical Environment Operating System) although the link doesn't provide this information, from what I see in the copyright notices, made it's debut on the commodore 64 back in 1986 (See the Apple GEOS to see how it looked liked on the commodore 64. GEOS was one of the first PC GUIs to come bundled with actual useful software like GeoWrite. it had scalable vector fonts (the first to offer this font technology) and was, at the time, one of the cleanest user interfaces available. everything was based on pages, not scollbars (except in software that needed more screen resolution and was very easy to use and understand.
Althought the Commodore 64 was more known for it's gaming feats, GEOS was able to turn this computer into a plausible office alternative for small businesses, which was, back 1988, quite a feat. not too long after it's release, many applications were created for GEOS and the more popular programming languages were ported to it in a record time. if you look at the screenshots you can see how clean that user interface was and how easy it was to locate where things were. It was floppy based and still managed to run pretty smoothly compared to other GUIs of the time.

### OS/2 - 1987

OS/2 version 1.X was a came out in 1987 and was a 16 bit Operating System. It began as a joint effort between IBM and Microsoft both of which released their own version of the operating system. Indeed, you could find Microsoft OS/2 and IBM OS/2 at the time and with version 1.3 was the point in time where microsoft and IBM went their seperate ways. IBM had OS/2 version 1.3 and Microsoft took parts of OS/2 and created Windows NT. This initial joint effort between the two companies explain why OS/2 could deal with DLLs so well.
In 1992, OS/2 Version 2.0 came out and was the first Desktop OS to be truely 32 bits. It featured the Workplace Shell (the icon driver user interface built in compliance with their established CUA '91 revision standard and that standard proved to be a very workable environment. For a good while OS/2 had alot to offer compared to windows and was becoming the el facto of operating systems on the PC, but Micrsoft had much better marketing and that's all it took back then to make or break a product. In 1996 the more known OS/2 Warp 4 came out and although OS/2 isn't sold on regular PCs anymore, still today IBM and others send patches and updates to bring OS/2 Warp up to date. Today IBM has OS/2 Warp Server for E-Business a newer OS/2 Warp but intended for servers, not clients.

### Windows 3.0 - 1990

Windows 3.0 Was the first version of Windows to really break the market. Windows 1.X (1985) and Windows 2.0 (1987) did exist but they never really made their marks on the market as a usable GUI in the workforce. Windows 3.0 did however and when Windows 3.1 came out in 1992 Windows then became the GUI standard. With every new release came a rich set of new features (and new problems for the most part) and that's what got Microsoft it's leading position today. Everyone was always curious to see what the next version of Windows would have to offer. And Microsoft made sure that it had so many new features to offer that people would essentially deal with the problems because there was so many features.
I think we all pretty much know what windows came out (see the link about for the full list of versions) and their features but the big mile stones after Windows 3.1 was Windows 95 (the first almos 32 bit OS) Windows 98, Windows NT 4.0 Windows 2000, Windows XP and still to come, Windows Longhorn. We're all curious to see what Longhorn will have in its guts Although you can read about it on the web we'll never know for sure until it's released and used. But this habit of releasing so many features to try to hide the problems promises that there will be alot of new features in Longhorn.

### QNX Photon MicroGUI - 1994

QNX's Photon MicroGUI isn't a name many of you have heard of, mainly because it didn't start off as a commonly available GUI. Many of us probably used it without knowing it. But it came out in 1994 and still available and in operation today. It is used in ndustrial, network, telecommunications, medical, and automotive devices. The OS itselt is a realtime OS and offers all the features you would expect from a truely realtime operating system. It is a very efficient Operating System and GUI even when compared to today's more popular GUIs.
The GUI could boot from a single floppy which also included web browsing, tools all in a single floppy drive. Pretty impressive no? Today it's available as an ISO image and can be either installed to hard drive or bootable right off the CD. No matter which way you look it at, Photon MicroGUI had/has features that still today sets it apart of other OSes in terms of resource efficiency, performance, and GUI functionality.

### BeOS - 1996

Back in the mid 90s, BeOS came out from a very important need. Multimedia was fast becoming the hotest subject on the computer industry. The ability to work with video productions, music, 3D and mix them all together in a finished product was becoming a necessity and BeOS was created to answer that call. It was designed from the grounds up to be a multimedia operating system, the first of it's kind. It was orginally created for a custom computer called the BeBox and was later ported to the macintosh and then the PC.
BeOS is not in production anymore however a team of programmers have started the OpenBEOS project in an attempt to recreate BeOS from the grounds up to offer a free BeOS alternative. In my belief, any Operating System that warrants itself an OpenSource version made by BeOS users that believed in them is definitaly a success story in itself. When you look at all the features that BeOS had as far as it's promise to the multimedia world was concerned, BeOS delivered like no other Operating System delivered on it's promises.

### AND NOW FOR THE FINAL WORD:

And there you have it. In essence these GUis are the ones that really left their mark in history on way or another. Some set new standards, some set new technological breakthroughs, but they all somehow helped defined what a GUI should have, how it should operate, and so on and so forth. The main reason why I created this article is simple. GUIs, still today are being developped by all kinds of different programmers with their own special list of features they want to see in their GUI projects. Take a look at Jacob Palm's GUI website and Todd's GUI website to get a glimpse of what personal GUIs were built and what they offered. I find it funny to say that there has been no new commercial GUIs since 1996
If you have your own GUI project or are planning to create one, I believe this article will help give you a good grasp of what makes a GUI successful wether it's inner workings or outside look and feel, each of the GUIs I described here all had something unique to offer. Of course there are/were other GUIs that might have made their marks but I believe this list feature the GUIs that were really successful for different periods of time. If you feel a GUI should be mentionned here that I haven't included, just let me know.

> MystikShadows
> Stéphane Richard
> srichard@adaworld.com

Download a copy of this article.

## Monthly Awards

### Written by Pete

Every month, QB Express hands out two awards to recognize QB or FB coders and websites that have done exceptional work in the last month. They are not awarded for work done in the past, only for work that has been released since the last issue of the magazine. We will bring you these awards on a monthly basis to help give credit where credit is due.

### Site of the Month

> Data Components GUI Reviews
> http://qbasicgui.us.tt/
> Webmaster: Todd Seuss

> Until you visit Todd Seuss's Data Components GUI Reviews site, you'll never realize just how many QB GUI programs have been made. Data Components has 162 reviewed GUIs and counting -- and all of them were written in either QB or VBDOS. It just boggles my mind that there are that many QB GUI programs, let alone the fact that Todd Seuss has managed to collect them all.

> On the Data Components site, each GUI is accompanied by a short review, a screenshot and information about the author, the date of its release, and its status. You can access all 162 reviews from a single navigation bar on the main page of the site.

> Launched on March 27, this site has grown at an astounding rate since it began. Data Components receives frequent updates, and has had several reviews added every week. In the past month, over a dozen new reviews have been added, and even more are on the way. I applaud Todd's dedication, and the quality of his work for the past four months. He's created the largest and most thorough QB GUI resource on the Internet, and for that, Data Components GUI Reviews is the QB Express site of the month!

### Programmer of the Month

> Syn9
> http://syn9.thingie.net/

> Last month when I previewed The Griffon Legend, it quickly became pretty apparent to me who would be programmer of the month for July. TGL is without a doubt the best FreeBasic game I've ever played. The sheer quality and polish of this action RPG is amazing, for a hobbyist game. And to top it all off -- it's fun!

> Over the years, Syn9 has proven himself to be a spectacular coder. He's best known for his stylish 3D QB racer, ZeroG, which I consider one of the best QB games ever released. Aside from that, Syn9's also made scores of 3D demos that have wowed the Qmunity for years. Just check through earlier issues of QB Express, and you'll invariably see a screenshot from one of Syn9's demos. I can't wait to see what he's going to come out with next!

> Do yourself a favor and play through The Griffon Legend and then I'm sure you'll agree with me that Syn9 was more than deserving to be named Programmer of the Month of July!

## What Got Me Into QB

### Written by James Kinney (aka Mech1031, aka The_Glove, aka Gebmasta)

What got me into QB? Well, oddly enough, I can remember it very vividly. It was just an average day of high school for a freshman such as myself when one of my friends approached me with a floppy disk. He said: “Check this out, it’s a game I made for the computer.” I clearly remember being very excited, and almost running home to try it out. Just the mere thought that “someone I know made a game, and wants me to play it” made me excited. I got home, put the disk in, and clicked the BB.EXE just like he told me to.

The words “Baseball Beta” came with the picture of a baseball diamond below it. I could feel something then, some sort of nirvana that I had never felt before. I was playing a game made by someone I knew. After several hours of hitting a ball and watching the small pixels run from base to base, I got around to asking him how he made the game. He told me it was with this great language called QuickBasic and gave me a very large packet of tutorials he printed out from Qbasicnews.com.

I must have read the whole thing at least 3 times. I didn’t understand half of it, but what I did know was enough to make a small game of my own. So that’s exactly what I did. My first game was called “chase”; in this game, you’re a green ball who has to chase a red ball around the screen until you catch it. I was so very proud of it, even though it was no baseball beta.

Eventually, I began taking on much larger projects and playing around with other peoples code to get custom versions of their games that only I could play. I can even remember being so enthused about QB, that I joined the forum on qbasicnews.com. Actually, to show you how enthused I was, I’ll post my very first post in that forum right here:

> A very naïve Mech1031 wrote:
> here is my plan, i am going to make an rpg using thousands of different characters suggested by you guys. i would need you to send me an email with your name, the occupation you want to serve under(knight, shop keeper, crazed woodland elf with the attitude of a rouge elephant), whatever you can think of. i will also need your age, and your standard of living(in game). send it to ------@-----.com, i will post a longer post with alot more details. please respond

How embarrassing. Wait, let me read through that…. did I really say “thousands” of characters? Ouch. But as you can see, I was rather excited. Of course this never took off, given how ridiculous it was. But I did get one or two replies telling me to “start smaller”. Luckily, I took the advice given to me and instead started work on a much smaller project: a top down shooter known as “falling starz”.

It took a great amount of effort, and the work was tedious, but the end result was glorious in my eyes. I even entered it into a challenge that was being held on the Qbasicnews forums (I think it got 6th place out of 8 entries.) It was at this time that I thought I had got what I came for. That I actually finished a game, and other people were able to play it. I look back on those days, and I feel like anything is possible as long as you’re willing.

But I also think of what could have been. What could have I accomplished if I hadn’t joined those forums? What could have happened if no one ever encouraged me to do more and go farther? Not nearly as much, that’s for sure. You see, it wasn’t the knowledge of the language that got me as far as I went, nor was it sheer willpower. It was the community that kept me going. Without that voice in the back of your head (the Qmunity), I doubt many people could accomplish what they do.

As of late, I only code for some of the computers at the grocery store where I work, just simple database programming and maybe a few interface designs here and there. But even today, I look back on those days of Programming in QB 5 hours out of the day, and I think to myself: “Why did I ever stop?”

Visit James' site, Gebmasta (home of Lobster Comics).

## Interview with Nekrophidius

### Conducted by Pete

> Last month's interview with Sumo Jo turned out to be QB Express's most controversial article yet, mostly because Sumo Jo and I made some rather disparaging comments about Nekrophidius and The Basic Network midway through our conversation. Many readers took offense to these remarks, and I got scores of feedback from readers telling me things like "I can see why Wildcard shut down Qbasic News ... all of this immature bullshitting", people calling QB Express a "gossip tabloid", saying we had "embraced the dark side of the force...using media power to harass people", and "that issue was...radical to say the least...Definitely not my favorite by a long way". Needless to say, those statements caused quite a stir among QB Express readers.

> Defending ourselves, Sumo Jo and I countered by reminding everyone that this was an opinion piece in an open, uncensored, free speech magazine, and that it would be against QB Express's philosophy not to print the interview in full.

> However, another thing QB Express embraces is getting opinions from all sides of an issue, so we asked Nekrophidius if he'd like to do a counter-interview this month. And...he obliged. This month, you get to hear from one of the QB scene's seminal figures -- find out what Nek's working on programming-wise lately, and read his thoughts on the scandal that we at QB Express like to call "Sumo-Jo-gate".

> -Pete

Pete:

So do you wanna do that interview now?

Nekrophidius:

Sure if you've got the time.

Pete:

Yeah, sure, let's do it.

Nekrophidius:

Sounds like a porno invitation or something but okay.

Pete:

First off, congratulations on your baby!

Nekrophidius:

Thanks. She's a pain in the butt even before she's born.

Pete:

You're probably the only QBer I've ever known where both he and his significant other are active in the community. How exactly did Rhiannon get involved in the QB scene?

Nekrophidius:

Well quite frankly, most of the women I've been involved with have somehow gotten into the scene in one way or another. Rhiannon is just the only one intelligent enough to actually mix in with everyone. She's not really a coder per se although she can do a bit.

Pete:

She was just drawn by the community aspect then?

Nekrophidius:

Yeah, for the most part.

Nekrophidius:

Rhia loves a good debate, which is one of the reasons she's around. Plus she likes to see people solve problems and improve their skills.

Pete:

Well, I guess she chose a good community then!

Moving onto more pressing issues though -- last issue's interview with Sumo Jo.

Nekrophidius:

Okay.

Pete:

This entire interview was of course inspired by the QBasic News shut down. Can you tell me what your thoughts were on the shut down?

Nekrophidius:

Well, my original opinion was that the shutdown was a pity party for Wildcard. Someone in his position, with his level of "political power" as it were, could garner a great deal of pity by doing such a thing. When he shut it down the first time [in 2003], that was also my thought on the reason "why". But I wasn't around when he shut it down this time, so basically I was thinking back to the first time and relating the two shutdowns. When he brought it back, it looked at first to be "hey look, I screwed you all over but now I'm bringing it back, so let me be your hero all over again!" Some people said that he had second thoughts about closing the place down and did it as a sudden, rash move, which also did make sense, so that was the theory I went with afterwards.

When he announced that someone else would be taking it over, of course I was skeptical about that. Remember, he said he would de-admin himself after the first shutdown but it didn't take long for him to be in admin position again, making that entire thing look like a smokescreen. So this didn't seem like it would hold any weight either.

Pete:

Now, when the shut down came, you had "left" the Qmunity and the QBN boards a few weeks before hand. Why did you decide to leave?

Nekrophidius:

To be 100% honest with you...I felt like the only use I had around the scene was to be the guy who always argued with people and was the first person people would look at when things went wrong…

After all, I'm the "troublemaker".

I had lost most of the work on V Planet due to a hard drive problem, so I thought the best thing to do would be to hand it over to someone else and just get out before anything worse happened. I don't like to argue and fight. I like to help people. When I can't help people, I don't have a purpose. Bottom line.

Pete:

Two quick questions about this then: (1) for someone who doesn't like to argue and fight, you sure have gotten in a lot of arguments and fights over the years, and (2) even though you've said farewell the Qmunity multiple times, you keep on coming back -- you're like the comeback kid of the QB scene. Why do you keep getting drawn back?

Nekrophidius:

There's only one person in the entire Qmunity who knows me well enough to know the answer to #1 and that's Neo. The short version is that it's a natural thing for me to want to fight, although it's an aspect of my personality that I've been, ironically, battling for many years. I also have a very high dislike of injustice and bias, and I'll speak out about it whenever I see it, even if it means getting involved in yet another victor-less "war".

I guess it's the same idea as people who "fight for peace".

As for #2....as much as I grow to hate the things that happen in the Qmunity...you know, the fighting, the elitism carried by some of the people, the occasional opression and favoritism...it always felt like my home and a place where I could help people out.

But eventually, a time came where I had to weigh the good and the bad, and I drew the conclusion that it was for my own benefit and probably for the benefit of others as well if I just put those thoughts of helping others aside for awhile and just left. I'm not the only one who can help people in the scene...there's plenty of good, talented people around that can do that, so I can help people somewhere else.

Pete:

Well, I have to say that you certainly have helped a LOT of aspiring QB and FB coders, and a lot of people neglect to notice how much you've given to the community in the past few years. They focus on the handful of arguments you've had… I’ve heard it called “Nek’s wrath”.

Nekrophidius:

Humans tend to focus on the negative, ignoring the positive. Remember the Sumo Jo interview where people got all kinds of crazy over some of the things he said, mostly ignoring the rest of the interview? That would be a very good example.

Pete:

Absolutely! In fact, someone accused the entire QB Express magazine of being negative because of a few comments the two of us made. Heheh.

Nekrophidius:

The entire issue was great, but people focused on a few lines of an interview and forgot the rest. People just focus on the negative, as if they expect the positive for free and take it for granted.

Pete:

Agreed. Anyway, Sumo Jo accused the people who decided to move to The Basic Network after the QBN shut down to be essentially your sheep: "The TBN loyalty will stay as long as Nekrophidius convinces people that QBN is evil and he knows all."

What do you have to say about your so-called followers?

Nekrophidius:

They're not followers at all. People have their own free will and those who came to TBN did so because they wanted to. The shutdown scattered people everywhere, TBN just happened to be one of the places people "landed".

The viewpoints I personally hold aren't unique to just me...a great number of people have the same thoughts. I think most of those people make up the majority of TBN members. If people want to call this association "following", then so be it...call it whatever you like.

If these people were really followers, don't you think they'd spend most of their time grovelling and worshipping me on the forum?

The funniest part was when someone called Z!re my "yes man”. Of course completely forgetting the fact that Z!re's a woman, first of all, but hey, such details don't matter when you're trying to insult someone, right?

Pete:

Heheh. I know that I personally advocated The Basic Network to become the new home for the Qmunity in QB Express #10 because it was the most active and interesting place, where most of the people with personality went after the QBN shut down.

Nekrophidius:

And of course, I'm sure you got a lot of shit for that, didn't you?

Pete:

Yeah, I was a "Nek sheep", I suppose.

Nekrophidius:

Again...focusing on the negative.

Pete:

Anyway, why do you think so many people have stayed away from QBasic News now that it's been restored?

Nekrophidius:

I don't really know. It might be that the last shutdown shattered the Qmunity too much. I know that the activity has picked up since it reopened, but from what I hear, it's nowhere near as active as it was in the past. Plus, when you have several "big names" leaving within a short time of each other, it tends to have an impact.

I've spoken with Agamemnus a few times since he disappeared from QBN and he says that the reason he stays away is because of all the fighting.

Pete:

I'll put it this way -- there is very little discussion of programming there anymore. Now it's all debates about next gen gaming consoles and weird topics that Spotted Cheetah brings up.

Nekrophidius:

That's not surprising. Talk about QB has gone down dramatically in the last few years anyways, and with FB "taking over", it seems all the dedicated FB coders are on the official FB forum now.

Pete:

QBN's QB *and* FB discussion unfortunately went from several posts a day to basically none after the shut down. (Though, there really isn't much hard programming discussion at TBN either. It's become more of a place for people to hang out. FreeBasic.net is the only place where we consistently see talk about good ol' fashioned programming.)

Nekrophidius:

I didn't really expect to see a lot of programming dicussion at TBN, honestly. Also, I think it's great that FB has its own dedicated place to discuss programming. What better place than its cyberspace home?

Pete:

I definitely agree with you on that one.

So one last question about the interview -- what was your gut reaction to it? Were you angry, disappointed, proud, indifferent...?

Nekrophidius:

Rather indifferent. Although I had no idea that you and Sumo Jo thought such things, we all have the right to our own opinions, regardless of how skewed they may be. I'm pretty sure that people expected me to get all kinds of crazy, start throwing insults around and all that, but sorry to disappoint guys...life's too short to get all kinds of pissed off over such things, and you won't be finding me taking the flamebait anymore.

Pete:

The main reason why I didn't edit the interview was because I thought "What would Nek do? He would post it. He's not afraid to speak his mind." When I started QB Express, I vowed that it would be an uncensored magazine where anyone who wanted to write would be allowed to, and I figured that the editor censoring his own thoughts would go against the magazine's own philosophy.

Nekrophidius:

Exactly. There was no need to edit it. I would have printed the same thing...hell, when I ran QB On Acid, I would have had no problem posting insulting letters that told me that my mother likes goat's cheese in her toes or something (actually I think she does, but that's another story).

QB Express, IMO, is the only remaining publication that isn't afraid to offer it all up uncensored.

Hey wait, you're the only zine left in the Qmunity, right?

Pete:

Heheh. QBOA was a big inspiration for QB Express. I wanted to create a mag like QB:TM but with the philosophy of QBOA -- a good mag but without all the censoring and elitism.

Nekrophidius:

Cool.

I hated QB:TM. It was good to see opposing publications back then but they were very rare.

Pete:

Now just a few more questions before we wrap this thing up...

First off, I've been wondering about the Gaming Gold Awards for a while. You said that the reason it never got off the ground was basically because nobody voted. What was the deal with that?

Nekrophidius:

In the past, the Gaming Gold Awards got tons of nominations, in the hundreds according to Vance. This time, there were only 33 nominations. Oh, and one cheater. There weren't enough nominations to even determine a top 2, let alone a top 3 or 4.

It was clearly obvious that very few people wanted it to run. There were a few people who nominated a few days in a row, but after about a week or so, no more nominations were received.

Pete:

I see. Of the 33 nominations, how many were repeat ballots? (How many people actually voted?)

Nekrophidius:

There were 14 unique IPs and a lot of votes from the same ISP over a few days, so we know that it was the same person from a dialup account voting on those. It looks to be about 20 people total, with only about four nominating on consecutive days. A lot of one-hitters.

Pete:

It's a shame that there was so little interest. I still think that there should be one final Gaming Golds/Qlympics/competition at some point. Maybe I'll try to do one in QB Express and hope that there's a bit more interest.

Okay…next question -- What's the status with your QB / FB projects? Two Lords, your FB RPG ("Phantasm" maybe?), FBXL? And what ever happened to "Nek's FB Page"?

Nekrophidius:

All have been cancelled. I had been coding in various languages for the computer almost non-stop for the past 20 years. Simply put...I became burned out. Also, whenever I would start up a new project, I'd find an excuse to start up another one, then another one, rinse and repeat.

Some of the projects I took on were beyond what I was capable of as well (like FBXL).

As for the page... I never did end up restoring it when we bought our new server. Barely anyone seemed to miss it anyways, so it made no sense in restoring a page that no one viewed.

Pete:

You certainly do start a lot of projects that you never finish... the only one I can think of that you *did* finish is Wrath of Sona.

Nekrophidius:

Yeah...used to happen a lot. And yes, WOS was eventually finished but never actually released in its finished form.

Pete:

Do you ever plan on releasing it?

Nekrophidius:

If I can ever find it, yes. WOS was finished in RPG Maker 2000 in its entirety and archived to CDROM. Unfortunately, I have no idea where the disc went. :-(

Pete:

Hmmmm, too bad.

Finally, what projects are you currently working on? (The TurboGrafix ones?)

Nekrophidius:

Right now, Frozen Utopia (the TG coding group started by myself and DeveloperX, who is a regular on rpgdx) is working to complete a remake of DarkDread's classic game Mysterious Song, and aside from some missing artwork, the game is set for release. We've also started our next project, which is a sequel to Hudson Soft's "Neutopia II", and it's called, ironically, "Neutopia III". There's a whole lineup of games planned after that, designed by various members of the group.

The key issue though is completion...that's what I drilled into my own head before getting seriously involved in projects again. One project MUST be completed before another is fully underway. That's my strategy, and I'm sticking to it.

Pete:

That's a great idea.

Nekrophidius:

It's worked so far.

Pete:

Well, thank you very much for the interview! Before I let you go, do you have any final comments to tell the Qmunity?

Nekrophidius:

I guess I'm supposed to say something witty and dramatic here, right? Hehehe.

[Long Pause]

Nekrophidius:

Watch out for potholes on the roadway of life...shocks are getting awfully expensive lately.

Pete:

That will do nicely.

Now I guess I'm supposed to say "For QB Express News, I'm Pete Berg."

Nekrophidius:

Okay, go ahead and say it then. Oh wait, you already did.

Pete:

For QB Express News, I'm Pete Berg.

[Pause]

Pete:

Allrighty, seeya later!

Nekrophidius:

Heh okay.

You can find Nek and all of his "sheep" at The Basic Network. :)

## QB Express - First Anniversary, So Many Spectactular Memories!

### Written by Adigun Azikiwe Polack

Ever since QB Express has first made its grand debut on the world wide web to the whole QB community everywhere on August 23, 2004, it very quickly became such an absolutely AMAZING new QuickBASIC magazine and then plenty! And part of such intensely wondrous magic is in the fact that the whole complete thing was (and always is!) open-source!! =b ! This simply meant that all 100% of the original articles, tutorials, game reviews, news briefs, and more — so long as they have had virtually *anything* to do with QuickBASIC/QBasic at all — were presented in their full, raw, and uncompromised entirety to you by the QB community itself and even newbies of QB programming, too, all in their original words and even in their own sayings as well! On top of all of that, this magazine has no less than genuinely added to the elegant and ever-awesome brilliance in a rather big way with an even more impressive “Gallery” section that usually appeared every month, presenting very special previews of brand-new games made in QuickBASIC even before they are released to the public for the very first time!!

And then suddenly after that, from right out of literally nowhere, a fiery ambitious and quite so truly daring QB programmer named Andre Victor T. Vicentini (aka v1ctor) took a rather bold step right after another to create such an *entirely* new and ultimately so ground-breaking BASIC programming platform known to all of us as FreeBASIC!! Thus, our QB world that we have known and cherished has without a single doubt turned topsy-turvy into such outstanding new programming heights so many, MANY times over like we have never experience before!!! Goodbye to 64k memory limits, real pain-in-the-butt “Out of Memory” errors, EMS- and XMS-based memory leaks, and QB-to-WinXP compatibility problems; and hello in such grandest style to such excellent Windows/Linux programming, DirectX, OpenGL, SDL, BASS/FMOD/OpenAL sound designing, plus the very truth that you can even actually break the 64k memory barrier so freely by simply writing and even successfully compiling QB-like programs that can go up to as much as a rather whopping 2 gigabytes long in apparently just ONE single source code, and tons upon tons more possibilities in ways we have never even dare dreamed possible!!! d==b !

Because of that totally revolutionary new BASIC programming platform indeed, QB Express soon expanded the whole field entirely to FreeBASIC in addition to QuickBASIC/QBasic. And add this to the fact that this very online publication is open-source, *combined* month-by-month with increasingly more and more of the absolute biggest record amounts of tutorials, QB/FB game reviews, and original articles than ANY OTHER QB- or FB-related magazine in existence, and you got the ultimate official FreeBASIC/QuickBASIC magazine in history. Period, total end, and that is final. (^-^)//

You know, there have been quite a helluva lot of outstanding articles that keep pumping and pumping out to QB Express ever since its very wonderful beginnings, which leads me right now to my first question that I asked the community:

#### What is the best and *most* inspiring QB or FB tutorial that has ever been written for QB Express 1-11?

Here are the following results that were made based upon the total and official number of votes made by the QB45/QB71/FreeBASIC community:

> 1 S T • P L A C E (tie):

> > “OpenGL Tutorials for FreeBasic Parts 1-4” by Relsoft
> > (from Issue #8 of QB Express)
> > The I.F. Games Tutorials (Chapters 1, 2, 3, 4, and 5) by Na_th_an
> > (from Issues #6-10 of QB Express)

> 3 R D • P L A C E (5-way tie):

> > “Text RPG Tutorial” by Nixon
> > (from Issue #7 of QB Express)
> > “Metaballs? I’d call them “Blobs”” by Relsoft
> > (from Issue #1 of QB Express)
> > “Lensflares” by Relsoft
> > (from Issue #4 of QB Express)
> > “Programming GUIs in QBasic” (Parts 1 and 2) by VonGodric
> > (from Issues #3 and #5 of QB Express)
> > “The BASIC User’s Guide to English Spelling and Grammar” by DrV
> > (from Issue #10 of QB Express)

To tell you straight and true right here, all of them are quite EXCELLENT examples of just how very helpful, informative, and even so fascinatingly good a tutorial can really be for this magazine. Fair and square. !

The second question that I have asked the QB45/QB71/FB community in honor of this special anniversary issue of QB Express was:

#### What was the BEST ground-breaking news story that has ever been introduced from within the first 11 issues?

Here are the results of their official total votes:

> 1 S T • P L A C E

> > “Is it a Bird? Is it a Plane? No, it’s FreeBasic!” by Blitz
> > (from Issue #4 of QB Express)

> 2 N D • P L A C E

> > The QBasic News Debacle
> > (from Issue #10 of QB Express)

Well, according to some of the votes here, it is obvious that just about anybody in the QB45/QB71/FB community knows well enough for sure that the sudden closure of the QBasicnews.com forums has really shocked the VERY hell out of all of us in a major way and then some — especially since it was given to us (without any warning at all) by Wildcard himself! Ohh, how rather so unfortunate! ! Some were crying, some were disappointed, some were terribly saddened, some were just deeply stark-raving mad......... just all different kinds of emotions that were raging to and fro from the whole community everywhere as that sudden event happened! In fact, it all took place *just* before QB Express #10 was first released. No wonder a lot of the people surely began to migrate apart to different QB/FB forums when this first happened indeed, you know? Shortly after that (fortunately!), Wildcard himself truly showed mercy on us all by re-opening the forums and transferring all ownership of QBasicnews.com itself — forums and all — to none other than Sumo Jo. And at the time this very article was written, Sumo Jo himself is already doing a TRULY phenomenal job at running and balancing these forums well, even with the newly-crowned moderators Rokkuman and MystikShadows as well!! Hey, keep up the excellent work, Sumo Jo!!! (^_-)v !

On the much more brighter side, though, there have been QUITE a lot of things happening in our ever-changing, ever-advancing QB world from within this past year (2004-2005) alone, and one of the most absolutely so amazing things to ever rock our world indeed was FreeBASIC, just like I mentioned from earlier within this article. And boy, does it truly rock or what?! ! That is *exactly* why this great article entitled “Is it a Bird? Is it a Plane? No, it’s FreeBasic!” — so awesomely written by Blitz himself (who is also one of the creators of UGL for QuickBASIC 4.5/7.1 and VBDOS!) — deserves 1st place as a result of it receiving an impressive eight votes versus only two votes for the QBasicnews.com closure.

Next up now, there was also a very handful of awesome (and even balanced!) QB/FB game reviews by such great people like Zap, Lachie Dazdarian, Cha0s, myself, and some others, all from within a single year of this publication of QB Express alone!! =b As an interesting little twist this year, let us now crown the best of the best game reviews, shall we? To begin here, I have asked the QB45/QB71/FB community this:

#### What is the BEST game review that you have ever read in QB Express 1-11?

On just that question alone, here are the final results based on total official votes from you, the QB45/QB71/FB community:

> 1 S T • P L A C E

> > “Scorched Planets Review” by Zap
> > (from Issue #7 of QB Express)

> 2 N D • P L A C E (3-way tie)

> > “Searching For The Unknown: Astral Worlds by K.D.A.G. 2004” by Lachie Dazdarian
> > (from Issue #11 of QB Express)
> > “Review of Larry the Dinosaur 2 by Delta Code, 2002” by Lachie Dazdarian
> > (from Issue #9 of QB Express)
> > “Detective Academy Review” by Oz
> > (from Issue #2 of QB Express)

There is clearly no doubt here that Zap has done such *very* honest and well-balanced reviews of FreeBASIC/QuickBASIC games, and his own original FB review of Scorched Planets by Joakim is the ABSOLUTE best ever from within the first year of the publication of this magazine you are looking at right now!! Here, he told about the game like it truly is, all from the graphics to the sound and gameplay and more..... even to the timespan this game took, too! =b ! Wow, his review of that game was so phenomenally good that it just plain hitted home to all of us and even encouraged us to go try the game out!! I am telling you, that is outstanding game reviewing the way it should be, so three TRULY BIG cheers for Zap on this most spendid game review ever printed for the first 11 issues of QB Express!!! (^_-)//

And Lachie Dazdarian — creator of such truly excellent-playing QB games Ball Blazing Fantasy and Evil Baron Lachie — has also done the same excellent job as Zap, especially on his dead-serious, no-nonsense way of reviewing games in both QB and FB, and his recent new game-review series entitled “Searching for the Unknown” clearly delivers us all the VERY rarest and most obscure QB games ever and gives them the surefire spotlight and attention that they *never* originally deserved in the first place! And I believe right on the spot that this is such a spectactular series ever written for QB Express so far, and I surely hope that more and more supposedly ‘lost’ games of this kind gets known like that!! A grandly splendid job from you, Lachie!!! d==b !

Turning to the flip side of this coin, we go now to the bottom-of-the-barrel out of all the game reviews that had ever been published from within the first 11 issues of this very online magazine publication. And speaking of which, this next question was asked to the QB45/QB71/FB community:

#### What is the WORST game review that you have ever read in QB Express 1-11?

......and on that, many of this community had singled out the most apallingly bashing (and therefore *really* inane! ! ) mistake of a review which was:

> “Review of The Quest for Opa Opa by Na_th_an and aetherfox” by Joseph Burke
> (from Issue #9 of QB Express)

The clear reason why Joseph Burke’s own review of The Quest for Opa Opa was so brutally appaling indeed where writing QB/FB game reviews are concerned is simply because that his own review was simply no more than designed to just cut down (and — at least to a lot of this whole community — even belittle as well!) the RATHER awesome job that both aetherFox and Na_th_an *originally* did on the entire game and then some, even right down to the way he scored it, too. You know what, to be dead-on honest with you, I can only say that this review certainly makes Cha0s’ original review of that very same game here (printed also in QB Express #9) look like an awesome and rather beautifully sculpted masterpiece. Roots and all. I am not putting Joseph Burke down or intending to harm him or anything like that, but rather, I am just showing you that ALL reviews of games written in FB or QB should just cut right down to the chase into getting real about the whole game itself (and such aspects of it as graphics, sound, gameplay, play control, and others as well), and the reviewer is to just tell it like it honestly and really is, without even being biased or compromising. For example, just look at Lachie’s and Zap’s reviews, plus my own current featured review of Pixel Snake Gem Hunt! in QB, and you will simply see that exact kind of stuff I am talking about. Period, and that is plain that. ! And, this following excellent point from MystikShadows himself needs to be considered and considered well:

> A review of a game should be made based on the type of game it falls under.....

.......and all FB/QB game reviewers (including aspiring ones as well!), PLEASE TAKE SERIOUS NOTE!!! !

Moving right along to something better here, the “Gallery” section is so uncompromisingly one of our most favorite sections ever to grace QB Express! And the magic here is that such AMAZING new previews of the newest and forthcoming FB and QB games are being shown to you to give you a wonderful taste of what to expect from them..... before they are released to the public!! =b ! So, this brings me now to this question:

#### What was your favorite upcoming game/project that has ever been featured in the “Gallery” section from the first 11 issues?

......and since this question was asked to the QB45/QB71/FB community, here now are the overall results on how they voted officially:

> 1 S T • P L A C E

> > The Griffon Legend - syn9
> > (originally featured in Issue #11 of QB Express)

> 2 N D • P L A C E (tie)

> > Inspiration - Wallace Software
> > (originally featured in Issue #5 of QB Express)
> > MOORPG (Massive Offline Open RPG) - Z!re
> > (originally featured in Issue #2 of QB Express)

> 4 T H • P L A C E (3-way tie)

> > Two Lords - Nekrophidius (aka Necros Ihsan Nodtveidt)
> > (originally featured in Issue #4 of QB Express)
> > Counter Strike 2D Clone - badlogic
> > (originally featured in Issue #1 of QB Express)
> > StarOdds32 - Na_th_an
> > (originally featured in Issue #7 of QB Express)

All of them were favorite preview games from among the QB/FB community’s own selections, but the one game that *really* captivated our eyes was The Griffon Legend by syn9, a most promisingly very awesome FreeBASIC RPG that has an enthrallingly original storyline (even involving a wonderful mix of griffons and dragons as well!), simply outstanding graphics, a very fresh icon-driven magic system, and excellent emphasis both on full control of your character and on being such a very intense action-oriented RPG, “Zelda III” style!!! One to look SERIOUSLY forward to....... and since The Griffon Legend has just now been released (with all music by David Turner), go on in here and get playing!!! !

And finally here in our most wonderful little reminiscing, as this very first anniversary of QB Express is here at long last, we, the whole QB45/QB71/FreeBASIC community, want to congratulate you very deeply from the rather bottom of our hearts, Pete Berg, for TRULY giving us all the most phenomenally successful FreeBASIC/QuickBASIC magazine this planet has ever even seen. d=^_-=b !! Here’s to many, MANY more great years of this utterly splendid open-source publication, our wonderful wonderful man, and..........

Extra Special Thanks to Pete Berg, MystikShadows, Relsoft, Jocke the Beast, DrV, Jofers, The walrus (Jacob Palm), Rattrapmax6, moochthemonkey, and many others who participated in this wonderful group effort to make this very article possible!!! !!

## QB/FB Legends of the Year / Site of the Year Awards 2004-2005

### Written by Adigun Azikiwe Polack

And now, ladies and gentlemen, it is definitely my absolute priviledge and honor on QB Express where I will now personally be handing out the very special awards this year for the QB/FB Legends of the Year and for the QB/FB Site of the Year, respectively. Let’s do it!!!

### QB / FB Legend Of The Year

The QB/FB Legends of the Year is a VERY special annual award on QB Express that so grandly honors the QB/FB programmer(s)/group(s) that truly revolutionize and touch us all in FreeBASIC or QuickBASIC with such simply spectactular works and outstanding inspiration to help make this QB45/QB71/FB community much stronger and even more awesomer than ever before! And I will, from deep within my heart, so grandly honor and salute this most unforgettable and most revolutionary man named Andre Victor T. Vicentini (aka v1ctor) who has gone out of his very way to so literally bless us all with such an utterly phenomenal new BASIC programming platform named FreeBASIC. (^-^)v !! Ever since this platform’s initial public release back on around October/November 2004, rather so many and many QB programmers everywhere began to migrate to this new BASIC programming platform that swept the QB world indeed by one *major* awesome storm right after the other..... without even stopping!! Thus, ports of old QB games were remade for Windows 9x/ME/NT/2000/XP, Linux, and so much more — including the classic Wetspot game that was first ported from QB to FB from January 2005, also!! Plus, there was an absolute never-ending cornucopia of even more programming opportunities opened to us now like we have never even dreamed of before in BASIC!!! And rather recently now, there is even a sure possibility that you can *actually* port your FB programs over to Microsoft’s original XBox game system, too!!! Man, I honestly no doubt believe on purpose (with all of my very heart!!) that FreeBASIC is the ABSOLUTELY REIGNING grand king of all the freeware BASIC programming platforms..... period, and that is truly just that. God bless him!!! ! v1ctor, my most personal deepest congratulations to you in such outstandingly awesome spades for revolutionizing this whole wide community and for making us all even stronger than ever!!! You truly deserve this most elegant award, on behalf of Pete Berg, myself, and the whole entire QB45/QB71/FreeBASIC community!!!

Long live FreeBASIC!!! d==b !!

(Saluting the excellent nominees of the QB/FB Legends of the Year 2004-2005!!)

> • Angelo Mottola (aka lillo)

> > In such grand honor of both FreeBASIC and v1ctor, we will most DEFINITELY salute this so intensely awesome man ( ! ) who has so deliberately helped out tremendously in bringing us this absolutely marvelous gift of the phenomenal QB-like library of GFXlib 2 as part of the whole FB package!! He has also helped out most excellently in both the work and development of FB itself! Ladies and gentlemen, please give a grand honorable salute to Angelo Mottola, original creator of the Wetspot games and one of the *original* contributors of the development of the Allegro game library!!! d=^-^=b !!

> • Los Monos Del Obús (aetherFox and Na_th_an) - The Quest for Opa Opa

> > Right here and right now, we take the time to so richly honor nominees aetherFox and Na_th_an (known together as Los Monos Del Obús), especially on the wonderfully AWESOME work they actually did on their original text-based adventure game The Quest for Opa Opa, fresh from FB!! I mean, anyone who dare thinks that text adventure games are just outdated and dull had better give this one a try ( ), because it truly does have a quality and very interesting RPG-based storyline, plus, I gotta love the fact that the music/ambience that these two people have put in there really draws you right into this game like a magnet, oh man!! That alone sure deserves a BIG thumbs-up from me!!! d==b ! Text-adventure creators in FreeBASIC, TAKE GOOD NOTE HERE, and our congratulations to both aetherFox and Na_th_an on treating us all to such an amazing experience in text-adventure gaming!!! (^-^)//

> • Z!re - MOORPG

> > Let us give a handsome salute to Z!re as well, who is working quite hard on her very interestingly immense RPG known fully as Massive Offline Open RPG (MOORPG). And it shows *quite* a lot of promise in that 1) there are SO many characters and then some; 2) there will be MASSIVE and possibly never-ending worlds for you to explore; 3) there are lots and lots of branching plots that are affected by the player’s own choices; and 4) there is more and more interactivity than you can imagine in an RPG!! Ground-breaking that it is all being done in good ‘ol QB, too! Hey, if this gets successfully ported to FB and does so well there, then this will be quite a special treat that RPG fans will be waiting for!!! Wish you such excellent success on your game, Z!re!! !

### QB / FB Site Of The Year

And now, we go to the QB/FB Site of the Year, which is a VERY special annual award on QB Express that so grandly honors the QB/FB sites that *absolutely* excel in the highest caliber QuickBASIC/FreeBASIC-related quality and content as well as the marvelously intense ease-of-use, thereby presenting such amazingly phenomenal works as a major support and blessing to this whole QB45/QB71/FB community!! The ultimate honor this year goes to..... you guessed it, Andre Victor T. Vicentini (aka v1ctor) and his current site home for FreeBASIC entitled “FreeBASIC Official Page”, where there is amazingly a SPECTACTULAR active forumboard as the true and official forums of FreeBASIC, containing all of the very latest scoop, developments and projects in FB, plus it even lets you get downright inspired to actually create your big and amazing game/project/demo in FreeBASIC!! The sheer beauty of it all is, such wonderful people as MystikShadows, Relsoft, DrV, v1ctor himself, and such other aspiring FB programmers are willing and able to encourage you to do so and to help you out truly good along the way..... even if you do run into some programming trouble there along the way! Also, there are tons more like an interesting FB gallery, as well as plenty of outstandingly helpful and informative documentation for all parts of FB and the many libraries supporting it — even at the nooks and crannies, too!!! WOW, what a phenomenally great site it already is, and I sure hope truly and deeply that more and more BASIC programmers will make the switch to the *totally* no-cost, absolutely no-nonsense programming platform of FreeBASIC!!! d=^-^=b !! Hail to our splendid man v1ctor, in such ABSOLUTE majestic salute to him for the official QB/FB Site of the Year 2004-2005, because he has earned it big-time and then plenty!!!

Like v1ctor clearly said: all stuff, no fluff! And it 100% shows right there!!! =b !!

(Saluting the excellent nominees of the QB/FB Site of the Year 2004-2005!!)

> You know, over this past year alone, there have been lots of truly good FreeBASIC/QuickBASIC sites, and few and far between, there have been *quite* excellent ones as well!!! ! Here now are the best of the best nominees that DESERVE such awesome recognition:

> • Pete’s QBASIC/QuickBasic Site - Pete Berg
> (website: www.petesqbsite.com)

> > One of the LONGEST running QB sites that existed before V-Planet even hit the scene for the very first time ever, this site — created and operated by spectactular QB/FB Site of the Year 2004-2005 nominee Pete Berg — currently boasts a staggeringly phenomenal 600+ tutorials, plus it even gives users a clear-cut opportunity to upload their own FB/QB related news, games, and projects into this site. A vastly so extensive wealth of QB downloads, reviews, links, and more are here for you as well, and this site is *also* home to this very sacred FreeBASIC/QuickBASIC publication known as QB Express!! A QUITE IMPRESSIVE SITE, no less!!! d=^-^=b !!

> • QB45 Programming Network - Jofers and Fling-master (aka Gered King)
> (website: www.qb45.com)

> > Another one of the LONGEST running QB sites, only this time it is back and absolutely bigger and better than it ever, ever was!!! =b The two awesome guys behind the successful resurrection of this rocking site — Jofers and Fling-master — have gave it their flat-out impressive best in piecing together all of the original 1,000+ QB downloads, tutorials, and so rather many more that was on this site from since it first debuted in 1996. It was quite a hell of an undertaking in that year-long process they had to do, but at the end, it sure paid off tremendously for them both and then some!! Now, this site has returned to its full fledged glory once again!!! Congratulations to both Jofers and Fling-master for giving us such a thrill of a *spectactular* resurrection of QB45.com, as they simply are such excellent nominees indeed!!! (^-^)v !!

> And here are the remaining REALLY good site nominees that also deserve the excellent honor just as ever ( d==b ! ):

> > • JacobPalm.dk - Jacob Palm
> > (website: www.jacobpalm.dk)
> > • QBasic News (QBN) - Formerly owned by Wildcard, now owned by Sumo Jo
> > (website: www.qbasicnews.com)
> > • FreeBasic.tk - Zap, Sumo Jo, and Rhican
> > (website: www.fbtk.net)

And this wraps up a most unforgettably grand event for this already PHENOMENAL year in the world of FreeBASIC and QuickBASIC. I, Adigun Azikiwe Polack, so personally owe it all to the whole entire QB45/QB71/FB community, and especially to you, Pete Berg, for truly helping to make this all no less than possible!! And to all of you aspiring FB/QB programmers, I wish you all such *marvelously majestic* success in all of your coding and then plenty!!! =b

God so utterly bless you all very seriously, and be seeing you again next year!!! A most splendid good night to you!!! d==b !!

> MY MOST HAPPIEST WISHES AND ENCOURAGEMENT TO ALL OF YOU,
> Adigun Azikiwe Polack
> Official Founder and Creator of the QB/FB Legends of the Year / Site of the Year Awards 2004-2005 for QB Express and Pete Berg

## Comics

### By Rattrapmax6 and James Kinney

Rattrapmax6 is back this month with another QBasic Horse Humor comic, plus James Kinney dropped in to bring us a new "Lobster Comic". A new record for QB Express: two comics in one month!

## IF TUT CHAPTER 6:
A NICE SCRIPTS INTERPRETER

### Written by Na_th_an

After last month's tacet, here we are with this bummer again . I somewhat doubt that someone is following this as I get no feedback and specially now that my popularity is in an all-time low after the QBN debacle, but I'll try to refresh the minds of the one or two readers I might have (j/k!).

In chapter 5 we began building the parser module, which we explained that consisted in two completely different parts which served for two rather different purposes; the first one was explained and developed during last chapter, and the second is to be discussed in this one. We are talking about the scripts interpreter which is used to code the exceptions.

We explained that "exceptions" were those "things that happened in our text adventure game which are not the normal things"... This definition is pretty loose. In our engine (we'll see this when we code the Objects Manager), there's a lot of things that are handled automaticly: for example, if your command is to open a container it gets open. If your command is to examine something the program will throw the description for you. Those "common actions" are called that way 'cause you don't have to code them intrinsicly, but they are handled by the objects manager 'cause they work in the same way for every object in the game. For example, openning a container is a matter of doing always the same things: 1.- Checking that it is a container, 2.- Checking that it is visible/reachable, 3.- Openning it. That's a common action: it will be done in the same way with every object in the game. Common actions are, as mentioned, handled in the Objects Manager.

"exceptions" are those things that can't be generalized. For example, imagine that you have set an object in your game that is a closed bottle containing a liquid, an expensive perfume which you have to deliver somewhere. You have to make it harder for the player: if the player opens the bottle and attempts to move with the bottle being open, the perfume will spill out. How do you do it with your objects manager? Just for 1 object that has a contents that gets spilled if you move with it open, you are not gonna expand your objects manager. This is the perfect thing to be done with an exception!

OpaOpa was made in a blast and exceptions are hard-coded. That's why you should avoid reading the OpaOpa sources by all means. Learn something: the OpaOpa sources stink and if you peek inside you'll stink forever. So you better delete them and then clean the surface in you hard drive where they were stored with alcohol or something. OpaOpa works greatly but it looks horrible. Just don't look at it.

We are doing things properly in this tutorial series, so we aren't gonna hardcode ANYTHING. Exceptions are just a lot of "IFs" which just change flags and values if the condition is true, way easy enough to build a fast interpreter which we can call in several points to execute several scripts.

Let's remember the basic game loop:

>     ' Main loop in pseudo-code

>     DO

>        DO

>           DO
>              parse phrase.
>              interpret phrase.
>              [
>              |
>              |]
>           LOOP UNTIL phrase is empty
>        LOOP UNTIL
>     LOOP

Now this bit should look familiar, we have used it almost in every chapter :P. Look at it: there are three places where exceptions must be checked for. In chapter 3 we talked about them extensively, but let's refresh our minds:

#### 1. Pre-description exceptions.

Those are checks that must be done "before entering" a location, i.e. just after the player moves and before the new location is described on screen. Why is this useful? I can think of many examples: for example, if you want that a room is dark so you can't see anything if you don't carry a light source that's turned on, you have to place an exception in this set. Look at the main loop structure: normally, room 10 is read from the file. The variable desc is filled with the description found in the file. Right afterwards, pre-description exceptions are ran and if you don't have the torch or you have it but it is off the desc variable is changed with a new description which tells the player that you can't see anything. The next step is showing the description. See how it works? Another situation where we could need a pre-description exception would be to add or remove an obvious exit from a location. For example, if the player wears sunglasses he could distinguish an extra location in a very sunny and shiny exterior place.

#### 2. Pre-input exceptions

Those are very similar to pre-description exceptions. If you look at the main loop structure, you'll notice how this set is placed just at the beginning of the inner loop. This set of exceptions may be used for the same kind of stuff that pre-description exceptions are used for, but don't need the player to enter a new location. For example, with the dark room problem mentioned above: what if, once in the dark room, the player turns the torch on?

#### 3. Post-Input exceptions

Those exceptions are very important. They will perform stuff according to the player's input. You want a funny reply in your game to several stupid possible player actions, you do it here. You need that a normal command acts differently (for example: open pandora's box causes a big explosion of evil, iraqis with mass destruction weapons and gay communists (big )!), you do it here. You allow the player to do specific stuff in a specific location, you do it here. For example, in The Quest for OpaOpa #1, released some time ago by aetherFox and me ( http://www.apeshell.net ), there's a location where you can swim a lake. Only in this location you can get naked and swim (I'm giving you a very important hint for this game!). Both actions are hold by two post-input exceptions.

I know you have noticed that I just CTRL+C/CTRL+V'ed this text directly from Chapter III, but I did so you don't have to look for it to re-read the explanations. That's because I'm a great guy.

Note that we'll need a different script file for each group of exceptions. At the end of the day, the one which will grow faster will be the one for Post-Input exceptions. The other two will end being used just to modify the room/objects data before things are displayed on screen. Anyway, having three different scripts to place conditions in three different point in the game loop gives us lots of flexibility and I'm pretty sure that you all will be able to do almost anything.

### Designing our language

The scripting language has to be simple yet powerful. Simple to parse, of course, and also FAST to parse. As we are just going to have conditions in our exceptions scripting language, we are designing it as a "clausal language". Every exception will be called a clausule composed of many sub-conditions joined with "AND", as explained in chapter III. Inside a clausule, the parser will be reading from the scripts file a condition each time and checking it. If it is true, the parser will keep with the next condition or with the executable code if there are no more conditions. If it is false, the parser will skip until the next clausule. It looks this way (pseudocode):

>     CLAUSULE 1:
>     If player in lid # 10
>     If player has torch
>     If torch is turned on
>        Set desc = "You can see everything clearly now... blah blah"
>        Exit parser
>     End Clausule

>     CLAUSULE 2:
>     If player in lid # 10
>        Set desc = "You can't see anything."
>     End Clausule

We designed the Ñe language according to that idea. Now check back Chapter III to read more about it. We are now coding the parser for that language!

### What we need

We need flags. Lots of them. Now I'm calling 'flags' to numeric variables, i.e. places where we can store values. A nice array will suffice. Make it shared for this module:

>     CONST MAXFLAGS = 255          ' Total number of user flags (for exceptions).

>     Dim Shared flags(MAXFLAGS) As Integer

We also need a function which breaks a sentence into words, but we already have it (remember last chapter and the funcion called Parser.parse).

And then, adding some functions to the locator manager to be able to read/write into some values, i.e. exits and descriptions. Add this code to your lm.bas file, and declare them in your lm.bi file to export them:

>     Function Loc.getMAXEXITS As Integer
>        Loc.getMAXEXITS = MAXEXITS
>     End Function

>     Function Loc.getExitWord (i As Integer) As String
>        Loc.getExitWord = X(i).w
>     End Function

>     Sub Loc.setExit (i As Integer, w As String, go As Integer)
>     	X(i).w = w
>     	X(i).go = go
>     End Sub

>     Sub Loc.setDesc (newDesc As String)
>     	desc = newDesc
>     End Sub

### More Finite State Machines!

Yeah, it is done that way. If you think of it, you'll realize that it is so natural to perform the scripts interpretation with a simple finite state machines; we already mentioned it indirectly: the interpreter might be checking conditions, or executing commands, or skipping to next clausule... See the states? A common clausule looks like this (again, refer to Chapter III for a language reference):

>     IF
>        AT 10
>        HAS 5
>     THEN
>        MSG "You feel good."
>        EXITEVAL
>     END

Our three states will be, then:

1. Waiting for IF, i.e. skipping everything until we find a new clausule.
2. Waiting for THEN, i.e. checking every condition.
3. Waiting for END, i.e. executing every command.

Our interpreter will be a big SELECT CASE with every condition, another SELECT CASE with every command, and the logic necessary to make the FSM work:

>     Function Parser.RunExceptionsFile(lid As Integer, file As String) As Integer
>     	Dim somethingDone As Integer	' flag set if something was done.
>     	Dim breakThis As Integer		' flag to exit evaluation
>     	Dim state As Integer			' our FSM
>     	Dim f As Integer				' file handle
>     	Dim t As Integer				' While loop exit condition
>     	Dim l As Integer				' lines counter
>     	Dim olid As Integer				' "other location id", auxiliary
>     	Dim foundAt As Integer
>     	Dim i As Integer

>     	Dim cmdLine As String			' command line read from file
>     	Dim cmd As String				' command extracted from cmdLine
>     	Dim oldPhrase As String

>         somethingDone = 0
>         breakThis = 0

>         ' Attempt to run commands at file located in lid

>     startOver:

>     	' Let's code our FSM:

>         State = 0

>         ' State =  0    => Waiting for IF
>         '          1    => Waiting for THEN (i.e. reading/evaluating clausules).
>         '          2    => Waiting for END  (i.e. reading/executing commands).

>         f = FreeFile: t = 0: l = 0

>         Open file For Input As #f

>         While (Not t) and (Not Eof(f))

>     		' Beware! Gotos ahead :P

>             Do
>                 Line Input #f, cmdLine
>                 l = l + 1
>                 If Eof(f) and cmdLine = "" Then Goto finSub		' Exit ASAP!
>             Loop While cmdLine = ""

>             ' Let's break the sentence into words:

>     		' This is a hack but I like reusing code:

>     		OldPhrase = Phrase 		' Save old contents.

>             Phrase = cmdline		' Remember that Parser.Parse used the shared variable
>             Parser.Parse			' Phrase.

>     		Phrase = OldPhrase		' Restore old contents.

>     		' Let's continue:

>             cmd = Ucase$(Words (0))	' The command will be on the first word in each line.
>     								' We uppercase it and assign it to the variable cmd.

>             Select case State

>                 Case 0

>     				' "Waiting for IF": basicly we do nothing but waiting for an IF. When that
>     				' happens, we change to the next state:

>                     If cmd = "IF" Then
>                         State = 1
>                     End If

>                 Case 1

>     				' "Waiting for THEN": Here we execute every condition. We can change to another
>     				' state in two different ways:

>     				' If we find a condition which evalues to "fase", we have to skip to the
>     				' next clausule, so we change to State 0 ("waiting for IF").

>     				' If we find the command "THEN" that means that every condition was checked
>     				' so we change to State 2 ("waiting for END") to begin executing the exception.

>                     Select Case cmd

>                         Case "EQF"

>     						' I'll comment just the first one, the next ones are in the same fashion
>     						' and I think you can figure them out:

>                             If flags (Val(Words (1))) <> Val(Words (2)) Then State  = 0

>     						' We have found the EQF condition. EQF x y is "true" if flag "x" equals "y".
>     						' (x and y being numbers, i.e. EQF 0 1 will be true if flags (0) = 1).
>     						' As we have called Parse.Parse, "EQF" will be in Words (0), "x" will be
>     						' in Words (1) and "y" will be in Words (2). So we just compare. If
>     						' the value of flags(x) is not equal to "y", then the condition fails and
>     						' we jump to State 0.

>                         Case "LTF"
>                             If flags(Val(Words(1))) >= Val(Words(2)) Then State = 0

>                         Case "GTF"
>                             If flags(Val(Words(1))) <= Val(Words(2)) Then State = 0

>                         Case "LEF"
>                             If flags(Val(Words(1))) > Val(Words(2)) Then State = 0

>                         Case "GEF"
>                             If flags(Val(Words(1))) < Val(Words(2)) Then State = 0

>                         Case "NEF"
>                             If flags(Val(Words(1))) = Val(Words(2)) Then State = 0

>                         Case "AT"
>                             If lid <> Val(Words(1)) Then State = 0

>                         Case "HAS"

>     						' This has to do with the objects manager so it calls to the objects manager.
>     						' Obj.Visible will be explained in the next chapter. Basicly this jumps to State
>     						' 0 if an object is not in the inventory.

>                             Obj.Visible 0, Val(Words(1)), olid
>                             If olid = -1 Then State = 0

>                         Case "SEES"
>                             Obj.Visible lid, Val(Words(1)), olid
>                             If olid = -1 Then State = 0

>                         Case "ISCNT"

>     						' This set will also call the objects manager, as it is for checking individual
>     						' flags of each objects. The Obj.GetFlag (i) just returns the flags of object #i
>     						' This just checks if bit "0" is set. Remember that we defined that bit "0" will
>     						' be set for containers. If it is "0", the object is not a container so the
>     						' condition fails and we skip:

>                             If (Obj.GetFlag(Val(Words(1))) And 1) = 0 Then State = 0

>                         Case "ISOPEN"
>                             If (Obj.GetFlag(Val(Words(1))) And 2) = 0 Then State = 0

>                         Case "ISLIGHT"
>                             If (Obj.GetFlag(Val(Words(1))) And 4) = 0 Then State = 0

>                         Case "ISTRND"
>                             If (Obj.GetFlag(Val(Words(1))) And 8) = 0 Then State = 0

>                         Case "ISAT"

>     						' Another objects manager function: this one returns the location where the
>     						' passed object is. ISAT x y is true if object x is at lid y, so if it is not,
>     						' we skip:

>                             If Obj.GetLoc(Val(Words$(1))) <> Val(Words(2)) Then State = 0

>                         Case "VERBWAS"

>     						' This set is for checking which exact "important words" the player used.
>     						' Remember that verb, noun1, noun2, adj1 and adj2 were module-level shared
>     						' variables.

>                             If verb <> Words(1) Then State = 0

>                         Case "NOUN1WAS"
>                             If noun1 <> Words(1) Then State = 0

>                         Case "NOUN2WAS"
>                             If noun2 <> Words(1) Then State = 0

>                         Case "ADJ1WAS"
>                             If Adj1 <> Words(1) Then State = 0

>                         Case "ADJ2WAS"
>                             If Adj2 <> Words(1) Then State = 0

>                         Case "THEN"
>                             State = 2

>                     End Select

>                 Case 2

>     				' Waiting for END: Here we just execute every command we find until
>     				' we get to the "END".

>                     Select Case cmd$
>                         Case "SETF"

>                             flags(Val(Words$(1))) = Val(Words(2))

>                         Case "SETCNT"

>     						' This command makes an object a container, i.e. it modifies its flags.
>     						' We have to call to functions from the objects manager to do this.
>     						' "Obj.SetFlag x, y" sets object x's flag to y:

>                             if Val(Words(2)) = 1 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) Or 1)

>                             ElseIf Val(Words(2)) = 0 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) And Not 1)

>                             Else
>                                 Print "** Warning! Invalid value in "; file; " at line "; l

>                             End If

>                         Case "SETOPEN"

>                             if Val(Words(2)) = 1 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) Or 2)

>                             ElseIf Val(Words(2)) = 0 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) And Not 2)

>                             Else
>                                 Print "** Warning! Invalid value in "; file; " at line "; l

>                             End If

>                         Case "SETLIGHT"

>                             if Val(Words(2)) = 1 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) Or 4)

>                             ElseIf Val(Words(2)) = 0 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) And Not 4)

>                             Else
>                                 Print "** Warning! Invalid value in "; file; " at line "; l

>                             End If

>                         Case "SETTRND"

>                             if Val(Words(2)) = 1 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words(1))) Or 8)

>                             ElseIf Val(Words(2)) = 0 Then
>                                 Obj.SetFlag Val(Words(1)), (Obj.GetFlag(Val(Words$(1))) And Not 8)

>                             Else
>                                 Print "** Warning! Invalid value in "; file; " at line "; l

>                             End If

>                         Case "SETAT"

>     						' Same again: "Obj.setLoc x, y" sets object x to lid y:

>                             Obj.SetLoc Val(Words(1)), Val(Words(2))

>                         Case "TELEPORT"
>                             lid = Val(Words(1))

>                         Case "MSG"

>     						' The Misc.WordWrap function is the one we'll use to display text. It
>     						' just prints the passed string to screen doing word-wrapping.

>                             Misc.WordWrap Words(1)

>                         Case "EXITEVAL"

>     						' We talked about this in Chapter III.

>                             Goto finSub

>                         Case "STARTOVER"

>     						' Might be useful re-starting the parsing:

>                             Close #f
>                             Goto startOver

>                         Case "ALSOCOMMON"

>                             breakThis = -1

>                         Case "ADDEXIT"

>     						' To add an exit to the current lid we have to call the
>     						' location manager.

>                             ' Check that exit is not already present:

>                             foundAt = -1

>                             For i = 0 To Loc.getMAXEXITS
>                                 If rtrim$(Loc.getExitWord(i)) = ltrim$(rtrim$(Words(1))) Then
>                                     foundAt = i
>                                     Exit For
>                                 End If
>                             Next i

>                             ' Set it otherwise:

>                             If foundAt = -1 Then
>                                 For i = 0 To Loc.getMAXEXITS
>                                     If rtrim$(Loc.getExitWord(i)) = "" Then
>     									Log.setExit i, Words(1), Val(Words(2))
>                                         Exit For
>                                     End If
>                                 Next i
>                             End If

>                         Case "RMVEXIT"
>                             For i = 0 To Loc.getMAXEXITS
>                                 If rtrim$(Log.getExitWord(i)) = ltrim$(rtrim$(Words(1))) Then
>     								log.setExit i, "", 0
>                                     Exit For
>                                 End If
>                             Next i
>                         Case "SETDESC"

>     						Loc.SetDesc Words(1)

>                         Case "END"

>     						' Found an "END", so we go back to state "0".

>                             State = 0
>                             If Not breakThis Then somethingDone = -1
>                             breakThis = 0

>                     End Select
>             End Select
>         Wend

>     finSub:
>         Close #f

>         Parser.RunExceptionsFile = somethingDone

>     End Function

### What the hell was that? Are you crazy?

Yes, I am, but fear not. I'll explain what I've done. For you to understand what the hell I'm doing in that Function, let me tell you a couple of things about interpreting scripts. The following technique will help you writing any kind of parsers as long as you have clear in your mind what you need and what kind of language you are coding.

Every language out there follows a set of rules, called "grammar". Like in the English language, the grammar specifies where every possible element in the sentence is located, and how. In our case, the grammar we use is pretty simple:

>     script :: clausules

>     clausules :: clausule clausules |

>     clausule :: IF conditions THEN commands END

>     conditions :: condition conditions |

>     commands :: command commands |

>     condition :: EQF | GTF | LTF | GEF | ... etc

>     command :: SETF | SETCNT | SETOPEN | ... etc

What the above strange code says is that we have a script, which is composed by clausules. Then, "clausules" are a list of "clausule" (that's what "clausules :: clausule clausules | " mean, there's some sort of recursion there which says basicly that "clausules" is defined as a "clausule" and more "clausules", OR (that's what "|" means) it is defined , which would be the base case).

Each "clausule" is defined as "IF conditions THEN commands END". Note how "conditions" or "commands" are defined like "clausules", i.e. they are lists of "condition" and "command", respectively. Then "condition" is defined as EQF, or GTF, etcetera, and "command" is defined as "SETF", or "SETCNT", or "SETOPEN" ...

There are lots of techniques to be able to build a true interpreter from a grammar, but they are out of the scope of this tutorial (heh - compilers theory is quite, quite complex :P). Our language is simple enough for the interpreter to be coded "by hand". We just have to look carefully at the grammar and identify the main features. First of all, our scripts will be composed by just one kind of constructions: clausules. So let's look at clausules. There are three fixed "tokens" in the rule "clausule": IF, THEN and END, plus two "variable" tokens: conditions and commands, which happen to be lists. If we look at the grammar again, we realise that, in fact, our script will be a sequence like this:

>     IF conditions THEN commands END IF conditions THEN commands END ...

As "conditions" and "commands" are variable, plus "conditions" can be interrupted if any of them fails, we have to focus on the fixed parts, i.e. IF, THEN and END. That gives us a clue to build our FSM. Naturally, IF, THEN and END should spawn three different states. In a perfect world:

>     STATE 0:
>        read line
>        If you find "IF" go to STATE 1 else keep on STATE 0

>     STATE 1:
>        read line
>        If you find "THEN" go to STATE 2 else keep on STATE 1

>     STATE 2:
>        read line
>        If you find "END" go to STATE 0 else keep on STATE 2

Looking at the grammar, we notice that "conditions" are always between IF and THEN, so they should be taken care of in STATE 1. In the same way, "commands" are always between THEN and END, so they should be taken care of in STATE 2. We can refine our FSM using the new information:

>     STATE 0:
>        read line
>        If you find "IF" go to STATE 1 else keep on STATE 0

>     STATE 1:
>        read line
>        If you find a proper "condition", evaluate it.
>        If you find "THEN" go to STATE 2 else keep on STATE 1

>     STATE 2:
>        If you find a proper "command", execute it.
>        If you find "END" go to STATE 0 else keep on STATE 2

Okay, now this is complete sintactically, but not semantically. There's a semantic aspect that is not yet taken in account: if a condition being read happens to evaluate to "false", the commands section should not be executed at all. What does that mean, in our FSM? Just that if a condition fails, we jump directoy to STATE 0, i.e., we skip the section between THEN and END. So our FSM is completed in this way:

>     STATE 0:
>        read line
>        If you find "IF" go to STATE 1 else keep on STATE 0

>     STATE 1:
>        read line
>        If you find a proper "condition", evaluate it. If it is false, go to STATE 0.
>        If you find "THEN" go to STATE 2 else keep on STATE 1

>     STATE 2:
>        If you find a proper "command", execute it.
>        If you find "END" go to STATE 0 else keep on STATE 2

The above Function Parser.RunExceptionsFile does exactly what the FSM tells. The current state is stored in the integer variable "state". There's a main loop which reads a line from the file ('cause that is done in every state), and then a "Select Case" structure to act according to which state we are at. Note that in Case 0 (state 0) we do nothing but detecting if we have read the word "IF", and in such case we jump to state 1. In Case 1, we just check if the condition just read from file is false, in such case we jump to state 0. If we find "THEN" we jump to state 2. In Case 2, we read commands and execute them until we find "END" and jump again to state 0. Everything ends when the file runs out of lines.

If you still don't understand it I suggest you to re-read this carefully. If you still can't understand it, you can whether give up and consider this function as a working black box, or you can bug me in the forums .

### Now that you are dizzy

... It's time to say goodbye until the next chapter, when we'll explain the objects manager and we'll close the circle Until then I hope you don't hate me more than yesterday after this piece of stone of a tute :P

About the lots of code snippets... Well, the last chapter will feature the whole engine put together, ready to be used. So, by the moment, just focus on learning how things work. It's very possible that there are bugs and miscarriages in the sources I'm posting, so you better wait for the final chapter

Check out the first five editions of Na_th_an's I.F. series: Chapter 1, Chapter 2, Chapter 3, Chapter 4, Chapter 5

## Using WX-C In FreeBasic - Part 2

### Written by dumbledore

if you are skimming at the moment, here's a quick summary of this article: OMG YOU CAN PRINT IN FREEBASIC !!! (with colors and usb printers, oh my.)

### INTRODUCTION

for the second installment of wx-c tutorials, i've decided (by popular request) to explain how to use wx-c to interface with the printer. since fb has no direct way to print things, this can be a good solution if you're looking for a way to print things out. be aware that this method is not a replacement for qb's lprint, but is far more flexible.

### 1. INITIALIZING

this time i'm going to throw some code at you, assuming you have a basic understanding of how wx-c works (if not, refer back to my first tut)

>     '$include: "wx-c/wx.bi"
>     #define wxCLOSE_BOX &h1000
>     #define FALSE 0
>     #ifndef TRUE
>     #   define TRUE NOT(FALSE)
>     #endif
>     option escape
>     option explicit

next, we'll have to use a (possibly) scary number of functions ;)

>     declare sub App_OnInit( )
>     declare sub App_OnExit( )
>     declare sub button0_event( byval event as wxEvent ptr, byval iListener as long )
>     declare function onBeginDocument( byval as integer, byval as integer ) as integer
>     declare sub onEndDocument( )
>     declare sub onBeginPrinting( )
>     declare sub onEndPrinting( )
>     declare sub onPreparePrinting( )
>     declare function hasPage( byval as integer ) as integer
>     declare function onPrintPage( byval as integer ) as integer
>     declare sub getPageInfo( byval as integer ptr, byval as integer ptr, _
>                              byval as integer ptr, byval as integer ptr )

if you're staring at that and going "omgwtfbbq, where the heck did he get all those parameters from!?", the answer is actually pretty simple: i borrowed them from the wx-c headers. doing this is (contrary to popular belief :P) a good habit, since there are no official docs on using wx-c.

>     '(taken from inc/wx-c/printer.bi)
>     type Virtual_NoParams as sub ( )
>     type Virtual_ParamsInt as function (byval as integer) as integer
>     type Virtual_OnBeginDocument as function (byval as integer, byval as integer) as integer
>     type Virtual_GetPageInfo as sub (byval as integer ptr, byval as integer ptr, byval as integer ptr, byval as integer ptr)

we will need functions declared like this to use in the registervirtual() function of the printer, or else the whole program will crash (!).

now we need to declare our globals:

>     dim shared wx_app as wxapp ptr,wx_frame as wxframe ptr, myprintout as any ptr

### 2. CREATING THE FRAME

this should look terribly familiar, if you've read the first tut, so i'm not going to comment on this particular block of code.

>     sub App_OnInit( )
>         wx_frame = wxFrame( )
>         wxFrame_Create( wx_frame, 0, -1, "My WX-C Project", wxSize( 440, 312 ), _
>                             wxSize( 378, 384 ), wxDEFAULT_FRAME_STYLE or wxCLOSE_BOX xor _
>                                                     wxMAXIMIZE_BOX xor wxRESIZE_BORDER, _
>                             "frame" )
>         wxWindow_SetBackgroundColour( wx_frame, wxSystemSettings_GetColour( 15 ) )

>         ''
>         '' create widget button0
>         ''
>         dim as wxButton ptr button0
>         button0 = wxButton( )
>         wxButton_Create( button0, wx_frame, -1, "button0", wxSize( 0, 0 ), _
>                              wxSize( 370, 350 ), 0, 0, 0 )

this next part is something new i'm introducing you to rather quickly: events. the basic idea is that when the event you specify occurs, the widget's assigned "handler function" aka "callback function" is called to handle the event. in this case, we're telling wx-c that when we click the button, we want the function "button0_event" to be executed. (visual wx-c developer does that for you ;), but you need the latest cvs version :*( )

>         wxEvtHandler_Proxy( button0, @button0_event )
>         wxEvtHandler_Connect( button0, wxEvent_EVT_COMMAND_BUTTON_CLICKED( ), -1, -1, 0 )

and, some more repeat stuff from last time.

>         wxWindow_SetAutoLayout( wx_frame, TRUE )
>         wxWindow_Show( wx_frame, 1 )
>     end sub

>     sub App_OnExit( )
>         wxapp_onexit( wx_app )
>     end sub

there, that should do it for the frame. now time for the printing! :-O

### 3. THE PRINTING!

ok, here's the function for the button event (don't start running in circles screaming, i'll explain afterwards :P)

>     sub button0_event( byval event as wxEvent ptr, byval iListener as long )
>         select case wxEvent_GetEventType( event )
>             case wxEvent_EVT_COMMAND_BUTTON_CLICKED
>                 ''stuff
>                 myprintout = wxPrintout( "some title or other ;P" )
>                 wxPrintout_RegisterVirtual( myprintout, _
>                                             @onBeginDocument, _
>                                             @onEndDocument, _
>                                             @onBeginPrinting, _
>                                             @onEndPrinting, _
>                                             @onPreparePrinting, _
>                                             @hasPage, _
>                                             @onPrintPage, _
>                                             @getPageInfo )
>                 dim as wxPrinter ptr myprinter
>                 myprinter = wxPrinter( 0 )
>                 wxPrinter_Print( myprinter, wx_frame, myprintout, TRUE )
>         end select
>     end sub

the proto is pretty straightforward, wx-c will automatically pass both a wxEvent pointer and an ilistener to any event-handler function, which can come in very handy when handling > 1 function. the select case stuff really isn't necessary in this example since we only have one event being handled, but vwx-cdev puts it there by default, and i'm not one to argue with myself ;). we want to declare myprintout as a wxPrintout pointer because that's what wx-c takes for printing ;P the title specified there will appear in a little "printing" window wx-c automatically pops up when your document is being sent to the printer. the registervirtual command is wx-c's sick and cruel way of making us do more work than we should have to ;) since most of the functions already exist, but with different numbers of parameters, so we have to manually override all of them in order to stop the program from crashing all over the place :*(. the next three lines of code initialize the printer with the default vars (hence the null), and tell it to print out our document. the wx_frame part tells it to make the print dialog a child of our main frame (aka wx_frame ;) ), and the TRUE tells it to make a dialog asking for the printer and number of copies, etc. specifying false only works if you send it the data in the constructor instead of null i think, basically that means don't change the true to false unless you want crashes ;P

the next bit of code is basically just placeholder callbacks, because wx-c is too dumb to assign automatic functions, which is kind of annoying :*(

>     function onBeginDocument( byval a as integer, byval b as integer ) as integer

>         function = wxPrintout_OnBeginDocument( myprintout, a, b )

>     end function

>     sub onEndDocument( )

>         wxPrintout_OnEndDocument( myprintout )

>     end sub

>     sub onBeginPrinting( )

>         wxPrintout_OnBeginPrinting( myprintout )

>     end sub

>     sub onEndPrinting( )

>         wxPrintout_OnEndPrinting( myprintout )

>     end sub

>     sub onPreparePrinting( )

>         wxPrintout_OnPreparePrinting( myprintout )

>     end sub

>     function hasPage( byval a as integer ) as integer

>         function = wxPrintout_HasPage( myprintout, a )

>     end function

>     sub getPageInfo( byval a as integer ptr, byval b as integer ptr, _
>                      byval c as integer ptr, byval d as integer ptr )

>         wxPrintout_GetPageInfo( myprintout, a, b, c, d )

>     end sub

(yes, it is an annoyingly large amount of code, but in the future if you want to override wx-c's default values and uses of these functions, this way you'll get flexibility.)

now, finally, (drumroll please :P), the "only" sub, er, function that we actually care about...

>     function onPrintPage( byval a as integer ) as integer

>         dim as wxDC ptr printoutdc
>         printoutdc = wxPrintout_GetDC( myprintout )
>         wxDC_SetTextForeground( printoutdc, wxColour_ctorByParts( 0, 0, 255 ) )
>         wxDC_DrawText( printoutdc, "printing test", 5, 5 )
>         return -1

>     end function

coincidentally, there is no corresponding wx-c default callback for this function, so i've decided we'll just have to return true on success ;). yes, all that work and this is really the only part that does anything :P.

the first step to drawing stuff to the print page is getting the actual page. we accomplish this by getting the printout's dc, which is special and different from normal dcs because its default colors are optimized for, gasp, printing! :-O. To show off our super color capabilities, we change the text color to blue, how often did you see lprint generate blue text? :P and then we draw the text to the page. you can use any dc function on the print page. a complete list of supported dc functions is in the dc header file at inc/wx-c/dc.bi. most of the functions speak for themselves. yes, the drawbitmap function does allow you to print pictures. no, you cannot have my children. :P

### 4. FINISHING UP

the rest of the code you should already know from the first tut.

>     wx_app = wxApp( )
>     wxApp_RegisterVirtual ( wx_app, @App_OnInit, @App_OnExit)
>     wxApp_Run(0,0)
>     end

and that's all there is to it.

### CONCLUSION

so as you have seen, wx-c can handle far more printing flexibility than old man qbasic. with the example code i provided in this tut, we accomplished colored text printing on any generic printer, it worked flawlessly on my usb printer. this means printing may again see its rise in usefulness, since we are no longer limited to the parallel port. as a parting gift though, i'll provide a function that should help convert those old lprint programs from qb.

>     function onPrintPage( byval a as integer ) as integer

>       dim as wxDC ptr printoutdc
>       printoutdc = wxPrintout_GetDC( myprintout )
>       dim as string mystr
>       for y = 0 to ( len( offscr ) + 1 ) / 80 - 1
>         wxDC_DrawText( printoutdc, mid$( offscr, y * 80, 80 ), 0, y * 100 )
>       next
>       return -1

>     end function

is the basic function, replace the one in the example with that. you'll want a global string called "offscr" which contains the current contents of the screen, what you want to do is do a cls, the change all your lprints to prints, then run this before calling the print function:

>       offscr = ""
>       dim as integer x, y
>       for y = 0 to csrlin - 1
>         for x = 0 to 79
>           offscr += CHR$( iif( screen( y + 1, x + 1 ) = 0, 32, screen( y + 1, x + 1 ) ) )
>         next
>       next
>       cls

the last thing you'll want to do is take your main code and stick it inside the app_oninit() function from the example (get rid of the frame and that ugly button though) and be sure to issue an "end" command before app_oninit completes. it may be hackish, but i converted a ~1000 line qb prog heavily using lprint to fb this way with few problems. (meaning it can be done!) ask on the fb forums if you experience severe problems or if you can't seem to figure any of this out :P. until next time,
-dumbledore

### CODE LISTING

>     '$include: "wx-c/wx.bi"
>     #define wxCLOSE_BOX &h1000
>     #define FALSE 0
>     #ifndef TRUE
>     #   define TRUE NOT(FALSE)
>     #endif
>     option escape
>     option explicit
>     declare sub App_OnInit( )
>     declare sub App_OnExit( )
>     declare sub button0_event( byval event as wxEvent ptr, byval iListener as long )
>     declare function onBeginDocument( byval as integer, byval as integer ) as integer
>     declare sub onEndDocument( )
>     declare sub onBeginPrinting( )
>     declare sub onEndPrinting( )
>     declare sub onPreparePrinting( )
>     declare function hasPage( byval as integer ) as integer
>     declare function onPrintPage( byval as integer ) as integer
>     declare sub getPageInfo( byval as integer ptr, byval as integer ptr, _
>                              byval as integer ptr, byval as integer ptr )

>     dim shared wx_app as wxapp ptr,wx_frame as wxframe ptr, myprintout as any ptr

>     sub App_OnInit( )
>         wx_frame = wxFrame( )
>         wxFrame_Create( wx_frame, 0, -1, "My WX-C Project", wxSize( 440, 312 ), _
>                             wxSize( 378, 384 ), wxDEFAULT_FRAME_STYLE or wxCLOSE_BOX xor _
>                                                     wxMAXIMIZE_BOX xor wxRESIZE_BORDER, _
>                             "frame" )
>         wxWindow_SetBackgroundColour( wx_frame, wxSystemSettings_GetColour( 15 ) )

>         ''
>         '' create widget button0
>         ''
>         dim as wxButton ptr button0
>         button0 = wxButton( )
>         wxButton_Create( button0, wx_frame, -1, "button0", wxSize( 0, 0 ), _
>                              wxSize( 370, 350 ), 0, 0, 0 )
>         wxEvtHandler_Proxy( button0, @button0_event )
>         wxEvtHandler_Connect( button0, wxEvent_EVT_COMMAND_BUTTON_CLICKED( ), -1, -1, 0 )

>         wxWindow_SetAutoLayout( wx_frame, TRUE )
>         wxWindow_Show( wx_frame, 1 )
>     end sub

>     sub App_OnExit( )
>         wxapp_onexit( wx_app )
>     end sub

>     sub button0_event( byval event as wxEvent ptr, byval iListener as long )
>         select case wxEvent_GetEventType( event )
>             case wxEvent_EVT_COMMAND_BUTTON_CLICKED
>                 ''stuff
>                 myprintout = wxPrintout( "some title or other ;P" )
>                 wxPrintout_RegisterVirtual( myprintout, _
>                                                    @onBeginDocument, _
>                                                    @onEndDocument, _
>                                                    @onBeginPrinting, _
>                                                    @onEndPrinting, _
>                                                    @onPreparePrinting, _
>                                                    @hasPage, _
>                                                    @onPrintPage, _
>                                                    @getPageInfo )
>                 dim as wxPrinter ptr myprinter
>                 myprinter = wxPrinter( 0 )
>                 wxPrinter_Print( myprinter, wx_frame, myprintout, TRUE )
>         end select
>     end sub

>     function onBeginDocument( byval a as integer, byval b as integer ) as integer

>         function = wxPrintout_OnBeginDocument( myprintout, a, b )

>     end function

>     sub onEndDocument( )

>         wxPrintout_OnEndDocument( myprintout )

>     end sub

>     sub onBeginPrinting( )

>         wxPrintout_OnBeginPrinting( myprintout )

>     end sub

>     sub onEndPrinting( )

>         wxPrintout_OnEndPrinting( myprintout )

>     end sub

>     sub onPreparePrinting( )

>         wxPrintout_OnPreparePrinting( myprintout )

>     end sub

>     function hasPage( byval a as integer ) as integer

>         function = wxPrintout_HasPage( myprintout, a )

>     end function

>     function onPrintPage( byval a as integer ) as integer

>         dim as wxDC ptr printoutdc
>         printoutdc = wxPrintout_GetDC( myprintout )
>         wxDC_SetTextForeground( printoutdc, wxColour_ctorByParts( 0, 0, 255 ) )
>         wxDC_DrawText( printoutdc, "printing test", 5, 5 )
>         return -1

>     end function

>     sub getPageInfo( byval a as integer ptr, byval b as integer ptr, _
>                      byval c as integer ptr, byval d as integer ptr )

>         wxPrintout_GetPageInfo( myprintout, a, b, c, d )

>     end sub

>     wx_app = wxApp( )
>     wxApp_RegisterVirtual ( wx_app, @App_OnInit, @App_OnExit)
>     wxApp_Run(0,0)
>     end

Download a copy of this tutorial, or visit dumbledore's site.

## Music Composition, Part 3

### Written by Matt2Jones

Click-click Click-click Click-click Click-click

### Part IV - Harmony

Author's Note: I suggest you glance back over the first two articles before we move on, to refresh your memory.

> - Part One - Issue #7
> - Part Two - Issue #8

### Preamble

Harmony, in this situation anyway, means playing notes at the same time, and having them sound good together. In the previous tutorials I showed you how to work out which notes are in a chord, and therefore will definatly sound good together, and in this section I will show you how to use the knowlage of chords that you have to beef up the sound of a peice of music.

Lets start with the melody:

Now I'm not going to explain just yet where I came up with this. Suffice it is to say it was somewhere in my proverbial annal regions... And really thats more then you need to know.

This is the melody line, you will notice that it is in the key of C Major (the first note of the first bar is on the third space, which is C), and the key signature shows no sharps or flats (the Key signature of C Major has no sharps or flats). It is written for the treble clef, which basically means it sounds high pitched (if you were playing it on the piano you'd use your right hand), and it is in 4/4 time.

Now, when I call this the melody what I mean is that this is the peice of music you would hum to yourself if you were thinking of the song it's from, or if there were lyrics to the song this would be the tune that the lyrics would be sung to. In a concise...wrong definition melody is the song.

What this tutorial will show you how to do is write chords which harmoniously accompany the melody, to make it sound fuller.

### One More Thing...

The Basic method for doing this is extreemly simple, and there is only one new peice of information you need to know in order to apply it, and that is

"In 4/4 time the stresses are on the First and Third beats"

If you think of this in terms of marching drums it equates to a sound like ONE two THREE four, or DUN dun DUN dun or LOUD quiet LOUD quiet or STRESSED unstressed STRESSED unstressed, but for writing chords it is best to understand the phrase to mean IMPORTANT unimportant IMPORTANT unimportant.

In a nutshell when writing chords for music the only notes you need to pay attention to you are the IMPORTANT ones, the ones of the first and third beats.

### Musikscreiben

So lets take a look at the Melody again:

and apply the new rule IMPORTANT unimportant IMPORTANT unimportant.

We're going to start with the second bar, because it is allot more straight forward.

In the second bar the note on the first beat is the crotchet on E, so the first important note is "E" (write that down). The note G is on the second beat, but seeing as that is unstressed, and so unimportant, we don't need to take it into account (ie. Don't write G down). G is followed by E again, but seeing as both these notes are Quavers, and only 1/2 a beat long, it still falls under the jurisdiction of the second, unimportant and unstressed, beat, and can so be safely ignored.

As you can see the Quaver note 'D' is on the third beat of Bar 2, and seeing as the third note of a 4/4 bar of music is stressed, and therefore important, the note "D" is important, and should be written down. Following the quaver on "D" a half beat later is another quaver on D, this makes our job allot easier because as the two notes are the same, because we really only have to deal with the single note "D".

Now we have our two important notes, E for the first beat and D for the third. That was the hard part.

### The Easy Part

Now all we have to do is look at every Chord in the key we're in (In this case C Major)*, and pick a chord, absolutely any chord, with the important note in it.

So lets go:

The Chords in the Key of C Major are:

>     G  A  B  C  D  E  F
>     E  F  G  A  B  C  D
>     C  D  E  F  G  A  B
>     I ii iii IV V vi VII

You needn't worry about Major or Minor chords for the time being, a chord is a chord.

Now, our first important note is "E", so lets list every chord in the key of C Major with "E" in it.

The first is obvious, chord iii, or chord "E" minor as it is usualy known. Others include:
Chord I, Chord CEG, or "C" major.
Chord vi, Chord ACE, or "A" minor.

Now, as long as a chord has the important note in it somewhere is will sound good if played alongside the melody for the beat the note is played in. So when we play the first beat of the second bar, we can also safely play any of the three chords we've picked, and it will sound fucking class.

* look back over previous tutorials if you can't remember how, its all there in patronising detail!!!!!!11111

Now we move on to the second important note, the one on the third beat. Its a "D". Same as before, list every chord in the key of C major -

>     G  A  B  C  D  E  F
>     E  F  G  A  B  C  D
>     C  D  E  F  G  A  B
>     I ii iii IV V vi VII

Pick out all the chords with D in them:

> Chord ii, Chord DFA or Chord D minor
> Chord V, Chord GBD or Chord G major
> Chord VII, Chord BDF or Chord B diminished

And play any of these alongside the melody for the third beat of the bar to fill out the musical sound.

Now try doing the same to the first bar, and see what chords you came up with.

...

If you got Chord I, Chord IV or Chord vi for the first beat then you've understood what I explained to you, and picked out every chord in the Key of C major with the note C in it (as C was the note on the first beat of the bar).

Now, once you get to the second important beat, the third beat, you're going to run into some problems:

A Closer Look...

The note on the third beat is an "E", but it lasts for only a half a beat (because its a quaver), and unlike in Bar two the following note is neither a quaver, or the same note, it is in this case a "D". This is not exactly a problem, because the music would still sound fine if you applied the formula explained above, but I want to show you how it is possible to fuck with the convention to acheive a better sound, because in the end everything I can learn you (yes that was a joke) makes listenable but boring music, that's extreemly formulaic, and the only way to make good music is to break the rules I've presented.

So look again at the picture, and realise that though the first note in the third beat is an E, the note played most often throughout the rest of the bar is D. Now wouldn't it make more sense (seeing as we're writing harmony) for our chords to sound harmonious with as much as the bar as possible? (if your stuck for an answer, I suggest going with 'yes').

So it would be my personal preferance to take the note 'D' as the most important note for the third beat, even though, and I stress, IT IS PERFECTLY OKAY TO STICK WITH "E" INSTEAD.

Author's Note: I had to reword that sentence for fear of sounding like a drug pusher.

And that actually brings us to a nice end to this article. I had intended to show you how to score the chords once you've chosen them, but I'm starving and the deadline was yesterday, so I'm going to hoist this off to pete straight away. These will continue every month from now on, now that I've finished with School forever.

This is M2j saying, go fuck yourself, QBXP
Yes, I did just see anchorman, how can you tell?

Download a copy of this tutorial (RTF format).

## Useful QBasic / QuickBasic Algorithms

### Written by Edward F. Moneo

### TABLE OF CONTENTS

1. INTRODUCTION
2. DETERMINE IF A NUMBER IS A POWER OF 2
3. GENERATE A GRAY CODE PATTERN
4. COMPUTE THE NEXT MULTIPLE
5. COMPUTE THE NEAREST MULTIPLE
6. ROUNDING NUMBERS
7. INPUT ONE AND ONLY ONE CHARACTER
8. REPRESENT A NUMBER AS BINARY BITS
9. BIT OPERATIONS
10. CENTIGRADE/FAHRENHEIT CONVERSION
11. GENERATE A RANDOM NUMBER
12. EUCLID'S ALGORITHM FOR GREATEST COMMON DIVISOR

### 1. INTRODUCTION

The following is a collection of algorithms or proven methods for solving common problems. Before you incorporate any of these into your programs, it is recommended that you fully understand the code, and that you test the algorithm with the range of numbers that you intend using. You will notice that for the most part, with few indicated exceptions, there are no type declarations on the variables used, and therefore, as a default, integer variables are assumed, and the logic has been tested using integers. Also, with few indicated exceptions, the variables are assumed to be positive numbers.

It is important to note that many of the following algorithms were chosen as the best available under intensive scrutiny and testing by members of the Qbasicnews and QBNZ forums.

NOTE: Credit is given for code developed by other programmers. If no credit is indicated, the code was developed by the author.

### 2. DETERMINE IF A NUMBER IS A POWER OF 2:

> CREDIT: Xhantt of Qbasicnews.
> GIVEN: N is the positive number in question.
> LOGIC:

> > When you AND a number which is a power of 2
> > with the number-1, which would be all 1 bits,
> > then if the result is zero (because no other bits were found),
> > then the number must be a power of 2.

> CODE:

> >     if (N>0) and ((N and (N-1))=0) then print N; " is a power of 2"

### 3. GENERATE A GRAY CODE PATTERN:

> CREDIT: author unknown
> Gray Code, named after Frank Gray of Bell Labs, is a series of bytes or words where each byte/word in the series differs from the preceding BY ONLY ONE BIT. Example: 0, 1, 3, 2, 6, 7. These patterns have been used for testing logic circuits, communication transmissions, etc.
> GIVEN: Generate a Gray Code pattern for values from 0 to 255.
> CODE:

> >        for x=0 TO 255
> >             GRAY = x XOR (INT(x/2))
> >             rem ...Here you print or output successive Gray Code values in GRAY.
> >        next x

### 4. COMPUTE THE NEXT MULTIPLE:

> GIVEN: Given a positive number N, compute the NEXT multiple of X. Result to R.
> EXAMPLE #1: Given 47, compute the next multiple of 5, which is 50.
> EXAMPLE #2: Given 50, compute the next multiple of 5, which is 55.
> CODE:

> >     R = int((N+X)/X)*X

### 5. COMPUTE THE NEAREST MULTIPLE:

> GIVEN: Given a positive number N, compute the NEAREST multiple of X. Result to R.
> Note: Nearest multiple means that if N is already a multiple of X, don't move up to next multiple. This is kind of like rounding; e.g., round to nearest $5. If already $5, leave it alone.
> EXAMPLE #1: Given 47, compute the nearest multiple of 5, which is 50.
> EXAMPLE #2: Given 50, compute the nearest multiple of 5, which is 50.
> CODE:

> >     R = int((N+X-1)/X)*X

### 6. ROUNDING NUMBERS (POSITIVE OR NEGATIVE):

> CREDIT: Oracle of Qbasicnews and QBNZ.
> The purpose is to round positive or negative numbers to the nearest whole number. The standard convention of "half-adjusting" by a rounding factor of .5 is used. Notice that positive numbers must be rounded up, and negative numbers are rounded down, that is, to a greater negative number.
> NOTE: If you do INT(123.9) you will get 123. However, if you do INT(-123.9) you will get -124. This is the documented method of how the INT works in QB, which in the case of the INT(-123.9), is NOT what we want, since we want -123.
> The following code takes the above conditions into consideration.
> * The absolute or ABS assures that the number to work with is positive.
> * This positive number is rounded by the rounding factor of "+.5".
> * The integer value INT is taken on the above positive result.
> * The sign of the original input number is restored by multiplying by the sign or SGN which is 1 for positive, -1 for negative, and 0 for zero.
> GIVEN:
> * N is the number to be rounded. Obviously, since it can have decimals, it must have a type declaration of single or double floating point. We will define it as single (!) for this example.
> * R will be the resultant rounded whole number.
> CODE:

> >     R = SGN(N!) * INT(ABS(N!) + .5)

### 7. INPUT ONE AND ONLY ONE CHARACTER:

> GIVEN: With the following routine, we want to input only one character, and if the user enters more than one character, we want to get rid of the extra characters.
> We get rid of the extra characters in order that they will not be processed later by any code performing an input or an inkey$. Example: If we ask the user for a yes/no answer and prompt him to enter Y or N, he could by error type in NO. If we don't get rid of the extra O, then it will be given as input to the next prompt. * Input the one character into TheKey$
> CODE:

> >         DO
> >           TheKey$=INKEY$
> >         LOOP WHILE TheKey$=""
> >         WHILE INKEY$<>"":WEND

### 8. REPRESENT A NUMBER AS BINARY BITS:

> GIVEN: Assume N is from 0 to 255; that is, 8 bits.

> >        zbin$="00000000"
> >        for X = 0 to 7
> >            if (N and 2^X) then mid$(zbin$,(X xor 7)+1,1)="1"
> >        next X
> >        print zbin$

> 8a. A similar approach:
> CREDIT: Francisco Moneo of ITAM University.
> CODE:

> >        DIM BIN AS LONG
> >        BIN=0
> >        FOR X=0 TO 7
> >            IF (N AND 2^X) THEN BIN=BIN+10^X
> >        NEXT X
> >        PRINT RIGHT$("00000000"+LTRIM$(STR$(BIN)),8)

### 9. BIT OPERATIONS:

> Here are some useful bit operations:
> 9a. Flip a switch that has a zero or one value.

> >     switch = switch xor 1

> 9b. Another method to flip a switch that has a zero or one value.
> CREDIT: WhiteTiger0990 of Qbasicnews.

> >     switch = 1 - switch

> 9c. Yet another method to flip a switch that has a zero or one value.
> This works, but it's tricky. Note that the expression switch=0 will evaluate as true (-1) or false (0) before performing the AND 1. CREDIT:Oracle of Qbasicnews and QBNZ.

> >     switch = (switch = 0) AND 1

> 9d. Flip a switch that has a zero (false) or minus one (true) value.

> >     switch = not(switch)

> 9e.
> NOTE: When testing a switch that has a zero or one value, you must specify the complete expression when doing an IF.

> >     if switch = 1 then goto swon  'This is correct
> >     if switch = 0 then goto swoff 'This is correct

> >     if switch then goto swon      'This is not correct

> 9f. NOTE: When testing a switch that has a zero (false)
> or a minus one (true) value, you must may test the switch as follows:

> >     if switch then goto swon       'This is correct
> >     if not(switch) then goto swoff 'This is correct
> >     if switch = -1 then goto swon  'This is also correct
> >     if switch = 0 then goto swoff  'This is also correct

> The recommended and more explicit way of handling switches with zero (false) and minus one (true) is as follows:

> >     CONST FALSE = 0            ' 0
> >     CONST TRUE  = NOT(FALSE)   ' -1

> >     if switch = TRUE then goto swon
> >     if switch = FALSE then goto swoff

> 9g. Perform an XOR without using the XOR operator.
> GIVEN: Perform the equivalent of a XOR b.

> >     result = (a and not(b)) or (b and not(a))

### 10. CENTIGRADE/FAHRENHEIT CONVERSION:

> GIVEN: Convert Centigrade degrees in C# to Fahrenheit degrees in F#.

> >     F# = 9/5*C# + 32

> GIVEN: Convert Fahrenheit degrees in F# to Centigrade degrees in C#.

> >     C# = 5/9*(F# - 32)

### 11. GENERATE A RANDOM NUMBER:

> GIVEN: Generate a random integer greater than or equal to the LOWER parameter and less than or equal to the UPPER parameter.

> >     RANDOMIZE TIMER  'Seed the random number generator
> >                  '(You must do this at the beginning of your program)

> >     RandInt% = INT(RND * (UPPER - LOWER + 1)) + LOWER

### 12. EUCLID'S ALGORITHM FOR GREATEST COMMON DIVISOR:

> CREDIT: Donald E. Knuth's book "The Art of Computer Programming, Volume 1: Fundamental Algorithms".
> GIVEN: Find the GREATEST common divisor for two non-zero, positive numbers M and N.

> >         IF M<N THEN SWAP M,N
> >         DO
> >             R=M MOD N
> >             IF R=0 THEN EXIT DO
> >             M=N
> >             N=R
> >         LOOP
> >         PRINT "Greatest common divisor = ";N

Download a copy of this tutorial. (TXT format)

## Database Design - A Complete Study
Part 1 - The Theory

### Written by Stéphane Richard (Mystikshadows)

### INTRODUCTION:

Today, with FreeBasic and it's new realm of possibilities, the Qmunity can now see database application as a definite possibility. Indeed efforts are being made to integrate ODBC to FreeBasic and with it, a whole new world falls within the grasp of freebasic developers. It's not enough today to say that your program can handle 10s of thousands of records the industry is much more demanding than this. Even if you could code to handly more than this say using random access files, would you really want to knowing there's a better solution out there? I didn't think so.
In this document, I will try to tell you everything you need to know to equip yourself with a good solid knowledge about databases and database design concepts so you can sit down, look at a problem and be able to intelligently design a database to fit the very specific needs of a given database project. This will be a 3 part study. The first part, which you are reading now will cover alot of the basic database concepts, What types of database exist and some design considerations. The Second part will take a sample situation and design a database for it. The third part will cover everything there is to know about database management, interrogation and reporting. Throughout this series we will be using MySQL as the database environment because it's free and will most likely be the first "bigger" database you'll want to get your hands on. So all SQL you'll learn will be as it is implemented in MySQL. With a few changes you can addapt your knowledge to most well known databases fairly quickly.

### DATABASE CONCEPTS:

We'll start things off by explaining some basic database concepts. Like I mentionned this first part is all about theory so brace yourselves. Here I'll just explain some parts of database design that you can expect to see in all "database related projects" by today's standards as they have changed over the years.

- Databases:
  When this term was first used, it's original definition was that a database was the name of a file on disk that could be opened (flat file). With the coming of the different early databases like DBase Foxpro and Paradox, this definition change to say that a Database was a folder name. Today a database regained it's original meaning in that it now represents a filename only the structure inside the file has changed dramatically.
- Tables:
  Table started to exist only recently and only had one definition. A table is a name that represent one fixed set of records, all of the same structure definition. Back in the days of DBase, FoxPro and Paradox, tables were each filename found inside of a folder with the proper file extension and inner structure. Today, a table is defined as one of the tables found inside a database file. Like it's first definition it has a fixed set of structures to define one given set of information.
- Record:
  A record always remained the same, it's one row of information that pertains to a given table. For instance in a Customer Table, each row of data (be it in a flat file, or a database, still represent the information that pertains to one given customer only. The means to store that one set of information changed drastically over the years, but the definition of a record still remains the same today.
- Indexes:
  Indexes always had just one purpose in history and still do today. Indexes server to present the records in a database in a specific order. In the days of DBase, FoxPro and Paradox (and others of the time) an index was a seperate file on the drive that held the information pertaining to the order of the table. An index also serve to accelerate the search process to find a specific record most database had a quick way to search the index to get to a specific record number in the main data file quite instantly even in indexes of 10s of thousands of records. It can still serve that purpose today as well.
- Keys:
  With the coming of the truely relational database management system and their concept of a field in a table relating to a field of another table, the term Key was used to represent those fields that helped link two or more tables together. There are two types of keys, Primary Keys and Foreign keys. Here's a brief description of both:
  - Primary Keys:
    This is usually a field that is chosen in a table that will more than likely not allow duplicate records with the same value as the primary key. The reason is this helps keep the referential integrity intact by making sure that no related set of records can be mistaken as belonging to a different record being processed.
  - Foreign Keys:
    A Foreign key was given it's name because it helps maintain a relationship between outside tables and the main table being used. This one could typically allow duplicates however (see below about Relationship for the reasons why).
- Relationships:
  When the Relational DBMS was invented is when the concept of relationships was created. The first implementation of a relationship system was in DBase with the "SET RELATION TO" instruction. When a relation was created in DBase it made the whole set of related tables synchronize themselves to each other automatically but today these relation only server to help maintain a database's referential integrity (see below). There are four types of relationships that you can make between tables of a database. Here they are:
  - One To One Relationships:
    This relationship states that a record in a table must be related to one record of another table. Not more than one but one record in both related tables must be present for the same record.
  - One To Many Relationships:
    This is the most common relationship used. this states that of one record in one table, atleast one (or more) records must exist in the related table. This is where you'd do your typical Invoice Header and Invoice Purchase Details type of relationships.
  - Many To One Relationships:
    This one is the inverted version of the previous relationship. This says that one or more records of the first table must belong to one record in the related table. A good example of that is a customer opening more than one bank account in a bank and the bank works with the bank account as the main table and not the customers themselves.
  - Many To Many Relationships:
    This relationship implies that one or more records from the first table must have one or more record in the related table. This can be usefull for cross referencing tables. There are many cases where more than one piece of a car, for example can be used to build one or more model of cars. There's other examples as well. This type of relationship isn't used as often as the one to many relationship but it is used often in these types of situations.
- Referencial Integrity:
  This concept is defined as if all the tables that are related to each other all have data to respect the contents of all the relationships that are defined then one can say that the database's referencial integrity is intact. This means that for each of the fore types of relationship defined in a database system, all data that lies in each of the related table must be present. This also means that if, for example, in a one to one relationship, one of the tables should have 2 elements relating one element in another table then the referencial integrity of the database has been compromised.

### DATABASE TYPES:

Indeed, over the years there have been many types of databases developed. The main reason for the different types was simply because of the evolution of the data that were needed by the industry. It was, in my opinion a very evolutionnary (not revolutionnary) sequence of database types that simply fit the needs of the data that would be handled by the databases of the times. Here we'll cover these database types.

- Flat File tables:
  This was the first type of data storage available, it consisted of flat files (text files) in which a line of text data represented a record. It was later called the Fixed Length Text file because all rows were lined up with the previous ones to allow to easily parse it's contents to retreive the different elements that made up a racord. It was created just to have a means of storing the data (which was the main focus of databases at the time, to store the data. Later, flat files evolved a bit because a new need became obvious, the need to find the data. The first evolution was found in spreadsheets which allowed to sort the data and then you could just page up and down to go to the area where your record would most likely reside. And even later systems like DBase and FOX database environment gave flat files even more flexibility. But they were still flat files (one filename per table) which had it's limits.
- Navigational Database Management Systems:
  Not too long after the Flat File model, the needs to browse through the data, the ability to go to specific places in the database became apparent. Data became bigger and bigger and in the mean the "conventional" means of retreiving data was becoming less and less of a "proper" solution. Hence came the Navigational DBMS. It was the first model that actually allowed a database to be interrogated. For instance you could answer questions like "give me all the people in Washington" and it would go about perusing the database collecting the records that matched the criteria and return it back to you. However good this was for global maintenance, when you only wanted one record in the whole database, this system had to browse through all the records nonetheless until it reached the end of the database.0
- Relational Database Management Systems:
  The Relational Model was the first Model that boasted the seperation of data elements in order to avoid unnecessary redundancy of information in a record. Bring the information elements back together was the key to this model's success. A relational model assumes that there will be more than one table to navigate and search in order to piece information together about a given criteria. A "key" field is defined to connect the pieces of information throughout all the "related" tables of data. This model was the first model that could allow a very streamlined organization of the data so that the tables would stay as small as possible in size. It was invented by Edgar Codd (who worked at IBM at the time). It was also then that what they call a "set oritented language" was developed for this need of looping. This set oriented language became what we now know as SQL. Main difference between navigational DBMS and Relational DBMS was that in the Navigational DBMS you looped to find a particular record, in the Relational DBMS you looped to find all the information pertaining to a particular record.
- Multidimensional Database Management Systems:
  Multidimensional DBMS was shortlived. In essence it was invented because at times, doing a query in a fully normalized Relating DMBS could sometimes be quite long. And so it was created to denormalize a database in order to be able to query the data faster (somewhat of a step backwards which is probably why it was so short lived). Indeed, Multidimensional DBMSs ignore the logical/physical independence of the relational model and instead exposes pointers to the programmer. Instead of finding an address by looking up the "key" in the address table, the multidimensional DBMS store a pointer to the data in question. In fact, if the data is "owned" by the original record (that is, no other records in the main table point to it), it can be stored in the same physical location, thereby increasing the speed at which it can be accessed. needless to say referential integrity was darn near impossible to achieve hence another reason for it's short lived existence There was no 100% sure way to secure the database from itself.
- Object Oriented Database Management Systems:
  The only good thing about Multidimentional DBMS was that they led directly to the development of Object-Oriented DBMS. The Relational DBMS serves to represent the relationship between the tables of a database. An Object Oriented DBMS is there to represent containment of one table as part of another table. Hence you could say that an invoice needs a customer from the customer table, details of items purchased in the details table and so on. When normalizing the database for this model it still resembles the classic normalization approach with a twist on records being part of other records in other tables. But it is still about avoiding redundancy in information as much as possible.

### DATABASE NORMALIZATION:

You seen this term earlier in this document. Database normalization is the process in which duplicate information is prevented and avoided when designing a database. There are 6 defined normalization levels (5 distinct levels and an modified version of the 3 normal form). Each of these normalization phase is designed to refine the previous level a degree more to assure that the database definition is properly normalized. Let's see these Normalization Forms along with their description. After we'll take an example situation and create a normalized database to reflect the needs of that situation.

- First Normal Form (1NF):
  This first normal form requires that all column values in a table are atomic (a number is an atomic value while a list or a set is not). This essentially means that you shouldn't have Repetitive fields in a table. For example if your table has Item1ID, Item1Description, Item2ID, Item2Description and so on, those should be put in a seperate table definition.
- Second Normal Form (2NF):
  The Second Normal Form requires that all elements of a table that are not dependant on the primary key, be put in a separate table. For example if you have the following fields in a table: PartNumber, SupplierID, Price, SupplierAddress, you don't need to go by the PartNumber to get the supplier information. Therefore Supplier Information should be in it's own table definition.
- Third Normal Form (3NF):
  The Third normal form requires that there are no non-trivial functional dependencies of non-key attributes on something other than a superset of a candidate key. A relation is in 3NF if none of the non-Primary Key attributes are a fact about any other non-Primary Key attribute. Hence if you have the following fields: PartNumber ManufacturerName and ManufacturerAddress the manufacturer information is not information about the part and therefore should be in a seperate table definition.
- Boyce-Codd Normal Form (BCNF):
  This is the modified version of the Third Normal Form. It requires that the database be 3NF and every non-trivial, left-irreducible functional dependency has a candidate key as its determinant. This essentially forces the fields in a table definition to only be about what the Key field is about (except for foreign keys that relate to information in other tables.
- Fourth Normal Form (4NF):
  The Fourth normal form (or 4NF) requires that there are no non-trivial multi-valued dependencies of attribute sets on something else than a superset of a candidate key. For Example If an employee relation has multiple job categories and multiple locations where they work it might seem to make sense to just add these fields in: EmployeeID, LocationID and JobCategoryID. However, we might have to enter Employee's Job Category more than once if they fulfill the same Job Category at more than one location. There should be 3 many to many relations here: EmployeeID, JobCategoryID is one, EmployeeID, LocationID is another and finally JobCategoryID, LocationID is the last one. Then the relation is truely 4NF.
- Fifth Normal Form (5NF):
  The Fifth normal form (or 5NF or PJ/NF) requires that there are no non-trivial join dependencies that do not follow from the key constraints. A relation is said to be in the 5NF if and only if it is in 4NF and every join dependency is implied by the candidate keys. For example, if a field can be calculated it shouldn't be stored. This is a level of normalization that optimized disk space usage a great deal but at the cost of performance.

Special Note:
I've stated here all the normalization forms. However, more than likely most database designs consider only the first three normaliziation levels. The reason why is because the other normalization levels usually cost too much in performance to be useful. All these normalization phases can be applied in both a relation DBMS and an Object-Oriented DBMS, the only difference is how you imply a relationship between two tables. In a relation DBMS you simply create a relationship stating which fields are the foreign keys going into which table and if it's a one to one, one to many, etcetc type of relationship. In Object-Oriented DBMS you create a relationship in terms of what the parent table contains (An InvoiceHeader table has a InvoiceDetails Table to hold the items purchased by the customer and specify the key that holds this containment relationship together).

### IN CONCLUSION TO THIS FIRST INSTALLEMENT:

And this is it for the bigger part of the theory (the first installement of this series). There's alot of material that I've covered and that's only to prepare you for what's up ahead. I tried to make it as concise and clear as I could to help make sure that the next installement will go smoothly. If you have questions, be sure to let me know so I can explain it further if needed.
In the next installement we'll take a complete sample situation and we'll define a database to represent the situation. We'll also normalize the database as per what we've learned here in terms of normalization. In other words, we'll begin to take the theory you learned here and apply it to a realworld situation. I'll give you tips and pointers to help you figure out what type of table you'd probably need as well as what fields you'd typically need to properly describe the items being stored in the table. Database design is really about domain specific knowledge and common sense. The way the situation is described to you often holds key information when you try to evaluate the database needs of a project. I'll show you how to extract that information from a typical description and you'll see it becaomes a very straightforward process in the ned. Until then, Happy coding and remember that you can always email me with questions or comments.

> MystikShadows
> Stéphane Richard
> srichard@adaworld.com

Download a copy of this tutorial.

## Coding a Parallax Scrolling Platformer
Chapter #2: "PARALLAXING"

### Written by Na_th_an

Hey there. After the short tacet we're back with this. On this second chapter, I'll explain how you create a parallax scroller. You'll notice that this thing is way easier than you expected, specially now that fB's default graphics libs (by our personal guru, Mr. Angello Mottola a.k.a. lillo) support clipping (i.e. you can PUT a sprite that's partially off-screen). Before the advent of fB you had to rely on reinventing wheels or using external libraries.

We'll begin this second chapter with something really important:

### What's a Parallax Scroller?

Uh sure, yeah, I forgot to explain this. We are coding a 2D game. That means that in our world you can only go up, down, left or right (or in an oblique direction, of course). There's no "depth" per se. If we want to add some depth to the visuals, some tricks have to be used.

Using this technique called "parallax", you can create illusion of 3D'ish depth in your game. To help you understand this, just take a drive in your car or someone else's, and while the car is moving, look accross a side window (please don't do this if it's you the one who's driving, please - unless you are 27 and you want to become a member of the infamous group). See what happens. Things that are far away move slower than things that are near. Of course, this is a visual effect. See? Well, that's the effect we want to get.

"parallax" is a funny word. My best guess is that it comes from "parallel axes", with axes as the plural of axis and not axe (it would be quite funny if we were using parallel axes from "axe" in our game - forget the horrid pun). It is a simplification of the real world, so everything is located in discrete, parallel axes, which you see perpendicularly. Basicly, you have several planes one on top of each other. The one which is on top of all moves fast, the next one a bit slower, the next one even a bit slower... and the bottom one usually is fixed or moves reaaaaaaally slow.

In parallax engines, there's always a "main plane", then at least one behind it (the more you add, the better it looks, but the slower it's rendered - of course), and maybe another one on top (which will be rendered on top of the player and sprites giving great and impresive visuals).

### What's a Tiled Parallax Scroller?

Well, to make it short, it is just a Parallax Scroller which uses tiles to draw each plane. That saves memory and is usually faster. Note that you will be only drawing those tiles which are shown on screen, ignoring all the rest.

What are tiles? Easy: those ceramic things which cover the walls in your bathroom. Look at them: they are all the same size and are located forming a grid. Now extrapolate the idea to video games. You got it: the game map is composed by square or rectangular small pieces of graphics which are located forming a grid. Look at Mario Bros. Look how all the maps are created with a discrete number of different small pieces that are combined to build those nice mountains and pipes. That saves heaps of memory, 'cause with a few graphics you can build huge maps. Oh - yeah, you already knew about tiles. Well, maybe someone didn't.

### How is it done?

That's what we are here for: to explain how it is done.

First of all you need a two-dimmensional array per layer, with each array element representing one of your tiles. If you have more than two layers, maybe a three-dimmensional array would be better. Note that layers that are behind the main layer need less tiles on them ('cause they move slower, so when you reach the end of the main layer, secondary layers might be half-way) - later we'll explain how to calculate how many tiles fit on secondary layers depending on their "speed". Having a three-dimmensional arrays you are wasting memory, but you are making your life easier when it comes to code the game renderer.

Which data type we need our tiles to be represented with? First of all, we need a tile number, which could fit in an unsigned byte (you won't use more than 256 tiles per level, right?). It would be handy to have a status byte per tile, with bit flags used to determine if the tile is walkable or not, if you can go accross it, if it kills... etcetera. So we have our data type:

>     Type MapType
>        tile   As Unsigned Byte    ' Tile number
>        status As Unsigned Byte    ' Status byte
>     End Type

So if your main layer has 100x100 tiles, and you want three layers, just create your three-dimmensional array accordingly:

>     Dim map (2, 99, 99) As MapType

Or, even better:

>     Const MAPLAYERS = 3
>     Const MAPWIDTH = 100
>     Const MAPHEIGHT = 100

>     Dim map (MAPLAYERS - 1, MAPHEIGHT - 1, MAPWIDTH - 1) As Maptype

Note that we are wasting a lot of memory. The Status byte should only be useful in the main layer, the one which you are gonna interact to. This main layer will have the platforms, cliffs and ledges. Secondary layers will only contain tiles, so you are wasting a byte per tile per layer, i.e. 20,000 bytes in our example. Anyway, for the sake of clarity, we'll use this structure. This is a tutorial, after all. In the real life, it would be better to have one array to store all the layers and one array to store the status of the main layer. But that's too many arrays for a tute.

Well, now you have a big bunch of memory reserved. How do we fill it? Well. The easiest way is having a map editor which saves in an easy to read format so we can read the file and write into our map accordingly.

There are tons of map editors, and you can even code your own. A good one I personally like is mappy, which you can configure to save the tiles in whichever format you can imagine, completely customizable. Anyway, this ain't the focus of this tutorial so I won't cover it. I will try to give some general tips on how this is done, although this is nothing too hard if you know how to work with binary files. Which you should.

Before thinking about loading maps we need to define the format of the status byte. To go basic, we can use it to tell if the tile is traspassable or not, i.e. if you can go accross it or not. We'll be using byte 0. Remember those bitwise operations from Chapter 1. As we won't be using more bits by the moment, status will only be wether 0 (traspassable) or 1 (non-traspassable).

So, basicly, what we have to do is create a subroutine which is passed a filename and the map array and then opens the file and fills the map accordingly. Of course, this funcion depends heavily on how our map is stored in the file. If I were you and I would feel like coding my own map editor (which, certainly, is NOT the case), what I would do is using the same kind of map array in the map editor so I can just BSAVE the map from the editor and BLOAD it from the game. That's the ideal scenario. But if you are a lazy ass you can always rely on an external map editor and its format.

The most basic format mappy saves to is just a bunch of MAPWIDTH * MAPHEIGHT bytes, so you just have to open the file and read bytes. This is pretty limiting, 'cause... how do you decide which tiles from the main plane will have their status = 1 (non transpassable)? The easiest approach is considering, for example, tiles with ID < BLAH non-walkable and tiles with ID >= BLAH walkable. But that is pretty limiting. The cool thing to do would be using mappy to assign a certain property to non-transpassable tiles and then saving in a easy to read format you can interpret to fill your array using two loops. I highly suggest you to download mappy and read its documentation. It's a pretty complete little program.

So, from now on, we'll assume your map array is correctly filled with map data.

### Yeah, but I also need graphics, I mean tiles. How do I...

... I was about to go to this right now, granted. Seriously. That's why I included the gif loader in last chapter (which was also the first chapter! Now that's interesting!). Some people like sprite editors which save a bunch of little BMPs, or they prefer to use PPwhateverthingo... I've always prefered the power of a true, full-fledged graphics editor which is good for pixel art. My personal favourite was the good ol' Deluxe Paint IIe v.3, but I'm having problems to run this properly lately (unless I punch in my DosBox), so I was using Photoshop and Paint. Whatever, the thing is that you end with a GIF file with all your graphics stored, nicely arranged in a grid. Any size, but try it to fit on screen. We are gonna use a VERY SIMPLE method which will keep your HDD clean of 1,000 files, one per graphic tile.

The first step is, of course, create our graphics file. For this example, we'll use a 256x128 bitmap in which we can store 256/16 = 16, 128/16 = 8; 16 * 8 = 128 tiles measuring 16x16 pixels. What we'll do is switching to a non-visible page, loading the GIF in there, GETtin every tile to our tile array, clearing the screen, switchingback to the visible page. That's the modus operandi.

We need some definitions:

>     Const TILEWIDTH       = 16
>     Const TILEHEIGHT      = 16
>     Const TILEMAPWIDTH    = 256
>     Const TILEMAPHEIGHT   = 128
>     Const NUMTILES        = 128

>     Dim tiles (NUMTILES - 1, TILEWIDTH * TILEHEIGHT + 1) As Byte

We'll set up a SUB to do this task. It couldn't be more simple:

>     Sub loadGfx (gfx () As Byte, fileName As String)

>     	Dim i As Integer

>     	Dim x As Integer

>     	Dim y As Integer

>     	ScreenSet 1, 0

>     	LoadGif 0, 0, fileName

>     	For i = 0 to NUMTILES - 1

>     		Get (x, y) - (TILEWIDTH + x - 1, TILEHEIGHT + y - 1), gfx (i, 0)

>     		x = x + TILEWIDTH

>     		If x = TILEMAPWIDTH Then

>     			x = 0

>     			y = y + TILEHEIGHT

>     		End If

>     	Next i

>     	Cls

>     	ScreenSet 0, 0

>     End Sub

It's very handy to just call to loadGfx passing our tile array and a file name, such as, for example:

>     loadGfx tiles (), "data/stage1.gif"

This way you can easily switch from a tileset to another, just calling loadGfx again with a different filename. The subroutine just goes accross the image on screen and gets rectangles right onto our array. Note that if you want to use this in QB you have to change a couple of things, as in QB arrays are stored in column order. There's a entry in the QBN FAQ where I explain what's the beef with row or column order, go there and check that. To summarize it, if you use QB just interchange the two array indexes (i.e. DIM (TILEWIDTH * TILEHEIGHT - 1, NUMTILES - 1) and Get (x, y) - (TILEWIDTH + x - 1, TILEHEIGHT + y - 1), gfx (0, i)).

### Now we (supposedly) have map data and tile data... Now?

Now we'll code the freakin' parallax scroller. Finally.

A parallax scroller just draws the tiles which are on screen, partially or totally. It skips the tiles which are completely off-screen. How is it done? Easily.

The first thing we need is a camera position. The camera position will determine which portion of the map will be shown. More correctly, the camera position determines which portion of the main layer in the map will be shown. The positions of the other layers are calculated applying scales to this position. For example, it's very common that if you are using just two layers, the second one moves at half the speed, so if camera.x and camera.y determine the main layer coordinates, then camera.x \ 2 and camera.y \ 2 will determine the second layer ones.

Just remember that the further the layer is behind the main layer, the slower it will move, so you have to divide by a higher number. If you are placing extra layers over the main layer (overlays to give more 3d'ish feel), they have to move faster, i.e. you have to multiply. The further this 'overlay' layer is over the main layer, the faster it moves. By the moment, we'll just have a position. When we code the player movement we'll explain how to make the camera follow the player in a smooth way (I really hate those games that have the player stuck to the middle of the screen and everything moving around linearly).

The second thing we need to know is how many tiles fit in the screen. The amount of rendered tiles will be determined, of course, by the size of our viewport. In a 320x240 display, using the full screen and 16x16 pixels tiles, you have to draw 20 or 21 tiles horizontally and 15 or 16 tiles vertically (depending on wether the camera coordinates are aligned with the tile coordinates, i.e. the camera coordinates are multiples of 16). The calculation is easy: VIEWPORTWIDTH \ TILEWIDTH + 1 and VIEWPORTHEIGHT \ TILEHEIGHT + 1. This will be precalculated, for speed.

For each layer, we'll have two nested loops which will draw the correct tiles according to the current camera coordinates. We'll begin drawing the layers from bottom to top, using transparent PUTs.

And how we know which tiles to draw? Here comes the stuff, of course. The first tile which appears on screen (at the top-left corner) is that in the map array which is located at (camera.x \ TILEWIDTH, camera.y \ TILEHEIGHT).

And how do we make it pixel by pixel? Easy, just substract camera.x Mod TILEWIDTH and camera.y Mod TILEHEIGHT from the coordinates...

Now let's try to make y'all understand how this works. Let's assume tiles are sized 16x16 pixels. Now consider the whole map like a huge bitmap image measured in pixels. In each coordinate which is multiple of 16 contains the upper-left pixel of a tile: you have a tile at (0, 0), a tile at (16, 0), a tile at (32, 0)... a tile at (0, 16), (16, 16), (32, 16), etcetera. That way, given a (x, y) pair of coordinates, you can easily calculate which tile is in there just performing a integer division: the tile located there is just map(layer, y \ 16, x \ 16).tile.

If your camera is located at (0, 0), you have to draw from tile #0 horizontally and tile #0 vertically until you fill your viewport. If your camera is located at, for example, (48, 64) you have to draw from tile #3 horizontally and tile #4 vertically (48 \ 16 = 3; 64 \ 16 = 4). So you do, for each layer, something like this:

>     tile.x = camera.x \ 16
>     tile.y = camera.y \ 16

>     For x = 0 To 20
>     	For y = 0 To 15

>     		tileToDraw = map (layer, tile.y + y, tile.x + x).tile
>     		Put (16 * x, 16 * y), gfx(tileToDraw, 0)

>     Next y, x

This works great when the camera coordinates are multiples of 16... But we want pixel by pixel scrolling. What happens if, for example, the camera is at (53, 68)?

Think of it: we still draw from tile #3 horizontally and tile #4 vertically (53 \ 16 = 3; 68 \ 16 = 4), but we have to shift a few pixels left and up what we draw 'cause we are a few pixels off the tile limit. If you are at (53, 68) you are 5 pixels away from the horizontal tile position (53 - 48 = 5) and 4 pixels away from the vertical tile position (68 - 64 = 4). How do we calculate that: easily, using module, as a MOD b gives the rest of dividing a / b. So, for each layer, we do something like this:

>     tile.x = camera.x \ 16
>     tile.y = camera.y \ 16

>     offset.x = camera.x Mod 16
>     offset.y = camera.y Mod 16

>     For x = 0 To 20
>     	For y = 0 To 15

>     		tileToDraw = map (layer, tile.y + y, tile.x + x).tile
>     		Put (16 * x - offset.x, 16 * y - offset.y), gfx(tileToDraw, 0)

>     Next y, x

As you see, this is incredibly simple. Do the same with each layer, drawing them one on top of another from bottom to top using transparent put and you got it. Everything put together using constants and stuff:

>     Type CoordinatesType
>     	x As Integer
>     	y As Integer
>     End Type

>     Dim Shared numTilesHorz As Short			' tiles to draw horizontally
>     Dim Shared numTilesVert As Short			' tiles to draw vertically

>     Dim Shared viewportPos As CoordinatesType	' where our viewport starts on screen
>     Dim Shared viewportWidth As Short			' width of our viewport, in pixels
>     Dim Shared viewportHeight As Short			' height of our viewport, in pixels

>     Sub Render (map () As Byte, gfx () As Byte, camera As CoordinatesType, dividers () as Integer)
>     	Dim tile As CoordinatesType
>     	Dim offset As CoordinatesType
>     	Dim layerCamera As CoordinatesType

>     	Dim layer As Short
>     	Dim tileToDraw As Short
>     	Dim x As Short
>     	Dim y As Short

>     	' First of all we create our viewport. Read the gfxlib documentation for
>     	' more info on this command:

>     	View Screen (viewPortpos.x, viewportPos.y, viewPortpos.x + viewportWidth - 1, viewportPos.y + viewportHeight - 1)

>     	' Render each layer, from bottom to top.

>     	For layer = MAPLAYERS - 1 To 0 Step -1			' Our main layer is layer #0,
>     													' we draw from bottom to top.

>     		layerCamera.x = camera.x \ dividers (layer)	' The dividers array contains the camera
>     		layerCamera.y = camera.y \ dividers (layer)	' speed dividers. For layer 0 (main layer)
>     													' it has to be 1. For subsequent layers,
>     													' it has to have increasing values.

>     		tile.x = layerCamera.x \ TILEWIDTH
>     		tile.y = layerCamera.y \ TILEHEIGHT

>     		offset.x = layerCamera.x Mod TILEWIDTH
>     		offset.y = layerCamera.y Mod TILEHEIGHT

>     		For x = 0 To numTilesHorz
>     			For y = 0 To numTilesVert

>     				tileToDraw = map (layer, tile.y + y, tile.x + x).tile
>     				Put (x * TILEWIDTH - offset.x, y * TILEHEIGHT - offset.y), gfx (tileToDraw, 0), Trans

>     			Next y
>     		Next x

>     	Next layer

>     	' Undo viewport:

>     	View

>     End Sub

I forgot to mention the dividers array this subroutine expects. It is just an array containing the divider for each layer speed. For layer 0, i.e. the main layer, it has to be 1, and then it has to increase for each layer. A normal set for two layers would be, for example, {1, 2}. Layer #0 (main layer) would move at the camera speed; layer #1 (background) would move at half the speed. Usually, a geometrical progression with factor 2 is used (this is, {1, 2, 4, 8, 16 ...}) so every frame moves twice as fast as the next one located behind it, but you can create interesting depth effects playing with each layer speed.

I'll give you an assignment: use the current code to create a simple program that scrolls in every direction using the control keys. You need to create your own graphics and map

Next chapter we'll talk a bit about physics.

Check out part one of this series!

## Final Word

The past twelve issues have taken a lot of work for me and dozens of contributors. Since QB Express couldn't have existed without the writers, I thought I'd pay tribute here to the people that have made QB Express what it is. So here it is: my personal thanks (and "roast") of QB Express contributors.

> Inspired QB Express magazine in the first place:
> Zkman (QB:TM), Vance Velez (V Planet!), Nekrophidius (QB On Acid)

> ...and just about every other past QB magazine ever.

> QB Express really is a conglomeration of the best parts of previous QB magazines. Three big inspirations were QB:TM, V Planet! and QB On Acid. QB:TM is arguably the best QB magazine ever, and when I was a 13 year old reading that stuff, I aspired to create something that good. Compare the formatting and sections of QB Express and you'll see the heavy influence from Zkman's seminal mag. V Planet!, the best QB reviews site ever, was also an influence -- especially the fantastic way Vance Velez used to cover QB scene news. The News section of QB Express was heavily influenced by V Planet. Finally, QB Express's open "free speech" philosophy, where everything is presented to you in full uncensored glory, was inspired partially by the no-holds-barred speak-your-mind editorial style in Nekrophidius's QB On Acid magazine.

> Contributor who most helped me get this mag off the ground: RelSoft

> Last July when I announced my intention to start a new QB magazine, I posted want ads all over the Qmunity asking for submissions of any type for the magazine. But at that time, submissions were anything but automatic (like they arenow). Nobody was really interested in my little zine at first, and nearly all of the articles in the first issue were there because I either wrote them myself or I searched out writers and begged them to submit something. All the articles except for one -- RelSoft's excellent Metaballs tutorial. In the first issue, that MetaBalls tutorial was the centerpiece of the fledgling tutorials section. Without that article, the first QB Express issue would have been pretty pathetic. Thanks Rel!

> QB Express's biggest fan (and biggest contributor): MystikShadows

> MystikShadows (aka Stéphane Richard) has gradually developed into QB Express's biggest contributor, and judging by his letters to the editor every month, he's got to be QB Express's biggest fan. His letters every month are just gushingly praising of this magazine, and over the past eight months, he's written EIGHTEEN articles for QB Express, and all of them have been thorough and well-written. It amazes me every month just how dedicated and prolific MystikShadows is, and I'm incredibly glad to have him on board as a writer!

> Writer of my favorite QB Express tutorial series: Na_th_an

> Na_th_an rocks, and his 6-part I.F. Games series has been a steadfast and very educational tutorial series that's covered just about every aspect of text adventure programming that you can think of. This series is so well-written and professional that it's hard to believe that it's written by hobbyist for a fanzine. These tutorials are so accessible that anyone could follow them and end up making a great I.F. game -- which tells you just how great these tutorials really are!

> Wrote my favorite ever QB Express article: Mike Wechsler

> My good friend and roommate Mike wrote a few articles for QB Express over the past year because he thought it was so funny that I was making a magazine about QBasic, that silly programming language taught to middle school students in between spelling tests and gym class. Although it has absolutely nothing to do with QBasic or the Qmunity, my favorite thing to ever appear in this mag is his joke article Realistic 3D Modelling in QBasic: A Tutorial. I don't know if anyone else finds it all that funny, but I loved it.

> Gives the best constructive criticism, and is a damn good reviewer too: Lachie Dazdarian

> Lachie's letters to the editor are the best, because he always has the most interesting and useful feedback for the magazine. I'm also a big fan of his effots to bring due recognition to relatively unknown QB games in his Searching for the Unknown series. Plus, he writes very fair, thorough and accurate reviews that should be a model for everyone else.

> Thanks for the comics: Matt2Jones and Rattrapmax6

> It's really nice having a comic every month in QB Express. It's a nice diversion from the articles, and also has been serving as the divider between the Articles/Editorials and the Tutorials ever since the very first issue. It doesn't matter who doesn't like Bobby the QBasic Maniac or Horse Humor Comics -- because I do like them, and they're here to stay. :-)

> Gave me the least trouble formatting articles: MystikShadows

> MystikShadows sure submits a lot of tutorials, but luckily for me, he always pre-formats them in QB Express format so all I have to do is copy and paste them into the issue. Ahhh, joy. :-)

> Gave me the most trouble formatting articles: Adigun Azikiwe Polack

> Adigun A. Polack has been a prominent contributor to QB Express, having written articles in seven of the first twelve issues, including some excellent reviews and a useful tutorial on Custom Windows Icons for your FreeBasic Programs. But...if any of you're familiar with Adigun's flamboyant, flashy, BBCode-rich writing style, you'll understand why converting these articles to fit in QB Express is such a pain in the ass. :-) Adigun's articles look nice, but they take *forever* to convert from the PHPBB format to QB Express HTML format. Going through every emoticon, every bolded, underlined, italicized, colored and manipulated block of text, and dozens of images is quite an ordeal. It's a good thing that Adigun writes interesting articles, because formatting them is hell. :-)

> Most "newsworthy" people of 2004/2005: Nekrophidius, SJ Zero and V1ctor

> Thinking back over the past year, there are three people who have appeared in the news of just about every QB Express issue, sometimes multiple times in each issue -- Nekrophidius, SJ Zero and V1ctor. All three of these guys have been tremendously active in the QB/FB community in the past year and contributed immeasurably to the scene (*especially* V1ctor, who basically recreated the scene as we know it). I'm not going to bother listing off everything these three have done in the past twelve months, but if you look through the news, you'll see just how much they've accomplished.

> Articles that got the biggest reaction (positive or negative) in the past year:

> > - Bobby The QBasic Maniac comics - Matt2Jones (Issues #1 - 4)
> > - Metaballs? I'd call them "Blobs" - Relsoft (Issue #1)
> > - Blast From The Past: Tsugumo's TheGame - Pete (Issue #2)
> > - GUI tutorial series by VonGodric (Issues #3 & 5)
> > - Is It A Bird? Is It A Plane? No, It's FreeBasic! - Blitz (Issue #4)
> > - Horse Humor Comics - Rattrapmax6 (Issues #6 - 12)
> > - I.F. Series - Na_th_an (Issues #6 - 10, #12)
> > - OpenGL Tutorials for FreeBasic (Parts 1 - 4) - RelSoft (Issue #8)
> > - The Quest For Opa Opa Review - Joseph Burke (Issue #9)
> > - The QBasic News Debacle - Pete/MystikShadows/lurah (Issue #10)
> > - The BASIC User's Guide to English Spelling and Grammar - Daniel Verkamp (DrV) (Issue #10)
> > - Interview With Sumo Jo - Pete (Issue #11)
> > - Gallery: The Griffon Legend - Pete (Issue #11)
> > - And...not quite an article, but they've caused the biggest reaction and discussion of all: the damn gray boxes errors in FireFox! Every issue someone brings this up, and I still haven't found a solution.

> And thanks to everybody else:

> I can't possibly thank everybody that's contributed to the mag in the past year here, but trust me, I appreciate it. VonGodric, Oz, Zap, 19day, Deleter, aetherFox, Moneo, Antoni Gual, abionnnn, DarkDread, Neo Deus Ex Machina, Piptol, Joe King, Blitz, dumbledore, lurah, Matthew R. Knight and everyone else I forgot to mention -- thank you! You made QB Express what it is!

Well, that's it for a great first year of QB Express... and also my last issue as a teenager. By the time issue #13 is released, I will have turned twenty years old (I'm not a kid anymore, ::tear::)! I started Pete's QB Site shortly after I turned 13 and officially became a teenager...and now that first era of Pete's QB Site is coming to a close. I can't believe it's already been seven years...

Anyway, The deadline for submissions is August 15th, as usual! See you in Issue #13!

Until next time...END.

-Pete

Copyright © Pete Berg and contributors, 2005. All rights reserverd.
This design is based loosely on St.ndard Bea.er by Altherac.