Status & Roadmap
Authors & License
Funding U++
Search on this site

SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord Logo

Including binary data using .brc files

In Ultimate++, using TheIDE, it is very easy to embed binary data in your applications using brc (binary resource) source files. Just insert a file with the extension ".brc" into a package and type into it:


BINARY(std_tmpl_vfk, "vfk.wtl")


The first argument (std_tmpl_vfk in the above example) is the public identifier of type byte * which points at the beginning of the binary data block. Also, another public variable is automatically generated, int std_tmpl_vfk_length, which contains the block length. \0 is automatically appended after the end of the block. Each block is aligned to a multiple of 4 bytes (in the current version, it is not possible to adjust the alignment individually). The second parameter is the filename (relative to the location of the brc file) of the file to embed as the binary block.


After doing this, just type somewhere in your source code:


#include "myfile.brc"


Now you can use the std_tmpl_vfk and std_tmpl_vfk_length variables to access the binary data - TheIDE builder performs the necessary steps to get them into your executable.


You can use a very similar mechanism to generate binary data arrays. This is supposed to be handy e.g. for animations in games or generally for processing a large number of binary blocks in a database-like manner. The variant of the above macro is as thus:


BINARY_ARRAY(std_tmpl_vfk, 1, "vfk.wtl")


Here the new middle argument (1) is the index at which to put the binary file in the array. The size of the array is automatically set to maximum of these values + 1. The array is accessed via the variable


byte *std_tmpl_vfk[];


The array can be managed with the help of another pair of variables:


int *std_tmpl_vfk_length[];

int std_tmpl_vfk_count;


The first variable, <ident>_length, is an array of block lengths. If you omit certain index numbers in the brc file, the appropriate pointers in the std_tmpl_vfk array are set to NULL and the appropriate length elements in the std_tmpl_vfk_length array are set to -1. The other variable, std_tmpl_vfk_count, gives number of elements in the std_tmpl_vfk and std_tmpl_vfk_length arrays.


Another variant lets you put multiple files matching a certain file mask to the binary resource:


    BINARY_MASK(std_templates, "*.wtl")


The binary resource generator locates all files matching the given mask (relative to the brc file directory) and puts them to the resource file in a very similar manner like with BINARY_ARRAY's. Again, the following variables are created:


byte *std_templates[];

int *std_templates_length[];

int std_templates_count;


However, in this case, another variable gets exported from the binary object:


char *std_templates_files[];


This is an array (with std_templates_count element) of pointers to zero-terminated strings holding the individual file names (without path). Also, before putting the files to the archive, they get sorted by their file names.


In all BINARY objects, you can use BZ2 or ZIP after the filename string to specify that the file(s) should be zipped or bzip2-ed before putting them to the archive. In this case, the <ident>_length variables apply to the length of the compressed file, not the original file. Like this:


BINARY(std_tmpl_vfk, "vfk.wtl" BZ2)


Currently, in the WIN32 version, an internal mechanism is used to generate the appropriate OBJ file during the binary data import. Under LINUX, a c source file with the binary data is generated internally which is then normally passed to the gcc compiler. In both cases, the import is rather fast at least for, say, a few megabytes of imported data.


Do you want to contribute?