Monday, July 23, 2012

Lesson 4: Event Driven Programming

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.


Now that we've learned how to draw images to the screen it's time to learn how to read user input. Our game won't be very good if there's no way to play it! In this lesson we will cover simple event handling using SDL and begin designing a primitive 'main loop'.

Before we begin it's important to mention that the majority of the code being used for this lesson is the code that we've built up from previous lessons, and as such the repeated code will not be shown as it is assumed you have it already and  are using what you're learning here to add on to the previous lesson's code. If you don't have the code, head back to the earlier lessons, or if you already understand the material grab the code from Lesson 3 off Github and let's get started modifying it.

We'll create the renderer and window the same as before, and our LoadImage and ApplySurface functions remain unchanged. The first change to our program is the loading of a different image, note that you will need to change the filepath to match the location of the image relative to the executable on your system, or the program will fail to run.
We also use the same equation as before for centering our image in the window. For this lesson our image will be:
 


Now before we dive into writing our main loop and event handling code, we'll want to get an understanding of how the SDL event system works.

An event is any interaction with the program done by the user: keypresses, mouse motion, mouse presses, joystick movement, window resizing, minimizing or closing, etc. SDL provides a structure for storing these events called SDL_Event. Let's create one now.
Whenever an event occurs it's added to the queue in chronological order. If we want to read an event from this queue we can pull the oldest event using SDL_PollEvent. This may be a bit confusing, hopefully this handy graphic will help make it a bit clearer.


So in this case the user resized the window, then clicked the mouse, then pushed a key. When we call SDL_PollEvent on this queue it will get the event that happened first, or the oldest event, and put it into our SDL_Event structure so that we can look at the event data in our program.

So if each frame of our game we want to process all events in the queue we'll want to loop through until there's nothing left to read, then continue on and do our other stuff like logic and rendering. This is starting to sound like something we could call our main loop!

In each iteration of the loop we'll want to process our event queue, do some program logic and draw the frame and then do it all over again until the user quits.
Next we'll want to do our event polling. Our goal was to run over all the events in the queue each frame, so let's use another while loop, as PollEvent will return 1, 'true', if there are any pending events, so our loop will run until there are no more events in the queue.
First we get an event from the queue with SDL_PollEvent, which we pass an address too as its signature is SDL_PollEvent(SDL_Event*) and then we do whatever we want to with the input. In this case we're just going to quit the program if the user pushes any key, clicks the mouse or closes the window, so if just about anything happens we set quit to true. Note that clicking the X on the window is read as SDL_QUIT.

SDL's event structure is able to read many different types of events and provides all the valid information tied to each event that may be needed in deciding what to do with the input. For more information on the various event types and the data that comes with them, check out the SDL_Event documentation.

The next step in our loop would be to do various calculations that our program needs to do, such as determining movement, collision outcomes and etc. However since our program is very primitive we don't need to do any logic at the moment, so we'll continue on to rendering.
The code is identical to before, but we must be sure each time to clear the screen before drawing our new scene or we could have images left over from previous frames start showing up.

You'll want to wrap up the program by destroying the texture, renderer and window and quit SDL.

When you run the program you should be able to quit by clicking the X on the window, clicking in the window or pressing a key while the window is selected. You may also notice something a bit interesting when running the program if you check its CPU usage. If you've seen tutorials where the main loop is discussed or have written SDL1.2 code you'd expect that our program for this lesson would max out one of your CPU cores because there's no framerate limiting being done. This is no longer the case with our program as we have created our renderer with the SDL_PRESENTVSYNC flag which tells the renderer to delay and match the framerate of our monitor, letting SDL take care of the framerate limiting for us, and letting us skip writing a line or two of code.

Lesson 4 Extra Challenge!

Try getting the image to move on the screen.
Hint

End of Lesson 4: Event Driven Programming

Thanks for joining me! I'll see you again soon in Lesson 5: Clipping Sprite Sheets

Thursday, July 19, 2012

Lesson 3: SDL Extension Libraries

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.

You may have been wondering throughout the previous tutorials if it is possible to load images that aren't BMPs. Although SDL does not provide functionality for loading non-BMP images itself, there exists a large amount of robust and powerful libraries that extend SDL's functionalities to include loading many image formats via SDL_image, rendering true-type fonts with SDL_ttf, support for more audio formats with SDL_mixer and even networking from SDL_net.

