QB Express

Issue #1  ~  August 23, 2004

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

In This Issue


From The Editor's Desk

Written by Pete

Two weeks ago, I had no intention of starting a new QB magazine. Two weeks ago, I was just skimming through all of the old QB magazines, you know, for old time's sake. At first, all I intended to do was archive the mags on my website. The BASIX Fanzine...QBasic: The Magazine...The QB Times...QB On Acid...QB Cult Magazine...QB Chronicles...and more. I gathered them together, archived them, wrote little paragraphs about each one, and uploaded them to my site. But as I read through them, I kept thinking to myself "What a great resource these are!", "Hey, I remember that!", "Wow, that's a handy tutorial!", and..."Hey, I could make one of these myself!"

Anyway, I set to work collecting QB magazines, sending emails to try to get ones that weren't available, and archiving the ones I could find. Soon enough, I had created a snazzy new section for my site that distributed them all in one unified and easy-to-access archive. As I worked on this section, I did quite a few web searches on various QB magazines. In the process, I stumbled across message board postings and excited raves about the various QB magazines...and a lot of demand for new issues. Meanwhile, I kept thinking "Hey, I could make one of these myself!"..."Hey, I could make one of these myself!"

I soon came to the realization that the existing QB magazines are dying out left and right. QB Cult Magazine is on its last legs, and has gone since January without a new issue. (In fact, QBCM turned down Relsoft's newest series of tutorials, since it probably won't be around long enough to release them.) QB Accelerator is no longer released on an issue-by-issue basis, and also hasn't been updated in months. QB On Acid ended its third short run early this year when its co-editor quit. QBOA has supposedly merged with V Planet!, another QB magazine which has slowed down substantially.

With all this going through my mind, I decided to start feeling up the QB Community to see if they'd be receptive of a new magazine. After a few apprehensive message board posts (see here and here), I found that the answer was, indeed, yes. I finally decided to start a new QB magazine...that's what you're reading right now. It's been a lot of work -- I've sent a lot of emails, spent a lot of time and posted a lot of messages to put this together, but I'd say it definitely worked out! I hope you agree!

Introduction

Welcome QBers! I'm proud to invite you to the first ever issue of QB Express. This month, I have gotten an absolute bounty of submissions -- far more than I ever expected for the first issue. In fact, at 141KB of text alone, this first issue is already one of the largest issues of any QB magazine ever made! The great response I got was a very pleasant surprise.

This issue, RelSoft has delivered a great tutorial on creating Metaballs ("Blobs"), Adigun A. Polack has written an article about the QuickBasic Caliber Programming Competition, Matt2Jones has submitted the first in his series of new comics, Bobby The QBasic Maniac, and I've written an article entitled Does The World Need Another QB Forum?. I've also started a column called "Blast From The Past" which discusses old and dead QB sites or programs. This time, it's all about Sneukeule's QB RPG Page. And of course, I've written up the latest QB community news.

The biggest section of this issue, however, is our focus on badlogic Software, Blitz and V1ctor's programming group. Interviews with both Blitz and V1ctor have been conducted, and this issue's Gallery is devoted to their new game, a clone of Counter Strike 2D. There is a heavy focus on V1ctor's online library for DOS, DSock, a powerful but under-used application. V1ctor's interview is dedicated almost entirely about DSock, and is prefaced by a short article on the library. Finally, Marcade's awesome DSock Tutorial Document is included to help you guys learn how to bring your QB games into the Internet age!

An Open Magazine

Also, you may be wondering about this issue's Comics section, which includes nudity and violence that some may find objectionable. I have decided that it is more important to include content from everyone than to selectively choose who can and can't have their submissions published in this magazine. This is the only truly fair way of running a magazine. If you're easily offended and don't want to see the comics or any other article, then don't read them. You're not forced to read this, and if it bothers you, you can either quit reading or tell us about it. We value your opinions.

QB Express is an "open" magazine, meaning that we are dedicated to free speech and opinion. We believe that everyone, no matter who they are or what they believe, has the right to have their voice heard. Anyone who wants to write is allowed to, and anything that is submitted will be published. We will not censor out strong opinions or commentary, and we will include anything that has any value to the QB community. Only gutter trash, tasteless commentary or images and useless dreck will not be published. Anything else is fair game.

Enjoy!

A lot of hard work has been put into this first issue, and I am very pleased with how it turned out.

But as you read through this issue, keep in mind that I am always in need of submissions of all types for future issues. If you have any QB news you would like me to include, or would like to write a tutorial, editorial, article or review, be sure to get in contact with me! I can be reached through my email address, pberg1@ithaca.edu, or this form. Remember, this magazine can't survive without YOUR support!

I hope you enjoy this first issue of QB Express!

-Pete


Letters

Letter From Matt2Jones

Pete,

At the moment I'm searching the net for a board to post this proposition on, and seeing a you have a magazine, this would be a good place to start.

I've been coding in QB for six years now, thats getting to be a big number, and I've been in on the 'scene' for four, and most of the people who were around when I came in, are all dead and gone now... QB generations seem to be only about a year, so most participants (or me at least) don't really know the history of this, just what came around during their time. You've got a huge archive of magazines on your site, which is allot of info to work with, and you've been around awhile, so doubtless you know of others who've been around before you....

How about a history of online QB? It'd be and interesting first issue article, and you've got the resources to make it quite detailed (major sites, program releases, coding groups, coders, trends)... If you remember the history of 3D in QBCM, I mean something like that...

It's an Idea I'm having right now, I just thought I'd tell you, I don't mind if you ignore it.

-Matt

Thanks for all the ideas!

As for QB history, there will be a regular section called "Blast From The Past", which will cover an old QB game or site that was once an important part of the QB community. I will focus on content that is no longer available online, or has long been forgotten. This month, "Blast From The Past" discusses Sneukeule's RPG Page.

I have actually already thought about doing QB history articles in the new magazine -- not an article or series that tries to cover all the history at once, but shorter articles that discuss just one aspect, such as "The History of QB Platform Games", "The Rise of QB Graphics Libraries", or "Tsugumo's Influence on the QB Community". Of course, it will take a lot of time and research to write these articles, so I'm not going to be doing it for this first issue. In future issues, though, QB history articles may end up being a regular feature.

If you (or any other QB history buffs) are interested in writing an article, though, you should by all means do it! Email me and we'll talk!

-Pete

Letter From Marcade

(This letter is in response to some questions I asked Marcade about V1ctor's online QB library, DSock.)

Hey Pete,

You should really stimulate QB programmers to use DSock .. because it has a hell of a lot potential. Somebody also should use it to make a new DS4QB version. I believe, the current version uses an indirect way of communicating with a windows slave client .. through files or DMA 0 or whatever .. With using DSock, a 'direct' connection can be made and lag between the QB app and the client could be minimal ..

Originally I think the DSock library was going to be used in Subshock, a project ran by some other QB'ers. The Subshock project died (I think?) and V1ctor got tired of waiting. If I remember correctly, earlier versions of DSock already existed years ago, but the Subshock team did not want V1ctor to release it to the public. You could ask V1ctor for more details though about this.

When DSock came out, WisdomDude and I created an online version of Connect 4. [You can find it here.] Connect 4 was released with the source code for people to learn from it. Of course all this only if credits are given. (Not only to me; Wisdomdude did the biggest part of C4; I only added DSock .. and V1ctor created DSock; the DSock Tutorial Document [included in this issue] was created by me.) The Networking code of Connect 4 can be used by other people if they want it (as long as credit is given). It's programmed in a way that it can be reused .. Actually the DSock code in Connect 4, was originally code from an MSN client I wrote in QB before I worked on Connect 4. Unfortunately because the MSN protocol has changed (and since I lost the source in a disk crash), the compiled version doesn't work anymore. :'-(

The DSock library is very much like the socket library for C or the CSocketmodule for VB6.0. I'm in to do anything to support other programmers using DSock. My Draft/tutorial document is incomplete by the way. I haven't explained in there, how to listen and to accept to incoming connections. But that is very easy .. people can look at the source of Connect 4 to figure it out .. basically.

Good luck with the new magazine!

Best regards,
_Marcade

Thank you for all the DSock info, Marcade! I agree with you that we should promote the use of DSock and the creation of online QB games. Online games are the next step in game development from the current generation of QB games, and I'm glad to see that people like you, V1ctor and WisdomDude are making headway!

As you can see by this issue, I have included your DSock Tutorial as well as an article about DSock. Hopefully people will take notice of this splendid application!

-Pete

Letter From Kevin D.A.G.

Hey Pete,

I think you have a great idea. Making a QB mag could really stimulate the QB world. On the topic of a title, I think "The QBasic Folio" sounds attractive to me.

Good luck with your project, and THANKS for hosting my game (Astral Worlds)!!!!!

-Kevin D.A.G.

Glad to hear you're excited about it! I have currently settled on QB Express for the title, though it is by no means final. It's more of a working / temporary name, that could very well be replaced. To me, The QBasic Folio has a sort of a snooty, aristocratic air to it, but I will certainly change the title if enough people prefer that name! Drop me an email and tell me which title you like: Express, Folio or something completely different!

-Pete


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 is your favorite QB Graphics Library?

LibraryVotesPercentGraph
DirectQB1528%
Future Library815%
Dash24%
RelLib1019%
Blast!24%
GSLib36%
UGL713%
Other59%
53 Total Votes

News Briefs

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

QB Site News

Pete's QBasic Site Returns

After a four year hiatus, without regular updates since mid-2000, Pete's QBasic Site has returned! Pete's QB Site was once one of the most popular QB sites on the Internet, famous for its "daily updates" policy (which lasted from October 1998 to May of 2000) and for being the first site dedicated to doing in-depth reviews of QuickBasic programs. The site secretly underwent a complete redesign between December 2003, and July, 2004, and opened its doors officially on July 22. This came as a big surprise to members of the QB community; you can find some reactions at V Planet! and QBasic News.

In addition to all of the old content from Pete's QB Site, many new additions have been made. The most significant of these include:

  • An automated script which allows users to instantly add content including program downloads, QB News articles, tutorials, FAQ entries and much more. Additionally, the Program Downloads section now includes full descriptions of programs, and instant ratings by the users.
  • The largest collection of QB Tutorials on the Internet. This section was recently revamped and now includes over 300 QB tutorials for download.
  • The QB Zines section, which archives over a dozen different QuickBasic magazines in one easy-to-access collection.
  • A gigantic links collection, which is the largest QB links collection available anywhere. Every link comes with a button image, a description of its Unique Features and a rating from 0 to 5 stars. Sites that get a perfect 5-star rating are presented with the "Five Star Site Award". So far, of the 315 links available, two have been awarded a perfect score: V Planet! and QBasic News.
  • Many other sections including: QB News, Top Ten Programs, Projects, Affiliates, QHumor, QB Philosophy, The Hall of Fame, The QBasic FAQ, Pete's QB Site History, and much more!

V Planet! Reconstruction Still in Progress

Since March, the popular QB magazine and reviews site V Planet! has been undergoing a massive reconstruction process. The magazine will be reformatted into "a friendlier, more workable php format" that will make updating the magazine easier. In April, chief editor Vance Velez stepped down from his position, and it was announced that QB On Acid would merge with V Planet! and that QBOA editor Nekrophidius would take charge of the magazine. Since that announcement, V Planet! has been very silent, with only two updates and five new articles since April.

Recently, Nekrophidius informed us that V Planet's reconstruction is still underway, and that all of the content leftover from the unpublished QB On Acid issue #12 will appear on the revamped V Planet! when it is finished. Accordiing to Nek, the site will appear at vplanetmag.com, though as of press time, that url is a dead link.

QB45.com Reconstruction News

QB45.com, once one of the largest QB sites ever created, has gone through crisis after crisis over the last year. Several months ago, QB45.com was brought to its knees by a crippling crash which left the site down for three months. At one time the most-visited QB website on the Internet, the site previously known as Future Software was left a shadow of its former self. Now, the site has been temporarily replaced with a message board as a new script-driven website is designed.


Bigfoot now adorns QB45's "Under Heavy Construction" logo.
 

Two members of the QB45 community, QB RPGs headman Fling-master and Joe have taken it upon themselves to restore the site to its former glory. Though Joe and Fling-master are currently heading the massive reconstruction project, they are being assisted by many other QB45 members.

The most recent update on the renovation process came on July 18, when some major updates to the forum were made (read about it here). A preview version of the unfinished QB45 site, with nothing but the massive downloads collection, is available here.

Currently, Fling-master is searching for about 100 missing files from the former QB45 collection, and members of the QB45 message board have been discussing how the new website should be divided up to tailor to different programming languages.

Future Software and QB45 founder Jorden Chamid once said this site would never go down as long as there was a QB Community alive on the Internet, and based on the recent progress, his promise seems to be holding true.

Is the old Future Software Returning?

While the QB45.com reconstruction is going on, two QB45 members, Jatos and TheBigBasicQ have banded together to restore the old Future Software site, which evolved into QB45.com in 2002. Future Software's old site was widely visited and well-loved, offering much unique and original content that disappeared from QB45.com during its many makeovers. Last month, TheBigBasicQ posted messages around the QB community asking for anyone with old copies of Future Software content to send him copies. TheBigBasicQ wrote: "We want to find out if its feasible for us to recreate [Future Software]. But that depends on how much content we get from the old site." As of this time, we do not know if Jatos and TheBigBasicQ have decided to continue their recovery effort.

QBasic.tk Announces New QB WIKI

Sumojo of Qbasic.tk announced that they are beginning a new QuickBasic WIKI, or online encyclopedia. They have invited users to sign on as contributors and add articles. This will be a neat idea if they can get enough contributions, but otherwise you're better off using existing resources like QBasic News Online Help, Dav's QB Knowledge Base or Pete's QBasic Site's Tutorials.

Recent Redesigns

Recently, Delta Code and Atosoft have undergone major redesigns. Delta Code has a lot of great content to read and download, and a nice feel to the site. The "purple mountains" design is pretty sweet. Atosoft, on the other hand, is basically an empty page. QBasic.tk has also introduced several different skins recently, and if you become a member, you can choose your favorite layout.

Project News

Syn9 In Three Dimensions

Recently, Syn9 released a snazzy-looking QB 3D demo over on the QBasic News forums. This demo allows players to walk through a medieval town with breathtaking graphics, as you can see in the screenshot to the right. Syn9's engine supports both bumpmapping and lightmaps, and the first release used DirectQB (though Syn9 was considering switching to RelLib or uGL). The maps were created using the map editor that Syn9 made for Vampira.

Also, Syn9 recently announced the creation of a team for a 3D RPG, which quite possibly could be based on the engine described above. He posted the following on the QBasic News Forum: "Syn9 is getting a team together to work on a possible 3d RPG project or to work on ZeroG2 using UGL. If you would be interested in collaborating on one of these projects, you can email Syn9 at syn9@rpgdx.net." QB Express is very excited about Syn9's engine and possible RPG, and we'll be sure to bring you the latest updates in future issues.

Frantic Journey Preview Room Updated

The website for Adigun A. Polack's highly-anticipated space shooter, Frantic Journey, has received some cool updates recently. Now if you visit The AAP Official Projects Squad, you will find artwork for an "all-new original design of a huge battleship for the Gigantic Battleship Stages" and "six (6) entirely different music tracks of [Adigun's] for FJ that you can preview for yourself." If you didn't already know, Frantic Journey is a horizontal space shooter with awesome graphics, some unique level designs, and and SNES "Mode-7"-style effects.

