1
// Copyright (C) 2011 Gaz Davidson
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
6
This tool creates a .h file from a given input file by encoding it into a C string,
7
allowing you to build your resources directly into your binaries, just like Irrlicht's
10
To distribute your app as a single executable file of minimal size:
12
1. Put all your resources into a single directory and add it to Irrlicht's filesystem
13
as a folder through IFileSystem::addArchive. Develop and test your app as usual.
14
2. Open IrrCompileConfig.h and comment out all the options that your app does not use.
15
This will reduce the size of the Irrlicht library considerably.
16
* You should remove the D3D video drivers, because they rely on external DLLs.
17
* You should keep either the TAR or ZIP archive loader, used in step 6.
18
* If you remove the JPEG loader, you don't have to say you use JPEG code in your
20
3. Recompile Irrlicht as a static library, editing the IRR_STATIC_LIB line in
22
The next time you compile your application it will take a while longer, but
23
Irrlicht will be built into your binary.
24
4. TAR or ZIP your resource directory using your favourite archiving tool (ie 7zip).
25
* If you chose ZIP but compiled without zlib, don't compress this archive or it
27
5. Run this tool to convert your resource file into a .h file, like so:
28
FileToHeader res.zip > EmbeddedResources.h
29
6. Add the .h file to your project, create the embedded read file then mount as a
30
ZIP or TAR archive instead of the folder, like so:
31
io::IReadFile *f = io::createEmbeddedFile(device->getFileSystem(), "res.zip");
32
device->getFileSystem()->addFileArchive(f);
34
7. Recompile your app.
35
* If you use Microsoft's compiler, make sure your CRT (common run-time) is
36
the static library version, otherwise you'll have a dependency on the CRT DLLs.
37
Your binary should now be completely portable; you can distribute just the exe file.
38
8. Optional: Use UPX (upx.sf.net) to compress your binary.
47
int main(int argc, char* argv[])
52
cerr << "You must to specify at least one input file" << endl;
53
cerr << "usage: " << argv[0] << "<file1> [file2...]" << endl;
54
cerr << "outputs a header file to stdout, so for example use";
61
cout << "// File made by FileToHeader, part of the Irrlicht Engine" << endl
63
<< "#ifndef _EMBEDDED_FILES_H_INCLUDED_" << endl
64
<< "#define _EMBEDDED_FILES_H_INCLUDED_" << endl
66
<< "#include \"irrTypes.h\"" << endl
67
<< "#include \"IReadFile.h\"" << endl
68
<< "#include \"IFileSystem.h\"" << endl
70
<< "namespace irr" << endl
72
<< "namespace io" << endl
75
<< " const c8* EmbeddedFileData[] = " << endl
78
// store sizes and file names
81
sizes << "const u32 EmbeddedFileSizes[] = {";
82
names << "const c8* EmbeddedFileNames[] = {";
85
// char to hex digit table, probably doesn't help for speed due to fstream. better than using sprintf though
86
char hextable[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
90
// open and seek to end of file
92
input.open(argv[i], ios::in | ios::binary | ios::ate);
96
int size = input.tellg();
97
input.seekg(0, ios::beg);
98
// read the file into RAM
99
char *entireFile = new char[size];
100
input.read(entireFile, size);
109
// save file size and name
111
names << '"' << argv[i] << '"';
113
// write the file data
115
for (int count=0; count < size; ++count)
117
if (count && (count % 16) == 0)
118
cout << "\"" << endl << " \"";
120
cout << "\\x" << hextable[(entireFile[count] >> 4) & 0xF] << hextable[entireFile[count] & 0x0F];
124
delete [] entireFile;
132
cerr << "Failed to open file: " << argv[i] << endl;
138
// close binary file list and write file metadata
142
<< " const u32 EmbeddedFileCount = " << fileCount << ";" << endl
143
<< " " << sizes.str() << "};" << endl
144
<< " " << names.str() << "};" << endl
147
// write functions to create embedded IReadFiles
148
cout << " IReadFile* createEmbeddedFile(IFileSystem *fs, u32 index)" << endl
150
<< " if (EmbeddedFileCount < index)" << endl
151
<< " return 0;" << endl
153
<< " return fs->createMemoryReadFile((void*)EmbeddedFileData[index], " << endl
154
<< " EmbeddedFileSizes[index], EmbeddedFileNames[index]);" << endl
157
<< " IReadFile* createEmbeddedFile(IFileSystem *fs, path filename)" << endl
159
<< " for (u32 i=0; i < EmbeddedFileCount; ++i)" << endl
160
<< " if (filename == EmbeddedFileNames[i])" << endl
161
<< " return createEmbeddedFile(fs, i);" << endl
163
<< " return 0;" << endl
168
cout << "} // namespace io" << endl
169
<< "} // namespace irr" << endl
171
<< "#endif // _EMBEDDED_FILES_H_INCLUDED_" << endl;