win32
[censuslogo] / src / main_w32.c
diff --git a/src/main_w32.c b/src/main_w32.c
new file mode 100644 (file)
index 0000000..f3577f3
--- /dev/null
@@ -0,0 +1,199 @@
+#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;
+}