123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- // Copyright (C) 2012 Gaz Davidson
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- /***
- This tool creates a .h file from a given input file by encoding it into a C string,
- allowing you to build your resources directly into your binaries, just like Irrlicht's
- built-in font.
- To distribute your app as a single executable file of minimal size:
- 1. Put all your resources into a single directory and add it to Irrlicht's filesystem
- as a folder through IFileSystem::addArchive. Develop and test your app as usual.
- 2. Open IrrCompileConfig.h and comment out all the options that your app does not use.
- This will reduce the size of the Irrlicht library considerably.
- * You should remove the D3D video drivers, because they rely on external DLLs.
- * You should keep either the TAR or ZIP archive loader, used in step 6.
- * If you remove the JPEG loader, you don't have to say you use JPEG code in your
- documentation.
- 3. Recompile Irrlicht as a static library, editing the IRR_STATIC_LIB line in
- IrrCompileConfig.h.
- The next time you compile your application it will take a while longer, but
- Irrlicht will be built into your binary.
- 4. TAR or ZIP your resource directory using your favourite archiving tool (ie 7zip).
- * If you chose ZIP but compiled without zlib, don't compress this archive or it
- won't open.
- 5. Run this tool to convert your resource file into a .h file, like so:
- FileToHeader res.zip > EmbeddedResources.h
- 6. Add the .h file to your project, create the embedded read file then mount as a
- ZIP or TAR archive instead of the folder, like so:
- io::IReadFile *f = io::createEmbeddedFile(device->getFileSystem(), "res.zip");
- device->getFileSystem()->addFileArchive(f);
- archive->drop();
- 7. Recompile your app.
- * If you use Microsoft's compiler, make sure your CRT (common run-time) is
- the static library version, otherwise you'll have a dependency on the CRT DLLs.
- Your binary should now be completely portable; you can distribute just the exe file.
- 8. Optional: Use UPX (upx.sf.net) to compress your binary.
- */
- #include <iostream>
- #include <fstream>
- #include <sstream>
- using namespace std;
- int main(int argc, char* argv[])
- {
- if (argc < 2)
- {
- // print usage
- cerr << "You must to specify at least one input file" << endl;
- cerr << "usage: " << argv[0] << "<file1> [file2...]" << endl;
- cerr << "outputs a header file to stdout, so for example use";
- return 1;
- }
- int i = 1;
- // write file header
- cout << "// File made by FileToHeader, part of the Irrlicht Engine" << endl
- << endl
- << "#ifndef _EMBEDDED_FILES_H_INCLUDED_" << endl
- << "#define _EMBEDDED_FILES_H_INCLUDED_" << endl
- << endl
- << "#include \"irrTypes.h\"" << endl
- << "#include \"IReadFile.h\"" << endl
- << "#include \"IFileSystem.h\"" << endl
- << endl
- << "namespace irr" << endl
- << "{" << endl
- << "namespace io" << endl
- << "{" << endl
- << endl
- << " const c8* EmbeddedFileData[] = " << endl
- << " {" << endl;
- // store sizes and file names
- stringstream sizes;
- stringstream names;
- sizes << "const u32 EmbeddedFileSizes[] = {";
- names << "const c8* EmbeddedFileNames[] = {";
- int fileCount = 0;
- // char to hex digit table, probably doesn't help for speed due to fstream. better than using sprintf though
- char hextable[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
- while (i < argc)
- {
- // open and seek to end of file
- ifstream input;
- input.open(argv[i], ios::in | ios::binary | ios::ate);
- if (input.is_open())
- {
- int size = input.tellg();
- input.seekg(0, ios::beg);
- // read the file into RAM
- char *entireFile = new char[size];
- input.read(entireFile, size);
- if (fileCount)
- {
- sizes << ", ";
- names << ", ";
- cout << "," << endl;
- }
- // save file size and name
- sizes << size;
- names << '"' << argv[i] << '"';
- // write the file data
- cout << " \"";
- for (int count=0; count < size; ++count)
- {
- if (count && (count % 16) == 0)
- cout << "\"" << endl << " \"";
- cout << "\\x" << hextable[(entireFile[count] >> 4) & 0xF] << hextable[entireFile[count] & 0x0F];
- }
- cout << "\"";
- delete [] entireFile;
- //
- input.close();
- fileCount++;
- }
- else
- {
- cerr << "Failed to open file: " << argv[i] << endl;
- }
- ++i;
- }
- // close binary file list and write file metadata
- cout << endl
- << " , 0};" << endl
- << endl
- << " const u32 EmbeddedFileCount = " << fileCount << ";" << endl
- << " " << sizes.str() << "};" << endl
- << " " << names.str() << "};" << endl
- << endl;
- // write functions to create embedded IReadFiles
- cout << " IReadFile* createEmbeddedFile(IFileSystem *fs, u32 index)" << endl
- << " {" << endl
- << " if (EmbeddedFileCount < index)" << endl
- << " return 0;" << endl
- << endl
- << " return fs->createMemoryReadFile((void*)EmbeddedFileData[index], " << endl
- << " EmbeddedFileSizes[index], EmbeddedFileNames[index]);" << endl
- << " }" << endl
- << endl
- << " IReadFile* createEmbeddedFile(IFileSystem *fs, path filename)" << endl
- << " {" << endl
- << " for (u32 i=0; i < EmbeddedFileCount; ++i)" << endl
- << " if (filename == EmbeddedFileNames[i])" << endl
- << " return createEmbeddedFile(fs, i);" << endl
- << endl
- << " return 0;" << endl
- << " }" << endl
- << endl;
- // write footer
- cout << "} // namespace io" << endl
- << "} // namespace irr" << endl
- << endl
- << "#endif // _EMBEDDED_FILES_H_INCLUDED_" << endl;
- return 0;
- }
|