Giter VIP home page Giter VIP logo

c-rez's Introduction

C-Rez

c-rez is a small tool to generate C arrays of data from a list of input files. You can then compile them in your project and reference them just as regular variables.

It features:

  • An easy to use command-line tool
  • A neat CMake interface for CMake users
  • Allows you to reference assets both as strings (c_rez_resource("sprites.png")) and as a variables (sprites_png)
  • Written in portable C89 code
  • Generates portable C89 code
  • Its MIT licensed

You might be wondering why would anyone ever need this tool since there are many ways of opening and reading a file, below are some of my reasons:

  • Cross-platform resource loading is a pain in the arse (specially when targeting mobile devices (I'm looking at you, Android Assets))
  • Cross-platform resource bundling is even worse
  • No loading time, your assets are available as soon as main starts (even before!)
  • No loose files, you can distribute a single executable file
  • Asset bundling is now part of the compile and link process.

Of course, there are downsides:

  • Makes your executable very very big depending on the size of your assets
  • Which in turn makes it slow to load
  • Depending on the final size of your app, the device might decide not to load it
  • You have no way of freeing up the loaded memory once you're done using the asset
  • No way of deciding what not to load at runtime. It is always all or nothing (you can go around this by making your assets a shared library and then loading them with dlopen, but if you're doing this you might as well use plain old fopen)

Output

A struct type is declared and used to represent each processed file. This is how the struct looks:

typedef struct c_rez_resource {
  unsigned char const * const data;
  unsigned int const length;
} c_rez_resource;

The path of input files given to the c-rez tool will be used to generate an identifier. This identifier will be the variable name declared in the .h file and defined it in the .cfile. c-rez also accepts a key that will be part of the generated identifiers.

For instance, if you pass a resource file img/sprites.png and key resources, the .h file will have a variable called resources_img_sprites_png that will have a data member pointing to its bytes and a length member with the byte count.

You can also use the function c_rez_locate_resources("img/sprites.png"), it will return &resources_img_sprites_png

Suppose you generate an img.h header file, it would look like this:

#ifndef c_rez_resources_img_h
#define c_rez_resources_img_h

#ifdef __cplusplus
extern "C" {
#endif

#ifndef c_rez_resource_struct
#define c_rez_resource_struct
typedef struct c_rez_resource {
  unsigned char const * const data;
  unsigned int const length;
} c_rez_resource;
#endif /* c_rez_resource_struct */

extern c_rez_resource const resources_img_sprites_png;
struct c_rez_resource const * c_rez_locate_resources(const char name[]);

#ifdef __cplusplus
}
#endif

#endif /* c_rez_resources_img_h */

Aftwewards you can #include it in your project and use the generated structs to get to your data:

#include "resources/img.h"

int main() {
    printf("sprites.png length: %u\n", resources_img_sprites_png.length);
    printf("address of sprites.png: %p\n", c_rez_locate_resources("img/sprites.png");
    return 0;
}

You can then either commit these files to your project or make it part of your build process.

Refer to either CMake usage or Command-line tool on how to generate and use these files in your project.

CMake usage

As a subproject

c-rez is ready to be used as a sub-project. Simply download the source archive and use add_subdirectory before adding targets using c-rez

add_subdirectory(path/to/c-rez)

As a CMake package

You can either compile from source or install a release archive.

Compile from source

  1. Have a compiler environment ready (GCC, LLVM, MSVC, MinGW, etc);
  2. Have CMake 3.0 (minimum) installed;
  3. Download this repository;
  4. Create a build folder inside it;
  5. Run cmake (or cmake-gui), set the binary dir to the newly created build folder and the source dir to the repository folder;
  6. build it with cmake --build . --target c-rez
    • Alternatively, you can open the generated project files and build them in your IDE
  7. Install it with cmake --build . --target install (you might need to use sudo here or to adjust CMAKE_INSTALL_PREFIX)
    • If using it inside an IDE, run the INSTALL target

Install a release

  1. Download a suitable archive from the releases section
  2. Unzip it somewhere you can later find with CMake (you may need to adjust the CMAKE_PREFIX_PATH of your project)

Add package

Use find_package to add it to your project:

list(APPEND CMAKE_PREFIX_PATH /path/to/c-rez/prefix)
find_package(c-rez REQUIRED)

Create a resource target

After using either find_package or add_subdirectory, a new CMake function will be available: add_c_rez. This function will create a new C STATIC library under the c-rez namespace that you can link your targets to:

add_executable(mygame mygame.c engine.c)
add_c_rez(images
    assets/tileset.png
    assets/sprites.png
    assets/gui.png
)
target_link_libraries(mygame c-rez::images)

If you place the word TEXT before a path, it will be treated as text and a \0 terminating byte will be appended to its data:

add_c_rez(texts
    TEXT texts/chapter01.txt
    TEXT texts/chapter02.txt
    TEXT texts/chapter03.txt
)

The header files for your target will be under a c-rez folder in your build path (different targets might not be in the same path, though)

#include "c-rez/images.h"
#include "c-rez/texts.h"

Command-line tool

If added to your PATH, you can call c-rez as a command line tool to generate a header and/or source files:

c-rez -k <resource key> [-h <output.h>] [-c <output.c>] [--text] <input_1> [[--text] <input_2>] [[--text] <input_n>]*
  • -h <file.h>: specifies the header output file. If omitted, only source gets generated.
  • -c <file.c>: specifies the source output file. If omitted, only header gets generated.
  • -k <resource key>: specifies a key to identify this resource. It will be used in header guards and resource functions.
  • --text: appends \0 when processing the next <input> file. This helps when using its data as a string resource.
  • <input>: space separated list of files to read from. Declarations and definitions will be generated based on the file name. If --text is specified before the file name, \0 will be appended after processing.

License

c-rez is MIT-licensed.

c-rez's People

Contributors

mobius3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.