changeset 1802:633f81bb3ae7

HWND -> class OSWindow
author Nomad
date Mon, 07 Oct 2013 11:52:33 +0200
parents a2ea57410b15
children 9f93b5700e2d
files AudioPlayer.cpp AudioPlayer.h GUIWindow.cpp Game.cpp Mouse.cpp Mouse.h NewUI/UIControl.h OSAPI.cpp Render.cpp Render.h UI/UIPopup.cpp UI/UiGame.cpp VideoPlayer.cpp VideoPlayer.h _deleted.cpp mm7_2.cpp mm7_data.cpp mm7_data.h
diffstat 18 files changed, 831 insertions(+), 1015 deletions(-) [+]
line wrap: on
line diff
--- a/AudioPlayer.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/AudioPlayer.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -1877,14 +1877,14 @@
 }
 
 //----- (004AB8CE) --------------------------------------------------------
-void AudioPlayer::Initialize(HWND hWnd)
+void AudioPlayer::Initialize()
 {
   //AudioPlayer *v2; // esi@1
   int v3; // ebx@1
   //_DIG_DRIVER *v4; // eax@1
   char v5; // dl@5
   _PROVIDER *v6; // eax@9
-  HWND v7; // ST00_4@9
+  //HWND v7; // ST00_4@9
   MixerChannel *pChannel; // edi@14
   _SAMPLE *v9; // eax@15
   //_REDBOOK *v10; // eax@19
@@ -1895,7 +1895,7 @@
 
   //v2 = this;
   v3 = 0;
-  this->hWindow = hWnd;
+  //this->hWindow = hWnd;
   this->hAILRedbook = 0;
   this->hDigDriver = 0;
   this->dword_0002AC = 0;
@@ -1926,11 +1926,12 @@
     ReadWindowsRegistryString("3DSoundProvider", p3DSoundProvider, 128u, "NONE");
     __debugbreak(); // audioplayer.cpp(1926): warning C4700: uninitialized local variable 'v5' used
     CheckA3DSupport(v5);
-    while ( AIL_enumerate_3D_providers(&v14, (HPROVIDER *)&hWnd, &Str1) )
+    HPROVIDER prov;
+    while ( AIL_enumerate_3D_providers(&v14, &prov, &Str1) )
     {
       if ( !strcmp(Str1, p3DSoundProvider) )
       {
-        if ( AIL_open_3D_provider((HPROVIDER)hWnd) )
+        if ( AIL_open_3D_provider(prov) )
         {
           bEAXSupported = 0;
           b3DSoundInitialized = 0;
@@ -1938,12 +1939,12 @@
         }
         else
         {
-          v6 = (_PROVIDER *)hWnd;
-          v7 = hWnd;
+          v6 = prov;
+          //v7 = prov;
           b3DSoundInitialized = 1;
           h3DSoundProvider = v6;
           uNum3DSamples = 4;
-          AIL_3D_provider_attribute((HPROVIDER)v7, "EAX environment selection", &v12);
+          AIL_3D_provider_attribute(prov, "EAX environment selection", &v12);
           if ( v12 != -1 )
             bEAXSupported = 1;
         }
--- a/AudioPlayer.h	Tue Oct 01 06:19:58 2013 +0200
+++ b/AudioPlayer.h	Mon Oct 07 11:52:33 2013 +0200
@@ -167,7 +167,7 @@
   void UpdateSounds();
   void StopChannels(int uStartChannel, int uEndChannel);
   void LoadAudioSnd();
-  void Initialize(HWND hWnd);
+  void Initialize();
   LSTATUS CheckA3DSupport(char a2);
   void Release();
   void FreeChannel(MixerChannel *pChannel);
@@ -189,7 +189,8 @@
   int sRedbookVolume;
   char p3DSoundProvider[128];
   unsigned int bPlayerReady;
-  HWND hWindow;
+  //HWND hWindow;
+  class OSWindow *window;
   struct _REDBOOK *hAILRedbook;
   struct _DIG_DRIVER *hDigDriver;
   int dword_0002AC;
--- a/GUIWindow.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/GUIWindow.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -2219,7 +2219,7 @@
   if ( GetCurrentMenuID() == -1 )
     GameUI_DrawFoodAndGold();
   if ( sub_4637E0_is_there_popup_onscreen() )
-    sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
+    UI_OnMouseRightClick(0);
 }
 //----- (00415485) --------------------------------------------------------
 void DrawCopyrightWindow()
--- a/Game.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/Game.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -355,22 +355,8 @@
         pRenderer->Present();
         continue;
       }
-      if ( pVideoPlayer->pSmackerMovie && !SmackWait(pVideoPlayer->pSmackerMovie) )
-      {
-        pRenderer->BeginScene();
-        pMouse->DrawCursorToTarget();
-        pVideoPlayer->SmackUpdatePalette(pVideoPlayer->hWindow);
-        pMouse->_469EA4();
-        pRenderer->EndScene();
-      }
-      else if ( pVideoPlayer->pBinkMovie && !BinkWait(pVideoPlayer->pBinkMovie) )
-      {
-        pRenderer->BeginScene();
-        pMouse->DrawCursorToTarget();
-        pVideoPlayer->BinkUpdatePalette(pVideoPlayer->hWindow);
-        pMouse->_469EA4();
-        pRenderer->EndScene();
-      }
+
+      pVideoPlayer->_inlined_in_463149();
       
       pEventTimer->Update();
       pMiscTimer->Update();
@@ -755,11 +741,11 @@
 
 
   WriteWindowsRegistryInt("startinwindow", pRenderer->bWindowMode);
-  if ( GetWindowRect(hWnd, &Rect) && pRenderer->bWindowMode )
+  /*if ( GetWindowRect(hWnd, &Rect) && pRenderer->bWindowMode )
   {
     WriteWindowsRegistryInt("window X", Rect.left);
     WriteWindowsRegistryInt("window Y", Rect.top);
-  }
+  }*/
   WriteWindowsRegistryInt("valAlwaysRun", bAlwaysRun);
   pItemsTable->Release();
   pNPCStats->Release();
@@ -946,7 +932,7 @@
   //pThreadWardInstance = new ThreadWard;
   pThreadWardInstance = nullptr;
   pParticleEngine = new ParticleEngine;
-  pMouse = pMouseInstance = new Mouse(pThreadWardInstance);
+  pMouse = pMouseInstance = new Mouse;
   pLightmapBuilder = new LightmapBuilder;
   pVisInstance = new Vis;
   pStru6Instance = new stru6;
--- a/Mouse.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/Mouse.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -57,8 +57,6 @@
 //----- (00469903) --------------------------------------------------------
 void Mouse::SetCursorBitmap(const char *pName)
 {
-  struct tagPOINT Point; // [sp+14h] [bp-8h]@20
-
   if ( !this->bInitialized || !pName )
     return;
   if ( _stricmp("MICON2", pName) )
@@ -84,17 +82,9 @@
     }
     return;
   }
-  this->bActive = 0;
+  this->bActive = false;
   this->field_C = 1;
-  if ( !strcmp(pName, "MICON1") )
-    SetClassLongA(hWnd, GCL_HCURSOR, (LONG)LoadCursorA(GetModuleHandleW(nullptr), "Arrow"));
-  else if ( !strcmp(pName, "MICON2") )
-    SetClassLongA(hWnd, -12, (LONG)LoadCursorA(GetModuleHandleW(nullptr), "Target"));
-  else if ( !strcmp(pName, "MICON3") )
-    SetClassLongA(hWnd, -12, (LONG)LoadCursorA(0, (LPCSTR)IDC_WAIT));
-  GetCursorPos(&Point);
-  ClientToScreen(hWnd,&Point);
-  SetCursorPos(Point.x, Point.y);
+  window->SetCursor(pName);
 }
 // 506128: using guessed type int areWeLoadingTexture;
 
@@ -118,7 +108,7 @@
   {*/
     GetCursorPos(&Point);
     if ( pRenderer->bWindowMode )
-      ScreenToClient(hWnd, &Point);
+      ScreenToClient(window->GetApiHandle(), &Point);
     result = Point.y;
     v2 = Point.x;
   //}
@@ -203,11 +193,11 @@
 }
 
 //----- (00469C65) --------------------------------------------------------
-void Mouse::Initialize(HWND hWnd)
+void Mouse::Initialize(OSWindow *window)
 {
-  this->hWnd = hWnd;
-  this->bActive = 0;
-  this->bInitialized = 1;
+  this->window = window;
+  this->bActive = false;
+  this->bInitialized = true;
   this->pCursorBitmapPos.x = 0;
   this->pCursorBitmapPos.y = 0;
   this->uMouseClickX = 0;
@@ -522,11 +512,11 @@
     y = pY;
     x = pX;
   }
-  if ( pCurrentScreen != SCREEN_GAME || !dword_507B98_ctrl_pressed )
+  if ( pCurrentScreen != SCREEN_GAME)// || !dword_507B98_ctrl_pressed ) // stealing cursor
     goto LABEL_30;
   v4 = GetCurrentMenuID();
   x = pX;
-  if ( (v4 & 0x80000000u) == 0
+  if ( v4 != 0xFFFFFFFF
     || (signed int)pX < (signed int)pViewport->uViewportTL_X
     || (signed int)pX > (signed int)pViewport->uViewportBR_X )
   {
--- a/Mouse.h	Tue Oct 01 06:19:58 2013 +0200
+++ b/Mouse.h	Mon Oct 07 11:52:33 2013 +0200
@@ -1,5 +1,5 @@
 #pragma once
-#include "OSAPI.h"
+#include "OSWindow.h"
 
 #include "VectorTypes.h"
 
@@ -46,11 +46,11 @@
 {
 public:
   //----- (00467E4E) --------------------------------------------------------
-  inline Mouse(void/*ThreadWard*/ *pWard)
+  inline Mouse():
+    window(nullptr)
   {
     uCursorTextureID = 0;
     uCursorTextureID_2 = 0;
-    hWnd = 0;
     pCursorBitmap_sysmem = 0;
     field_34 = 0;
     pCursorBitmap2_sysmem = 0;
@@ -69,7 +69,7 @@
   void AllocCursorSystemMem();
   void *DoAllocCursorMem();
   POINT *GetCursorPos(POINT *p);
-  void Initialize(HWND hWnd);
+  void Initialize(OSWindow *window);
   void SetActive(bool active);
   void Deactivate();
   void DrawCursor();
@@ -92,7 +92,8 @@
   int field_20;
   unsigned int uCursorTextureID;
   unsigned int uCursorTextureID_2;
-  HWND hWnd;
+  //HWND hWnd;
+  OSWindow *window;
   unsigned __int16 *pCursorBitmap_sysmem;
   int field_34;
   unsigned __int8 *pCursorBitmap2_sysmem;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NewUI/UIControl.h	Mon Oct 07 11:52:33 2013 +0200
@@ -0,0 +1,17 @@
+#pragma once
+
+class UIControl
+{
+  public:
+    virtual void Show() = 0;
+
+    virtual bool Focused() = 0;
+
+    // Events
+    virtual bool OnKey(int key) = 0;
+
+    virtual bool OnMouseLeftClick(int x, int y) = 0;
+    virtual bool OnMouseRightClick(int x, int y) = 0;
+    virtual bool OnMouseEnter() = 0;
+    virtual bool OnMouseLeave() = 0;
+};
\ No newline at end of file
--- a/OSAPI.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/OSAPI.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -32,7 +32,6 @@
   delete pVersion;
   pVersion = nullptr;
 
-  SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
   if (hPrevWindow)
     SetActiveWindow(hPrevWindow);
 
--- a/Render.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/Render.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -2094,16 +2094,16 @@
   hd_water_current_frame = 0;
 }
 
-bool Render::Initialize(bool bWindowed, int windowed_width, int windowed_height, uint32_t uDefaultDevice,
-                        bool bColoredLights, uint32_t uDetailLevel, bool bTinting)
+bool Render::Initialize(bool bWindowed, OSWindow *window, bool bColoredLights, uint32_t uDetailLevel, bool bTinting)
 {
-  bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0);
-
+  //bUserDirect3D = true;//ReadWindowsRegistryInt("Use D3D", 0);
+
+  this->window = window;
   bStartInWindow = bWindowed;
-  windowed_mode_width = windowed_width;
-  windowed_mode_height = windowed_height;
-
-  uDesiredDirect3DDevice = uDefaultDevice;//ReadWindowsRegistryInt("D3D Device", 1);
+  //windowed_mode_width = windowed_width;
+  //windowed_mode_height = windowed_height;
+
+  uDesiredDirect3DDevice = 0;//ReadWindowsRegistryInt("D3D Device", 1);
 
   bUseColoredLights = bColoredLights;//ReadWindowsRegistryInt("Colored Lights", 0);
   uLevelOfDetail = uDetailLevel;//ReadWindowsRegistryInt("Detail Level", 1);
@@ -2186,7 +2186,7 @@
   RECT x; // [sp+68h] [bp-10h]@3
 
   memset(&v3, 0, sizeof(DDBLTFX));
-  GetWindowRect(hWnd, &x);
+  GetWindowRect(window->GetApiHandle(), &x);
   if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
       pVersion->pVersionInfo.dwMajorVersion >= 5)
   {
@@ -2909,8 +2909,8 @@
         pRenderD3D->Present(false);
       }
     }
-    else
-    {
+    else __debugbreak(); // no sr
+    /*{
       if ( v1->bWindowMode )
       {
         RestoreFrontBuffer();
@@ -2934,7 +2934,7 @@
         a4.right = 640;
         BltBackToFontFast(0, 0, &a4);
       }
-    }
+    }*/
   }
 }
 
