Tag: c++

Flibbertigibbet

What happens when I’m away for a fortnight with my low-spec laptop and haven’t made a game for 1GAM? Turns out it’s this:

Flibbertigibbet

Flibbertigibbet (I couldn’t think of an actually good name, so used favourite word instead.) is a Minecraft-inspired roguelike. You mine, you build, and you craft — all from the comfort of your 80×25 character, 8-colour terminal window. It’s nowhere near as complete as I’d hoped, but I’ll definitely be tinkering with it in the future. It’s just so fun to work on!

Part of what’s made it so fun is that it’s been almost entirely my own code. All I’m using library-wise is PDCurses for terminal stuff, and some simplex noise code I found online because I was in a hurry. Otherwise, I’ve been free to write it in whatever weird way I want! 😀 Whether this results in code that is actually good remains to be seen, but it’s lovely not having to conform to someone else’s idea of what makes sense.

It’s pretty limited right now though. First on the list for improvements would be to replace the terminal with a graphical window that I can fully control. Mostly I’d like more colours, and to show more on screen at once – 80×25 is pretty cramped. I never got around to making the world keep generating as you move around either, and the world it does generate isn’t that interesting. There’s not even any combat or death yet, so it’s hardly even a roguelike! I’ve got a big list with a bunch of other things, so this is only the beginning for my terribly-named ASCII adventure.

SDL: Blitting to transparent surfaces

I mostly like SDL, but some of its ways are a little bizarre, requiring knowledge of how things work underneath, but without making that knowledge easily available.

Having just spent several hours trying to get blitting with transparent surfaces to work, I thought I would share so that hopefully others won’t go through the same frustrating period of confusion. Also, it’ll be here if I forget how to do this in the future.

To create a surface supporting transparency, you need to specify the bit masks for each pixel, which is a long way of saying ‘do this:’

SDL_Surface* surface;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
surface = SDL_CreateRGBSurface(SDL_HWSURFACE,width,height,32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
#else
surface = SDL_CreateRGBSurface(SDL_HWSURFACE,width,height,32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
#endif

Here, we set the flags differently based on the endian-ness of the computer. Otherwise, things could go horribly wrong, with colours being inverted and other stuff you really don’t want.

The surface will be filled-in with black pixels, but we want it to be transparent, so we fill it with transparent pixels using SDL_FillRect:

SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));

Now, this is all pretty simple so far, and yet I had so much trouble getting some surfaces of text on a transparent background to blit to this surface. The trick is that you have to make sure that the SDL_SRCALPHA flag is not set on the source surface. Otherwise, the surfaces are blended together, and as the target surface is completely transparent, nothing will apparently be blitted.

You can remove the flag like this:

SDL_SetAlpha( sourceSurface, 0, SDL_ALPHA_OPAQUE );