changeset 2544:c674d547cc7c

GUIWindow switch logic refactored into behaviour classes
author a.parshin
date Mon, 11 May 2015 09:51:04 +0200
parents b6140dfeac27
children e06a3fe9ad6e
files Build/Visual Studio 2013/World of Might and Magic.vcxproj Build/Visual Studio 2013/World of Might and Magic.vcxproj.filters Engine/Engine.cpp Engine/Events.cpp Engine/Graphics/IRender.h Engine/Graphics/Render.cpp Engine/Graphics/Render.h Engine/Graphics/RenderD3D11.cpp Engine/Graphics/RenderD3D11.h Engine/Graphics/Texture.cpp Engine/Graphics/Texture.h Engine/MMT.cpp Engine/Objects/Chest.cpp Engine/Objects/NPC.cpp Engine/Objects/Player.cpp Engine/Party.cpp Engine/Random.cpp Engine/Spells/CastSpellInfo.cpp Engine/stuff.h GUI/GUIButton.cpp GUI/GUIWindow.cpp GUI/GUIWindow.h GUI/UI/UICharacter.cpp GUI/UI/UIHouses.cpp GUI/UI/UIMainMenu.cpp GUI/UI/UIOptions.cpp GUI/UI/UIPartyCreation.cpp GUI/UI/UIPopup.cpp GUI/UI/UIRest.cpp GUI/UI/UISaveLoad.cpp GUI/UI/UIShops.cpp GUI/UI/UITransition.cpp GUI/UI/UiGame.cpp Game/Game.cpp Game/GameOver.cpp Game/MainMenu.cpp Game/MainMenu.h IO/Mouse.cpp OSWindow.cpp
diffstat 39 files changed, 1222 insertions(+), 1090 deletions(-) [+]
line wrap: on
line diff
--- a/Build/Visual Studio 2013/World of Might and Magic.vcxproj	Sun May 10 03:21:14 2015 +0200
+++ b/Build/Visual Studio 2013/World of Might and Magic.vcxproj	Mon May 11 09:51:04 2015 +0200
@@ -313,7 +313,6 @@
     <ClInclude Include="..\..\Engine\stru298.h" />
     <ClInclude Include="..\..\Engine\stru314.h" />
     <ClInclude Include="..\..\Engine\stru367.h" />
-    <ClInclude Include="..\..\Engine\stuff.h" />
     <ClInclude Include="..\..\Engine\Tables\FactionTable.h" />
     <ClInclude Include="..\..\Engine\Tables\FrameTableInc.h" />
     <ClInclude Include="..\..\Engine\Tables\IconFrameTable.h" />
--- a/Build/Visual Studio 2013/World of Might and Magic.vcxproj.filters	Sun May 10 03:21:14 2015 +0200
+++ b/Build/Visual Studio 2013/World of Might and Magic.vcxproj.filters	Mon May 11 09:51:04 2015 +0200
@@ -1146,9 +1146,6 @@
     <ClInclude Include="..\..\Engine\stru367.h">
       <Filter>Engine</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Engine\stuff.h">
-      <Filter>Engine</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Engine\texts.h">
       <Filter>Engine</Filter>
     </ClInclude>
--- a/Engine/Engine.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Engine.cpp	Mon May 11 09:51:04 2015 +0200
@@ -1059,7 +1059,7 @@
     static_assert(sizeof(PartyTimeStruct) == 0x678, "Wrong type size");
     static_assert(sizeof(Party) == 0x16238, "Wrong type size");
     static_assert(sizeof(GUIButton) == 0xBC, "Wrong type size");
-    static_assert(sizeof(GUIWindow) == 0x54, "Wrong type size");
+    //static_assert(sizeof(GUIWindow) == 0x54, "Wrong type size");
     //static_assert(sizeof(GUIProgressBar) == 0x1B8, "Wrong type size");
     static_assert(sizeof(GUIFont) == 0x1020, "Wrong type size");
     // static_assert(sizeof(stru262_TurnBased) == 0x40, "Wrong type size");
@@ -1811,8 +1811,8 @@
     Log::Warning(L"MM: entering main loop");
     while (1)
     {
-        //MainMenuWindow* main_menu_window = MainMenuWindow::Create();
-        //window->AddControl(main_menu_window);
+        MainMenuWindow *main_menu_window = MainMenuWindow::Create();
+        window->AddControl(main_menu_window);
         MainMenu_Loop();
         uGameState = GAME_STATE_PLAYING;
         while (1)
@@ -2127,7 +2127,11 @@
     v0 = uNumVisibleWindows;
     pParty->armageddon_timer = 0;
     while (v0 > 0)
-        pWindowList[pVisibleWindowsIdxs[v0--] - 1].Release();
+    {
+        pWindowList[pVisibleWindowsIdxs[v0--] - 1]->Release();
+        delete pWindowList[pVisibleWindowsIdxs[v0--] - 1];
+        pWindowList[pVisibleWindowsIdxs[v0--] - 1] = nullptr;
+    }
 }
 
 //----- (00461103) --------------------------------------------------------
@@ -3405,7 +3409,7 @@
         dword_5C3418 = a1;
         dword_5C341C = a2;
         _591094_decoration = activeLevelDecoration;
-        pGUIWindow2 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_GreetingNPC, a4, 0);
+        pGUIWindow2 = new GUIWindow_GenericDialogue(0, 0, window->GetWidth(), window->GetHeight(), a4, 0);
         pGUIWindow2->CreateButton(61, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
         pGUIWindow2->CreateButton(177, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
         pGUIWindow2->CreateButton(292, 424, 31, 40, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
--- a/Engine/Events.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Events.cpp	Mon May 11 09:51:04 2015 +0200
@@ -582,7 +582,7 @@
                   if ( EnterHouse(HOUSE_DARK_GUILD_PIT) )
                   {
                     pAudioPlayer->StopChannels(-1, -1);
-                    window_SpeakInHouse = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_HouseInterior, 170, 0);
+                    window_SpeakInHouse = new GUIWindow_House(0, 0, window->GetWidth(), window->GetHeight(), 170, 0);
                     window_SpeakInHouse->CreateButton( 61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1',  "", 0);
                     window_SpeakInHouse->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2',  "", 0);
                     window_SpeakInHouse->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3',  "", 0);
@@ -650,7 +650,7 @@
             if ( EnterHouse(HOUSE_BODY_GUILD_ERATHIA) )
               {
               pAudioPlayer->PlaySound(SOUND_Invalid, 0, 0, -1, 0, 0, 0, 0);
-              window_SpeakInHouse = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_HouseInterior, 165, 0);
+              window_SpeakInHouse = new GUIWindow_House(0, 0, window->GetWidth(), window->GetHeight(), 165, 0);
               v48 = window_SpeakInHouse->pControlsHead;
               if ( window_SpeakInHouse->pControlsHead )
                 {
@@ -1177,7 +1177,7 @@
           v104 = 187;
           if ( uCurrentHouse_Animation != 167 )
             v104 = EVT_DWORD(_evt->v5);
-          window_SpeakInHouse = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_HouseInterior, v104, 0);
+          window_SpeakInHouse = new GUIWindow_House(0, 0, window->GetWidth(), window->GetHeight(), v104, 0);
           window_SpeakInHouse->CreateButton( 61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1,  '1', "", 0);
           window_SpeakInHouse->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2,  '2', "", 0);
           window_SpeakInHouse->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3,  '3', "", 0);
--- a/Engine/Graphics/IRender.h	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/IRender.h	Mon May 11 09:51:04 2015 +0200
@@ -4,6 +4,7 @@
 #include "OSWindow.h"
 #include "RenderStruct.h"
 #include "../VectorTypes.h"
+#include "Engine/Graphics/Texture.h"
 
 struct IRender
 {
@@ -66,11 +67,11 @@
 
     virtual void SetUIClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW) = 0;
     virtual void ResetUIClipRect() = 0;
-    virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture) = 0;
+    virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, struct RGBTexture *pTexture) = 0;
 
     virtual void DrawTextureNew(float u, float v, struct Texture *) = 0;
     virtual void DrawTextureNew(float u, float v, struct RGBTexture *) = 0;
-    virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4) = 0;
+    virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, struct RGBTexture *a4) = 0;
     virtual void DrawTextureIndexed(signed int x, signed int y, struct Texture *tex) = 0;
 
     virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5) = 0;
@@ -105,7 +106,6 @@
 
     virtual void RenderTerrainD3D() = 0;
 
-    virtual void ChangeBetweenWinFullscreenModes() = 0;
     virtual bool AreRenderSurfacesOk() = 0;
     virtual bool IsGammaSupported() = 0;
 
--- a/Engine/Graphics/Render.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/Render.cpp	Mon May 11 09:51:04 2015 +0200
@@ -7810,121 +7810,6 @@
   }
 }
 
-//----- (004667E9) --------------------------------------------------------
-void Render::ChangeBetweenWinFullscreenModes()
-{
-  float v0; // ST14_4@17
-  int v4; // edx@26
-  ObjectDesc *v5; // eax@26
-  RGBTexture *v6; // esi@33
-  const char *v8; // [sp-4h] [bp-28h]@33
-//  struct tagRECT Rect; // [sp+14h] [bp-10h]@15
-
-  /*if ( !pRenderer->bWindowMode && (dword_6BE364_game_settings_1 & 2) )
-  {
-    ModalWindow(pGlobalTXT_LocalizationStrings[62], UIMSG_0);// "Might and Magic VII requires your desktop to be in 16bit (32k or 65k) Color mode in order to operate in a window."
-    return;
-  }*/
-  if ( bWindowMode || pRenderD3D->pAvailableDevices->bIsDeviceCompatible )
-  {
-    if ( pEventTimer->bPaused )
-      dword_6BE364_game_settings_1 |= GAME_SETTINGS_0800;
-    else
-      pEventTimer->Pause();
-    if ( pMiscTimer->bPaused )
-      dword_6BE364_game_settings_1 |= GAME_SETTINGS_1000;
-    else
-      pMiscTimer->Pause();
-    pMouse->bActive = 0;
-    if ( pRenderD3D )
-    {
-      pBitmaps_LOD->ReleaseHardwareTextures();
-      pSprites_LOD->ReleaseAll();
-    }
-    if ( bWindowMode )
-    {
-      //SetMenu(hWnd, 0);
-      //SetWindowLongA(hWnd, -20, 0);
-      //SetWindowLongA(hWnd, -16, 0x10000000u);
-      window->SetFullscreenMode();
-      pRenderer->InitializeFullscreen();
-    }
-    else
-    {
-      //ClipCursor(0);
-      window->SetWindowedMode(window->GetWidth(), window->GetHeight());
-      pRenderer->SwitchToWindow();
-    }
-    if ( pRenderD3D )
-    {
-      pBitmaps_LOD->_410423_move_textures_to_device();
-      pSprites_LOD->MoveSpritesToVideoMemory();
-    }
-    if (!( pPaletteManager->uNumTargetBBits == uTargetBBits
-      && pPaletteManager->uNumTargetGBits == uTargetGBits
-      && pPaletteManager->uNumTargetRBits == uTargetRBits ))
-    {
-      pPaletteManager->SetColorChannelInfo(uTargetRBits, uTargetGBits, uTargetBBits);
-      pPaletteManager->RecalculateAll();
-      pBitmaps_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits);
-      pIcons_LOD->SetupPalettes(uTargetRBits, uTargetGBits, uTargetBBits);
-      for (uint i = 0; i < pObjectList->uNumObjects; i++)
-      {
-        BYTE3(v4) = 0;
-        v5 = &pObjectList->pObjects[i];
-        *(short *)((char *)&v4 + 1) = v5->uParticleTrailColorR;
-        LOBYTE(v4) = v5->uParticleTrailColorG;
-        v5->uParticleTrailColor = v5->uParticleTrailColorB | (v4 << 8);
-      }
-      SetUserInterface(pParty->alignment, true);
-      if ( pMediaPlayer->pVideoFrame.pPixels )
-        pMediaPlayer->pVideoFrame.Load(pMediaPlayer->pVideoFrameTextureFilename, 1);
-      if ( sCurrentMenuID != MENU_CREATEPARTY )
-      {
-        if ( sCurrentMenuID == MENU_CREDITSPROC )
-          dword_A74C88 = 1; 
-      }
-      else
-      {
-        if ( sCurrentMenuID )
-        {
-          v6 = &pTexture_PCX;
-          pTexture_PCX.Release();
-          v8 = "makeme.pcx";
-        }
-        else
-        {
-          v6 = &pTexture_PCX;
-          pTexture_PCX.Release();
-          v8 = "title.pcx";
-          if ( sCurrentMenuID )
-            v8 = "lsave640.pcx";
-        }
-        v6->Load(v8, 0);
-      }
-    }
-    viewparams->bRedrawGameUI = 1;
-    viewparams->InitGrayPalette();
-    pMouse->SetCurrentCursorBitmap();
-    /*if ( pRenderer->bWindowMode )
-    {
-      //MoveWindow(hWnd, uWindowX, uWindowY, uWindowWidth, uWindowHeight, 0);
-      CenterWindowAndAdjustSize(hWnd, windowed_mode_width, windowed_mode_height);
-      ShowWindow(hWnd, SW_SHOWNORMAL);
-    }*/
-    pMouse->bActive = true;
-    if ( pMovie_Track )
-      pMediaPlayer->SelectMovieType();
-    if (dword_6BE364_game_settings_1 & GAME_SETTINGS_0800)
-      dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_0800;
-    else
-      pEventTimer->Resume();
-    if (dword_6BE364_game_settings_1 & GAME_SETTINGS_1000)
-      dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_1000;
-    else
-      pMiscTimer->Resume();
-  }
-}
 
 
 //----- (004524D8) --------------------------------------------------------
--- a/Engine/Graphics/Render.h	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/Render.h	Mon May 11 09:51:04 2015 +0200
@@ -250,11 +250,11 @@
 
   virtual void SetUIClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW);
   virtual void ResetUIClipRect();
-  virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture);
+  virtual void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, struct RGBTexture *pTexture);
 
   virtual void DrawTextureNew(float u, float v, struct Texture *);
   virtual void DrawTextureNew(float u, float v, struct RGBTexture *);
-  virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4);
+  virtual void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, struct RGBTexture *a4);
   virtual void DrawTextureIndexed(signed int x, signed int y, struct Texture *tex);
 
   virtual void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5);
@@ -295,7 +295,6 @@
   //void DrawTerrainSW(int a1, int a2, int a3, int a4);
 
   //void ExecOutdoorDrawSW();
-  virtual void ChangeBetweenWinFullscreenModes();
   virtual bool AreRenderSurfacesOk();
   virtual bool IsGammaSupported();
 
--- a/Engine/Graphics/RenderD3D11.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/RenderD3D11.cpp	Mon May 11 09:51:04 2015 +0200
@@ -78,7 +78,6 @@
 void RenderD3D11::PrepareDecorationsRenderList_ODM() {__debugbreak();}
 void RenderD3D11::DrawSpriteObjects_ODM() {__debugbreak();}
 void RenderD3D11::RenderTerrainD3D() {__debugbreak();}
-void RenderD3D11::ChangeBetweenWinFullscreenModes() {__debugbreak();}
 bool RenderD3D11::AreRenderSurfacesOk() {return true;}
 void RenderD3D11::SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height) {__debugbreak();}
 void RenderD3D11::SavePCXScreenshot() {__debugbreak();}
--- a/Engine/Graphics/RenderD3D11.h	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/RenderD3D11.h	Mon May 11 09:51:04 2015 +0200
@@ -115,7 +115,6 @@
 
   virtual void RenderTerrainD3D();
 
-  virtual void ChangeBetweenWinFullscreenModes();
   virtual bool AreRenderSurfacesOk();
   virtual bool IsGammaSupported();
 
--- a/Engine/Graphics/Texture.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/Texture.cpp	Mon May 11 09:51:04 2015 +0200
@@ -74,7 +74,6 @@
 
 
 RGBTexture stru_506E40; // weak
-RGBTexture pTexture_PCX;
 
 
 int uTextureID_RestUI_restb4; // weak
--- a/Engine/Graphics/Texture.h	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Graphics/Texture.h	Mon May 11 09:51:04 2015 +0200
@@ -174,7 +174,6 @@
 
 
 extern RGBTexture stru_506E40; // weak
-extern RGBTexture pTexture_PCX;
 
 
 extern int uTextureID_RestUI_restb4; // weak
@@ -261,11 +260,11 @@
 extern unsigned int uTextureID_right_panel; // weak
 
 
-extern RGBTexture *pTexture_StatusBar;
-extern RGBTexture *pTexture_LeftFrame;
-extern RGBTexture *pTexture_TopFrame;
-extern RGBTexture *pTexture_BottomFrame;
-extern RGBTexture *pTexture_RightFrame;
+extern struct RGBTexture *pTexture_StatusBar;
+extern struct RGBTexture *pTexture_LeftFrame;
+extern struct RGBTexture *pTexture_TopFrame;
+extern struct RGBTexture *pTexture_BottomFrame;
+extern struct RGBTexture *pTexture_RightFrame;
 
 
 extern unsigned int uTextureID_right_panel_loop; // weak
@@ -320,7 +319,7 @@
 extern struct Texture pTex_F7CE30;
 
 
-extern RGBTexture stru_5773C4; // idb
+extern struct RGBTexture stru_5773C4; // idb
 
 extern struct stru355 stru_4E82A4;// = {0x20, 0x41, 0, 0x20, 0xFF0000, 0xFF00, 0xFF, 0xFF000000};  moved to texture.h
 extern struct stru355 stru_4EFCBC;// = {0x20, 0x41, 0, 0x10, 0x7C00, 0x3E0, 0x1F, 0x8000};  moved to texture.h
--- a/Engine/MMT.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/MMT.cpp	Mon May 11 09:51:04 2015 +0200
@@ -17,6 +17,8 @@
 #include "lib/libpng/png.h"
 #include "Media/Video/Bink_Smacker.h"
 
+#include "Game/MainMenu.h"
+
 bool FileExists(const char *fname)
 {
     return access(fname, 0) != -1;
@@ -230,7 +232,7 @@
 
   //Create new window
   //WINDOW_MainMenu included in GUIWindow.h
-  pWindow_MMT_MainMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+  pWindow_MMT_MainMenu = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
 
   //load buttons
   //Texture* MMT_MM6      = pIcons_LOD->LoadTexturePtr("title_new", TEXTURE_16BIT_PALETTE);
@@ -249,10 +251,10 @@
   pMMT_MainMenu_BtnContinue = pWindow_MMT_MainMenu->CreateButton((window->GetWidth() / 4) - 100,                 window->GetHeight() - ((window->GetHeight() / 4) + 50), MMT_Continue->uTextureWidth, MMT_Continue->uTextureHeight, 1, 0, UIMSG_MMT_MainMenu_Continue, 3, 0, "", MMT_Continue, 0);
   pMMT_MainMenu_BtnExit     = pWindow_MMT_MainMenu->CreateButton(window->GetWidth() - 130,                       window->GetHeight() - 35,                               MMT_Exit->uTextureWidth,     MMT_Exit->uTextureHeight,     1, 0, UIMSG_ExitToWindows,         4, 0, "", MMT_Exit, 0);
 
-  pTexture_PCX.Release();
+  main_menu_background.Release();
 
   sprintf(pContainerName, "data\\New_Icons/%s", "MMTTITLE.pcx");
-  if (pTexture_PCX.LoadPCXFile(pContainerName, 0) == 1)
+  if (main_menu_background.LoadPCXFile(pContainerName, 0) == 1)
 	Error("File not found: %s", pContainerName);
 
   SetCurrentMenuID(MENU_MMT_MAIN_MENU);
@@ -278,7 +280,7 @@
     }
 
       pRenderer->BeginScene();
-      pRenderer->DrawTextureRGB(0, 0, &pTexture_PCX);
+      pRenderer->DrawTextureRGB(0, 0, &main_menu_background);
 
       MMT_MenuMessageProc();//for ÌÌÒ menu
       GUI_UpdateWindows();
@@ -335,7 +337,7 @@
   pRenderer->Present();
 
   //remove resource
-  pTexture_PCX.Release();
+  main_menu_background.Release();
   if ( pGUIWindow2 )
   {
     pGUIWindow2->Release();
@@ -384,7 +386,8 @@
           pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0, 0, 0);//temporarily
           break;
         case UIMSG_ExitToWindows:
-          GUIWindow::Create(495, 337, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnExit, 0);
+            extern GUIButton *pMainMenu_BtnExit;
+            new OnButtonClick2(495, 337, 0, 0, (int)pMainMenu_BtnExit, 0);
           SetCurrentMenuID(MENU_EXIT_GAME);
 
         default:
--- a/Engine/Objects/Chest.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Objects/Chest.cpp	Mon May 11 09:51:04 2015 +0200
@@ -185,7 +185,7 @@
       pPlayers[uActiveCharacter]->PlaySound(SPEECH_4, 0);
   }
   OpenedTelekinesis = false;
-  pChestWindow = pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Chest, uChestID, 0);
+  pChestWindow = pGUIWindow_CurrentMenu = new GUIWindow_Chest(0, 0, window->GetWidth(), window->GetHeight(), uChestID, 0);
   pBtn_ExitCancel = pChestWindow->CreateButton(471, 445, 169,  35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], pIcons_LOD->GetTexture(uExitCancelTextureId), 0);// Exit
                     pChestWindow->CreateButton(  7,   8, 460, 343, 1, 0, UIMSG_CHEST_ClickItem, 0, 0, "", 0);
   current_screen_type = SCREEN_CHEST;
--- a/Engine/Objects/NPC.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Objects/NPC.cpp	Mon May 11 09:51:04 2015 +0200
@@ -1319,14 +1319,14 @@
 }
 //----- (004B40E6) --------------------------------------------------------
 void NPCHireableDialogPrepare()
-    {
+{
   signed int v0; // ebx@1
   NPCData *v1; // edi@1
 
   v0 = 0;
   v1 = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0) )];//- 1
   pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 0, 0);
+  pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 350, 0, 0);
   pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 0x1BDu,  0xA9u,   0x23u,  1,  0,  UIMSG_Escape,  0,   0,
                  pGlobalTXT_LocalizationStrings[34], //"Cancel"
                  pIcons_LOD->GetTexture(uExitCancelTextureId),
@@ -1363,7 +1363,7 @@
   if ( _this + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
   {
     pDialogueWindow->Release();
-    pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+    pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S], pMapStats->pInfos[uHouse_ExitPic].pName);
     pBtn_ExitCancel = pDialogueWindow->CreateButton(566, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 'N', pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);// "Cancel"
     pBtn_YES        = pDialogueWindow->CreateButton(486, 445, 75, 33, 1, 0, UIMSG_BF,     1, 'Y', sHouseName.data(), pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
@@ -1382,7 +1382,7 @@
       for ( i = 0; i < uNumDialogueNPCPortraits; ++i )
         HouseNPCPortraitsButtonsList[i]->Release();
     }
-    pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 0, 0);
+    pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 345, 0, 0);
     pBtn_ExitCancel = pDialogueWindow->CreateButton(  471,  445,  169, 35,  1,   0, UIMSG_Escape,  0,  0,
                    pGlobalTXT_LocalizationStrings[74],// "End Conversation"
                    pIcons_LOD->GetTexture(uExitCancelTextureId),   0);
--- a/Engine/Objects/Player.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Objects/Player.cpp	Mon May 11 09:51:04 2015 +0200
@@ -7591,7 +7591,7 @@
   unsigned int pX; // [sp+40h] [bp-8h]@2
   CastSpellInfo *pSpellInfo;
 
-  if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )
+  if (current_character_screen_window == WINDOW_CharacterWindow_Inventory)
   {
     pMouse->GetClickPos(&pX, &pY);
     inventoryYCoord = (pY - 17) / 32;
--- a/Engine/Party.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Party.cpp	Mon May 11 09:51:04 2015 +0200
@@ -540,7 +540,7 @@
     pPartyBuffs[i].Reset();
 
 
-  pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 100;  // default character ui - stats
+  current_character_screen_window = WINDOW_CharacterWindow_Stats;  // default character ui - stats
   uFlags = 0;
   memset(_autonote_bits, 0, sizeof(_autonote_bits));
   memset(_quest_bits, 0, sizeof(_quest_bits));
--- a/Engine/Random.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Random.cpp	Mon May 11 09:51:04 2015 +0200
@@ -11,7 +11,7 @@
 
 
 
-struct Random *pRnd=new Random(); // idb
+struct Random *pRnd = new Random();
 
 
 
--- a/Engine/Spells/CastSpellInfo.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Engine/Spells/CastSpellInfo.cpp	Mon May 11 09:51:04 2015 +0200
@@ -3503,7 +3503,7 @@
       {
         if ( pGUIWindow_Settings )
           return;
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pGUIWindow_Settings->CreateButton(52, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 0, 49, "", 0);
         pGUIWindow_Settings->CreateButton(165, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 1, 50, "", 0);
         pGUIWindow_Settings->CreateButton(280, 422, 35, 0, 2, 0, UIMSG_CastSpell_Character_Big_Improvement, 2, 51, "", 0);
@@ -3516,7 +3516,7 @@
         if ( pGUIWindow_Settings )
           return;
 
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Shoot_Monster, 0, 0, "", 0);
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
@@ -3526,7 +3526,7 @@
         if ( pGUIWindow_Settings )
           return;
 
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pGUIWindow_Settings->CreateButton(game_viewport_x, game_viewport_y, game_viewport_width, game_viewport_height, 1, 0, UIMSG_CastSpell_Telekinesis, 0, 0, "", 0);
         pParty->sub_421B2C_PlaceInInventory_or_DropPickedItem();
         return;
@@ -3548,7 +3548,7 @@
       {
         if ( pGUIWindow_Settings )
           return;
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+        pGUIWindow_Settings = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pGUIWindow_Settings->CreateButton(0x34u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 0, 0x31u, "", 0);
         pGUIWindow_Settings->CreateButton(0xA5u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 1, 0x32u, "", 0);
         pGUIWindow_Settings->CreateButton(0x118u, 0x1A6u, 0x23u, 0, 2, 0, UIMSG_CastSpell_Character_Small_Improvement, 2, 0x33u, "", 0);
@@ -3558,7 +3558,7 @@
       }
       if ( HIBYTE(a5) & 2 && !pGUIWindow_Settings )
       {
-        pGUIWindow_Settings = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell, (int)&pCastSpellInfo[result], 0);
+          pGUIWindow_Settings = new OnCastTargetedSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)&pCastSpellInfo[result], 0);
         pBtn_NPCLeft = pGUIWindow_Settings->CreateButton(469, 178,
                        pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureWidth,
                        pIcons_LOD->GetTexture(uTextureID_Btn_NPCLeft)->uTextureHeight,
--- a/Engine/stuff.h	Sun May 10 03:21:14 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#pragma once
-#include <windows.h>
-#include <stdio.h>
-
-
-
-inline void Assert(bool condition, const char *format, ...)
-{
-  if (condition)
-    return;
-  
-  va_list va;
-  va_start(va, format);
-    char msg[4096];
-    vsprintf(msg, format, va);
-    MessageBoxA(nullptr, msg, "Assert", 0);
-  va_end(va);
-
-  __debugbreak();
-}
-
-inline void Error(const char *format, ...)
-{
-  va_list va;
-  va_start(va, format);
-    char msg[4096];
-    vsprintf(msg, format, va);
-    MessageBoxA(nullptr, msg, "Error", 0);
-  va_end(va);
-
-  __debugbreak();
-}
-
-
-
--- a/GUI/GUIButton.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/GUIButton.cpp	Mon May 11 09:51:04 2015 +0200
@@ -72,12 +72,6 @@
 struct GUIButton *pMMT_MainMenu_BtnExit;
 
 
-struct GUIButton *pMainMenu_BtnExit;
-struct GUIButton *pMainMenu_BtnCredits;
-struct GUIButton *pMainMenu_BtnLoad;
-struct GUIButton *pMainMenu_BtnNew;
-
-
 struct GUIButton *pBtn_Up;
 struct GUIButton *pBtn_Down;
 struct GUIButton *ptr_507BA4;
@@ -241,7 +235,7 @@
 void UI_CreateEndConversationButton()
 {
   pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 0, 0);
+  pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 345, 0, 0);
   pBtn_ExitCancel = pDialogueWindow->CreateButton( 471, 445,  169, 35, 1, 0, UIMSG_Escape,  0,  0,
                  pGlobalTXT_LocalizationStrings[74],  //"End Conversation"
                  pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
--- a/GUI/GUIWindow.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/GUIWindow.cpp	Mon May 11 09:51:04 2015 +0200
@@ -61,10 +61,10 @@
     {0x96, 0xD4, 0xFF}}};
 
 
-int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[1]; // idb
+enum WindowType current_character_screen_window;
 struct GUIWindow *pWindow_MMT_MainMenu;
 struct GUIWindow *pWindow_MainMenu;
-std::array<struct GUIWindow, 20> pWindowList;
+std::array<struct GUIWindow *, 20> pWindowList;
 
 struct GUIMessageQueue *pMessageQueue_50CBD0 = new GUIMessageQueue;
 struct GUIMessageQueue *pMessageQueue_50C9E8 = new GUIMessageQueue;
@@ -74,6 +74,194 @@
 
 
 
+GUIWindow_Inventory_CastSpell::GUIWindow_Inventory_CastSpell(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    pMouse->SetCursorBitmap("MICON2");
+    pBtn_ExitCancel = CreateButton(392, 318, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
+        pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[39], 2); // Choose target / Âûáðàòü öåëü
+    ++pIcons_LOD->uTexturePacksCount;
+    current_character_screen_window = WINDOW_CharacterWindow_Inventory;
+    current_screen_type = SCREEN_CASTING;
+    if (!pIcons_LOD->uNumPrevLoadedFiles)
+        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+}
+
+GUIWindow_House::GUIWindow_House(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    current_screen_type = SCREEN_HOUSE;
+    pBtn_ExitCancel = CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[80], // Quit building / Âûéòè èç çäàíèÿ
+        pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
+    for (int v26 = 0; v26 < uNumDialogueNPCPortraits; ++v26)
+    {
+        char *v29, *v30;
+        if (v26 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic)
+        {
+            v30 = pMapStats->pInfos[uHouse_ExitPic].pName;
+            v29 = (char*)pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S];
+        }
+        else
+        {
+            if (v26 || !dword_591080)
+                v30 = HouseNPCData[v26 + 1 - ((dword_591080 != 0) ? 1 : 0)]->pName;
+            else
+                v30 = (char*)p2DEvents[button - 1].pProprieterName;
+            v29 = (char*)pGlobalTXT_LocalizationStrings[435];
+        }
+        sprintfex(byte_591180[v26].data(), v29, v30);
+        HouseNPCPortraitsButtonsList[v26] = CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v26],
+            pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v26],
+            63, 73, 1, 0, UIMSG_ClickHouseNPCPortrait, v26, 0, byte_591180[v26].data(), 0, 0, 0);
+    }
+    if (uNumDialogueNPCPortraits == 1)
+    {
+        window_SpeakInHouse = this;
+        _4B4224_UpdateNPCTopics(0);
+    }
+}
+
+GUIWindow_Dialogue::GUIWindow_Dialogue(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    prev_screen_type = current_screen_type;
+    current_screen_type = SCREEN_NPC_DIALOGUE;
+    pBtn_ExitCancel = CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], //"Exit"
+        pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
+    if (par1C != 1)
+    {
+        int num_menu_buttons = 0;
+        int v11 = LOBYTE(pFontArrus->uFontHeight) - 3;
+        NPCData *speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+        if (GetGreetType(sDialogue_SpeakingActorNPC_ID) == 1)//QuestsNPC_greet
+        {
+            if (speakingNPC->joins)
+            {
+                CreateButton(480, 130, 140, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0xDu, 0, "", 0);
+                num_menu_buttons = 1;
+            }
+            if (speakingNPC->evt_A)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v14 = NPC_EventProcessor(speakingNPC->evt_A);
+                    if (v14 == 1 || v14 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x13u, 0, "", 0);
+                }
+            }
+            if (speakingNPC->evt_B)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v16 = NPC_EventProcessor(speakingNPC->evt_B);
+                    if (v16 == 1 || v16 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x14u, 0, "", 0);
+                }
+            }
+            if (speakingNPC->evt_C)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v18 = NPC_EventProcessor(speakingNPC->evt_C);
+                    if (v18 == 1 || v18 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x15u, 0, "", 0);
+                }
+            }
+            if (speakingNPC->evt_D)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v20 = NPC_EventProcessor(speakingNPC->evt_D);
+                    if (v20 == 1 || v20 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x16u, 0, "", 0);
+                }
+            }
+            if (speakingNPC->evt_E)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v22 = NPC_EventProcessor(speakingNPC->evt_E);
+                    if (v22 == 1 || v22 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x17u, 0, "", 0);
+                }
+            }
+            if (speakingNPC->evt_F)
+            {
+                if (num_menu_buttons < 4)
+                {
+                    int v24 = NPC_EventProcessor(speakingNPC->evt_F);
+                    if (v24 == 1 || v24 == 2)
+                        CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x18u, 0, "", 0);
+                }
+            }
+        }
+        else
+        {
+            if (speakingNPC->joins)
+            {
+                CreateButton(0x1E0u, 0x82u, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Du, 0, pGlobalTXT_LocalizationStrings[407], 0);//Ïîäðîáíåå
+                if (speakingNPC->Hired())
+                {
+                    sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[408], speakingNPC->pName); //Îòïóñòèòü
+                    CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pTmpBuf.data(), 0);
+                }
+                else
+                    CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
+                num_menu_buttons = 2;
+            }
+        }
+        _41D08F_set_keyboard_control_group(num_menu_buttons, 1, 0, 1);
+    }
+}
+
+GUIWindow_Travel::GUIWindow_Travel(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    prev_screen_type = current_screen_type;
+    current_screen_type = SCREEN_CHANGE_LOCATION;
+    pBtn_ExitCancel = CreateButton(566, 445, 75, 33, 1, 0, UIMSG_CHANGE_LOCATION_ClickCencelBtn, 0, 'N', pGlobalTXT_LocalizationStrings[156], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);// Stay in this area / Îñòàòüñÿ â ýòîé îáëàñòè
+    pBtn_YES = CreateButton(486, 445, 75, 33, 1, 0, UIMSG_OnTravelByFoot, 0, 'Y', hint, pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
+    CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 63, 73, 1, 0, UIMSG_OnTravelByFoot, 1, ' ', hint, 0, 0, 0);
+    CreateButton(8, 8, 460, 344, 1, 0, UIMSG_OnTravelByFoot, 1, 0, hint, 0);
+}
+
+GUIWindow_Transition::GUIWindow_Transition(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    prev_screen_type = current_screen_type;
+    current_screen_type = SCREEN_INPUT_BLV;
+    pBtn_ExitCancel = CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_TransitionWindowCloseBtn, 0, 'N', pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0); // Cancel / Îòìåíà
+    pBtn_YES = CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_TransitionUI_Confirm, 0, 'Y', hint, pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
+    CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, UIMSG_TransitionUI_Confirm, 1, 0x20u, hint, 0);
+    CreateButton(8, 8, 0x1CCu, 0x158u, 1, 0, UIMSG_TransitionUI_Confirm, 1u, 0, hint, 0);
+}
+
+GUIWindow_Spellbook::GUIWindow_Spellbook(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    InitializeBookTextures();
+    OpenSpellBook();
+}
+
+GUIWindow_GenericDialogue::GUIWindow_GenericDialogue(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    prev_screen_type = current_screen_type;
+    pKeyActionMap->EnterText(0, 15, this);
+    current_screen_type = SCREEN_BRANCHLESS_NPC_DIALOG;
+}
+
+OnCastTargetedSpell::OnCastTargetedSpell(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+    GUIWindow(x, y, width, height, button, hint)
+{
+    pEventTimer->Pause();
+    pAudioPlayer->StopChannels(-1, -1);
+    pMouse->SetCursorBitmap("MICON2");
+    ShowStatusBarString(pGlobalTXT_LocalizationStrings[39], 2u); // ChooseTarget / Âûáåðèòå öåëü
+}
+
+
 // inlined
 //----- (mm6c::00420520) --------------------------------------------------
 void GUIMessageQueue::Flush()
@@ -104,9 +292,8 @@
 }
 
 //----- (0041B4E1) --------------------------------------------------------
-int __fastcall GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall)
+void GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall)
 {
-  int result; // eax@1
   int i; // edx@2
   GUIButton *j; // ecx@3
   int k; // edx@7
@@ -116,35 +303,29 @@
 
   //v3 = uNewHotkey;
   old_hot_key = toupper(uOldHotkey);
-  result = toupper(uNewHotkey);
-  v9 = result;
+  v9 = toupper(uNewHotkey);
   if ( bFirstCall )
   {
     for ( i = uNumVisibleWindows; i >= 0; --i )
     {
-      result = 84 * pVisibleWindowsIdxs[i];
-      for ( j = pWindowList[pVisibleWindowsIdxs[i] - 1].pControlsHead; j; j = j->pNext )
+      for ( j = pWindowList[pVisibleWindowsIdxs[i] - 1]->pControlsHead; j; j = j->pNext )
         j->field_28 = 0;
     }
   }
   for ( k = uNumVisibleWindows; k >= 0; --k )
   {
-    result = 84 * pVisibleWindowsIdxs[k];
-    for ( l = pWindowList[pVisibleWindowsIdxs[k] - 1].pControlsHead; l; l = l->pNext )
+    for ( l = pWindowList[pVisibleWindowsIdxs[k] - 1]->pControlsHead; l; l = l->pNext )
     {
-      LOBYTE(result) = old_hot_key;
       if ( l->uHotkey == old_hot_key )
       {
         if ( !l->field_28 )
         {
-          LOBYTE(result) = v9;
           l->field_28 = 1;
           l->uHotkey = v9;
         }
       }
     }
   }
-  return result;
 }
 
 //----- (0041B438) --------------------------------------------------------