Badlogic Wows With Their CounterStrike 2D Clone

Blitz and V1ctor announced a clone they are making of Counter Strike 2D, and released some screenshots. Check out this issue's Gallery for more details.

Zelda Clone?

QB Express has received word from an anonymous source that a clone of The Legend of Zelda for NES is currently being made in QB. This project is in its very early stages right now, and the author "is not making any promises." Recently, the author has been teaching himself how to make Nintendo music, with the idea that he will include it in this Zelda clone. If this project is indeed finished, it will inclde a level editor so that users can quickly and easily make their own Zelda adventures.

Competition News

QuickBasic Caliber Programming Competition

Adigun A. Polack's QuickBasic Caliber Programming Competition 2004/2005 has seen much activity as of late. For more information, see Adigun's QBCPC article.

Rhiannon's QB Tutorials Competition Has Ended

On June 19th, Rhiannon started a BASIC Tutorials competition over at The BASIC Network. This competition was open to tutorials about all forms of BASIC, though most of the submissions were for QB. The competition ended on August 15th, after it was extended for an extra two-and-a-half-weeks. Results from the competition have not been posted yet, though you can find the latest information at The Basic Network's Message Board.

Dunric's 1 to 2K Text Adventure Competition

Dunric, a QB coder who is famous for his gigantic text adventure Westfront PC: The Trials of Guilder as well as some other ASCII graphics games like P.R.O.G.U.E., has recently announced a competition for programmers to create the best text adventure they can, using only 1 to 2K of code. Over the years, Dunric has wrestled with optimizing his text adventure code to make it as memory-efficient as possible. In June, Dunric got the idea that others might also enjoy his hobby of budget adventure game coding, so he opened up this contest for interested text adventure programmers.

Esotera Text AdventureAccording to Dunric, he will accept text adventures written in over a dozen languages, including every dialect of BASIC. As for the file size, "The 2K size can be either the source coce, or the EXE, BIN, OBJ, PRG, ELF or other self-contained, self-running binary. So you can thus have, say, an 8K source code listing, so long as the binary format doesn't exceed 2.9KB of size. You may also crunch the binary down with a compressing program such as UPX or Winzip." To help get entrants started, Dunric has written an 8KB adventure game called The Melarkian in BASIC.

Dunric's competition officially began on June 28, 2004, and it runs through September 29, 2004. All submissions will be posted on the official site, where they will be reviewed and graded by Dunric. (Grades will be posted on October 7th.) For more informatino, visit The Official Site.

Sumojo's Maze Challenge

Sumojo of QBasic.tk ran a neat maze challenge on the QBasic.tk and Qbasic News message boards. The contest was to create a program that could find its way through a text maze:

"In this challenge you will nagivate your way through a rectangular maze. The maze is a 10 by 10 grid of cells where each cell is either a 1 (representing a wall that you can't go through) or a 0 (representing a passage way that you can go through). There are two cells on the boundary of the grid which will be marked 2 (representing the entrance into the maze) and 3 (representing the exit out of the maze)...

Your program should identify the locations of the entrance and the exit and display the "path" from the entrance to the exit. The path should be a string of characters made up of the letters N, E, W, S (in upper case) denoting North, East, West, and South repectively. Note that there will be exactly one path from the entrance to the exit represented by the sequence of 0's between 2 (the entrance) and 3 (the exit).

Example maze:
1111111111
1110000002
1110111111
1110011111
1111011111
1000011111
1011111111
1011111111
1000011111
1111311111

The output for the program should read: WWWWWWSSESSWWWSSSEEES

The contest ended with two winners: red_Marvin and Plasma. You can read more about it here.

Other News

Dale Harris Point of Sale on TV

Johnathon Simpson recently posted some cool news on the QBasic News forum: "The DHPOS program that I work with (written in QB) was on TechTV last week, on the show "The Screen Savers". I'm trying to get hold of a tape of the show, but I thought you guys might like to know that a QB program was featured on a cable TV show.

"I didn't write it, although I help out with the project a bit. It's got about 54,000 downloads since we started counting, roughly 100 a day, and it's used all over the world (45 countries known)."

You can find Dale Harris Point of Sale at this address: pages.prodigy.net/daleharris/pos.htm


Gallery

Every issue QB Express features a exciting new screenshots from an upcoming QB game. If you would like your game featured, send in some screenshots!

Counter Strike 2D Clone by badlogic

On August 20th, V1ctor and Blitz of badlogic posted the first amazing screenshots of a Counter Strike 2D Clone that they are making. (Counter Strike 2D is a PC game available for free at http://www.cs2d.com.) badlogic is "trying to get it the closest possible to the original - that needs a 3D card to work, btw :P". Currently, the game "loads maps, tiles, etc. from CS2D, and clearly supports several soldiers at once as well as large amounts of bullets.

The graphics are all presented in snazzy SVGA, and are enhanced with uGL's new 2DFX Module. 2DFX "has many blending modes that can only be found in big APIs such as Direct3D and OpenGL." Its most significant feature is its ability to create anti-aliased sprites and realistic shadows. According to Blitz, "Those wall shadows in the screenshots are all done in realtime without any special sprites. The 2DFX module just creates a shadow from the original tile and blends it with the rest."

As for the game itself, Counter Strike 2D Clone promises to have TCP/IP multiplayer, so you can play it on a network or over the Internet -- "which you most probably will." Blitz says that "it's quite a fun game." Judging by the screenshots, I'm inclined to believe him.

From what little I've seen of this game, I am very impressed. I can barely even judge this game in the same category as most other QB games -- it has SVGA, amazing 2D graphical effects, and network play. Since when has QB been that powerful? The 2DFX Module for uGL sounds like it's going to bring QB graphics to a whole new level, and I'm looking forward to seeing how the Internet play on this works out. According to V1ctor, he hopes to release the full game "soon", so I would suggest dropping by Bad Logic's Forum for the latest on this revolutionary game.


Six guys go at it on the helipad. Check out that glowing effect on the red and blue lights.


Watch the bullets fly! This game's particle system can clearly handle dozens of bullets.


Blast From The Past!

Written by Pete

Every issue, we take you back in time to the early days of QB on the Internet and show you a lost relic of the QB Community. This is your Blast From The Past!

Sneukeule's QBasic / QuickBasic RPG Page

Back in 1998, right in the middle of the QB RPG craze, a guy named Sneukeule started the first ever site dedicated to QB RPGs. Sneukeule's QBasic/QuickBasic RPGs Page had an absolute bounty of information and downloads for aspiring QB RPG programmers. There were dozens of tutorials, theory articles, downloads of all types of utilities, game engines and example programs to help you create a QB RPG, and an active "QBoard" where you could get programming help or discuss the latest happenings in the QB world.

Most importantly, Sneukeule's QB RPG page hosted the largest collection of QB RPGs and RPG demos ever put together at that point. Remember that this was at the height of the QB RPG craze, so everyone and their mother had their own RPG demo out -- and Sneukeule collected and archived them all. They were classified by type, and each came with a screenshot, much like the current reigning QB RPG champ, QB RPGs.

But even in that early period of 1998-1999, Sneukeule's QB RPG Page had MORE QuickBasic RPGs listed than QB RPGs has today. I did a quick count, and found 177 RPGs listed on the site; 37 were listed as "Upcoming", but all the rest were available for download. To put that into perspective, QB RPGs currently has only 131 RPGs in all...and it has had an extra five years to accumulate the latest releases.

Most of these games are walking demos with very little gameplay, but there were quite a few gems in the bunch that have since disappeared completely from the Internet. It's quite unfortunate that Sneukeule's amazing RPG collection was lost due to Geocities and Fortune City server purges, because this site was one of the greatest resources the QB community has ever known.

Still available through the Archive.org backup of Sneukeule's site is a collection of thirty-two brief interviews, conducted mostly in fall of 1999, with many prominent members of the QB community. The interviews ask people like Tek, Tsugumo, Nekrophidius, LordQBASIC, MagnaUnum, Michael Hoopman, Jay Cook, 19day and Danny Gump about the RPGs they were developing. These are quite an interesting read, and will really give you some insight into the QB RPG obsession of the late '90s.

Sneukeule quit updating his site in February of 1999, and it remained online until 2001 -- though many of its download links and images had broken by then. Still today, there are remnants of the site at his old Fortune City account, though not much is left.

Since Sneukeule's site shut down, other sites devoted to QB RPGs, such as the QB RPG Top 50, QB RPGs, RPG-Dev.net, the late QB-RPG Scene, have risen. But still, to this day, none have been able to match Sneukeule's incredible quantity of RPGs, tutorials and interviews.

Of the hundreds of dead QB sites on the Internet, Sneukeule's QB RPG Page is among the the few that I most would like to see restored. Even with most of its content missing, it is more interesting than the majority of QB sites around today. QB history buffs: this is an absolute treasure trove of QB history, and is not to be missed!


You can find an archived copy of Sneukeule's QBasic/QuickBasic RPG Page at this address.


QuickBASIC Caliber Programming Compo 2004/2005

Written by Adigun A. Polack

Adigun Azikiwe Polack of Aura Flow, Frantic Journey and Star Angelic Slugger fame is here to give you the latest news on his latest competition, The QuickBASIC Caliber Programming Compo 2004/2005.
 

The ULTIMATE QuickBasic Programming Challenge!

The current QuickBASIC Caliber Programming Compo 2004/2005 is so intensely awaiting new and aspiring programmers of QuickBASIC/QBasic to create something wildly revolutionary and never-before-seen in the QB project universe. Be it young, old, beginner, expert, or seasoned veteran, it doesn t even matter one flat bit, as EVERYONE IS DEFINITELY WELCOME to sign-up and partake of this tremendously grand QB programming gala!! ;*) ! In this compo, it so far has recently introduced the following:

Also returning to the scene is a real interesting category devoted to SNES Mode-7 -based graphics demo in QB!! Should be a lot of fun! :D

Let us now give you some of my compo background history here.

The QuickBASIC Caliber Programming Compo (aka QBCPC) originally created and founded by none other than me, Adigun Azikiwe Polack has first been introduced to the QB45/QB71 community near the end of 2002. My first one was entitled QBCPC Winter 2003, which was sadly cancelled due to absolutely no entrant sign-ups at all before the deadline of April 1, 2003. And a bit later, my second compo has arrived and it was called the QBCPC Summer and Autumn 2003 . Those two compos had the sheer makings of an *excellent* QB compo, in that it showed you A BIG-TIME PLENTY of inspiration files to enable you and get you pumped up to create your very hottest and winning QB project, whether game-based or otherwise! If there was only one serious problem that TOTALLY turned off (and even offended, too!) apparently a whole lot of people was such too many needless and overly strict limitations from my previous Official Rules that possibly angered them. Even I absolutely did not know that at all!

I was so merciful enough and also generous enough that during the month of July 2004 and ever since then, I plain had to get down on my face here and just brutally correct myself publicly by plain majorly changing the Official Entry Rules of the QBCPC 2004/2005 to encourage more and more people like you to enter this special QB event. ;) The new rules are now *ENTIRELY* different from my previous two compos, making the gala much more of a masterpiece for helping you create positive and truly revolutionary originality in QuickBASIC/QBasic!!!

