Bunchbox
My primary goal for this program was to learn how to make a modern (i.e. Windows) demo
that fits into 4096 bytes. In addition to this I wanted it to make 3D graphics
and music, have scrolling text (for nostalgia), and have the graphics synchronized
precisely with the music. I also wanted to make a guide for others on how to make a 4k
intro, since I had to cobble together the knowledge I needed from scraps here and there,
which is why I have made the source code available.
This zip file contains the demo (bunchbox.exe) as well as its full source code for
those who are interested. The program runs in a 1280x720 window and can be closed
by pressing the escape key.
Requirements
To compile this program you will need:
- Visual C++ 2008
- The Crinkler
- I used version 1.2
- http://www.crinkler.net/
- Copy crinkler.exe into the same directory as demo0.sln and rename it link.exe.
- Add "$(SolutionDir)" to the top of Visual Studio's executable directory list.
- See Crinkler's manual for more explanation.
- Crinkler is not required to compile this program, but the executable will be considerably smaller.
4k Guide
Creating a 4k intro is not a task for someone who isn't interested in experimenting with
their compiler and learning some nitty gritty details, so I'm not going to explain everything here;
I'm just trying to give enough to get you started. Take a look at the source code, and look
up the compiler settings you don't understand. Try changing them and see what happens to your
code size.
- Some of my compiler settings:
- No debug information.
- Optimize for size (/O1)
- Default inline function expansion
- No intrinsic functions.
- Favour small code (/Os)
- Omit frame pointers
- String pooling (/GF)
- Multi-threaded runtime library (/MT)
- Align structs to 1 byte (/Zp1)
- No buffer security check (/GS-)
- Fast floating point model (/fp:fast)
- No RTTI (/GR-)
- __fastcall calling convention (/Gr)
- Omit default library names (/Zl)
- Extra command line: /QIfist (suppresses unlinkable intrinsics for float to int conversion)
- For suitable linker settings, read the Crinkler manual,
or check my settings for the Release or Best build.
A lot of the Microsoft settings are ignored by Crinkler.
- No incremental linking (/INCREMENTAL:NO)
- Do not link library dependencies.
- Ignore all default libraries (/NODEFAULTLIB)
- No debug info
- Eliminate unreferenced data (/OPT:REF)
- Remove redundant COMDATs (/OPF:ICF)
- Don't link with the C runtime library.
- This goes with the /NODEFAULTLIB setting, above.
- Working without the CRT is tricky; mostly it is not needed and this saves space, but some functions
will have to be replaced. See below.
- Define your own entry point.
- I called mine WinMain. See main4k.cpp.
- Doing this also means you can't use static instances of C++ classes,
because their constructors are normally called by an internal C runtime entry point
(see http://www.codeproject.com/KB/library/tlibc.aspx
for an interesting article about replacing the C runtime).
- Define atexit.
- It doesn't have to do anything, but you will need it.
- Without the C runtime library you will need this magic line
somewhere in a cpp file in order to use floating points:
- extern "C" int _fltused = 1;
- Define your own memset and memcpy
- Even if you do not explicitly use these functions MSVC will probably
implicitly use them for you (sometimes it will even replace simple for loops).
Because you are not using the C runtime library, you will therefore need your own.
- You may want to use #pragma function(memset) to force explicit usage.
- Use Crinkler's build information output to analyze your source
and how big each part of it is. It is an amazing tool.
- Create a debug build with diagnostics you can define out.
- Since using a debugger on your compressed exe is going to be
very difficult, I strongly recommend trying to set up a debug build
to help catch problems.
- The compiler settings for a debug build are tricky;
I had to experiment to get it going, mainly because I wanted vsnprintf
for debug output.
- An ASSERT macro is extremely useful.
- I created a LOG macro for debugging output. It couldn't use %f to print
floats, but it was otherwise a great help.
Anyhow, if you have questions or have found this useful, please e-mail me. Have fun!
Links
brad
rainwarrior.cabr />
2011-7-30