--- /dev/null
+#include <stdio.h>
+#include <windows.h>
+#include "app.h"
+
+static int create_glwin(int xsz, int ysz);
+static void destroy_glwin(void);
+static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam);
+
+static HWND win;
+static HDC dc;
+static HGLRC ctx;
+static int quit;
+static long start_time;
+
+
+int WINAPI WinMain(HINSTANCE pid, HINSTANCE prevpid, char *cmdline, int showcmd)
+{
+ if(memcmp(cmdline, "-c", 2) == 0) {
+ return 0;
+ }
+ if(memcmp(cmdline, "-s", 2) == 0) {
+ fullscr = 1;
+ }
+
+ if(create_glwin(1280, 800) == -1) {
+ return 1;
+ }
+
+ if(app_init() == -1) {
+ return 1;
+ }
+ start_time = timeGetTime();
+
+ while(!quit) {
+ MSG ev;
+ while(PeekMessage(&ev, 0, 0, 0, PM_REMOVE)) {
+ if(ev.message == WM_QUIT) {
+ goto done;
+ }
+ TranslateMessage(&ev);
+ DispatchMessage(&ev);
+ }
+ if(quit) goto done;
+
+ msec = timeGetTime() - start_time;
+ app_display();
+ SwapBuffers(dc);
+ }
+
+done:
+ destroy_glwin();
+ return 0;
+}
+
+void app_quit(void)
+{
+ quit = 1;
+}
+
+void app_fullscreen(void)
+{
+}
+
+void app_windowed(void)
+{
+}
+
+
+static int create_glwin(int xsz, int ysz)
+{
+ int x, y, win_xsz, win_ysz, pix_fmt;
+ unsigned int style;
+ HINSTANCE pid;
+ WNDCLASSEX wc;
+ PIXELFORMATDESCRIPTOR pfd;
+ RECT rect;
+
+ pid = GetModuleHandle(0);
+
+ memset(&wc, 0, sizeof wc);
+ wc.cbSize = sizeof wc;
+ wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+ wc.hCursor = LoadCursor(0, IDC_ARROW);
+ wc.hIcon = wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
+ wc.hInstance = pid;
+ wc.lpfnWndProc = (WNDPROC)handle_events;
+ wc.lpszClassName = "census";
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+ RegisterClassEx(&wc);
+
+ if(fullscr) {
+ x = y = 0;
+ win_xsz = xsz = GetSystemMetrics(SM_CXSCREEN);
+ win_ysz = ysz = GetSystemMetrics(SM_CYSCREEN);
+
+ style = WS_POPUP;
+ } else {
+ x = y = CW_USEDEFAULT;
+ style = WS_OVERLAPPEDWINDOW;
+
+ rect.left = rect.top = 0;
+ rect.right = xsz;
+ rect.bottom = ysz;
+ AdjustWindowRect(&rect, style, 0);
+
+ win_xsz = rect.right - rect.left;
+ win_ysz = rect.bottom - rect.top;
+ }
+
+ printf("creating window: %dx%d\n", xsz, ysz);
+ win = CreateWindow("census", "census", style, x, y, win_xsz, win_ysz, 0, 0, pid, 0);
+ dc = GetDC(win);
+
+ memset(&pfd, 0, sizeof pfd);
+ pfd.nSize = sizeof pfd;
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+ pfd.cDepthBits = 24;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ if(!(pix_fmt = ChoosePixelFormat(dc, &pfd)) || !SetPixelFormat(dc, pix_fmt, &pfd)) {
+ fprintf(stderr, "Failed to get suitable pixel format\n");
+ ReleaseDC(win, dc);
+ DestroyWindow(win);
+ UnregisterClass("census", pid);
+ return -1;
+ }
+
+ if(!(ctx = wglCreateContext(dc))) {
+ fprintf(stderr, "Failed to create WGL context\n");
+ ReleaseDC(win, dc);
+ DestroyWindow(win);
+ UnregisterClass("census", pid);
+ return -1;
+ }
+ wglMakeCurrent(dc, ctx);
+
+ ShowWindow(win, SW_SHOW);
+ UpdateWindow(win);
+ SetFocus(win);
+
+ app_reshape(xsz, ysz);
+ win_width = xsz;
+ win_height = ysz;
+ return 0;
+}
+
+static void destroy_glwin(void)
+{
+ wglMakeCurrent(0, 0);
+ wglDeleteContext(ctx);
+ ReleaseDC(win, dc);
+ DestroyWindow(win);
+ UnregisterClass("census", GetModuleHandle(0));
+}
+
+static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam)
+{
+ static int window_mapped;
+
+ switch(msg) {
+ case WM_SHOWWINDOW:
+ window_mapped = wparam;
+ break;
+
+ case WM_PAINT:
+ if(window_mapped) {
+ ValidateRect(win, 0);
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ quit = 1;
+ break;
+
+ case WM_KEYDOWN:
+ app_keyboard(wparam, 1);
+ break;
+
+ case WM_ACTIVATE:
+ if(!wparam) {
+ PostQuitMessage(0);
+ quit = 1;
+ }
+ break;
+
+ case WM_SYSCOMMAND:
+ if(wparam == SC_SCREENSAVE) {
+ break;
+ }
+
+ default:
+ return DefWindowProc(win, msg, wparam, lparam);
+ }
+ return 0;
+}