For instance, some of the newest things that are _NOW ALLOWED_ in my compo are:

Animť-like or otherwise, YOU ARE WELCOME TO ADD THEM IF YOU DESIRE TO!! ^_- !

Also, the many needless and unwanted limitations have been recently shattered apart! And as for no more than only a few limitations that are needed, they are all balanced now to help you create positive originalities in your potentially awesome project through your own QB programming!

With all of that and more, the QBCPC 2004/2005 is dead-seriously shaping up to become the biggest, hottest, and most amazingly improved QB compo of 2004. So don t you even be afraid to enter it, as there is a lot of intensified excitement that I want to show you in there!! ;*)

For more details on how to enter as well as the amazing improvements that I have made to my Official Rules, please be sure to check them all out beginning at http://dhost.hopto.org/aapproj/qbcpc. BE SEEING YOU THERE, and *much* splendid QuickBASIC/QBasic coding to you all at this current and most challenging contest!!! ^_^ !!
 

WITH SUCH WONDERFUL RESPECT TO YOU,

Adigun Azikiwe Polack
One of the Founders of Aura Flow
Webmaster of the AAP Official Projects Squad
Official Founder of the QuickBASIC Caliber Programming Compo


Interview With Blitz

Conducted by Seph

In July of 2003, a group of QB programmers at the QBasic News forums discussed ideas and made plans for a new QuickBasic magazine that never got off the ground. For that ill-fated magazine, Seph conducted this interview with Blitz, which has neve been published anywhere but in the original thread at QBasic News. Blitz is a member of the QB programming group Bad Logic, which is behind the revolutionary QB graphics library UGL. Since this magazine was partly inspired by that QBasic News thread, I have decided to include it in the first issue. This interview is presented in its unedited, original form, so you'll find quite a bit of off-topic (but interesting) banter.
 

Introduction by Seph

Very few libraries for QuickBASIC are still being worked on to this day. Fortunately, one of the best libraries around is an exception. UGL is a TLA standing for the very appropriately chosen words "Ultimate Gaming Library" and is written by 2 of the best programmers anyone has ever met in the whole world. I get paid 30 USD just to say that. I had the opportunity to talk to one of these brilliant men, and unlike many in my life, that is an opportunity I have taken.

Seph:
So how did you decide to start working on UGL?

Blitz:
Well, I was hanging in our IRC channel (as always) and was pretty bored. So I was thinking of stuff I might do to waste time. The idea came to me to do a graphics library for 320x200x16 which would have one thing in mind, and that being performance. And also have things other QB libs lacked, surfaces. So I asked v1ctor if he wanted to be part of it and he said yes. So you could say that we made UGl becuase we had nothing better to do. I'll kill your cat if you don't fix my damn spelling and grammar errors...

Seph:
Sure thing. About when did you begin work on this library?

Blitz:
Good question, the answer is way too long. But I think it was just about two years ago. Of course, we never planned working on it for so long.

Seph:
Was there any library in particular that inspired you to write this library to be the fastest of ALL TIME?

Blitz:
Me? Not really, but I think allegro inspired v1ctor in someways, but us both having done lots of non-QB coding. We had seen how the big APIs were designed and knew how a good lib should be.

Seph:
Ah. Were there any other people involved in this project besides both you and v1ctor? Not to mention, v1ctor's first name is not victor...

Blitz:
Well my first name isn't Blitz either.

Seph:
Indeed.

Blitz:
Any other people? Hmm, the only person that comes into mind right now is Eric Cowles aka 1000101. He helped out with lots of bugs. I'm sorry if I forgot anyone

Seph:
Did you ever think that it was possible this "Eric" character was planning on rewriting your very own library, and then killing you?

Blitz:
Nah, Eric was working on future library 2. But I think they gave up on that when UGL came out.

Seph:
Because UGL was so much better than anything Eric could ever do in his life, yes?

Blitz:
Oh, I just remember a person I definitly would not want to thank. Alan 'O Hagan known as CGI Joe/Generic. He was supposed to do lots of things for UGL. But he never did more then a few lines on anything. That lazy bastard.

Blitz:
No, Eric is one of the few programmers in the QB community I have respect for.

Seph:
Jerk, I have feelings too...

Blitz:
He could do a lib like UGL, no doubt.

Seph:
Are there any comments you would like to make to anyone making a library for QBasic?

Blitz:
I would like to say that coding style and code organization is very important. It's one of the top things differ from someone who can be called a pro-coder and someone who can't. I also would like to add that PureQB(tm) is pretty lame. Coding old demo effects from the 80s doesn't make you l33t, nor does it make you a good coder. On the contrary... You don't learn anything from PureQB coding but bad coding habbits which does not apply to anything when you start doing pro- programming in C/C++ or any other advanced language which has decent compilers. By trying to optimize code yourself when you have a good compiler you're actually crippling the compiler's ability to do good optimizations. And another thing that I have noticed is that QB coders are not willing to let go of their old coding habbits. They are not willing to try/learn new things. That's bad if you ever want to work as a programmer. A programmer always have to be ready to learn new things and solve new problems.

Seph:
Speaking of PureQB, what do you think of the concept?

Blitz:
I do not have the words to describe how stupid it is that people actually call it a concept. Good programming is about making fast programs that use as little cpu power as possible, not to convert your 3 ghz cpu to a 33 mhz 486. That's exactly what PureQB(tm) does. What makes you "l33t" is your ability to get your program to use as little cpu power as possible and still run smooth. It's perfectly ok to mix C or Assembly with your qb code.

Seph:
I see. And are there any programmers you would like to give a shout out to? Feel free to not exclude me...

Blitz:
Hmm, I have a feeling that I will forget lots of people. But here it comes in no specific order. v1ctor, Toonski, 1000101, CGI Joe/Generic, Lithium, Sephiroth, Nexarinius/Mr Moose, Smokey, Joakim A-R, Fling-master, Syn9, Marcade. And of course, to all the loyal UGL users. Can't think of any else right now, sorry if I forgot anyone.

Blitz:
Not really, but feel free to write some good things on UGL and don't forget to fix the gramar and spelling.

Seph:
Indeed.


Visit the badlogic for uGL, great tutorials and free cookies.

About DSock & An Interview With V1ctor

Conducted by Pete

In the days of yore (the '90s), online gaming with QuickBasic was just a glint in most programmers' eyes. Networked games in QB were the stuff of legends; programming one was a near impossible feat. Nobody knew how to make a decent online game in QB. In those days, there were a few experiments with networking -- tutorials on how to use the modem were released, an application that used IRC to exchange game data surfaced and fizzled away, and some developers offered downloadable levels and the ability to post high scores on their websites. But nobody ever really figured out how to bring their QB games online.

Enter V1ctor, a talented QB and ASM programmer with a natural knack of figuring out stuff that nobody's ever done before. (If you need evidence, just take a look at the fastest QB library ever, uGL.) V1ctor signed on to help bring a promising game called SubShock online, with an innovative new technique: interfacing directly with the built-in Windows TCP/IP handler, Winsock. V1ctor put his mind to the task and created DSock, the first *good* method to bring QB online. This new technology had incredible potential, and it should have turned the QB world upside down....

...Unfortunately, SubShock was never finished, and DSock was only ever used to bring one game online: WisdomDude and Marcade's Connect 4 QB. Since then, V1ctor's incredible techniques have gone largely unnoticed, much to the chagrin of DSock's biggest proponents (see Marcade's letter to the editor).

In this issue of QB Express, we present to you an interview with V1ctor (below), information and screenshots about badlogic's upcoming Counter Strike 2D Clone which promises online multiplayer, and Marcade's DSock Tutorial Document to show the potential of DSock. I heartily encourage everyone to learn about and experiment with DSock. Now there's no excuse for QB programmers not to make online games!

The Interview

V1ctor is well-known through the QB community as one-half of badlogic software, the group behind the graphics library uGL and the DSock networking routines that make Internet and networked QB gaming a reality. I conducted this interview with V1ctor to help spread the word about his incredible DSock routines.


>> First off, can you introduce yourself and your programming group, Bad Logic?

Well, i'm from Brazil (aka jungle, oi!), i began messing with qbasic (not qb!) when i got my first computer, 8 year ago or such. Around 6 months later i started to make routines in assembly, when i got my copy of QB 4.5 and could finally use external libraries (oh, those days..). Now i do web coding for living (surviving?). Badlogic is the group created by the dirty mind of Blitz, he controls the whole thing. It's a group of just 2 people, so.. it's not really a group (hmm).

>> You are definitely an accomplished QB (and ASM) programmer! What makes you focus your time on QB when you could work with other faster and more versatile languages?

I passed the last year coding - boring web stuff - in PHP and Java mainly and had no time for other projects (uGL for example). I've got a free time lately and then i restarted working on uGL again, fixing bugs and finishing the 2DFX module, that was an idea i had for years. 2DFX allows the creation of 2D games with features like different kinds of blend modes that couldn't be done in any QB lib yet. Our upcoming game, the Counter Strike 2D clone, is an example of usage of that module - the game was first written to be a test and to show how 2DFX worked.

>> Explain what DSock is in one sentence, for somebody who has never heard of it before.

DSock is an DOS interface to Winsock, that's the API used in Windows to access the Internet or a local network. No other DOS Winsock library offers the number of options that DSock has, as it tries to be a 1:1 map of the Winsock 1.1 API. If you know how to code net applications/games for Windows, adapting them to QB wouldn't be too hard.

>> What inspired you to make DSock?

Well, that's a long story, that involves being part of the defunct team and.. i don't want to talk about that, sorry.

>> Shortly after you released DSock, WisdomDude and Marcade used it to make an online two-player game called "Connect 4 QB". What do you think of Connect 4 QB?

I'm glad they made that game, it was really fun to play and stills be used as an example of how DSock works - well, it's actually the only game that ever used DSock, anyways ;)

>> How exactly does DSock exchange data between players? Is it only suited for slower, turn-based games (like Connect 4 or Pool), or can it handle fast, real-time action games?

It can be used for any kind of game, you can exchange data every frame, as you do to control the local players. Dsock is a small layer between DOS and Windows, there's no polling, no copy, no files, no clipboards being used. The only difference between a QB game using DSock and a Windows application using Winsock is that a real- to protected-mode is done on each call to the interface, what can slow down things badly, if done many times per second. On a 600MHz CPU or better it won't be a big deal.

>> Recently on the badlogic QuickBasic forum, you posted a screenshot and information about your upcoming Counter Strike 2D Clone. (It looks amazing, I might add!) How do you plan to handle online multiplayer support for that game?

Thanks ;). We plan to use the original CS2D protocol, so you could be able to play against other players that are running the original game and join their servers - that will have more players than any QB-only server would, of course. The problem is that.. we don't know the protocol used :/. CS2D is closed-source and the developers don't want to tell us about the network protocol, because it's not secure enough yet and such. We will see what can be done.

>> What are the main limitations of DSock?

Mainly the limitation of DOS, real-mode and QB ;). It's hard to create servers, because you need linked-list that are a pain to do in QB. There's the penalty of real-mode to protected-mode switching that is needed in most calls done to DSock routines, as the Windows drivers run in a different processor mode. The bad part is that the Windows 9x/Me version is NOT bug free, it can crash the DOS box sometimes, mainly because the interface is *completely* based in hacking, done by me and coders that wrote other Winsock DOS interfaces. The Windows NT/2k/XP driver is pretty solid, never had any problems with it (*knock on wood*). Now that most people switched to Windows XP, well, i don't think it's really a problem - i can't debug the Windows 9x interface anymore, i've only XP installed on a NTFS-formatted HD.

>> Since its release, only one finished game has been created with DSock. Why do you think so few QB programmers have tried DSock?

Well, coding a network protocol for a game is not an easy task, you probably know. It seems simple when you plan do add that, but turns into message processing, latency compensation, players synchronization and so on.. For most coders (including me), Winsock can be a bit confusing when you start working with the API and yet you can use blocking sockets together with threads in Windows, what makes a server much easier to write, and that can't be done in DOS, unfortunately.

>> Have you and Blitz ever considered bundling DSock as part of uGL?

I thought about making a high-level game protocol on top of DSock, that would be added as a new module to uGL. If we get CS2D really to multi-play, we will probably have half of that module done, then it may be adapted to a generic one, if i've free time and there's enough interest :P

>> Any final words?

Thanks for the interview, that was the first one i got invited ever ;).. Keep the good work with your site, QB really needs that!



Does The World Need Another QB Forum?

Written By Pete

