User Tools

Site Tools


resources_in_c_c_programs

The source for this is on the public git hub. It is dependent on Qt (however, this is free for most of you).

What this program does is to take a folder and generate C 'binaries' and a structure to allow you to access those from you C (or C++) program.

Why would you want this. Simple! You have some non code data that you want to carry with your program and you want a broadly platform agnostic way of doing so. You do not want the data to b separated from your application and/or you do not want to hassle you using the file system.

Incremental updates is also a feature. That is, if only a single file has changed then only that file will be reprocessed. If there are only additions then only those new files and the header are updated.

Operation

Simply direct the tool to a folder and it will generate a “resources.h” file (which can be renamed) that contains a resource structures. Here's an example from one of my own projects.

//;(c)kuiash.com 2015+;
 
#ifndef _resources_h_
#define _resources_h_
 
#include <resource.h>
 
struct resources_background_noises_t {
    resource_t fire_1_wav;
    resource_t fire_2_wav;
    resource_t fire_3_wav;
    resource_t noise_1_wav;
    resource_t noise_2_wav;
    resource_t noise_3_wav;
    resource_t noise_4_wav;
    resource_t noise_5_wav;
};
 
struct resources_noises_t {
    resource_t boom_1_wav;
    resource_t boom_2_wav;
    resource_t boom_3_wav;
    resource_t boom_4_wav;
    resource_t click_1_wav;
    resource_t click_2_wav;
    resource_t harp_1_wav;
    resource_t harp_2_wav;
    resource_t harp_3_wav;
    resource_t harp_4_wav;
    resource_t locked_wav;
    resource_t locking_wav;
};
 
struct resources_old_vitals_t {
    resource_t vital_bitmap_png;
};
 
struct resources_rt_sfx_t {
    resource_t rum_ting_bass_intro_loop_wav;
    resource_t rum_ting_harp_loop_wav;
    resource_t rum_ting_main_loop_wav;
};
 
struct resources_t {
    resources_background_noises_t background_noises;
    resources_noises_t noises;
    resources_old_vitals_t old_vitals;
    resources_rt_sfx_t rt_sfx;
    resource_t block_edge_pixels_raw_png;
    resource_t block_edge_pixels_raw_little_blur_bright_png;
    resource_t cloud_png;
    resource_t cloud_shadow_png;
    resource_t code_png;
    resource_t down_arrows_png;
    resource_t graphics_png;
    resource_t icon_png;
    resource_t line_1_png;
    resource_t line_2_png;
    resource_t line_3_png;
    resource_t lines_four_png;
    resource_t logo_png;
    resource_t moon_png;
    resource_t music_png;
    resource_t paper_png;
    resource_t stars_test_png;
    resource_t sun_png;
};
 
extern resources_t resources;
 
#endif

For every level of the folder hierarchy there will be a structure. These structures are embedded within each other such that you can, using the standard member of operator (“.”), navigate these these in the same way that you can navigate the file/folder hierarchy.

Mapping Files & File Names

The '/' (or '\') character can not be used in C identifiers.

It is used in file paths to represent containership e.g X/Y/Z means 'Z' is contained in 'Y' which is contained in 'X'. I have considered overriding the '/' operator to do this but, frankly, that seems a little crazy. After a lot of consideration I believe that this is not possible. '.' operator (member of) explicitly searches the context of the structure given on the right hand side whereas '/' expects an object in the global or local scope or a constant. Therefore every sub folder would need to be an object with a name in the global namespace. This is not possible although I wonder if template customisation can help I'm simply not going to work on that now.

!!todo; add example (ascii text)

#include <resources.h>
 
int main(int argc, char * argv[]) {
    // Print the address and size of an entry
    // 
    printf("resources.noises.harp_1_wav._size = %d\n",
        resources.noises.harp_1_wav._length);
    printf("resources.noises.harp_1_wav._data = %d\n",
        resources.noises.harp_1_wav._data);
}

So the 'hierarchy' character is '.' as you'd expect in C.

Next, almost everything else is expected to be a C identifier. Our own code is very simple in this regard in that only lower case letter (ascii 7bit) and numbers or underscore are ever present in an identifier.

Handling the dot in file names is not currently done but is equally easy and compile time constant. That is 'folder/my_image.png' is a struct resource_root_folder that contains an structure called 'my_image' that contains a structure called 'png'.

File Hierarchies and Mapping to Structure Hierarchies

The very top of the resource structures is called 'root' although you may rename this to allow multiple collections of resources in the application.

A resource itself is simply an untyped (void) pointer and a length in bytes.

Adding You Own Extensions

You may have a massive collection of complicated rules that mean the artefact on disk is not the one you want in your application. Some examples:

  • Resize image to power of 2 dimensions
  • Swap R and B for use as textures
  • Repack from PNG/JPG to some other format
  • Resample audio to 44.1 KHz 16 bit stereo from, say, 192 KHz 24 bit 5.1
  • Compress text files with LZ77, Huffman or similar
resources_in_c_c_programs.txt · Last modified: 2018/03/16 05:05 by xylene