@@ -2979,9 +2979,9 @@
 void Render::Release()
 {
   Render *v1; // esi@1
-  RenderD3D *v2; // ecx@1
-  char v3; // zf@4
-  void *v4; // ebx@6
+  //RenderD3D *v2; // ecx@1
+  //char v3; // zf@4
+  //void *v4; // ebx@6
   IDirectDraw *v5; // eax@10
   IDirectDrawSurface2 *v6; // eax@11
   IDirectDrawSurface2 *v7; // eax@13
@@ -2996,36 +2996,34 @@
   void **v16; // esi@29
 
   v1 = this;
-  v2 = this->pRenderD3D;
-  if ( v2 )
+  if (pRenderD3D)
   {
     if ( v1->field_40110 )
     {
-      pRenderD3D->ClearTarget(1u, 0, 0, 1.0);
+      pRenderD3D->ClearTarget(true, 0, false, 1.0);
       pRenderD3D->Present(0);
-      pRenderD3D->ClearTarget(1u, 0, 0, 1.0);
+      pRenderD3D->ClearTarget(true, 0, false, 1.0);
     }
     v1->pColorKeySurface4 = 0;
     v1->pBackBuffer4 = 0;
-    v3 = v1->pTargetSurface == 0;
     v1->pFrontBuffer4 = 0;
     v1->pDirectDraw4 = 0;
-    if ( !v3 )
+    if (v1->pTargetSurface)
     {
       free(v1->ptr_400E8);
       v1->pTargetSurface = 0;
       v1->ptr_400E8 = 0;
     }
-    v4 = v1->pRenderD3D;
-    if ( v4 )
+    if (pRenderD3D)
     {
       pRenderD3D->Release();
-      free(v4);
-    }
-    v1->pRenderD3D = 0;
+      delete pRenderD3D;
+    }
+    pRenderD3D = 0;
   }
   else
-  {
+    ;//__debugbreak(); // no sr
+  /*{
     if ( bWinNT4_0 == 1 )
     {
       v5 = (IDirectDraw *)v1->pDirectDraw2;
@@ -3098,7 +3096,7 @@
       *v15 = 0;
       *v16 = 0;
     }
-  }
+  }*/
 }
 
 //----- (0049FFD7) --------------------------------------------------------
@@ -3108,7 +3106,7 @@
 }
 
 //----- (0049FFFB) --------------------------------------------------------
-bool Render::InitializeFullscreen(HWND hWnd)
+bool Render::InitializeFullscreen()
 {
   //Render *v2; // esi@1
   //HWND v3; // ebx@1
@@ -3147,10 +3145,19 @@
   this->bColorKeySupported = 0;
   Release();
   //v3 = hWnd;
-  this->hWnd = hWnd;
+  this->window = window;
   CreateZBuffer();
-  if ( bUserDirect3D )
-  {
+
+  /*if (!bUserDirect3D)
+  {
+    CreateDirectDraw();
+    SetDirectDrawCooperationMode(hWnd, 1);
+    SetDirectDrawDisplayMode(640u, 480u, 16u);
+    CreateDirectDrawPrimarySurface();
+    v15 = 1;
+  }
+  else
+  {*/
     pRenderD3D = new RenderD3D;
     v28 = pRenderD3D;
     v6 = uDesiredDirect3DDevice;
@@ -3158,14 +3165,14 @@
     v7 = pRenderD3D->pAvailableDevices;
     if ( v7[v6].bIsDeviceCompatible )
     {
-      v8 = pRenderD3D->CreateDevice(v6, 0, hWnd);
+      v8 = pRenderD3D->CreateDevice(v6, 0, window->GetApiHandle());
       uAcquiredDirect3DDevice = uDesiredDirect3DDevice;
     }
     else
     {
       if ( v7[1].bIsDeviceCompatible )
       {
-        v8 = pRenderD3D->CreateDevice(1u, 0, hWnd);
+        v8 = pRenderD3D->CreateDevice(1u, 0, window->GetApiHandle());
         uAcquiredDirect3DDevice = 1;
       }
       else
@@ -3173,7 +3180,7 @@
         if ( !v7->bIsDeviceCompatible )
           Error("There aren't any D3D devices to create.");
 
-        v8 = pRenderD3D->CreateDevice(0, 0, hWnd);
+        v8 = pRenderD3D->CreateDevice(0, 0, window->GetApiHandle());
         uAcquiredDirect3DDevice = 0;
       }
     }
@@ -3261,15 +3268,7 @@
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2u));
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0));
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u));
-  }
-  else
-  {
-    CreateDirectDraw();
-    SetDirectDrawCooperationMode(hWnd, 1);
-    SetDirectDrawDisplayMode(640u, 480u, 16u);
-    CreateDirectDrawPrimarySurface();
-    v15 = 1;
-  }
+  //}
   ddpfPrimareSuface.dwSize = 32;
   GetTargetPixelFormat(&ddpfPrimareSuface);
   ParseTargetPixelFormat();
@@ -3329,7 +3328,7 @@
 }
 
 //----- (004A05F3) --------------------------------------------------------
-bool Render::SwitchToWindow(HWND hWnd)
+bool Render::SwitchToWindow()
 {
   //Render *v2; // esi@1
   //void *v3; // eax@2
@@ -3371,8 +3370,19 @@
   pDirectDraw4 = 0;
   bColorKeySupported = 0;
   CreateZBuffer();
-  if ( bUserDirect3D )
-  {
+  /*if (!bUserDirect3D)
+  {
+    CreateDirectDraw();
+    SetDirectDrawCooperationMode(hWnd, 0);
+    field_4004C = 1;
+    CreateFrontBuffer();
+    CreateClipper(hWnd);
+    CreateBackBuffer();
+    field_40030 = 0;
+    field_18_locked_pitch = 0;
+  }
+  else
+  {*/
     /*v3 = malloc(0x148u);
     thisa = (RenderD3D *)v3;
     v29 = 0;
@@ -3388,7 +3398,7 @@
     if (pRenderD3D->pAvailableDevices[uDesiredDirect3DDevice].bIsDeviceCompatible &&
         uDesiredDirect3DDevice != 1 )
     {
-      v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, 1, hWnd);
+      v7 = pRenderD3D->CreateDevice(uDesiredDirect3DDevice, 1, window->GetApiHandle());
       uAcquiredDirect3DDevice = uDesiredDirect3DDevice;
     }
     else
@@ -3396,7 +3406,7 @@
       if ( !pRenderD3D->pAvailableDevices[0].bIsDeviceCompatible )
         Error("There aren't any D3D devices to init.");
 
-      v7 = pRenderD3D->CreateDevice(0, 1, hWnd);
+      v7 = pRenderD3D->CreateDevice(0, 1, window->GetApiHandle());
       uAcquiredDirect3DDevice = 0;
     }
     if ( !v7 )
@@ -3480,18 +3490,8 @@
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, 2u));
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, 0));
     ErrD3D(pRenderD3D->pDevice->SetTextureStageState(0, D3DTSS_COLOROP, 4u));
-  }
-  else
-  {
-    CreateDirectDraw();
-    SetDirectDrawCooperationMode(hWnd, 0);
-    field_4004C = 1;
-    CreateFrontBuffer();
-    CreateClipper(hWnd);
-    CreateBackBuffer();
-    field_40030 = 0;
-    field_18_locked_pitch = 0;
-  }
+  //}
+
   ddpfPrimareSuface.dwSize = 32;
   GetTargetPixelFormat(&ddpfPrimareSuface);
   ParseTargetPixelFormat();
@@ -3523,7 +3523,7 @@
     field_40110 = 1;
 LABEL_47:
     bWindowMode = 1;
-    hWnd = hWnd;
+    //hWnd = hWnd;
     return 0;
   }
   pTargetSurface = 0;
@@ -3997,7 +3997,8 @@
   pDirectDraw2 = nullptr;
   pDirectDraw4 = nullptr;
 
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
     ErrD3D(lpDD->QueryInterface(IID_IDirectDraw4, (void **)&pDirectDraw4));
   else
     ErrD3D(lpDD->QueryInterface(IID_IDirectDraw2, (void **)&pDirectDraw2));
@@ -4018,7 +4019,8 @@
   flags = bFullscreen ? DDSCL_NORMAL | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN :
                         DDSCL_NORMAL;
 
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
     ErrD3D(pDirectDraw4->SetCooperativeLevel(hWnd, flags | DDSCL_MULTITHREADED));
   else
     ErrD3D(pDirectDraw2->SetCooperativeLevel(hWnd, flags));
@@ -4027,7 +4029,8 @@
 //----- (004A11C6) --------------------------------------------------------
 void Render::SetDirectDrawDisplayMode(unsigned int uWidth, unsigned int uHeight, unsigned int uBPP)
 {
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
     ErrD3D(pDirectDraw4->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0));
   else
     ErrD3D(pDirectDraw2->SetDisplayMode(uWidth, uHeight, uBPP, 0, 0));
@@ -4046,7 +4049,8 @@
   DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3
 
   v1 = this;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
   {
     memset(&a2, 0, 0x7Cu);
     pDD = (IDirectDraw *)v1->pDirectDraw4;
@@ -4086,7 +4090,8 @@
   DDSURFACEDESC2 a2; // [sp+4h] [bp-80h]@3
 
   v1 = this;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
   {
     memset(&a2, 0, 0x7Cu);
     v2 = (IDirectDraw *)v1->pDirectDraw4;
@@ -4140,7 +4145,8 @@
   int a4; // [sp+98h] [bp-8h]@3
 
   v1 = this;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
   {
     v2 = 0;
     this->field_4004C = 1;
@@ -4191,7 +4197,8 @@
 //----- (004A14F4) --------------------------------------------------------
 void Render::CreateClipper(HWND a2)
 {
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
   {
     ErrD3D(pDirectDraw4->CreateClipper(0, &pDDrawClipper, 0));
     ErrD3D(pDDrawClipper->SetHWnd(0, a2));
@@ -4209,7 +4216,8 @@
 {
   IDirectDrawSurface *v2; // eax@3
 
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
     v2 = (IDirectDrawSurface *)this->pFrontBuffer4;
   else
     v2 = (IDirectDrawSurface *)this->pFrontBuffer2;
@@ -4223,7 +4231,8 @@
   signed int v4; // eax@3
 
   v3 = this;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
   {
   DDSURFACEDESC2 pDesc; // [sp+4h] [bp-7Ch]@3
     memset(&pDesc, 0, 0x7Cu);
@@ -4244,16 +4253,11 @@
   *pOutPixelsPerRow = v4 >> 1;
 }
 
-//----- (004A169E) --------------------------------------------------------
-bool Render::UsingDirect3D()
-{
-  return bUserDirect3D == 0;
-}
-
 //----- (004A16E1) --------------------------------------------------------
 void Render::UnlockBackBuffer()
 {
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion != 4 )
     ErrD3D(pBackBuffer4->Unlock(0));
   else
     ErrD3D(pBackBuffer2->Unlock(0));
@@ -8316,17 +8320,19 @@
     }
     if ( pRenderer->bWindowMode )
     {
-      SetMenu(hWnd, 0);
-      SetWindowLongA(hWnd, -20, 0);
-      SetWindowLongA(hWnd, -16, 0x10000000u);
-      pRenderer->InitializeFullscreen(hWnd);
+      //SetMenu(hWnd, 0);
+      //SetWindowLongA(hWnd, -20, 0);
+      //SetWindowLongA(hWnd, -16, 0x10000000u);
+      window->SetFullscreenMode();
+      pRenderer->InitializeFullscreen();
       v0 = (double)(signed int)uGammaPos * 0.1 + 0.6;
       pGame->pGammaController->Initialize(v0);
     }
     else
     {
-      ClipCursor(0);
-      pRenderer->SwitchToWindow(hWnd);
+      //ClipCursor(0);
+      window->SetWindowedMode(window->GetWidth(), window->GetHeight());
+      pRenderer->SwitchToWindow();
     }
     if ( pRenderer->pRenderD3D )
     {
@@ -8379,13 +8385,13 @@
     viewparams->bRedrawGameUI = 1;
     viewparams->InitGrayPalette();
     pMouse->SetCurrentCursorBitmap();
-    if ( pRenderer->bWindowMode )
+    /*if ( pRenderer->bWindowMode )
     {
       //MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0);
       CenterWindowAndAdjustSize(hWnd, windowed_mode_width, windowed_mode_height);
       ShowWindow(hWnd, SW_SHOWNORMAL);
-    }
-    pMouse->bActive = 1;
+    }*/
+    pMouse->bActive = true;
     if ( pVideoPlayer->AnyMovieLoaded() )
       pVideoPlayer->SelectMovieType();
     if (dword_6BE364_game_settings_1 & 0x0800 )
--- a/Render.h	Tue Oct 01 06:19:58 2013 +0200
+++ b/Render.h	Mon Oct 07 11:52:33 2013 +0200
@@ -4,7 +4,7 @@
 #include <cstdio>
 
 #include "lib\legacy_dx\d3d.h"
-#include "OSAPI.h"
+#include "OSWindow.h"
 
 #include "VectorTypes.h"
 
@@ -269,8 +269,7 @@
 
   static Render *Create() {return new Render;}
 
-  bool Initialize(bool bWindowed, int window_width, int window_height, uint32_t uDefaultDevice,
-                  bool bColoredLights, uint32_t uDetailLevel, bool bTinting);
+  bool Initialize(bool bWindowed, OSWindow *window, bool bColoredLights, uint32_t uDetailLevel, bool bTinting);
 
 
   bool IsColorKeySupported(IDirectDraw4 *);
@@ -288,8 +287,8 @@
   void CreateZBuffer();
   void Release();
   void CreateSomeTexture();
-  bool InitializeFullscreen(HWND hWnd);
-  bool SwitchToWindow(HWND hWnd);
+  bool InitializeFullscreen();
+  bool SwitchToWindow();
   char RasterLine2D(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned __int16 uColor);
   void ClearZBuffer(int a2, int a3);
   void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW);
@@ -305,7 +304,6 @@
   void CreateClipper(HWND a2);
   void GetTargetPixelFormat(DDPIXELFORMAT *pOut);
   void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow);