I think it's a testament to the amazing advances in message forum design these days that an entire site can now be based out of an Invision or phpBB forum. In fact, forum-based-sites, with all content submitted by users, have become quite popular in recent years, perhaps because they're self-moderating and so easy to set up. Many QB sites have taken up this format; QuickBasic community sites like QBasic News and QBasic.tk are run almost entirely from message boards, and QB45.com has been replaced with a board while it undergoes a massive reconstruction project. Instead of relying on a webmaster to stay current, these sites are autonomous collectives or anarcho-syndicalist communes (I've always wanted to use those terms) -- they're run by the users, for the users. It's proven to be a very successful format.

But for some reason when somebody decides to start a new QB forum, nobody's happy. On July 25th, a chap named Semerkoala announced the opening of his new forum-based site, and that he was looking for members. Semerkoala QB is an Invision Power Board hosted by MyFreeBulletinBoard.Com. It's divided into sections for members to post tutorials, program downloads, questions and answers, QB news, and more, though not much has really been posted yet. As far as content goes, it has a handful of downloads and tutorials that are widely available throughout the QB Community...and a little bit of news and information. That's about it.

It comes as no surprise that Semerkoala was instantly lambasted by the QB Community for having the audacity to start another QB forum. Their responses were hostile: on the QBasic News board, Barok posted "we have enough qb forums! This one is good enough. I refuse to even look at it." Dark_prevail seconded Barok's opinion: "I think we should have a sticky topic entitled NO NEW QB FORUMS!" Others said that there weren't enough people in the QB community to populate all of the message boards out there. Everyone was picking on Semerkoala -- angry because, as Fling-master put it, "too many people starting too many forums with too few unique features."

Seeing this mercilous flaming, I knew I had to step in and defend Semerkoala. After all, I am in the school of thought that *any* development in the QB community is a *good* development. The number of new sites and games released is declining at astronomical rates, and the only way to ensure that the QB community continues to attract new members is by offering something fresh. That's why I redid my website, and made this magazine. I also have created the largest QB links section on the Internet in order to help QBers share information and learn. The way I see it, anyone that takes the time to make a QB site, no matter how small or pathetic, deserves a link.

I posted the following message on the QBasic News forum:

I support anyone who decides to make their own QB site / forum / etc.... we need growth in the QB community, innovation, new blood. I'm glad that Semerkoala's trying his hand at creating a new site, even if it is based on a forum. If he works on it diligently for long enough, it will undoubtedly become something great.

Now I'd like to point out something about Semerkoala's forum that you might not have noticed if you didn't look closely: it's not just an empty forum meant for discussion. Semerkoala's using it more as an automatic content-management script, instead of creating a site based on HTML pages. Each "item" that he adds to his site is its own post, whether it's a tutorial, a program, a link, etc. This strategy also opens up the site to some unique possibilities, like automatic user commenting, searching, and sorting items based on various criteria. This format has proven successful at other QB sites like QBasic.tk (which is a great site, I may add).

Now I have to agree with you all that right now, Semerkoala's site has nothing original to offer, and is hardly in need of a forum. But I don't think of this so much as a discussion forum, but as a standard QB site that's based on a forum.

Tek of NeoZones posted this on the last version of NeoZones before it disappeared:

"Back in the day, a good recipe for [a QBasic site] was rather simple. A laundry list of downloadable files, links, tutorials, questions and answers, the infamous discussion forum, and some other goodies. Stir a user system in to the mix, sprinkle with the ever pervasive link to the top-sites list, and decorate with a couple webrings. You've got yourself a formula for success. And don't forget about your RPG that's in the works, either."

If you look at Semerkoala's site, it's following the "laundry list" recipe for a QB site...it's just based entirely on a forum. So cut him some slack.

All beginning QB sites start with almost no visitors... for the first month of Pete's QBasic Site, I think I got less than 100 hits. Pigeon's GBGames site took a few months of daily updates to pass 200 hits (I was checking the site out on Archive.org the other day). But it was regular updates and devotion that made my site and GBGames thrive. The same is true for V Planet!, which took a long time with regular updates before it became popular.

Think of this site as a standard HTML site, and think of Semerkoala as the webmaster rather than the admin. If he keeps working on his site and adds content regularly, (expecially UNIQUE content), it can become a worthwhile site and a valuable resource. Who knows, Semerkoala QB could evolve into the next Qbasic.tk.

After that, people stopped their assualt of Semerkoala...and his site was pretty much forgotten. Semerkoala sent me a message thanking me for the defense:

Hey Pete,

I just want to thank you for your posts here and on QBasic News. I really appreciate all you are doing for me, I hope that I can pull something together and get this thing going. I would do a website but due to lack of funds it would probably have to be on Geocities or something of that sort. Anywho thanks again.

~Semerkoala~

It seemed like I was the only one to look through the who truly understood what Semerkoala was trying to do with his website. But I gave him some parting advice:

No problem. I know what it's like starting a new site, and you at least deserve the benefit of the doubt.

Keep working on your site and maybe some day it will be great!

I do have some advice for you though: you need to find a niche. Or at least start doing something unique that all the other sites aren't doing. Right now, as I said, you're following the "laundry list" formula that Tek mentioned on NeoZones a while back. (I quoted him in my QBasic News post.) If you didn't know, the term "laundry list" is negative; it means you're following a tried and true formula and not doing anything new or innovative. If you want to get hits, don't just serve as a mirror of the content you can find everywhere else. You've got to create something new and interesting that will attract visitors.

My QBasic site was not popular at all until I started doing in-depth QB game reviews. I was the first person to ever do in-depth reviews of QB programs, and it attracted visits. That format was so successful that many other sites kind of copied or improved upon it...V Planet! and GBGames to name a few. I also started reporting news from around the QB community, which influenced some other sites to do the same. Then I branched out and created things like QB Comics and the QB Dance. Those are things that you won't find on any other site. Those were my innovations, and they helped my site thrive. Before that, Pete's QB Site fit perfectly into the "laundry list" formula...and wasn't very successful.

Think of something new and unique for your site....then keep on doing it. People will notice.

-Pete

Now a month has passed since Semerkoala started his site. I was interested to see what kind of progress he had made since I gave him those parting words of advice, and then I took a look and saw: NOT MUCH. Since those first few days in late July, almost nothing has been added to the site. In a little less than a month, Semerkoala QB has become a ghost town.

I had really high hopes for this site, and really wanted it to succeed. (It still might, but the lack of updates is a pretty strong indication that this was a flash-in-the-pan site that will just fade into even further obscurity.) I want all QB sites, projects and message forums to succeed. But they take time and dedication, and unless a webmaster or programmer can offer that undying dedication, their sites will die away.

Looking back at the QB forums debate from last month, I can now see why everyone was upset that ANOTHER QB forum had been created. A small, struggling QB forum just spreads the QB community out, and keeps groups of people from talking to each other. It takes too much time for everyone to check two dozen forums to find out about the latest happenings in the QB world; they'd just rather stick to one or two. That's understandable. I now see the flawed logic of Semerkoala QB looking for members. What it needed were visitors and submissions. When a site has interesting content, it will get visitors, and then a message board community can blossom. Only in very rare circumstances can it happen the other way around.

I tried to explain to Semerkoala that he needed to add content to get members to join his *forum*, and I tried to explain to the people at QBasic News that Semerkoala was just building his *site* through a forum, not trying to start a new community. It seems like I was only half right, any way you look at it.

No matter what, though, I'm glad to see anything new in the QB community. QB is going to die if people don't start creating new sites and programs. I welcome anything new, no matter how crappy it is.

Now quit reading this and go create something!


Semerkoala QB can be found here: http://semerkoalaqb.ne1.net/.

Comics

By Matt2Jones

Warning: These comics contain adult content!
(If you're wondering, all you'll just see a 2cm tall topless woman and some blood and guts of dead C++ coders. Skip this section if you're easily offended. You can click here to return to the top, or here to skip to the next article. You've been warned.)


This month, Matt2Jones has submitted two comics starring a character known as "Bobby The QBasic Maniac". Watch out -- Bobby (or "BBY" as he's known to his hacker buddies) is a homicidal QB coder with an attitude! This may be the first comic in a series, as Matt is considering making "Bobby The QBasic Maniac" a regular feature of QB Express!











Leviís Plot Line Tutorial

Written by Levi

Disclaimer:

This will in no way make you a better game creator. It will not guarantee excellent games, nor will it improve your abilities to make games interesting. This is simply a tutorial on the basics of writing and story creation. It is general and in no way in depth, it is meant to give you a different way to look at and plan things for your games. I might create more tutorials that will give you a better way to look at your stories and implement them into your games but until then this is all Iíve got.


Introduction

Final Fantasy, Legend of Dragoon, Dark Cloud, what do these three games have in common? They are all Role Playing Games. Though the name RPG is very confusing cause no matter which game you play you are playing as a character other than yourself. RPGs have been known to be games that allowed you to use multiple characters on a single quest to search out clues and go on grand adventures fighting enemies, monsters, and demons alike. But whether you are playing an RPG like Final Fantasy or a third person adventure game like The Legend of Zelda you always notice the same thing. A plot line. The characters have a past, the world has a history, the towns and places each have their own little part to play in the world. From the thriving metropolis to the homey little country towns and farms. You always encounter someone or something that makes the games realistic. Now not all games require such attention of course. Towers of Hanoi, the Rubix Cube, Super Mario Brothers for the NES even, never seem to have any real plot or story line. Except that Mario seems to be on a quest to find the princess and Luigi is helping by going off on his own. In fact Iíve seen and played many games that seemed to have no point or plot to them that based upon game play alone were enjoyable. But many of them are getting old, and some may just be boring with the absence of a plot line.

So knowing what type of game you are going to create is the best way to start any project. Iím not going to make a ridiculous story about how solving the mystery of the Towers of Hanoi is the only way to save a doomed kingdom just to make my users interested, though this isnít a bad idea. I would however wish to create a hero and villain that will be the main characters in my game if I were to create say an RPG or Action/Adventure game.

And though there is so much more to the creation of a gameís plot than just the hero and the villain these two are almost always the best starting points. Besides the title that is but the title can be saved for last for you more creative people. So letís start shall we?

1. The Hero and Villain (Protagonist and Antagonist)

Now the first thing you must always realize is that though a villain is preferred in a story, the villain does not need to be a person or something evil. As a matter of fact the villain can be anything or anyone. In Armageddon it was the asteroid(man vs. Nature), in The matrix it was the ďAgentĒ programs in the computers, and in fact the computers themselves. While in E.T. the villains were the adults and government agents trying to get the alien. The villain is often called the antagonist, the one who antagonizes the hero. Makes the hero try to fight him/her/it that sort of thing. The one that makes things go wrong. The main villain may be the one who is doing something to the hero that causes the hero to save the world by stopping some madman who just happens to be a lesser unknown or unnecessary villain in the story. As you can see your villain doesnít have to be the guy in the black cloak with magical powers trying to take over the world. You can even make the hero and the villain one and the same. Which makes for a fantastic twist at the end of the game.

So first decide on a hero and villain type. Remembering that there are very few rules as to whom and what they are. The main themes for villains and heroes are: Man vs. Nature, Man vs. Man (this can be anything from Gods to sea creatures the term man is simply used as a reference to another living being), Man vs. Himself, Man vs. Fate.

For the sake of this tutorial Iíll make up a story using these steps as we go along. Now remember just because you come up with these ideas initially doesnít mean they have to be the ones you stick with. Feel free to explore and reinvent you ideas time and time again. A good plot line in a good game is never finished, its flaws are simply masked by graphics and sound.

So Iíll create my Hero Levi (who else?) and my villain is a mixture between Himself and Fate. Thus my story will revolve around my main characterís past, personality, internal struggles, and a fate to which he wishes to escape. But to add a twist Iíll make fate into an actual person as well and Iíll call himÖTalin. So my theme is Man Vs. Man, Himself, and Fate.

2. Plot

Okay, So you have your hero and your villain. Great woopdeedoo! I mean what good is it? You can make two characters that fight all the time, very boring for a game, even one with excellent graphics.

So now we need a plot, a reason for these two characters to be at war with one another. But there are so many possibilities and many thousands of them are unoriginal. This of course isnít surprising since weíve had over five thousand years of written tradition and over ten thousand of oral tradition that is passed down from generation to generation with many different variations. So donít expect to be original expect to be creative and tricky. Even the most unoriginal ideas can be made to seem original with the right amount of tweaking.

Now with my two main characters I have no where to go, and yet everywhere to go. I have Fate transformed into a man, and my main character Levi who has many internal struggles with himself and what he must do. But what must he do? Why is Fate bothering him? What can fate do? Whatís going on? Thus the need for plot becomes even more necessary. But there are two ways to approach this problem. One is to develop the characters first and build some sort of past and relationship with them. Maybe the villain killed the heroís father, maybe they are brothers, maybe they donít know each other at all they simply donít agree on how to deal with the world and its problems. The second way is to create a problem that you think the villain might try to create. Have the asteroid come hurtling toward earth, make an alien civilization pretend to be friends while destroying us from the inside. Or make it a local problem. Make it a plot against your family alone, make it emotional more hard hitting to an individual.

Iíll develop the plot using the second method. Letís say that my main character is in love with his best friend Jessie, but Fate has designated her to die in order to stop some tragedy, now this is a rough draft so I will naturally change a lot of it. But Fate appears to these two and their families and becomes friends with them thus setting into motion what is necessary to do what he plans. And when Levi finds out, or gains clues that something is a miss he starts a journey or quest to discover what Fate is trying to hide from his eyes.

Now though this isnít detailed it is a plot, and itís something that can be easily worked off of. But this brings to mind, exactly what can these two do, and who are these other people who make fighting the villain that much harder to do?

3. Secondary Characters, and Character Traits

Okay we have our general plot line, we have our main characters the hero and the villain but what about these two truly makes us care about them? If Fate is so powerful and all controlling why canít he stop the tragic even from occurring without killing someone off? What sort of limitations, physical, or mental do they have? Well it would be boring if you couldnít defeat Fate so what if Fate was nothing more than a person this whole time? That his power to manipulate and control people was limited to only a few, and lets make it go even further that he can only manipulate those whoíve managed to see him when he worked invisibly in the crowd.

And what about our hero? There is so much to consider for the setting that what our hero looks like has yet to be thought. What sorts of things might be good for our hero? How about a troubled past that dealt with everyone he ever loved getting hurt because of him and he is the reason Fate has chosen Jessie to die? That would sure be motivation to try and save her, no?

Does he have any physical weaknesses? A crippled arm or leg? An old injury that prevents him from doing anything great? A simple scar across his face to make him look mean? Anything?

And what about the other characters in the story? The parents, Jessie, friends, family, strangers, random people who simply walk around with no point to their existence in the game? These are secondary characters. I usually split these up into groups: Main Secondary characters, Secondary Characters, anomalous characters, and disposable characters. Let me explain these to you.

Main Secondary characters
These are the extra characters who have just as much say and purpose in the story as the main characters just not as large a part. In an RPG these would be the followers or group members of your party. In games like Zelda these are the main characters who you always have to visit, meet, help, receive help from. And so on.
 
Secondary characters
These characters are the extra characters who give depth to all of your main characters. Leviís parents, Jessieís friend Allegra, people who exist for the sole purpose of being helpful but unnecessary. Who accentuate and give a realness feeling to your characters without having any say in how the game turns out.
 
Anomalous characters
I made this up basically but in a game these do exist. They are much like regular Secondary Characters except that their parts are far under developed and a stupid move by them causes the whole game to go out of wack. These characters are ones who if you donít beat to a certain area youíll never finish you objective, these are minor enemies and bosses who are there only for the purpose of stopping you and making the game more fun and time consuming.
 
Disposable characters
These characters are simply there to make sure you town isnít deserted, to be there, shopping, walking, giving a tid-bit of info if you ask nicely. Totally unnecessary and worthless when it comes to gaining your objective in the game.

All of these are important in your game and so I suggest you think about them carefully. Of course have plain generic people and adding and subtracting characters will happen throughout the creation process so take nothing you make now as any form of final draft on who is going to be in your game. Youíll find a lot you donít like and a lot you do.

4. Setting

Now donít get me wrong. Normally I would have put this at the beginning of the plot section but in this case I decided it was better to write it here. You see you have your characters in general figured out, you have the plot and reasons for things but you donít have a setting, you donít have extras that will really accentuate your story and give it that extra pizzazz needed to make it an instant hit.

So what are the usual things to consider in a setting? Who, What, When, Why, Where, and how right? You have the who, you have the way so what about the What When Where and how? So lets start with When and Where. Is it on earth or another world? What sort of time and society do they live in? The middle ages on earth? The middle ages on a planet known as Zorath? The future with technology, or lack of technology, a post Armageddon age. So many extras can be added on with any of these. On another planet you introduce animals and dangers not known to earth. Like a billowing pit of black oozing tar like substance that is intelligent and alive seeking out human sacrifices to feed its ever lasting hunger. In the future you can have teleporters, guns and explosive devices, in the past you can have weapons like swords and spears, vast wilderness. And so on. Iím sure youíve seen all of them before and you each have your own preferences so work those in and really add to your plot. Maybe the tragedy is the black bog threatens to kill everyone if it is not fed every year but no one has ever known of its existence. Maybe a mad man is threatening the world with nerve gas. As many possibilities and each of them leading to brave new worlds and adventures.

Then you have the What and How. What are the dangers of the world, what do they have to find, what do they live in? How is life lived there, how do they get around, how does the society survive. So many things, a past, a present, a future, prophesy, for people, places and things. This is all in setting, this is all needed in setting. So I hope you can see why I chose to make a general plot and save this step till later.

5. Game Implementation

Okay, lets admit it. What Iíve just done here is had you write a book. A great story, probably not good enough for the best sellers list, but defiantly not a game. Now of course there are other tutorials that will show how to make a game engine or implement the flow of game creation but this is a plot tutorial. A way of making the games deeper and more meaningful to the user. What could I possibly have to say about placing it into a game? Nothing. In truth Iím a writer not a true game creator. Of all the things here they only give you the building blocks for the putting of your game together. They only give you the starting and ending points, they give the characters, and personalities to which each character will reply to certain circumstances. But you have to implement them into your game. You have to make those who simply shop and fill the town to shop, you have to make the plot line applicable and interesting to the user so that they will be willing to read dialogue and descriptions of events and history. You have to decide when game play will stop and automated story will begin. When to force your characters to do something and when to allow them to roam free.

Well luckily when you make a story most of this will be done for you. As you go along youíll find that any changes you make will be automatically updated in your game and many extras will follow. So these are just a few things to consider and use. I will post my story line I made using these steps as well as a text introduction that I came up with. It sucks since I made it within the span of a day or two and am use to weeks of planning but work with me here, itís just a rough draft.

6. The Hand of Fate

Levi is a young boy of 19, he lives in a modern day society where threats to national security and personal safety are the norm. He lives with his father his adopted brother, his best friend Jessie, whom he secretly loves, and her father. He has red hair and is rather hansom though only in an average sort of way. He loves computers and mystery books as well as ancient mythology and philosophy. His father is the top research scientist at a lab that produces cures and ways to fight chemical and biological germ warfare. Jessieís father is a colonel in the airforce who is assigned a secret mission to find an insane scientist Lisa Whineholdt. Who use to work on one of Leviís fatherís projects and instead of finding a cure for a certain disease created the most powerful nerve gas in the world. But no one knows about it. That is until Fate comes for a visit. A young man found wandering outside their complex one night with a serious gun wound is taken in by this family to be taken care of. He calls himself Talin, his eyes and hair and clothing, with the exception of the blood stains, are all white. Giving him a sort of angelic look. In the middle of the night Jessie goes missing meant to be the last victim of Whineholdtís experiments before releasing the gas on the world. In a frantic race against time it is your job as Levi to find clues, friends, and any help you can in order to save Jessie. Talin of course comes with you but causes you to get lost on your quest time and time again. In the end you discover who he really is and with an over used clichť ďDonít temp fate Levi, Donít tempt me!Ē You set out once again alone meeting up with many strange events that can only be described as a fated presence that is trying to stop you at every turn. In the end Iíll introduce the surprise ending that all you have to do is die in Jessieís place and you beat the game. It would of course get into deep philosophical reasoning and ideas. Human nature and psychological and spiritual ideas on Fate and who or what he really is.

Paragraph:

War, there isnít a single generation that has been spared its wrath. Not a single child alive or still born has escaped it looming presence. That death like grip that holds all man in fear for their lives. Now war is not simply over there being fought by a few. Itís here, itís now, its being fought by all. As Levi walked down the streets of his once lovely town he realized that with greed came destruction, and that in this world the death that so many suffered was the only escape greed offered to relieve them of their pain.

If he didnít have the love of his family, of his friends, Levi might just wish for such an end for himself.


Download a printable version of Levi's Plot Line Tutorial at here.

Metaballs? I'd call them "Blobs"

Tutorial by Relsoft

People emailed me to write a tutorial about stuff/effects they saw in my "mono and disco" QB demo. Most of which regarding Plasmas, 3d and Blobs. As I've already finished writing the plasma article, and discussing 3d in layman's tern would involve me dicussing polar coordinates and Trig Identities, I am writing a tutorial on how to model 2d blobs as it would require less space. ;*)

I. Illumination

Illumination is how light behaves proportional to its distance from the center.

ie: Intensity=1/distance≤

Which means that the Intensity of light is *inversely* proportional to its distance from the lightsource. So the farther the coordinate from the center of the lightsource the darker it gets. If you don't believe me, try to point a flashlight on a dark area. ;*)

II. Preparing the LightMap

First you have to make a lightmap. A lightmap is a map/table of illumination. We should use the above formula in making the lightmap. Say we want to have a 64*64 Lightmap (you could use an size that will fit your purpose), we wan't to fill that table with values derived from our illumination formula. As we are using screen 13, which has 256 colors (0-255), our value for MAXCOLOR would be 255. You'll notice that the image of the Lightmap is curved/quadratic:

This is what our lightmap would look like if plotted on the screen. But this lightmap, although mathematically sound, won't look very good for our blobs. What we wan't is a more linear lightmap like this:

Trust me on this, the second one would look way cooler. You could develop your own formula if you want, as long as it follows the concept of inverse proportion.

Here's the QB code to generate both Lightmaps:

'LightMap tester
'Relsoft 2003
'SetvideoSeg by Plasma357

DEFINT A-Z

CONST PI = 3.141593


DIM SHARED Light%(64, 64)           'Our LightMap
CLS
SCREEN 13
RANDOMIZE TIMER


'////==============Grey Scaled Pal
 FOR i = 0 TO 255
  OUT &H3C8, i
  OUT &H3C9, i \ 4
  OUT &H3C9, i \ 4
  OUT &H3C9, i \ 4
 NEXT i



'////==============Generate our LightMap
'Illumination formula:
'"Distance is inversly propotional to illumination
'i = 1 / (d ^ 2)

'/////=======Standard formula
MAXCOLOR = 255
FOR x% = -32 TO 31
FOR y% = -32 TO 31
        Dist! = SQR(x ^ 2 + y ^ 2)
        IF x% = 0 AND y% = 0 THEN   'check for center
            c% = 255
        ELSE
            c% = Dist! ^ 2
            c% = MAXCOLOR - c%
        END IF
    IF c% < 0 THEN c% = 0           'Check if it's out of bounds
    IF c% > 255 THEN c% = 255
    Light%(x% + 32, y% + 32) = c%       'save it
NEXT y%
NEXT x%


'////==============Test to see out lightmap in action
FOR y = 0 TO 64
FOR x = 0 TO 64
    PSET (70 + x, 70 + y), Light%(x, y)
NEXT x
NEXT y


'/////=======Better looking formula

'Our own way...
'i = (Strength / Distance * MAXCOLOR) - MAXCOLOR

Strength% = 32
MAXCOLOR = 255
FOR x% = -32 TO 31
FOR y% = -32 TO 31
        Dist! = SQR(x ^ 2 + y ^ 2)
        IF x% = 0 AND y% = 0 THEN   'check for center
            c% = 255
        ELSE
            c% = Strength% / Dist! * MAXCOLOR
            c% = c% - MAXCOLOR
        END IF
    IF c% < 0 THEN c% = 0           'Check if it's out of bounds
    IF c% > 255 THEN c% = 255
    Light%(x% + 32, y% + 32) = c%       'save it
NEXT y%
NEXT x%


'////==============Test to see out lightmap in action
FOR y = 0 TO 64
FOR x = 0 TO 64
    PSET (180 + x, 70 + y), Light%(x, y)
NEXT x
NEXT y


END

SUB SetVideoSeg (Segment) STATIC

DEF SEG

IF VideoAddrOff& = 0 THEN ' First time the sub is called

' We need to find the location of b$AddrC, which holds the graphics
' offset (b$OffC) and segment (b$SegC). Since b$AddrC is in the default
' segment, we can find it by setting it to a certain value, and then
' searching for that value.

SCREEN 13 ' Set b$SegC to A000 (00A0 in memory)
PSET (160, 100), 0 ' Set b$OffC to 7DA0 (not needed in the IDE)

FOR offset& = 0 TO 32764 ' Search for b$AddrC, which is
IF PEEK(offset&) = &HA0 THEN ' in the default segment and
IF PEEK(offset& + 1) = &H7D THEN ' should have a value of
IF PEEK(offset& + 2) = &H0 THEN ' A0 7D 00 A0.
IF PEEK(offset& + 3) = &HA0 THEN
VideoAddrOff& = offset& + 2 ' If we found it, record the
EXIT FOR ' offset of b$SegC and quit
END IF ' looking. (Oddly, changing
END IF ' the b$OffC doesn't seem to
END IF ' do anything, so this is why
END IF ' this sub only changes b$SegC)
NEXT

END IF

' Change b$SegC to the specified Segment

POKE VideoAddrOff&, Segment AND &HFF
POKE VideoAddrOff& + 1, (Segment AND &HFF00&) \ &H100


END SUB

Download TestLite.bas here.

III. The Algorithm

Now that we have decided what lightMap to use, we can start making our blob render. The algo is actually very simple it hurts. ;*) Blobs are made when lightmaps "overlap".

