Mundane C tricks ...
Posted: Thu Dec 06, 2012 10:43 am
None of this is rocket science, just some elementary code and macros used lately that has made life easier.
With C, a lot of stuff is kind of obscure at times but once you discover something, you can have a lot of fun with it. String macros, for instance, I had a ton of trouble getting any of them to work once upon a time (until I found the option in Visual Studio that let's you view a file AFTER the preprocessor macros have been evaluated ... )
With these macros ...
Evaluates to ...
Another funny trick (Windows only as far as I know) ... allocating a debug console to run along side main OpenGL window.
And along with this ...
I can do Logme ("Something"); and have an entirely separate DOS-like window just showing the messages.
And third one I found satisfying ...
... to load whatever data out of a Windows resource file. And combined with this it could be saved to disk.
Again, nothing "space age" above, but something I've found satisfying is after you build up a small mountain of these kinds of conveniences, things start getting really fast and easy and it seems like small inconveniences are the ones that really add to the length of time of making stuff and when you eliminate some of those everything becomes much more fun.
Case in point: The above allocating a separate window for messages that print to standard error, the next time I get around to messing with the Quake engine more that will save major time because I won't have to worry about everything printing to the console any more.
With C, a lot of stuff is kind of obscure at times but once you discover something, you can have a lot of fun with it. String macros, for instance, I had a ton of trouble getting any of them to work once upon a time (until I found the option in Visual Studio that let's you view a file AFTER the preprocessor macros have been evaluated ... )
Code: Select all
const_entry_uint_t messagenames[] =
{ KEYVALUE(WM_ACTIVATE), KEYVALUE(WM_KILLFOCUS), KEYVALUE(WM_CLOSE),
KEYVALUE(WM_DESTROY), KEYVALUE(WM_CREATE), KEYVALUE(WM_SYSCHAR),
KEYVALUE(WM_SIZE), KEYVALUE(WM_MOVE), KEYVALUE(WM_PAINT), KEYVALUE(WM_GETMINMAXINFO)
}; COUNT_ARRAY (messagenames);Code: Select all
#define KEYVALUE(x) { #x , x }
#define COUNT_ARRAY(_array) const int _num ## _array = sizeof(_array) / sizeof(_array[0])
typedef struct
{
const char* string;
unsigned int value;
} const_entry_uint_t;
Code: Select all
messagenames[] = {
{ "WM_ACTIVATE", WM_ACTIVATE },
{ "WM_KILLFOCUS", WM_KILLFOCUS },
...
}; const int _nummessages = sizeof(messagenames) / sizeof(messagenames[0]);Code: Select all
AllocConsole ();
freopen("CONIN$", "rt", stdin);
freopen("CONOUT$", "wt", stdout);
freopen("CONOUT$", "wt", stderr);
SetConsoleTitle("Debug Console");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);Code: Select all
void Logme (const char *fmt, ...)
{
va_list argptr;
char msg[16384];
va_start (argptr, fmt);
vsnprintf (msg, sizeof(msg), fmt, argptr);
va_end (argptr);
StringLCat (msg, "\n"); // <--------- append \n just so life is less annoying
fprintf (stderr, "Warning: "); /// <------------------------- fprintf to stderr
fprintf (stderr, msg);
}And third one I found satisfying ...
Code: Select all
byte* Win32_Bytes_From_Resource (int* numBytesSize, int resourceNum, const char* text_type_field_in_rc)
{
HMODULE handle = GetModuleHandle(NULL);
HRSRC rc = FindResource(handle, MAKEINTRESOURCE(resourceNum), TEXT(text_type_field_in_rc));
HGLOBAL rcData = LoadResource(handle, rc);
int numBytes = SizeofResource(handle, rc);
byte* rawData = LockResource(rcData);
*numBytesSize = numBytes;
if (numBytes == 0)
return NULL;
return rawData;
}Code: Select all
fbool File_Memory_To_File (const char* fileToWrite, byte* data, int numBytes)
{
FILE* fout = fopen (fileToWrite, "wb");
if (!fout) return False;
if ( fwrite (data, numBytes, 1, fout) != 1) return False;
fclose (fout);
return True;
}Case in point: The above allocating a separate window for messages that print to standard error, the next time I get around to messing with the Quake engine more that will save major time because I won't have to worry about everything printing to the console any more.