-  bool UsingDirect3D();
   void UnlockBackBuffer();
   void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow);
   void UnlockFrontBuffer();
@@ -373,7 +371,7 @@
   void DrawBillboardList_BLV();
 
 
-  unsigned int bUserDirect3D;
+  //unsigned int bUserDirect3D;
   unsigned int bStartInWindow;
   unsigned int uDesiredDirect3DDevice;
   unsigned int uAcquiredDirect3DDevice;
@@ -395,7 +393,8 @@
   int field_40044;
   int field_40048;
   int field_4004C;
-  HWND hWnd;
+  //HWND hWnd;
+  OSWindow *window;
   int field_40054;
   unsigned int bWindowMode;
   int field_4005C[11];
@@ -459,8 +458,8 @@
   unsigned __int16 *pCurrentlyLockedSoftSurface;
 
 
-  int windowed_mode_width;
-  int windowed_mode_height;
+  //int windowed_mode_width;
+  //int windowed_mode_height;
 };
 #pragma pack(pop)
 
--- a/UI/UIPopup.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/UI/UIPopup.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -1284,7 +1284,7 @@
     // 507B00: using guessed type int dword_507B00_spell_info_to_draw_in_popup;
 
 //----- (00416D62) --------------------------------------------------------
-void sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(Vec2_int_ *_this)
+void UI_OnMouseRightClick(Vec2_int_ *_this)
 {
   int v5; // esi@62
   GUIButton *pButton; // esi@84
@@ -1309,7 +1309,7 @@
   if ( pRenderer->bWindowMode )
   {
     GetCursorPos(&Point);
-    ScreenToClient(hWnd, &Point);
+    ScreenToClient(window->GetApiHandle(), &Point);
     if ( Point.x < 1 || Point.y < 1 || Point.x > 638 || Point.y > 478 )
     {
       back_to_game();
--- a/UI/UiGame.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/UI/UiGame.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -2178,7 +2178,7 @@
         {
           uFrameID = pParty->pHirelings[(unsigned __int8)pTmpBuf[i]].evt_B;
           v13 = 0;
-          if ( (signed int)pIconsFrameTable->uNumIcons )
+          if (pIconsFrameTable->uNumIcons)
           {
             for ( v13 = 0; v13 < pIconsFrameTable->uNumIcons; ++v13 )
             {
@@ -2247,5 +2247,5 @@
     case Condition_Eradicated:
       return ui_character_condition_severe_color;
   }
-  assert(false && "Invalid condition");
+  Error("Invalid condition (%u)", uConditionIdx);
 }
--- a/VideoPlayer.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/VideoPlayer.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -68,7 +68,7 @@
 void BinkUnlockBuffer(struct _BINKBUF *_this);
 
 //----- (004BFE2D) --------------------------------------------------------
-_BINKBUF *VideoPlayer::CreateBinkBuffer(HWND hWindow, unsigned int uWidth, unsigned int uHeight, char a4)
+_BINKBUF *VideoPlayer::CreateBinkBuffer(unsigned int uWidth, unsigned int uHeight, char a4)
 {
   __int32 v4; // edi@3
   _BINKBUF *v5; // esi@3
@@ -79,14 +79,13 @@
   DDSURFACEDESC2 v11; // [sp+Ch] [bp-108h]@7
   DDSURFACEDESC Dst; // [sp+88h] [bp-8Ch]@3
   unsigned int v13; // [sp+F4h] [bp-20h]@1
-  struct tagRECT Rect; // [sp+F8h] [bp-1Ch]@11
+  //struct tagRECT Rect; // [sp+F8h] [bp-1Ch]@11
   IDirectDrawSurface4 *v15; // [sp+108h] [bp-Ch]@7
   IDirectDrawSurface2 *a2; // [sp+10Ch] [bp-8h]@3
-  HWND hWnd; // [sp+110h] [bp-4h]@1
 
   v13 = uWidth;
-  hWnd = hWindow;
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5u )
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
+      pVersion->pVersionInfo.dwMajorVersion >= 5u )
   {
     v4 = 0;
     v15 = 0;
@@ -101,6 +100,7 @@
       v5 = new _BINKBUF_3_0_0_0;
       memset(v5, 0, sizeof(_BINKBUF_3_0_0_0));
     }
+    else __debugbreak();
 
     memset(&v11, 0, 0x7Cu);
     v11.dwSize = 124;
@@ -142,6 +142,7 @@
       v5 = new _BINKBUF_3_0_0_0;
       memset(v5, 0, sizeof(_BINKBUF_3_0_0_0));
     }
+    else __debugbreak();
 
     memset(&Dst, 0, 0x6Cu);
     Dst.dwSize = 108;
@@ -170,27 +171,29 @@
     v7 = (IDirectDrawSurface *)a2;
   }
   v5->pTargetDDrawSurface = v7;
-  v5->hWnd = hWnd;
+  v5->hWnd = window->GetApiHandle();
   v9 = a4;
   v5->field_4C = v4;
   v5->field_68 = v4;
   v5->field_5C = v4;
   v5->field_74 = v9 & 0x1F;
   v5->field_78 = 1;
-  v5->field_24 = GetSystemMetrics(v4);
-  v5->field_28 = GetSystemMetrics(SM_CYSCREEN);
+  v5->target_width = GetSystemMetrics(SM_CXSCREEN);
+  v5->target_height = GetSystemMetrics(SM_CYSCREEN);
   v5->field_2C = 16;
-  GetWindowRect(hWnd, &Rect);
-  v5->field_8 = Rect.right - Rect.left;
-  v5->field_C = Rect.bottom - Rect.top;
+
+  RECT Rect;
+  GetWindowRect(window->GetApiHandle(), &Rect);
+  v5->field_8 = window->GetWidth();
+  v5->field_C = window->GetHeight();
   v5->field_1C = Rect.left;
   v5->field_20 = Rect.top;
   Rect.left = v4;
   Rect.top = v4;
-  ClientToScreen(hWnd, (LPPOINT)&Rect);
+  ClientToScreen(window->GetApiHandle(), (POINT *)&Rect);
   v5->field_1C = Rect.left - v5->field_1C;
   v5->field_20 = Rect.top - v5->field_20;
-  GetClientRect(hWnd, &Rect);
+  GetClientRect(window->GetApiHandle(), &Rect);
   v5->field_30 = v5->field_8 - Rect.right;
   v5->field_34 = v5->field_C - Rect.bottom;
   v5->field_8 = v5->uWidth + v5->field_30;
@@ -351,7 +354,7 @@
 
 
 //----- (004BE70E) --------------------------------------------------------
-void __fastcall VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4)
+void VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4)
 {
   int v4; // ebp@1
   const char *pName; // edi@1
@@ -382,7 +385,7 @@
     {
       if ( pVideoPlayer->pBinkMovie )
       {
-        pVideoPlayer->BinkDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag);
+        pVideoPlayer->BinkDrawFrame(v4, ScreenSizeFlag);
         while ( pVideoPlayer->pBinkMovie )
         {
           if ( pVideoPlayer->bStopBeforeSchedule )
@@ -400,7 +403,7 @@
           if ( !pVideoPlayer->pBinkMovie )
             break;
           if ( !BinkWait(pVideoPlayer->pBinkMovie) && !pVideoPlayer->bStopBeforeSchedule )
-            pVideoPlayer->BinkDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag);
+            pVideoPlayer->BinkDrawFrame(v4, ScreenSizeFlag);
         }
       }
       if ( pVideoPlayer->bStopBeforeSchedule == 1 )
@@ -412,7 +415,7 @@
       {
         if ( pVideoPlayer->pSmackerMovie )
         {
-          pVideoPlayer->SmackDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag);
+          pVideoPlayer->SmackDrawFrame(v4, ScreenSizeFlag);
           while ( pVideoPlayer->pSmackerMovie )
           {
             if ( pVideoPlayer->bStopBeforeSchedule )
@@ -430,7 +433,7 @@
             if ( !pVideoPlayer->pSmackerMovie )
               break;
             if ( !SmackWait(pVideoPlayer->pSmackerMovie) && !pVideoPlayer->bStopBeforeSchedule )
-              pVideoPlayer->SmackDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag);
+              pVideoPlayer->SmackDrawFrame(v4, ScreenSizeFlag);
           }
         }
       }
@@ -475,10 +478,12 @@
 }
 
 //----- (004BE9D8) --------------------------------------------------------
