Welcome to the first in a series of posts demonstrating how to program a simple 3D game using DarkBasic! Many will correctly assert that DarkBasic is not a professional quality language and IDE; however, I believe it is a great tool to learn a number of aspects related to programming in general as well as graphical and 3D applications. If you would like to skip the introduction and other things just scroll to the first bold text, but don't blame me if you receive down-votes for something you asked or said!
Let's begin with my own background! Although my specialties lean more towards electrical engineering, solid-state chemistry, and microprocessor design, I have done a lot of programming. I taught myself programming via 8080 (MCS-80) assembly language when I was about 12 and progressed to QBASIC, then to other assembly dialects including MCS-4, Z80, x86, 680x0, UPI-41/42, MCS-51, IA-32/64, and so on. I have also written scripts using JavaScript, PHP, Python, and Scratch more out of necessity than enjoyment. While I have delved in to object-oriented programming using high-level languages like C++, I don't find any joy in it.
So, what is DarkBasic? Simply, it is a dialect of Basic which natively supports the use of DirectX via keywords. To follow along with these tutorials you will need to start with a copy of DarkBasic Professional. What will we make in this series of tutorials? I believe the answer to that is not as important as what we will not be making; we won't be making a AAA game engine, MMORPG, a game similar to [insert your favorite game here], and so on. Responses asking "design me a WoW", "How do I make teh besteses MMORPG evar", "Make a CoD but like a MMOFPSRPGRTS", etc will receive down-votes. This isn't intended to be a series which teaches you basic programming concepts, algebra, and so on; therefore, you will need to learn those yourself. Also, I've chosen to include screenshots rather than video and have also chosen to forego including code you can cut-n-paste into your IDE for several reasons. So no, I won't put code here for you to simply cut-n-paste; don't ask or you will receive a down-vote. The following images may not be easy for you to read, just right-click on them and select "View Image". Let's Start!
**The Setup**
The first task we must accomplish is specifying the name of the executable DBPro will produce when we tell it to build our program. Open DBPro and ensure you have the "Project Summary" pane open by clicking the red button labeled "Project" in the lower-right corner of the screen. Next, specify an executable name by clicking the "Browse" button near the upper-right corner of the Project Summary pane.
<center></center>
<center>*Project Summary Pane*</center>
Find or create a folder which will house all of the code for our project and name your executable anything you like then click "Save"; I'm simply naming it "3D Engine" and placing it in the "3D Engine" directory.
<center></center>
<center>*Giving it a Name*</center>
Finally give your project a name by entering it in the "Project Name" text box at the top of the Project Summary pane.
<center></center>
<center>*Naming the Project*</center>
At this point we could save our *project* but we wouldn't have any *source* files. DBPro projects are composed of one or more source files, each containing functions that make up our program. Let's enter a bit of code for our main source file:
<center></center>
<center>*A Bit of Code*</center>
The *wait key* keyword tells DBPro to halt program execution until a key has been pressed while the *end* keyword tells DBPro it has reached the end of our program and must terminate. Click the "Make EXE/Run" button, or press the F5 key to test our program; you should see a black screen with "Success!" displayed.
We may now save our source file, and because the code in it will be the point at which our program begins execution, I am naming it "Main". From the "File" menu, select "Save Source As" and enter the name of your choice.
<center></center>
<center>*Saving the Source*</center>
The final step before moving on to doing some real coding is to examine the "Source Files" panel; just click the red "Files" button in the lower-right corner of the screen to show the panel. Notice the main source file is the one we just saved, and that we can also include additional source files. It's always important we remember that source files are saved separately from the project file; I prefer to periodically select "Save Project" as well as "Save All" from the "File" menu to ensure I don't lose any work I've done.
<center></center>
<center>*Source Files Panel*</center>
**On To Code**
Now that we have set up a project, how do we begin to program something as complex as a 3D game? We can start with one item which will make things easier for us later as well as help to make our program easier on our eyes - the display resolution.
As stated earlier, source files contain code which is specific to a particular program function or group of functions. For example, routines handling joystick input could be grouped into a source file named "Joystick" while routines handling player movement could be grouped in a source file named "Player". The "Add New" button allows us to create *new* source files, while the "Browse" button permits us to add *existing* source files to our project. For our display routines I will name my source file "Display"; from the Source Files panel, select "Add New" and enter the name you wish to use then click "Save".
<center></center>
<center>*Creating a New Source File*</center>
We must now edit our display source file, but how do we make it show in our editor? Easy, click the drop-down box near the top of the screen, just to the left of center, and select your display source file. In my case it's named "Display" and shows in the drop-down box as the same name. After selecting the source file, enter the code included in the following image.
<center></center>
<center>*Selecting a Source File and Entering Code*</center>
The code we just entered accomplishes the following:
* Defines a data type used to to describe a single display mode (lines 1 - 5)
* Horizontal resolution in pixels (line 2)
* Vertical resolution in pixels (line 3)
* Color depth in bits (line 4)
* Defines a function which initializes our display data and display mode (lines 7 - 52)
* Creates an array for storing display modes (line 9)
* Creates temporary variables for resolution and depth; sets their default values (lines 14 - 19)
* Prepares video memory and clears the screen (lines 21 & 22)
* Clears the checklist and requests available display modes from the system (lines 24 & 25)
* Moves available display modes from checklist into display mode array (lines 27 - 35)
* Sorts display modes from smallest to largest (lines 37 - 50)
* First by horizontal resolution
* Next by vertical resolution
* Last by color depth
* Sets the display mode to the highest resolution and color depth combination (line 52)
* Returns to main routine (line 54)
With a method to initialize our display, we need to invoke it from our main routine, found in our main source file. Remember, we show different source files using the drop-down box near the top of the window. In the main source file, enter the code in the image below:
<center></center>
<center>*Code to Invoke Our Display Routine*</center>
At this point we may compile and execute our code by clicking the button near the top of the window or pressing the F5 key; to advance the program once it's running you will need to press a key after each display mode is shown on the screen. You should have noticed the resolution changed by the time the program displayed "Success!". Ok so we can change resolutions, but if your system is like my own, the resolution may be too high for you to easily read and see what is on the screen. This is due to a mismatch in what the graphics adapter reports to DBPro and what the display is capable of clearly showing. There are additional functions we need to implement which will also help address this issue. we will be creating the following three functions: a method to check if a specified display mode is available, a method to return the current display mode, and a method to set the desired display mode. Before we do this, let's look at a small but helpful control that lets us collapse functions in order to free screen space for other uses:
<center></center>
<center>*Collapsing a Function*</center>
By clicking on the little box to the left of a function declaration the entire function can be collapsed. To expand a collapsed function simply click on the little box again. With this knowledge we can move on to coding the next three functions in our display source file; enter the code found in the image below:
<center></center>
<center>*More Display Functions*</center>
Our first new function does the following:
* Steps through each display mode (lines 63 - 71)
* Returns a 1 (or True) to the caller if the display mode is available (line 67)
* Returns a 0 (or False) to the caller if the display mode is unavailable (line 73)
In the second new function we find:
* Converts integer values to strings and packs them into a return string (line 77)
* Returns the string to the caller (line 78)
The third new function adds these lines:
* Step through each display mode (lines 82 - 94)
* Set the display mode if (line 86):
* Horizontal resolution is equal to requested horizontal resolution AND (line 83)
* Vertical resolution is greater than or equal to requested vertical resolution AND (line 84)
* Color depth is greater than or equal to requested color depth (line 85)
* Store the new display mode values in the display mode array if all the above conditions are met (lines 87 - 89)
* Return to caller with True if all the above conditions are met (line 90)
* Return to caller with False if any of the above conditions are not met (line 96)
In addition to adding this to our display file, we must remove code which was included to allow us to view available display modes as they were read into the system. In our display initialization routine, remove the print statement as well as the wait key statement (lines 29 & 30 in image 08).
Next we must add code to our main source file to use these functions. Enter the following into main, substituting the appropriate resolution and color depth for your system in lines 6 & 7, and compile/run it when ready:
<center></center>
<center>*Using All Our Display Functions*</center>
Results vary, but on my system I first see a black screen with "2560x1600x32" displayed, then "1920x1080x32" after I press a key. Remember to save your project as well as source files!
What do you think the code we added to our main file does? How does it work?
This wraps up our first tutorial, in which we configured our project, created our main and display source files, and got our display functions working.
Thanks for reading and following along, and I hope to hear your comments, questions, and suggestions!