diff --git a/Client/Audio/Audio.hpp b/Client/Audio/Audio.hpp
index c7f6250..fb7b21a 100644
--- a/Client/Audio/Audio.hpp
+++ b/Client/Audio/Audio.hpp
@@ -18,6 +18,5 @@
 #include "windows/xaudio2.hpp"
 
 namespace Audio {
-    DWORD WINAPI ThreadProc(LPVOID lpParameter);
-    extern HANDLE Thread;
+    int Initialize();
 }
\ No newline at end of file
diff --git a/Client/Audio/Startup.cpp b/Client/Audio/Startup.cpp
index 36ce517..f1a7471 100644
--- a/Client/Audio/Startup.cpp
+++ b/Client/Audio/Startup.cpp
@@ -26,8 +26,9 @@ IXAudio2MasteringVoice *MasterVoice = NULL;
 
 void Shutdown();
 
-DWORD WINAPI ThreadProc(LPVOID){
+int Initialize(){
     HRESULT result;
+    
     result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY);
     if(result != S_OK){
         MessageBox(Window::hWnd, "Failed to initialize Microsoft COM.", NULL, MB_OK | MB_ICONERROR);
@@ -49,12 +50,6 @@ DWORD WINAPI ThreadProc(LPVOID){
         Shutdown();
         return ERROR_AUDIO_CREATE_VOICE;
     }
-    
-    ResetEvent(System::Terminated[HANDLE_AUDIO]);
-    SetEvent(System::Initialized[HANDLE_AUDIO]);
-    WaitForSingleObject(System::Shutdown, INFINITE);
-    
-    Shutdown();
     return 0;
 }
 
@@ -67,8 +62,6 @@ void Shutdown(){
         pXAudio2->Release();
         pXAudio2 = NULL;
     }
-    
-    SetEvent(System::Terminated[HANDLE_AUDIO]);
 }
 
 }
\ No newline at end of file
diff --git a/Client/Client.cpp b/Client/Client.cpp
index 1e034d6..488c055 100644
--- a/Client/Client.cpp
+++ b/Client/Client.cpp
@@ -44,41 +44,68 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
         return ERROR_INIT_ANOTHERINSTRUNNING;
     }
     
