Introduction
This is the C++ 64-bit transcription of an original PowerBASIC project written by Borje Hagsten.
The C++ version is built upon direct access to the core FLAT SDK API to produce a tiny standalone EXEcutable of only 36 KB. This was done by eliminating as much as possible most of the CRT, using the same approach done by Matt Pietrek's LibCTiny.lib, and the different techniques explained here.
This project has also been translated into WinDev p-code here.
About the Use of the Custom Control
The GUI exposed a complete MIDI interface using either the mouse or the PC's keyboard to play the selected instrument.
You can press on F1 to display this information help:
Using the Code
This project has been done with the latest C++ Visual Studio 2017 community free version.
For the fun of it, you can enable extra skinning by editing the lines of code shown below (at the end of Main.cpp).
ShowWindow(gP.hMain, nCmdShow);
UpdateWindow(gP.hMain);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
then with the WinLIFT
magic, the whole GUI will change to this:
Points of Interest
You can reduce drastically the size of your 64-bit code if you follow these few steps:
- Always use direct call to the core FLAT API whenever available
- Prefer procedural code when there is no need to use a class to achieve the same thing
- Use explicit linking rather than implicit
- Get free of the runtime Library, using Multi-threaded (/MT) in the code generation
And here is an example on how to use explicit linking to MSVCRT
to achieve ultimate granularity:
#define long_proc typedef long (__stdcall *zProc)
#define void_proc typedef void (__stdcall *zProc)
#define double_proc typedef double (__stdcall *zProc)
#define M_LOG2E 1.44269504088896340736
HMODULE MSVCRT() {
static HMODULE hModule;
if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
return hModule;
}
double log2(IN double X) {
double l2 = 0;
HMODULE hModule = MSVCRT();
if (hModule) {
double_proc (double);
zProc hProc = (zProc) GetProcAddress(hModule, "log");
if (hProc) { l2 = hProc(X) * M_LOG2E; }
}
return l2;
}
void RandoMize(IN DWORD seed) {
HMODULE hModule = MSVCRT();
if (hModule) {
void_proc (DWORD);
zProc hProc = (zProc) GetProcAddress(hModule, "srand");
if (hProc) { hProc(seed); }
}
}
long Rand() {
long nRand = 0;
HMODULE hModule = MSVCRT();
if (hModule) {
long_proc ();
zProc hProc = (zProc) GetProcAddress(hModule, "rand");
if (hProc) { nRand = hProc(); }
}
return nRand;
}
size_t rnd(IN long nMin, IN long nMax) {
double dblRange = nMax - nMin;
double dblMaxFactor = dblRange / RAND_MAX;
double dblRandomNumber = (double) Rand();
return (size_t) (nMin + dblMaxFactor * dblRandomNumber);
}
The End
Enjoy playing midi with this tiny piece of { unsafe } code. ;)