-void VideoPlayer::Initialize()
+void VideoPlayer::Initialize(OSWindow *target_window)
 {
   DWORD NumberOfBytesRead; // [sp+10h] [bp-4h]@9
     
+  window = target_window;
+
   uint uBinkVersionMajor = -1,
        uBinkVersionMinor = -1;
   GetDllVersion(L"BINKW32.DLL", &uBinkVersionMajor, &uBinkVersionMinor);
@@ -524,79 +529,70 @@
 //----- (004BEB41) --------------------------------------------------------
 void VideoPlayer::Prepare()
 {
-  VideoPlayer *pVideoPlayer; // esi@1
-  IDirectDrawSurface *v2; // [sp-4h] [bp-Ch]@5
-
-  pVideoPlayer = this;
   pEventTimer->Pause();
-  pVideoPlayer->bStopBeforeSchedule = 0;
   if ( pAudioPlayer->hAILRedbook )
     AIL_redbook_pause(pAudioPlayer->hAILRedbook);
-  pVideoPlayer->field_54 = 1;
-  pVideoPlayer->hWindow = hWnd;
-  pVideoPlayer->pSmackerMovie = 0;
-  pVideoPlayer->pSmackerBuffer = 0;
-  pVideoPlayer->pBinkMovie = 0;
-  pVideoPlayer->pBinkBuffer = 0;
-  pVideoPlayer->bPlayingMovie = 0;
-  pVideoPlayer->bFirstFrame = 0;
-  pVideoPlayer->bUsingSmackerMMX = SmackUseMMX(1);
+
+  bStopBeforeSchedule = false;
+  field_54 = 1;
+  pSmackerMovie = 0;
+  pSmackerBuffer = 0;
+  pBinkMovie = 0;
+  pBinkBuffer = 0;
+  bPlayingMovie = false;
+  bFirstFrame = false;
+  bUsingSmackerMMX = SmackUseMMX(1);
   BinkSetSoundSystem(BinkOpenMiles, pAudioPlayer->hDigDriver);
-  if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5 )
-    v2 = (IDirectDrawSurface*)pRenderer->pBackBuffer4;
+  if (pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5)
+    uBinkDirectDrawSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)pRenderer->pBackBuffer4);
   else