-    System::Shutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
-    for(int i=0; i<2; i++){
-        System::Initialized[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
-        System::Terminated[i] = CreateEvent(NULL, TRUE, TRUE, NULL);
-    }
-    
     result = CreateWindowInvisible(hInstance, 800, 600, false);
     if(result != 0){
         Shutdown();
         return ERROR_INIT | ERROR_INIT_WINDOW | result;
     }
-
-    Graphics::Thread = CreateThread(NULL, 0, Graphics::ThreadProc, NULL, 0, NULL);
-    if(Graphics::Thread == NULL){
-        Shutdown();
-        return ERROR_INIT | ERROR_INIT_GRAPHICS | ERROR_GRAPHICS_CREATE_THREAD;
-    }
-
-    Audio::Thread = CreateThread(NULL, 0, Audio::ThreadProc, NULL, 0, NULL);
-    if(Audio::Thread == NULL){
-        Shutdown();
-        return ERROR_INIT | ERROR_INIT_GRAPHICS | ERROR_GRAPHICS_CREATE_THREAD;
-    }
     
-    WaitForMultipleObjects(2, System::Initialized, TRUE, INFINITE);
-    for(int i=0; i<2; i++){
-        if(WaitForSingleObject(System::Terminated[i], 0) != WAIT_TIMEOUT){
-            /* If Terminated for this thread is signaled, an initialization error occurred */
-            Shutdown();
-            return ERROR_INIT;
-        }
+    result = System::Initialize();
+    if(result != 0){
+        Shutdown();
+        return ERROR_INIT | ERROR_INIT_SYSTEM | result;
+    }
+
+    result = Graphics::Initialize();
+    if(result != 0){
+        Shutdown();
+        return ERROR_INIT | ERROR_INIT_GRAPHICS | result;
+    }
+
+    result = Audio::Initialize();
+    if(result != 0){
+        Shutdown();
+        return ERROR_INIT | ERROR_INIT_AUDIO | result;
     }
     
     CurrentScene = new LoginScreen();
-    CurrentScene->Render();
+    if(CurrentScene == NULL){
+        Shutdown();
+        return ERROR_INIT | ERROR_INIT_LOGIC | ERROR_LOGIC_CREATE_SCENE;
+    }
+    
+    LARGE_INTEGER PreviousTime;
+    QueryPerformanceCounter(&PreviousTime);
+    
+    ShowWindow(Window::hWnd, SW_SHOW);
+    SetForegroundWindow(Window::hWnd);
+    SetFocus(Window::hWnd);
+    
+    while(true){
+        MSG msg;
+        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        
+        LARGE_INTEGER CurrentTime;
+        QueryPerformanceCounter(&CurrentTime);
+        float TimeDelta = (float)(CurrentTime.QuadPart-PreviousTime.QuadPart)/System::ClockFreq.QuadPart;
+        
+        int result = CurrentScene->RunFor(TimeDelta);
+        if(result == System::SHUTDOWN)
+            break;
+        if(result > 0){
+            CurrentScene->Render();
+            SwapBuffers(Graphics::hDC);
+        }
+        
+        PreviousTime.QuadPart = CurrentTime.QuadPart;
+        QueryPerformanceCounter(&CurrentTime);
+        unsigned SleepDuration = (unsigned)
+            ((System::FramePeriod - (float)(CurrentTime.QuadPart-PreviousTime.QuadPart)/System::ClockFreq.QuadPart) * 1000);
+        if(SleepDuration > 1) Sleep(SleepDuration);
+    }
     
     MSG msg;
     while(GetMessage(&msg, NULL, 0, 0))
@@ -167,8 +194,6 @@ int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Height, bool
 
 void Shutdown()
 {
-    SetEvent(System::Shutdown);
-    WaitForMultipleObjects(2, System::Terminated, TRUE, INFINITE);
     if(Window::hWnd){
         DestroyWindow(Window::hWnd);
         Window::hWnd = NULL;
diff --git a/Client/Graphics/Graphics.hpp b/Client/Graphics/Graphics.hpp
index 770a3ae..e4dc9ca 100644
--- a/Client/Graphics/Graphics.hpp
+++ b/Client/Graphics/Graphics.hpp
@@ -20,8 +20,7 @@
 
 //Graphics/Startup.cpp
 namespace Graphics {
-    DWORD WINAPI ThreadProc(LPVOID lpParameter);
-    extern HANDLE Thread;
+    int Initialize();
     extern HDC hDC;
     extern HGLRC hRC;
     
diff --git a/Client/Graphics/Startup.cpp b/Client/Graphics/Startup.cpp
index 0e76dfa..ecdf434 100644
--- a/Client/Graphics/Startup.cpp
+++ b/Client/Graphics/Startup.cpp
@@ -25,7 +25,7 @@ HGLRC hRC;
 
 void Shutdown();
 
-DWORD WINAPI ThreadProc(LPVOID){
+int Initialize(){
     hDC = GetDC(Window::hWnd);
     if(hDC == NULL){
         MessageBox(Window::hWnd, "Failed to obtain the device context.", NULL, MB_OK | MB_ICONERROR);
@@ -39,7 +39,7 @@ DWORD WINAPI ThreadProc(LPVOID){
         PFD_SUPPORT_OPENGL |
         PFD_DOUBLEBUFFER,
         PFD_TYPE_RGBA,                    //iPixelType
-        32,                               //cColorBits
+        24,                               //cColorBits
         0, 0, 0, 0, 0, 0, 0, 0,           //R,G,B,A bits
         0, 0, 0, 0, 0,                    //Accumulation buffer bits
         16,                               //cDepthBits
@@ -76,6 +76,11 @@ DWORD WINAPI ThreadProc(LPVOID){
         return ERROR_GRAPHICS_ACTIVATE_GLRC;
     }
     
+    BOOL (WINAPI *wglSwapIntervalEXT)(int) = (BOOL (WINAPI *)(int)) wglGetProcAddress("wglSwapIntervalEXT");
+    if(wglSwapIntervalEXT) wglSwapIntervalEXT(1);
+    int (WINAPI *wglGetSwapIntervalEXT)(void) = (int (WINAPI *)(void)) wglGetProcAddress("wglGetSwapIntervalEXT");
+    if(wglGetSwapIntervalEXT) wglGetSwapIntervalEXT(); //Seems necessary on some cards
+    
     int result = InitGL();
     if(result != 0){
         Shutdown();
@@ -83,16 +88,6 @@ DWORD WINAPI ThreadProc(LPVOID){
     }
     
     ResizeViewport(Window::Width, Window::Height);
-    
-    ResetEvent(System::Terminated[HANDLE_GRAPHICS]);
-    SetEvent(System::Initialized[HANDLE_GRAPHICS]);
-    ShowWindow(Window::hWnd, SW_SHOW);
-    SetForegroundWindow(Window::hWnd);
-    SetFocus(Window::hWnd);
-    
-    WaitForSingleObject(System::Shutdown, INFINITE);
-    
-    Shutdown();
     return 0;
 }
 
@@ -110,7 +105,6 @@ int InitGL(){
 }
 
 void Shutdown(){
-    ShowWindowAsync(Window::hWnd, SW_HIDE);
     if(Graphics::hRC){
         wglMakeCurrent(NULL, NULL);
         wglDeleteContext(Graphics::hRC);
@@ -120,8 +114,6 @@ void Shutdown(){
         ReleaseDC(Window::hWnd, Graphics::hDC);
         Graphics::hDC = NULL;
     }
-    
-    SetEvent(System::Terminated[HANDLE_GRAPHICS]);
 }
 
 }
\ No newline at end of file
diff --git a/Client/MessageHandler.cpp b/Client/MessageHandler.cpp
index a6d9db9..4898f04 100644
--- a/Client/MessageHandler.cpp
+++ b/Client/MessageHandler.cpp
@@ -40,13 +40,19 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
     case WM_KEYDOWN:
     case WM_KEYUP:
-        System::Keys[wParam] = (uMsg == WM_KEYDOWN);
+        System::UserInput.Keys[wParam] = (uMsg == WM_KEYDOWN);
         return 0;
     
     case WM_CLOSE:
         PostQuitMessage(0);
         return 0;
-    }
 
+    case WM_DEVMODECHANGE: {
+        DEVMODE dm;
+        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+        System::FramePeriod = 1.0f/dm.dmDisplayFrequency;
+    } return 0;
+
+    }
     return DefWindowProc(hWnd, uMsg, wParam, lParam);
 }
\ No newline at end of file
diff --git a/Client/Scene/Scene.hpp b/Client/Scene/Scene.hpp
index 4f44e42..f956e53 100644
--- a/Client/Scene/Scene.hpp
+++ b/Client/Scene/Scene.hpp
@@ -49,6 +49,9 @@ class LoginScreen : public Scene {
 
   private:
     int Run(float){
+        if(System::UserInput.CloseWindow){
+            System::Shutdown = true;
+        }
         return 0;
     }
 
diff --git a/Client/System/System.cpp b/Client/System/System.cpp
index 4dc0c19..6a5a88b 100644
--- a/Client/System/System.cpp
+++ b/Client/System/System.cpp
@@ -18,14 +18,21 @@
 #include "../EngineInterface.hpp"
 
 namespace System {
+    bool Shutdown = false;
     HINSTANCE hInst = NULL;
-    HANDLE Terminate;
     HANDLE Process;
     HANDLE ProcessHeap;
-    LARGE_INTEGER ClockFrequency;
-    bool Keys[256];
+    LARGE_INTEGER ClockFreq;
+    float FramePeriod;
+    UserInput_t UserInput;
     
-    //Event objects
-    HANDLE Shutdown;
-    HANDLE Initialized[2], Terminated[2];
+    int Initialize(){
+        QueryPerformanceFrequency(&ClockFreq);
+        
+        DEVMODE dm;
+        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+        System::FramePeriod = 1.0f/dm.dmDisplayFrequency;
+
+        return 0;
+    }
 }
\ No newline at end of file
diff --git a/Client/System/System.hpp b/Client/System/System.hpp
index ae3cdf4..51fac26 100644
--- a/Client/System/System.hpp
+++ b/Client/System/System.hpp
@@ -17,26 +17,28 @@
 
 //System/System.cpp
 namespace System {
+    int Initialize();
+    extern bool Shutdown;
     extern HINSTANCE hInst;
     extern HANDLE Process;
     extern HANDLE ProcessHeap;
-    extern LARGE_INTEGER ClockFrequency;
+    extern LARGE_INTEGER ClockFreq;
+    extern float FramePeriod;
     extern bool Keys[256];
     
-    //Event objects
-    extern HANDLE Shutdown;
-    extern HANDLE Initialized[2], Terminated[2];
+    struct UserInput_t {
+        bool Keys[256];
+        bool MouseDown;
+        bool CloseWindow;
+    };
+    extern UserInput_t UserInput;
     
+    //Constants
     enum {
-        SHUTDOWN
+        SHUTDOWN = 0
     };
 }
 
-enum {
-    HANDLE_GRAPHICS,
-    HANDLE_AUDIO
-};
-
 /****
 ** Program exit codes
 ** (Return 0 for success)
@@ -52,20 +54,23 @@ enum {
         ERROR_REGISTER_CLASS = 1,
         ERROR_CREATE_WINDOW
     };
-#define ERROR_INIT_GRAPHICS 0x0200
+#define ERROR_INIT_SYSTEM 0x0200
+#define ERROR_INIT_GRAPHICS 0x0300
     enum {
-        ERROR_GRAPHICS_CREATE_THREAD = 1,
-        ERROR_GRAPHICS_OBTAIN_DC,
+        ERROR_GRAPHICS_OBTAIN_DC = 1,
         ERROR_GRAPHICS_FIND_PIXELFORMAT,
         ERROR_GRAPHICS_SET_PIXELFORMAT,
         ERROR_GRAPHICS_CREATE_GLRC,
         ERROR_GRAPHICS_ACTIVATE_GLRC,
         ERROR_GRAPHICS_INIT_GLSCENE
     };
-#define ERROR_INIT_AUDIO 0x0300
+#define ERROR_INIT_AUDIO 0x0400
     enum {
         ERROR_AUDIO_INIT_COM = 1,
         ERROR_AUDIO_INIT_XAUDIO2,
         ERROR_AUDIO_CREATE_VOICE
     };
-#define ERROR_INIT_LOGIC 0x0400
\ No newline at end of file
+#define ERROR_INIT_LOGIC 0x0500
+    enum {
+        ERROR_LOGIC_CREATE_SCENE = 1
+    };
\ No newline at end of file