By using these libraries we can add much more functionality to our programs and do many things much easier. For now we will only be using SDL_image, but will cover the other extensions in later lessons.

In Lesson 0, when you cloned from the Mercurial and built the libraries you should have also downloaded and built the source for SDL_image, SDL_ttf and SDL_mixer, although I was unable to get SDL_mixer to compile with Visual Studio at the time of writing. This part of the tutorial will be updated when SDL 2.0 is officially released to simply contain links to download the libraries.

If you have not done this, head over to the SDL Mercurial and clone and build the extension libraries available there.

To include the headers and library files on Windows simply paste them in the include and lib directories of your SDL 2.0 folder and add SDL_image.lib and etc. to your linker settings. On Linux following the configure, make, make install pattern will spit out a location where the libraries were installed that you can link against.

In addition to setting up the includes and libraries you will also need to put the dlls that are located in the externals folder along with the dll that was created when building the project. Some dlls are dynamically loaded and as such, only needed if you intend to use their functionality, you may consult the extension library page for the specifics on which dlls behave this way.

In addition to exploring the SDL_image library in this lesson we will also begin to learn about throwing and catching exceptions by adding some error handling to our LoadImage function from last time, instead of checking if the returned pointer was still null. This will allow us to get more information about the exact error that happened and help us track down the cause of the error faster.

For this lesson we will simply be adding some extra stuff to the code we wrote in Lesson 2, so let's get that open. IDE users will want to add SDL_image to their linker settings as described above, and for those of you compiling with g++ add -lSDL_image or -lSDL2_image depending on how your 2.0 libraries are named.

We'll need to add the extra includes for the new things we want to use, SDL_image and stdexcept.
From here we setup as before our screen parameters and create a global window and renderer. If you're feeling ill from the use of global objects you may want to take a moment.
Now let's rework our LoadImage function to use SDL_image's IMG_LoadTexture to directly load a texture from an image. SDL_image supports many image formats: BMP, GIF, JPEG, LBM, PCX, PNG, PNM, TGA, TIFF, WEBP, XCF, XPM, XV and as such is a very powerful and useful library, as we are no longer limited to the BMP format

Reworking our function is surprisingly simple, we just take out the SDL_Surface business and load the texture directly. Note that we now use IMG_GetError() instead of SDL_GetError(), this is because we're now using the SDL_image library to load the image, and as such the appropriate error information would be stored there instead of in SDL.
But we've got one more new thing here. Since we've decided to be smart and add more informative error checking if our image fails to load we will throw a runtime_error which will tell us what happened and more helpfully, which image caused the error. However if you leave this error uncaught when you call the function later in your program and it occurs, it will crash the program. Depending on the situation this may be desirable, but at the moment we'll want it to tell us what happened as opposed to just crashing.

We're almost ready to draw our images, for this lesson we'll be using this image as our background:
and our foreground image will be:

If you look at our foreground image you'll notice that it has a transparent background, I've set it like this to demonstrate that IMG_LoadTexture will respect alpha channels and that when the texture is drawn the transparent properties will be retained.

Now that we've got our images we can write our loading code, but recall that we'll need to add a try/catch structure to handle the error if one is thrown. Also, don't forget to set the file paths to match the image locations on your system.
In our catch statement we tell the program to print out e.what(), which will display the string that we put into the runtime_error's parentheses. Note that depending on how you've configured your project to build you may not get stdout displayed, if that is the case you can simply write the information to a file instead.

The rest of the code is not shown as it is identical to what was written for Lesson 2, so you can just drop in this new functionality into the old program. If you want to mess with the image positions, feel free to play around. When running the program with the same position settings as Lesson 2 you should see this:

Note that the transparency of the foreground image was preserved. This is a very useful effect as it means we won't have to use color keying to cut out the background of our images but instead can use simple transparency. However if you do wish to use color keying, it will be covered in later lessons.

End of Lesson 3: SDL Extension Libraries

If you have issues compiling or running the code make sure that you've added the include paths and linker settings correctly, along with putting the dlls from SDL_image and its dependencies, located in the externals folder of the source code, into the same folder as your executable.

I'll see you again soon in Lesson 4: Event Driven Programming!


