DinoMage on Twitter RSS Feed

Archive for the ‘Libraries’ Category

2
Apr

C string explode

   Posted by: in Dev, Libraries

I was working on porting some code from C++ to C and I couldn’t really find a simple explode() function for C online.  So, of course, I had to make it myself.  I’m just putting it here for general reference.  This implementation uses malloc(), so it’s going to be a little less performant than a static one, though easier to use.  At least it can’t be any worse than my C++ implementation!

No guarantees, you’re granted the code under the MIT license.

typedef struct StringList
{
    char* value;
    struct StringList* next;
} StringList;
void StringListFree(StringList* node)
{
    // Delete the nodes in order
    while(node != NULL)
    {
        StringList* last = node;
        node = node->next;
        free(last->value);
        free(last);
    }
}
// Returns a linked list of malloc'ed NULL-terminated strings.  The delimiter is erased.
static StringList* explode(const char* text, char delimiter)
{
    StringList* head;
    StringList* new_node;
    StringList** node;
    const char* start;
    const char* end;
    unsigned int size;
    if(text == NULL)
        return NULL;
    head = NULL;
    node = &head;
    // Doesn't technically support UTF-8, but it's probably fine, right?
    size = 0;
    start = end = text;
    while(1)
    {
        if(*end == delimiter || *end == '\0')
        {
            *node = (StringList*)malloc(sizeof(StringList));
            new_node = *node;
            new_node->value = (char*)malloc(size + 1);
            memcpy(new_node->value, start, size);
            new_node->value[size] = '\0';
            new_node->next = NULL;
            if(*end == '\0')
                break;
            node = &((*node)->next);
            start = end+1;
            size = 0;
        }
        else
            ++size;
        ++end;
    }
    return head;
}

Hey there!  This is a tutorial on some of the basics of using SDL_gpu.  If you are comfortable with C or C++ and SDL, then you’re ready for this.  I’ll post installation instructions for SDL_gpu some other time, though if you use SDL then you probably already have that down.

To start things off, here’s a listing of the functions we’ll be using:

GPU_SetDebugLevel
GPU_Init
GPU_LoadImage
GPU_Clear
GPU_Blit
GPU_Flip
GPU_Quit

These will be everything we need to put together a simple simulation to play with.

If you’ve used SDL’s built-in rendering before, then SDL_gpu shouldn’t feel too different.  They do the same basic things, but SDL_gpu has a lot more functionality and a few different conventions.  The most blatant convention difference you’ll see is that GPU_Blit() and the other blitting functions draw sprites at their center instead of from the upper-left corner.  This doesn’t actually change much in your code, but makes scaling and rotating sprites work without hassle.

Initialization

void GPU_SetDebugLevel(GPU_DebugLevelEnum level);
GPU_Target* GPU_Init(Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags);

There are a couple of ways that SDL_gpu lets you know when something goes wrong.  Some functions can have an obvious return value when there’s an error.  E.g. GPU_Init() will return a NULL render target on error.  SDL_gpu also maintains an error stack that you can check manually (sometimes a silent program is bliss). But we’re just starting off! We need to know right when errors occur. With GPU_SetDebugLevel(), we can tell SDL_gpu to print out the errors just as they happen.  That will help us catch some mistakes that we might make along the way.

GPU_Init() is the easy way to get a window and render target created.  All you have to do is pass in the width and height of the window you want.  You can also pass in some SDL window flags if you want to.  This will set everything up and choose the best renderer that is available.

So here’s a snippet of those two functions. Once you have #include “SDL_gpu.h” and set up your main() function:

// Tell us whenever something bad happens
GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);
// Get a 800x600 window to render to
GPU_Target* screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS);

Rendering an image

Now we would like to draw something on the screen. To render to our new window, we need either an image or we can draw shapes.  Here’s what we need for drawing images:

GPU_Image* GPU_LoadImage(const char* filename);
void GPU_Clear(GPU_Target* target);
void GPU_Blit(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y);
void GPU_Flip(GPU_Target* target);

GPU_LoadImage() of course loads images. It currently supports .png, .jpg, .tga, .gif, and .bmp image files. Before each frame is drawn, we might want to use GPU_Clear() to erase the contents of the screen target. In some cases you don’t need to, especially when you are drawing over the entire screen every frame (e.g. with a background image).  When we pass our new image and the screen target to GPU_Blit(), we get the image rendered right where we want it.  To actually see what we rendered, we need to GPU_Flip() the screen buffer so it is shown in the window.

// Load the image...
// (Make sure that you have some image named test_image.png in the executable's directory)
GPU_Image* image = GPU_LoadImage("test_image.png");
// Clear the screen
GPU_Clear(screen);
// Remember that GPU_Blit() draws the image *centered* at the given position
GPU_Blit(image, NULL, screen, image->w/2, image->h/2);
// Show the result in the window
GPU_Flip(screen);

With that, we can technically see something drawn…

Shutting down

void GPU_Quit(void);

Let’s not forget to shut down SDL_gpu at the end. GPU_Quit() will free up the resources that SDL_gpu was using.

Source

