philliptrudeau

Ludum Dare 45

Start with nothing in C: the first 3 hours

First Ludum Dare; second jam. My self-imposed challenge is to build the game from scratch in C with no #includes or #defines. This means no libraries except the ones I link against and manually pre-declare as headers. (Meaning, in this case, just Windows, and no C runtime library.)

So far I've written a simple OpenGL loader, and this macro-less assertion handler: static void assert_passed(void) {} static void (*assert(bool condition))(void) { if (condition) return assert_passed; // stack trace printing code omitted int result = MessageBoxA(NULL, textual_trace, "Assert Fired", 0x2102); if (result == 3) ExitProcess(1); if (result == 4) return NULL; // 4 represents "Retry" being clicked in the message box return assert_passed; } // Usage code: int swap_result = GL.wglSwapIntervalEXT(0); assert(swap_result)(); // calls a NULL function pointer if "Retry" is clicked in the message box, crashing and/or trapping to debugger. (I had to format the stack trace myself, because there's no printf!)

The big challenges will be asset loading and audio. I have written WASAPI code from scratch before, so I'll reuse that, but I've only ever done simple additive wave synthesis with it, so the music will be pretty minimalistic; more of a tracker-music vibe, probably. (I'm a fan of Fearofdark!)

Got simple fixed-function rendering going on right now to draw a blue square to the screen. Runs at about 7,000 FPS, so it's less than ideal, but it'll do for a game jam.blog1pic1.png

Start with nothing in C, part 2: Ending the first night

blog2pic1.png Used STBeasyfont to get some simple text rendering. (Does that count as using a library? I copied-and-pasted the code directly, so it wasn't an #include or anything.) The code makes weird assumptions about coordinate system, so I opted to just iterate over the vertices myself and call the fixed-function GL.Vertex3f() on them manually, injecting my own transform code rather than uploading some sort of transformation matrix to the GPU.

Start with nothing in C, part 3: Dawn of the second day

10:00 EST: I got into an Internet Argument™ with someone who didn't really believe that I'd be able to finish on time! Now, there's a point there - I definitely wouldn't suggest starting from complete scratch in C. Being able to #include <Windows.h> definitely has the benefit of eliminating a HUGE amount of boilerplate that I've had to write: __pragma(comment(lib, "kernel32.lib")); void *GetProcAddress(void *handle, const char *name); void *LoadLibraryA(const char *name); void ExitProcess(unsigned long dwExitCode); void *GetModuleHandleA(const char *module_name); void Sleep(unsigned long dwMilliseconds); int QueryPerformanceFrequency(union _LARGE_INTEGER *freq); int QueryPerformanceCounter(union _LARGE_INTEGER *count); // ... 115 lines later ... enum { // Window Styles WS_OVERLAPPED = 0x00000000L, WS_POPUP = 0x80000000L, WS_CHILD = 0x40000000L, WS_MINIMIZE = 0x20000000L, WS_VISIBLE = 0x10000000L, // .. 120 lines later ... typedef struct tagPOINT { long x; long y; } POINT; typedef struct _RECT { long left; long top; long right; long bottom; } RECT; Thankfully I have written this kind of boilerplate about 3 times before, so I'm able to copy over a lot of those declarations. This is basically what the Windows header does anyway, which is why I again don't recommend doing this in a serious game dev situation. (The compile times are great, though!)

14:00 EST: ... Alright, so something like 3 hours pass, and I get nothing done thanks to an infestation in my house. Oh well, when life gives you lemons, bite directly into the lemons.

Anyway, I've also copied over some of my 2D vector functions to quicken things -- once again, not much variance to be had here, so I'd be wasting time to transcribe it manually, despite this perhaps violating "purity". I also plan to write a build step that uses STB_image to convert .png files to C-style array declarations, which will let me embed game assets directly into the executable. (The alternative is putting a PNG parser INSIDE my game to read files from disk, which definitely feels like breaking my self-imposed rules.) Because I'm time-constrained (other life stuff happening as well, today, in a few hours) I think this "create game universe and mechanics using the console" idea is too heady and complex to be feasible for the compo deadline, so I'll just make a shooter. That's how lemons work!

Anyway, here's a picture of how ugly the console looks with multisampling and polygon smoothing:blog3pic1.png Eurgh, that quad-based text rendering does NOT fare well. Definitely gonna rip that out, and return to a library-free codebase. (That big black square is the character, and that little black square is the cursor. You'll see what kind of gun the character uses soon enough!)