Wednesday, July 18, 2012

Lesson 2: Don't Put Everything in Main

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.

In this lesson we will begin organizing our code from the previous lesson by writing some very useful functions, along with discussing how images are positioned and scaled in the SDL window.

As always we'll need to start our program off by including SDL. We'll also need the string class in this lesson so we include that as well.
We'll also declare some constant values for our screen width and height along with global declarations of a window and renderer so that they're accessible by our functions. Again we initialize the pointers as nullptr for safety. If you're not using C++11 initialize them as NULL.

Note: You should avoid using non-constant global values or global values in general as much as possible, ie. you should never ever declare a global SDL_Window or SDL_Renderer. However, for this simple lesson we'll let it slide. But it's ok if you feel grossed out. We'll cover a solution to global objects in a few lessons.

Remember from Lesson 1 where we loaded a texture? It wasn't so bad to just have it in main for loading one image, but what if we had lots images to load? We'd have to type it out every time! We can do much better, instead let's define a function for loading textures from a filename:
The function here should look very familiar as it's the exact same code we wrote in Lesson 1, but now we have wrapped it up in a nice function. With this function we can pass a file name as a string and get back a pointer to the loaded SDL_Texture. Note that the pointer will be nullptr if the loading fails because we initialize both pointers as nullptr for error checking.

Next we'll want to write a function to simplify our draw calls and also allow us to specify a position to draw the image too on the screen. We'll want it to be able to take an x, y coordinate position along with a texture pointer and a renderer pointer and then draw the texture to that position.
In order to specify a position for the texture to be drawn too we need to create a SDL_Rect that we can pass the address to SDL_RenderCopy's destination rect parameter. This is done because the last two parameters of SDL_RenderCopy are SDL_Rect pointers, so it's expecting an address.

To create our rectangle we take the x and y values that we passed in and the set rectangle's values equal to them. However we must also specify the width and height we want the texture to be drawn with as SDL 2.0 also gives us the ability to scale our textures. Try playing with the width and height values once the tutorial is done and see what happens!

For now we just want to pass the texture's width and height so that we draw it at a 1:1 scale. We can get these values by using SDL_QueryTexture. This function takes the texture pointer we want to query, the two parameters we pass NULL to are the format and access level parameters respectively, which we can ignore. Finally we must pass the addresses of the variables that we want to fill with the width and height of the texture.

Now that we've got our SDL_Rect set up we can pass it, along with the renderer and texture as before, to SDL_RenderCopy so that our texture will be drawn at the point specified and with its original width and height. The remaining NULL parameter in this function is for taking a clip of the source texture, which we'll cover later.

Let's see our functions in action. First we've got to start up SDL and create our window and renderer as before. We've also got something new here, SDL_WINDOWPOS_CENTERED. This is an option we can use when creating our window to tell SDL to center its position on the specified axis, here we do it for x and y.
Now let's load up our images. For this lesson we'll be drawing a tiled background image and drawing a centered image on top of it. Here's our background:

And this will be our foreground image:

Let's load them up with the LoadImage function we just wrote.
Note that you will have to change the file paths to match the relative location of the image to the executable on your system.

Before we draw the images we'll need to know where we want to position them, specifically how we'll tile our background and also how we can draw the foreground image centered on the screen. First we'll have to understand how SDL's coordinate system works, as it is a bit different than the standard 2D Cartesian coordinate system. SDL's coordinate system looks like this:
With 0, 0 being in the top-left corner of the screen. Y values increase as we move down the screen and X values increase as we move to the right on the screen. Another thing to note about SDL's coordinate system is that the x, y point specified to draw an image at is used as the location to draw the top-left corner of the image, as opposed to the center of the image like some other libraries.

Before we draw: A note about SDL's drawing order: The order in which things are drawn will be the order in which they sit on top of each other, so the first thing drawn is the bottom-most image, and the last image drawn will sit on top of everything.

If you've taken a peek at the background image yet you'll have noticed that it has a width of 320 and a height of 240, with a screen that is 640x280 we'll need to draw the background image four times to tile it over the window scooting it over by its width or height each time.

