z0b's realm

Random snippets

On this page you can find several useful code snippets I've written over the years. Some of them are stand-alone, but most are not. Some are self-contained functions that are useful only as a part of a larger program. They may or may not be useful to you, but they were useful to me.

Unless otherwise noted, every single snippet here is hereby placed into public domain. You can steal/edit/rip/mutilate them at your will. I generally try to keep the code as platform-independent as possible. I mainly use the GCC compiler under Linux and Windows, but I have not used any compiler-specific constructs in the code, at least not intentionally. I will often use Clang to test

Here's a raw directory listing of all snippet files.

Major categories:

Caveat emptor! These snippets can be revised, deleted, renamed, etc. without any prior notice, at any time. No changelogs are kept. There is no warranty. Use everything strictly at your own risk. If this code destroys your files/computer/sanity/etc., that's too bad. You have been warned. Everything has been tested and they all worked. Feedback and improvement ideas are welcome, flames can be sent to /dev/null.

File formats

Loading and saving PNG images

Using libpng to load and save PNG files can be a daunting task, especially for the first-timer. The manual is useless unless you know exactly what to look for, and the examples are somewhat complex. It can take a while to piece together even the most basic save/load code.

These snippets here are examples on how to save and load to and from files and memory buffers. Everything has been tested with libpng 1.6.6, but they should work with other versions too (because the core API is more or less frozen). The "simplified" API introduced in libpng 1.6.0 is not used.

FileDescription
png_read_stdio.cppLoad a PNG using stdio
png_write_stdio.cppSave a PNG using stdio
png_read_memory.cppLoad a PNG from a memory buffer
png_write_memory.cppSave a PNG into a memory buffer

I'm avoiding the use of more advanced C++ features, because I want the code to be still easily portable to plain C. The new/delete can be converted to malloc/free easily and references turn into pointers easily. The hardest part will be replacing std::vector with a realloc()'ed dynamic array, but that's nothing a battle-hardened C veteran can't handle. Similarly, going "fully" C++ isn't difficult.

These are just basic examples! You want to replace the error message handling with your own routines, for example. If you need a minimalistic PNG load/save code with no external dependencies, try LodePNG/picoPNG.

Simple TGA writer

TGA is a great image format if you just need to quick and dirty image saving. The file just has an 18-byte header, followed by BGR(A) pixel data. This code supports 24- and 32-bit images. RLE compression is not implemented.

tga_write.cpp

WAV header writer

If you need to save sound data in a WAV file, you need to calculate the bit rate parameters for the header and that is not a trivial task. Here's a small function that takes the sound parameters (channel count, bit rate, etc.) and writes a fully-working header for you. You need to output the sound data yourself.

wavheader.cpp

Graphics (2D/3D)

Notes

The math::vec3 is a simple 3D vector class with public X, Y and Z components. It has overloaded +, - and = operators. [] is used to access components by index (0-2). distance(point) returns the distance (not squared!) between two points. The overloaded * and / with floats simply scale the components. dot(v) and cross(v) are dot and cross products.

The math::plane is a 3D hyperplane with X, Y, Z and D components. distance(p) takes a math::vec3 and returns the distance from the plane to that point.

Distance between arbitrary 3D point and an AABB

This calculates the distance between any 3D AABB and another point. The nearest point on AABB can be anywhere (corner, edge, etc.). The algorithm is simple: clamp the reference point inside the AABB, component-wise. Now you have the nearest point. Can be modified to work in 2D.

aabbpointdist.cpp

Nearest point on a line segment

This is often-asked question in math forums: you have a 2D/3D line segment with two end points and a third point. What is the nearest distance from that line segment to a third point? This code shows how to do that. The same code works in 2D and 3D.

linepointdist.cpp

Angle between two lines that share one common endpoint

If you have two 2D lines and they share one end point, what is the angle between them? Remember, the lines can be oriented arbitrarily on the 2D plane. The algorithm in this snippet may not be the best, fastest or simplest, but it works.

lineangle.cpp

It works by computing angle between the two lines in relation to an imaginary horizontal line and then it twiddles those values.

Clipping a 3D polygon against a set of planes

This function clips a convex polygon against N clipping planes, keeping the part that is inside. I've used it to clip portals in real-time 3D engines, checked polygon-frustum intersections and many other things. The plane normals point inside the space, so the front fragments remain and back fragments are discarded. The output polygon is always convex.

The output vector pointer can be NULL if you don't need the polygon. In that case, the function simply returns true if something of original polygon is still left after all clipping; false if not. If the code clips away the wrong side (i.e. backsides) then your plane normals point in the wrong way. Flip them or change the comparisons in the loop.

polyplaneclip.cpp

Generic 2D/3D polygon splitter

This is a barebones variation of the above. It takes a 2D/3D polygon and splits it into two halves, either by line (2D) or hyperplane (3D). No other bells and whistles are included. Needs a C++11 compiler

generic_polygon_splitter.cpp

Miscellaneous

RGB <-> HSL color conversion

Two small and standalone functions for converting RGB colors to HSL and back. A small main() is included to test the functions, but you don't need that.

hsl.cpp

Windows: Loading JPEG and GIF images from raw resources

If you want to use JPEG or GIF images in your application, but do not want to load them from the disk, you can store them in the resources. Just use a custom raw resource type and pass the ID to this function. It returns a HBITMAP for you. The loader uses the OLE stream and bitmap loaders.

winloadresimage.cpp

Linux: Code page 437 in UTF-8

Remember old the DOS CP437? Now you can use it again! This table has UTF-8 equivalences for all CP437 symbols. The table is complete, you can even use those good old box drawing characters again. You can even dump binary files in the console if you translate the characters through this. Usage instructions are included in the file.

Tested only under Linux! Requires Unicode font to work. You will get strange results if your font does not contain all the symbols.

cprintf(): color printf()

This is a custom printf -style function that supports embedded color change codes. Each color code has the format #<code>, where code is a hexadecimal color change code between 0 (0) and 15 (F). These color codes match directly the old DOS color codes. In addition to these, there are two special codes, #R to reset the color back to default and ## to print the hash symbol. Feel free to adjust the colors if you want.

For example, the following

cprintf("#CHe#Ell#Ao w#9or#Dld#F!#R\n");

will print a rainbow-colored "Hello world!" message:

Hello world!

However:

  • Background color cannot be changed. This isn't impossible, just needs messier parsing.
  • Windows version has no Unicode support (does not use wchar_t)
  • No underline, bold, reverse video or 256-color support under Linux
  • I've no idea how to get the "default" attributes under Linux, so the color reset (code #R) will simply use hardcoded values.
  • Depending on how your console has been configured, the colors may be different and even in different styles

Tested under Windows XP, Windows 7, Arch Linux, XUbuntu, Debian 6 (Squeeze), Debian 7 (Wheezy) and Debian 8 (Jessie).