Here’s what your complete program might look like now with some usual SDL stuff thrown in:

#include "SDL_gpu.h"
int main(int argc, char** argv)
{
    // Tell us whenever something bad happens
    GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);
    // Get a 800x600 window to render to
    GPU_Target* screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS);
    // Did initialization fail?
    if(screen == NULL)
        return 1;
    // Load the image...
    // (Make sure that you have some image named test_image.png in the executable's directory)
    GPU_Image* image = GPU_LoadImage("test_image.png");
    if(image == NULL)
        return 2;
    SDL_Event event;
    Uint8 done = 0;
    while(!done)
    {
        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT)
                done = 1;
        }
        // Clear the screen
        GPU_Clear(screen);
        // Remember that GPU_Blit() draws the image *centered* at the given position
        GPU_Blit(image, NULL, screen, image->w/2, image->h/2);
        // Show the result in the window
        GPU_Flip(screen);
    }
    GPU_Quit();
    return 0;
}

Tags: ,

SDL_gpu has its first binary release!   If you make games or applications in C or C++, you should give it a spin.

In case you aren’t familiar with it yet, SDL_gpu is an alternative rendering system for SDL 1.2 and SDL 2.0.   It includes everything you need to make amazing, high-performance 2D graphics:

  • Fast buffered blits
  • Shader support
  • Sprite rotation and scaling
  • Plenty of 2D primitives (e.g. lines, arcs, circles, rounded rectangles, annulus sectors)
  • Render-to-Texture
  • An enjoyable basic abstraction (targets and images)
  • Virtual resolution and viewports
  • 2D camera control
  • Built-in support for some popular image formats
  • Blend, filter, and wrap modes
  • Arbitrary 2D geometry (batched textured triangles)
  • Can be used with native OpenGL calls

You can get started at the Google Code page.  There’s some introductory info, documentation, and downloads there.

Tags: , ,

TinyXML is a great little library (tiny, even) for loading and parsing XML documents.  Here I’m going to introduce the basics of getting all your data out of (and into) XML files.  Part 1 is quick and simple.  In Part 2, I’ll use a more complete solution.

Read the rest of this entry »

I recently bought a wired XBox 360 controller to use with my Steam games on my PC.  It works very nicely, so of course, I had to use it in my own code eventually.

Here’s the first place I’m using it.  I made a little library called XController that wraps XInput in a class.  It makes the interface to the controller a lot friendlier in C++ and does not require you to include the dreaded windows.h (or XInput.h for that matter).

Next, I might try to update StickyInput to use a similar interface.  Then I could have support for these controllers in all of my games.

You can find XController on Google Code!

28
Nov

A first look at NFont 3

   Posted by: in Dev, Libraries

It’s been a while since NFont was updated.  While working on GigaSun Jet, I had added a couple of very useful features.  It seems like it’s time to show NFont some official love. 🙂

I started working on the new version yesterday, but I’m nearly done already.  All the hard work was done before.  I will be pushing the version number up to 3.0.0 due to some serious changes to the API.  Most importantly, NFont now controls the surfaces that you give to it.  It will take care of freeing the memory.

Other nice things should be apparent from this screenshot:

Built-in animations and much more 😉

8
Feb

NFont v2.0.0

   Posted by: in Dev, Libraries

NFont has been upgraded!  Check out the NFont page for details.

goodio has been updated to v1.1!  I added a FileReader class that makes all your problems with ifstream go away (output will come eventually), as well as ioExplode() for help with parsing certain things, and little improvements like changing things such as ioStripDir to ioStripToDir (to make what it does clearer).  I also found a way to get the program’s executable path in Linux, so I’ve replaced the ugly argv stuff with that and the equivalent code for Windows.  So now you can use ioGetProgramPath() with ioSetCWD() to make sure that your relative file names work even if your program is called from a weird place (like /usr/bin).  Comments?  Suggestions?  Let me know!

With Knight of the Cave Dragon, I finally added sound to a Ludum Dare game.  I was really surprised by how easy it was, so I’ve polished the library that I used.  Here’s the first official release of MixBox, a C++ library that wraps and extends SDL_mixer.  You can download it from the SDL page and read the quick usage guide to get more details and to get started.

When I was writing Frank the Dinosaur, I ran into a question:  How should I handle game events?  Of course, since I was on a bit of a time crunch, I just did it the naive way.  I checked each condition once every frame.  I knew this was a bad way, since some events were time-based and hence would not be triggered out of order.  Yesterday, I wrote up the first bit of a library that will deal with this problem.  JEL Event Library holds both time-based and action-based events.  The action events are stored for quick access in a vector.  The time events are stored in a sorted tree.  In this way, many time conditions can be skipped altogether, meaning fewer checks and a more efficient system.  Borrowing from the GRO_gui codebase, JEL events trigger Signals, which are typesafe wrappers for function pointers (i.e. events call the functions you give them).  With Ludum Dare 15 starting this coming weekend, I’ve uploaded the initial implementation here.  There are pieces missing, but the basic functionality is there.  Future plans include a conditional system that automatically checks variables that you provide and triggers events as their conditions are met.