Before drawing anything, we'll want to clear the screen, next we'll want to setup the positioning of elements on the window. We can get the width and height of the image again by using the QueryTexture function on the background, this gives us a more versatile method in which we could instead create a for loop to iterate over the positions based on the image width and height, perhaps if we were placing many small tiles. For this case we're only drawing it four times, so we can take the 'dumb' route and just type it out.
Now we want to draw our foreground image on top of the background, and centered in the window. We can calculate the center point quite easily but because the point we pass to ApplySurface is the location of the top-left corner of the image we must also apply an offset to the point relative to the image's width for x and height for y to put the real center of the image at the center point of the screen.
In order to see our drawing we'll have to present the renderer and then have SDL wait for a second or two so we have a chance to see the image.
Finally, we wrap up the program by freeing the memory being used by the textures, renderer and window, quit SDL and return.
When you compile and run the program your window should look like this:


Lesson 2 Extra Challenge!

Find a way to convert our dumb method of tiling the background into a lean mean for loop! While it may not be so effecient for four background tiles, using a for loop for tiling is a very nice method for placing a large amount of tiles.
Hint


End of Lesson 2: Don't Put Everything in Main

If you have trouble compiling or running the program make sure you've set up the includes, include directories, linker settings and linker directories correctly, along with setting the correct path to the images and placing the SDL.dll in your executable folder. For Linux users there is no SDL.dll but instead make sure you have the runtime libraries in the correct place in your system.

I'll see you again soon in Lesson 3: SDL Extension Libraries!

Wednesday, July 11, 2012

Lesson 1: Hello World!

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.


In this lesson we will learn a simple method for drawing a bmp image to a screen, the image below to be specific.

You can download the image above by right clicking and selecting save-as. The link is a direct link to the image on the Github repository I have created and as such will be a true BMP image that SDL can load. The repository is also home to all my code from the tutorials and any related assets they need. If you ever lose the assets or want to take a peak at my code, grab it here. But never copy!

The first step as always is to include the SDL header
#include "SDL.h"
Note that depending on your SDL configuration you, Linux users to be specific, may need to do
#include "SDL/SDL.h"
//or
#include "SDL2/SDL.h"
//depending on your configuration
Unless you're specifying the full path to your header files in your flags (Linux users)

First we'll need to start up SDL so that we can use it, note that if SDL fails to initialize it will return -1, in which case we'll want to print out the error using SDL_GetError() and exit our program.

Special note for Visual Studio users: If you've set your System to Windows in your Linker options panel you won't get std out to console, to get this you must change your System to Console.
Next we'll need to create a window that we can draw things too, we can do this by using the SDL_Window:
The SDL_CreateWindow function takes care of making our window and returns a SDL_Window pointer back to us. The first parameter is the name we want for our window, followed by the x,y position we want to open it up at followed by the width and height we want our window to be. The last parameter are various flags we may want for our window, in this case we want it to pop up immediately, so we pass SDL_WINDOW_SHOWN.

We also take care of providing some error safety in that we initialize our pointer as a nullptr and then check to see if it's still null after trying to create the window. If creating the window failed it would still be null and as such we'd want to break out of program. It is important that you always initialize your pointers to NULL, or with the new C++11 standard to nullptr.

Now just opening up a window isn't going to do very much for us, we'll need something to render things to the window as well, so let's get an SDL_Renderer up and running.
Our renderer is created by SDL_CreateRender, which requires a window to render too. We can also specify a video driver to select, or put -1 to have SDL select the appropriate driver based on which is able to support the flags we specify. This is probably the best option to use, as you let SDL take care of picking the right driver for your needs, ie. the flags you pass as the last parameter.

In this case our flags are SDL_RENDERER_ACCELERATED because we want to use a hardware accelerated renderer, ie. the graphics card and SDL_RENDERER_PRESENTVSYNC because we want the SDL_RendererPresent function, which refreshes the screen to be run in sync with the monitor refresh rate.

Note that we use the same error checking method that we used when creating the window

It's time to load an image to draw to the screen! You should have downloaded the image from the Github repository and saved it in the same folder, or nearby to where your executable will be built too.

