|
|
The resource compiler is designed for the world of Baby X, the system for writing small or baby programs which have minimal dependencies and will run anywhere. Baby X is meant to meet the needs of the hobby programmer, but is free to anyone for any use. And the resource compiler, babyxrc, is an independent program that can be used by people who don't want it for Baby X. We now have an anciliary project, BabyXFS , or the Baby X filesystem project. This is designed to allow Baby X programmers to mount directories and embed them in programs. The files use the <FileSystem> XML file format. This allows directories to be packaged up and then imported via the Baby X resource compiler. There is now a suite of babyxfs_ programs to manipulate the FileSystem XML files. A particularly intetesting use case is allowing a program to print out its own source so it can be recompiled on a diferent platform. This is explained as part of the BabyXFS project, here. The Baby X resource compiler will load most images in most common formats, including .jpeg, .png, .tiff, .gif, and .bmp. SVG images are rasterized (import SVG as text data if you want to treat SVG as vector). So the loadimage function will load almost anything, and you are welcome to steal it for your own projects. (If you enhance or bug fix, please contact me). Audio is loaded as .wav, .aiff, or .mp3. AIFF files with bitrates other than 16 bits per sample are not supported, nor are compressed AIFC files, with the exception of the special case of AIFC files which reverse endianness. MP3 files will be decompressed (include as <binary> if you have facilites for playing MP3. There's a samplerate parameter so you can include audio from any source and store it at the samplerate required by your platform. The Baby X resource compiler will also take in text in most common formats, and save it as human-readable ASCII strings, UTF-8, or UTF-16. Text files commonly have non-standard extensions, so the format has to be determined by heuristic analysis. For this reason it is recommended to use UTF-8 whereever posible. It's also recommended to use UTF-8 in the output. However UTF-16 output is provided for compatibility. By default, surrogate pairs are turned off, because the usual reason for using UTF-16 is that the program doesn't want to handle non-fixed width representations. However you can turn them on with the "allowsurrogatepairs" attribute. You can incorporate UTF-8 in your source with the <string> tag, but some compilers and editors won't accept it. So the <utf8> tag dumps UTF-8 as ASCII-encoded binary. Users of the Baby X resource compiler will be C programmers, so it is the work of a moment to modify the program slightly to output data in a slightly different format, for example if you need an exact binary signature for audio samples, or if you want images as ARGB rather than RGBA. It's hard to predict these requirements by providing runtime options. So whilst it sounds a bit 1970s, modifying the program source is the best approach. For a developer-oriented documentation of the Baby X resource compiler source, see the Baby X resource compiler source overview. |
babyxrc script.xml > outputfile.c babyxrc -header script.xml > outputfile.h
There is currently only one option, which is to write a header file rather an a .c source file. The Baby X resource compiler will read in the resource list from the script, and write the .c output file to standard output. Errors are passed to stderr, so they will be lost in the output unless you redirect it.
The Baby X resource compiler is provided as source. It's all 100% portable ANSI C with no dependencies other than those provided in the distribution itself and the C standard library. So it should compile with the minimum of problems. There's a CMake script to help out, but it's not necessary to use it. You'll have to put the executable on your path using the operating system's specific facilities (usually by adding it to the ${PATH} environment variable). It should run on absolutely any machine with a C compiler and a standard output.
The Baby X resource compiler accepts a simple XML script as input. Essentially it is a list of your resource files together with a few attributes to control the format you want them output in. So everything is together.
<BabyXRC> <string name = "hello">Hello Baby X</string> <image name = "babyxpic", src = "Babyx.jpeg", width = "100", height = 100"> </image> <audio name = "babyxcry", src = "crying.mp3", samplerate = 22050> </audio> </BabyXRC>
Here's a very simple sample Baby X resource compiler script file containing on string, one image, and one audio clip. If the image is not 100x100 it will be resized, and the MP3 will be decompressed and resampled at 22050Hz.
The tag type gives the output format, not the input format of the resource. Usually the resource compiler will determine the format of the resource from its extension or, in the case of text files, by using a heuristic.
Tags take attributes. All tags can take a "name" attribute, which gives the base name of the C identifiers output. "name" is usually optional as the name can be generated from the resource file name. All tags also take a "src" attribute which gives the path to the resource file. Text tags <string> <utf8> <utf16> can omit the "src" attribute if text is included in within the tags.
Attributes name, src, const
<string name = "fred">Fred Bloggs</string> <string name = "fred" const="true">"My name is \"Fred Bloggs\"\n"</string> <string name = "fred", src = "fred.txt"></string>
In the first case we are creating a string with the value "Fred Bloggs".
In the second case the string is quoted, so it is not escaped but is
output as is. (This is useful for entering printf format strings).
And it is also const.In the third case, the string is read from an external
file. It will be escaped so tabs will be expanded to "\t" and newlines to "\n".
Attributes name, src
<utf8 name = "fred">Fred Bloggs/n></utf8> <utf8 name = "fred" src = "fredunicode"></utf8>
In the first case we are creating UTF-8 string with the value "Fred
Bloggs". You can put UTF-8 in this position to etner human-readable
extended character (this text file is ASCII so we can't show that).
In the second case we are creating a UTF-8 string from an input file.
The resource compiler will attempt to dtermine the format. However it
is recommedend to use UTF-8.
Attributes name, src, allowsurrogatepairs
<utf16 name = "fred">Fred Bloggs</utf16> <utf16 src = "fred.utf8"></utf16> <utf16 src = "fred.utf8" allowsurrogatepairs="true"></utf16>
In the first case we are creating UTF-16 with the value "Fred Bloggs".
In the second case we are creating UTF-16 from a text file. The extension
suggests that it is UTF-8 file (as recommended). The resource compiler
will re-encode it as UTF-16. name isn't given and will default to
"fred", based on the file name.
In the third case we are allowing surrogate pairs in the UTF-16 output.
By default this isn't on an code points over 0xFFFF will be mapped to
0xFFFE (unknown character). This is because a lot of code relies on one
wide character representing one code point.
Attributes src
<comment>Add this comment to my source</comment> <comment src = "licence.txt"></comment>
In the first case the comment text is embedded in the script file.
In the second case we load in the text from an external file.
Attributes name, src
<binary name = Fred, src = "fred.bin"></binary>
In the first case the file "fred.bin" is simply read in and passed out as binary bytes, with no processing.
Attributes name, src, width, height
<image name = "fred" src = "fred.jpeg"></image> <image name = "fred" src = "fred.tiff", width = "100", height = "80"></image>
In the first case the image is read from "fred.jpeg" and written out as
32 bit rgba values.
In the second case the image is read from "fred.tiff" and resized to
width 100 pixels, height 80 pixels, then written out as 32 bit rgba
values.
Supported formats are .png, .jpeg, .gif, .bmp, .tiff and .svg. The format will be determined form the file extension. Svg files will be converted to raster.
Attributes name, src, points
<font name = "fred", src = "fredsfont.ttf", points = "12"></font> <font name = "fred", src = "fredsfont.bdf"></font>
In the first case we a loading a true type font, and outputting raster
glyphs for 12 point text.
In the second case we are loading a BDF raster font which cannot be
resized.
The <font> tag is mainly intended for ripping true type fonts and rasterising them so they can be used by simple programs. If you have runtime support for true type fonts, load the font with the <binary> tag.
Attributes name, src, samplerate
<audio name = "fred", src = "fred.wav"></audio> <audio name = "fred", src = "fred.mp3", samplerate = "22050"></audio>
In the first case we are inputting "fred,wav" and writing the data out
as 16 bit pcm samples with minimal processing.
In the second case we are inputting an MP3 file, decompressing it,
resampling at 22050Hz, the outputting as PCM samples.
If you have facilities for playing MP3 streams, load the MP3 with the <binary> tag.
Attributes name, src
<cursor name = "fred", src = "fred.cur"></cursor>
In the first case we are loading a Microsoft .cur file, and outputting it as 32 bit rgba buffer plus a hotspot.
Attributes name, src
<dataframe name = "payroll", src = "employees.csv"></dataframe>
We load in a dataframe, which in C is simply an array of structs which represent data from an external source. Currently the only format supported is csv.
Attributes name
Children <string> <utf8> tags.
<international name = "hellofred"> <string language = "english">Hello Fred</string> <string language = "french">Bonjour Fred</string> <utf8 src = "chinesefred.unicode" language = "chinese"></utf8> </international>
Here we are setting up an internationalised string with the base identifer "hellofred" and English, French, and Chinese translations. The English and French are entered directly, the Chinese is read in from an external file. In this context, <string> and <utf8> tags should take a "language" attribute.
The Baby X resource compiler is provided as a service to the C programming community. You can help out by enhancing the program, bug fixing, and so on. You can also help by promoting it and recommending it to your friends. The more users we have, the more developers we will attract, and the project should go from strength to strength.
On the wishlist is an MP3 encoder to allow users to store resources in .wav file format and incorporate them in their programs as MP3. The bmp file loader won't support some of the more exotic bitmap formats (run length encoding and bit masks). We could also do with a "filesystem" tag to allow users to package a directory as a runtime-accessible filesystem, stored in the programs data section. We also need more work on internationalisation. Functions to mix audio would also be useful.
To add a new tag, add it to the list in main. It will likely have the attributes "name" and "src". If there are any other attributes with new names, add a variable declared as
const char *attributenamestr; ... attributenamestr = xml_getattribute(node, "attributename");
The write a function called processtagnametag which takes a FILE * as the first parameter, and the attributes as additional parameters. Note that these will be null if the user doesn't provide the attribute.
To add an attribute, create the variable to hold the string using the convention above. Then add the attribute to the parameter list of the tag process function.
If the tag has children or for other reasons is difficult to process using the above interface, the write a "processtagnamenode" function which takes the node as a parameter. You'll then need to use the xml functions in xmlparser.h to access the node's information.