[Pseudo code}
1. Decide where you want to put a
 	blob.
2. Read your lightmap sequentially
3. Check if the lightmap contains a
 	color.
3. If it contains a color other than
 	0, Check the color of the
 	the particular pixel on the
 	screen.
4. Add both colors together
5. Limit the color to the maximum
 	color.
6. Plot the summed-up colors to
 	screen. 
[end pseudo code]

See, pretty elementary. If you want QB code here it is:

SUB DrawBlob (bx%, by%)

    FOR y% = 0 TO 64
    FOR x% = 0 TO 64
        c% = Light%(x%, y%)
        IF c% THEN
            oc% = POINT(x% + bx%, y% + by%)
            occ% = c% + oc%
            IF occ% > 255 THEN
                occ% = 255
            END IF
            PSET (x% + bx%, y% + by%), occ%
        END IF
    NEXT x
    NEXT y

END SUB

It is very important that you clear the screen to blank after every frame to make the display right. Now that we know how to generate blobs, we would want to see it in action. To do those cool movements, use what you have learned in HighSchool algebra/Trig. Ie. Polar coordinates or vectors.

Here's the complete commented code:

'How to generate Blobs(also called MetaBalls)
'Relsoft 2003
'SetvideoSeg by Plasma357

DECLARE SUB DrawBlob (bx%, by%)
DECLARE SUB SetVideoSeg (Segment%)
DEFINT A-Z