@@ -157,7 +338,7 @@
   Hot_key_num = toupper(uHotkey);
   for( int i = uNumVisibleWindows; i >= 0 && pVisibleWindowsIdxs[i] > 0; i-- )
   {
-	current_window = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+	current_window = pWindowList[pVisibleWindowsIdxs[i] - 1];
 	for ( result = current_window->pControlsHead; result; result = result->pNext )
 	{
 	  if ( result->uHotkey == Hot_key_num )
@@ -237,6 +418,85 @@
 }
 
 
+
+void GUIWindow_Book::Release()
+{
+    OnCloseBook();
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_Travel::Release()
+{
+    pTexture_outside->Release();
+    pTexture_Dialogue_Background->Release();
+    pIcons_LOD->SyncLoadedFilesCount();
+    current_screen_type = prev_screen_type;
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_Transition::Release()
+{
+    //pVideoPlayer->Unload();
+    pTexture_outside->Release();
+    pTexture_Dialogue_Background->Release();
+    pIcons_LOD->SyncLoadedFilesCount();
+    current_screen_type = prev_screen_type;
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_Dialogue::Release()
+{
+    if (!dword_591084)
+        pDialogueNPCPortraits[0]->Release();
+    uNumDialogueNPCPortraits = 0;
+    pTexture_Dialogue_Background->Release();
+
+    pIcons_LOD->SyncLoadedFilesCount();
+    current_screen_type = prev_screen_type;
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_Spellbook::Release()
+{
+    OnCloseSpellBookPage();
+    OnCloseSpellBook();
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_GenericDialogue::Release()
+{
+    pIcons_LOD->SyncLoadedFilesCount();
+    current_screen_type = prev_screen_type;
+    pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CANCELLED);
+
+    GUIWindow::Release();
+}
+
+void GUIWindow_House::Release()
+{
+    for (int i = 0; i < uNumDialogueNPCPortraits; ++i)
+        pDialogueNPCPortraits[i]->Release();
+    uNumDialogueNPCPortraits = 0;
+    pTexture_Dialogue_Background->Release();
+
+    pIcons_LOD->SyncLoadedFilesCount();
+    pIcons_LOD->RemoveTexturesPackFromTextureList();
+    dword_5C35D4 = 0;
+    if (bFlipOnExit)
+    {
+        pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (stru_5C6E00->uIntegerPi + pParty->sRotationY);
+        pIndoorCameraD3D->sRotationY = pParty->sRotationY;
+    }
+    pParty->uFlags |= 2u;
+
+    GUIWindow::Release();
+}
+
 //----- (0041C26A) --------------------------------------------------------
 void GUIWindow::Release()
 {
@@ -251,78 +511,7 @@
   //v1 = this;
   if ( !this )
     return;
-  
-  switch( this->eWindowType )
-  {
-	case WINDOW_GreetingNPC:
-		{
-		pIcons_LOD->SyncLoadedFilesCount();
-		current_screen_type = prev_screen_type;
-		pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CANCELLED);
-		break;
-		}
-	case WINDOW_HouseInterior:
-		{
-		for ( i = 0; i < uNumDialogueNPCPortraits; ++i )
-			pDialogueNPCPortraits[i]->Release();
-		uNumDialogueNPCPortraits = 0;
-		pTexture_Dialogue_Background->Release();
 
-		pIcons_LOD->SyncLoadedFilesCount();
-		pIcons_LOD->RemoveTexturesPackFromTextureList();
-		dword_5C35D4 = 0;
-		if ( bFlipOnExit )
-		{
-          pParty->sRotationY = (stru_5C6E00->uIntegerDoublePi - 1) & (stru_5C6E00->uIntegerPi + pParty->sRotationY);
-          pIndoorCameraD3D->sRotationY = pParty->sRotationY;
-		}
-		pParty->uFlags |= 2u;
-		break;
-		}
-	case WINDOW_Transition:
-		{
-		//pVideoPlayer->Unload();
-		pTexture_outside->Release();
-		pTexture_Dialogue_Background->Release();
-		pIcons_LOD->SyncLoadedFilesCount();
-		current_screen_type = prev_screen_type;
-		break;
-		}
-	case WINDOW_SpellBook:
-		{
-		OnCloseSpellBookPage();
-		OnCloseSpellBook();
-		break;
-		}
-	case WINDOW_Book:
-		{
-		OnCloseBook();
-		break;
-		}
-      case WINDOW_ChangeLocation:
-      {
-        pTexture_outside->Release();
-        pTexture_Dialogue_Background->Release();
-        pIcons_LOD->SyncLoadedFilesCount();
-        current_screen_type = prev_screen_type;
-        break;
-		}
-	case WINDOW_Dialogue:
-		{
-        if ( !dword_591084 )
-	        pDialogueNPCPortraits[0]->Release();
-        uNumDialogueNPCPortraits = 0;
-        pTexture_Dialogue_Background->Release();
-
-        pIcons_LOD->SyncLoadedFilesCount();
-        current_screen_type = prev_screen_type;
-        break;
-		}
-  case WINDOW_null:
-    return;
-	default:
-		break;
-  }
   //v8 = this->pControlsHead;
   if ( this->pControlsHead )
   {
@@ -342,7 +531,7 @@
   {
     v12 = pVisibleWindowsIdxs[this->numVisibleWindows + 1];
     pVisibleWindowsIdxs[this->numVisibleWindows] = v12;
-    --pWindowList[v12 - 1].numVisibleWindows;
+    --pWindowList[v12 - 1]->numVisibleWindows;
     ++this->numVisibleWindows;
   }
   pVisibleWindowsIdxs[uNumVisibleWindows] = 0;
@@ -1380,262 +1569,68 @@
     DrawText(a2, uX, uY, 0, "_", 0, 0, 0);
 }
 
-//----- (0041C432) --------------------------------------------------------
-GUIWindow * GUIWindow::Create( unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, enum WindowType eWindowType, int pButton, const char* hint )
-{
-  unsigned int uNextFreeWindowID; // ebp@1
-  //int *v8; // eax@1
-  //GUIWindow *pWindow; // esi@4
-  //int v10; // eax@4
-  unsigned int v11; // ebx@15
-  NPCData *speakingNPC; // ebp@15
-  int v14; // eax@20
-  int v16; // eax@25
-  int v18; // eax@30
-  int v20; // eax@35
-  int v22; // eax@40
-  int v24; // eax@45
-//  int v25; // eax@65
-  unsigned int v26; // ebx@65
-  char *v27; // eax@71
-  const char *v29; // [sp-8h] [bp-18h]@68
-  char *v30; // [sp-4h] [bp-14h]@68
-//  int uWidtha; // [sp+14h] [bp+4h]@66
-  int num_menu_buttons; // [sp+20h] [bp+10h]@15
+
+GUIWindow::GUIWindow() :
+    uNumControls(0),
+    pControlsHead(nullptr),
+    pControlsTail(nullptr),
+    eWindowType(WINDOW_null)
+{}
 
-  for (uNextFreeWindowID = 0; uNextFreeWindowID < 20; ++uNextFreeWindowID)
-  {
-    if (pWindowList[uNextFreeWindowID].eWindowType == WINDOW_null)
-      break;
-  }
-
-  GUIWindow* pWindow = &pWindowList[uNextFreeWindowID];
-  pWindow->uFrameWidth = uWidth;
-  pWindow->uFrameHeight = uHeight;
+//----- (0041C432) --------------------------------------------------------
+GUIWindow::GUIWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, int pButton, const char* hint) :
+    uNumControls(0),
+    pControlsHead(nullptr),
+    pControlsTail(nullptr),
+    eWindowType(WINDOW_MainMenu)
+{
+    unsigned int uNextFreeWindowID; // ebp@1
+    //int *v8; // eax@1
+    //GUIWindow *pWindow; // esi@4
+    //int v10; // eax@4
+    unsigned int v11; // ebx@15
+    NPCData *speakingNPC; // ebp@15
+    int v14; // eax@20
+    int v16; // eax@25
+    int v18; // eax@30
+    int v20; // eax@35
+    int v22; // eax@40
+    int v24; // eax@45
+    //  int v25; // eax@65
+    unsigned int v26; // ebx@65
+    char *v27; // eax@71
+    const char *v29; // [sp-8h] [bp-18h]@68
+    char *v30; // [sp-4h] [bp-14h]@68
+    //  int uWidtha; // [sp+14h] [bp+4h]@66
+    int num_menu_buttons; // [sp+20h] [bp+10h]@15
 
-  pWindow->uFrameX = uX;
-  pWindow->uFrameY = uY;
-  pWindow->uFrameZ = uX + uWidth - 1;
-  pWindow->uFrameW = uY + uHeight - 1;
-
-  pWindow->ptr_1C = (void *)pButton;
-  pWindow->Hint = hint;
-  
-  pWindow->eWindowType = eWindowType;
-  pWindow->receives_keyboard_input = false;
-  ++uNumVisibleWindows;
-  pWindow->numVisibleWindows = uNumVisibleWindows;
-  pVisibleWindowsIdxs[uNumVisibleWindows] = uNextFreeWindowID + 1;
-  if ( (signed int)eWindowType <= 20 )
-  {
-    if (eWindowType != WINDOW_Chest)
+    for (uNextFreeWindowID = 0; uNextFreeWindowID < 20; ++uNextFreeWindowID)
     {
-      switch (eWindowType)
-      {
-        case WINDOW_Book: {
-          pWindow->InitializeBookView();
-          break;
-          }
-        case WINDOW_Dialogue: {
-          prev_screen_type = current_screen_type;
-          current_screen_type = SCREEN_NPC_DIALOGUE;
-          pBtn_ExitCancel = pWindow->CreateButton(0x1D7u, 0x1BDu, 0xA9u, 0x23u, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], //"Exit"
-                         pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
-          if ( pWindow->par1C != 1 )
-          {
-            num_menu_buttons = 0;
-            v11 = LOBYTE(pFontArrus->uFontHeight) - 3;
-            speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-            if ( GetGreetType(sDialogue_SpeakingActorNPC_ID) == 1 )//QuestsNPC_greet
-            {
-              if ( speakingNPC->joins )
-              {
-                pWindow->CreateButton(480, 130, 140, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0xDu, 0, "", 0);
-                num_menu_buttons = 1;
-              }
-              if ( speakingNPC->evt_A )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v14 = NPC_EventProcessor(speakingNPC->evt_A);
-                  if ( v14 == 1 || v14 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x13u, 0, "", 0);
-                }
-              }
-              if ( speakingNPC->evt_B )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v16 = NPC_EventProcessor(speakingNPC->evt_B);
-                  if ( v16 == 1 || v16 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x14u, 0, "", 0);
-                }
-              }
-              if ( speakingNPC->evt_C )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v18 = NPC_EventProcessor(speakingNPC->evt_C);
-                  if ( v18 == 1 || v18 == 2 )
-                    pWindow->CreateButton( 0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x15u, 0, "", 0);
-                }
-              }
-              if ( speakingNPC->evt_D )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v20 = NPC_EventProcessor(speakingNPC->evt_D);
-                  if ( v20 == 1 || v20 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x16u, 0, "", 0);
-                }
-              }
-              if ( speakingNPC->evt_E )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v22 = NPC_EventProcessor(speakingNPC->evt_E);
-                  if ( v22 == 1 || v22 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x17u, 0, "", 0);
-                }
-              }
-              if (speakingNPC->evt_F )
-              {
-                if ( num_menu_buttons < 4 )
-                {
-                  v24 = NPC_EventProcessor(speakingNPC->evt_F);
-                  if ( v24 == 1 || v24 == 2 )
-                    pWindow->CreateButton(0x1E0u, num_menu_buttons++ * v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x18u, 0, "", 0);
-                }
-              }
-            }
-            else
-            {
-              if ( speakingNPC->joins )
-              {
-                pWindow->CreateButton(0x1E0u, 0x82u, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Du, 0, pGlobalTXT_LocalizationStrings[407], 0);//Ïîäðîáíåå
-                if (speakingNPC->Hired())
-                {
-                  sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[408], speakingNPC->pName); //Îòïóñòèòü
-                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pTmpBuf.data(), 0);
-                }
-                else
-                  pWindow->CreateButton(0x1E0u, v11 + 130, 0x8Cu, v11, 1, 0, UIMSG_SelectNPCDialogueOption, 0x4Cu, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
-                num_menu_buttons = 2;
-              }
-            }
-            pWindow->_41D08F_set_keyboard_control_group(num_menu_buttons, 1, 0, 1);
-          }
-          break;
-            }
-        case WINDOW_ChangeLocation:
-        {
-          prev_screen_type = current_screen_type;
-          current_screen_type = SCREEN_CHANGE_LOCATION;
-          pBtn_ExitCancel = pWindow->CreateButton(                  566,                   445,  75,  33, 1, 0, UIMSG_CHANGE_LOCATION_ClickCencelBtn, 0, 'N', pGlobalTXT_LocalizationStrings[156], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);//Îñòàòüñÿ â ýòîé îáëàñòè
-          pBtn_YES        = pWindow->CreateButton(                  486,                   445,  75,  33, 1, 0, UIMSG_OnTravelByFoot, 0, 'Y', pWindow->Hint, pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
-                            pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0],  63,  73, 1, 0, UIMSG_OnTravelByFoot, 1, ' ', pWindow->Hint, 0, 0, 0);
-                            pWindow->CreateButton(                    8,                     8, 460, 344, 1, 0, UIMSG_OnTravelByFoot, 1,   0, pWindow->Hint, 0);
-          break;
-        }
-        case WINDOW_SpellBook: {// îêíî êíèãè çàêëîâ
-          InitializeBookTextures();
-          pWindow->OpenSpellBook();
-          break;
-            }
-        case WINDOW_GreetingNPC: {// îêíî ïðèâåòñòâèÿ ÍÏÑ
-          prev_screen_type = current_screen_type;
-          pKeyActionMap->EnterText(0, 15, pWindow);
-          current_screen_type = SCREEN_BRANCHLESS_NPC_DIALOG;
-          break;
-            }
+        if (pWindowList[uNextFreeWindowID] == nullptr)
+            break;
+    }
+
+    //GUIWindow* pWindow = &pWindowList[uNextFreeWindowID];
+    pWindowList[uNextFreeWindowID] = this;
+    this->uFrameWidth = uWidth;
+    this->uFrameHeight = uHeight;
 
-      }
-      return pWindow;
-    }
-//LABEL_62:
-    pWindow->CreateButton(61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
-    pWindow->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
-    pWindow->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
-    pWindow->CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
-    pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9, "", 0);
-    return pWindow;
-  }
-  if (eWindowType == WINDOW_HouseInterior)
-  {
-    current_screen_type = SCREEN_HOUSE;
-    pBtn_ExitCancel = pWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[80],//Âûéòè èç çäàíèÿ
-                   pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
-    for ( v26 = 0; v26 < uNumDialogueNPCPortraits; ++v26 )
-    {
-      if ( v26 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
-      {
-        v30 = pMapStats->pInfos[uHouse_ExitPic].pName;
-        v29 = (char*)pGlobalTXT_LocalizationStrings[LOCSTR_ENTER_S];
-      }
-      else
-      {
-        if ( v26 || !dword_591080 )
-          v27 = HouseNPCData[v26 +1 - ((dword_591080 != 0)? 1:0)]->pName;
-        else
-          v27 = (char*)p2DEvents[pButton - 1].pProprieterName;
-        v30 = v27;
-        v29 = (char*)pGlobalTXT_LocalizationStrings[435];
-      }
-      sprintfex(byte_591180[v26].data(), v29, v30);
-      HouseNPCPortraitsButtonsList[v26] = pWindow->CreateButton(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v26],
-                                                                pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v26],
-                                           63, 73, 1, 0, UIMSG_ClickHouseNPCPortrait, v26, 0, byte_591180[v26].data(), 0, 0, 0);
-    }
-    if ( uNumDialogueNPCPortraits == 1 )
-    {
-      window_SpeakInHouse = &pWindowList[uNextFreeWindowID];
-      _4B4224_UpdateNPCTopics(0);
-    }
-  }
-  else
-  {
-    if (eWindowType == WINDOW_Transition)
-    {
-      prev_screen_type = current_screen_type;
-      current_screen_type = SCREEN_INPUT_BLV;
-      pBtn_ExitCancel = pWindow->CreateButton(0x236u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_TransitionWindowCloseBtn, 0, 'N', pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);//Îòìåíà
-      pBtn_YES        = pWindow->CreateButton(0x1E6u, 0x1BDu, 0x4Bu, 0x21u, 1, 0, UIMSG_TransitionUI_Confirm, 0, 'Y', pWindow->Hint, pIcons_LOD->GetTexture(uTextureID_BUTTYES2), 0);
-                        pWindow->CreateButton(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], 0x3Fu, 0x49u, 1, 0, UIMSG_TransitionUI_Confirm, 1, 0x20u, pWindow->Hint, 0);
-                        pWindow->CreateButton(8, 8, 0x1CCu, 0x158u, 1, 0, UIMSG_TransitionUI_Confirm, 1u, 0, pWindow->Hint, 0);
-      return pWindow;
-    }
-    if (eWindowType == WINDOW_CastSpell)
-    {
-      pEventTimer->Pause();
-      pAudioPlayer->StopChannels(-1, -1);
-      pMouse->SetCursorBitmap("MICON2");
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[39], 2u);//Âûáåðèòå öåëü
-      return pWindow;
-    }
-    if (eWindowType == WINDOW_Scroll)
-    {
-      pWindow->CreateButton(61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
-      pWindow->CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
-      pWindow->CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
-      pWindow->CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
-      pWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, '\t', "", 0);
-      return pWindow;
-    }
-    if (eWindowType == WINDOW_CastSpell_InInventory)
-    {
-      pMouse->SetCursorBitmap("MICON2");
-      pBtn_ExitCancel = pWindow->CreateButton(392, 318, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],//Îòìåíà
-                     pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
-      ShowStatusBarString(pGlobalTXT_LocalizationStrings[39], 2);//Âûáðàòü öåëü
-      ++pIcons_LOD->uTexturePacksCount;
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
-      current_screen_type = SCREEN_CASTING;
-      if ( !pIcons_LOD->uNumPrevLoadedFiles )
-        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
-    }
-  }
-  return pWindow;
+    this->uFrameX = uX;
+    this->uFrameY = uY;
+    this->uFrameZ = uX + uWidth - 1;
+    this->uFrameW = uY + uHeight - 1;
+
+    this->ptr_1C = (void *)pButton;
+    this->Hint = hint;
+
+    //this->eWindowType = eWindowType;
+    this->receives_keyboard_input = false;
+    ++uNumVisibleWindows;
+    this->numVisibleWindows = uNumVisibleWindows;
+    pVisibleWindowsIdxs[uNumVisibleWindows] = uNextFreeWindowID + 1;
 }
+
+
 //----- (004B3EF0) --------------------------------------------------------
 void DrawJoinGuildWindow( int pEventCode )
 {
@@ -1643,15 +1638,15 @@
   current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
   ContractSelectText(pEventCode);
   pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, pEventCode, 0);
+  pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 350, pEventCode, 0);
   pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape,                    0, 0, pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uExitCancelTextureId), 0); // Cancel
                     pDialogueWindow->CreateButton(  0,   0,   0,  0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-                    pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_ClickNPCTopic,             0x52u, 0, pGlobalTXT_LocalizationStrings[122], 0);
+                    pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_ClickNPCTopic,             82, 0, pGlobalTXT_LocalizationStrings[122], 0);
   pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
   dialog_menu_id = HOUSE_DIALOGUE_OTHER;
 }
 //----- (0044603D) --------------------------------------------------------
-void  DialogueEnding()
+void DialogueEnding()
 {
   sDialogue_SpeakingActorNPC_ID = 0;
   pDialogueWindow->Release();
@@ -1659,6 +1654,302 @@
   pMiscTimer->Resume();
   pEventTimer->Resume();
 }