-    v2 = (IDirectDrawSurface*)pRenderer->pBackBuffer2;
-  pVideoPlayer->uBinkDirectDrawSurfaceType = BinkDDSurfaceType(v2);
-  _flushall();
+    uBinkDirectDrawSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)pRenderer->pBackBuffer2);
 }
 
 
 //----- (004BEBD7) --------------------------------------------------------
 void VideoPlayer::Unload()
 {
-  VideoPlayer *pVideoPlayer; // esi@1
-  _BINK *pBinkMovie; // eax@1
-  _BINKBUF *pBinkBuffer; // eax@3
-  _SMACK *pSmackerMovie; // eax@5
+  //_BINK *pBinkMovie; // eax@1
+  //_BINKBUF *pBinkBuffer; // eax@3
+  //_SMACK *pSmackerMovie; // eax@5
 
-  pVideoPlayer = this;
-  pBinkMovie = this->pBinkMovie;
   if ( pBinkMovie )
   {
     BinkPause(pBinkMovie, 1);
     Sleep(300);
-    BinkClose(pVideoPlayer->pBinkMovie);
-    pVideoPlayer->pBinkMovie = 0;
+    BinkClose(pBinkMovie);
+    pBinkMovie = 0;
   }
-  pBinkBuffer = pVideoPlayer->pBinkBuffer;
+
   if ( pBinkBuffer )
   {
     pBinkBuffer->pTargetDDrawSurface->Release();
-    pVideoPlayer->pBinkBuffer->pTargetDDrawSurface = 0;
-    free(pVideoPlayer->pBinkBuffer);
-    pVideoPlayer->pBinkBuffer = 0;
+    pBinkBuffer->pTargetDDrawSurface = 0;
+    free(pBinkBuffer);
+    pBinkBuffer = 0;
   }
-  pSmackerMovie = pVideoPlayer->pSmackerMovie;
+
   if ( pSmackerMovie )
   {
     SmackSoundOnOff(pSmackerMovie, 0);
-    SmackClose(pVideoPlayer->pSmackerMovie);
-    pVideoPlayer->pSmackerMovie = 0;
+    SmackClose(pSmackerMovie);
+    pSmackerMovie = 0;
   }
-  if ( pVideoPlayer->pSmackerBuffer )
+  if ( pSmackerBuffer )
   {
-    SmackBufferClose(pVideoPlayer->pSmackerBuffer);
-    pVideoPlayer->pSmackerBuffer = 0;
+    SmackBufferClose(pSmackerBuffer);
+    pSmackerBuffer = 0;
   }
-  if ( pVideoPlayer->pSmackMovieBlit )
+  if ( pSmackMovieBlit )
   {
-    SmackBlitClose(pVideoPlayer->pSmackMovieBlit);
-    pVideoPlayer->pSmackMovieBlit = 0;
+    SmackBlitClose(pSmackMovieBlit);
+    pSmackMovieBlit = 0;
   }
-  pVideoPlayer->field_54 = 0;
-  pVideoPlayer->uMovieFormat = 0;
-  pVideoPlayer->dword_0000A0 = 0;
-  memset(pVideoPlayer->pCurrentMovieName, 0, 0x40);
+  field_54 = 0;
+  uMovieFormat = 0;
+  dword_0000A0 = 0;
+  memset(pCurrentMovieName, 0, 0x40);
   if ( pAudioPlayer->hAILRedbook && !bGameoverLoop )
     AIL_redbook_resume(pAudioPlayer->hAILRedbook);
   pEventTimer->Resume();
@@ -643,7 +639,7 @@
 
 
 //----- (004BED4F) --------------------------------------------------------
-void VideoPlayer::BinkDrawFrame(HWND hWnd, int a3, int a4)
+void VideoPlayer::BinkDrawFrame(int a3, int a4)
 {
   //VideoPlayer *v4; // esi@1
   _BINKBUF *v5; // eax@5
@@ -712,7 +708,7 @@
 
 
 //----- (004BEE6B) --------------------------------------------------------
-void VideoPlayer::SmackDrawFrame(HWND hWnd, int a3, int a4)
+void VideoPlayer::SmackDrawFrame(int a3, int a4)
 {
   VideoPlayer *v4; // esi@1
   _SMACK *v5; // eax@3
@@ -733,7 +729,7 @@
   unsigned int uPixelsPerRow; // [sp+14h] [bp-4h]@5
 
   v4 = this;
-  if ( !pRenderer->bWindowMode || GetFocus() == hWnd )
+  if ( !pRenderer->bWindowMode || window->Focused())
   {
     v5 = v4->pSmackerMovie;
     if ( v5->NewPalette )
@@ -749,7 +745,7 @@
       {
         Point.y = 0;
         Point.x = 0;
-        ClientToScreen(hWnd, &Point);
+        ClientToScreen(window->GetApiHandle(), &Point);
         v17 = -1;
         v16 = 480;
         v15 = 640;
@@ -774,7 +770,7 @@
     {
       Point.y = 0;
       Point.x = 0;
-      ClientToScreen(hWnd, &Point);
+      ClientToScreen(window->GetApiHandle(), &Point);
       v8 = SmackToBufferRect(v4->pSmackerMovie, 0);
       if ( a4 )
       {
@@ -824,9 +820,28 @@
   }
 }
 
+void VideoPlayer::_inlined_in_463149()
+{
+      if ( pSmackerMovie && !SmackWait(pSmackerMovie) )
+      {
+        pRenderer->BeginScene();
+        pMouse->DrawCursorToTarget();
+        SmackUpdatePalette();
+        pMouse->_469EA4();
+        pRenderer->EndScene();
+      }
+      else if ( pBinkMovie && !BinkWait(pBinkMovie) )
+      {
+        pRenderer->BeginScene();
+        pMouse->DrawCursorToTarget();
+        BinkUpdatePalette();
+        pMouse->_469EA4();
+        pRenderer->EndScene();
+      }
+}
 
 //----- (004BF08B) --------------------------------------------------------
-void VideoPlayer::SmackUpdatePalette(HWND hWnd)
+void VideoPlayer::SmackUpdatePalette()
 {
   VideoPlayer *v2; // esi@1
   unsigned __int16 *v3; // ebx@1
@@ -950,7 +965,7 @@
     this->uMovieFormat = 1;
     strcpy(this->pCurrentMovieName, (const char *)pMovieName);
     this->dword_0000A0 = 1;
-    this->pSmackerBuffer = (_SMACKBUF *)SmackBufferOpen(this->hWindow, 4, LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height), LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height));
+    this->pSmackerBuffer = (_SMACKBUF *)SmackBufferOpen(window->GetApiHandle(), 4, LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height), LOWORD(this->pSmackerMovie->Width), LOWORD(this->pSmackerMovie->Height));
     if ( this->pSmackerBuffer )
     {
       pRenderer->BeginScene();
@@ -986,7 +1001,7 @@
       pBinkMovie = this->pBinkMovie;
       this->dword_0000A0 = 1;
       if ( pBinkMovie )
-        this->pBinkBuffer = CreateBinkBuffer(this->hWindow, pBinkMovie->uWidth, pBinkMovie->uHeight, 0);
+        this->pBinkBuffer = CreateBinkBuffer(pBinkMovie->uWidth, pBinkMovie->uHeight, 0);
     }
     else
     {
--- a/VideoPlayer.h	Tue Oct 01 06:19:58 2013 +0200
+++ b/VideoPlayer.h	Mon Oct 07 11:52:33 2013 +0200
@@ -1,5 +1,5 @@
 #pragma once
-#include "OSAPI.h"
+#include "OSWindow.h"
 #include "Texture.h"
 
 
@@ -47,8 +47,8 @@
   int uDDrawSurfacePitch;
   int field_1C;
   int field_20;
-  int field_24;
-  int field_28;
+  int target_width;
+  int target_height;
   int field_2C;
   int field_30;
   int field_34;
@@ -123,14 +123,14 @@
 
   void PlayDeathMovie();
   unsigned int SmackCheckSurfaceFromat();
-  void Initialize();
+  void Initialize(OSWindow *window);
   void Prepare();
   void Unload();
   void FastForwardToFrame(unsigned int uFrameNum);
-  void BinkDrawFrame(HWND hWnd, int a3, int a4);
-  void BinkUpdatePalette(HWND hWnd) {}
-  void SmackDrawFrame(HWND hWnd, int a3, int a4);
-  void SmackUpdatePalette(HWND hWnd);
+  void BinkDrawFrame(int a3, int a4);
+  void BinkUpdatePalette() {}
+  void SmackDrawFrame(int a3, int a4);
+  void SmackUpdatePalette();
   _BINK *OpenBink(const char *pName);
   struct _SMACK *OpenSmack(const char *pFilename);
   void OpenHouseMovie(const char *pMovieName, unsigned int a3_1);//0x4BF28F
@@ -138,9 +138,10 @@
   void OpenGlobalMovie(const char *pFilename, unsigned int bLoop, int a4);
   void _4BF5B2();
   void SelectMovieType();//0x4BF73A
-  _BINKBUF *CreateBinkBuffer(HWND a1, unsigned int uWidth, unsigned int uHeight, char a4);
+  _BINKBUF *CreateBinkBuffer(unsigned int uWidth, unsigned int uHeight, char a4);
+  void _inlined_in_463149();
 
-  static void __fastcall MovieLoop(const char *pMovieName, int a2, int a3, int a4);
+  static void MovieLoop(const char *pMovieName, int a2, int a3, int a4);
 
 
   RGBTexture pVideoFrame;
@@ -162,7 +163,8 @@
   unsigned int bLoopPlaying;
   int field_68;
   unsigned int bStopBeforeSchedule;
-  HWND hWindow;
+  //HWND hWindow;
+  OSWindow *window;
   struct _SMACKBLIT *pSmackMovieBlit;
   HANDLE hMightVid;
   HANDLE hMagicVid;
--- a/_deleted.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/_deleted.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -13206,8 +13206,556 @@
   camera_rotation_x_int_sine   = stru_5C6E00->Sin(pGame->pIndoorCameraD3D->sRotationX);
   camera_rotation_x_int_cosine = stru_5C6E00->Cos(pGame->pIndoorCameraD3D->sRotationX);
 }
-
-
+//----- (004A169E) --------------------------------------------------------
+bool Render::UsingDirect3D()
+{
+  return bUserDirect3D == 0;
+}
+
+//----- (004637EB) --------------------------------------------------------
+int __stdcall aWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  //HANDLE v6; // eax@32
+  //HDC v10; // edi@50
+  //int v11; // esi@50
+  //signed int v13; // eax@135
+  //char v29; // dl@209
+  //bool v31; // ebx@211
+  //float v33; // ST04_4@246
+  //float v34; // ST04_4@254
+  //struct tagPAINTSTRUCT Paint; // [sp+24h] [bp-48h]@13
+  //int pXY[2]; // [sp+64h] [bp-8h]@261
+  //int a2; // [sp+7Ch] [bp+10h]@50
+
+  switch (uMsg)
+  {
+    case WM_SIZING: return 1;
+    
+    case WM_CREATE:  case WM_NCCREATE:
+    case WM_GETTEXT: case WM_SETTEXT:
+    case WM_SHOWWINDOW:
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_DESTROY:
+      SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+      PostQuitMessage(0);
+      return 0;
+
+    case WM_WINDOWPOSCHANGED:
+    {
+      if (pVideoPlayer && pVideoPlayer->AnyMovieLoaded() && pVideoPlayer->pBinkBuffer)
+        BinkBufferSetOffset(pVideoPlayer->pBinkBuffer, 0, 0);
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+    }
+
+    case WM_CHAR:
+    {
+      if (!pKeyActionMap->_459F10(wParam) && !viewparams->field_4C)
+        GUI_HandleHotkey(wParam);
+    }
+    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+
+    case WM_DEVICECHANGE:
+    {
+      if (wParam == 0x8000)          // CD or some device has been inserted - notify InsertCD dialog
+        PostMessageW(hInsertCDWindow, WM_USER + 1, 0, 0);
+      return 0;
+    }
+
+    case WM_COMMAND:
+    {
+      switch (wParam)
+      {
+        case 103:  pRenderer->SavePCXScreenshot();  return 0;
+
+        case 101:  // Quit game
+        case 40001:
+          SendMessageW(hWnd, WM_DESTROY, 0, 0);
+        return 0;
+
+
+        case 104:
+          pRenderer->ChangeBetweenWinFullscreenModes();
+          if ( pArcomageGame->bGameInProgress )
+            pArcomageGame->field_F6 = 1;
+        return 0;
+
+        //SubMenu "Party"
+        case 40007:  pParty->SetGold(pParty->uNumGold + 10000); return 0;
+        case 40008:  GivePartyExp(20000);  return 0;
+        case 40013:  pParty->SetGold(0);   return 0;
+
+        case 40059:
+          for (uint i = 0; i < 4; ++i)
+            pParty->pPlayers[i].uSkillPoints = 50;
+        return 0;
+        
+        case 40029:  pPlayers[uActiveCharacter]->SetPertified(true);  return 0;
+        case 40030:  pPlayers[uActiveCharacter]->SetWeak(true);       return 0;
+        case 40031:  pPlayers[uActiveCharacter]->SetPoison3(true);    return 0;
+        case 40032:  pPlayers[uActiveCharacter]->SetPoison2(true);    return 0;
+        case 40033:  pPlayers[uActiveCharacter]->SetPoison1(true);    return 0;
+        case 40034:  pPlayers[uActiveCharacter]->SetDisease3(true);   return 0;
+        case 40035:  pPlayers[uActiveCharacter]->SetDisease2(true);   return 0;
+        case 40036:  pPlayers[uActiveCharacter]->SetDisease1(true);   return 0;
+        case 40037:  pPlayers[uActiveCharacter]->SetCursed(true);     return 0;
+        case 40038:  pPlayers[uActiveCharacter]->SetInsane(true);     return 0;
+        case 40039:  pPlayers[uActiveCharacter]->SetDrunk(true);      return 0;
+        case 40040:  pPlayers[uActiveCharacter]->SetUnconcious(true); return 0;
+        case 40041:  pPlayers[uActiveCharacter]->SetDead(true);       return 0;
+        case 40042:  pPlayers[uActiveCharacter]->SetEradicated(true); return 0;
+        case 40043:  pPlayers[uActiveCharacter]->SetAsleep(true);     return 0;
+        case 40044:  pPlayers[uActiveCharacter]->SetAfraid(true);     return 0;
+        case 40045:  pPlayers[uActiveCharacter]->SetParalyzed(true);  return 0;
+        case 40073:  pPlayers[uActiveCharacter]->SetZombie(true);     return 0;
+
+        case 40006:  pParty->SetFood(pParty->uNumFoodRations + 20);   return 0;
+
+        case 40062:
+          pParty->alignment = PartyAlignment_Good;
+          SetUserInterface(pParty->alignment, true);
+          return 0;
+        case 40063:
+          pParty->alignment = PartyAlignment_Neutral;
+          SetUserInterface(pParty->alignment, true);
+          return 0;
+        case 40064:
+          pParty->alignment = PartyAlignment_Evil;
+          SetUserInterface(pParty->alignment, true);
+          return 0;
+
+        //SubMenu "Time"
+        case 40009:  pParty->uTimePlayed += Timer::Day;   return 0;
+        case 40010:  pParty->uTimePlayed += Timer::Week;   return 0;
+        case 40011:  pParty->uTimePlayed += Timer::Month;   return 0;
+        case 40012:  pParty->uTimePlayed += Timer::Year;   return 0;
+
+        //SubMenu "Items"
+        case 40015:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 1 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40016:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 2 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40017:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 3 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40018:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 4 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40019:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 5 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40020:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 6 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+        case 40061:
+        {
+          int pItemID = rand() % 500;
+          for ( uint i = 0; i < 500; ++i )
+          {
+            if ( pItemID + i > 499 )
+              pItemID = 0;
+            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St > 6 )
+            {
+              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
+              return 0;
+            }
+          }
+        }
+        return 0;
+
+      }
+    }
+    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_LBUTTONDOWN:
+      if (pArcomageGame->bGameInProgress)
+      {
+        pArcomageGame->stru1.field_0 = 7;
+        ArcomageGame::OnMouseClick(0, true);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      goto __handle_mouse_click;
+
+    case WM_RBUTTONDOWN:
+      if (pArcomageGame->bGameInProgress)
+      {
+        pArcomageGame->stru1.field_0 = 8;
+        ArcomageGame::OnMouseClick(1, true);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      if (pVideoPlayer->pVideoFrame.pPixels)
+        pVideoPlayer->bStopBeforeSchedule = 1;
+
+      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+      if (pGame)
+      {
+        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 0, &vis_sprite_filter_2, &vis_door_filter);
+      }
+
+      UI_OnMouseRightClick(0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+
+    case WM_LBUTTONUP:
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        back_to_game();
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      pArcomageGame->stru1.field_0 = 3;
+      ArcomageGame::OnMouseClick(0, 0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+    case WM_RBUTTONUP:
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        back_to_game();
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      pArcomageGame->stru1.field_0 = 4;
+      ArcomageGame::OnMouseClick(1, false);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_LBUTTONDBLCLK:
+      if ( pArcomageGame->bGameInProgress )
+      {
+        pArcomageGame->stru1.field_0 = 7;
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+        
+__handle_mouse_click:
+      if (pVideoPlayer->pVideoFrame.pPixels)
+        pVideoPlayer->bStopBeforeSchedule = 1;
+
+      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+      if (GetCurrentMenuID() == MENU_CREATEPARTY)
+      {
+        UI_OnKeyDown(VK_SELECT);
+      }
+
+      if (pGame)
+        pGame->PickMouse(512.0, LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_3, &vis_door_filter);
+
+      UI_OnMouseLeftClick(0);
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_RBUTTONDBLCLK:
+      if (pArcomageGame->bGameInProgress)
+      {
+        pArcomageGame->stru1.field_0 = 8;
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+
+      if (pVideoPlayer->pVideoFrame.pPixels)
+        pVideoPlayer->bStopBeforeSchedule = true;
+
+      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+
+      if (pGame)
+        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_2, &vis_door_filter);
+
+      UI_OnMouseRightClick(0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+
+    case WM_MBUTTONDOWN:
+      if (pRenderer->pRenderD3D && pGame)
+      {
+        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 1, &vis_sprite_filter_3, &vis_face_filter);
+      }
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_MOUSEMOVE:
+      if ( pArcomageGame->bGameInProgress )
+      {
+        ArcomageGame::OnMouseMove(LOWORD(lParam), HIWORD(lParam));
+        ArcomageGame::OnMouseClick(0, wParam == MK_LBUTTON);
+        ArcomageGame::OnMouseClick(1, wParam == MK_RBUTTON);
+      }
+      else
+      {
+        pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
+      }
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_SYSCOMMAND:
+      if ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER )
+        return 0;
+
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    //case WM_KEYUP:
+    //  if (wParam == VK_CONTROL)
+    //  {
+    //    dword_507B98_ctrl_pressed = 0;
+    //  }
+
+    //  return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_KEYDOWN:
+      if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
+      {
+        pKeyActionMap->_459F10(wParam);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      if ( !pArcomageGame->bGameInProgress )
+      {
+        if ( pVideoPlayer->pVideoFrame.pPixels )
+          pVideoPlayer->bStopBeforeSchedule = 1;
+        if ( wParam == VK_RETURN )
+        {
+          if ( !viewparams->field_4C )
+            UI_OnKeyDown(wParam);
+          return 0;
+        }
+        //if ( wParam == VK_CONTROL )
+        //{
+        //  dword_507B98_ctrl_pressed = 1;
+        //  return 0;
+        //}
+        if ( wParam == VK_ESCAPE )
+        {
+          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, window_SpeakInHouse != 0, 0);
+          return 0;
+        }
+        if ( wParam <= VK_HOME )
+          return 0;
+        if ( wParam > VK_DOWN )
+        {
+          if ( wParam != VK_F4 || pVideoPlayer->AnyMovieLoaded() )
+            return 0;
+          SendMessageW(hWnd, WM_COMMAND, 104, 0);
+          return 0;
+        }
+        if ( wParam >= VK_LEFT && wParam <= VK_DOWN )
+        {
+          if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
+          {
+            if ( !viewparams->field_4C )
+              UI_OnKeyDown(wParam);
+            return 0;
+          }
+        }
+        if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
+          return 0;
+      }
+
+      pArcomageGame->stru1.field_0 = 1;
+
+      set_stru1_field_8_InArcomage(MapVirtualKey(wParam, MAPVK_VK_TO_CHAR));
+      if ( wParam == 27 )
+      {
+        pArcomageGame->GameOver = 1;
+        pArcomageGame->field_F4 = 1;
+        pArcomageGame->uGameResult = 2;
+        pArcomageGame->field_B0 = -2;
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      if ( wParam != 114 )
+      {
+        if ( wParam == 115 && !pVideoPlayer->AnyMovieLoaded() )
+          SendMessage(hWnd, WM_COMMAND, 0x68u, 0);
+        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+      }
+      SendMessageW(hWnd, WM_COMMAND, 103, 0);
+      return 0;
+
+    case WM_ACTIVATEAPP:
+      if ( wParam && (GetForegroundWindow() == hWnd || GetForegroundWindow() == hInsertCDWindow) )
+      {
+        if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
+        {
+          dword_4E98BC_bApplicationActive = 1;
+          if ( pRenderer->bWindowMode )
+          {
+            HDC hDC = GetDC(hWnd);
+            int bitsPerPixel = GetDeviceCaps(hDC, BITSPIXEL);
+            int planes = GetDeviceCaps(hDC, PLANES);
+            ReleaseDC(hWnd, hDC);
+            if (bitsPerPixel != 16 || planes != 1)
+              Error(pGlobalTXT_LocalizationStrings[62]);
+          }
+          BYTE1(dword_6BE364_game_settings_1) &= 0xFEu;
+
+          if ( pArcomageGame->bGameInProgress )
+          {
+            pArcomageGame->field_F9 = 1;
+          }
+          else
+          {
+            if ( BYTE1(dword_6BE364_game_settings_1) & 2 )
+              BYTE1(dword_6BE364_game_settings_1) &= 0xFDu;
+            else
+              pEventTimer->Resume();
+            if ( BYTE1(dword_6BE364_game_settings_1) & 4 )
+              BYTE1(dword_6BE364_game_settings_1) &= 0xFBu;
+            else
+              pMiscTimer->Resume();
+
+            viewparams->bRedrawGameUI = true;
+            if ( pVideoPlayer->pSmackerMovie )
+            {
+              pRenderer->RestoreFrontBuffer();
+              pRenderer->_4A184C();
+              pVideoPlayer->_4BF5B2();
+            }
+          }
+          if ( pAudioPlayer->hAILRedbook && !bGameoverLoop && !pVideoPlayer->pSmackerMovie )
+            AIL_redbook_resume(pAudioPlayer->hAILRedbook);
+        }
+      }
+      else
+      {
+        if (!(dword_6BE364_game_settings_1 & 0x100))
+        {
+          dword_4E98BC_bApplicationActive = 0;
+          if ( (pVideoPlayer->pSmackerMovie || pVideoPlayer->pBinkMovie) && pVideoPlayer->bPlayingMovie )
+            pVideoPlayer->bStopBeforeSchedule = 1;
+
+          //if (pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1)
+          if (pRenderer->uAcquiredDirect3DDevice == 1)
+            SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
+          ClipCursor(0);
+          dword_6BE364_game_settings_1 |= 0x100u;
+          if ( pEventTimer->bPaused )
+            BYTE1(dword_6BE364_game_settings_1) |= 2u;
+          else
+            pEventTimer->Pause();
+          if ( pMiscTimer->bPaused )
+            BYTE1(dword_6BE364_game_settings_1) |= 4u;
+          else
+            pMiscTimer->Pause();
+
+          pAudioPlayer->StopChannels(-1, -1);
+          if ( pAudioPlayer->hAILRedbook )
+            AIL_redbook_pause(pAudioPlayer->hAILRedbook);
+        }
+      }
+      return 0;
+
+    case WM_SETFOCUS:
+      dword_4E98BC_bApplicationActive = 0;
+      if (pRenderer)
+      {
+        //if (pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1)
+        if (pRenderer->uAcquiredDirect3DDevice == 1)
+          SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
+      }
+      ClipCursor(0);
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_KILLFOCUS:
+      dword_4E98BC_bApplicationActive = 1;
+      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
+
+    case WM_PAINT:
+      if ( !GetUpdateRect(hWnd, 0, 0) || !dword_4E98BC_bApplicationActive && !pRenderer->bWindowMode )
+        return 0;
+      PAINTSTRUCT Paint;
+      BeginPaint(hWnd, &Paint);
+      if ( pArcomageGame->bGameInProgress )
+      {
+        pArcomageGame->field_F9 = 1;
+      }
+      else
+      {
+        //if (!pRenderer->pRenderD3D && !pRenderer->UsingDirect3D() || !AreRenderSurfacesOk())
+        if (!AreRenderSurfacesOk())
+        {
+          EndPaint(hWnd, &Paint);
+          return 0;
+        }
+      }
+      pRenderer->Present();
+      EndPaint(hWnd, &Paint);
+      return 0;
+
+    default:
+      return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+  }
+}
 
 const wchar_t *UIMessage2String(UIMessageType msg)
 {
--- a/mm7_2.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/mm7_2.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -3108,8 +3108,8 @@
   pTexture_PCX.Release();
   pTexture_PCX.Load("title.pcx", 0);
   SetCurrentMenuID(MENU_MAIN);
-  SetForegroundWindow(hWnd);
-  SendMessageW(hWnd, WM_ACTIVATEAPP, 1, 0);
+  //SetForegroundWindow(hWnd);
+  //SendMessageW(hWnd, WM_ACTIVATEAPP, 1, 0);
   while (GetCurrentMenuID() == MENU_MAIN || GetCurrentMenuID() == MENU_SAVELOAD)
   {
     POINT pt;
@@ -3213,549 +3213,6 @@
   pIcons_LOD->RemoveTexturesPackFromTextureList();
 }
 
-//----- (004637EB) --------------------------------------------------------
-int __stdcall aWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-  //HANDLE v6; // eax@32
-  //HDC v10; // edi@50
-  //int v11; // esi@50
-  //signed int v13; // eax@135
-  //char v29; // dl@209
-  //bool v31; // ebx@211
-  //float v33; // ST04_4@246
-  //float v34; // ST04_4@254
-  //struct tagPAINTSTRUCT Paint; // [sp+24h] [bp-48h]@13
-  //int pXY[2]; // [sp+64h] [bp-8h]@261
-  //int a2; // [sp+7Ch] [bp+10h]@50
-
-  switch (uMsg)
-  {
-    case WM_SIZING: return 1;
-    
-    case WM_CREATE:  case WM_NCCREATE:
-    case WM_GETTEXT: case WM_SETTEXT:
-    case WM_SHOWWINDOW:
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_DESTROY:
-      SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
-      PostQuitMessage(0);
-      return 0;
-
-    case WM_WINDOWPOSCHANGED:
-    {
-      if (pVideoPlayer && pVideoPlayer->AnyMovieLoaded() && pVideoPlayer->pBinkBuffer)
-        BinkBufferSetOffset(pVideoPlayer->pBinkBuffer, 0, 0);
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-    }
-
-    case WM_CHAR:
-    {
-      if (!pKeyActionMap->_459F10(wParam) && !viewparams->field_4C)
-        GUI_HandleHotkey(wParam);
-    }
-    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-
-    case WM_DEVICECHANGE:
-    {
-      if (wParam == 0x8000)          // CD or some device has been inserted - notify InsertCD dialog
-        PostMessageW(hInsertCDWindow, WM_USER + 1, 0, 0);
-      return 0;
-    }
-
-    case WM_COMMAND:
-    {
-      switch (wParam)
-      {
-        case 103:  pRenderer->SavePCXScreenshot();  return 0;
-
-        case 101:  // Quit game
-        case 40001:
-          SendMessageW(hWnd, WM_DESTROY, 0, 0);
-        return 0;
-
-
-        case 104:
-          pRenderer->ChangeBetweenWinFullscreenModes();
-          if ( pArcomageGame->bGameInProgress )
-            pArcomageGame->field_F6 = 1;
-        return 0;
-
-        //SubMenu "Party"
-        case 40007:  pParty->SetGold(pParty->uNumGold + 10000); return 0;
-        case 40008:  GivePartyExp(20000);  return 0;
-        case 40013:  pParty->SetGold(0);   return 0;
-
-        case 40059:
-          for (uint i = 0; i < 4; ++i)
-            pParty->pPlayers[i].uSkillPoints = 50;
-        return 0;
-        
-        case 40029:  pPlayers[uActiveCharacter]->SetPertified(true);  return 0;
-        case 40030:  pPlayers[uActiveCharacter]->SetWeak(true);       return 0;
-        case 40031:  pPlayers[uActiveCharacter]->SetPoison3(true);    return 0;
-        case 40032:  pPlayers[uActiveCharacter]->SetPoison2(true);    return 0;
-        case 40033:  pPlayers[uActiveCharacter]->SetPoison1(true);    return 0;
-        case 40034:  pPlayers[uActiveCharacter]->SetDisease3(true);   return 0;
-        case 40035:  pPlayers[uActiveCharacter]->SetDisease2(true);   return 0;
-        case 40036:  pPlayers[uActiveCharacter]->SetDisease1(true);   return 0;
-        case 40037:  pPlayers[uActiveCharacter]->SetCursed(true);     return 0;
-        case 40038:  pPlayers[uActiveCharacter]->SetInsane(true);     return 0;
-        case 40039:  pPlayers[uActiveCharacter]->SetDrunk(true);      return 0;
-        case 40040:  pPlayers[uActiveCharacter]->SetUnconcious(true); return 0;
-        case 40041:  pPlayers[uActiveCharacter]->SetDead(true);       return 0;
-        case 40042:  pPlayers[uActiveCharacter]->SetEradicated(true); return 0;
-        case 40043:  pPlayers[uActiveCharacter]->SetAsleep(true);     return 0;
-        case 40044:  pPlayers[uActiveCharacter]->SetAfraid(true);     return 0;
-        case 40045:  pPlayers[uActiveCharacter]->SetParalyzed(true);  return 0;
-        case 40073:  pPlayers[uActiveCharacter]->SetZombie(true);     return 0;
-
-        case 40006:  pParty->SetFood(pParty->uNumFoodRations + 20);   return 0;
-
-        case 40062:
-          pParty->alignment = PartyAlignment_Good;
-          SetUserInterface(pParty->alignment, true);
-          return 0;
-        case 40063:
-          pParty->alignment = PartyAlignment_Neutral;
-          SetUserInterface(pParty->alignment, true);
-          return 0;
-        case 40064:
-          pParty->alignment = PartyAlignment_Evil;
-          SetUserInterface(pParty->alignment, true);
-          return 0;
-
-        //SubMenu "Time"
-        case 40009:  pParty->uTimePlayed += Timer::Day;   return 0;
-        case 40010:  pParty->uTimePlayed += Timer::Week;   return 0;
-        case 40011:  pParty->uTimePlayed += Timer::Month;   return 0;
-        case 40012:  pParty->uTimePlayed += Timer::Year;   return 0;
-
-        //SubMenu "Items"
-        case 40015:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 1 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40016:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 2 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40017:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 3 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40018:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 4 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40019:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 5 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40020:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St == 6 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-        case 40061:
-        {
-          int pItemID = rand() % 500;
-          for ( uint i = 0; i < 500; ++i )
-          {
-            if ( pItemID + i > 499 )
-              pItemID = 0;
-            if ( pItemsTable->pItems[pItemID + i].uItemID_Rep_St > 6 )
-            {
-              pPlayers[uActiveCharacter]->AddItem(-1, pItemID + i);
-              return 0;
-            }
-          }
-        }
-        return 0;
-
-      }
-    }
-    return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_LBUTTONDOWN:
-      if (pArcomageGame->bGameInProgress)
-      {
-        pArcomageGame->stru1.field_0 = 7;
-        ArcomageGame::OnMouseClick(0, true);
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-
-      goto __handle_mouse_click;
-
-    case WM_RBUTTONDOWN:
-      if (pArcomageGame->bGameInProgress)
-      {
-        pArcomageGame->stru1.field_0 = 8;
-        ArcomageGame::OnMouseClick(1, true);
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-
-      if (pVideoPlayer->pVideoFrame.pPixels)
-        pVideoPlayer->bStopBeforeSchedule = 1;
-
-      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
-
-      if (pGame)
-      {
-        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 0, &vis_sprite_filter_2, &vis_door_filter);
-      }
-
-      sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-
-    case WM_LBUTTONUP:
-      if ( !pArcomageGame->bGameInProgress )
-      {
-        back_to_game();
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-      pArcomageGame->stru1.field_0 = 3;
-      ArcomageGame::OnMouseClick(0, 0);
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-    case WM_RBUTTONUP:
-      if ( !pArcomageGame->bGameInProgress )
-      {
-        back_to_game();
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-      pArcomageGame->stru1.field_0 = 4;
-      ArcomageGame::OnMouseClick(1, false);
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_LBUTTONDBLCLK:
-      if ( pArcomageGame->bGameInProgress )
-      {
-        pArcomageGame->stru1.field_0 = 7;
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-        
-__handle_mouse_click:
-      if (pVideoPlayer->pVideoFrame.pPixels)
-        pVideoPlayer->bStopBeforeSchedule = 1;
-
-      pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
-
-      if (GetCurrentMenuID() == MENU_CREATEPARTY)
-      {
-        UI_OnKeyDown(VK_SELECT);
-      }
-
-      if (pGame)
-        pGame->PickMouse(512.0, LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_3, &vis_door_filter);
-
-      UI_OnMouseLeftClick(0);
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_RBUTTONDBLCLK:
-      if ( !pArcomageGame->bGameInProgress )
-      {
-        if (pVideoPlayer->pVideoFrame.pPixels)
-          pVideoPlayer->bStopBeforeSchedule = 1;
-
-        pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
-
-        if (pGame)
-        {
-          pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), false, &vis_sprite_filter_2, &vis_door_filter);
-        }
-
-        sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(0);
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-
-      pArcomageGame->stru1.field_0 = 8;
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_MBUTTONDOWN:
-      if (pRenderer->pRenderD3D && pGame)
-      {
-        pGame->PickMouse(pGame->pIndoorCameraD3D->GetPickDepth(), LOWORD(lParam), HIWORD(lParam), 1, &vis_sprite_filter_3, &vis_face_filter);
-      }
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_MOUSEMOVE:
-      if ( pArcomageGame->bGameInProgress )
-      {
-        ArcomageGame::OnMouseMove(LOWORD(lParam), HIWORD(lParam));
-        ArcomageGame::OnMouseClick(0, wParam == MK_LBUTTON);
-        ArcomageGame::OnMouseClick(1, wParam == MK_RBUTTON);
-      }
-      else
-      {
-        pMouse->SetMouseClick(LOWORD(lParam), HIWORD(lParam));
-      }
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_SYSCOMMAND:
-      if ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER )
-        return 0;
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_KEYUP:
-      if (wParam == VK_CONTROL)
-      {
-        dword_507B98_ctrl_pressed = 0;
-      }
-
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_KEYDOWN:
-      if ( uGameMenuUI_CurentlySelectedKeyIdx != -1 )
-      {
-        pKeyActionMap->_459F10(wParam);
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-      if ( !pArcomageGame->bGameInProgress )
-      {
-        if ( pVideoPlayer->pVideoFrame.pPixels )
-          pVideoPlayer->bStopBeforeSchedule = 1;
-        if ( wParam == VK_RETURN )
-        {
-          if ( !viewparams->field_4C )
-            UI_OnKeyDown(wParam);
-          return 0;
-        }
-        if ( wParam == VK_CONTROL )
-        {
-          dword_507B98_ctrl_pressed = 1;
-          return 0;
-        }
-        if ( wParam == VK_ESCAPE )
-        {
-          pMessageQueue_50CBD0->AddMessage(UIMSG_Escape, window_SpeakInHouse != 0, 0);
-          return 0;
-        }
-        if ( wParam <= VK_HOME )
-          return 0;
-        if ( wParam > VK_DOWN )
-        {
-          if ( wParam != VK_F4 || pVideoPlayer->AnyMovieLoaded() )
-            return 0;
-          SendMessageW(hWnd, WM_COMMAND, 104, 0);
-          return 0;
-        }
-        if ( wParam >= VK_LEFT && wParam <= VK_DOWN )
-        {
-          if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
-          {
-            if ( !viewparams->field_4C )
-              UI_OnKeyDown(wParam);
-            return 0;
-          }
-        }
-        if ( pCurrentScreen != SCREEN_GAME && pCurrentScreen != SCREEN_MODAL_WINDOW )
-          return 0;
-      }
-
-      pArcomageGame->stru1.field_0 = 1;
-
-      set_stru1_field_8_InArcomage(MapVirtualKey(wParam, MAPVK_VK_TO_CHAR));
-      if ( wParam == 27 )
-      {
-        pArcomageGame->GameOver = 1;
-        pArcomageGame->field_F4 = 1;
-        pArcomageGame->uGameResult = 2;
-        pArcomageGame->field_B0 = -2;
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-      if ( wParam != 114 )
-      {
-        if ( wParam == 115 && !pVideoPlayer->AnyMovieLoaded() )
-          SendMessage(hWnd, WM_COMMAND, 0x68u, 0);
-        return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-      }
-      SendMessageW(hWnd, WM_COMMAND, 103, 0);
-      return 0;
-
-    case WM_ACTIVATEAPP:
-      if ( wParam && (GetForegroundWindow() == hWnd || GetForegroundWindow() == hInsertCDWindow) )
-      {
-        if ( BYTE1(dword_6BE364_game_settings_1) & 1 )
-        {
-          dword_4E98BC_bApplicationActive = 1;
-          if ( pRenderer->bWindowMode )
-          {
-            HDC hDC = GetDC(hWnd);
-            int bitsPerPixel = GetDeviceCaps(hDC, BITSPIXEL);
-            int planes = GetDeviceCaps(hDC, PLANES);
-            ReleaseDC(hWnd, hDC);
-            if (bitsPerPixel != 16 || planes != 1)
-              Error(pGlobalTXT_LocalizationStrings[62]);
-          }
-          BYTE1(dword_6BE364_game_settings_1) &= 0xFEu;
-
-          if ( pArcomageGame->bGameInProgress )
-          {
-            pArcomageGame->field_F9 = 1;
-          }
-          else
-          {
-            if ( BYTE1(dword_6BE364_game_settings_1) & 2 )
-              BYTE1(dword_6BE364_game_settings_1) &= 0xFDu;
-            else
-              pEventTimer->Resume();
-            if ( BYTE1(dword_6BE364_game_settings_1) & 4 )
-              BYTE1(dword_6BE364_game_settings_1) &= 0xFBu;
-            else
-              pMiscTimer->Resume();
-
-            viewparams->bRedrawGameUI = true;
-            if ( pVideoPlayer->pSmackerMovie )
-            {
-              pRenderer->RestoreFrontBuffer();
-              pRenderer->_4A184C();
-              pVideoPlayer->_4BF5B2();
-            }
-          }
-          if ( pAudioPlayer->hAILRedbook && !bGameoverLoop && !pVideoPlayer->pSmackerMovie )
-            AIL_redbook_resume(pAudioPlayer->hAILRedbook);
-        }
-      }
-      else
-      {
-        if (!(dword_6BE364_game_settings_1 & 0x100))
-        {
-          dword_4E98BC_bApplicationActive = 0;
-          if ( (pVideoPlayer->pSmackerMovie || pVideoPlayer->pBinkMovie) && pVideoPlayer->bPlayingMovie )
-            pVideoPlayer->bStopBeforeSchedule = 1;
-
-          if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
-            SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
-          ClipCursor(0);
-          dword_6BE364_game_settings_1 |= 0x100u;
-          if ( pEventTimer->bPaused )
-            BYTE1(dword_6BE364_game_settings_1) |= 2u;
-          else
-            pEventTimer->Pause();
-          if ( pMiscTimer->bPaused )
-            BYTE1(dword_6BE364_game_settings_1) |= 4u;
-          else
-            pMiscTimer->Pause();
-
-          pAudioPlayer->StopChannels(-1, -1);
-          if ( pAudioPlayer->hAILRedbook )
-            AIL_redbook_pause(pAudioPlayer->hAILRedbook);
-        }
-      }
-      return 0;
-
-    case WM_SETFOCUS:
-      dword_4E98BC_bApplicationActive = 0;
-      if (pRenderer)
-      {
-        if ( pRenderer->bUserDirect3D && pRenderer->uAcquiredDirect3DDevice == 1 )
-          SetWindowPos(hWnd, (HWND)0xFFFFFFFE, 0, 0, 0, 0, 0x18u);
-      }
-      ClipCursor(0);
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_KILLFOCUS:
-      dword_4E98BC_bApplicationActive = 1;
-      return DefWindowProcW(hWnd, uMsg, wParam, lParam);
-
-    case WM_PAINT:
-      if ( !GetUpdateRect(hWnd, 0, 0) || !dword_4E98BC_bApplicationActive && !pRenderer->bWindowMode )
-        return 0;
-      PAINTSTRUCT Paint;
-      BeginPaint(hWnd, &Paint);
-      if ( pArcomageGame->bGameInProgress )
-      {
-        pArcomageGame->field_F9 = 1;
-      }
-      else
-      {
-        if ( !pRenderer->pRenderD3D && !pRenderer->UsingDirect3D() || !AreRenderSurfacesOk() )
-        {
-          EndPaint(hWnd, &Paint);
-          return 0;
-        }
-      }
-      pRenderer->Present();
-      EndPaint(hWnd, &Paint);
-      return 0;
-
-    default:
-      return DefWindowProcA(hWnd, uMsg, wParam, lParam);
-  }
-}
 
 //----- (00464479) --------------------------------------------------------
 void ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows()
@@ -3812,9 +3269,9 @@
   ResetCursor_Palettes_LODs_Level_Audio_SFT_Windows();
   pGame->Deinitialize();
   pRenderer->Release2();
-  if ( !DestroyWindow(hWnd) )
-    GetLastError();
-  hWnd = 0;
+  delete window;
+  //if ( !DestroyWindow(hWnd) )
+  //  GetLastError();
   exit(exitCode);
 }
 
@@ -4274,7 +3731,7 @@
         }
     }
 
-    if (DialogBoxParamA(GetModuleHandleW(nullptr), "InsertCD", ::hWnd, (DLGPROC)InsertMM7CDDialogFunc, 0))
+    if (DialogBoxParamA(GetModuleHandleW(nullptr), "InsertCD", hWnd, (DLGPROC)InsertMM7CDDialogFunc, 0))
       continue;
     return false;
   }
@@ -4282,35 +3739,6 @@
 
 
 
-void CenterWindowAndAdjustSize(HWND hwnd, int client_width, int client_height)
-{
-  RECT rcWindow;
-  GetWindowRect(hWnd, &rcWindow);
-
-  RECT rcClient;
-  GetClientRect(hWnd, &rcClient);
-
-  int window_borders_width = (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left),
-      window_borders_height = (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
-  int window_total_width = client_width + window_borders_width,
-      window_total_height = client_height + window_borders_height;
-
-  
-  if (GetMenu(hwnd))
-    window_total_height += GetSystemMetrics(SM_CYMENU);
-
-  MoveWindow(hWnd, (GetSystemMetrics(SM_CXSCREEN) - window_total_width) / 2,
-                   (GetSystemMetrics(SM_CYSCREEN) - window_total_height) / 2,
-                   window_total_width,
-                   window_total_height, 0);
-/*
-  auto hDesktopDC = GetDC(nullptr);
-  uint uDesktopWidth = GetDeviceCaps(hDesktopDC, HORZRES);
-  uint uDesktopHeight = GetDeviceCaps(hDesktopDC, VERTRES);
-  ReleaseDC(nullptr, hDesktopDC);
-*/
-}
-
 //----- (004651F4) --------------------------------------------------------
 bool MM7_Initialize(int game_width, int game_height)
 {
@@ -4325,187 +3753,14 @@
     bCanLoadFromCD = false;
   if (bCanLoadFromCD)
   {
-    if (!FindMM7CD(hWnd, &cMM7GameCDDriveLetter))
+    if (!FindMM7CD(nullptr, &cMM7GameCDDriveLetter))
       return false;
   }
 
 
   srand(GetTickCount());
-  
-  WNDCLASSEXW wcxw;
-  {
-    wcxw.cbSize = sizeof(wcxw);
-    wcxw.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
-    wcxw.lpfnWndProc = (WNDPROC)aWinProc;
-    wcxw.cbClsExtra = 0;
-    wcxw.cbWndExtra = 0;
-    wcxw.hInstance = GetModuleHandleW(nullptr);
-    wcxw.hCursor = 0;
-    wcxw.hIcon = wcxw.hIconSm = LoadIconW(wcxw.hInstance, L"MM7_ICON");
-    wcxw.lpszMenuName = nullptr;
-    wcxw.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
-    wcxw.lpszClassName = L"M&MTrilogy";
-  }
-  if (!RegisterClassExW(&wcxw))
-  {
-    Log::Warning(L"Cannot register window class");
-    return false;
-  }
-
-  hWnd = CreateWindowExW(0, wcxw.lpszClassName, L"Might and MagicŪ VII",
-                         WS_SYSMENU | WS_GROUP | WS_DLGFRAME | WS_BORDER,
-                         0, 0,
-                         1, 1,
-                         nullptr,
-                         nullptr,
-                         wcxw.hInstance,
-                         nullptr);
-
-  HMENU menu = CreateMenu();
-  {
-    HMENU file = CreatePopupMenu();
-    AppendMenuW(menu, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)file, L"&File");
-    {
-      AppendMenuW(file, MF_ENABLED | MF_STRING, 40001, L"Exit");
-    }
-
-    HMENU debug = CreatePopupMenu();
-    AppendMenuW(menu, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug, L"&Debug");
-    {
-      HMENU debug_party = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_party, L"&Party");
-      {
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING, 40007, L"Give Gold (10 000)");
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING, 40008, L"Give Exp (20 000)");
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING, 40059, L"Give Skills (50 each)");
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING, 40013, L"Remove Gold");
-
-        HMENU debug_party_setconditions = CreatePopupMenu();
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_party_setconditions, L"Set Condition");
-        {
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40044, L"Afraid");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40043, L"Asleep");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40037, L"Curse");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40036, L"Disease1");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40035, L"Disease2");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40034, L"Disease3");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40041, L"Dead");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40039, L"Drunk");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40042, L"Eradicated");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40038, L"Insane");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40045, L"Paralyzed");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40033, L"Poison1");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40032, L"Poison2");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40031, L"Poison3");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40029, L"&Stone");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40040, L"Unconscious");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40030, L"Weak");
-          AppendMenuW(debug_party_setconditions, MF_ENABLED | MF_STRING, 40073, L"Zombie");
-        }
-
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING, 40006, L"Set Food (20)");
-
-        HMENU debug_party_alignment = CreatePopupMenu();
-        AppendMenuW(debug_party, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_party_alignment, L"Alignment");
-        {
-          AppendMenuW(debug_party_alignment, MF_ENABLED | MF_STRING, 40062, L"Good");
-          AppendMenuW(debug_party_alignment, MF_ENABLED | MF_STRING | MF_CHECKED, 40063, L"Neutral");
-          AppendMenuW(debug_party_alignment, MF_ENABLED | MF_STRING, 40064, L"Evil");
-        }
-      }
-
-      HMENU debug_time = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_time, L"&Time");
-      {
-        AppendMenuW(debug_time, MF_ENABLED | MF_STRING, 40009, L"Add 1 Day");
-        AppendMenuW(debug_time, MF_ENABLED | MF_STRING, 40010, L"Add 1 Week");
-        AppendMenuW(debug_time, MF_ENABLED | MF_STRING, 40011, L"Add 1 Month");
-        AppendMenuW(debug_time, MF_ENABLED | MF_STRING, 40012, L"Add 1 Year");
-      }
-
-      HMENU debug_items = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_items, L"&Items");
-      {
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40015, L"Generate level &1 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40016, L"Generate level &2 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40017, L"Generate level &3 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40018, L"Generate level &4 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40019, L"Generate level &5 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40020, L"Generate level &6 item");
-        AppendMenuW(debug_items, MF_ENABLED | MF_STRING, 40061, L"Generate special item");
-      }
-
-      HMENU debug_graphics = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_graphics, L"&Graphics");
-      {
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40023, L"Lighting Mode");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40024, L"Lighting Geometry");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING | MF_GRAYED, 40104, L"Lights Off");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40105, L"Colored Lights");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40025, L"Debug Lights");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40101, L"Debug Decals");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40027, L"HWID Portals");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40047, L"SWID Portals");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40051, L"OD Frustum");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40054, L"SWOD Constant Redraw");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40055, L"SWOD Lit Rasterizer");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40056, L"Party Light off");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40060, L"SWOD Nice Lighting off");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40067, L"HWOD Additive Fog Lights");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40072, L"HWID Nice Lighting");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40048, L"Wireframe");
-        AppendMenuW(debug_graphics, MF_ENABLED | MF_STRING, 40049, L"Fog");
-      }
-
-      HMENU debug_misc = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_misc, L"&Misc");
-      {
-        AppendMenuW(debug_misc, MF_ENABLED | MF_STRING, 40066, L"Object Viewcone Culling");
-        AppendMenuW(debug_misc, MF_ENABLED | MF_STRING, 40068, L"Red Tint");
-        AppendMenuW(debug_misc, MF_ENABLED | MF_STRING, 40071, L"Display Secrets");
-        AppendMenuW(debug_misc, MF_ENABLED | MF_STRING, 40102, L"Massive Bloodsplat");
-        AppendMenuW(debug_misc, MF_ENABLED | MF_STRING, 40103, L"Underwater Gravity");
-      }
-      
-      HMENU debug_eax = CreatePopupMenu();
-      AppendMenuW(debug, MF_ENABLED | MF_STRING | MF_POPUP, (UINT_PTR)debug_eax, L"EAX Environs");
-      {
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40074, L"NONE");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40075, L"GENERIC");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40076, L"PADDEDCELL");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40077, L"ROOM");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40078, L"BATHROOM");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40079, L"LIVINGROOM");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40080, L"STONEROOM");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40081, L"AUDITORIUM");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40082, L"CONCERTHALL");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40083, L"CAVE");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40084, L"ARENA");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40085, L"HANGAR");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40086, L"CARPETEDHALLWAY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40087, L"HALLWAY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40088, L"STONECORRIDOR");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40089, L"ALLEY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40090, L"FOREST");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40091, L"CITY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40092, L"MOUNTAINS");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40093, L"QUARRY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40094, L"PLAIN");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40095, L"PARKINGLOT");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40096, L"SEWERPIPE");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40097, L"UNDERWATER");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40098, L"DRUGGED");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40099, L"DIZZY");
-        AppendMenuW(debug_eax, MF_ENABLED | MF_STRING, 40100, L"PSICHOTIC");
-      }
-    }
-  }
-
-  SetMenu(hWnd, menu);
-  CenterWindowAndAdjustSize(hWnd, game_width, game_height);
-  ShowWindow(hWnd, SW_SHOWNORMAL);
-  
-  SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+
+  window = OSWindow::Create(L"Might and MagicŪ Trilogy", game_width, game_height);
 
   pRenderer = Render::Create();
   if (!pRenderer)