CONST PI = 3.141593


DIM SHARED Light%(64, 64)           'Our LightMap
REDIM SHARED Vpage(32009)  AS INTEGER       'SetVideoSeg Buffer
Vpage(6) = 2560                      'Width 320*8
Vpage(7) = 200                       'Height
Layer = VARSEG(Vpage(0)) + 1         'Buffer Seg(Ask Plasma)


CLS
SCREEN 13
RANDOMIZE TIMER


'////==============Grey Scaled Pal
 FOR i = 0 TO 255
  OUT &H3C8, i
  OUT &H3C9, i \ 4
  OUT &H3C9, i \ 4
  OUT &H3C9, i \ 4
 NEXT i



'////==============Generate our LightMap
'Illumination formula:
'"Distance is inversly propotional to illumination
'i = 1 / (d ^ 2)
'Our own way...
'i = (Strength / Distance * MAXCOLOR) - MAXCOLOR

Strength% = 32
MAXCOLOR = 255
FOR x% = -32 TO 31
FOR y% = -32 TO 31
        dist! = SQR(x ^ 2 + y ^ 2)
        IF x% = 0 AND y% = 0 THEN   'check for center
            c% = 255
        ELSE
            c% = (Strength / dist!) * MAXCOLOR
            c% = c% - MAXCOLOR
        END IF
    IF c% < 0 THEN c% = 0           'Check if it's out of bounds
    IF c% > 255 THEN c% = 255
    Light%(x% + 32, y% + 32) = c%       'save it
NEXT y%
NEXT x%


'////==============Test to see out lightmap in action
FOR y = 0 TO 64
FOR x = 0 TO 64
    PSET (130 + x, 70 + y), Light%(x, y)
NEXT x
NEXT y

COLOR 255
LOCATE 1, 1
PRINT "This is our LightMap"
PRINT "Press any key..."
c$ = INPUT$(1)


'//////============TYPE 1
'//////============TYPE 1
'//////============TYPE 1
F& = 0              'Frame counter
DO
    F& = F& + 1
    SetVideoSeg Layer               'Set draw to buffer
    LINE (0, 0)-(319, 199), 0, BF   'Clear the screen
    FOR i% = 1 TO 6
        bx% = SIN(F& / 30 * .8 * i%) * (i% * 20) + 110      'Move the balls
        by% = COS(F& / 25 * .9 * i%) * (i% * 15) + 70
        DrawBlob bx%, by%                               'Draw the balls
    NEXT i%
    SetVideoSeg &HA000              'set draw to screen
    WAIT &H3DA, 8                   'vsynch
    PUT (0, 0), Vpage(6), PSET      'Display the screen

LOOP UNTIL INKEY$ <> ""


'//////============TYPE 2
'//////============TYPE 2
'//////============TYPE 2

DO
    F& = F& + 1
    SetVideoSeg Layer
    LINE (0, 0)-(319, 199), 0, BF
    FOR i% = 1 TO 6
        bx% = SIN(F& / 30 * .8 * i%) * (i% * 20) + 110
        by% = COS(F& / 25 * .9 * i%) * (i% * 15) + 70
        DrawBlob bx%, by%
    NEXT i%

    'Scan the whole screen
    FOR y = 0 TO 199
    FOR x = 0 TO 319
        c% = POINT(x, y)                    'get pixel
        IF c% > 80 THEN                     'if > 80 plot the color
            PSET (x, y), x XOR y
        ELSEIF c% < 80 AND c% > 0 THEN      'if <80 then don't plot
            PSET (x, y), 0
        ELSEIF c% = 80 THEN                 'border color of 5
            PSET (x, y), 5
        END IF
    NEXT x
    NEXT y
    SetVideoSeg &HA000
    WAIT &H3DA, 8
    PUT (0, 0), Vpage(6), PSET  'Pcopy the buffer

LOOP UNTIL INKEY$ <> ""



'//////============TYPE 3
'//////============TYPE 3
'//////============TYPE 3
'Brutalizing the Palette ;*)
j! = 255 / 360 * 6
k! = 255 / 360 * 2
l! = 255 / 360 * 6
FOR i% = 0 TO 255
    OUT &H3C8, i%
    m% = INT(a!)
    n% = INT(b!)
    o% = INT(c!)
    r% = 63 * ABS(SIN(m% * PI / 180))
    g% = 63 * ABS(SIN(n% * PI / 180))
    b% = 63 * ABS(SIN(o% * PI / 180))
    a! = a! + j!
    b! = b! + k!
    c! = c! + l!
    OUT &H3C9, r%
    OUT &H3C9, g%
    OUT &H3C9, b%
NEXT



DO
    F& = F& + 1
    SetVideoSeg Layer
    LINE (0, 0)-(319, 199), 0, BF
    FOR i% = 1 TO 6
        bx% = SIN(F& / 30 * .8 * i%) * (i% * 20) + 110
        by% = COS(F& / 25 * .9 * i%) * (i% * 15) + 70
        DrawBlob bx%, by%
    NEXT i%
    SetVideoSeg &HA000
    WAIT &H3DA, 8
    PUT (0, 0), Vpage(6), PSET  'Pcopy the buffer

LOOP UNTIL INKEY$ <> ""



END

SUB DrawBlob (bx%, by%)

    FOR y% = 0 TO 64
    FOR x% = 0 TO 64
        c% = Light%(x%, y%)
        IF c% THEN
            oc% = POINT(x% + bx%, y% + by%)
            occ% = c% + oc%
            IF occ% > 255 THEN
                occ% = 255
            END IF
            PSET (x% + bx%, y% + by%), occ%
        END IF
    NEXT x
    NEXT y

END SUB

SUB SetVideoSeg (Segment) STATIC

DEF SEG

IF VideoAddrOff& = 0 THEN ' First time the sub is called

' We need to find the location of b$AddrC, which holds the graphics
' offset (b$OffC) and segment (b$SegC). Since b$AddrC is in the default
' segment, we can find it by setting it to a certain value, and then
' searching for that value.

SCREEN 13 ' Set b$SegC to A000 (00A0 in memory)
PSET (160, 100), 0 ' Set b$OffC to 7DA0 (not needed in the IDE)

FOR offset& = 0 TO 32764 ' Search for b$AddrC, which is
IF PEEK(offset&) = &HA0 THEN ' in the default segment and
IF PEEK(offset& + 1) = &H7D THEN ' should have a value of
IF PEEK(offset& + 2) = &H0 THEN ' A0 7D 00 A0.
IF PEEK(offset& + 3) = &HA0 THEN
VideoAddrOff& = offset& + 2 ' If we found it, record the
EXIT FOR ' offset of b$SegC and quit
END IF ' looking. (Oddly, changing
END IF ' the b$OffC doesn't seem to
END IF ' do anything, so this is why
END IF ' this sub only changes b$SegC)
NEXT

END IF

' Change b$SegC to the specified Segment

POKE VideoAddrOff&, Segment AND &HFF
POKE VideoAddrOff& + 1, (Segment AND &HFF00&) \ &H100


END SUB

Download Blob.bas here.

These are the blobs created by Blob.bas:

Type 1 >
< Type 2
Type 3 >

IV. Appendix

Yes, I got mine removed already. Oops!!!! If you already have read my articles on QBCM issues prior to this, you already know how to generate realtime plasmas and you could combine both effects in one as in this example:

'Blobs on Plasma in translucent mode!!!
'I intentionally used long integers so that this would
'run inside the IDE.
'Relsoft 2003
DECLARE SUB DrawBlob (bx%, by%)
DECLARE SUB Blobs (Fps%, Vsynch%, MaxFrame%, Intensity%)
DEFINT A-Z

TYPE PartType
        x               AS INTEGER
        y               AS INTEGER
        xv              AS INTEGER
        yv              AS INTEGER
        tx              AS INTEGER
        ty              AS INTEGER
        Angle           AS INTEGER
        newtarget       AS INTEGER
END TYPE



RANDOMIZE TIMER


CONST PI = 3.14151693#
CONST FALSE = 0, TRUE = NOT FALSE

'$DYNAMIC
DIM SHARED Vpage1%(0 TO 32001)          'our Buffer
'$STATIC

DIM SHARED Lsin1%(-1024 TO 1024)        'some sinus precalcs
DIM SHARED Lsin2%(-1024 TO 1024)        'to speed things up
DIM SHARED Lsin3%(-1024 TO 1024)        'used for Plasma
DIM SHARED Lsin!(-10 TO 370)            'ditto but single
DIM SHARED Lcos!(-10 TO 370)            'used for Particles
DIM SHARED Ly&(0 TO 199)                'y lookuptable
DIM SHARED Light%(127, 127)             'the lightmap


DIM SHARED Layer1%, Offs1%              'Easy reference of
                                        'our Buffer
Vpage1%(0) = 320 * 8                    'PUT/GET stuff
Vpage1%(1) = 200

Layer1% = VARSEG(Vpage1%(2))            ';*)
Offs1% = VARPTR(Vpage1%(2))

FOR i% = 0 TO 199                       'Prefcalc Y lookup
    Ly&(i%) = i% * 320&
NEXT i%
FOR i% = 0 TO 359                       'Cosine/Sine LUT
    RA! = i% * (3.141593 / 180)
    Lcos!(i%) = COS(RA!)
    Lsin!(i%) = SIN(RA!)
NEXT i%


CLS
SCREEN 13


Vsynch% = FALSE                         'No WAIT
Blobs Fps%, Vsynch%, MaxFrame%, 512
              
CLS
SCREEN 0
WIDTH 80
PRINT "FPS:"; Fps%
c$ = INPUT$(1)
END

SUB Blobs (Fps%, Vsynch%, MaxFrame%, Intensity%)

Numblobs = 20                       'Number of particles
DIM blob(Numblobs) AS PartType
FOR i% = 0 TO UBOUND(blob)          'Init
        blob(i%).x = 160
        blob(i%).y = 100
        blob(i%).Angle = 0
NEXT i%

FOR x% = -64 TO 63                  'Calc lightmap
FOR y% = -64 TO 63
        IF x% = 0 AND y% = 0 THEN
            c% = 255
        ELSE
            c% = ((8 / SQR((x% * x%) + (y% * y%))) * Intensity%) - ...
				  (SQR((x% * x%) + (y% * y%)) * 2)
        END IF
    IF c% < 0 THEN c% = 0
    IF c% > 255 THEN c% = 255
    Light%(x% + 64, y% + 64) = c%
NEXT y%
NEXT x%

FOR i% = -1024 TO 1024
   Lsin1%(i%) = SIN(i% * PI / (128)) * 16       'Precalc x,y,z
   Lsin2%(i%) = SIN(i% * PI / (64)) * 32        'and scale factor
   Lsin3%(i%) = SIN(i% * PI / (32)) * 16
NEXT i%


j! = 255 / 360 * 3              'Sinus interpolation of our palette
k! = 255 / 360 * 2
l! = 255 / 360 * 5
FOR i% = 0 TO 255
    OUT &H3C8, i%
    m% = INT(a!)
    n% = INT(b!)
    o% = INT(c!)
    r% = 63 * ABS(SIN(m% * PI / 180))
    g% = 63 * ABS(SIN(n% * PI / 180))
    b% = 63 * ABS(SIN(o% * PI / 180))
    a! = a! + j!
    b! = b! + k!
    c! = c! + l!
    OUT &H3C9, r%
    OUT &H3C9, g%
    OUT &H3C9, b%
NEXT