+
+
+
+void GUIWindow_GameMenu::Update()
+{
+    pRenderer->DrawTextureIndexed(
+        pViewport->uViewportTL_Y,
+        pViewport->uViewportTL_X,
+        pIcons_LOD->GetTexture(uTextureID_Options)
+    );
+    viewparams->bRedrawGameUI = 1;
+}
+
+void GUIWindow_CharacterRecord::Update()
+{
+    CharacterUI_CharacterScreen_Draw(pPlayers[uActiveCharacter]);
+}
+
+void GUIWindow_Options::Update()
+{
+    GameMenuUI_Options_Draw();
+}
+
+void GUIWindow_KeymappingOptions::Update()
+{
+    GameMenuUI_DrawKeyBindings();
+}
+
+void GUIWindow_VideoOptions::Update()
+{
+    GameMenuUI_DrawVideoOptions();
+}
+
+void GUIWindow_Book::Update()
+{
+    BookUI_Draw((WindowType)(int)ptr_1C);
+}
+
+void GUIWindow_BooksWindow::Update()
+{
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexed(uFrameY, uFrameX, pButton->pTextures[0]);
+    viewparams->bRedrawGameUI = true;
+}
+
+void GUIWindow_QuickReference::Update()
+{
+    GameUI_QuickRef_Draw();
+}
+
+void GUIWindow_Rest::Update()
+{
+    RestUI_Draw();
+}
+
+void GUIWindow_Travel::Update()
+{
+    TravelUI_Draw();
+}
+
+void GUIWindow_Transition::Update()
+{
+    TransitionUI_Draw();
+}
+
+void GUIWindow_Dialogue::Update()
+{
+    GameUI_DrawDialogue();
+}
+
+void GUIWindow_GenericDialogue::Update()
+{
+    GameUI_DrawBranchlessDialogue();
+}
+
+void GUIWindow_Spellbook::Update()
+{
+    DrawSpellBookContent(pPlayers[uActiveCharacter]);
+}
+
+void GUIWindow_Chest::Update()
+{
+    if (current_screen_type == SCREEN_CHEST)
+    {
+        Chest::DrawChestUI(par1C);
+    }
+    else if (current_screen_type == SCREEN_CHEST_INVENTORY)
+    {
+        pRenderer->ClearZBuffer(0, 479);
+        draw_leather();
+        CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+        pRenderer->DrawTextureIndexed(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uExitCancelTextureId));
+    }
+}
+
+void GUIWindow_Save::Update()
+{
+    SaveUI_Draw();
+}
+
+void GUIWindow_Load::Update()
+{
+    LoadUI_Draw();
+}
+
+void GUIWindow_House::Update()
+{
+    HouseDialogManager();
+    if (!window_SpeakInHouse)
+        return;
+    if (window_SpeakInHouse->par1C >= 53)
+        return;
+    if (pParty->PartyTimes._shop_ban_times[window_SpeakInHouse->par1C] <= pParty->uTimePlayed)
+    {
+        if (window_SpeakInHouse->par1C < 53)
+            pParty->PartyTimes._shop_ban_times[window_SpeakInHouse->par1C] = 0;
+        return;
+    }
+    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+}
+
+void GUIWindow_Scroll::Update()
+{
+    CreateScrollWindow();
+}
+
+void GUIWindow_Inventory::Update()
+{
+    DrawMessageBox(0);
+    DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
+    DrawText(pFontLucida, 10, 40, 0, pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
+    if (!pKeyActionMap->field_204)
+    {
+        ItemGen ItemGen2;
+        ItemGen2.Reset();
+        Release();
+        pEventTimer->Resume();
+        current_screen_type = SCREEN_GAME;
+        viewparams->bRedrawGameUI = 1;
+        int v39 = atoi(pKeyActionMap->pPressedKeysBuffer);
+        if (v39 > 0 && v39 < 800)
+            SpawnActor(v39);
+    }
+}
+
+void GUIWindow_Inventory_CastSpell::Update()
+{
+    pRenderer->ClearZBuffer(0, 479);
+    draw_leather();
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    CharacterUI_DrawPaperdoll(pPlayers[uActiveCharacter]);
+    pRenderer->DrawTextureIndexedAlpha(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+}
+
+void GUIWindow_Modal::Update()
+{
+    ModalWindow_ShowHint();
+}
+
+void GUIWindow_RestWindow::Update()
+{
+    __debugbreak(); // doesnt seems to get here, check stack trace & conditions
+    GUIButton GUIButton2; // [sp+28h] [bp-E0h]@133
+    memset(&GUIButton2, 0, sizeof(GUIButton2));
+    GUIButton2.uZ = 197;
+    GUIButton2.uW = 197;
+    GUIButton2.uX = 27;
+    GUIButton2.uY = 161;
+    GUIButton2.uWidth = 171;
+    GUIButton2.uHeight = 37;
+    GUIButton2.pParent = pButton_RestUI_WaitUntilDawn->pParent;
+    pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    pRenderer->DrawTextureIndexed(uFrameX, uFrameY, *((Texture **)ptr_1C + 15));
+    viewparams->bRedrawGameUI = 1;
+    GUIButton2.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, 0, 0); // Rest & Heal 8 hrs / Îòäûõ è ëå÷åíèå 8 ÷àñîâ
+    GUIButton2.pParent = 0;
+    Release();
+}
+
+void OnButtonClick::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    GUIButton *pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexedAlpha(uFrameX, uFrameY, pButton->pTextures[0]);
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+}
+
+void OnButtonClick2::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    GUIButton *pButton = (GUIButton *)ptr_1C;
+    if (pButton->uX >= 0 && pButton->uX <= window->GetWidth())
+    {
+        if (pButton->uY >= 0 && pButton->uY <= window->GetHeight())
+        {
+            pRenderer->DrawTextureIndexed(uFrameX, uFrameY, pButton->pTextures[0]);
+            viewparams->bRedrawGameUI = true;
+            if (Hint && Hint != (char *)1)
+                pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+            Release();
+            return;
+        }
+    }
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+}
+
+void OnButtonClick3::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexed(uFrameX, uFrameY, pButton->pTextures[1]);
+    viewparams->bRedrawGameUI = 1;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+}
+
+void OnButtonClick4::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexedAlpha(uFrameX, uFrameY, pButton->pTextures[1]);
+    viewparams->bRedrawGameUI = true;
+
+    Release();
+}
+
+void OnSaveLoad::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexed(uFrameX, uFrameY, pButton->pTextures[0]);
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+
+    if (current_screen_type == SCREEN_SAVEGAME)
+        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_SaveGame, 0, 0);
+    else
+        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_LoadGame, 0, 0);
+}
+
+void OnCancel::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pGUIButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexed(uFrameX, uFrameY, pGUIButton->pTextures[0]);
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pGUIButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+
+    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+}
+
+void OnCancel2::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexed(uFrameX, uFrameY, pButton->pTextures[1]);
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+
+    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+}
+
+void OnCancel3::Update()
+{
+    if (Hint != (char *)1)
+        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
+    auto pButton = (GUIButton *)ptr_1C;
+    pRenderer->DrawTextureIndexedAlpha(uFrameX, uFrameY, pButton->pTextures[0]);
+    viewparams->bRedrawGameUI = true;
+    if (Hint && Hint != (char *)1)
+        pButton->DrawLabel(Hint, pFontCreate, 0, 0);
+    Release();
+
+    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+}
+
 //----- (004156F0) --------------------------------------------------------
 void GUI_UpdateWindows() 
 {
@@ -1674,7 +1965,6 @@
   int v31; // eax@115
   GUIButton *pButton; // ebp@118
   int v39; // eax@129
-  unsigned int pNumMessages; // eax@142
   GUIButton *pGUIButton; // ebp@146
   //unsigned int pX; // [sp-1Ch] [bp-124h]@17
   //unsigned int pY; // [sp-18h] [bp-120h]@17
@@ -1690,129 +1980,14 @@
 
   for ( i = 1; i <= uNumVisibleWindows; ++i )
   {
-    pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+    pWindow = pWindowList[pVisibleWindowsIdxs[i] - 1];
+
+    pWindow->Update();
     switch (pWindow->eWindowType)
     {
-      case WINDOW_GameMenu:
-      {
-        pRenderer->DrawTextureIndexed(pViewport->uViewportTL_Y,
-                                      pViewport->uViewportTL_X, pIcons_LOD->GetTexture(uTextureID_Options));
-        viewparams->bRedrawGameUI = 1;
-        continue;
-      }
-      case WINDOW_CharacterRecord:
-      {
-        CharacterUI_CharacterScreen_Draw(pPlayers[uActiveCharacter]);
-        continue;
-      }
-      case WINDOW_Options:
-      {
-        GameMenuUI_Options_Draw();
-        continue;
-      }
-      case WINDOW_Book:
-      {
-        BookUI_Draw((WindowType)(int)pWindow->ptr_1C);
-        continue;
-      }
-      case WINDOW_Dialogue:
-      {
-        GameUI_DrawDialogue();
-        continue;
-      }
-      case WINDOW_QuickReference:
-      {
-        GameUI_QuickRef_Draw();
-        continue;
-      }
-      case WINDOW_Rest:
-      {
-        RestUI_Draw();
-        continue;
-      }
-      case WINDOW_ChangeLocation:
-      {
-        TravelUI_Draw();
-        continue;
-      }
-      case WINDOW_SpellBook:
-      {
-        DrawSpellBookContent(pPlayers[uActiveCharacter]);
-        continue;
-      }
-      case WINDOW_GreetingNPC:
-      {
-        GameUI_DrawBranchlessDialogue();
-        continue;
-      }
-      case WINDOW_Chest:
-      {
-        if ( current_screen_type == SCREEN_CHEST )
-        {
-          Chest::DrawChestUI(pWindow->par1C);
-        }
-        else if ( current_screen_type == SCREEN_CHEST_INVENTORY )
-        {
-          pRenderer->ClearZBuffer(0, 479);
-          draw_leather();
-          CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-          pRenderer->DrawTextureIndexed(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uExitCancelTextureId));
-        }
-        continue;
-      }
-      case WINDOW_SaveLoadButtons:
-      {
-        SaveUI_Draw();
-        continue;
-      }
-      case WINDOW_MainMenu_Load:
-      {
-        LoadUI_Draw();
-        continue;
-      }
-      case WINDOW_HouseInterior:
-      {
-        pWindowList[pVisibleWindowsIdxs[i] - 1].HouseDialogManager();
-        if ( !window_SpeakInHouse )
-          continue;
-        if ( window_SpeakInHouse->par1C >= 53 )
-          continue;
-        if ( pParty->PartyTimes._shop_ban_times[window_SpeakInHouse->par1C] <=pParty->uTimePlayed )
-        {
-          if ( window_SpeakInHouse->par1C < 53 )
-            pParty->PartyTimes._shop_ban_times[window_SpeakInHouse->par1C] = 0;
-          continue;
-        }
-        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_Transition:
-      {
-        TransitionUI_Draw();
-        continue;
-      }
-      case WINDOW_Scroll:
-      {
-        CreateScrollWindow();
-        continue;
-      }
-      case WINDOW_CastSpell_InInventory:
-      {
-        pRenderer->ClearZBuffer(0, 479);
-        draw_leather();
-        CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-        CharacterUI_DrawPaperdoll(pPlayers[uActiveCharacter]);
-        pRenderer->DrawTextureIndexedAlpha(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
-        continue;
-      }
-      case WINDOW_ModalWindow:
-      {
-        ModalWindow_ShowHint();
-        continue;
-      }
       case WINDOW_50:
       {
+          __debugbreak(); // looks like debugging tools
         v27 = Color16(255, 255, 255);
         if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
         {
@@ -1839,9 +2014,12 @@
           ptr_507BD0->Release();
           continue;
         }
+
+        __debugbreak(); // switch pass-through
       }
       case WINDOW_59:
       {
+          __debugbreak(); // looks like debugging tools
         pWindow->DrawMessageBox(0);
         pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
         pWindow->DrawText(pFontLucida, 10, 40, 0, pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
@@ -1876,193 +2054,11 @@
         }
         continue;
       }
-      case WINDOW_PressedButton2:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        if ( pButton->uX >= 0 && pButton->uX <= window->GetWidth() )
-        {
-          if ( pButton->uY >= 0 && pButton->uY <= window->GetHeight() )
-          {
-            pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-            viewparams->bRedrawGameUI = 1;
-            if ( pWindow->Hint )
-            {
-              if ( pWindow->Hint != (char *)1 )
-                pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-            }
-            pWindow->Release();
-            continue;
-          }
-        }
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_CharactersPressedButton:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_PressedButton:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexedAlpha(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint )
-        {
-          if ( pWindow->Hint != (char *)1 )
-            pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        }
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_5D:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexedAlpha(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        viewparams->bRedrawGameUI = 1;
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_SaveLoadBtn:
-      {
-        if (pWindow->Hint != (char *)1)
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        if (current_screen_type == SCREEN_SAVEGAME)
-          pMessageQueue_50CBD0->AddGUIMessage(UIMSG_SaveGame, 0, 0);
-        else
-          pMessageQueue_50CBD0->AddGUIMessage(UIMSG_LoadGame, 0, 0);
-        continue;
-      }
-      case WINDOW_LoadGame_CancelBtn:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexedAlpha(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = 1;
-        if ( pWindow->Hint && pWindow->Hint != (char *)1 )
-          pButton->DrawLabel(pWindow->Hint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_CloseRestWindowBtn:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pGUIButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pGUIButton->pTextures[0]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pGUIButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_ExitCharacterWindow:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        pHint = pWindow->Hint;
-        viewparams->bRedrawGameUI = 1;
-        if ( pHint && pHint != (char *)1 )
-          pButton->DrawLabel(pHint, pFontCreate, 0, 0);
-        pWindow->Release();
-        pNumMessages = pMessageQueue_50CBD0->uNumMessages;
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-        continue;
-      }
-      case WINDOW_RestWindow:
-      {
-        memset(&GUIButton2, 0, 0xBCu);
-        GUIButton2.uZ = 197;
-        GUIButton2.uW = 197;
-        GUIButton2.uX = 27;
-        GUIButton2.uY = 161;
-        GUIButton2.uWidth = 171;
-        GUIButton2.uHeight = 37;
-        GUIButton2.pParent = pButton_RestUI_WaitUntilDawn->pParent;
-        pAudioPlayer->PlaySound(SOUND_StartMainChoice02, 0, 0, -1, 0, 0, 0, 0);
-        pRenderer->DrawTextureIndexed(pWindow->uFrameX, pWindow->uFrameY, *((Texture **)pWindow->ptr_1C + 15));
-        viewparams->bRedrawGameUI = 1;
-        GUIButton2.DrawLabel(pGlobalTXT_LocalizationStrings[183], pFontCreate, 0, 0);//Îòäûõ è ëå÷åíèå 8 ÷àñîâ
-        GUIButton2.pParent = 0;
-        pGUIWindow2 = pWindow;
-        pGUIWindow2->Release();
-        continue;
-      }
-      case WINDOW_BooksWindow:
-      {
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureIndexed(pWindow->uFrameY,
-                                      pWindow->uFrameX, pButton->pTextures[0]);
-        viewparams->bRedrawGameUI = true;
-        continue;
-      }
-      case WINDOW_CharacterWindow_Inventory:
-      {
-        pWindow->DrawMessageBox(0);
-        pWindow->DrawText(pFontLucida, 10, 20, 0, "Making item number", 0, 0, 0);
-        pWindow->DrawText(pFontLucida, 10, 40, 0, pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
-        if ( !pKeyActionMap->field_204 )
-        {
-          ItemGen2.Reset();
-          pWindow->Release();
-          pEventTimer->Resume();
-          current_screen_type = SCREEN_GAME;
-          viewparams->bRedrawGameUI = 1;
-          v39 = atoi(pKeyActionMap->pPressedKeysBuffer);
-          if ( v39 > 0 )
-          {
-            if ( v39 < 800 )
-              SpawnActor(v39);
-          }
-        }
-        continue;
-      }
-      case WINDOW_KeyMappingOptions:
-      {
-        GameMenuUI_DrawKeyBindings();
-        continue;
-      }
-      case WINDOW_VideoOptions:
-      {
-        GameMenuUI_DrawVideoOptions();
-        continue;
-      }
+      case WINDOW_MainMenu:
+      case WINDOW_null:
+          continue;
       default:
+          __debugbreak();
         continue;
     }
   }
@@ -2071,11 +2067,7 @@
   if ( sub_4637E0_is_there_popup_onscreen() )
     UI_OnMouseRightClick(0);
 }
-//void LoadFonts_and_DrawCopyrightWindow()
-//{
-  //MainMenuUI_LoadFontsAndSomeStuff();
- // DrawCopyrightWindow();
-//}
+
 //----- (00415485) --------------------------------------------------------
 void DrawMM7CopyrightWindow()
 {
@@ -2111,7 +2103,7 @@
 {
   pEventTimer->Pause();
   modal_window_prev_screen_type = current_screen_type;
-  pModalWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_ModalWindow, OnRelease_message, pStrHint);
+  pModalWindow = new GUIWindow_Modal(0, 0, window->GetWidth(), window->GetHeight(), OnRelease_message, pStrHint);
   current_screen_type = SCREEN_MODAL_WINDOW;
 }
 
@@ -2186,7 +2178,7 @@
     if ( mscroll_id <= 782 )
     {
       uTextureID_720980 = pIcons_LOD->LoadTexture("leather", TEXTURE_16BIT_PALETTE);
-      pGUIWindow_ScrollWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Scroll, mscroll_id - 700, 0);
+      pGUIWindow_ScrollWindow = new GUIWindow_Scroll(0, 0, window->GetWidth(), window->GetHeight(), mscroll_id - 700, 0);
     }
   }
 }
@@ -2798,7 +2790,7 @@
 }
 
 //----- (004B3E1E) --------------------------------------------------------
-void  sub_4B3E1E()
+void sub_4B3E1E()
 {
 	NPCData *v0; // ST40_4@1
 	signed int v1; // edi@1
@@ -2809,7 +2801,7 @@
 	v1 = 0;
 	pDialogueWindow->eWindowType = WINDOW_MainMenu;
 	pDialogueWindow->Release();
-	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Dialogue, 1, 0);
+    pDialogueWindow = new GUIWindow_Dialogue(0, 0, window->GetWidth(), window->GetHeight(), 1, 0);
 	if (pNPCStats->pProfessions[v0->uProfession].pBenefits)//*(&pNPCStats->field_13A5C + 5 * v0->uProfession) )
 	{
 		pDialogueWindow->CreateButton(480, 160, 140, 28, 1, 0, UIMSG_SelectNPCDialogueOption, 77, 0, pGlobalTXT_LocalizationStrings[407], 0);//Ïîäðîáíåå
@@ -3122,7 +3114,7 @@
 	current_npc_text = (char *)pNPCTopics[a4 + 168].pText;
 	_4B254D_SkillMasteryTeacher(a4);  //might be needed because of contract_approved ?
 	pDialogueWindow->Release();
-	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, a4, 0);
+    pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 350, a4, 0);
 	pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0,
 		pGlobalTXT_LocalizationStrings[34], pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
 	pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
@@ -3234,7 +3226,7 @@
 
 	uDialogueType = 83;
 	pDialogueWindow->Release();
-	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 0, 0);
+    pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 350, 0, 0);
 	pBtn_ExitCancel = pDialogueWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[34],// "Cancel"
 		pIcons_LOD->GetTexture(uExitCancelTextureId), 0);
 	pDialogueWindow->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
--- a/GUI/GUIWindow.h	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/GUIWindow.h	Mon May 11 09:51:04 2015 +0200
@@ -267,54 +267,54 @@
 {
   WINDOW_null            = 0,
   WINDOW_MainMenu        = 1,
-  WINDOW_GameMenu  = 3,
+  WINDOW_GameMenu        = 3,
   WINDOW_CharacterRecord = 4,
   WINDOW_Options         = 6,
   WINDOW_8               = 8,
   WINDOW_Book            = 9,
-  WINDOW_Dialogue       = 10,
-  WINDOW_QuickReference = 12,
-  WINDOW_F              = 15,
-  WINDOW_Rest           = 16,
-  WINDOW_ChangeLocation = 17,
-  WINDOW_SpellBook      = 18,
-  WINDOW_GreetingNPC    = 19,
-  WINDOW_Chest          = 20,
-  WINDOW_22 = 0x16,
+  WINDOW_Dialogue        = 10,
+  WINDOW_QuickReference  = 12,
+  WINDOW_F               = 15,
+  WINDOW_Rest            = 16,
+  WINDOW_ChangeLocation  = 17,
+  WINDOW_SpellBook       = 18,
+  WINDOW_GreetingNPC     = 19,
+  WINDOW_Chest           = 20,
+  WINDOW_22              = 0x16,
   WINDOW_SaveLoadButtons = 23,
-  WINDOW_MainMenu_Load = 0x18,
-  WINDOW_HouseInterior = 0x19,
-  WINDOW_Transition = 26,
-  WINDOW_CastSpell = 27,
-  WINDOW_Scroll = 0x1E,
+  WINDOW_MainMenu_Load   = 0x18,
+  WINDOW_HouseInterior   = 0x19,
+  WINDOW_Transition      = 26,
+  WINDOW_CastSpell       = 27, // OnCastTargetedSpell
+  WINDOW_Scroll          = 0x1E,
   WINDOW_CastSpell_InInventory = 31,
-  WINDOW_ModalWindow = 70,
-  WINDOW_50 = 80,
-  WINDOW_59 = 89,
+  WINDOW_ModalWindow    = 70,
+  WINDOW_50             = 80,
+  WINDOW_59             = 89,
   WINDOW_PressedButton2 = 90,
   WINDOW_CharactersPressedButton = 91,
-  WINDOW_PressedButton = 92,
-  WINDOW_5D = 93,
-  WINDOW_SaveLoadBtn = 94,
-  WINDOW_LoadGame_CancelBtn = 95,
-  WINDOW_CloseRestWindowBtn = 96,
-  WINDOW_ExitCharacterWindow = 97,
-  WINDOW_RestWindow = 0x62,
-  WINDOW_BooksWindow = 99,
-  WINDOW_CharacterWindow_Stats = 0x64,
-  WINDOW_CharacterWindow_Skills = 0x65,
-  WINDOW_CharacterWindow_Awards = 0x66,
+  WINDOW_PressedButton       = 92,
+  WINDOW_5D                  = 93,
+  WINDOW_SaveLoadBtn         = 94,
+  WINDOW_LoadGame_CancelBtn  = 95, // OnCancel3
+  WINDOW_CloseRestWindowBtn  = 96,
+  WINDOW_ExitCharacterWindow = 97, // OnCancel2
+  WINDOW_RestWindow          = 0x62,
+  WINDOW_BooksWindow         = 99,
+  WINDOW_CharacterWindow_Stats     = 0x64,
+  WINDOW_CharacterWindow_Skills    = 0x65,
+  WINDOW_CharacterWindow_Awards    = 0x66,
   WINDOW_CharacterWindow_Inventory = 0x67,
-  WINDOW_68 = 104,
+  WINDOW_68                = 104,
   WINDOW_KeyMappingOptions = 0x69,
-  WINDOW_VideoOptions = 0x6A,
-  WINDOW_LloydsBeacon = 177,
-  WINDOW_TownPortal = 195,
-  WINDOW_QuestBook = 200,
-  WINDOW_AutonotesBook = 0xC9,
-  WINDOW_MapsBook = 0xCA,
-  WINDOW_CalendarBook = 0xCB,
-  WINDOW_JournalBook = 0xE0,
+  WINDOW_VideoOptions      = 0x6A,
+  WINDOW_LloydsBeacon      = 177,
+  WINDOW_TownPortal        = 195,
+  WINDOW_QuestBook         = 200,
+  WINDOW_AutonotesBook     = 0xC9,
+  WINDOW_MapsBook          = 0xCA,
+  WINDOW_CalendarBook      = 0xCB,
+  WINDOW_JournalBook       = 0xE0,
 };
 
 struct GUIButton;