@@ -4516,12 +3771,12 @@
   else
   {
     bool bWindowMode = ReadWindowsRegistryInt("startinwindow", false);
-    uint uDefaultDevice = ReadWindowsRegistryInt("D3D Device", 1);
+    //uint uDefaultDevice = ReadWindowsRegistryInt("D3D Device", 1);
     bool bColoredLights = ReadWindowsRegistryInt("Colored Lights", false);
     uint uLevelOfDetail = ReadWindowsRegistryInt("Detail Level", 1);
     uint bTinting = ReadWindowsRegistryInt("Tinting", 1) != 0;
 
-    if (!pRenderer->Initialize(bWindowMode, game_width, game_height, uDefaultDevice, bColoredLights, uLevelOfDetail, bTinting))
+    if (!pRenderer->Initialize(bWindowMode, window, bColoredLights, uLevelOfDetail, bTinting))
     {
       Log::Warning(L"Render failed to initialize");
       return false;
@@ -4797,15 +4052,13 @@
                                                 // or
                                                 //   not in window
   {
-    SetMenu(hWnd, 0);
-    SetWindowLongA(hWnd, GWL_EXSTYLE, 0);
-    SetWindowLongA(hWnd, GWL_STYLE, WS_VISIBLE);
-    pRenderer->InitializeFullscreen(hWnd);
+    window->SetFullscreenMode();
+    pRenderer->InitializeFullscreen();
   }
   else
   {
-    ClipCursor(nullptr);
-    pRenderer->SwitchToWindow(hWnd);
+    window->SetWindowedMode(game_width, game_height);
+    pRenderer->SwitchToWindow();
   }
 
   uSoundVolumeMultiplier = ReadWindowsRegistryInt("soundflag", 9);
@@ -4836,10 +4089,10 @@
   dword_6BE384_2dacceloff = ReadWindowsRegistryInt("2dacceloff", 0);
 
   if (!bNoSound)
-    pAudioPlayer->Initialize(hWnd);
+    pAudioPlayer->Initialize();
 
   pVideoPlayer = new VideoPlayer();
-  pVideoPlayer->Initialize();
+  pVideoPlayer->Initialize(window);
 
   dword_6BE364_game_settings_1 |= 0x4000;
 
@@ -4869,7 +4122,7 @@
 }
 
 //----- (00465D0B) --------------------------------------------------------
-void  SecondaryInitialization()
+void SecondaryInitialization()
 {
   __int16 v4; // ax@4
   signed int v5; // esi@5
@@ -4878,7 +4131,7 @@
   ObjectDesc *v8; // eax@7
   char pContainer[32]; // [sp+10h] [bp-Ch]@9
 
-  pMouse->Initialize(hWnd);
+  pMouse->Initialize(window);
 
   pItemsTable = new ItemsTable;
   pItemsTable->Initialize();
--- a/mm7_data.cpp	Tue Oct 01 06:19:58 2013 +0200
+++ b/mm7_data.cpp	Mon Oct 07 11:52:33 2013 +0200
@@ -873,7 +873,7 @@
 
 _UNKNOWN unk_4FAA20; // weak
 char byte_4FAA24; // weak
-HWND dword_4FAA28; // idb
+//HWND dword_4FAA28; // idb
 
 
 
@@ -948,7 +948,6 @@
 std::array<char *, 9> aSpellSchoolNames;
 std::array<char *, 7> aAttributeNames;
 int dword_507B94; // weak
-int dword_507B98_ctrl_pressed; // weak
 unsigned int uActiveCharacter;
 int dword_507BF0_is_there_popup_onscreen; // weak
 int awards_scroll_bar_created; // weak
@@ -1194,7 +1193,8 @@
 float fBackwardWalkSpeedMultiplier = 1.0f; // weak
 float fTurnSpeedMultiplier = 1.0f; // weak
 float flt_6BE150_look_up_down_dangle = 1.0f; // weak
-HWND hWnd; // idb
+//HWND hWnd; // idb
+class OSWindow *window = nullptr;
 int dword_6BE340; // weak
 char pCurrentMapName[32]; // idb
 unsigned int uLevelMapStatsID;
--- a/mm7_data.h	Tue Oct 01 06:19:58 2013 +0200
+++ b/mm7_data.h	Mon Oct 07 11:52:33 2013 +0200
@@ -519,7 +519,7 @@
 
 extern _UNKNOWN unk_4FAA20; // weak
 extern char byte_4FAA24; // weak
-extern HWND dword_4FAA28; // idb
+//extern HWND dword_4FAA28; // idb
 
 
 
@@ -593,7 +593,6 @@
 extern std::array<char *, 9> aSpellSchoolNames;
 extern std::array<char *, 7> aAttributeNames;
 extern int dword_507B94; // weak
-extern int dword_507B98_ctrl_pressed; // weak
 extern unsigned int uActiveCharacter;
 extern int dword_507BF0_is_there_popup_onscreen; // weak
 extern int awards_scroll_bar_created; // weak
@@ -844,7 +843,8 @@
 //extern char pMM7WindowClassName[]; // idb
 //extern HINSTANCE hInstance; // idb
 //extern char *pCmdLine;
-extern HWND hWnd; // idb
+//extern HWND hWnd; // idb
+extern class OSWindow *window;
 extern int dword_6BE340; // weak
 extern char pCurrentMapName[32]; // idb
 extern unsigned int uLevelMapStatsID;
@@ -1074,7 +1074,7 @@
 void uGameUIFontMain_initialize();
 void uGameUIFontShadow_initialize();
 void Inventory_ItemPopupAndAlchemy();
-void sub_416D62_ShowPopupWindow_MonsterRecord_ItemInfo_etcsub_416D62(struct Vec2_int_ *_this);
+void UI_OnMouseRightClick(struct Vec2_int_ *_this);
 void UI_OnMouseLeftClick(int *pXY); // idb
 unsigned int UI_GetHealthManaAndOtherQualitiesStringColor(signed int current_pos, signed int base_pos);
 unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels);
@@ -1360,8 +1360,6 @@
 }
 //inline void __fastcall j_memset32(int a2, void *a1, unsigned int a3) {memset32(a1, a2, a3);}
 
-void CenterWindowAndAdjustSize(HWND hwnd, int client_width, int client_height);
-
 #define ErrD3D(hr) do {extern void ErrHR(HRESULT, const char *, const char *, const char *, int); ErrHR(hr, "Direct3D", __FUNCTION__, __FILE__, __LINE__);} while(0)