Flatland

Documentation

SourceForge.net Logo

osWindows.c

Go to the documentation of this file.
00001 // Summary: Defines methods for windows-specific functions.
00002 // Copyright: 2007  Philip Rideout.  All rights reserved.
00003 // License: see bsd-license.txt
00004 
00005 #include <stdio.h>
00006 #include "os.h"
00007 #include "resource.h"
00008 #include <GL/wglext.h>
00009 
00010 static HINSTANCE g_hInstance;
00011 static HDC g_hDC;
00012 static OS_Event *g_eventHead = 0;
00013 static OS_Event **g_eventTail = &g_eventHead;
00014 static HWND g_hWnd;
00015 static int g_cursorVisible = 1;
00016 
00017 int main(int argc, char** argv);
00018 
00019 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
00020 {
00021     int argc;
00022     char** argv = (char**) CommandLineToArgvW((LPCWSTR) lpCmdLine, &argc);
00023     g_hInstance = hInstance;
00024     return main(argc, argv);
00025 }
00026 
00027 void osWaitVsync(int interval)
00028 {
00029     PFNWGLSWAPINTERVALEXTPROC wglSwapInterval;
00030     wglSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
00031     if (wglSwapInterval)
00032         wglSwapInterval(interval);
00033 }
00034 
00035 int osGetScreenWidth() { return GetSystemMetrics(SM_CXSCREEN); }
00036 int osGetScreenHeight() { return GetSystemMetrics(SM_CYSCREEN); }
00037 
00038 #pragma warning(push)
00039 #pragma warning(disable:4996)
00040 void fatalf(const char *format, ...)
00041 {
00042     va_list args;
00043     int length;
00044     char *buffer;
00045 
00046     va_start(args, format);
00047     length = _vscprintf(format, args);
00048     buffer = malloc(length + 1);
00049     vsprintf(buffer, format, args);
00050     OutputDebugString("\n\n");
00051     OutputDebugString(buffer);
00052     OutputDebugString("\n\n");
00053     free(buffer);
00054     exit(1);
00055 }
00056 void debugf(const char *format, ...)
00057 {
00058     va_list args;
00059     int length;
00060     char *buffer;
00061 
00062     va_start(args, format);
00063     length = _vscprintf(format, args);
00064     buffer = malloc(length + 1);
00065     vsprintf(buffer, format, args);
00066     OutputDebugString(buffer);
00067     free(buffer);
00068 }
00069 #pragma warning(pop)
00070 
00071 void osQuit(void)
00072 {
00073     timeEndPeriod(1);
00074 
00075     if (g_hWnd)
00076     {
00077         DestroyWindow(g_hWnd);
00078         g_hWnd = 0;
00079     }
00080 
00081     while (g_eventHead)
00082     {
00083         OS_Event *pending = g_eventHead;
00084         g_eventHead = pending->next;
00085         if (!g_eventHead)
00086             g_eventTail = &g_eventHead;
00087         free(pending);
00088     }
00089 }
00090 
00091 static LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00092 {
00093     OS_Event e;
00094     e.type = 0;
00095 
00096     switch (uMsg)
00097     {
00098         case WM_KEYDOWN:
00099             e.type = OS_KEYDOWN;
00100             e.key.key = (unsigned char) wParam;
00101             e.key.state = OSKS_DOWN;
00102             break;
00103 
00104         case WM_KEYUP:
00105             e.type = OS_KEYUP;
00106             e.key.key = (unsigned char) wParam;
00107             e.key.state = OSKS_UP;
00108             break;
00109 
00110         case WM_SIZE:
00111             e.type = OS_RESIZE;
00112             e.resize.width = LOWORD(lParam);
00113             e.resize.height = HIWORD(lParam);
00114             break;
00115 
00116         case WM_PAINT:
00117         case WM_ERASEBKGND:
00118             break;
00119 
00120         case WM_MOUSEMOVE:
00121             e.type = OS_MOUSEMOTION;
00122             e.mouse.button = 0;
00123             if (wParam & MK_LBUTTON) e.mouse.button |= OS_BUTTON_LEFT;
00124             if (wParam & MK_MBUTTON) e.mouse.button |= OS_BUTTON_MIDDLE;
00125             if (wParam & MK_RBUTTON) e.mouse.button |= OS_BUTTON_RIGHT;
00126             e.mouse.x = LOWORD(lParam);
00127             e.mouse.y = HIWORD(lParam);
00128             break;
00129 
00130         case WM_LBUTTONDOWN:
00131             e.type = OS_MOUSEBUTTONDOWN;
00132             e.mouse.button = OS_BUTTON_LEFT;
00133             e.mouse.x = LOWORD(lParam);
00134             e.mouse.y = HIWORD(lParam);
00135             break;
00136 
00137         case WM_LBUTTONUP:
00138             e.type = OS_MOUSEBUTTONUP;
00139             e.mouse.button = OS_BUTTON_LEFT;
00140             e.mouse.x = LOWORD(lParam);
00141             e.mouse.y = HIWORD(lParam);
00142             break;
00143 
00144         case WM_CLOSE:
00145         case WM_QUIT:
00146             e.type = OS_QUIT;
00147             break;
00148     }
00149 
00150     if (e.type)
00151     {
00152         e.next = 0;
00153         *g_eventTail = malloc(sizeof(OS_Event));
00154         memcpy(*g_eventTail, &e, sizeof(OS_Event));
00155         g_eventTail = &((*g_eventTail)->next);
00156     }
00157 
00158     return DefWindowProc(hWnd, uMsg, wParam, lParam);
00159 }
00160 
00161 void osInit(int width, int height, unsigned int flags, int *attribs)
00162 {
00163     HICON tiny, big;
00164     PIXELFORMATDESCRIPTOR pfd;
00165     LPCTSTR name = "Flatland Demo";
00166     int pixelFormat;
00167     HGLRC hRC;
00168     RECT rect;
00169     DWORD dwStyle, dwExStyle;
00170     int x, y;
00171 
00172     WNDCLASS wndClass =
00173     {
00174         CS_OWNDC, WinProc, 0, 0,
00175         g_hInstance, 0, LoadCursor(0, IDC_ARROW), 0, 0, name
00176     };
00177 
00178     atexit(osQuit);
00179     RegisterClass(&wndClass);
00180 
00181     if (flags & OS_FULLSCREEN)
00182     {
00183         width = GetSystemMetrics(SM_CXSCREEN);
00184         height = GetSystemMetrics(SM_CYSCREEN);
00185         dwStyle = WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00186         dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | WS_EX_TOPMOST;
00187         x = y = 0;
00188     }
00189     else
00190     {
00191         dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX;
00192         dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
00193         x = y = CW_USEDEFAULT;
00194         if (flags & OS_RESIZABLE)
00195             dwStyle |= WS_SIZEBOX | WS_MAXIMIZEBOX;
00196     }
00197 
00198     // Create the window.
00199     SetRect(&rect, 0, 0, width, height);
00200     AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
00201     width = rect.right - rect.left;
00202     height = rect.bottom - rect.top;
00203     g_hWnd = CreateWindowEx(0, name, name, dwStyle, x, y, width, height, 0, 0, g_hInstance, 0);
00204 
00205     // Create the GL context.
00206     ZeroMemory(&pfd, sizeof(pfd));
00207     pfd.nSize = sizeof(pfd);
00208     pfd.nVersion = 1;
00209     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
00210     pfd.iPixelType = PFD_TYPE_RGBA;
00211     pfd.cColorBits = 24;
00212     pfd.cDepthBits = 0;
00213     pfd.cStencilBits = 0;
00214     pfd.iLayerType = PFD_MAIN_PLANE;
00215 
00216     g_hDC = GetDC(g_hWnd);
00217     pixelFormat = ChoosePixelFormat(g_hDC, &pfd);
00218 
00219     SetPixelFormat(g_hDC, pixelFormat, &pfd);
00220     hRC = wglCreateContext(g_hDC);
00221     wglMakeCurrent(g_hDC, hRC);
00222 
00223     tiny = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_SMALL));
00224     SendMessage(g_hWnd, WM_SETICON, ICON_SMALL, (LPARAM) tiny);
00225 
00226     big = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BIG));
00227     SendMessage(g_hWnd, WM_SETICON, ICON_BIG, (LPARAM) big);
00228 
00229     timeBeginPeriod(1);
00230 }
00231 
00232 unsigned int osGetMilliseconds()
00233 {
00234     return timeGetTime();
00235 }
00236 
00237 int osPollEvent(OS_Event *e)
00238 {
00239     MSG msg;
00240     msg.message = WM_NULL;
00241 
00242     while (PeekMessage(&msg, g_hWnd, 0, 0, PM_REMOVE))
00243     {
00244         TranslateMessage(&msg);
00245         DispatchMessage(&msg);
00246 
00247         if (msg.message == WM_QUIT || msg.message == WM_CLOSE)
00248         {
00249             e->type = OS_QUIT;
00250             return 1;
00251         }
00252     }
00253 
00254     if (g_eventHead)
00255     {
00256         OS_Event *pending = g_eventHead;
00257         memcpy(e, pending, sizeof(OS_Event));
00258         g_eventHead = pending->next;
00259         if (!g_eventHead)
00260             g_eventTail = &g_eventHead;
00261         free(pending);
00262         return 1;
00263     }
00264 
00265     e->type = 0;
00266     return 0;
00267 }
00268 
00269 void osSwapBuffers()
00270 {
00271     SwapBuffers(g_hDC);
00272 }
00273 
00274 int osIsKeyDown(int key)
00275 {
00276     int vKey;
00277     switch (key)
00278     {
00279         case OSK_ESCAPE: vKey = VK_ESCAPE; break;
00280         case OSK_LEFT: vKey = VK_LEFT; break;
00281         case OSK_RIGHT: vKey = VK_RIGHT; break;
00282         case OSK_UP: vKey = VK_UP; break;
00283         case OSK_DOWN: vKey = VK_DOWN; break;
00284         case OSK_SHIFT: vKey = VK_SHIFT; break;
00285         default: return 0;
00286     }
00287     return (GetAsyncKeyState(vKey) & 0x8000) == 0x8000;
00288 }
00289 
00290 int osShowCursor(int toggle)
00291 {
00292     switch (toggle)
00293     {
00294         case OS_ENABLE:
00295             if (!g_cursorVisible)
00296             {
00297                 ShowCursor(TRUE);
00298                 g_cursorVisible = 1;
00299             }
00300             break;
00301 
00302         case OS_DISABLE:
00303             if (g_cursorVisible)
00304             {
00305                 ShowCursor(FALSE);
00306                 g_cursorVisible = 0;
00307             }
00308             break;
00309 
00310         case OS_QUERY:
00311             return g_cursorVisible;
00312     }
00313 
00314     return g_cursorVisible;
00315 }

Generated on Sat Jan 13 17:20:21 2007 for Flatland by doxygen 1.5.1