@@ -330,11 +330,9 @@
 #pragma pack(push, 1)
 struct GUIWindow
 {
-  inline GUIWindow()
-  {
-    pControlsHead = pControlsTail = nullptr;
-    eWindowType = WINDOW_null;
-  }
+    GUIWindow();
+    GUIWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, int pButton, const char* hint);
+    virtual ~GUIWindow() {}
 
   GUIButton *CreateButton(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, int a6, int a7, 
 	                      UIMessageType msg, unsigned int msg_param, unsigned __int8 uHotkey, const char *pName, struct Texture *pTextures, ...);
@@ -348,11 +346,11 @@
   void InitializeBookView();
   void DrawMessageBox(int arg0);
   GUIButton *GetControl(unsigned int uID);
-  void Release();
   void _41D08F_set_keyboard_control_group(int num_buttons, int a3, int a4, int a5);
   void _41D73D_draw_buff_tooltip();
 
-  static GUIWindow *Create(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, enum WindowType eWindowType, int pButton, const char* hint);
+  virtual void Update() {}
+  virtual void Release();
 
   unsigned int uFrameX;
   unsigned int uFrameY;
@@ -381,8 +379,300 @@
 };
 #pragma pack(pop)
 
+struct GUIWindow_GameMenu : public GUIWindow
+{
+    GUIWindow_GameMenu(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_GameMenu() {}
 
+    virtual void Update();
+};
+struct GUIWindow_CharacterRecord : public GUIWindow
+{
+    GUIWindow_CharacterRecord(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_CharacterRecord() {}
 
+    virtual void Update();
+};
+struct GUIWindow_Options : public GUIWindow
+{
+    GUIWindow_Options(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Options() {}
+
+    virtual void Update();
+};
+struct GUIWindow_KeymappingOptions : public GUIWindow
+{
+    GUIWindow_KeymappingOptions(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_KeymappingOptions() {}
+
+    virtual void Update();
+};
+struct GUIWindow_VideoOptions : public GUIWindow
+{
+    GUIWindow_VideoOptions(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_VideoOptions() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Book : public GUIWindow
+{
+    GUIWindow_Book(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {
+        InitializeBookView();
+    }
+    virtual ~GUIWindow_Book() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_BooksWindow : public GUIWindow
+{
+    GUIWindow_BooksWindow(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_BooksWindow() {}
+
+    virtual void Update();
+};
+struct GUIWindow_QuickReference : public GUIWindow
+{
+    GUIWindow_QuickReference(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_QuickReference() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Rest : public GUIWindow
+{
+    GUIWindow_Rest(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Rest() {}
+
+    virtual void Update();
+};
+struct GUIWindow_RestWindow : public GUIWindow
+{
+    GUIWindow_RestWindow(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_RestWindow() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Travel : public GUIWindow
+{
+    GUIWindow_Travel(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_Travel() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Transition : public GUIWindow
+{
+    GUIWindow_Transition(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_Transition() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Dialogue : public GUIWindow
+{
+    GUIWindow_Dialogue(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_Dialogue() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Spellbook : public GUIWindow
+{
+    GUIWindow_Spellbook(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_Spellbook() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_GenericDialogue : public GUIWindow
+{
+    GUIWindow_GenericDialogue(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_GenericDialogue() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Chest : public GUIWindow
+{
+    GUIWindow_Chest(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {
+        CreateButton(61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+        CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+        CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+        CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+        CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, 9, "", 0);
+    }
+    virtual ~GUIWindow_Chest() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Save : public GUIWindow
+{
+    GUIWindow_Save(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Save() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Load : public GUIWindow
+{
+    GUIWindow_Load(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Load() {}
+
+    virtual void Update();
+};
+struct GUIWindow_House : public GUIWindow
+{
+    GUIWindow_House(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_House() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Scroll : public GUIWindow
+{
+    GUIWindow_Scroll(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {
+        CreateButton(61, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);
+        CreateButton(177, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 2, '2', "", 0);
+        CreateButton(292, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 3, '3', "", 0);
+        CreateButton(407, 424, 31, 0, 2, 94, UIMSG_SelectCharacter, 4, '4', "", 0);
+        CreateButton(0, 0, 0, 0, 1, 0, UIMSG_CycleCharacters, 0, '\t', "", 0);
+    }
+    virtual ~GUIWindow_Scroll() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Inventory : public GUIWindow
+{
+    GUIWindow_Inventory(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Inventory() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct GUIWindow_Inventory_CastSpell : public GUIWindow
+{
+    GUIWindow_Inventory_CastSpell(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~GUIWindow_Inventory_CastSpell() {}
+
+    virtual void Update();
+};
+struct GUIWindow_Modal : public GUIWindow
+{
+    GUIWindow_Modal(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~GUIWindow_Modal() {}
+
+    virtual void Update();
+};
+struct OnButtonClick : public GUIWindow
+{
+    OnButtonClick(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnButtonClick() {}
+
+    virtual void Update();
+};
+struct OnButtonClick2 : public GUIWindow
+{
+    OnButtonClick2(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnButtonClick2() {}
+
+    virtual void Update();
+};
+struct OnButtonClick3 : public GUIWindow
+{
+    OnButtonClick3(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnButtonClick3() {}
+
+    virtual void Update();
+};
+struct OnButtonClick4 : public GUIWindow
+{
+    OnButtonClick4(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnButtonClick4() {}
+
+    virtual void Update();
+    virtual void Release();
+};
+struct OnSaveLoad : public GUIWindow
+{
+    OnSaveLoad(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnSaveLoad() {}
+
+    virtual void Update();
+};
+struct OnCancel : public GUIWindow
+{
+    OnCancel(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnCancel() {}
+
+    virtual void Update();
+};
+struct OnCancel2 : public GUIWindow
+{
+    OnCancel2(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnCancel2() {}
+
+    virtual void Update();
+};
+struct OnCancel3 : public GUIWindow
+{
+    OnCancel3(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint) :
+        GUIWindow(x, y, width, height, button, hint)
+    {}
+    virtual ~OnCancel3() {}
+
+    virtual void Update();
+};
+struct OnCastTargetedSpell : public GUIWindow
+{
+    OnCastTargetedSpell(unsigned int x, unsigned int y, unsigned int width, unsigned int height, int button, const char *hint);
+    virtual ~OnCastTargetedSpell() {}
+};
 
 
 
@@ -473,10 +763,10 @@
 
 
 
-extern int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[]; // idb
+extern enum WindowType current_character_screen_window;
 extern struct GUIWindow *pWindow_MMT_MainMenu;
 extern struct GUIWindow *pWindow_MainMenu;
-extern std::array<struct GUIWindow, 20> pWindowList;
+extern std::array<struct GUIWindow *, 20> pWindowList;
 
 
 
@@ -616,7 +906,7 @@
 unsigned int UI_GetHealthManaAndOtherQualitiesStringColor(signed int current_pos, signed int base_pos);
 unsigned int __fastcall GetSizeInInventorySlots(unsigned int uNumPixels);
 struct GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey); // idb
-int __fastcall GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall);
+void GUI_ReplaceHotkey(unsigned __int8 uOldHotkey, unsigned __int8 uNewHotkey, char bFirstCall);
 void DrawBuff_remaining_time_string(int uY, struct GUIWindow *window, __int64 remaining_time, struct GUIFont *Font);
 void GameUI_DrawItemInfo(struct ItemGen* inspect_item); // idb
 void MonsterPopup_Draw(unsigned int uActorID, struct GUIWindow *window);
@@ -748,11 +1038,6 @@
 extern struct GUIButton *pMMT_MainMenu_BtnContinue;
 extern struct GUIButton *pMMT_MainMenu_BtnExit;
 
-extern struct GUIButton *pMainMenu_BtnExit;
-extern struct GUIButton *pMainMenu_BtnCredits;
-extern struct GUIButton *pMainMenu_BtnLoad;
-extern struct GUIButton *pMainMenu_BtnNew;
-
 
 extern struct GUIButton *pBtn_Up;
 extern struct GUIButton *pBtn_Down;
--- a/GUI/UI/UICharacter.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UICharacter.cpp	Mon May 11 09:51:04 2015 +0200
@@ -416,7 +416,7 @@
   CharacterUI_LoadPaperdollTextures();
   current_screen_type = screen;
 
-  auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CharacterRecord, uActiveCharacter, 0);
+  auto wnd = new GUIWindow_CharacterRecord(0, 0, window->GetWidth(), window->GetHeight(), uActiveCharacter, 0);
   pCharacterScreen_StatsBtn = wnd->CreateButton(pViewport->uViewportTL_X + 12, pViewport->uViewportTL_Y + 308,
                                 pIcons_LOD->GetTexture(papredoll_dbrds[9])->uTextureWidth,
                                 pIcons_LOD->GetTexture(papredoll_dbrds[9])->uTextureHeight,
@@ -472,7 +472,7 @@
   bRingsShownInCharScreen = 0;
   CharacterUI_LoadPaperdollTextures();
   current_screen_type = SCREEN_CASTING;
-  CS_inventory_window = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_CastSpell_InInventory, (int)this, 0);
+  CS_inventory_window = new GUIWindow_Inventory_CastSpell(0, 0, window->GetWidth(), window->GetHeight(), (int)this, 0);
   pCharacterScreen_ExitBtn = CS_inventory_window->CreateButton(394, 318, 75, 33, 1, 0, UIMSG_ClickExitCharacterWindowBtn, 0, 0,
                  pGlobalTXT_LocalizationStrings[79], // Close
                  pIcons_LOD->GetTexture(papredoll_dbrds[2]),
@@ -695,7 +695,7 @@
 void CharacterUI_CharacterScreen_Draw(Player *player)
 {
   pRenderer->ClearZBuffer(0, 479);
-  switch (pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0])
+  switch (current_character_screen_window)
   {
     case WINDOW_CharacterWindow_Stats:                                // stats
       CharacterUI_ReleaseButtons();
--- a/GUI/UI/UIHouses.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIHouses.cpp	Mon May 11 09:51:04 2015 +0200
@@ -1023,7 +1023,7 @@
         return;
       }
       pDialogueWindow->Release();
-      pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 0, 0);
+      pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 345, 0, 0);
       pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
                                                        pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
       pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
@@ -1035,7 +1035,7 @@
           || in_current_building_type != BuildingType_Temple || uMessageParam != BuildingType_MindGuild )
       {
         pDialogueWindow->Release();
-        pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 0, 0);
+        pDialogueWindow = new GUIWindow(0, 0, window->GetWidth(), 345, 0, 0);
         pBtn_ExitCancel = pDialogueWindow->CreateButton(526, 445, 75, 33, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[74],// "End Conversation"
                                                          pIcons_LOD->GetTexture(uTextureID_BUTTDESC2), 0);
         pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", nullptr);
@@ -3405,7 +3405,7 @@
     if ( EnterHouse(HOUSE_BODY_GUILD_ERATHIA) )
     {
       pAudioPlayer->PlaySound(SOUND_Invalid, 0, 0, -1, 0, 0, 0, 0);
-      window_SpeakInHouse = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_HouseInterior, 165, 0);
+      window_SpeakInHouse = new GUIWindow_House(0, 0, window->GetWidth(), window->GetHeight(), 165, 0);
       window_SpeakInHouse->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 1, 0x31, "", 0);
       window_SpeakInHouse->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 2, 0x32, "", 0);
       window_SpeakInHouse->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, UIMSG_SelectCharacter, 3, 0x33, "", 0);
--- a/GUI/UI/UIMainMenu.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIMainMenu.cpp	Mon May 11 09:51:04 2015 +0200
@@ -50,7 +50,7 @@
   pFontComic = LoadFont("comic.fnt", "FONTPAL", nullptr);
 
   for (uint i = 0; i < 20; ++i)
-    pWindowList[i].eWindowType = WINDOW_null;
+      pWindowList[i] = nullptr;
 
   uNumVisibleWindows = -1;
   memset(pVisibleWindowsIdxs.data(), 0, sizeof(pVisibleWindowsIdxs));
@@ -108,7 +108,7 @@
   uTextureID_BUTTMAKE = pIcons_LOD->LoadTexture("BUTTMAKE", TEXTURE_16BIT_PALETTE);
   uTextureID_BUTTMAKE2 = pIcons_LOD->LoadTexture("BUTTMAKE2", TEXTURE_16BIT_PALETTE);
 
-  pPrimaryWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+  pPrimaryWindow = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
   pPrimaryWindow->CreateButton(7, 8, 460, 343, 1, 0, UIMSG_MouseLeftClickInGame, 0, 0, "", 0);
 
   pPrimaryWindow->CreateButton(61, 424, 31, 80, 2, 94, UIMSG_SelectCharacter, 1, '1', "", 0);//buttons for portraits
@@ -298,7 +298,7 @@
     cred_texture.uHeight, Color16(0x70u, 0x8Fu, 0xFEu), Color16(0xECu, 0xE6u, 0x9Cu), pString, cred_texture.pPixels, cred_texture.uWidth);
   free(pString);
 
-  pWindow_MainMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, cred_texturet);
+  pWindow_MainMenu = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, cred_texturet);
   pWindow_MainMenu->CreateButton(0, 0, 0, 0, 1, 0, UIMSG_Escape, 0, 27, "", 0);
   current_screen_type = SCREEN_CREATORS;
   SetCurrentMenuID(MENU_CREDITSPROC);
--- a/GUI/UI/UIOptions.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIOptions.cpp	Mon May 11 09:51:04 2015 +0200
@@ -26,7 +26,7 @@
 
 GUIWindow *GameMenuUI_Load()
 {
-    auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_GameMenu, 0, 0);
+    auto wnd = new GUIWindow_GameMenu(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     uTextureID_Options = pIcons_LOD->LoadTexture("options", TEXTURE_16BIT_PALETTE);
     uTextureID_New1 = pIcons_LOD->LoadTexture("new1", TEXTURE_16BIT_PALETTE);
     uTextureID_Load1 = pIcons_LOD->LoadTexture("load1", TEXTURE_16BIT_PALETTE);
@@ -94,7 +94,7 @@
     uTextureID_Optkb[3] = pIcons_LOD->LoadTexture("optkb_1", TEXTURE_16BIT_PALETTE);
     uTextureID_Optkb[4] = pIcons_LOD->LoadTexture("optkb_2", TEXTURE_16BIT_PALETTE);
 
-    auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_KeyMappingOptions, 0, 0);
+    auto wnd = new GUIWindow_KeymappingOptions(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
 
     wnd->CreateButton(241, 302, 214, 40, 1, 0, UIMSG_Escape, 0, 0, "", 0);
 
@@ -249,7 +249,7 @@
     not_available_bloodsplats_texture_id = pIcons_LOD->LoadTexture("opvdG-bs", TEXTURE_16BIT_PALETTE);
     not_available_us_colored_lights_texture_id = pIcons_LOD->LoadTexture("opvdG-cl", TEXTURE_16BIT_PALETTE);
     not_available_tinting_texture_id = pIcons_LOD->LoadTexture("opvdG-tn", TEXTURE_16BIT_PALETTE);
-    auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_VideoOptions, 0, 0);
+    auto wnd = new GUIWindow_VideoOptions(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     wnd->CreateButton(0xF1u, 0x12Eu, 0xD6u, 0x28u, 1, 0, UIMSG_Escape, 0, 0, "", 0);
     //if ( pRenderer->pRenderD3D )
     {
@@ -332,7 +332,7 @@
     options_menu_skin.uTextureID_ShowDamage = pIcons_LOD->LoadTexture("option02", TEXTURE_16BIT_PALETTE);
     options_menu_skin.uTextureID_WalkSound = pIcons_LOD->LoadTexture("option01", TEXTURE_16BIT_PALETTE);
 
-    auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Options, 0, 0);
+    auto wnd = new GUIWindow_Options(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     wnd->CreateButton(22, 270,
         pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureWidth,
         pIcons_LOD->GetTexture(options_menu_skin.uTextureID_TurnSpeed[2])->uTextureHeight,
--- a/GUI/UI/UIPartyCreation.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIPartyCreation.cpp	Mon May 11 09:51:04 2015 +0200
@@ -107,7 +107,7 @@
 
   //move sky
   pRenderer->BeginScene();
-  pRenderer->DrawTextureNew(0, 0, &pTexture_PCX);
+  pRenderer->DrawTextureNew(0, 0, &main_menu_background);
   uPlayerCreationUI_SkySliderPos = (GetTickCount() % 12800) / 20;
   pRenderer->DrawTextureIndexed(uPlayerCreationUI_SkySliderPos, 2, pTexture_MAKESKY);
   pRenderer->DrawTextureIndexed(uPlayerCreationUI_SkySliderPos - window->GetWidth(), 2, pTexture_MAKESKY);
@@ -165,9 +165,9 @@
         case WINDOW_INPUT_CONFIRMED: // press enter
           pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
           v126 = 0;
-          for ( int i = 0; i < strlen(pKeyActionMap->pPressedKeysBuffer); ++i )//edit name
+          for ( int j = 0; j < strlen(pKeyActionMap->pPressedKeysBuffer); ++j )//edit name
           {
-            if ( pKeyActionMap->pPressedKeysBuffer[i] == ' ' )
+            if ( pKeyActionMap->pPressedKeysBuffer[j] == ' ' )
               ++v126;
           }
           if ( strlen(pKeyActionMap->pPressedKeysBuffer) && v126 != strlen(pKeyActionMap->pPressedKeysBuffer) )
@@ -438,7 +438,7 @@
     pTextures_arrowr[i] = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE);
   }
 
-  pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+  pGUIWindow_CurrentMenu = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
   uControlParam = 0;
   uX = 8;
   do
@@ -558,8 +558,8 @@
   bool party_not_creation_flag; // [sp+74h] [bp-Ch]@1
 
   party_not_creation_flag = false;
-  pTexture_PCX.Release();
-  pTexture_PCX.Load("makeme.pcx", 0);
+  main_menu_background.Release();
+  main_menu_background.Load("makeme.pcx", 0);
 
   pGUIWindow_CurrentMenu->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
   SetCurrentMenuID(MENU_CREATEPARTY);
@@ -599,7 +599,7 @@
       }
     }
   }
-  pTexture_PCX.Release();
+  main_menu_background.Release();
   pGUIWindow_CurrentMenu->Release();
   pIcons_LOD->RemoveTexturesPackFromTextureList();
 
--- a/GUI/UI/UIPopup.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIPopup.cpp	Mon May 11 09:51:04 2015 +0200
@@ -1482,11 +1482,11 @@
         Inventory_ItemPopupAndAlchemy();
       else if ( (signed int)pY >= 345 )
         break;
-      else if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 100 )//2DEvent - CharacerScreenStats
+      else if (current_character_screen_window == WINDOW_CharacterWindow_Stats)//2DEvent - CharacerScreenStats
         CharacterUI_StatsTab_ShowHint();
-      else if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 101 )//2DEvent - CharacerScreenSkills
+      else if (current_character_screen_window == WINDOW_CharacterWindow_Skills)//2DEvent - CharacerScreenSkills
         CharacterUI_SkillsTab_ShowHint();
-      else if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 103 )//2DEvent - CharacerScreenInventory
+      else if (current_character_screen_window == WINDOW_CharacterWindow_Inventory)//2DEvent - CharacerScreenInventory
           Inventory_ItemPopupAndAlchemy();
       break;
     }
--- a/GUI/UI/UIRest.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIRest.cpp	Mon May 11 09:51:04 2015 +0200
@@ -30,7 +30,7 @@
     }
     pEventTimer->Pause();
     if (_506F14_resting_stage != 2)
-        GUIWindow::Create(518, 450, 0, 0, WINDOW_PressedButton2, (int)pBtn_Rest, 0);
+        new OnButtonClick2(518, 450, 0, 0, (int)pBtn_Rest, 0);
     _506F18_num_minutes_to_sleep = 0;
     _506F14_resting_stage = 0;
     uRestUI_FoodRequiredToRest = 2;
@@ -72,7 +72,7 @@
 
   OutdoorLocation::LoadActualSkyFrame();
 
-  auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Rest, 0, 0);
+  auto wnd = new GUIWindow_Rest(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
   pButton_RestUI_Exit =          wnd->CreateButton(280, 297, 154, 37, 1, 0, UIMSG_ExitRest, 0, 0, "", pIcons_LOD->GetTexture(uTextureID_RestUI_restexit), 0);
   pButton_RestUI_Main =          wnd->CreateButton( 24, 154, 225, 37, 1, 0, UIMSG_Rest8Hour, 0, 'R', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb4), 0);
   pButton_RestUI_WaitUntilDawn = wnd->CreateButton( 61, 232, 154, 33, 1, 0, UIMSG_AlreadyResting, 0, 'D', "", pIcons_LOD->GetTexture(uTextureID_RestUI_restb1), 0);
@@ -170,6 +170,5 @@
       Party::Sleep6Hours();
   }
   else
-    GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn, 
-      (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]); // "Exit Rest"
+      new OnCancel(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]); // "Exit Rest"
 }
\ No newline at end of file
--- a/GUI/UI/UISaveLoad.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UISaveLoad.cpp	Mon May 11 09:51:04 2015 +0200
@@ -17,6 +17,8 @@
 #include "..\../Engine/SaveLoad.h"
 #include "..\../Engine/texts.h"
 
+#include "Game/MainMenu.h"
+
 
 //----- (004601B7) --------------------------------------------------------
 static void UI_DrawSaveLoad(bool save)
@@ -180,9 +182,9 @@
     pRenderer->DrawTextureIndexed(351, 302, pIcons_LOD->GetTexture(uTextureID_x_u));
   }
   else
-    pRenderer->DrawTextureNew(0, 0, &pTexture_PCX);
-  pGUIWindow_CurrentMenu = GUIWindow::Create(saveload_dlg_xs[uDialogueType], saveload_dlg_ys[uDialogueType], saveload_dlg_zs[uDialogueType],
-      saveload_dlg_ws[uDialogueType], WINDOW_MainMenu_Load, 0, 0);
+    pRenderer->DrawTextureNew(0, 0, &main_menu_background);
+  pGUIWindow_CurrentMenu = new GUIWindow_Load(saveload_dlg_xs[uDialogueType], saveload_dlg_ys[uDialogueType], saveload_dlg_zs[uDialogueType],
+      saveload_dlg_ws[uDialogueType], 0, 0);
   pGUIWindow_CurrentMenu->DrawText(pFontSmallnum, 25, 199, 0, pGlobalTXT_LocalizationStrings[505], 0, 0, 0);// "Reading..."
   pRenderer->Present();
   pSavegameList->Initialize(0);
@@ -312,7 +314,7 @@
   uTextureID_AR_UP_DN = pIcons_LOD->LoadTexture("AR_UP_DN", TEXTURE_16BIT_PALETTE);
   uTextureID_AR_DN_DN = pIcons_LOD->LoadTexture("AR_DN_DN", TEXTURE_16BIT_PALETTE);
 
-  auto wnd = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_SaveLoadButtons, 0, 0);
+  auto wnd = new GUIWindow_Save(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
   wnd->CreateButton(21, 198, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 0, 0, "", 0);
   wnd->CreateButton(21, 218, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 1, 0, "", 0);
   wnd->CreateButton(21, 238, 191, 18, 1, 0, UIMSG_SelectLoadSlot, 2, 0, "", 0);
--- a/GUI/UI/UIShops.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UIShops.cpp	Mon May 11 09:51:04 2015 +0200
@@ -1508,7 +1508,7 @@
   {
     case HOUSE_DIALOGUE_SHOP_DISPLAY_EQUIPMENT:
     {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+        current_character_screen_window = WINDOW_CharacterWindow_Inventory;
       pPlayers[uActiveCharacter]->OnInventoryLeftClick();
       break;
     }
--- a/GUI/UI/UITransition.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UITransition.cpp	Mon May 11 09:51:04 2015 +0200
@@ -62,7 +62,7 @@
     if ( pMapStats->GetMapInfo(pCurrentMapName) )
     {
       sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName); // "Leave %s"
-      pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Transition, 0, sHouseName.data());
+      pDialogueWindow = new GUIWindow_Transition(0, 0, window->GetWidth(), window->GetHeight(), 0, sHouseName.data());
       //if ( pAnimatedRooms[p2DEvents[anim_id].uAnimationID].uRoomSoundId )
         //PlayHouseSound(anim_id, HouseSound_Greeting);
       if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
@@ -72,7 +72,7 @@
       return;
     }
     strcpy(sHouseName.data(), pGlobalTXT_LocalizationStrings[79]);
-    pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Transition, 0, sHouseName.data());
+    pDialogueWindow = new GUIWindow_Transition(0, 0, window->GetWidth(), window->GetHeight(), 0, sHouseName.data());
     //if ( pAnimatedRooms[p2DEvents[anim_id].uAnimationID].uRoomSoundId )
       //PlayHouseSound(anim_id, HouseSound_Greeting);
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
@@ -87,7 +87,7 @@
   if ( pMapStats->GetMapInfo(v15) )
   {
     sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[411], pMapStats->pInfos[pMapStats->GetMapInfo(v15)].pName);//Âîéòè â ^Pv[%s]
-    pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Transition, 0, sHouseName.data());
+    pDialogueWindow = new GUIWindow_Transition(0, 0, window->GetWidth(), window->GetHeight(), 0, sHouseName.data());
     if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
       pPlayers[uActiveCharacter]->PlaySound(SPEECH_47, 0);
     if ( IndoorLocation::GetLocationIndex(pLocationName) )
@@ -95,7 +95,7 @@
     return;
   }
   strcpy(sHouseName.data(), pGlobalTXT_LocalizationStrings[73]);//Âîéòè
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Transition, 0, sHouseName.data());
+  pDialogueWindow = new GUIWindow_Transition(0, 0, window->GetWidth(), window->GetHeight(), 0, sHouseName.data());
   //if ( pAnimatedRooms[p2DEvents[anim_id].uAnimationID].uRoomSoundId )
     //PlayHouseSound(anim_id, HouseSound_Greeting);
   if ( uCurrentlyLoadedLevelType == LEVEL_Indoor && uActiveCharacter && pParty->uFlags & 0x30 )
@@ -125,7 +125,7 @@
     sprintfex(sHouseName.data(), pGlobalTXT_LocalizationStrings[410], pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName);// "Leave %s"
   else
     strcpy(sHouseName.data(), pGlobalTXT_LocalizationStrings[79]);// "Exit"
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_ChangeLocation, 0, sHouseName.data());
+  pDialogueWindow = new GUIWindow_Travel(0, 0, window->GetWidth(), window->GetHeight(), 0, sHouseName.data());
 }
 
 //----- (00444DCA) --------------------------------------------------------
--- a/GUI/UI/UiGame.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/GUI/UI/UiGame.cpp	Mon May 11 09:51:04 2015 +0200
@@ -88,7 +88,7 @@
     viewparams->bRedrawGameUI = true;
     if ( uActiveCharacter == uPlayerID )
     {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+        current_character_screen_window = WINDOW_CharacterWindow_Inventory;
       current_screen_type = SCREEN_CHEST_INVENTORY;
       uActiveCharacter = uPlayerID;
       return;
@@ -109,14 +109,14 @@
     {
       viewparams->bRedrawGameUI = true;
       uActiveCharacter = uPlayerID;
-      if ( pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] == 102 )
+      if (current_character_screen_window == WINDOW_CharacterWindow_Awards)
         FillAwardsData();
       return;
     }
     viewparams->bRedrawGameUI = true;
     if ( uActiveCharacter == uPlayerID )
     {
-      pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+        current_character_screen_window = WINDOW_CharacterWindow_Inventory;
       current_screen_type = SCREEN_CHEST_INVENTORY;
       uActiveCharacter = uPlayerID;
       return;
@@ -137,7 +137,7 @@
   if (dialog_menu_id == HOUSE_DIALOGUE_SHOP_BUY_STANDARD || dialog_menu_id == HOUSE_DIALOGUE_SHOP_6)
   {
     __debugbreak(); // fix indexing
-    pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+    current_character_screen_window = WINDOW_CharacterWindow_Inventory;
     pGUIWindow_CurrentMenu = CharacterUI_Initialize(SCREEN_E);
     return;
   }
@@ -318,7 +318,7 @@
   }
   if (sDialogue_SpeakingActorNPC_ID < 0)
     v9 = 4;
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(),  window->GetHeight(), WINDOW_Dialogue, 3, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
+  pDialogueWindow = new GUIWindow_Dialogue(0, 0, window->GetWidth(), window->GetHeight(), 3, 0);//pNumberContacts = 1, v9 = 0; pNumberContacts = 2, v9 = 3;
   if (pNPCInfo->Hired() && !pNPCInfo->bHasUsedTheAbility)
   {
     if (pNPCInfo->uProfession == 10 ||    //Healer
@@ -1315,7 +1315,7 @@
   {    
     for (int i = uNumVisibleWindows; i > 0; --i)
     {
-      pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+      pWindow = pWindowList[pVisibleWindowsIdxs[i] - 1];
       if ( (signed int)pX >= (signed int)pWindow->uFrameX && (signed int)pX <= (signed int)pWindow->uFrameZ
         && (signed int)pY >= (signed int)pWindow->uFrameY && (signed int)pY <= (signed int)pWindow->uFrameW )
       {
@@ -1436,10 +1436,10 @@
       return;
     }
   }
-  if ( (signed int)pX >= (signed int)pWindowList[0].uFrameX && (signed int)pX <= (signed int)pWindowList[0].uFrameZ
-    && (signed int)pY >= (signed int)pWindowList[0].uFrameY && (signed int)pY <= (signed int)pWindowList[0].uFrameW )
+  if ( (signed int)pX >= (signed int)pWindowList[0]->uFrameX && (signed int)pX <= (signed int)pWindowList[0]->uFrameZ
+    && (signed int)pY >= (signed int)pWindowList[0]->uFrameY && (signed int)pY <= (signed int)pWindowList[0]->uFrameW )
   {
-    for ( pButton = pWindowList[0].pControlsHead; pButton != nullptr; pButton = pButton->pNext )
+    for ( pButton = pWindowList[0]->pControlsHead; pButton != nullptr; pButton = pButton->pNext )
     {
       switch (pButton->uButtonType)
       {
--- a/Game/Game.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Game/Game.cpp	Mon May 11 09:51:04 2015 +0200
@@ -328,25 +328,25 @@
                 pIcons_LOD->RemoveTexturesPackFromTextureList();
                 pGUIWindow_CurrentMenu->Release();
                 current_screen_type = SCREEN_OPTIONS;
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_8, 0, 0);
+                __debugbreak();//pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_8, 0, 0);
                 continue;
             case UIMSG_ArrowUp:
                 --pSaveListPosition;
                 if (pSaveListPosition < 0)
                     pSaveListPosition = 0;
-                GUIWindow::Create(215, 199, 17, 17, WINDOW_PressedButton2, (int)pBtnArrowUp, 0);
+                new OnButtonClick2(215, 199, 17, 17, (int)pBtnArrowUp, 0);
                 continue;
             case UIMSG_DownArrow:
                 ++pSaveListPosition;
                 if (pSaveListPosition >= uMessageParam)
                     pSaveListPosition = uMessageParam - 1;
-                GUIWindow::Create(215, 323, 17, 17, WINDOW_PressedButton2, (int)pBtnDownArrow, 0);
+                new OnButtonClick2(215, 323, 17, 17, (int)pBtnDownArrow, 0);
                 continue;
             case UIMSG_Cancel:
-                GUIWindow::Create(350, 302, 106, 42, WINDOW_CloseRestWindowBtn, (int)pBtnCancel, 0);
+                new OnCancel(350, 302, 106, 42, (int)pBtnCancel, 0);
                 continue;
             case UIMSG_SaveLoadBtn:
-                GUIWindow::Create(241, 302, 106, 42, WINDOW_SaveLoadBtn, (int)pBtnLoadSlot, 0);
+                new OnSaveLoad(241, 302, 106, 42, (int)pBtnLoadSlot, 0);
                 continue;
             case UIMSG_SelectLoadSlot:
                 if (pGUIWindow_CurrentMenu->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
@@ -490,7 +490,7 @@
                     }
                     v19 = (double)(signed int)uGammaPos * 0.1 + 0.6;
                     //pEngine->pGammaController->Initialize(v19);
-                    GUIWindow::Create(21, 161, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderLeft, (char *)1);
+                    new OnButtonClick2(21, 161, 0, 0, (int)pBtn_SliderLeft, (char *)1);
                     pAudioPlayer->PlaySound(SOUND_ClickMovingSelector, 0, 0, -1, 0, 0, 0, 0);
                     continue;
                 }
@@ -501,7 +501,7 @@
                     {
                         v21 = (double)(signed int)uGammaPos * 0.1 + 0.6;
                         //pEngine->pGammaController->Initialize(v21);
-                        GUIWindow::Create(213, 161, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderRight, (char *)1);
+                        new OnButtonClick2(213, 161, 0, 0, (int)pBtn_SliderRight, (char *)1);
                         pAudioPlayer->PlaySound(SOUND_ClickMovingSelector, 0, 0, -1, 0, 0, 0, 0);
                         continue;
                     }
@@ -531,7 +531,7 @@
                     --uMusicVolimeMultiplier;
                     if ((char)uMusicVolimeMultiplier < 1)
                         uMusicVolimeMultiplier = 0;
-                    GUIWindow::Create(243, 216, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderLeft, (char *)1);
+                    new OnButtonClick2(243, 216, 0, 0, (int)pBtn_SliderLeft, (char *)1);
                     if (uMusicVolimeMultiplier)
                         pAudioPlayer->PlaySound(SOUND_hurp, -1, 0, -1, 0, 0, pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f, 0);
 
@@ -547,7 +547,7 @@
                     ++uMusicVolimeMultiplier;
                     if ((char)uMusicVolimeMultiplier > 9)
                         uMusicVolimeMultiplier = 9;
-                    GUIWindow::Create(435, 216, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderRight, (char *)1);
+                    new OnButtonClick2(435, 216, 0, 0, (int)pBtn_SliderRight, (char *)1);
                     if (uMusicVolimeMultiplier)
                         pAudioPlayer->PlaySound(SOUND_hurp, -1, 0, -1, 0, 0, pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f, 0);
                     if (use_music_folder)
@@ -572,7 +572,7 @@
                     --uSoundVolumeMultiplier;
                     if ((char)uSoundVolumeMultiplier < 1)
                         uSoundVolumeMultiplier = 0;
-                    GUIWindow::Create(243, 162, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderLeft, (char *)1);
+                    new OnButtonClick2(243, 162, 0, 0, (int)pBtn_SliderLeft, (char *)1);
                     pAudioPlayer->SetMasterVolume(pSoundVolumeLevels[uSoundVolumeMultiplier] * 128.0f);
                     pAudioPlayer->PlaySound(SOUND_church, -1, 0, -1, 0, 0, 0, 0);
                     int v = AIL_redbook_volume(pAudioPlayer->hAILRedbook);
@@ -589,7 +589,7 @@
                     //v168 = 1;
                     v24 = 435;
                     //v154 = (int)pBtn_SliderRight;
-                    GUIWindow::Create(v24, 162, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderRight, (char *)1);
+                    new OnButtonClick2(v24, 162, 0, 0, (int)pBtn_SliderRight, (char *)1);
                     pAudioPlayer->SetMasterVolume(pSoundVolumeLevels[uSoundVolumeMultiplier] * 128.0f);
                     pAudioPlayer->PlaySound(SOUND_church, -1, 0, -1, 0, 0, 0, 0);
                     continue;
@@ -618,7 +618,7 @@
                     --uVoicesVolumeMultiplier;
                     if ((char)uVoicesVolumeMultiplier < 1)
                         uVoicesVolumeMultiplier = 0;
-                    GUIWindow::Create(243, 270, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderLeft, (char *)1);
+                    new OnButtonClick2(243, 270, 0, 0, (int)pBtn_SliderLeft, (char *)1);
                     if (!uVoicesVolumeMultiplier)
                         continue;
                     pAudioPlayer->PlaySound(SOUND_hf445a, -1, 0, -1, 0, 0, pSoundVolumeLevels[uVoicesVolumeMultiplier] * 128.0f, 0);
@@ -629,7 +629,7 @@
                     ++uVoicesVolumeMultiplier;
                     if ((char)uVoicesVolumeMultiplier > 8)
                         uVoicesVolumeMultiplier = 9;
-                    GUIWindow::Create(435, 270, 0, 0, WINDOW_PressedButton2, (int)pBtn_SliderRight, (char *)1);
+                    new OnButtonClick2(435, 270, 0, 0, (int)pBtn_SliderRight, (char *)1);
                     if (!uVoicesVolumeMultiplier)
                         continue;
                     pAudioPlayer->PlaySound(SOUND_hf445a, -1, 0, -1, 0, 0, pSoundVolumeLevels[uVoicesVolumeMultiplier] * 128.0f, 0);
@@ -687,8 +687,8 @@
                     pGUIWindow_CurrentMenu->Release();
                 pEventTimer->Pause();
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, uMessage, 0);
-                pBooksWindow = GUIWindow::Create(493u, 355u, 0, 0, WINDOW_BooksWindow, (int)pBtn_Quests, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), uMessage, 0);
+                pBooksWindow = new GUIWindow_BooksWindow(493u, 355u, 0, 0, (int)pBtn_Quests, 0);
                 bFlashQuestBook = 0;
                 continue;
             case UIMSG_OpenAutonotes:
@@ -697,8 +697,8 @@
                     pGUIWindow_CurrentMenu->Release();
                 pEventTimer->Pause();
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, uMessage, 0);
-                pBooksWindow = GUIWindow::Create(527u, 353u, 0, 0, WINDOW_BooksWindow, (int)pBtn_Autonotes, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), uMessage, 0);
+                pBooksWindow = new GUIWindow_BooksWindow(527u, 353u, 0, 0, (int)pBtn_Autonotes, 0);
                 bFlashAutonotesBook = 0;
                 continue;
             case UIMSG_OpenMapBook:
@@ -709,8 +709,8 @@
                 viewparams->sViewCenterX = pParty->vPosition.x;
                 viewparams->sViewCenterY = pParty->vPosition.y;
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, uMessage, 0);
-                pBooksWindow = GUIWindow::Create(546, 353, 0, 0, WINDOW_BooksWindow, (int)pBtn_Maps, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), uMessage, 0);
+                pBooksWindow = new GUIWindow_BooksWindow(546, 353, 0, 0, (int)pBtn_Maps, 0);
                 continue;
             case UIMSG_OpenCalendar:
                 DoThatMessageThing();
@@ -718,8 +718,8 @@
                     pGUIWindow_CurrentMenu->Release();
                 pEventTimer->Pause();
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, uMessage, 0);
-                pBooksWindow = GUIWindow::Create(570, 354, 0, 0, WINDOW_BooksWindow, (int)pBtn_Calendar, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), uMessage, 0);
+                pBooksWindow = new GUIWindow_BooksWindow(570, 354, 0, 0, (int)pBtn_Calendar, 0);
                 continue;
             case UIMSG_OpenHistoryBook:
                 DoThatMessageThing();
@@ -727,8 +727,8 @@
                     pGUIWindow_CurrentMenu->Release();
                 pEventTimer->Pause();
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, uMessage, 0);
-                pBooksWindow = GUIWindow::Create(0x258u, 0x169u, 0, 0, WINDOW_BooksWindow, (int)pBtn_History, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), uMessage, 0);
+                pBooksWindow = new GUIWindow_BooksWindow(0x258u, 0x169u, 0, 0, (int)pBtn_History, 0);
                 bFlashHistoryBook = 0;
                 continue;
             case UIMSG_Escape:// íàæàòèå Escape and return to game
@@ -1256,7 +1256,7 @@
                     if (!pGUIWindow_Settings)//Draw Menu
                     {
                         dword_6BE138 = -1;
-                        GUIWindow::Create(0x25Au, 0x1C2u, 0, 0, WINDOW_PressedButton2, (int)pBtn_GameSettings, (char *)1);
+                        new OnButtonClick2(0x25Au, 0x1C2u, 0, 0, (int)pBtn_GameSettings, (char *)1);
                         pEventTimer->Pause();
                         pAudioPlayer->StopChannels(-1, -1);
                         current_screen_type = SCREEN_MENU;
@@ -1289,7 +1289,7 @@
             case UIMSG_ScrollNPCPanel://Right and Left button for NPCPanel
                 if (uMessageParam)
                 {
-                    GUIWindow::Create(626, 179, 0, 0, WINDOW_PressedButton2, (int)pBtn_NPCRight, 0);
+                    new OnButtonClick2(626, 179, 0, 0, (int)pBtn_NPCRight, 0);
                     v37 = (pParty->pHirelings[0].pName != 0) + (pParty->pHirelings[1].pName != 0) + (unsigned __int8)pParty->field_70A - 2;
                     if (pParty->hirelingScrollPosition < v37)
                     {
@@ -1300,7 +1300,7 @@
                 }
                 else
                 {
-                    GUIWindow::Create(469, 179, 0, 0, WINDOW_PressedButton2, (int)pBtn_NPCLeft, 0);
+                    new OnButtonClick2(469, 179, 0, 0, (int)pBtn_NPCLeft, 0);
                     /*if ( pParty->field_709 )
                     {
                     --pParty->field_709;
@@ -1658,12 +1658,12 @@
 
             case UIMSG_OnCastTownPortal:
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, WINDOW_TownPortal, (char *)uMessageParam);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_TownPortal, (char *)uMessageParam);
                 continue;
 
             case UIMSG_OnCastLloydsBeacon:
                 pAudioPlayer->StopChannels(-1, -1);
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Book, WINDOW_LloydsBeacon, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_Book(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_LloydsBeacon, 0);
                 continue;
 
             case UIMSG_LloydsBeacon_FlippingBtn:
@@ -2100,7 +2100,7 @@
                 __debugbreak();
                 if (!uActiveCharacter || current_screen_type != SCREEN_GAME)
                     continue;
-                ptr_507BC8 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_68, uMessageParam, 0);
+                __debugbreak();//ptr_507BC8 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_68, uMessageParam, 0);
                 current_screen_type = SCREEN_19;
                 pEventTimer->Pause();
                 continue;
@@ -2140,7 +2140,7 @@
                     Player::_42ECB5_PlayerAttacksActor();
                 continue;
             case UIMSG_ExitRest:
-                GUIWindow::Create(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, WINDOW_CloseRestWindowBtn, (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]);// "Exit Rest"
+                new OnCancel(pButton_RestUI_Exit->uX, pButton_RestUI_Exit->uY, 0, 0, (int)pButton_RestUI_Exit, pGlobalTXT_LocalizationStrings[81]);// "Exit Rest"
                 continue;
             case UIMSG_Wait5Minutes:
                 if (_506F14_resting_stage == 2)
@@ -2149,7 +2149,7 @@
                     pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0, 0, 0);
                     continue;
                 }
-                GUIWindow::Create(pButton_RestUI_Wait5Minutes->uX, pButton_RestUI_Wait5Minutes->uY, 0, 0, WINDOW_PressedButton2,
+                new OnButtonClick2(pButton_RestUI_Wait5Minutes->uX, pButton_RestUI_Wait5Minutes->uY, 0, 0,
                     (int)pButton_RestUI_Wait5Minutes, pGlobalTXT_LocalizationStrings[238]);// "Wait 5 Minutes"
                 _506F14_resting_stage = 1;
                 _506F18_num_minutes_to_sleep = 5;
@@ -2161,7 +2161,7 @@
                     pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0, 0, 0);
                     continue;
                 }
-                GUIWindow::Create(pButton_RestUI_Wait1Hour->uX, pButton_RestUI_Wait1Hour->uY, 0, 0, WINDOW_PressedButton2,
+                new OnButtonClick2(pButton_RestUI_Wait1Hour->uX, pButton_RestUI_Wait1Hour->uY, 0, 0,
                     (int)pButton_RestUI_Wait1Hour, pGlobalTXT_LocalizationStrings[239]);// "Wait 1 Hour"
                 _506F14_resting_stage = 1;
                 _506F18_num_minutes_to_sleep = 60;
@@ -2297,7 +2297,7 @@
                     pAudioPlayer->PlaySound(SOUND_error, 0, 0, -1, 0, 0, 0, 0);
                     continue;
                 }
-                GUIWindow::Create(pButton_RestUI_WaitUntilDawn->uX, pButton_RestUI_WaitUntilDawn->uY, 0, 0, WINDOW_PressedButton2,
+                new OnButtonClick2(pButton_RestUI_WaitUntilDawn->uX, pButton_RestUI_WaitUntilDawn->uY, 0, 0,
                     (int)pButton_RestUI_WaitUntilDawn, pGlobalTXT_LocalizationStrings[237]);// "Wait until Dawn"
                 v97 = _494820_training_time(pParty->uCurrentHour);
                 _506F14_resting_stage = 1;
@@ -2340,7 +2340,7 @@
                 GameUI_SetFooterString(pTmpBuf.data());
                 continue;
             case UIMSG_ClickInstallRemoveQuickSpellBtn:
-                GUIWindow::Create(pBtn_InstallRemoveSpell->uX, pBtn_InstallRemoveSpell->uY, 0, 0, WINDOW_PressedButton2, (int)pBtn_InstallRemoveSpell, 0);
+                new OnButtonClick2(pBtn_InstallRemoveSpell->uX, pBtn_InstallRemoveSpell->uY, 0, 0, (int)pBtn_InstallRemoveSpell, 0);
                 if (!uActiveCharacter)
                     continue;
                 pPlayer10 = pPlayers[uActiveCharacter];
@@ -2467,10 +2467,10 @@
                     {
                         if (current_screen_type == SCREEN_GAME)
                         {
-                            GUIWindow::Create(476, 450, 0, 0, WINDOW_PressedButton2, (int)pBtn_CastSpell, 0);
+                            new OnButtonClick2(476, 450, 0, 0, (int)pBtn_CastSpell, 0);
                             current_screen_type = SCREEN_SPELL_BOOK;
                             pEventTimer->Pause();
-                            pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_SpellBook, 0, 0);
+                            pGUIWindow_CurrentMenu = new GUIWindow_Spellbook(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
                             pAudioPlayer->PlaySound(SOUND_48, 0, 0, -1, 0, 0, 0, 0);
                             viewparams->field_48 = 1;
                             continue;
@@ -2479,10 +2479,10 @@
                             && (current_screen_type <= SCREEN_63 || current_screen_type > SCREEN_67))
                         {
                             pGUIWindow_CurrentMenu->Release();
-                            GUIWindow::Create(476, 450, 0, 0, WINDOW_PressedButton2, (int)pBtn_CastSpell, 0);
+                            new OnButtonClick2(476, 450, 0, 0, (int)pBtn_CastSpell, 0);
                             current_screen_type = SCREEN_SPELL_BOOK;
                             pEventTimer->Pause();
-                            pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_SpellBook, 0, 0);
+                            pGUIWindow_CurrentMenu = new GUIWindow_Spellbook(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
                             pAudioPlayer->PlaySound(SOUND_48, 0, 0, -1, 0, 0, 0, 0);
                             viewparams->field_48 = 1;
                             continue;
@@ -2497,12 +2497,12 @@
                 ++pIcons_LOD->uTexturePacksCount;
                 if (!pIcons_LOD->uNumPrevLoadedFiles)
                     pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
-                GUIWindow::Create(0x230u, 0x1C2u, 0, 0, WINDOW_PressedButton2, (int)pBtn_QuickReference, 0);
+                new OnButtonClick2(0x230u, 0x1C2u, 0, 0, (int)pBtn_QuickReference, 0);
                 viewparams->bRedrawGameUI = 1;
                 pEventTimer->Pause();
                 pAudioPlayer->StopChannels(-1, -1);
                 current_screen_type = SCREEN_QUICK_REFERENCE;
-                pGUIWindow_CurrentMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_QuickReference, 5, 0);
+                pGUIWindow_CurrentMenu = new GUIWindow_QuickReference(0, 0, window->GetWidth(), window->GetHeight(), 5, 0);
                 papredoll_dbrds[2] = pIcons_LOD->LoadTexture("BUTTEXI1", TEXTURE_16BIT_PALETTE);
                 pBtn_ExitCancel = pGUIWindow_CurrentMenu->CreateButton(0x187u, 0x13Cu, 0x4Bu, 0x21u, 1, 0, UIMSG_Escape, 0, 0,
                     pGlobalTXT_LocalizationStrings[79],// "Exit"
@@ -2521,7 +2521,7 @@
                 pRenderer->SaveScreenshot("gamma.pcx", 155, 117);
                 stru_506E40.LoadPCXFile("gamma.pcx", 0);
 
-                GUIWindow::Create(0x25Au, 0x1C2u, 0, 0, WINDOW_PressedButton, (int)pBtn_GameSettings, 0);
+                new OnButtonClick(0x25Au, 0x1C2u, 0, 0, (int)pBtn_GameSettings, 0);
                 //LABEL_453:
                 /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages >= 40 )
                 continue;
@@ -2538,11 +2538,11 @@
                     books_page_number = -1;
                 continue;
             case UIMSG_ClickAwardsUpBtn:
-                GUIWindow::Create(pBtn_Up->uX, pBtn_Up->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pBtn_Up, 0);
+                new OnButtonClick3(pBtn_Up->uX, pBtn_Up->uY, 0, 0, (int)pBtn_Up, 0);
                 BtnUp_flag = 1;
                 continue;
             case UIMSG_ClickAwardsDownBtn:
-                GUIWindow::Create(pBtn_Down->uX, pBtn_Down->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pBtn_Down, 0);
+                new OnButtonClick3(pBtn_Down->uX, pBtn_Down->uY, 0, 0, (int)pBtn_Down, 0);
                 BtnDown_flag = 1;
                 continue;
             case UIMSG_ChangeDetaliz:
@@ -2573,17 +2573,17 @@
                 OnPaperdollLeftClick();
                 continue;
             case UIMSG_ClickStatsBtn:
-                pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 100;
+                current_character_screen_window = WINDOW_CharacterWindow_Stats;
                 CharacterUI_ReleaseButtons();
                 ReleaseAwardsScrollBar();
-                GUIWindow::Create(pCharacterScreen_StatsBtn->uX, pCharacterScreen_StatsBtn->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pCharacterScreen_StatsBtn, 0);
+                new OnButtonClick3(pCharacterScreen_StatsBtn->uX, pCharacterScreen_StatsBtn->uY, 0, 0, (int)pCharacterScreen_StatsBtn, 0);
                 continue;
             case UIMSG_ClickSkillsBtn:
-                pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 101;
+                current_character_screen_window = WINDOW_CharacterWindow_Skills;
                 CharacterUI_ReleaseButtons();
                 ReleaseAwardsScrollBar();
                 CharacterUI_SkillsTab_CreateButtons();
-                GUIWindow::Create(pCharacterScreen_SkillsBtn->uX, pCharacterScreen_SkillsBtn->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pCharacterScreen_SkillsBtn, 0);
+                new OnButtonClick3(pCharacterScreen_SkillsBtn->uX, pCharacterScreen_SkillsBtn->uY, 0, 0, (int)pCharacterScreen_SkillsBtn, 0);
                 continue;
             case UIMSG_SkillUp:
                 pPlayer4 = pPlayers[uActiveCharacter];
@@ -2609,20 +2609,20 @@
                 ShowStatusBarString(v87, 2);
                 continue;
             case UIMSG_ClickInventoryBtn:
-                pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 103;
+                current_character_screen_window = WINDOW_CharacterWindow_Inventory;
                 ReleaseAwardsScrollBar();
                 CharacterUI_ReleaseButtons();
-                GUIWindow::Create(pCharacterScreen_InventoryBtn->uX, pCharacterScreen_InventoryBtn->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pCharacterScreen_InventoryBtn, 0);
+                new OnButtonClick3(pCharacterScreen_InventoryBtn->uX, pCharacterScreen_InventoryBtn->uY, 0, 0, (int)pCharacterScreen_InventoryBtn, 0);
                 continue;
             case UIMSG_ClickExitCharacterWindowBtn:
-                GUIWindow::Create(pCharacterScreen_ExitBtn->uX, pCharacterScreen_ExitBtn->uY, 0, 0, WINDOW_ExitCharacterWindow, (int)pCharacterScreen_ExitBtn, 0);
+                new OnCancel2(pCharacterScreen_ExitBtn->uX, pCharacterScreen_ExitBtn->uY, 0, 0, (int)pCharacterScreen_ExitBtn, 0);
                 continue;
             case UIMSG_ClickAwardsBtn:
                 ReleaseAwardsScrollBar();
                 CharacterUI_ReleaseButtons();
                 CreateAwardsScrollBar();
-                pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[0] = 102;
-                GUIWindow::Create(pCharacterScreen_AwardsBtn->uX, pCharacterScreen_AwardsBtn->uY, 0, 0, WINDOW_CharactersPressedButton, (int)pCharacterScreen_AwardsBtn, 0);
+                current_character_screen_window = WINDOW_CharacterWindow_Awards;
+                new OnButtonClick3(pCharacterScreen_AwardsBtn->uX, pCharacterScreen_AwardsBtn->uY, 0, 0, (int)pCharacterScreen_AwardsBtn, 0);
                 FillAwardsData();
                 continue;
             case UIMSG_ClickBooksBtn:
@@ -2679,7 +2679,7 @@
                 default:
                     continue;
                 }
-                GUIWindow::Create(pButton->uX, pButton->uY, 0, 0, WINDOW_PressedButton, (int)pButton, (char *)1);
+                new OnButtonClick(pButton->uX, pButton->uY, 0, 0, (int)pButton, (char *)1);
                 continue;
             case UIMSG_SelectCharacter:
                 DoThatMessageThing();
@@ -2810,12 +2810,12 @@
                 v116 = pRenderer->pActiveZBuffer[*(int *)uNumSeconds + pSRZBufferLineOffsets[pPoint3->y]];
                 }*/
                 pButton2 = (GUIButton *)(unsigned __int16)v116;
-                GUIWindow::Create(0, 0, 0, 0, WINDOW_F, (int)pButton2, 0);
+                __debugbreak();//GUIWindow::Create(0, 0, 0, 0, WINDOW_F, (int)pButton2, 0);
                 continue;
             case UIMSG_54:
                 __debugbreak();
                 pButton2 = (GUIButton *)uMessageParam;
-                GUIWindow::Create(0, 0, 0, 0, WINDOW_22, (int)pButton2, 0);
+                __debugbreak();//GUIWindow::Create(0, 0, 0, 0, WINDOW_22, (int)pButton2, 0);
                 continue;
             case UIMSG_Game_Action:
                 DoThatMessageThing();
@@ -2825,7 +2825,7 @@
                 if (current_screen_type)
                     continue;
                 pParty->uFlags |= 2u;
-                GUIWindow::Create(519, 136, 0, 0, WINDOW_PressedButton2, (int)pBtn_ZoomOut, 0);
+                new OnButtonClick2(519, 136, 0, 0, (int)pBtn_ZoomOut, 0);
                 uNumSeconds = 131072;
                 v118 = 2 * viewparams->uMinimapZoom;
                 ++viewparams->field_28;
@@ -2855,7 +2855,7 @@
                 if (current_screen_type)
                     continue;
                 pParty->uFlags |= 2u;
-                GUIWindow::Create(574, 136, 0, 0, WINDOW_PressedButton2, (int)pBtn_ZoomIn, 0);
+                new OnButtonClick2(574, 136, 0, 0, (int)pBtn_ZoomIn, 0);
                 uNumSeconds = 32768;
                 v118 = (unsigned __int64)((signed __int64)(signed int)viewparams->uMinimapZoom << 15) >> 16;
                 --viewparams->field_28;
--- a/Game/GameOver.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Game/GameOver.cpp	Mon May 11 09:51:04 2015 +0200
@@ -58,7 +58,7 @@
     pRenderer->EndScene();
     free(_this.pPixels);
     _this.pPixels = 0;
-    window_SpeakInHouse = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+    window_SpeakInHouse = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     pWindow.uFrameX = 75;
     pWindow.uFrameY = 60;
     pWindow.uFrameWidth = 469;
--- a/Game/MainMenu.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/Game/MainMenu.cpp	Mon May 11 09:51:04 2015 +0200
@@ -18,6 +18,15 @@
 #include "Game/MainMenu.h"
 
 
+GUIButton *pMainMenu_BtnExit = nullptr;
+GUIButton *pMainMenu_BtnCredits = nullptr;
+GUIButton *pMainMenu_BtnLoad = nullptr;
+GUIButton *pMainMenu_BtnNew = nullptr;
+
+RGBTexture main_menu_background;
+
+
+
 //----- (00435748) --------------------------------------------------------
 void MainMenu_EventLoop()
 {
@@ -51,19 +60,19 @@
             switch (pUIMessageType) // For buttons of window MainMenu
             {
             case UIMSG_MainMenu_ShowPartyCreationWnd:
-                GUIWindow::Create(495, 172, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnNew, 0);
+                new OnButtonClick2(495, 172, 0, 0, (int)pMainMenu_BtnNew, 0);
                 SetCurrentMenuID(MENU_NEWGAME);
                 break;
             case UIMSG_MainMenu_ShowLoadWindow:
-                GUIWindow::Create(495, 227, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnLoad, 0);
+                new OnButtonClick2(495, 227, 0, 0, (int)pMainMenu_BtnLoad, 0);
                 SetCurrentMenuID(MENU_SAVELOAD);
                 break;
             case UIMSG_ShowCredits:
-                GUIWindow::Create(495, 282, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnCredits, 0);
+                new OnButtonClick2(495, 282, 0, 0, (int)pMainMenu_BtnCredits, 0);
                 SetCurrentMenuID(MENU_CREDITS);
                 break;
             case UIMSG_ExitToWindows:
-                GUIWindow::Create(495, 337, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnExit, 0);
+                new OnButtonClick2(495, 337, 0, 0, (int)pMainMenu_BtnExit, 0);
                 SetCurrentMenuID(MENU_EXIT_GAME);
                 break;
             case UIMSG_PlayerCreation_SelectAttribute:
@@ -81,7 +90,7 @@
                     else --pParty->pPlayers[pParam].uVoiceID;
                 } while (pParty->pPlayers[pParam].GetSexByVoice() != pSex);
                 pButton = pCreationUI_BtnPressLeft2[pParam];
-                GUIWindow::Create(pButton->uX, pButton->uY, 0, 0, WINDOW_PressedButton, (int)pButton, (char *)1);
+                new OnButtonClick(pButton->uX, pButton->uY, 0, 0, (int)pButton, (char *)1);
                 pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
                 pParty->pPlayers[pParam].PlaySound(SPEECH_PickMe, 0);
                 break;
@@ -92,7 +101,7 @@
                     pParty->pPlayers[pParam].uVoiceID = (pParty->pPlayers[pParam].uVoiceID + 1) % 20;
                 } while (pParty->pPlayers[pParam].GetSexByVoice() != pSex);
                 pButton = pCreationUI_BtnPressRight2[pParam];
-                GUIWindow::Create(pButton->uX, pButton->uY, 0, 0, WINDOW_PressedButton, (int)pButton, (char *)1);
+                new OnButtonClick(pButton->uX, pButton->uY, 0, 0, (int)pButton, (char *)1);
                 pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
                 pParty->pPlayers[pParam].PlaySound(SPEECH_PickMe, 0);
                 break;
@@ -110,7 +119,7 @@
                 pGUIWindow_CurrentMenu->pCurrentPosActiveItem = (pGUIWindow_CurrentMenu->pCurrentPosActiveItem - pGUIWindow_CurrentMenu->pStartingPosActiveItem)
                     % 7 + pGUIWindow_CurrentMenu->pStartingPosActiveItem + 7 * pParam;
                 uPlayerCreationUI_SelectedCharacter = v25;
-                GUIWindow::Create(pCreationUI_BtnPressLeft[v25]->uX, pCreationUI_BtnPressLeft[v25]->uY, 0, 0, WINDOW_PressedButton, (int)pCreationUI_BtnPressLeft[v25], (char *)1);
+                new OnButtonClick(pCreationUI_BtnPressLeft[v25]->uX, pCreationUI_BtnPressLeft[v25]->uY, 0, 0, (int)pCreationUI_BtnPressLeft[v25], (char *)1);
                 pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0.0, 0);
                 pParty->pPlayers[pParam].PlaySound(SPEECH_PickMe, 0);
                 break;
@@ -126,17 +135,17 @@
                 pGUIWindow_CurrentMenu->pCurrentPosActiveItem = (pGUIWindow_CurrentMenu->pCurrentPosActiveItem - pGUIWindow_CurrentMenu->pStartingPosActiveItem)
                     % 7 + pGUIWindow_CurrentMenu->pStartingPosActiveItem + 7 * pParam;
                 uPlayerCreationUI_SelectedCharacter = v21;
-                GUIWindow::Create(pCreationUI_BtnPressRight[v21]->uX, pCreationUI_BtnPressRight[v21]->uY, 0, 0, WINDOW_PressedButton, (int)pCreationUI_BtnPressRight[v21], (char *)1);
+                new OnButtonClick(pCreationUI_BtnPressRight[v21]->uX, pCreationUI_BtnPressRight[v21]->uY, 0, 0, (int)pCreationUI_BtnPressRight[v21], (char *)1);
                 pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
                 pParty->pPlayers[pParam].PlaySound(SPEECH_PickMe, 0);
                 break;
             case UIMSG_PlayerCreationClickPlus:
-                GUIWindow::Create(613, 393, 0, 0, WINDOW_PressedButton2, (int)pPlayerCreationUI_BtnPlus, (char *)1);
+                new OnButtonClick2(613, 393, 0, 0, (int)pPlayerCreationUI_BtnPlus, (char *)1);
                 pPlayer[uPlayerCreationUI_SelectedCharacter].IncreaseAttribute((pGUIWindow_CurrentMenu->pCurrentPosActiveItem - pGUIWindow_CurrentMenu->pStartingPosActiveItem) % 7);
                 pAudioPlayer->PlaySound(SOUND_ClickMinus, 0, 0, -1, 0, 0, 0, 0);
                 break;
             case UIMSG_PlayerCreationClickMinus:
-                GUIWindow::Create(523, 393, 0, 0, WINDOW_PressedButton2, (int)pPlayerCreationUI_BtnMinus, (char *)1);
+                new OnButtonClick2(523, 393, 0, 0, (int)pPlayerCreationUI_BtnMinus, (char *)1);
                 pPlayer[uPlayerCreationUI_SelectedCharacter].DecreaseAttribute((pGUIWindow_CurrentMenu->pCurrentPosActiveItem - pGUIWindow_CurrentMenu->pStartingPosActiveItem) % 7);
                 pAudioPlayer->PlaySound(SOUND_ClickPlus, 0, 0, -1, 0, 0, 0, 0);
                 break;
@@ -150,14 +159,14 @@
                 pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
                 break;
             case UIMSG_PlayerCreationClickOK:
-                GUIWindow::Create(580, 431, 0, 0, WINDOW_PressedButton2, (int)pPlayerCreationUI_BtnOK, 0);
+                new OnButtonClick2(580, 431, 0, 0, (int)pPlayerCreationUI_BtnOK, 0);
                 if (PlayerCreation_GetUnspentAttributePointCount() || !PlayerCreation_Choose4Skills())
                     GameUI_Footer_TimeLeft = GetTickCount() + 4000;
                 else
                     uGameState = GAME_STATE_STARTING_NEW_GAME;
                 break;
             case UIMSG_PlayerCreationClickReset:
-                GUIWindow::Create(527, 431, 0, 0, WINDOW_PressedButton2, (int)pPlayerCreationUI_BtnReset, 0);
+                new OnButtonClick2(527, 431, 0, 0, (int)pPlayerCreationUI_BtnReset, 0);
                 pParty->Reset();
                 break;
             case UIMSG_PlayerCreationRemoveUpSkill:
@@ -218,7 +227,7 @@
                 }
                 break;
             case UIMSG_SaveLoadBtn:
-                GUIWindow::Create(pGUIWindow_CurrentMenu->uFrameX + 241, pGUIWindow_CurrentMenu->uFrameY + 302, 61, 28, WINDOW_SaveLoadBtn, (int)pBtnLoadSlot, 0);
+                new OnSaveLoad(pGUIWindow_CurrentMenu->uFrameX + 241, pGUIWindow_CurrentMenu->uFrameY + 302, 61, 28, (int)pBtnLoadSlot, 0);
                 break;
             case UIMSG_DownArrow:
                 ++pSaveListPosition;
@@ -227,24 +236,24 @@
                 if (pSaveListPosition < 1)
                     pSaveListPosition = 0;
                 pWindow = pGUIWindow_CurrentMenu;
-                GUIWindow::Create(pWindow->uFrameX + 215, pGUIWindow_CurrentMenu->uFrameY + 323, 0, 0, WINDOW_PressedButton2, (int)pBtnDownArrow, 0);
+                new OnButtonClick2(pWindow->uFrameX + 215, pGUIWindow_CurrentMenu->uFrameY + 323, 0, 0, (int)pBtnDownArrow, 0);
                 break;
             case UIMSG_Cancel:
-                GUIWindow::Create(pGUIWindow_CurrentMenu->uFrameX + 350, pGUIWindow_CurrentMenu->uFrameY + 302, 61, 28, WINDOW_LoadGame_CancelBtn, (int)pBtnCancel, 0);
+                new OnCancel3(pGUIWindow_CurrentMenu->uFrameX + 350, pGUIWindow_CurrentMenu->uFrameY + 302, 61, 28, (int)pBtnCancel, 0);
                 break;
             case UIMSG_ArrowUp:
                 --pSaveListPosition;
                 if (pSaveListPosition < 0)
                     pSaveListPosition = 0;
                 pWindow = pGUIWindow_CurrentMenu;
-                GUIWindow::Create(pWindow->uFrameX + 215, pGUIWindow_CurrentMenu->uFrameY + 197, 0, 0, WINDOW_PressedButton2, (int)pBtnArrowUp, 0);
+                new OnButtonClick2(pWindow->uFrameX + 215, pGUIWindow_CurrentMenu->uFrameY + 197, 0, 0, (int)pBtnArrowUp, 0);
                 break;
             case UIMSG_AD:
-                GUIWindow::Create(pMainMenu_BtnNew->uX, pMainMenu_BtnNew->uY, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnNew, 0);
+                new OnButtonClick2(pMainMenu_BtnNew->uX, pMainMenu_BtnNew->uY, 0, 0, (int)pMainMenu_BtnNew, 0);
                 SetCurrentMenuID(MENU_LoadingProcInMainMenu);
                 break;
             case UIMSG_AE:
-                GUIWindow::Create(pMainMenu_BtnExit->uX, pMainMenu_BtnExit->uY, 0, 0, WINDOW_PressedButton2, (int)pMainMenu_BtnExit, 0);
+                new OnButtonClick2(pMainMenu_BtnExit->uX, pMainMenu_BtnExit->uY, 0, 0, (int)pMainMenu_BtnExit, 0);
                 SetCurrentMenuID(MENU_DebugBLVLevel);
                 break;
             case UIMSG_Escape:
@@ -298,8 +307,8 @@
                 {
                     pIcons_LOD->RemoveTexturesPackFromTextureList();
                     //crt_deconstruct_ptr_6A0118();
-                    pTexture_PCX.Release();
-                    pTexture_PCX.Load("title.pcx", 0);
+                    main_menu_background.Release();
+                    main_menu_background.Load("title.pcx", 0);
                     SetCurrentMenuID(MENU_MAIN);
                     v15 = 1;
                     pGUIWindow_CurrentMenu->Release();
@@ -355,7 +364,7 @@
 
     pIcons_LOD->_inlined_sub2();
 
-    pWindow_MainMenu = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+    pWindow_MainMenu = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
     Texture* pNew = pIcons_LOD->LoadTexturePtr("title_new", TEXTURE_16BIT_PALETTE);
     Texture* pLoad = pIcons_LOD->LoadTexturePtr("title_load", TEXTURE_16BIT_PALETTE);
     Texture* pCredits = pIcons_LOD->LoadTexturePtr("title_cred", TEXTURE_16BIT_PALETTE);
@@ -366,8 +375,8 @@
     pMainMenu_BtnCredits = pWindow_MainMenu->CreateButton(495, 282, pCredits->uTextureWidth, pCredits->uTextureHeight, 1, 0, UIMSG_ShowCredits, 2, 'C', "", pCredits, 0);
     pMainMenu_BtnExit = pWindow_MainMenu->CreateButton(495, 337, pExit->uTextureWidth, pExit->uTextureHeight, 1, 0, UIMSG_ExitToWindows, 3, 0, "", pExit, 0);
 
-    pTexture_PCX.Release();
-    pTexture_PCX.Load("title.pcx", 0);
+    main_menu_background.Release();
+    main_menu_background.Load("title.pcx", 0);
     SetCurrentMenuID(MENU_MAIN);
     SetForegroundWindow(window->GetApiHandle());
     SendMessageW(window->GetApiHandle(), WM_ACTIVATEAPP, 1, 0);
@@ -380,9 +389,9 @@
         {
             if (current_screen_type != SCREEN_LOADGAME)
             {
-                pTexture_PCX.Release();
-                pTexture_PCX.Load("lsave640.pcx", 0);
-                pGUIWindow2 = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_MainMenu, 0, 0);
+                main_menu_background.Release();
+                main_menu_background.Load("lsave640.pcx", 0);
+                pGUIWindow2 = new GUIWindow(0, 0, window->GetWidth(), window->GetHeight(), 0, 0);
                 current_screen_type = SCREEN_LOADGAME;
                 LoadUI_Load(0);
             }
@@ -404,7 +413,7 @@
         }
 
         pRenderer->BeginScene();
-        pRenderer->DrawTextureNew(0, 0, &pTexture_PCX);
+        pRenderer->DrawTextureNew(0, 0, &main_menu_background);
 
         MainMenu_EventLoop();
         GUI_UpdateWindows();
@@ -464,7 +473,7 @@
     GUI_UpdateWindows();
     pRenderer->EndScene();
     pRenderer->Present();
-    pTexture_PCX.Release();
+    main_menu_background.Release();
     if (pGUIWindow2)
     {
         pGUIWindow2->Release();
--- a/Game/MainMenu.h	Sun May 10 03:21:14 2015 +0200
+++ b/Game/MainMenu.h	Mon May 11 09:51:04 2015 +0200
@@ -1,4 +1,7 @@
 #pragma once
 
 void MainMenu_Loop();
-void MainMenu_EventLoop();
\ No newline at end of file
+void MainMenu_EventLoop();
+
+
+extern struct RGBTexture main_menu_background;
\ No newline at end of file
--- a/IO/Mouse.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/IO/Mouse.cpp	Mon May 11 09:51:04 2015 +0200
@@ -473,10 +473,10 @@
     y = pY;
     for ( int i = uNumVisibleWindows; i >= 0; --i )
     {
-      if ( x >= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1].uFrameX && x <= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1].uFrameZ
-        && y >= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1].uFrameY && y <= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1].uFrameW )
+      if ( x >= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1]->uFrameX && x <= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1]->uFrameZ
+        && y >= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1]->uFrameY && y <= (signed int)pWindowList[pVisibleWindowsIdxs[i] - 1]->uFrameW )
       {
-        for ( control = pWindowList[pVisibleWindowsIdxs[i] - 1].pControlsHead; control; control = control->pNext )
+        for ( control = pWindowList[pVisibleWindowsIdxs[i] - 1]->pControlsHead; control; control = control->pNext )
         {
           if ( control->uButtonType == 1 )
           {
@@ -604,30 +604,30 @@
   //while ( 1 )
   {
     v3 = pVisibleWindowsIdxs[i] - 1;
-    if (!pWindowList[v3].receives_keyboard_input)
+    if (!pWindowList[v3]->receives_keyboard_input)
       continue;
 
     switch (vkKey)
     {
       case VK_LEFT:
       {
-        v12 = pWindowList[v3].field_34;
-        if ( pWindowList[v3].pCurrentPosActiveItem - pWindowList[v3].pStartingPosActiveItem - v12 >= 0 )
+        v12 = pWindowList[v3]->field_34;
+        if ( pWindowList[v3]->pCurrentPosActiveItem - pWindowList[v3]->pStartingPosActiveItem - v12 >= 0 )
         {
           v8 = current_screen_type == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem -= v12;
+          pWindowList[v3]->pCurrentPosActiveItem -= v12;
           if ( v8 )
           {
             pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
             //v2 = pMessageQueue_50CBD0->uNumMessages;
           }
         }
-        if ( pWindowList[v3].field_30 != 0 )
+        if ( pWindowList[v3]->field_30 != 0 )
         {
           break;
         }
-        pButton = pWindowList[v3].pControlsHead;
-        v13 = pWindowList[v3].pCurrentPosActiveItem;
+        pButton = pWindowList[v3]->pControlsHead;
+        v13 = pWindowList[v3]->pCurrentPosActiveItem;
         if ( v13 > 0)
         {
           do
@@ -642,23 +642,23 @@
       }
       case VK_RIGHT:
       {
-        v7 = pWindowList[v3].pCurrentPosActiveItem + pWindowList[v3].field_34;
-        if ( v7 < pWindowList[v3].pNumPresenceButton + pWindowList[v3].pStartingPosActiveItem )
+        v7 = pWindowList[v3]->pCurrentPosActiveItem + pWindowList[v3]->field_34;
+        if ( v7 < pWindowList[v3]->pNumPresenceButton + pWindowList[v3]->pStartingPosActiveItem )
         {
           v8 = current_screen_type == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem = v7;
+          pWindowList[v3]->pCurrentPosActiveItem = v7;
           if ( v8 )
           {
             pAudioPlayer->PlaySound(SOUND_SelectingANewCharacter, 0, 0, -1, 0, 0, 0, 0);
             //v2 = pMessageQueue_50CBD0->uNumMessages;
           }
         }
-        if ( pWindowList[v3].field_30 != 0 )
+        if ( pWindowList[v3]->field_30 != 0 )
         {
           break;
         }
-        pButton = pWindowList[v3].pControlsHead;
-        v10 = pWindowList[v3].pCurrentPosActiveItem;
+        pButton = pWindowList[v3]->pControlsHead;
+        v10 = pWindowList[v3]->pCurrentPosActiveItem;
         if ( v10 > 0)
         {
           do
@@ -673,16 +673,16 @@
       }
       case VK_DOWN:
       {
-        v17 = pWindowList[v3].pStartingPosActiveItem;
-        v18 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v18 >= pWindowList[v3].pNumPresenceButton + v17 - 1 )
-          pWindowList[v3].pCurrentPosActiveItem = v17;
+        v17 = pWindowList[v3]->pStartingPosActiveItem;
+        v18 = pWindowList[v3]->pCurrentPosActiveItem;
+        if ( v18 >= pWindowList[v3]->pNumPresenceButton + v17 - 1 )
+          pWindowList[v3]->pCurrentPosActiveItem = v17;
         else
-          pWindowList[v3].pCurrentPosActiveItem = v18 + 1;
-        if ( pWindowList[v3].field_30 != 0 )
+          pWindowList[v3]->pCurrentPosActiveItem = v18 + 1;
+        if ( pWindowList[v3]->field_30 != 0 )
           return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v20 = pWindowList[v3].pCurrentPosActiveItem;
+        pButton = pWindowList[v3]->pControlsHead;
+        v20 = pWindowList[v3]->pCurrentPosActiveItem;
         if ( v20 > 0)
         {
           do
@@ -698,13 +698,13 @@
       case VK_SELECT:
       {
         pMouse->GetClickPos(&uClickX, &uClickY);
-        v4 = pWindowList[v3].pStartingPosActiveItem;
-        v28 = v4 + pWindowList[v3].pNumPresenceButton;
-        if ( v4 < v4 + pWindowList[v3].pNumPresenceButton )
+        v4 = pWindowList[v3]->pStartingPosActiveItem;
+        v28 = v4 + pWindowList[v3]->pNumPresenceButton;
+        if ( v4 < v4 + pWindowList[v3]->pNumPresenceButton )
         {
           while ( 1 )
           {
-            pButton = pWindowList[v3].pControlsHead;
+            pButton = pWindowList[v3]->pControlsHead;
             if ( v4 > 0 )
             {
               v6 = v4;
@@ -731,7 +731,7 @@
               //continue;
             }
           }
-          pWindowList[v3].pCurrentPosActiveItem = v4;
+          pWindowList[v3]->pCurrentPosActiveItem = v4;
           return true;
         }
         //v2 = pMessageQueue_50CBD0->uNumMessages;
@@ -739,18 +739,18 @@
       }
       case VK_UP:
       {
-        v22 = pWindowList[v3].pCurrentPosActiveItem;
-        v23 = pWindowList[v3].pStartingPosActiveItem;
+        v22 = pWindowList[v3]->pCurrentPosActiveItem;
+        v23 = pWindowList[v3]->pStartingPosActiveItem;
         if ( v22 <= v23 )
-          v24 = pWindowList[v3].pNumPresenceButton + v23 - 1;
+          v24 = pWindowList[v3]->pNumPresenceButton + v23 - 1;
         else
           v24 = v22 - 1;
-        v8 = pWindowList[v3].field_30 == 0;
-        pWindowList[v3].pCurrentPosActiveItem = v24;
+        v8 = pWindowList[v3]->field_30 == 0;
+        pWindowList[v3]->pCurrentPosActiveItem = v24;
         if ( !v8 )
           return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v25 = pWindowList[v3].pCurrentPosActiveItem;
+        pButton = pWindowList[v3]->pControlsHead;
+        v25 = pWindowList[v3]->pCurrentPosActiveItem;
         if ( v25 > 0)
         {
           do
@@ -765,13 +765,13 @@
       }
       case VK_NEXT:
       {  
-        if ( pWindowList[v3].field_30 != 0 )   //crashed at skill draw
+        if ( pWindowList[v3]->field_30 != 0 )   //crashed at skill draw
         {
           pMouse->GetClickPos(&uClickX, &uClickY);
-          v29 = pWindowList[v3].pStartingPosActiveItem + pWindowList[v3].pNumPresenceButton; //num buttons more than buttons 
-          for ( v4 = pWindowList[v3].pStartingPosActiveItem; v4 < v29; ++v4 )
+          v29 = pWindowList[v3]->pStartingPosActiveItem + pWindowList[v3]->pNumPresenceButton; //num buttons more than buttons 
+          for ( v4 = pWindowList[v3]->pStartingPosActiveItem; v4 < v29; ++v4 )
           {
-            pButton = pWindowList[v3].pControlsHead;
+            pButton = pWindowList[v3]->pControlsHead;
             if ( v4 > 0 )
             {
               for ( v15 = v4; v15; --v15 )
@@ -780,7 +780,7 @@
             if ( (signed int)uClickX >= (signed int)pButton->uX && (signed int)uClickX <= (signed int)pButton->uZ
               && (signed int)uClickY >= (signed int)pButton->uY && (signed int)uClickY <= (signed int)pButton->uW )
             {
-              pWindowList[v3].pCurrentPosActiveItem = v4;
+              pWindowList[v3]->pCurrentPosActiveItem = v4;
               return true;
             }
           }
--- a/OSWindow.cpp	Sun May 10 03:21:14 2015 +0200
+++ b/OSWindow.cpp	Mon May 11 09:51:04 2015 +0200
@@ -796,11 +796,11 @@
       SendMessageW(api_handle, WM_DESTROY, 0, 0);
     break;
 
-    case 104: //F4 button
+    /*case 104: //F4 button
       pRenderer->ChangeBetweenWinFullscreenModes();
       if (pArcomageGame->bGameInProgress)
         pArcomageGame->field_F6 = 1;
-    break;
+    break;*/
 
         //SubMenu "Party"
     case 40006:  pParty->SetFood(pParty->uNumFoodRations + 20); break;