F& = 0
Tim# = TIMER
DEF SEG = Layer1%
countdir% = -1
switch& = 1
DO
    F& = (F& + 1) AND &H7FFFFFFF

    REDIM Vpage1%(0 TO 32001)           'CLS
    Vpage1%(0) = 320 * 8
    Vpage1%(1) = 200

    FOR i% = 0 TO UBOUND(blob)
        GOSUB DoBlobs                   'Move Particles
    NEXT i%

    FOR i% = 0 TO UBOUND(blob)
        bx% = blob(i%).x
        by% = blob(i%).y
        DrawBlob bx%, by%               'Draw
    NEXT i%

    counter% = (counter% + countdir%)
    IF counter% < -700 THEN
        countdir% = -countdir%
    ELSEIF counter% > 400 THEN
        countdir% = -countdir%
    END IF

    offset& = Offs1%
    FOR ya% = 0 TO 199
        ysin% = Lsin1%(ya% - counter%)
    FOR xa% = 0 TO 319
                dc% = PEEK(offset&)
                IF dc% > 40 AND dc% <= 84 THEN
                    c% = Lsin1%(xa% - counter%) + Lsin1%(ya% - ...
				counter%) + ya%
                    c% = Lsin3%(c% + Lsin2%(x% - counter%) - ya% + counter%) ...
				+ xa%
                    c% = c% + Lsin2%(xa% - ya% + counter%) + Lsin1%(ya% - ...
				Lsin2%(xa% - counter% + c%))
                    c% = c% + Lsin3%(c% + Lsin1%(x% - counter%) - ya% + counter%)...
				 + xa%
                ELSEIF dc% > 84 AND (switch& AND 1) THEN       'alternate it
                    c% = Lsin1%(xa% - counter%) + Lsin1%(ya% - counter%) + ya%
                    c% = Lsin3%(c% + Lsin2%(x% - counter%) - ya% + counter%) + xa%
                    c% = c% + Lsin2%(xa% - ya% + counter%) + Lsin1%(ya% - ...
				Lsin2%(xa% - counter% + c%))
                    c% = c% + Lsin3%(c% + Lsin1%(x% - counter%) - ya% + counter%) + xa%
                ELSE
                    c% = Lsin3%(xa% - counter%) + ysin% + Lsin2%(ya% + xa%) ...
				+ Lsin3%(ysin%)
                    c% = Lsin1%(Lsin2%(Lsin3%(c% + ysin% + xa% + counter%))) + ...
				Lsin3%(Lsin2%(Lsin1%(c% + ysin% + xa% + counter%)))
                    c% = c% + Lsin1%(Lsin2%(Lsin3%(c% + ysin% + xa% + counter%))) ...
				+ Lsin3%(Lsin2%(Lsin1%(c% + ysin% + xa% + counter%)))
                END IF
                POKE offset&, c%
                offset& = offset& + 1
                switch& = switch& + 1
    NEXT xa%
                switch& = switch& - 1  'move 1 pixel back
    NEXT ya%

    IF Vsynch% THEN WAIT &H3DA, 8
    PUT (0, 0), Vpage1%(0), PSET                       'Blit
LOOP UNTIL INKEY$ <> ""


Fps% = F& / (TIMER - Tim#)
ERASE blob
EXIT SUB

DoBlobs:

    IF blob(i%).newtarget THEN
            blob(i%).tx = INT(RND * 320)
            blob(i%).ty = INT(RND * 200)
            blob(i%).newtarget = FALSE
    END IF

    'move the blobs
    blob(i%).xv = (Lcos!(blob(i%).Angle)) * 3
    blob(i%).yv = (Lsin!(blob(i%).Angle)) * 3

    blob(i%).x = blob(i%).x + blob(i%).xv
    blob(i%).y = blob(i%).y + blob(i%).yv

    'Check proximity
    IF ABS(blob(i%).tx - blob(i%).x) AND ABS(blob(i%).ty - ...
			blob(i%).y) < 5 THEN
            blob(i%).newtarget = TRUE
    END IF

    'Modified DOT product.
    'Check if Result>0 then Dec else Inc
    'the actual angle is not important
    Dot = ((blob(i%).yv * (blob(i%).tx - blob(i%).x)) - ...
			(blob(i%).xv * (blob(i%).ty - blob(i%).y)))
    IF Dot > 0 THEN
            blob(i%).Angle = (blob(i%).Angle - 3)
            IF blob(i%).Angle < 0 THEN blob(i%).Angle = ...
			blob(i%).Angle + 360
    ELSE
            blob(i%).Angle = (blob(i%).Angle + 3) MOD 360
    END IF

RETURN
END SUB

SUB DrawBlob (bx%, by%)
'Draws a blob using a lightmap
'Bx=Blobx coord

x% = bx% - 64           'Restore coord to new coord
y% = by% - 64           'correct center offset

xsize% = 128
ysize% = 128

newx% = x%                        'get coords
newy% = y%

minx% = 0                       'Lightmap offset correctors
miny% = 0

'Clip/Crop it
IF newy% < 0 THEN
        CY = -newy%
        ysize% = ysize% - CY
        newy% = 0
        miny% = CY
ELSEIF newy% > 199 THEN
        EXIT SUB
ELSE
        Ndy = newy% + ysize%
        IF Ndy > 199 THEN
                ysize% = ysize% - (Ndy - (200))
        END IF
END IF

IF newx% < 0 THEN
        CX = -newx%
        xsize% = xsize% - CX
        newx% = 0
        minx% = CX
ELSEIF newx% > 319 THEN
        EXIT SUB
ELSE
        Ndx = newx% + xsize%
        IF Ndx > 319 THEN
                xsize% = xsize% - (Ndx - 320)
        END IF
END IF

'Draw

offset& = Offs1% + Ly&(newy%) + newx%       'Start offset

FOR y% = 0 TO ysize% - 1
FOR x% = 0 TO xsize% - 1
    c% = Light%(x% + minx%, y% + miny%)     'Correct Light offset
    IF c% THEN
        oc% = PEEK(offset& + x%)
        occ% = c% + oc%                     'Combine colors
        IF occ% > 255 THEN
            occ% = 255
        END IF
        POKE offset& + x%, occ%
    END IF
NEXT x
    offset& = offset& + 320
NEXT y

END SUB


Download BlobPlas.Bas here.

BlobPlas.Bas creates the following effect:

V. Disclaimer

Who cares? ;*) I want to have some feedback regarding this article or the others that I have written. I'm accepting requests as to what to write next. And remember. You are only limited by your imagination. ;*)

Download this zip archive for a copy of the tutorial, all images and all example programs.

Relsoft 2003      ~      vic_viperph@yahoo.com      ~      rel.betterwebber.com


DSock Tutorial Document

Written by Marcade

A note from the editor:

This is a tutorial on using DSock written some time ago by Marcade. This covers most of what you need to know to implement DSock into your QB program, though it is not yet complete: it does not explain how to listen and accept to incoming connections. But according to Marcade, "that is very easy .. people can look at the source of Connect 4 to figure it out .. basically.

"Connect 4 was released with the source code for people to learn from it... The Networking code of Connect 4 can be used by other people if they want it (as long as credit is given). It's programmed in a way that it can be reused."

You can find Connect 4 QB and DSock at http://www.neozones.com/c4/.

Introduction

This document will describe in easy steps, how to use V1ctor's DSock library. You will need the library itself, and the library only, to be able to use it. The code that comes with the library, dsock.bi, scc.bas and scs.bas can be used for learning references, but are very confusing at first sight. This document was written to clarify it, making it possible to practically copy/paste what you need, from this document into your program.

The DSock.bi file that comes with DSock is filled with allot of information, declarations and constants, fromwhich most of them, you will never use in your program. It is strongly suggested not to use DSock.bi and create your own .BI include. Every section of this document will contain a Blue Square Field with Dark Blue code. This code was found in the DSock.bi and is needed for the code in that section, to work properly. So basically you only need that code in your .BI file if you are going to use the code described in the section. Beware, if you will be using code from different sections, the blue squares might already contain code you found in a previous blue square. Do not include that code, twice in your .BI file.

All code written in Blue, which is outside the DSock.bi declaration square, is code that will need code included in the Blue Square Field on top.

All code written in Red, mostly being comments, should be read as pseudo code. The user self has to decide what to do then, at that spot, since it differs from every program.

All code written in Fuchsia, is mostly a variable, depending on code written in another section of this document. For example lSocketHandle cannot immediately be used. It needs to contain the handle of a socket that was opened in another piece of code, written in a different section of this document.

Initializations

Before you can use Dsock, you will have to initialize it first. This initialization code will do that, and request extended information about the type of Winsock you have on your system.


Lines that need to be included
Type WSAData
	wVersion AS INTEGER
	wHighVersion AS INTEGER
	szDescription AS STRING * WSADESCRIPTIONLEN%
	szSystemStatus AS STRING * WSASYSSTATUSLEN%
	iMaxSockets AS INTEGER
	lpVendorInfo AS LONG
End Type


DECLARE FUNCTION WSAStartup% (BYVAL wVersionRequired AS INTEGER, ...
			SEG lpWSAData AS WSaData)
DECLARE FUNCTION MAKEWORD% (BYVAL lsb AS INTEGER, BYVAL msb AS...
			INTEGER)

CONST WSADESCRIPTIONLEN% = 256  + 1
CONST WSASYSSTATUSLEN% = 128 + 1
DIM iRetVal AS INTEGER
DIM wsaDat AS WSAData

wVersionRequested = MAKEWORD(1, 1)
iRetVal = WSAStartup(wVersionRequested, wsaDat)

IF (wsaDat.wVersion <> wVersionRequested) THEN
        Error! WinSock version not supported. Do NOT try to use DSock.
END IF

Opening a New Socket

When you want to make a single connection, you first will have to request and open a new socket which you can use. When you have opened a socket, you will get a Socket Handle you will have to use for the rest of the time. Of course, you can open multiple sockets, and thus you then will have to manage multiple handles.

Since by default we are going to use the socket in a way where we do not want it to lag our program, we put it in NonBlockingMode. NonBlockingMode means, whenever we are polling the sockets, it will NOT wait until something happens, and it will NOT wait for the time to run out. NonBlockingMode means we will merely poll the socket.

If opening a socket fails, it is best just to close the socket again, display an error message, and continue your program.


Lines that need to be included
DECLARE FUNCTION socket&  (BYVAL addrfamily AS INTEGER, BYVAL socktype ...
			AS INTEGER, BYVAL protocol AS INTEGER)
DECLARE FUNCTION ioctlsocket% (BYVAL s AS LONG, BYVAL cmd AS LONG, ...
			SEG argp AS LONG)
DECLARE FUNCTION closesocket% (BYVAL s AS LONG)

 
CONST AF.INET% = 2%
CONST SOCK.STREAM% = 1%
CONST IPPROTO.TCP% = 6%
CONST INVALID.SOCKET& = -1&
CONST FIONBIO& = -2147195266&
CONST SOCKET.ERROR% = -1%
DIM lSocketHandle AS LONG
DIM iRetVal AS INTEGER
 
Ď Create a new socket
lSocketHandle = socket(AF.INET%, SOCK.STREAM%, IPPROTO.TCP%)
IF lSocketHandle = INVALID.SOCKET& THEN
        Error! Socket could not be reserved.
END IF
 
Ď Put socket in non-blocking mode.
IF (ioctlsocket(lSocketHandle, FIONBIO&, 1) = SOCKET.ERROR%) THEN
        Error! Socket could not be put in non-blocking mode
        Ď Close socket because we cannot use it in non-blocking mode
        IretVal = closesocket(lSocketHandle)
END IF

Connecting

When connecting to a remote computer, you first have to resolve the hostname or IP address. Using the DSock resolve functions gethostbyname&() or gethostbyaddr&(), it will return a pointer where more information about the host is found. Using different functions and the pointer, the information can be retrieved.

Note: When using Windows 2000 or Windows XP, you also can resolve IP addresses with gethostbyname&(), but under Windows 95/98/ME this will not work and you have to use the gethostbyaddr&() function.

After the hostname has been resolved, the connect() function will be called with a special sockaddrIn record, and the socket will try to connect to that host.

Whether the connection succeeds or fails cannot be determined at this point. This should be checked when polling the sockets.


Lines that need to be included
TYPE inAddr
        Saddr AS LONG
END TYPE
TYPE sockaddrIn
        sinFamily AS INTEGER
        sinPort AS INTEGER
        sinAddr AS inAddr
        sinZero AS STRING * 8
END TYPE
 
DECLARE FUNCTION gethostbyname& (hname AS STRING)
DECLARE FUNCTION gethostbyaddr& (SEG addr AS ANY, BYVAL length AS ...
			INTEGER, BYVAL addrtype AS INTEGER)
DECLARE FUNCTION hostent.hAddrList& ALIAS "hent_addr" (BYVAL entry ...
			AS LONG)
DECLARE FUNCTION hostent.hName$ ALIAS "hent_name" (BYVAL entry AS ...
			LONG)
DECLARE FUNCTION htons% (BYVAL hostshort AS INTEGER)
DECLARE FUNCTION inetAddr& ALIAS "inet_addr" (cp AS STRING)
DECLARE FUNCTION connect% (BYVAL s AS LONG, SEG connname AS ANY, ...
			BYVAL namelen AS INTEGER)
DECLARE FUNCTION closesocket% (BYVAL s AS LONG)
DECLARE FUNCTION WSAGetLastError% ()
 
CONST AF.INET% = 2%
CONST SOCKET.ERROR% = -1%
CONST INADDR.NONE& = &hffffffff&
 
CONST WSABASEERR% = 10000%
CONST WSAEWOULDBLOCK% = WSABASEERR + 35%
DIM iaHost AS inAddr
DIM lHostPointer AS LONG
DIM stHostName AS STRING
DIM SocketAddress AS sockaddrIn
DIM iRetVal AS INTEGER
DIM iPortNumber AS INTEGER
 
stHostName="Hostname or IP address of computer you want to connect with."
iPortNumber=PortNumber you want to connect with.

iaHost.sAddr = inetAddr(stHostName)
 
Ď Retrieve information about the hostname
        IF (iaHost.sAddr = INADDR.NONE&) THEN
               ' The address isn't an IP address string, assume it is a name
               lHostPointer = gethostbyname(stHostName)
               if (lHostPointer = 0) then
                       Error! Did not retrieve a pointer. Cannot connect.
                       EXIT SUB
               END IF
        ELSE
               ' It was a valid IP address string.
               lHostPointer = gethostbyaddr(iaHost, LEN(iaHost), AF.INET%)
               IF (lHostPointer = 0) THEN
                       Error! Did not retrieve a pointer. Cannot connect.
                       EXIT SUB
               END IF
              
               Ď Fetching the Server hostname from the IP address.
               lpServerName = hostent.hName(lHostPointer)
        END IF
 