Although SDL 2.0 uses SDL_Textures for hardware accelerated rendering, we'll still need to load our image to an SDL_Surface using SDL_LoadBMP, as this lesson isn't using the fantastic SDL_image extension library (we'll get to it soon).
Note that you will need to change the filepath passed to SDL_LoadBMP to match the location of the image on your machine, or leave it the same if you've decided to follow my folder structure exactly.

To take advantage of hardware accelerated rendering we must next convert our SDL_Surface to an SDL_Texture that the renderer can draw.
We also free the SDL_Surface at this point because it is no longer needed.

We can now draw our texture to the renderer. First we clear the screen with SDL_RenderClear, then we can draw the texture with SDL_RenderCopy. Finally we update the screen with SDL_RenderPresent.
We also pass two NULL values to RenderCopy, the first one is a pointer to the source rectangle, ie. a clip to take of the image sheet while the second is a pointer to the destination rectangle. By passing NULL to both parameters we tell SDL to take the whole image (first NULL) and draw it at 0, 0 and stretch it to fill the entire screen (second NULL), more on this later.

We also tell our program to wait for 2000milliseconds with SDL_Delay so that we can see the screen. Without the delay the window would pop up and then close as the program finishes very quickly.
Before we exit our program it is necessary to free the memory used by our window, renderer and texture. This is done using the various SDL_Destroy functions
Finish the program by quitting SDL, and returning 0.
Compile the program and check it out! Don't forget to put SDL.dll in the same directory as your executable or you'll get an error pop-up. If you're using Linux you should already have the shared libraries installed in your path so you shouldn't have any issues

Congratulations on your first SDL 2.0 program!


Troubleshooting

If your program fails to compile make sure you've properly configured your libraries and linked to the correct path in your include statement.

If your program complains about SDL.dll missing, make sure it is located in the same folder as the executable.

If your program runs but exits with out displaying anything make sure your image path is set correctly. If that doesn't help try writing some cout or file output into the program, although depending on your platform and configuration settings cout may not appear.

End of Lesson 1

That does it for Lesson 1, I'll see you again soon in Lesson 2: Don't Put Everything in Main

Lesson 0: Setting up SDL

SDL 2.0 Note

SDL Release Update: Now that SDL2 is out (hooray!) I've put an updated setup guide over here.

 

As of the time of writing this post, July 17, 2012 the SDL 2.0 libraries have not been officially released and as such you will need to compile them for yourself with your editor of choice.

You may download the libraries from here.

Cloning from the Mercurial directly will get you an up to the minute version and while the snapshots are also a fine alternative, at the time of writing you need to clone the Mercurial repository in order to download snapshots of the extension libraries we will be using later in this tutorial.

After downloading the repositories setup should be reasonably straightforward. Note that the extension libraries SDL_image, SDL_ttf and SDL_mixer depend on SDL and as such you may need to specify include directories or linker settings for them to compile and SDL should be compiled first.

Note that the source folders contain documentation on how to build them with each platform which should take you through building and confirming that everything works, or you may continue reading.

When SDL 2.0 is officially released I'll update to simply link to the locations where you can download the pre-compiled libraries, which is far easier.



C++11 Note

Throughout this tutorial we will be using a few of the new features provided by the new C++11 standard and as such you may either use a compiler that supports these features, or translate the code to features that are supported by your compiler, which shouldn't be too much of a pain. Visual Studio 2012 has C++11 support, and if using GCC you may specify enabling of C++11 features by adding -std=c++0x to your compile flags.

Visual Studio

The source folders should contain a folder titled VisualC, if you are prompted to update the project upon opening, do so. Before building the solution make sure you have selected to build the Release version. From here the solution should build smoothly. The main directory also contains an instruction file called VisualC.html that contains some helpful information if you have trouble compiling.

When building the extension libraries be sure to build the Release versions. Note that before you're able to compile you will need to specify include and library directories for your SDL2.0 files.

SDL_mixer Note: Unfortunately I was unable to build SDL_mixer under Visual Studio, although it did work under Linux, so I think there's some issue related to the Visual Studio project.

Once you've built all the libraries put the header files, lib files and dlls somewhere you won't forget, as we'll need to use these files in our projects. My location of preference is C:\

The guide for creating your first SDL project with Visual Studio is found here.

Linux

Linux users simply follow the standard configure, make, make install pattern. Make sure to record the path that the header files and libraries where installed too, as you may need to specify the path when compiling. Alternatively you can move the libraries and headers to the standard location. You must also place or link the runtime libraries to /lib/ or a similar alternative location where your runtime libraries are stored.

The Linux command line tutorial continues here.

Mac

The source folders also come with a project for XCode however I don't have a mac and unfortunately am unable to provide further guidance. Check the included documentation for instructions on building the libraries and how to include the headers and libraries in a project.

Setting up SDL on the Linux Command Line

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.


Let's make sure everything is installed properly. Open up a new C++ file and enter: Note that on linux you may need to instead include SDL/SDL.h or SDL2/SDL.h depending on your configuration, although in my tutorials the code will say SDL.h

And compile the file using
g++ -Wall YOURFILENAME.cpp -o SDL_Test -lSDL2

Note: If g++ fails to find your libraries or header files, you probably need to specify the paths to them, using some extra flags
-L /path/to/libs/ -I /path/to/includes/

If you get any errors, make sure you've followed each step.

End of Lesson 0

If you're having trouble setting up SDL please leave a comment below.

I'll see you again soon in Lesson 1: Hello World

Monday, July 9, 2012

Setting up SDL in Visual Studio

Deprecation Notice:

I've been updating the lessons now that SDL2 is officially released, please visit my new site on Github that has updated lessons and improved code.


Now that we've got the libraries setup we'll want to link up the them up with our project, so that we can begin using the library, start up Visual Studio and create a new empty C++ project.


To make our project recognize the headers and libraries for SDL we'll have to edit some simple configuration options about our include directories and linker settings.

Right click project name and bring up the properties menu. Under the C/C++ listing select General and click the Additional Include Directories item at the top.


Click the down arrow button at the end of the text entry box, and select Edit.
 

Click on the New Folder icon to add an entry to the list and click the Browse Button (the three dots) at the right side of the text box. Navigate to where you put your SDL folder, and within it select the folder titled 'include'. Hit Select Folder, Ok and Apply to save your selection.

Next we'll want to change the Runtime Library, in the C/C++ menu select Code Generation and find the Runtime Library entry. Select it and change it to Multi-Threaded DLL.


To link up the libraries select the Linker listing beneath C/C++, select the General tab and click on the Additional Library Directories entry, located just about in the middle of the window.


As before, click the down arrow button at the right side of the text box, and select Edit



Again select the New Folder button and click on the Browse button (three dots) at the end of the entry box. Navigate to your SDL folder and descend into the folder titled 'lib'. Here you will see two more directories, x86 for 32bit and x64 for 64bit. While you may choose either, keep in mind that by default VC++ is configured to compile to 32bit and you will have to change some other settings accordingly. Select the folder you want to use, I'll be using x86 for this tutorial, hit Select, Ok, and Apply to save your changes.


Next we must specify which libraries we want to link against, so under the Linker menu, select the Input menu and click on the Additional Dependencies text box, selecting as before the down arrow and Edit to bring up the menu.


To let VC++ know which libraries we want to it to use, you will want to enter:
SDL.lib; SDLmain.lib;


Hit Ok and Apply to save the configuration. 

The final step is to change our SubSystem target to Windows. To do this, select the System menu under Linker and change the entry in the SubSystem to Windows.


Hit Apply to save the configuration and Ok to close the properties window.

Now let's test if we've configured everything correctly. Add a new C++ source file to the project and enter

This simple code will initialize SDL and then quit, nothing visible will occur. Try compiling the project, if you get any errors, make sure you didn't skip a step and selected the correct folders. Before you can run this code you will need to put the Dynamic-Linked Library SDL.dll, found in the bin folder of your SDL directory, into the same folder as the executable. If you don't the program will fail to run and will pop up an error that it couldn't find SDL.


As a last extra to save the trouble of having to do this for every SDL project you create, you can export this project as a template. Select the File menu and click Export Template and export it as a Project Template. You can name and set description as you like. Now when creating a new SDL project you can simply select your template, and as long as you haven't moved your SDL folder around everything will already be configured!



End of Lesson 0

If you're having trouble setting up SDL please leave a comment below.

I'll see you again soon in Lesson 1: Hello World

Sunday, July 8, 2012

Coming Soon

Mostly a post to myself, as no one knows this blog exists at the moment, but coming soon will be a general tutorial on SDL 2.0 and game development topics, including how to create a simple tile-based game engine.

And of course the obligatory:
std::cout << "Hello World!";
See you soon