SocketAddress.sinFamily = AF.INET%
SocketAddress.saddr = hostent.hAddrList(lHostPointer)
SocketAddress.sinport = htons(port)
 
iRetVal = connect(lSocketHandle, SocketAddress, LEN(SocketAddress))
IF iRetVal=SOCKET.ERROR% THEN
        IF WSAGetLastError% <> WSAEWOULDBLOCK% THEN
               Error! Failed to perform connect function.
               iRetVal = closesocket(lSocketHandle)
               EXIT SUB
        END IF
END IF

Polling the sockets for events

Always poll your sockets. Polling the sockets will check if a socket is connected, if data has been received, or if an error has occurred. This is a part of code you will be calling over and over. Do not just call it if you are waiting for data; because then you will not know if your sockets still are connected or not, and if an error has occurred.

The general idea of this routine is, you will be calling selectsocket() and supply three lists, each list containing a list of sockets you want to poll for a certain state. The first list would be to check if new data has arrived, the second list to check if you can write to the socket, and thus if youíre (still) connected, and the thirth list to see if an error has occurred. Each list starts of with the number of sockets being in this list.

Our lists in this piece of code are called rfds() for the read list, wfds() for the write list, and efds() for the error list. We Dimensioned them from 0 to 1, because we are only polling a single socket here. If weíd be polling a list of sockets, we put the number of sockets as the first element of the list, and the socket handles in the following elements. Meaning weíd dimension the list bigger.

We also supply a timeval record with the selectsocket() function, which really has no use in our case. This only has meaning when we would be working in BlockingMode. Meaning the selectsocket() function will wait for an event to happen, or to time out, using the timevalues in the timeval record youíd supply. By default, in NonBlockingMode, set them to zero.

When the selectsocket() is performed, it will return a zero, if no events have happened. This is case when your sockets arenít connected in some way. If it is lower than zero, an error occurred. If it is bigger than zero, it is the number of sockets which something happened with.

If something did happen, selectsocket() will return lists of the sockets in which something happened. For example, if data has arrived and stored in the receive buffer of one socket, rfds(0) would contain 1, meaning one socket has data in itís received buffer, and rfds(1) would contain the handle of the socket. If two sockets have received data, rfds(0) would contain 2, and rfds(1) and rfds(2) would contain the handles of those two sockets, which received data.

Same goes for writing and errors. Whenever a socket is connected, you can write to it. Meaning wfds() will return the sockets that are connected. This is a way to test if your connection in the previous chapter has succeeded. If the connection would fail, the socket handle eventually would end up in the efds() list.

If there is a socket in the efds() list, close the socket, the connection has been terminated.


Lines that need to be included
TYPE timeval
        tvSec AS LONG ' Seconds
        tvUsec AS LONG ' And MicroSeconds
END TYPE
 
DECLARE FUNCTION closesocket% (BYVAL s AS LONG)
DECLARE FUNCTION selectsocket% ALIAS "select" (BYVAL nfds AS INTEGER, ...
			SEG readfds AS LONG, SEG writefds AS LONG, ...
			SEG exceptfds AS LONG, SEG timeout AS timeval)
DIM iRetVal AS INTEGER
DIM rfds(0 TO 1) AS LONG
DIM wfds(0 TO 1) AS LONG
DIM efds(0 TO 1) AS LONG
DIM TimeOutValues AS timeval
 
TimeOutValues.tvSec = 0 Ď Wait zero seconds.
TimeOutValues.tvUsec = 0 Ď Also wait zero MicroSeconds

rfds(0) = 1 Ď Number of sockets included in the write list
rfds(1) = lSocketHandle
wfds(0) = 1 Ď Number of sockets included in the write list
wfds(1) = lSocketHandle
efds(0) = 1 Ď Number of sockets included in the error list
efds(1) = lSocketHandle

Ď Poll the lists of sockets.
iRetVal = selectsocket(0, rfds(0), wfds(0), efds(0), TimeOutValues)
 
IF iRetVal = 0 THEN
        Socket has no new updates. Thus the socket is not yet connected.
        EXIT SUB
END IF
 
IF iRetVal > 0 AND (rfds(0) <> 0) THEN
        Data has been received in the socketís receive buffer.
END IF
 
IF iRetVal > 0 AND (wfds(0) <> 0) THEN
        It is possible to send data. The socket is connected.
END IF
 
IF iRetVal < 0 OR (efds(0) <> 0) THEN
        Error! Something wend wrong with the socket, close it.
        iRetVal = closesocket(lSocketHandle)
        EXIT SUB
END IF

Disconnect

Disconnecting and closing the socket is pretty straightforward. The number given with the shutdown() function determines how brutal the socket must kill the connection. There isnít much that can go wrong here.


Lines that need to be included
DECLARE FUNCTION closesocket% (BYVAL s AS LONG)
DECLARE FUNCTION shutdown% (BYVAL s AS LONG, BYVAL how AS INTEGER)
DIM iRetVal AS INTEGER

iRetVal = shutdown(lSocketHandle, 2)
iRetVal = closesocket(lSocketHandle)

Deinitializing DSock

When youíre completely done with DSock, do not forget to uninitialize the library. Not doing so might result in some programs to remain in memory. Before you do a cleanup, make sure you shutdown and closed all the sockets first! Not much to it, really.

Lines that need to be included

Lines that need to be included
DECLARE FUNCTION WSACleanup% ()                                     
DIM iRetVal AS INTEGER

iRetVal = WSACleanup%

Sending Data

When sending data, make sure you did poll the socket first, and that it is connected. Or else youíll surely get an error while trying to send data. For some reason, the send() function will not accept a simple STRING. It always wants the data to be sent away, to be in a record structure. Thatís why the record was temporary made. Whenever you are going to code a decent program using DSock, you probably have all that stuff in a record anyways.


Lines that need to be included
DECLARE FUNCTION send% (BYVAL s AS LONG, BYVAL buf AS LONG,...
		BYVAL length AS INTEGER, BYVAL flags INTEGER)
DECLARE FUNCTION MAKELONG& (BYVAL lsw AS INTEGER, BYVAL ...
		msw AS INTEGER)
TYPE SocketStuff
      lSocketHandle AS LONG
      stSendData AS STRING * 256
      iLengthOfData AS INTEGER
END TYPE
 
DIM iRetVal AS INTEGER
DIM iBytesSent AS INTEGER
DIM Sock(0) AS SocketStuff
 
Sock(0).lSocketHandle = lSocketHandle
Sock(0).stSendData = ĒMessage you want to sendĒ
Sock(0).iLengthOfData = LEN(ĒMessage you want to sendĒ)
 
Ď Make SURE you do NOT get the length by performing LEN(Sock(0).stSendData) 
Ď because that will just be 256, always.

iBytesSent = send(Sock(0).lSocketHandle, MAKELONG(VARPTR(Sock(0).stSendData),
   VARSEG(Sock(0).stSendData)), Sock(0).iLengthOfData, 0)

Receiving Data

When receiving data, make sure you did poll the socket first, and that it is connected. Or else youíll surely get an error while trying to receive data. For some reason, the recv() function, just like the send() function, will not accept a simple STRING. It always wants the data to be sent away, to be in a record structure. Thatís why the record was temporary made. Whenever you are going to code a decent program using DSock, you probably have all that stuff in a record anyways.


Lines that need to be included
DECLARE FUNCTION recv% (BYVAL s AS LONG, BYVAL buf AS LONG, ...
		BYVAL length AS INTEGER, BYVAL flags AS INTEGER)
DECLARE FUNCTION MAKELONG& (BYVAL lsw AS INTEGER, ...
		BYVAL msw AS INTEGER)
TYPE SocketStuff
      lSocketHandle AS LONG
      stReceivedData AS STRING * 256
      iLengthOfDataReceived AS INTEGER
END TYPE
 
DIM iRetVal AS INTEGER
DIM stMessageReceived AS STRING
DIM Sock(0) AS SocketStuff
 
Sock(0).lSocketHandle = lSocketHandle
 
iRetVal = recv(lSocketHandle, MAKELONG(VARPTR(Sock(0). stReceivedData), ...
		VARSEG(Sock(0). stReceivedData)), LEN(Sock(0).stReceivedData), 0)

Appendices

"Ignore this lower part of the document. It is badly written and barely helps you." - Marcade

Appendix A: Type Definitions

WSAData
wVersion AS INTEGER
wHighVersion AS INTEGER
szDescription AS STRING * 257
szSystemStatus AS STRING * 129
iMaxSockets AS INTEGER
lpVendorInfo AS LONG

inAddr
Saddr AS LONG

sockaddrIn
sinFamily AS INTEGER
sinPort AS INTEGER
sinAddr AS inAddr
sinZero AS STRING * 8

Appendix B: Subs/Functions

closesocket([long]) AS INTEGER
This function will close and terminate a socket for usage. The parameter given is the socket handle.

connect([long], [any], [integer])
This function will connect a socket. The first parameter is the socket handle, the second parameter is the SocketAddress record that was defined earlier. The thirth parameter is the Length of the SocketAddress record.

gethostbyname([string]) AS LONG
This function will resolve a hostname and retrieve information. It returns a pointer that can be used by the hostent functions of Dsock.
Returns:
[Pointer to be used by hostend functions]
hostent.hAddrList ([long])
This will return the address thing? Parameter is the HostHandle retrieved with gethostbyname.

htons ([integer]) AS INTEGER
Returns a port thing that can be used for the host address record passed to a connect function. Parameter is the portnumber you want to use in your hostaddress record.

ioctrlsocket([long], [long], [long]) AS INTEGER
This function will help putting the socket into non-blocking mode. The first parameter is the Socket Handle, the second parameter the command what to do (Non blocking). The thirth I am not sure.

MAKEWORD([integer], [integer]) AS INTEGER
This function will create a word in the selected integer. I donít know exactly what it really does.
Returns:

[unknown]
WSAGetLastError() AS INTEGER
This function will retrieve the error code of the last error that occurred.

WSAStartup([integer], [WSAData]) AS INTEGER
This function will start up Dsock and request the winsock version number. It will put all the information in a predefined record WSAData.
If the first [integer] does not matches wVersion in [WSAData] then the Winsock version requested, is not supported.
Returns:

0                                 -                       Ok.

<>0                               -                       Not Ok.
recv([long], [long], [integer], [integer])
Receives data from a socket. First parameter specifies the Socket Handle. Second Parameter specifies the Segment of the string where the array is at, created with MAKELONG. The Thirth Parameter specifies how long the message is. And the fourth is a flag to specify if it is an OOB message.
Returns:

-1                                 -                       Error Occured

Number of bytes received
selectsocket([integer], [long], [long], [long], [long]) AS INTEGER
This function checks for status changes of a list of sockets. First parameter is zero, this is for compatibility reasons. Second record is to check readability of the socket(s). Thirth checks the writability of the socket(s).Fouth checks for OOB stuff of the socket(s), and fifth parameters specifies timeout values. If the timeout values are zero, it will just check and immediately return the statuses. Else it will wait for the time.
Returns:

Above zero                         -                       Number of sockets ready

0                                  -                       Time out

-1                                 -                       Error occured
send([long], [long], [integer], [integer])
Sends data away through a socket. First parameter specifies the Socket Handle. Second Parameter specifies the Segment of the string where the array is at, created with MAKELONG. The Thirth Parameter specifies how long the message is. And the fourth is a flag to specify if it is an OOB message (Out Of Band; a message sent to the other party with priority, meaning it will disrupt the flow. For example, server is sending to client ďABCDEFĒ and then an OOB message ďGĒ immediately after that. The client will receive something like ďABCGEFĒ or ďAGBCDEFĒ. The G will get there ASAP.)
Returns:

-1                                 -                       Error occured

Number of bytes sent away. Does not have to comply with the length of the message.
socket([integer], [integer], [integer]) AS LONG
This function will create/reserve a new socket for you to use. First parameter specifies what kind of network you will be operating on. The second parameter will specify the type of connection you will make. The final parameter will specify what protocol you will be using.
Returns:

-1                                 -                       Could not open a new socket.

[Socket Handle]
shutdown([long], [integer]) AS INTEGER
This function will disconnect the socket selected in the first parameter. The second parameter is how brutal the socket should disconnect. (Standard it is 2)

Download the original DSock Tutorial Document here.

Final Word

Well, that's it for this first issue of QB Express!

Next issue, we will bring you more tutorials (RelSoft has mentioned that he's got another up his sleeve), probably the next edition of "Bobby The QBasic Maniac", another "Blast From The Past", more interviews with QB gurus, some editorials on the state of the QB community by yours truly, the latest QB News and a whole lot more! However

Before then, though, I would love to have some feedback on this first issue. What did you like? What didn't you like? What could we make better? Do you like the title "QB Express", or do you think I should change it to something else? Tell me by emailing me or filling out this form!

Also, we are looking for more submissions -- tutorials, articles, editorials, reviews, QB news stories, comics, advice or anything else you'd like to submit. Remember, QB Express is an open magazine, and anyone is allowed to write for us! Send your submissions to pberg1@ithaca.edu or fill out this form.

That about wraps it up for this issue. I'd like to again thank all of our contributors, and thank you for reading! I hope you liked it!

Until next time...END.

-Pete


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