changeset 2502:a77c34acdbc9

Media folder
author Ritor1
date Fri, 19 Sep 2014 05:13:32 +0600
parents 0ff6a9e9bf7f
children 502246699451
files AIL.cpp AIL.h Arcomage/Arcomage.cpp AudioPlayer.cpp AudioPlayer.h Bink_Smacker.cpp Bink_Smacker.h Build/Visual Studio 2012/World of Might and Magic.vcxproj Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters DirectX11.cpp DirectX11.h Engine/Events.cpp Engine/Game.cpp Engine/Graphics/Indoor.cpp Engine/Graphics/Outdoor.cpp Engine/Graphics/Overlays.cpp Engine/Graphics/Render.cpp Engine/Graphics/Viewport.cpp Engine/MMT.cpp Engine/Objects/Actor.cpp Engine/Objects/Chest.cpp Engine/Objects/Items.cpp Engine/Objects/NPC.cpp Engine/Objects/Player.cpp Engine/Objects/SpriteObject.cpp Engine/Party.cpp Engine/SaveLoad.cpp Engine/Spells/CastSpellInfo.cpp Engine/Spells/Spells.cpp Engine/Timer.cpp Engine/TurnEngine/TurnEngine.cpp Engine/mm7_data.cpp GUI/GUIButton.cpp GUI/GUIButton.h GUI/GUIFont.cpp GUI/GUIFont.h GUI/GUIProgressBar.cpp GUI/GUIProgressBar.h GUI/GUIWindow.cpp GUI/GUIWindow.h GUI/UI/Books/UIMapBook.cpp GUI/UI/Books/UINotesBooks.cpp GUI/UI/Books/UISpellBook.cpp GUI/UI/UIArena.cpp GUI/UI/UIBooks.cpp GUI/UI/UICharacter.cpp GUI/UI/UIGuilds.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 GUIButton.cpp GUIButton.h GUIFont.cpp GUIFont.h GUIProgressBar.cpp GUIProgressBar.h GUIWindow.cpp GUIWindow.h IO/Keyboard.cpp IO/Keyboard.h IO/Mouse.cpp IO/Mouse.h Keyboard.cpp Keyboard.h Media/Audio/AIL.cpp Media/Audio/AIL.h Media/Audio/AudioPlayer.cpp Media/Audio/AudioPlayer.h Media/Audio/OpenALSoundProvider.h Media/MediaPlayer.cpp Media/MediaPlayer.h Media/Video/Bink_Smacker.cpp Media/Video/Bink_Smacker.h MediaPlayer.cpp MediaPlayer.h Mouse.cpp Mouse.h OSWindow.cpp OpenALSoundProvider.h
diffstat 86 files changed, 14668 insertions(+), 14964 deletions(-) [+]
line wrap: on
line diff
--- a/AIL.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "AIL.h"
-
-
-
-
-int (__stdcall *mss32_AIL_startup)() = 0;
-HREDBOOK (__stdcall *mss32_AIL_redbook_open_drive)(long) = 0;
-int (__stdcall *mss32_AIL_set_preference)(unsigned int, int) = 0;
-int (__stdcall *mss32_AIL_waveOutOpen)(HDIGDRIVER *, HWAVEOUT *, int, WAVEFORMAT *) = 0;
-int (__stdcall *mss32_AIL_get_preference)(unsigned int) = 0;
-int (__stdcall *mss32_AIL_digital_configuration)(HDIGDRIVER, int *, int *, char *) = 0;
-HSAMPLE (__stdcall *mss32_AIL_allocate_sample_handle)(HDIGDRIVER) = 0;
-void (__stdcall *mss32_AIL_3D_provider_attribute)(HPROVIDER, char *, void *) = 0;
-unsigned int (__stdcall *mss32_AIL_redbook_tracks)(HREDBOOK) = 0;
-int (__stdcall *mss32_AIL_redbook_volume)(HREDBOOK) = 0;
-unsigned int (__stdcall *mss32_AIL_redbook_stop)(HREDBOOK) = 0;
-void (__stdcall *mss32_AIL_set_digital_master_volume)(HDIGDRIVER, float) = 0;
-int (__stdcall *mss32_AIL_redbook_set_volume)(HREDBOOK, int) = 0;
-void (__stdcall *mss32_AIL_waveOutClose)(HDIGDRIVER) = 0;
-unsigned int (__stdcall *mss32_AIL_redbook_pause)(HREDBOOK) = 0;
-void (__stdcall *mss32_AIL_redbook_track_info)(HREDBOOK, unsigned int, unsigned int *, unsigned int *) = 0;
-unsigned int (__stdcall *mss32_AIL_redbook_play)(HREDBOOK, unsigned int, unsigned int) = 0;
-unsigned int (__stdcall *mss32_AIL_redbook_resume)(HREDBOOK) = 0;
-AIL::Sample::Status (__stdcall *mss32_AIL_sample_status)(HSAMPLE) = 0;
-int (__stdcall *mss32_AIL_sample_volume)(HSAMPLE) = 0;
-int (__stdcall *mss32_AIL_enumerate_3D_providers)(int *, HPROVIDER *, char **) = 0;
-DWORD (__stdcall *mss32_AIL_open_3D_provider)(HPROVIDER) = 0;
-int (__stdcall *mss32_AIL_end_sample)(HSAMPLE) = 0;
-int (__stdcall *mss32_AIL_set_sample_volume)(HSAMPLE, long) = 0;
-int (__stdcall *mss32_AIL_set_sample_pan)(HSAMPLE, long) = 0;
-void (__stdcall *mss32_AIL_end_sequence)(HSEQUENCE) = 0;
-void (__stdcall *mss32_AIL_pause_stream)(HSTREAM, int) = 0;
-void (__stdcall *mss32_AIL_init_sample)(HSAMPLE) = 0;
-int (__stdcall *mss32_AIL_set_sample_file)(HSAMPLE, const void *, int) = 0;
-void (__stdcall *mss32_AIL_set_sample_loop_count)(HSAMPLE, int) = 0;
-void (__stdcall *mss32_AIL_set_sample_playback_rate)(HSAMPLE, int) = 0;
-void (__stdcall *mss32_AIL_sample_ms_position)(HSAMPLE, int *, int *) = 0;
-int (__stdcall *mss32_AIL_start_sample)(HSAMPLE) = 0;
-AILFILETYPE (__stdcall *mss32_AIL_file_type)(void *, int) = 0;
-int (__stdcall *mss32_AIL_WAV_info)(void *, AILSOUNDINFO *) = 0;
-int (__stdcall *mss32_AIL_decompress_ADPCM)(AILSOUNDINFO *, void *, void *) = 0;
-HREDBOOK (__stdcall *mss32_AIL_redbook_open)(int) = 0;
-void (__stdcall *mss32_AIL_release_sample_handle)(HSAMPLE) = 0;
-void MSS32_DLL_Initialize()
-{
- HMODULE pDll = LoadLibraryW(L"mss32.dll");
-
- mss32_AIL_startup = (int (__stdcall *)())GetProcAddress(pDll, "_AIL_startup@0");
- mss32_AIL_redbook_open_drive = (HREDBOOK (__stdcall *)(long))GetProcAddress(pDll, "_AIL_redbook_open_drive@4");
- mss32_AIL_set_preference = (int (__stdcall *)(unsigned int, int))GetProcAddress(pDll, "_AIL_set_preference@8");
- mss32_AIL_waveOutOpen = (int (__stdcall *)(HDIGDRIVER *, HWAVEOUT *, int, WAVEFORMAT *))GetProcAddress(pDll, "_AIL_waveOutOpen@16");
- mss32_AIL_get_preference = (int (__stdcall *)(unsigned int))GetProcAddress(pDll, "_AIL_get_preference@4");
- mss32_AIL_digital_configuration = (int (__stdcall *)(HDIGDRIVER, int *, int *, char *))GetProcAddress(pDll, "_AIL_digital_configuration@16");
- mss32_AIL_allocate_sample_handle = (HSAMPLE (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_AIL_allocate_sample_handle@4");
- mss32_AIL_3D_provider_attribute = (void (__stdcall *)(HPROVIDER,char *, void *))GetProcAddress(pDll, "_AIL_3D_provider_attribute@12");
- mss32_AIL_redbook_tracks = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_tracks@4");
- mss32_AIL_redbook_volume = (int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_volume@4");
- mss32_AIL_redbook_stop = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_stop@4");
- mss32_AIL_set_digital_master_volume = (void (__stdcall *)(HDIGDRIVER, float))GetProcAddress(pDll, "_AIL_set_digital_master_volume@8");
- mss32_AIL_redbook_set_volume = (int (__stdcall *)(HREDBOOK, int))GetProcAddress(pDll, "_AIL_redbook_set_volume@8");
- mss32_AIL_waveOutClose = (void (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_AIL_waveOutClose@4");
- mss32_AIL_redbook_pause = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_pause@4");
- mss32_AIL_redbook_track_info = (void (__stdcall *)(HREDBOOK, unsigned int, unsigned int *, unsigned int *))GetProcAddress(pDll, "_AIL_redbook_track_info@16");
- mss32_AIL_redbook_play = (unsigned int (__stdcall *)(HREDBOOK, unsigned int, unsigned int))GetProcAddress(pDll, "_AIL_redbook_play@12");
- mss32_AIL_redbook_resume = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_resume@4");
- mss32_AIL_sample_status = (AIL::Sample::Status (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_sample_status@4");
- mss32_AIL_sample_volume = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_sample_volume@4");
- mss32_AIL_enumerate_3D_providers = (int (__stdcall *)(int *, HPROVIDER *, char **))GetProcAddress(pDll, "_AIL_enumerate_3D_providers@12");
- mss32_AIL_open_3D_provider = (DWORD (__stdcall *)(HPROVIDER))GetProcAddress(pDll, "_AIL_open_3D_provider@4");
- mss32_AIL_end_sample = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_end_sample@4");
- mss32_AIL_set_sample_volume = (int (__stdcall *)(HSAMPLE, long))GetProcAddress(pDll, "_AIL_set_sample_volume@8");
- mss32_AIL_set_sample_pan = (int (__stdcall *)(HSAMPLE, long))GetProcAddress(pDll, "_AIL_set_sample_pan@8");
- mss32_AIL_end_sequence = (void (__stdcall *)(HSEQUENCE))GetProcAddress(pDll, "_AIL_end_sequence@4");
- mss32_AIL_pause_stream = (void (__stdcall *)(HSTREAM, int))GetProcAddress(pDll, "_AIL_pause_stream@8");
- mss32_AIL_init_sample = (void (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_init_sample@4");
- mss32_AIL_set_sample_file = (int (__stdcall *)(HSAMPLE, const void *, int))GetProcAddress(pDll, "_AIL_set_sample_file@12");
- mss32_AIL_set_sample_loop_count = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_loop_count@8");
- mss32_AIL_set_sample_playback_rate = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_playback_rate@8");
- mss32_AIL_sample_ms_position = (void (__stdcall *)(HSAMPLE, int *, int *))GetProcAddress(pDll, "_AIL_sample_ms_position@12");
- mss32_AIL_start_sample = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_start_sample@4");
- mss32_AIL_file_type = (AILFILETYPE (__stdcall *)(void *, int))GetProcAddress(pDll, "_AIL_file_type@8");
- mss32_AIL_WAV_info = (int (__stdcall *)(void *, AILSOUNDINFO *))GetProcAddress(pDll, "_AIL_WAV_info@8");
- mss32_AIL_decompress_ADPCM = (int (__stdcall *)(AILSOUNDINFO *, void *, void *))GetProcAddress(pDll, "_AIL_decompress_ADPCM@12");
- mss32_AIL_redbook_open = (HREDBOOK (__stdcall *)(int))GetProcAddress(pDll, "_AIL_redbook_open@4");
- mss32_AIL_release_sample_handle = (void (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_release_sample_handle@4");
-}
-
-
-
-unsigned int __stdcall AIL_redbook_play(HREDBOOK hRedbook, unsigned int uStartMS, unsigned int uEndMS)
-{
- return (mss32_AIL_redbook_play)(hRedbook, uStartMS, uEndMS);
-}
-
-void __stdcall AIL_redbook_track_info(HREDBOOK hRedbook, unsigned int uTrackNum, unsigned int *pStartMS, unsigned int *pEndMS)
-{
- (mss32_AIL_redbook_track_info)(hRedbook, uTrackNum, pStartMS, pEndMS);
-}
-
-unsigned int __stdcall AIL_redbook_resume(HREDBOOK hRedbook)
-{
- return (mss32_AIL_redbook_resume)(hRedbook);
-}
-
-int __stdcall AIL_enumerate_3D_providers(int *a1, HPROVIDER *pOutProv, char **pOutName)
-{
- return (mss32_AIL_enumerate_3D_providers)(a1, pOutProv, pOutName);
-}
-HREDBOOK __stdcall AIL_redbook_open(int w)
-{
- return (mss32_AIL_redbook_open)(w);
-}
-
-
-int __stdcall AIL_sample_volume(HSAMPLE s)
-{
- return (mss32_AIL_sample_volume)(s);
-}
-
-AIL::Sample::Status __stdcall AIL_sample_status(HSAMPLE a1)
-{
- return (mss32_AIL_sample_status)(a1);
-}
-
-// sub_4D8304: using guessed type int __stdcall AIL_set_digital_master_volume(_DWORD, _DWORD);
-void __stdcall AIL_set_digital_master_volume(HDIGDRIVER hDrv, float master_volume)
-{
- (mss32_AIL_set_digital_master_volume)(hDrv, master_volume);
-}
-
-// sub_4D8370: using guessed type int __stdcall AIL_allocate_sample_handle(_DWORD);
-HSAMPLE __stdcall AIL_allocate_sample_handle(HDIGDRIVER hDrv)
-{
- return (mss32_AIL_allocate_sample_handle)(hDrv);
-}
-
-// sub_4D8308: using guessed type int __fastcall AIL_redbook_set_volume(_DWORD, _DWORD, _DWORD, _DWORD);
-int __stdcall AIL_redbook_set_volume(HREDBOOK hRedbook, int volume)
-{
- return (mss32_AIL_redbook_set_volume)(hRedbook, volume);
-}
-
-// sub_4D8324: using guessed type int __stdcall AIL_redbook_stop(_DWORD);
-unsigned int __stdcall AIL_redbook_stop(HREDBOOK hRedbook)
-{
- return (mss32_AIL_redbook_stop)(hRedbook);
-}
-
-// sub_4D835C: using guessed type int __stdcall AIL_startup();
-int __stdcall AIL_startup()
-{
- return (mss32_AIL_startup)();
-}
-
-// sub_4D8360: using guessed type int __stdcall AIL_redbook_open_drive(_DWORD);
-HREDBOOK __stdcall AIL_redbook_open_drive(long drive)
-{
- return (mss32_AIL_redbook_open_drive)(drive);
-}
-
-// sub_4D834C: using guessed type int __stdcall AIL_waveOutOpen(_DWORD, _DWORD, _DWORD, _DWORD);
-int __stdcall AIL_waveOutOpen(_DIG_DRIVER **drv, HWAVEOUT *phWaveOut, int wDeviceID, WAVEFORMAT *pFormat)
-{
- return (mss32_AIL_waveOutOpen)(drv, phWaveOut, wDeviceID, pFormat);
-}
-
-
-DWORD __stdcall AIL_open_3D_provider(HPROVIDER a2)
-{
- return (mss32_AIL_open_3D_provider)(a2);
-}
-
-void __stdcall AIL_3D_provider_attribute(HPROVIDER lib, char *name, void *val)
-{ 
- (mss32_AIL_3D_provider_attribute)(lib,name,val);
-}
-
-// sub_4D8374: using guessed type int __stdcall AIL_redbook_tracks(_DWORD);
-unsigned int __stdcall AIL_redbook_tracks(HREDBOOK hRedbook)
-{
- return (mss32_AIL_redbook_tracks)(hRedbook);
-}
-
-// sub_4D83B0: using guessed type int __stdcall AIL_redbook_volume(_DWORD);
-int __stdcall AIL_redbook_volume(HREDBOOK hRedbook)
-{
- return (mss32_AIL_redbook_volume)(hRedbook);
-}
-
-// sub_4D8348: using guessed type int __stdcall AIL_set_preference(_DWORD, _DWORD);
-int __stdcall AIL_set_preference(unsigned int number, int value)
-{
- return (mss32_AIL_set_preference)(number, value);
-}
-
-// sub_4D8350: using guessed type int __stdcall AIL_digital_configuration(_DWORD, _DWORD, _DWORD, _DWORD);
-int __stdcall AIL_digital_configuration(HDIGDRIVER drv, int *rate, int *format, char *string)
-{
- return (mss32_AIL_digital_configuration)(drv, rate, format, string);
-}
-
-// sub_4D8354: using guessed type int __stdcall AIL_get_preference(_DWORD);
-int __stdcall AIL_get_preference(unsigned int number)
-{
- return (mss32_AIL_get_preference)(number);
-}
-
-void __stdcall AIL_waveOutClose(HDIGDRIVER drvr)
-{
- (mss32_AIL_waveOutClose)(drvr);
-}
-
-// sub_4D8320: using guessed type int __stdcall AIL_redbook_pause(_DWORD);
-unsigned int __stdcall AIL_redbook_pause(HREDBOOK hRedbook)
-{
- return (mss32_AIL_redbook_pause)(hRedbook);
-}
-
-int __stdcall AIL_set_3D_provider_preference(HPROVIDER a1, const char *a2, int *a3)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_allocate_3D_sample_handle(HPROVIDER)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_sample_float_distances(void *a1, long a2, long a3, long a4, long a5)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_sample_volume(void *a1, long a2)
-{
- __asm int 3
- return 0;
-}
-
-void __stdcall AIL_release_sample_handle(HSAMPLE s)
-{
- (mss32_AIL_release_sample_handle)(s);
-}
-
-int __stdcall AIL_release_3D_sample_handle(void *a1)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_close_3D_provider(HPROVIDER)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_redbook_close(HREDBOOK a1)
-{
- __asm int 3
- return 0;
-}
-
-// sub_4D8344: using guessed type int __stdcall AIL_shutdown();
-int __stdcall AIL_shutdown()
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_end_sample(HSAMPLE a1)
-{
- return (mss32_AIL_end_sample)(a1);
-}
-
-int __stdcall AIL_end_3D_sample(void *a1)
-{
- __debugbreak();
- return 0;
-}
-
-
-void __stdcall AIL_end_sequence(HSEQUENCE a1)
-{
- (mss32_AIL_end_sequence)(a1);
-}
-
-void __stdcall AIL_pause_stream(HSTREAM a1, int onoff)
-{
- (mss32_AIL_pause_stream)(a1, onoff);
-}
-
-int __stdcall AIL_set_sample_file(HSAMPLE s, const void *file_image, int block)
-{
- return (mss32_AIL_set_sample_file)(s, file_image, block);
-}
-
-int __stdcall AIL_start_sample(HSAMPLE s)
-{
- return (mss32_AIL_start_sample)(s);
-}
-
-void __stdcall AIL_set_sample_playback_rate(HSAMPLE s, int rate)
-{
- (mss32_AIL_set_sample_playback_rate)(s, rate);
-}
-
-void __stdcall AIL_sample_ms_position(HSAMPLE s, int *pTotalMS, int *pCurrentMS)
-{
- (mss32_AIL_sample_ms_position)(s, pTotalMS, pCurrentMS);
-}
-
-int __stdcall AIL_3D_sample_status(void *a1)
-{
- __asm int 3
- return 0;
-}
-
-void __stdcall AIL_set_sample_loop_count(HSAMPLE s, int num)
-{
- (mss32_AIL_set_sample_loop_count)(s, num);
-}
-
-int __stdcall AIL_set_sample_volume(HSAMPLE a1, long a2)
-{
- return (mss32_AIL_set_sample_volume)(a1, a2);
-}
-
-int __stdcall AIL_3D_position(void *a1, int *a2, float *a3, long *a4)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_sample_file(long a1, void *a2)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_sample_loop_count(long a1, long a2)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_start_3D_sample(long a1)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_position(void *hSample, long a2, long a3, long a4)
-{
- __asm int 3
- return 0;
-}
-
-int __stdcall AIL_set_3D_orientation(void *hSample, long a2, long a3, long a4, long a5, long a6, long a7)
-{
- __asm int 3
- return 0;
-}
-
-void __stdcall AIL_init_sample(HSAMPLE a1)
-{
- (mss32_AIL_init_sample)(a1);
-}
-
-int __stdcall AIL_set_sample_pan(HSAMPLE a1, long a2)
-{
- return (mss32_AIL_set_sample_pan)(a1, a2);
-}
-
-
-AILFILETYPE __stdcall AIL_file_type(void *pSoundBytes, int numBytes)
-{
-  return (mss32_AIL_file_type)(pSoundBytes, numBytes);
-}
-
-int __stdcall AIL_WAV_info(void *pSoundBytes, AILSOUNDINFO *pInfo)
-{
-  return (mss32_AIL_WAV_info)(pSoundBytes, pInfo);
-}
-
-int __stdcall AIL_decompress_ADPCM(AILSOUNDINFO *pInfo, void *a2, void *a3)
-{
-  return (mss32_AIL_decompress_ADPCM)(pInfo, a2, a3);
-}
-
-int __stdcall AIL_mem_free_lock(void *a1)
-{
- __asm int 3
- return 0;
-}
\ No newline at end of file
--- a/AIL.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,318 +0,0 @@
-#pragma once
-#include "OSAPI.h"
-
-
-
-/*  252 */
-enum AILFILETYPE : __int32
-{
-  AILFILETYPE_UNKNOWN = 0x0,
-  AILFILETYPE_PCM_WAV = 0x1,
-  AILFILETYPE_ADPCM_WAV = 0x2,
-  AILFILETYPE_OTHER_WAV = 0x3,
-  AILFILETYPE_VOC = 0x4,
-  AILFILETYPE_MIDI = 0x5,
-  AILFILETYPE_XMIDI = 0x6,
-  AILFILETYPE_7 = 0x7,
-  AILFILETYPE_XMIDI_MLS = 0x8,
-  AILFILETYPE_DLS = 0x9,
-  AILFILETYPE_MLS = 0xA,
-  AILFILETYPE_MPEG_L1_AUDIO = 0xB,
-  AILFILETYPE_MPEG_L2_AUDIO = 0xC,
-  AILFILETYPE_MPEG_L3_AUDIO = 0xD,
-  AILFILETYPE_OTHER_ASI_WAV = 0xE,
-  AILFILETYPE_OTHER_ASI_F = 0xF,
-};
-
-
-
-/*  253 */
-#pragma pack(push, 1)
-struct AILSOUNDINFO
-{
-  int uFormat;
-  void *pData;
-  unsigned int uDataSize;
-  unsigned int uRate;
-  int uBits;
-  int uChannels;
-  unsigned int uSamples;
-  unsigned int uBlockSize;
-  void *pInitial;
-};
-#pragma pack(pop)
-
-
-
-
-//Bink
-typedef struct _BINK    *HBINK;
-typedef struct _BINKBUF *HBINKBUF;
-//Smacker & AIL types
-typedef struct _DIG_DRIVER *HDIGDRIVER;
-typedef struct _SMACK      *HSMACK;
-typedef struct _SMACKBLIT  *HSMACKBLIT;
-typedef struct _SMACKBUF   *HSMACKBUF;
-//AIL
-typedef struct _REDBOOK    *HREDBOOK;
-typedef struct _SAMPLE     *HSAMPLE;
-typedef struct _PROVIDER   *HPROVIDER;
-typedef struct _SEQUENCE   *HSEQUENCE;
-typedef struct _STREAM     *HSTREAM;
-typedef __int32             HATTRIB;
-typedef __int32             HASISTREAM; // Handle to stream being managed by ASI codec
-
-
-
-void MSS32_DLL_Initialize();
-
-#define AILCALL __stdcall
-#define AILCALLBACK __stdcall
-
-
-typedef __int32 (AILCALLBACK FAR * AILASIFETCHCB) (unsigned __int32		user,			// User value passed to ASI_open_stream()
-												void FAR *dest,			// Location to which stream data should be copied by app
-												__int32		bytes_requested, // # of bytes requested by ASI codec
-												__int32		offset);		 // If not -1, application should seek to this point in stream
-
-typedef HASISTREAM (AILCALL FAR *ASI_STREAM_OPEN) (unsigned __int32			user,				// User value passed to fetch callback
-													AILASIFETCHCB fetch_CB,			// Source data fetch handler
-													unsigned __int32			total_size);		// Total size for %-done calculations (0=unknown)
-typedef __int32	(AILCALL FAR *ASI_STREAM_PROCESS) (HASISTREAM	stream,				// Handle of stream
-												void FAR	*buffer,				// Destination for processed data
-												__int32		 buffer_size);		// # of bytes to return in buffer
-typedef __int32 (AILCALL FAR *ASI_STREAM_SEEK)	(HASISTREAM stream,
-													 __int32		stream_offset);
-typedef __int32 (AILCALL FAR *ASI_STREAM_CLOSE) (HASISTREAM stream);
-typedef __int32 (AILCALL FAR *ASI_STREAM_ATTRIBUTE) (HASISTREAM stream,
-												 HATTRIB	attrib);
-typedef __int32 (AILCALL FAR *ASI_STREAM_SET_PREFERENCE) (HASISTREAM stream,
-														HATTRIB	preference,
-														void const FAR	*	value);
-
-typedef struct
-	{
-	ASI_STREAM_OPEN			ASI_stream_open;
-	ASI_STREAM_PROCESS		ASI_stream_process;
-	ASI_STREAM_SEEK			ASI_stream_seek;
-	ASI_STREAM_CLOSE			ASI_stream_close;
-	ASI_STREAM_ATTRIBUTE		ASI_stream_attribute;
-	ASI_STREAM_SET_PREFERENCE ASI_stream_set_preference;
-
-	HATTRIB INPUT_BIT_RATE;
-	HATTRIB INPUT_SAMPLE_RATE;
-	HATTRIB INPUT_BITS;
-	HATTRIB INPUT_CHANNELS;
-	HATTRIB OUTPUT_BIT_RATE;
-	HATTRIB OUTPUT_SAMPLE_RATE;
-	HATTRIB OUTPUT_BITS;
-	HATTRIB OUTPUT_CHANNELS;
-	HATTRIB POSITION;
-	HATTRIB PERCENT_DONE;
-	HATTRIB MIN_INPUT_BLOCK_SIZE;
-	HATTRIB RAW_RATE;
-	HATTRIB RAW_BITS;
-	HATTRIB RAW_CHANNELS;
-	HATTRIB REQUESTED_RATE;
-	HATTRIB REQUESTED_BITS;
-	HATTRIB REQUESTED_CHANS;
-
-	HASISTREAM stream;
-	}
-ASISTAGE;
-
-
-
-
-typedef void (AILCALLBACK FAR* AILSTREAMCB)(HSTREAM stream);
-typedef struct _STREAM {
-
-	__int32 block_oriented; // 1 if this is an ADPCM or ASI-compressed stream
-	__int32 using_ASI;		// 1 if using ASI decoder to uncompress stream data
-	ASISTAGE FAR *ASI;	// handy pointer to our ASI coded
-
-	HSAMPLE samp;		// the sample handle
-
-	unsigned __int32 fileh;			// the open file handle
-
-	unsigned __int8 FAR* bufs[3];	// the data buffers
-	unsigned __int32 bufsizes[3];	// the size of each buffer
-	__int32 reset_ASI[3];	// should we reset the ASI at the end of the buffer?
-	__int32 bufstart[3];	// offset of where this buffer started
-	void FAR* asyncs[3];// async read structures
-
-	__int32 loadedbufstart[2]; // offset of where the loaded buffer started
-	__int32 loadedorder[2]; // order of the buffers as they were loaded
-	__int32 loadorder;		// incremented as each buffer is loaded
-
-	__int32 bufsize;		// size of each buffer
-	__int32 readsize;		// size of each read block
-
-	unsigned __int32 buf1;			// 0,1,2 (current buffer that we are reading into)
-	__int32 size1;			// holds the current amount of data read
-
-	unsigned __int32 buf2;			// 0,1,2 (the next buffer that we are reading into)
-	__int32 size2;			// next buffer loaded up to
-
-	unsigned __int32 buf3;			// 0,1,2 (the next buffer that we are reading into)
-	__int32 size3;			// next buffer loaded up to
-
-	unsigned __int32 datarate;		// datarate in bytes per second
-	__int32 filerate;		// original datarate of the file
-	__int32 filetype;		// file format type
-	unsigned __int32 fileflags;		// file format flags (signed or unsigned)
-	__int32 totallen;		// total length of the sound data
-
-	__int32 substart;		// subblock loop start
-	__int32 sublen;		 // subblock loop len
-	__int32 subpadding;	 // amount to pad the final block
-
-	unsigned __int32 blocksize;		// ADPCM block size
-	__int32 padding;		// padding to be done
-	__int32 padded;		 // padding done
-
-	__int32 loadedsome;	 // have we done any loads?
-
-	unsigned __int32 startpos;		// point that the sound data begins
-	unsigned __int32 totalread;		// total bytes read from the disk
-
-	unsigned __int32 loopsleft;		// how many loops are left
-
-	unsigned __int32 error;			// read error has occurred
-
-	__int32 preload;		// preload the file into the first buffer
-	unsigned __int32 preloadpos;	 // position to use in preload
-	__int32 noback;		 // no background processing
-	__int32 alldone;		// alldone
-	__int32 primeamount;	// amount to load after a seek
-	__int32 readatleast;	// forced amount to read on next service
-
-	__int32 playcontrol;	// control: 0=stopped, 1=started, |8=paused, |16=sample paused
-
-	AILSTREAMCB callback;	// end of stream callback
-
-	__int32 user_data[8];	// Miscellaneous user data
-	void FAR* next;	 // pointer to next stream
-
-#if defined(IS_WINDOWS) || defined(IS_MAC)
-	__int32 autostreaming;	// are we autostreaming this stream
-#endif
-
-#ifdef IS_WINDOWS
-	__int32 cb_IsWin32s;	// Is the callback win32s?
-#endif
-	__int32 docallback;	 // set when it time to poll for a callback
-#ifdef IS_MAC
-	IOParam	stream_param;
-	__int32		donext;
-	__int32		donext1;
-	unsigned __int32		fillup;
-	unsigned __int32		session;
-	unsigned __int32		tamt;
-	unsigned __int32		buf;
-	__int32*	 size;
-	__int32*	 done;
-	__int32		done1;
-	__int32		done2;
-	__int32		done3;
-	Boolean	force_quit;
-#endif
-
-} MSTREAM_TYPE;
-
-
-
-
-
-
-
-
-int __stdcall AIL_startup();
-HREDBOOK __stdcall AIL_redbook_open_drive(long drive);
-HREDBOOK __stdcall AIL_redbook_open(int);
-int __stdcall AIL_set_preference(unsigned int number, int value);
-int __stdcall AIL_waveOutOpen(HDIGDRIVER *drv, HWAVEOUT *phWaveOut, int wDeviceID, WAVEFORMAT *pFormat);
-int __stdcall AIL_get_preference(unsigned int number);
-int __stdcall AIL_digital_configuration(HDIGDRIVER drv, int *rate, int *format, char *string);
-HSAMPLE __stdcall AIL_allocate_sample_handle(HDIGDRIVER hDrv);
-unsigned int __stdcall AIL_redbook_tracks(HREDBOOK hRedbook);
-int __stdcall AIL_redbook_volume(HREDBOOK hRedbook);
-unsigned int __stdcall AIL_redbook_stop(HREDBOOK hRedbook);
-void __stdcall AIL_set_digital_master_volume(HDIGDRIVER hDrv, float master_volume);
-int __stdcall AIL_redbook_set_volume(HREDBOOK hRedbook, int volume);
-unsigned int __stdcall AIL_redbook_pause(HREDBOOK hRedbook);
-void __stdcall AIL_redbook_track_info(HREDBOOK hRedbook, unsigned int uTrackNum, unsigned int *pStartMS, unsigned int *pEndMS);
-unsigned int __stdcall AIL_redbook_play(HREDBOOK hRedbook, unsigned int uStartMS, unsigned int uEndMS);  	
-unsigned int __stdcall AIL_redbook_resume(HREDBOOK);
-int __stdcall AIL_enumerate_3D_providers(int *a1, HPROVIDER *pOutProv, char **pOutName);
-DWORD __stdcall AIL_open_3D_provider(HPROVIDER a2);
-void __stdcall AIL_3D_provider_attribute(HPROVIDER lib, char *name, void *val);
-int __stdcall AIL_set_3D_provider_preference(HPROVIDER a1, const char *a2, int *a3);
-void __stdcall AIL_waveOutClose(HDIGDRIVER drvr);
-int __stdcall AIL_allocate_3D_sample_handle(HPROVIDER);
-int __stdcall AIL_set_3D_sample_float_distances(void *a1, long a2, long a3, long a4, long a5);
-int __stdcall AIL_set_3D_sample_volume(void *a1, long a2);
-void __stdcall AIL_release_sample_handle(HSAMPLE s);
-int __stdcall AIL_3D_position(void *a1, int *a2, float *a3, long *a4);
-int __stdcall AIL_set_3D_sample_file(long a1, void *a2);
-int __stdcall AIL_set_3D_sample_loop_count(long a1, long a2);
-int __stdcall AIL_start_3D_sample(long a1);
-int __stdcall AIL_set_3D_position(void *hSample, long a2, long a3, long a4);
-int __stdcall AIL_set_3D_orientation(void *hSample, long a2, long a3, long a4, long a5, long a6, long a7);
-int __stdcall AIL_release_3D_sample_handle(void *hHandle);
-
-int __stdcall AIL_close_3D_provider(HPROVIDER);
-int __stdcall AIL_redbook_close(HREDBOOK);
-
-// sub_4D8344: using guessed type int __stdcall AIL_shutdown();
-int __stdcall AIL_shutdown();
-
-int __stdcall AIL_end_sample(HSAMPLE a1);
-int __stdcall AIL_end_3D_sample(void *a1);
-void __stdcall AIL_end_sequence(HSEQUENCE a1);
-void __stdcall AIL_pause_stream(HSTREAM a1, int onoff);
-int __stdcall AIL_set_sample_file(HSAMPLE, const void *file_image, int block);
-int __stdcall AIL_start_sample(HSAMPLE);
-void __stdcall AIL_set_sample_playback_rate(HSAMPLE, int rate);
-void __stdcall AIL_sample_ms_position(HSAMPLE, int *pTotalMS, int *pCurrentMS);
-int __stdcall AIL_3D_sample_status(void *a1);
-
-
-namespace AIL
-{
- namespace Sample
- {
-  enum Status
-  {
-   Free = 1,               // Sample is available for allocation
-   Done = 2,               // Sample has finished playing, or has never been started
-   Playing = 4,            // Sample is playing
-   Stopped = 8,            // Sample has been stopped
-   PlayingButReleased = 16 // Sample is playing, but digital handle has been temporarily released
-  };
- };
-};
-AIL::Sample::Status __stdcall AIL_sample_status(HSAMPLE a1);
-
-
-void __stdcall AIL_set_sample_loop_count(HSAMPLE, int);
-int __stdcall AIL_set_sample_volume(HSAMPLE a1, long a2);
-
-
-int __stdcall AIL_sample_volume(HSAMPLE);
-void __stdcall AIL_init_sample(HSAMPLE);
-int __stdcall AIL_set_sample_pan(HSAMPLE, long a2);
-AILFILETYPE __stdcall AIL_file_type(void *pSoundBytes, int numBytes);
-int __stdcall AIL_WAV_info(void *pSoundBytes, AILSOUNDINFO *pInfo);
-int __stdcall AIL_decompress_ADPCM(AILSOUNDINFO *pInfo, void *a2, void *a3);
-int __stdcall AIL_mem_free_lock(void *a1);
-
-
-
-
-
-
-
-
-
-
--- a/Arcomage/Arcomage.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Arcomage/Arcomage.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,13 +8,13 @@
 
 #include "..\Engine/Graphics/Render.h"
 #include "Arcomage.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Engine/Game.h"
 #include "..\Engine/Graphics/Viewport.h"
 #include "../Engine/Timer.h"
-#include "GUIFont.h"
+#include "GUI/GUIFont.h"
 #include "../Engine/Party.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "../Engine/texts.h"
 #include <windef.h>
 #include "../Engine/mm7_data.h"
--- a/AudioPlayer.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2740 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-#define _CRT_SECURE_NO_WARNINGS
-
-#include <string>
-#include "Engine/ZlibWrapper.h"
-
-#include "Engine/mm7_data.h"
-#include "MediaPlayer.h"
-#include "AudioPlayer.h"
-#include "Engine/Tables/FrameTableInc.h"
-#include "Engine/Graphics/Indoor.h"
-#include "Engine/Objects/SpriteObject.h"
-#include "Engine/Party.h"
-#include "Engine/Objects/Actor.h"
-#include "Engine/Game.h"
-#include "Engine/Graphics/DecorationList.h"
-#include "Engine/Timer.h"
-#include "Engine/OurMath.h"
-#include "Engine/MapInfo.h"
-#include "GUIWindow.h"
-#include "Engine/Log.h"
-#include "Engine/ErrorHandling.h"
-#include "Engine/Graphics/Level/Decoration.h"
-#include "Engine/Registry.h"
-
-#include "Bink_Smacker.h"
-
-#include "Engine/MM7.h"
-
-
-PCMWAVEFORMAT pcmWaveFormat;
-
-int uFindSound_BinSearch_ResultID; // weak
-int uLastLoadedSoundID; // weak
-int sLastTrackLengthMS;
-std::array<Sound, 3000> pSounds;
-AudioPlayer *pAudioPlayer;
-SoundList *pSoundList;
-
-
-std::array<stru339_spell_sound, 4> stru_A750F8;
-std::array<stru339_spell_sound, 4> AA1058_PartyQuickSpellSound;
-
-
-
-unsigned __int8 uSoundVolumeMultiplier;// = 4;
-unsigned __int8 uVoicesVolumeMultiplier;// = 4;
-unsigned __int8 uMusicVolimeMultiplier;// = 4;
-int bWalkSound; // idb
-
-std::array<float, 10> pSoundVolumeLevels = 
-{
-  0.0000000f, 0.1099999f, 0.2199999f, 0.3300000f, 0.4399999f,
- 0.5500000f, 0.6600000f, 0.7699999f, 0.8799999f, 0.9700000f  
-//  0.0000000f, 0.4900000f, 0.5500000f, 0.6100000f, 0.6700000f,  //for 128.0f
-// 0.7000000f, 0.7600000f, 0.8200000f, 0.8800000f, 0.9700000f     //changed 0.9900000f to 0.9700000f. for some reason it only works for values below this
-};
-
-
-
-
-void ReleaseSoundData(void *_this);
-_DIG_DRIVER *Audio_GetFirstHardwareDigitalDriver();
-
-
-
-
-//----- (004A9953) --------------------------------------------------------
-void SoundList::Initialize()
-{
-  SoundDesc *pSoundDesc; // eax@5
-  void *pSoundData; // ebx@7
-  unsigned int uSoundSize; // eax@7
-  char *pSoundBytes; // ebx@7
-  AILFILETYPE pType; // eax@7
-  int v8; // eax@8
-  char pSoundName[120]; // [sp+4h] [bp-A4h]@4
-  AILSOUNDINFO pInfo; // [sp+7Ch] [bp-2Ch]@10
-  int v12; // [sp+A0h] [bp-8h]@12
-
-  if ( sNumSounds > 1 )
-  {
-    for ( uint i = 1; i < pSoundList->sNumSounds; ++i )
-    {
-      sprintf(pSoundName, "%s", pSL_Sounds[i].pSoundName);
-      pSoundDesc = &pSoundList->pSL_Sounds[i];
-      if ( pSoundList->pSL_Sounds[i].eType != SOUND_DESC_SYSTEM )
-        continue;
-      pSoundList->pSL_Sounds[i].pSoundData[0] = ::LoadSound(pSoundName, (SoundData *)-1, pSL_Sounds[i].uSoundID); // Ritor result crash exe file
-      if ( !pAudioPlayer->b3DSoundInitialized )
-        continue;
-      pSoundDesc = &pSoundList->pSL_Sounds[i];
-      if ( !(pSoundDesc->uFlags & SOUND_DESC_SWAP) || !pSoundDesc->pSoundData[0] )
-        continue;
-      pSoundData = pSoundDesc->pSoundData[0];
-      uSoundSize = *(int *)pSoundData;
-      pSoundBytes = (char *)pSoundData + 4;
-      pType = AIL_file_type(pSoundBytes, uSoundSize);
-      if ( !pType )
-      {
-        pSoundList->pSL_Sounds[i].bDecompressed = false;
-        pSoundList->UnloadSound(i, 1);
-        continue;
-      }
-      v8 = pType - 1;
-      if ( v8 )
-      {
-        if ( v8 == 1 )
-        {
-          if ( AIL_WAV_info(pSoundBytes, &pInfo) && pInfo.uChannels != 2 )
-          {
-            if ( !AIL_decompress_ADPCM(&pInfo, &pSoundList->pSL_Sounds[i].p3DSound, &v12) )
-            {
-              pSoundList->pSL_Sounds[i].p3DSound = 0;
-              pSoundList->pSL_Sounds[i].bDecompressed = true;
-            }
-          }
-          pSoundList->UnloadSound(i, 1);
-          continue;
-        }
-        pSoundList->pSL_Sounds[i].bDecompressed = false;
-        pSoundList->UnloadSound(i, 1);
-        continue;
-      }
-      pSoundList->pSL_Sounds[i].p3DSound = pSoundList->pSL_Sounds[i].pSoundData[0];
-      pSoundList->UnloadSound(i, 1);
-    }
-  }
-  //_CrtDumpMemoryLeaks();
-}
-
-//----- (004A9A67) --------------------------------------------------------
-__int16 SoundList::LoadSound(int a1, unsigned int a3)
-{
-  AILSOUNDINFO v24; // [sp+84h] [bp-28h]@23
-
-  if (bNoSound || !sNumSounds)
-    return 0;
-
-  uint       uSoundIdx = 0;
-  SoundDesc *pSound = nullptr;
-  for (uint i = 1; i < sNumSounds; ++i)
-    if (pSL_Sounds[i].uSoundID == a1)
-    {
-      uSoundIdx = i;
-      pSound = &pSL_Sounds[i];
-      break;
-    }
-  if (!pSound)
-    return 0;
-
-  if (pSound->uFlags & SOUND_DESC_SWAP && pSound->p3DSound ||
-      ~pSound->uFlags & SOUND_DESC_SWAP && pSound->pSoundData[0])
-    return uSoundIdx;
-
-  if (!pSound->pSoundData[0])
-    pSound->pSoundData[0] = ::LoadSound(pSound->pSoundName, (SoundData *)-1, pSound->uSoundID);
-
-  if (!pSound->pSoundData[0])
-    return 0;
-
-  if (a3)
-    pSound->uFlags |= SOUND_DESC_SYSTEM;
-
-  if (!pAudioPlayer->b3DSoundInitialized)
-    return uSoundIdx;
-
-  if (~pSound->uFlags & SOUND_DESC_SWAP || !pSound->pSoundData[0])
-    return uSoundIdx;
-
-
-  SoundData* pSoundData = pSound->pSoundData[0];
-  switch (AIL_file_type((void *)pSoundData->pData, pSoundData->uDataSize))
-  {
-    default:
-    case AILFILETYPE_UNKNOWN:
-      pSound->bDecompressed = false;
-      return 0;
-
-    case AILFILETYPE_PCM_WAV:
-      pSound->p3DSound = pSound->pSoundData[0];
-      return uSoundIdx;
-
-    case AILFILETYPE_ADPCM_WAV:
-      if (AIL_WAV_info((void *)pSoundData->pData, &v24) && v24.uChannels != 2)
-      {
-        if (!AIL_decompress_ADPCM(&v24, &pSound->p3DSound, &a1) )
-        {
-          pSound->p3DSound = nullptr;
-          pSound->bDecompressed = true;
-          UnloadSound(uSoundIdx, 0);
-        }
-      }
-      return uSoundIdx;
-  };
-}
-
-//----- (004A9BBD) --------------------------------------------------------
-int SoundList::LoadSound(unsigned int a2, LPVOID lpBuffer, int uBufferSizeLeft, int *pOutSoundSize, int a6)
-{
-  void *v18; // ebx@19
-  DWORD NumberOfBytesRead;
-
-  if (!sNumSounds)
-    return 0;
-
-  for ( uint i = 0; i < sNumSounds; ++i )
-  {
-    if ( a2 == pSL_Sounds[i].uSoundID )
-    {
-      if ( !a6 && pSL_Sounds[i].pSoundData )
-        return i;
-      for ( uint j = 0; j < (signed int)pAudioPlayer->uNumSoundHeaders; ++j )
-      {
-        if ( !_stricmp(pAudioPlayer->pSoundHeaders[j].pSoundName, pSL_Sounds[i].pSoundName) )
-        {
-          if ( (signed int)pAudioPlayer->pSoundHeaders[j].uDecompressedSize > uBufferSizeLeft )
-            Error("Sound %s is size %i bytes, sound buffer size is %i bytes", pSL_Sounds[i].pSoundName, pAudioPlayer->pSoundHeaders[j].uDecompressedSize, uBufferSizeLeft);
-          SetFilePointer(pAudioPlayer->hAudioSnd, pAudioPlayer->pSoundHeaders[j].uFileOffset, 0, 0);
-          if ( (signed int)pAudioPlayer->pSoundHeaders[j].uCompressedSize >= (signed int)pAudioPlayer->pSoundHeaders[j].uDecompressedSize )
-          {
-            if ( pAudioPlayer->pSoundHeaders[j].uCompressedSize == pAudioPlayer->pSoundHeaders[j].uDecompressedSize )
-              ReadFile(pAudioPlayer->hAudioSnd, lpBuffer, pAudioPlayer->pSoundHeaders[j].uDecompressedSize, &NumberOfBytesRead, 0);
-            else
-              MessageBoxW(nullptr, L"Can't load sound file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Sound.cpp:666", 0);
-          }
-          else
-          {
-            v18 = malloc(pAudioPlayer->pSoundHeaders[j].uCompressedSize);
-            ReadFile(pAudioPlayer->hAudioSnd, v18, pAudioPlayer->pSoundHeaders[j].uCompressedSize, &NumberOfBytesRead, 0);
-            zlib::MemUnzip(lpBuffer, &pAudioPlayer->pSoundHeaders[j].uDecompressedSize, v18, pAudioPlayer->pSoundHeaders[j].uCompressedSize);
-            free(v18);
-          }
-          pSL_Sounds[i].pSoundData[a6] = (SoundData *)lpBuffer;
-          *pOutSoundSize = a2;
-          return i;
-        }
-      }
-    }
-  }
-  return 0;
-}
-
-//----- (004A9D3E) --------------------------------------------------------
-SoundDesc *SoundList::Release()
-{
-  SoundDesc *result; // eax@3
-  //void *v5; // ecx@3
-
-  if ( (signed int)this->sNumSounds > 0 )
-  {
-    for ( uint i = 0; i < (signed int)this->sNumSounds; ++i )
-    {
-      result = this->pSL_Sounds;
-      //v5 = this->pSL_Sounds[i].pSoundData[0];
-      if ( this->pSL_Sounds[i].pSoundData[0] )
-      {
-        ReleaseSoundData(this->pSL_Sounds[i].pSoundData[0]);
-        this->pSL_Sounds[i].pSoundData[0] = nullptr;
-        this->pSL_Sounds[i].uFlags &= 0xFFFFFFFE;
-      }
-    }
-  }
-  return result;
-}
-
-//----- (004A9D79) --------------------------------------------------------
-void SoundList::_4A9D79(int a2)
-{
-  for ( int i = 0; i < (signed int)this->sNumSounds; ++i )
-  {
-    if ( this->pSL_Sounds[i].eType != SOUND_DESC_SYSTEM && (a2 || this->pSL_Sounds[i].eType != SOUND_DESC_LOCK) )
-    {
-      if ( this->pSL_Sounds[i].pSoundData[0] )
-      {
-        ReleaseSoundData(this->pSL_Sounds[i].pSoundData[0]);
-        this->pSL_Sounds[i].pSoundData[0] = nullptr;
-      }
-      this->pSL_Sounds[i].uFlags &= ~SOUND_DESC_SYSTEM;
-    }
-  }
-}
-
-//----- (004A9DCD) --------------------------------------------------------
-void SoundList::UnloadSound(unsigned int uSoundID, char a3)
-{
-  if ( pSL_Sounds[uSoundID].eType != SOUND_DESC_SYSTEM )
-  {
-    if ( (pSL_Sounds[uSoundID].uFlags & SOUND_DESC_SWAP) && pSL_Sounds[uSoundID].p3DSound && a3 )
-    {
-      if ( pSL_Sounds[uSoundID].bDecompressed)
-        AIL_mem_free_lock(pSL_Sounds[uSoundID].p3DSound);
-      pSL_Sounds[uSoundID].p3DSound = 0;
-      pSL_Sounds[uSoundID].uFlags &= ~SOUND_DESC_SYSTEM;
-    }
-    if ( pSL_Sounds[uSoundID].pSoundData[0] )
-    {
-      ReleaseSoundData(pSL_Sounds[uSoundID].pSoundData[0]);
-      pSL_Sounds[uSoundID].pSoundData[0] = nullptr;
-      pSL_Sounds[uSoundID].uFlags &= ~SOUND_DESC_SYSTEM;
-    }
-  }
-}
-
-
-//----- (004A9E3D) --------------------------------------------------------
-void SoundList::ToFile()
-{
-  FILE *v2; // eax@1
-
-  v2 = fopen("data\\dsounds.bin", "wb");
-  if ( !v2 )
-    Error("Unable to save dsounds.bin!");
-
-  fwrite(this, 4, 1, v2);
-  fwrite(this->pSL_Sounds, 0x78u, this->sNumSounds, v2);
-  fclose(v2);
-}
-
-//----- (004A9E89) --------------------------------------------------------
-void SoundList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8)
-{
-  uint num_mm6_sounds = data_mm6 ? *(int *)data_mm6 : 0,
-       num_mm7_sounds = data_mm7 ? *(int *)data_mm7 : 0,
-       num_mm8_sounds = data_mm8 ? *(int *)data_mm8 : 0;
-
-  sNumSounds = num_mm6_sounds + num_mm7_sounds + num_mm8_sounds;
-  assert(sNumSounds);
-  assert(!num_mm8_sounds);
-
-  pSL_Sounds = (SoundDesc *)malloc(sNumSounds * sizeof(SoundDesc));
-  memcpy(pSL_Sounds, (char *)data_mm7 + 4, num_mm7_sounds * sizeof(SoundDesc));
-  for (uint i = 0; i < num_mm6_sounds; ++i)
-  {
-    auto src = (SoundDesc_mm6 *)((char *)data_mm6 + 4) + i;
-    SoundDesc* dst = &pSL_Sounds[num_mm7_sounds + i];
-
-    memcpy(dst, src, sizeof(SoundDesc_mm6));
-    dst->p3DSound = nullptr;
-    dst->bDecompressed = false;
-  }
-}
-
-//----- (004A9ED0) --------------------------------------------------------
-int SoundList::FromFileTxt(const char *Args)
-{
-  __int32 v3; // edi@1
-  FILE *v4; // eax@1
-  unsigned int v5; // esi@3
-  void *v6; // eax@9
-  FILE *v7; // ST0C_4@11
-  char *i; // eax@11
-  char Buf; // [sp+Ch] [bp-2F0h]@3
-  FrameTableTxtLine v18; // [sp+200h] [bp-FCh]@4
-  FrameTableTxtLine v19; // [sp+27Ch] [bp-80h]@4
-  FILE *File; // [sp+2F8h] [bp-4h]@1
-  unsigned int Argsa; // [sp+304h] [bp+8h]@3
-
-  free(this->pSL_Sounds);
-  v3 = 0;
-  this->pSL_Sounds = 0;
-  this->sNumSounds = 0;
-  v4 = fopen(Args, "r");
-  File = v4;
-  if ( !v4 )
-    Error("SoundListClass::load - Unable to open file: %s.");
-
-  v5 = 0;
-  Argsa = 0;
-  if ( fgets(&Buf, 490, v4) )
-  {
-    do
-    {
-      *strchr(&Buf, 10) = 0;
-      memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19));
-      if ( v19.uPropCount && *v19.pProperties[0] != 47 )
-        ++Argsa;
-    }
-    while ( fgets(&Buf, 490, File) );
-    v5 = Argsa;
-    v3 = 0;
-  }
-  this->sNumSounds = v5;
-  v6 = malloc(120 * v5);
-  this->pSL_Sounds = (SoundDesc *)v6;
-  if ( v6 == (void *)v3 )
-    Error("SoundListClass::load - Out of Memory!");
-
-  memset(v6, v3, 120 * this->sNumSounds);
-  v7 = File;
-  this->sNumSounds = v3;
-  fseek(v7, v3, v3);
-  for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) )
-  {
-    *strchr(&Buf, 10) = 0;
-    memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19));
-    if ( v19.uPropCount && *v19.pProperties[0] != 47 )
-    {
-      sprintf(this->pSL_Sounds[this->sNumSounds].pSoundName, "%s", v19.pProperties[0]);
-      this->pSL_Sounds[this->sNumSounds].uSoundID = atoi(v19.pProperties[1]);
-      if ( _stricmp(v19.pProperties[2], "system") )
-      {
-        if ( _stricmp(v19.pProperties[2], "swap") )
-        {
-          if ( !_stricmp(v19.pProperties[2], "lock") )
-            this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_LOCK;
-          else
-            this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_LEVEL;
-        }
-        else
-          this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_SWAP;
-      }
-      else
-        this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_SYSTEM;
-      if ( v19.uPropCount >= 4 && !_stricmp(v19.pProperties[3], "3D") )
-        this->pSL_Sounds[this->sNumSounds].uFlags |= SOUND_DESC_SWAP;
-      ++this->sNumSounds;
-    }
-  }
-  fclose(File);
-  return 1;
-}
-
-//----- (004AA13F) --------------------------------------------------------
-void AudioPlayer::PlayMusicTrack(MusicID eTrack)
-{
-  if (!bNoSound && bPlayerReady && hAILRedbook && uMusicVolimeMultiplier)
-  {
-    AIL_redbook_stop(hAILRedbook);
-    AIL_redbook_set_volume(hAILRedbook, (signed)pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f);
-    AIL_redbook_track_info(hAILRedbook, eTrack, &uCurrentMusicTrackStartMS, &uCurrentMusicTrackEndMS);
-    AIL_redbook_play(hAILRedbook, uCurrentMusicTrackStartMS + 1, uCurrentMusicTrackEndMS);
-    uCurrentMusicTrackLength = ((uCurrentMusicTrackEndMS - uCurrentMusicTrackStartMS) * 128) / 1000;
-  }
-}
-
-
-//----- (004AA1F3) --------------------------------------------------------
-void AudioPlayer::SetMusicVolume(int vol)
-{
-  if (bPlayerReady)
-  {
-    if (hAILRedbook)
-      AIL_redbook_set_volume(hAILRedbook, vol);
-  }
-}
-
-//----- (004AA214) --------------------------------------------------------
-void AudioPlayer::SetMasterVolume(float fVolume)
-{
-  if ( bPlayerReady )
-  {
-    uMasterVolume = fVolume;
-    if ( hDigDriver )
-      AIL_set_digital_master_volume(hDigDriver, fVolume);
-    if ( b3DSoundInitialized )
-      s3DSoundVolume = fVolume * 0.5f;
-  }
-}
-// 4D8304: using guessed type int __stdcall AIL_set_digital_master_volume(int, int);
-
-//----- (004AA258) --------------------------------------------------------
-void AudioPlayer::_4AA258(int a2)
-{
-  if (!bPlayerReady)
-    return;
-
-  if ( this->b3DSoundInitialized && a2 )
-  {
-    for ( uint i = 0; i < this->uNum3DSamples; ++i )
-    {
-      if ( this->p3DSamples[i].field_4 == a2 && AIL_3D_sample_status(this->p3DSamples[i].hSample) == AIL::Sample::Playing )
-        AIL_end_3D_sample(this->p3DSamples[i].hSample);
-    }
-  }
-  if ( this->hDigDriver && a2 )
-  {
-    for ( uint i = 0; i < this->uMixerChannels; ++i )
-    {
-      if ( this->pMixerChannels[i].source_pid == a2 && AIL_sample_status(this->pMixerChannels[i].hSample) == AIL::Sample::Playing)
-      {
-        AIL_end_sample(this->pMixerChannels[i].hSample);
-        FreeChannel(&this->pMixerChannels[i]);
-      }
-    }
-  }
-}
-
-//----- (004AA306) --------------------------------------------------------
-void AudioPlayer::PlaySound(SoundID eSoundID, signed int pid, unsigned int uNumRepeats, signed int source_x, signed int source_y, int sound_data_id, float uVolume, int sPlaybackRate)
-{
-  int v12; // edi@13
-  signed int v13; // ecx@17
-  signed int v14; // eax@20
-  int v15; // eax@24
-  signed int v16; // eax@25
-  SpriteObject *pLayingItem; // eax@28
-  signed int v18; // eax@29
-  Actor *pActor1; // eax@32
-  signed int v20; // ecx@32
-  double v21; // st7@32
-  signed int v22; // ecx@33
-  AudioPlayer_3DSample *pAudioPlayer_3DSample; // esi@53
-  AudioPlayer_3DSample *pAudioPlayer_3DSample1; // esi@61
-  int v25; // esi@67
-  double v26; // st7@68
-  int v27; // ST18_4@68
-  int v28; // ebx@68
-  int v29; // eax@68
-  AudioPlayer_3DSample *pAudioPlayer_3DSample2; // esi@69
-  int v31; // ST18_4@70
-  int v32; // ebx@70
-  int v33; // eax@70
-  int v34; // eax@70
-  char v35; // zf@70
-  signed int v36; // ebx@74
-  AudioPlayer_3DSample *pAudioPlayer_3DSample3; // esi@79
-  int v40; // eax@81
-  char *v41; // edi@82
-  int v42; // esi@82
-  double v43; // st7@91
-  SpriteObject *pLayingItem2; // eax@92
-  Actor *pActor; // eax@93
-  signed int v46; // ecx@93
-  double v47; // st7@93
-  BLVDoor *pBLVDoor; // eax@97
-  double v49; // st7@104
-  int v50; // ST18_4@104
-  int v51; // ebx@104
-  int v52; // eax@104
-  float v53; // ST0C_4@106
-  float v54; // ST04_4@106
-//  SoundDesc *pSoundDesc; // edx@107
-//  SpriteObject *pLayingItem3; // eax@114
-  signed int v62; // esi@133
-//  int v68; // eax@143
-  unsigned int v86; // [sp+14h] [bp-60h]@84
-  RenderVertexSoft pRenderVertexSoft; // [sp+24h] [bp-50h]@1
-  int v90; // [sp+58h] [bp-1Ch]@68
-  float v91; // [sp+5Ch] [bp-18h]@68
-  float v93; // [sp+64h] [bp-10h]@1
-  signed int varC; // [sp+68h] [bp-Ch]@68
-  int v96; // [sp+70h] [bp-4h]@19
-  signed int uNumRepeatsb; // [sp+84h] [bp+10h]@93
-  float uNumRepeatsa; // [sp+84h] [bp+10h]@104
-  float v99; // [sp+8Ch] [bp+18h]@104
-  signed int v100; // [sp+90h] [bp+1Ch]@32
-  int v101; // [sp+90h] [bp+1Ch]@52
-  int v102; // [sp+90h] [bp+1Ch]@60
-  int v103; // [sp+90h] [bp+1Ch]@68
-
-  if ( !bPlayerReady || !uSoundVolumeMultiplier || !hDigDriver || eSoundID == SOUND_Invalid )
-    return;
-
-  int sample_volume = 10000;
-
-  int sound_id = 0;
-  for (uint i = 0; i < pSoundList->sNumSounds; ++i)
-    if (pSoundList->pSL_Sounds[i].uSoundID == eSoundID)
-    {
-      sound_id = i;
-      break;
-    }
-
-  if (!sound_id)
-  {
-    Log::Warning(L"SoundID = %u not found", eSoundID);
-    return;
-  }
-  assert(sound_id < pSoundList->sNumSounds);
-  if ( !sound_data_id )
-  {
-    if ( !pSoundList->pSL_Sounds[sound_id].pSoundData[0] )
-    {
-      if ( pSoundList->pSL_Sounds[sound_id].eType == SOUND_DESC_SWAP )
-        pSoundList->LoadSound(eSoundID, 0);
-    }
-  }
-  if ( !pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] )
-    return;
-
-  int start_channel = 0,
-      end_channel = 0;
-  v62 = start_channel;
-
-  if (!b3DSoundInitialized || pSoundList->pSL_Sounds[sound_id].Is3D())
-  {
-    if (pid == 0)  // generic sound like from UI
-    {
-      start_channel = 10;
-      end_channel = 12;
-      for (uint i = start_channel; i <= end_channel; ++i)
-      {
-        if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-        {
-          if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-            return;                          // already playing the same sound from the same source - return
-          AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      for ( uint j = start_channel; j <= end_channel; j++ )
-      {
-        if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-        {
-          AIL_init_sample(pMixerChannels[j].hSample);
-          char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
-          //if (sound_data_id == 0)  p = p + 4;//for RIFF
-		  //if ( eSoundID == 75 )// Ritor1: include +7 for pSounds[20]
-			  //p = p + 7;
-          AIL_set_sample_file(pMixerChannels[j].hSample, p, -1);
-          if ( sample_volume == 10000 )
-            sample_volume = uMasterVolume;
-          if (uVolume)
-            sample_volume = uVolume;
-          int object_type = PID_TYPE(pid),
-              object_id = PID_ID(pid);
-          if (source_x != -1)//ñðàáàòûâàåò íàïðèìåð ó ôîðòà â Õåðìîíäåéëå çâóê âûñòðåëîâ ïóøåê
-          {
-            //if (!source_x)
-              //source_x = pParty->vPosition.x;
-            //if (!source_y)
-              //source_y = pParty->vPosition.y;
-           if ( source_x )//Ritor1: for pedestals
-           {
-              AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(source_x, source_y));
-              int vol = GetSoundStrengthByDistanceFromParty(source_x, source_y, pParty->vPosition.z);
-              AIL_set_sample_volume(pMixerChannels[j].hSample, vol);
-           }
-          }
-          if (uNumRepeats)
-            AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-          pMixerChannels[j].uSourceTrackIdx = sound_id;
-          pMixerChannels[j].source_pid = pid;
-          pMixerChannels[j].uSourceTrackID = eSoundID;
-          int rval = AIL_start_sample(pMixerChannels[j].hSample);
-          if ( sPlaybackRate )
-            AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-          if (object_type == OBJECT_Player)
-            AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-          return;
-        }
-      }
-      return;
-    }
-    else if (pid == -1)  // exclusive sounds - can override
-    {
-      /*if ( AIL_sample_status(pMixerChannels[13].hSample) == AIL::Sample::Done )
-      {
-          AIL_end_sample(pMixerChannels[13].hSample);
-          if ( pMixerChannels[13].uSourceTrackIdx )
-            FreeChannel(&pMixerChannels[13]);
-      }*/
-      AIL_init_sample(pMixerChannels[13].hSample);
-      char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
-      if (sound_data_id == 0)
-        p = p + 4;//for RIFF
-	  if ( eSoundID == 75 )//  Ritor1: include +7 for pSounds[20]
-		  p = p + 7;
-       AIL_set_sample_file(pMixerChannels[13].hSample, p, -1);
-       if ( sample_volume == 10000 )
-         sample_volume = uMasterVolume;
-       if (uVolume)
-         sample_volume = uVolume;
-       AIL_set_sample_volume(pMixerChannels[13].hSample, sample_volume);
-       int object_type = PID_TYPE(pid),
-           object_id = PID_ID(pid);
-       if (uNumRepeats)
-         AIL_set_sample_loop_count(pMixerChannels[13].hSample, uNumRepeats - 1);
-       pMixerChannels[13].uSourceTrackIdx = sound_id;
-       pMixerChannels[13].source_pid = pid;
-       pMixerChannels[13].uSourceTrackID = eSoundID;
-       int rval = AIL_start_sample(pMixerChannels[13].hSample);//no sound chest close 
-       if ( sPlaybackRate )
-         AIL_set_sample_playback_rate(pMixerChannels[13].hSample, sPlaybackRate);
-       if (object_type == OBJECT_Player)
-         AIL_sample_ms_position(pMixerChannels[13].hSample, &sLastTrackLengthMS, 0);
-       return;
-    }
-    else if (pid < 0)    // exclusive sounds - no override (close chest)
-    {
-      start_channel = 14;
-      end_channel = 14;
-      for (uint i = start_channel; i <= end_channel; ++i)
-      {
-        if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-        {
-          if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-            return;                          // already playing the same sound from the same source - return
-          AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      for ( uint j = start_channel; j <= end_channel; j++ )
-      {
-        if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-        {
-          AIL_init_sample(pMixerChannels[j].hSample);
-          char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
-          if (sound_data_id == 0)  p = p + 4;//for RIFF
-		  if ( eSoundID == 75 )//  Ritor1: include +7 for pSounds[20]
-			  p = p + 7;
-          AIL_set_sample_file(pMixerChannels[j].hSample, p, -1);
-          if ( sample_volume == 10000 )
-            sample_volume = uMasterVolume;
-          if (uVolume)
-            sample_volume = uVolume;
-          int object_type = PID_TYPE(pid),
-              object_id = PID_ID(pid);
-          if (uNumRepeats)
-            AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-          pMixerChannels[j].uSourceTrackIdx = sound_id;
-          pMixerChannels[j].source_pid = pid;
-          pMixerChannels[j].uSourceTrackID = eSoundID;
-          int rval = AIL_start_sample(pMixerChannels[j].hSample);//no sound chest close 
-          if ( sPlaybackRate )
-            AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-          if (object_type == OBJECT_Player)
-            AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-          return;
-        }
-      }
-      return;
-    }
-    else
-    {
-        int object_type = PID_TYPE(pid),
-            object_id = PID_ID(pid);
-        switch (object_type)
-        {
-          case OBJECT_BLVDoor:
-          {
-            assert(uCurrentlyLoadedLevelType == LEVEL_Indoor);
-            assert(object_id < pIndoor->uNumDoors);
-            if ( !pIndoor->pDoors[object_id].uDoorID )
-              return;
-
-            start_channel = 10;
-            end_channel = 12;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-              {
-                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                /*if (!GetSoundStrengthByDistanceFromParty(pIndoor->pDoors[object_id].pXOffsets[0], pIndoor->pDoors[object_id].pYOffsets[0], pIndoor->pDoors[object_id].pZOffsets[0]))
-                {
-                  AIL_end_sample(pMixerChannels[j].hSample);
-                  FreeChannel(&pMixerChannels[j]);
-                  return;
-                } */
-                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pIndoor->pDoors[object_id].pXOffsets[0], pIndoor->pDoors[object_id].pYOffsets[0]));
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          case OBJECT_Player:
-          {
-            start_channel = 10;
-            end_channel = 12;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-              {
-                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          case OBJECT_Actor:
-          {
-            start_channel = 0;
-            end_channel = 3;
-            assert(object_id < uNumActors);
-            sample_volume = GetSoundStrengthByDistanceFromParty(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y, pActors[object_id].vPosition.z);
-            if (!sample_volume)
-              return;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-              {
-                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                if (!GetSoundStrengthByDistanceFromParty(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y, pActors[object_id].vPosition.z))
-                  return;
-                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y));
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          case OBJECT_Decoration:
-          {
-            start_channel = 4;
-            end_channel = 4;
-            assert(object_id < uNumLevelDecorations);
-            sample_volume = GetSoundStrengthByDistanceFromParty(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y, pLevelDecorations[object_id].vPosition.z);
-            if (!sample_volume)
-              return;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )//çâóê ôîíòàíà è øàãîâ íå ïðîõîäÿò ïðîâåðêó íà ïîâòîð
-              {
-                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                if (!GetSoundStrengthByDistanceFromParty(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y, pLevelDecorations[object_id].vPosition.z))
-                  return;
-                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y));
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          case OBJECT_Item:
-          {
-            start_channel = 5;
-            end_channel = 7;
-            assert(object_id < uNumSpriteObjects);
-            sample_volume = GetSoundStrengthByDistanceFromParty(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y, pSpriteObjects[object_id].vPosition.z);
-            if (!sample_volume)
-              return;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-              {
-                if (pMixerChannels[i].uSourceTrackIdx == sound_id)
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                if (!GetSoundStrengthByDistanceFromParty(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y, pSpriteObjects[object_id].vPosition.z) )
-                  return;
-                AIL_set_sample_pan(pMixerChannels[v62].hSample, sub_4AB66C(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y));
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          case OBJECT_BModel:
-          {
-            start_channel = 8;
-            end_channel = 9;
-            for (uint i = start_channel; i <= end_channel; ++i)
-            {
-              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
-              {
-                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
-                  return;                          // already playing the same sound from the same source - return
-                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
-                FreeChannel(&pMixerChannels[i]);
-              }
-            }
-            for ( uint j = start_channel; j <= end_channel; j++ )
-            {
-              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
-              {
-                AIL_init_sample(pMixerChannels[j].hSample);
-                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-                if (uVolume)
-                  sample_volume = uVolume;
-                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
-                if (uNumRepeats)
-                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
-                pMixerChannels[j].uSourceTrackIdx = sound_id;
-                pMixerChannels[j].source_pid = pid;
-                pMixerChannels[j].uSourceTrackID = eSoundID;
-                int rval = AIL_start_sample(pMixerChannels[j].hSample);
-                if ( sPlaybackRate )
-                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
-                if (object_type == OBJECT_Player)
-                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
-                return;
-              }
-            }
-          }
-          return;
-
-          default:
-            assert(false);
-        }
-      }
-
-	  __debugbreak();//Ritor1
-      if (start_channel > end_channel)  // no free channel - occupy the quitest one
-      {
-        start_channel = -1;
-        int min_volume = sample_volume;
-        for (uint i = start_channel; i <= end_channel; ++i)
-        {
-          int volume = AIL_sample_volume(pMixerChannels[i].hSample);
-          if (volume < min_volume)
-          {
-            min_volume = volume;
-            start_channel = i;
-          }
-        }
-        if (v62 == -1)   // no free channels at all - only channel 13 allows override (a3 == -1)
-        {
-          if (start_channel != 13)
-            return;
-          v62 = 13;
-        }
-        AIL_end_sample(pMixerChannels[v62].hSample);
-        FreeChannel(&pMixerChannels[v62]);
-      }
-
-      if (v62 > end_channel)//10!=13
-        return;
-
-      if ( sample_volume == 10000 )
-        sample_volume = uMasterVolume;
-
-      AIL_init_sample(pMixerChannels[v62].hSample);
-      AIL_set_sample_file(pMixerChannels[v62].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
-      if (uVolume)
-        sample_volume = uVolume;
-      AIL_set_sample_volume(pMixerChannels[v62].hSample, sample_volume);
-
-      int object_type = PID_TYPE(pid),
-          object_id = PID_ID(pid);
-      if (source_x != -1)
-      {
-        if (!source_x)
-          source_x = pParty->vPosition.x;
-        if (!source_y)
-          source_y = pParty->vPosition.y;
-        AIL_set_sample_pan(pMixerChannels[v62].hSample, sub_4AB66C(source_x, source_y));
-        AIL_set_sample_volume(pMixerChannels[v62].hSample, GetSoundStrengthByDistanceFromParty(source_x, source_y, pParty->vPosition.z));
-      }
-
-      if (uNumRepeats)
-        AIL_set_sample_loop_count(pMixerChannels[v62].hSample, uNumRepeats - 1);
-      pMixerChannels[v62].uSourceTrackIdx = sound_id;
-      pMixerChannels[v62].source_pid = pid;
-      pMixerChannels[v62].uSourceTrackID = eSoundID;
-      int rval = AIL_start_sample(pMixerChannels[v62].hSample);
-      if ( sPlaybackRate )
-        AIL_set_sample_playback_rate(pMixerChannels[v62].hSample, sPlaybackRate);
-      if (object_type == OBJECT_Player)
-        AIL_sample_ms_position(pMixerChannels[v62].hSample, &sLastTrackLengthMS, 0);
-      return; 
-  }
-  else
-  {
-  __debugbreak(); // 3d sound stuff, refactor
-  v12 = 13;
-  if ( pid < 0 )
-  {
-    v15 = pAudioPlayer->uNum3DSamples;
-    if ( pid == -1 )
-    {
-      if ( v15 < 16 )
-        v12 = v15 - 1;
-      v96 = v12;
-      //goto LABEL_46;
-	  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-      pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
-      v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-      goto LABEL_47;
-    }
-    if ( v15 >= 16 )
-      v15 = 14;
-    v12 = v15;
-    //goto LABEL_45;
-	v96 = v15;
-    pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-    pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
-    v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-    goto LABEL_47;
-  }
-  if ( PID_TYPE(pid) == 2 )
-  {
-    v22 = pAudioPlayer->uNum3DSamples;
-    if ( v22 < 16 )
-    {
-      v12 = 5 * v22 / 16;
-      v96 = 7 * v22 / 16;
-    }
-    else
-    {
-      v96 = 7;
-      v12 = 5;
-    }
-    pLayingItem = &pSpriteObjects[PID_ID(pid)];
-  }
-  else
-  {
-    if ( PID_TYPE(pid) == 3 )
-    {
-      v18 = pAudioPlayer->uNum3DSamples;
-      v12 = 0;
-      if ( v18 < 16 )
-        v96 = 3 * v18 / 16;
-      else
-        v96 = 3;
-      pActor1 = &pActors[PID_ID(pid)];
-      v20 = pActor1->vPosition.y;
-      pRenderVertexSoft.vWorldPosition.x = (double)pActor1->vPosition.x;
-      v100 = pActor1->vPosition.z;
-      pRenderVertexSoft.vWorldPosition.y = (double)v20;
-      v21 = (double)v100;
-      goto LABEL_47;
-    }
-    if ( PID_TYPE(pid) != 5 )
-    {
-      v13 = pAudioPlayer->uNum3DSamples;
-      if ( PID_TYPE(pid) == 6 )
-      {
-        if ( v13 >= 16 )
-        {
-          v96 = 9;
-          v12 = 8;
-          //goto LABEL_46;
-		  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-          pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
-		  v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-		  goto LABEL_47;
-        }
-        v12 = 8 * v13 / 16;
-        v14 = 9 * v13;
-      }
-      else
-      {
-        if ( v13 >= 16 )
-        {
-          v96 = 12;
-          v12 = 10;
-//LABEL_46:
-          pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-          pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
-          v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-          goto LABEL_47;
-        }
-        v12 = 10 * v13 / 16;
-        v14 = 12 * v13;
-      }
-      v15 = v14 / 16;
-//LABEL_45:
-      v96 = v15;
-      //goto LABEL_46;
-	  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-      pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
-      v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-      goto LABEL_47;
-    }
-    v16 = pAudioPlayer->uNum3DSamples;
-    if ( v16 < 16 )
-    {
-      v12 = v16 / 4;
-      v96 = v16 / 4;
-    }
-    else
-    {
-      v12 = 4;
-      v96 = 4;
-    }
-    pLayingItem = (SpriteObject *)&pLevelDecorations[PID_ID(pid)];
-  }
-  pRenderVertexSoft.vWorldPosition.x = (double)pLayingItem->vPosition.x;
-  pRenderVertexSoft.vWorldPosition.y = (double)pLayingItem->vPosition.y;
-  v21 = (double)pLayingItem->vPosition.z;
-LABEL_47:
-  pRenderVertexSoft.vWorldPosition.z = v21;
-  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-    sub_4AAEA6_transform(&pRenderVertexSoft);
-  else
-    pGame->pIndoorCameraD3D->ViewTransform(&pRenderVertexSoft, 1);
-  if ( pid )
-  {
-    if ( pid != -1 )
-    {
-      v101 = 0;
-      if ( pAudioPlayer->uNum3DSamples > 0 )
-      {
-        pAudioPlayer_3DSample = pAudioPlayer->p3DSamples;
-        do
-        {
-          if ( AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 
-			  && pAudioPlayer_3DSample->field_4 == pid && AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 )
-          {
-            if ( pAudioPlayer_3DSample->field_8 == sound_id )
-              return;
-            AIL_end_3D_sample(pAudioPlayer_3DSample->hSample);
-            pAudioPlayer->_4ABF23(pAudioPlayer_3DSample);
-          }
-          ++v101;
-          ++pAudioPlayer_3DSample;
-        }
-        while ( v101 < pAudioPlayer->uNum3DSamples );
-      }
-    }
-  }
-  v102 = v12;
-  if ( v12 <= v96 )
-  {
-    pAudioPlayer_3DSample1 = &pAudioPlayer->p3DSamples[v12];
-    while ( AIL_3D_sample_status(pAudioPlayer_3DSample1->hSample) != 2 )
-    {
-      ++v102;
-      ++pAudioPlayer_3DSample1;
-      if ( v102 > v96 )
-        goto LABEL_67;
-    }
-    AIL_end_3D_sample(pAudioPlayer_3DSample1->hSample);
-    if ( pAudioPlayer_3DSample1->field_8 )
-      pAudioPlayer->_4ABF23(pAudioPlayer_3DSample1);
-  }
-LABEL_67:
-  v25 = v96;
-  if ( v102 == v96 + 1 )
-  {
-    LODWORD(v91) = -1;
-    v103 = 0;
-    *(float *)&varC = pRenderVertexSoft.vWorldViewPosition.y * -0.012207031;
-    v93 = 0.0;
-    v26 = pRenderVertexSoft.vWorldViewPosition.x * 0.012207031;
-    *(float *)&uVolume = v26;
-    v27 = abs((signed __int64)v26);
-    v28 = abs((signed __int64)v93);
-    v29 = abs((signed __int64)*(float *)&varC);
-    v90 = int_get_vector_length(v29, v28, v27);
-    sPlaybackRate = v12;
-    if ( v12 > v25 )
-      goto LABEL_192;
-    pAudioPlayer_3DSample2 = &pAudioPlayer->p3DSamples[v12];
-    do
-    {
-      AIL_3D_position(pAudioPlayer_3DSample2->hSample, &varC, &v93, (long *)&uVolume);
-      v31 = abs((signed __int64)*(float *)&uVolume);
-      v32 = abs((signed __int64)v93);
-      v33 = abs((signed __int64)*(float *)&varC);
-      v34 = int_get_vector_length(v33, v32, v31);
-      v35 = v103 == v34;
-      if ( v103 < v34 )
-      {
-        v103 = v34;
-        v35 = 1;
-      }
-      if ( v35 && v90 < v103 )
-      {
-        v36 = sPlaybackRate;
-        LODWORD(v91) = sPlaybackRate;
-      }
-      else
-      {
-        v36 = LODWORD(v91);
-      }
-      ++sPlaybackRate;
-      ++pAudioPlayer_3DSample2;
-    }
-    while ( sPlaybackRate <= v96 );
-    if ( v36 == -1 )
-    {
-LABEL_192:
-      v36 = 13;
-      if ( v12 != 13 )
-        return;
-    }
-    //pAudioPlayer2 = pAudioPlayer;
-    pAudioPlayer_3DSample3 = &pAudioPlayer->p3DSamples[v36];
-    AIL_end_3D_sample(pAudioPlayer_3DSample3->hSample);
-    pAudioPlayer->_4ABF23(pAudioPlayer_3DSample3);
-    v102 = v36;
-  }
-  //v39 = v89;
-  if ( pSoundList->pSL_Sounds[sound_id].p3DSound || (LOWORD(v40) = pSoundList->LoadSound(eSoundID, 0), v40) )
-  {
-    v41 = (char *)pAudioPlayer + 16 * v102;
-    v42 = (int)(v41 + 20);
-    if ( AIL_set_3D_sample_file(*((int *)v41 + 5), *(void **)((char *)&pSoundList->pSL_Sounds->p3DSound + sound_id * sizeof(SoundDesc))) )
-    {
-      if ( uNumRepeats )
-        v86 = uNumRepeats - 1;
-      else
-        v86 = 1;
-      AIL_set_3D_sample_loop_count(*(int *)v42, v86);
-      if ( source_x == -1 )
-      {
-        if ( PID_TYPE(pid) == 1 )
-        {
-          if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-          {
-			//goto LABEL_103;
-            pBLVDoor = &pIndoor->pDoors[PID_ID(pid)];
-            if ( !pBLVDoor->uDoorID )
-             return;
-            pRenderVertexSoft.vWorldPosition.x = (double)*pBLVDoor->pXOffsets;
-            pRenderVertexSoft.vWorldPosition.y = (double)*pBLVDoor->pYOffsets;
-            v47 = (double)*pBLVDoor->pZOffsets;
-LABEL_101:
-            pRenderVertexSoft.vWorldPosition.z = v47;
-          //if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-          //{
-            sub_4AAEA6_transform(&pRenderVertexSoft);
-            //goto LABEL_104;
-          //}
-		  }
-//LABEL_103:
-		  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )
-            pGame->pIndoorCameraD3D->ViewTransform(&pRenderVertexSoft, 1);
-//LABEL_104:
-          AIL_start_3D_sample(*(int *)v42);
-          AIL_set_3D_sample_float_distances(*(int **)v42, 100.0, 20.0, 100.0, 20.0);
-          AIL_set_3D_sample_volume(*(int **)v42, pAudioPlayer->s3DSoundVolume);
-          v99 = pRenderVertexSoft.vWorldViewPosition.y * -0.012207031;
-          v49 = pRenderVertexSoft.vWorldViewPosition.x * 0.012207031;
-          uNumRepeatsa = v49;
-          v50 = abs((signed __int64)v49);
-          v51 = abs(0);
-          v52 = abs((signed __int64)v99);
-          if ( int_get_vector_length(v52, v51, v50) <= 100 )
-          {
-            AIL_set_3D_position((void *)*(int *)v42, LODWORD(v99), 0.0, LODWORD(uNumRepeatsa));
-            v53 = -uNumRepeatsa;
-            v54 = -v99;
-            AIL_set_3D_orientation((void *)*(int *)v42, LODWORD(v54), 0.0, LODWORD(v53), 0.0, 1.0, 0.0);
-            //pAudioPlayer3 = pAudioPlayer;
-            *((int *)v41 + 6) = pid;
-            *((int *)v41 + 7) = sound_id;
-            *(&pAudioPlayer->bEAXSupported + 4 * (v102 + 2)) = eSoundID;
-          }
-          else
-          {
-            AIL_end_3D_sample(*(int **)v42);
-            pAudioPlayer->_4ABF23((AudioPlayer_3DSample *)(v41 + 20));
-          }
-          return;
-        }
-        if ( PID_TYPE(pid) == 2 )
-        {
-          pLayingItem2 = &pSpriteObjects[PID_ID(pid)];
-        }
-        else
-        {
-          if ( PID_TYPE(pid) == 3 )
-          {
-            pActor = &pActors[PID_ID(pid)];
-            v46 = pActor->vPosition.y;
-            pRenderVertexSoft.vWorldPosition.x = (double)pActor->vPosition.x;
-            uNumRepeatsb = pActor->vPosition.z;
-            pRenderVertexSoft.vWorldPosition.y = (double)v46;
-            v47 = (double)uNumRepeatsb;
-            goto LABEL_101;
-          }
-          if ( PID_TYPE(pid) != 5 )
-          {
-            pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
-            v43 = (double)pParty->vPosition.y;
-            pRenderVertexSoft.vWorldPosition.y = v43;
-            v47 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-            goto LABEL_101;
-          }
-          pLayingItem2 = (SpriteObject *)&pLevelDecorations[PID_ID(pid)];
-        }
-        pRenderVertexSoft.vWorldPosition.x = (double)pLayingItem2->vPosition.x;
-        pRenderVertexSoft.vWorldPosition.y = (double)pLayingItem2->vPosition.y;
-        v47 = (double)pLayingItem2->vPosition.z;
-        goto LABEL_101;
-      }
-      pRenderVertexSoft.vWorldPosition.x = (double)source_x;
-      v43 = (double)source_y;
-      pRenderVertexSoft.vWorldPosition.y = v43;
-      v47 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-      goto LABEL_101;
-    }
-  }
-  }
-}
-
-//----- (0040DEA5) --------------------------------------------------------
-void  AudioPlayer::MessWithChannels()
-{
-  pAudioPlayer->StopChannels(-1, -1);
-}
-
-
-//----- (004AAFCF) --------------------------------------------------------
-void AudioPlayer::UpdateSounds()
-{
-  int v2; // ebx@1
-  int v7; // ebx@6
-  int v8; // ebx@9
-  int v9; // ebx@10
-  int v10; // ebx@11
-  double v11; // st7@13
-  SpriteObject *v12; // eax@14
-  Actor *v13; // eax@15
-//  signed int v14; // edx@15
-  BLVDoor *pDoor; // eax@19
-  double v16; // st7@22
-  double v17; // st6@22
-  double v18; // st5@23
-  double v19; // st4@24
-  double v20; // st3@24
-  double v21; // st6@28
-  double v22; // st7@32
-  int v23; // ST1C_4@32
-  int v24; // ebx@32
-  int v25; // eax@32
-  float v26; // ST10_4@34
-  float v27; // ST08_4@34
-//  int v38; // eax@53
-//  __int16 v51; // ax@71
-  signed int v53; // eax@88
-  RenderVertexSoft a1; // [sp+24h] [bp-48h]@1
-  float v55; // [sp+54h] [bp-18h]@22
-  float v56; // [sp+58h] [bp-14h]@22
-  int uNumRepeats; // [sp+5Ch] [bp-10h]@15
-  float v58; // [sp+60h] [bp-Ch]@23
-  int v59; // [sp+64h] [bp-8h]@4
-
-  //pAudioPlayer = this;
-  v2 = 0;
-  //thisa = this;
-  //v3 = this->bPlayerReady == 0;
-  //a1.flt_2C = 0.0;
-  if (!bPlayerReady)
-    return;
-  
-  //if (field_2D0_time_left <= pEventTimer->uTimeElapsed)
-    //field_2D0_time_left = 32;
-  //else
-  //{
-    //field_2D0_time_left -= pEventTimer->uTimeElapsed;
-    //return;
-  //}
-  field_2D0_time_left -= pEventTimer->uTimeElapsed;
-  if ( field_2D0_time_left <= 0 )
-  {
-  field_2D0_time_left = 32;
-  if ( b3DSoundInitialized )//for 3D sound
-  {
-    __debugbreak(); // refactor refactor
-    v2 = 0;
-    for ( v59 = 0; v59 < pAudioPlayer->uNum3DSamples; ++v59 )
-    {
-      v7 = PID_TYPE(this->p3DSamples[v59].field_4);
-      if ( AIL_3D_sample_status(this->p3DSamples[v59].hSample) == AIL::Sample::Done )
-      {
-        AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-        pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-      }
-      if ( AIL_3D_sample_status(this->p3DSamples[v59].hSample) != AIL::Sample::Playing )
-        continue;
-      v8 = v7 - 1;//
-      if ( v8 )//> 1
-      {
-        v9 = v8 - 1;//
-        if ( v9 )//> 2
-        {
-          v10 = v9 - 1;//
-          if ( !v10 )//3
-          {
-            v13 = &pActors[PID_ID(this->p3DSamples[v59].field_4)];
-            //uNumRepeats = v13->vPosition.x;
-            //v14 = v13->vPosition.y;
-            a1.vWorldPosition.x = (double)v13->vPosition.x;
-            //uNumRepeats = v13->vPosition.z;
-            a1.vWorldPosition.y = (double)v13->vPosition.y;
-            //v11 = (double)uNumRepeats;
-            a1.vWorldPosition.z = v13->vPosition.z;
-            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-            {
-              v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
-              v17 = pGame->pIndoorCameraD3D->fRotationXSine;
-              v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
-              v56 = pGame->pIndoorCameraD3D->fRotationYSine;
-              if (pGame->pIndoorCameraD3D->sRotationX)
-              {
-                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-                v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-                //if ( pRenderer->pRenderD3D )
-                {
-                  v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
-                  v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
-                }
-                /*else
-                {
-                  v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
-                  v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
-                }*/
-                a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
-                a1.vWorldViewPosition.y = v20;
-                a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
-              }
-              else
-              {
-                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-                //if ( pRenderer->pRenderD3D )
-                {
-                  a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
-                  v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
-                }
-                /*else
-                {
-                  a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
-                  v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
-                }*/
-                a1.vWorldViewPosition.y = v21;
-                a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-              }
-            }
-            else
-              pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-            v58 = a1.vWorldViewPosition.y * -0.012207031;
-            v22 = a1.vWorldViewPosition.x * 0.012207031;
-            *(float *)&uNumRepeats = v22;
-            v23 = abs((signed __int64)v22);
-            v24 = abs(0);
-            v25 = abs((signed __int64)v58);
-            if ( int_get_vector_length(v25, v24, v23) <= 100 )
-            {
-              AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
-              v26 = -*(float *)&uNumRepeats;
-              v27 = -v58;
-              AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
-            }
-            else
-            {
-              AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-              pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-            }
-            continue;
-          }
-          if ( v10 != 2 )//4
-          {
-            a1.vWorldPosition.x = (double)pParty->vPosition.x;
-            a1.vWorldPosition.y = (double)pParty->vPosition.y;
-            v11 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
-            a1.vWorldPosition.z = v11;
-            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-            {
-              v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
-              v17 = pGame->pIndoorCameraD3D->fRotationXSine;
-              v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
-              v56 = pGame->pIndoorCameraD3D->fRotationYSine;
-              if (pGame->pIndoorCameraD3D->sRotationX)
-              {
-                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-                v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-                //if ( pRenderer->pRenderD3D )
-                {
-                  v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
-                  v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
-                }
-                /*else
-                {
-                  v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
-                  v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
-                }*/
-                a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
-                a1.vWorldViewPosition.y = v20;
-                a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
-              }
-              else
-              {
-                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-                //if ( pRenderer->pRenderD3D )
-                {
-                  a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
-                  v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
-                }
-                /*else
-                {
-                  a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
-                  v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
-                }*/
-                a1.vWorldViewPosition.y = v21;
-                a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-              }
-            }
-            else
-              pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-            v58 = a1.vWorldViewPosition.y * -0.012207031;
-            v22 = a1.vWorldViewPosition.x * 0.012207031;
-            *(float *)&uNumRepeats = v22;
-            v23 = abs((signed __int64)v22);
-            v24 = abs(0);
-            v25 = abs((signed __int64)v58);
-            if ( int_get_vector_length(v25, v24, v23) <= 100 )
-            {
-              AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
-              v26 = -*(float *)&uNumRepeats;
-              v27 = -v58;
-              AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
-            }
-            else
-            {
-              AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-              pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-            }
-            continue;
-          }//5
-          v12 = (SpriteObject *)&pLevelDecorations[PID_ID(this->p3DSamples[v59].field_4)];
-        }
-        else//2
-          v12 = &pSpriteObjects[PID_ID(this->p3DSamples[v59].field_4)];
-        a1.vWorldPosition.x = (double)v12->vPosition.x;
-        a1.vWorldPosition.y = (double)v12->vPosition.y;
-        v11 = (double)v12->vPosition.z;
-//LABEL_21:
-        a1.vWorldPosition.z = v11;
-        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-        {
-          v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
-          v17 = pGame->pIndoorCameraD3D->fRotationXSine;
-          v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
-          v56 = pGame->pIndoorCameraD3D->fRotationYSine;
-          if (pGame->pIndoorCameraD3D->sRotationX)
-          {
-            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-            v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-            //if ( pRenderer->pRenderD3D )
-            {
-              v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
-              v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
-            }
-            /*else
-            {
-              v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
-              v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
-            }*/
-            a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
-            a1.vWorldViewPosition.y = v20;
-            a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
-          }
-          else
-          {
-            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-            //if ( pRenderer->pRenderD3D )
-            {
-              a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
-              v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
-            }
-            /*else
-            {
-              a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
-              v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
-            }*/
-            a1.vWorldViewPosition.y = v21;
-            a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-          }
-        }
-        else
-          pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-        v58 = a1.vWorldViewPosition.y * -0.012207031;
-        v22 = a1.vWorldViewPosition.x * 0.012207031;
-        *(float *)&uNumRepeats = v22;
-        v23 = abs((signed __int64)v22);
-        v24 = abs(0);
-        v25 = abs((signed __int64)v58);
-        if ( int_get_vector_length(v25, v24, v23) <= 100 )
-        {
-          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
-          v26 = -*(float *)&uNumRepeats;
-          v27 = -v58;
-          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
-        }
-        else
-        {
-          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-        }
-        continue;
-      }
-      if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )//==1
-      {
-        pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-        v58 = a1.vWorldViewPosition.y * -0.012207031;
-        v22 = a1.vWorldViewPosition.x * 0.012207031;
-        *(float *)&uNumRepeats = v22;
-        v23 = abs((signed __int64)v22);
-        v24 = abs(0);
-        v25 = abs((signed __int64)v58);
-        if ( int_get_vector_length(v25, v24, v23) <= 100 )
-        {
-          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
-          v26 = -*(float *)&uNumRepeats;
-          v27 = -v58;
-          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
-        }
-        else
-        {
-          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-        }
-        continue;
-      }
-      pDoor = &pIndoor->pDoors[PID_ID(this->p3DSamples[v59].field_4)];
-      if ( pDoor->uDoorID )
-      {
-        uNumRepeats = *pDoor->pXOffsets;
-        a1.vWorldPosition.x = (double)uNumRepeats;
-        uNumRepeats = *pDoor->pYOffsets;
-        a1.vWorldPosition.y = (double)uNumRepeats;
-        uNumRepeats = *pDoor->pZOffsets;
-        v11 = (double)uNumRepeats;
-        a1.vWorldPosition.z = v11;
-        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
-        {
-          v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
-          v17 = pGame->pIndoorCameraD3D->fRotationXSine;
-          v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
-          v56 = pGame->pIndoorCameraD3D->fRotationYSine;
-          if (pGame->pIndoorCameraD3D->sRotationX)
-          {
-            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-            v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-            //if ( pRenderer->pRenderD3D )
-            {
-              v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
-              v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
-            }
-            /*else
-            {
-              v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
-              v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
-            }*/
-            a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
-            a1.vWorldViewPosition.y = v20;
-            a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
-          }
-          else
-          {
-            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
-            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
-            //if ( pRenderer->pRenderD3D )
-            {
-              a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
-              v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
-            }
-            /*else
-            {
-              a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
-              v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
-            }*/
-            a1.vWorldViewPosition.y = v21;
-            a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
-          }
-        }
-        else
-          pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
-        v58 = a1.vWorldViewPosition.y * -0.012207031;
-        v22 = a1.vWorldViewPosition.x * 0.012207031;
-        *(float *)&uNumRepeats = v22;
-        v23 = abs((signed __int64)v22);
-        v24 = abs(0);
-        v25 = abs((signed __int64)v58);
-        if ( int_get_vector_length(v25, v24, v23) <= 100 )
-        {
-          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
-          v26 = -*(float *)&uNumRepeats;
-          v27 = -v58;
-          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
-        }
-        else
-        {
-          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
-          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
-        }
-      }
-    }
-    //}
-  }
-
-//LABEL_37:
-  for (int i = 0; i < uMixerChannels; ++i)
-  {
-    if (AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Done)
-    {
-      AIL_end_sample(pMixerChannels[i].hSample);
-      FreeChannel(&pMixerChannels[i]);
-    }
-  }
-
-  for (int i = 0; i < uMixerChannels; ++i)
-  {
-    if (pMixerChannels[i].source_pid <= 0)
-      continue;
-
-    int source_type = PID_TYPE(pMixerChannels[i].source_pid),
-        source_id = PID_ID(pMixerChannels[i].source_pid);
-//    int source_x,
-//       int source_y,
-//        source_z;
-
-    switch (source_type)
-    {
-      case 0:
-      case OBJECT_Player:
-      case OBJECT_BModel:
-        continue;
-
-      case OBJECT_BLVDoor:
-      {
-        assert(uCurrentlyLoadedLevelType == LEVEL_Indoor);
-
-        assert(source_id < pIndoor->uNumDoors);
-        if (!pIndoor->pDoors[source_id].uDoorID)
-          continue;
-
-        //source_x = pIndoor->pDoors[source_id].pXOffsets[0];
-        //source_y = pIndoor->pDoors[source_id].pYOffsets[0];
-        //source_z = pIndoor->pDoors[source_id].pZOffsets[0];
-        int sound_strength = GetSoundStrengthByDistanceFromParty(pIndoor->pDoors[source_id].pXOffsets[0],
-                                                                 pIndoor->pDoors[source_id].pYOffsets[0],
-                                                                 pIndoor->pDoors[source_id].pZOffsets[0]);
-        if ( sound_strength )
-        {
-          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
-          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pIndoor->pDoors[source_id].pXOffsets[0],
-                                                                 pIndoor->pDoors[source_id].pYOffsets[0]));
-        }
-        else
-        {
-          AIL_end_sample(pMixerChannels[i].hSample);
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      continue;
-
-      case OBJECT_Item:
-      {
-        //assert(source_id < uNumSpriteObjects); // Ritor1:â èäà äî è ïîñëå ïåðåõîäà îäèíàêîâî
-
-        //source_x = pSpriteObjects[source_id].vPosition.x;
-        //source_y = pSpriteObjects[source_id].vPosition.y;
-        //source_z = pSpriteObjects[source_id].vPosition.z;
-        int sound_strength = GetSoundStrengthByDistanceFromParty(pSpriteObjects[source_id].vPosition.x,
-                                                                 pSpriteObjects[source_id].vPosition.y,
-                                                                 pSpriteObjects[source_id].vPosition.z);
-        if ( sound_strength )
-        {
-          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
-          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pSpriteObjects[source_id].vPosition.x,
-                                                                   pSpriteObjects[source_id].vPosition.y));
-        }
-        else
-        {
-          AIL_end_sample(pMixerChannels[i].hSample);
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      continue;
-
-      case OBJECT_Decoration:
-      {
-        assert(source_id < uNumLevelDecorations);
-
-        //source_x = pLevelDecorations[source_id].vPosition.x;
-        //source_y = pLevelDecorations[source_id].vPosition.y;
-        //source_z = pLevelDecorations[source_id].vPosition.z;
-        int sound_strength = GetSoundStrengthByDistanceFromParty(pLevelDecorations[source_id].vPosition.x,
-                                                                 pLevelDecorations[source_id].vPosition.y,
-                                                                 pLevelDecorations[source_id].vPosition.z);
-        if ( sound_strength )
-        {
-          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
-          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pLevelDecorations[source_id].vPosition.x,
-                                                                   pLevelDecorations[source_id].vPosition.y));
-        }
-        else
-        {
-          AIL_end_sample(pMixerChannels[i].hSample);
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      continue;
-
-      case OBJECT_Actor:
-      {
-        assert(source_id < uNumActors);
-
-        //source_x = pActors[source_id].vPosition.x;
-        //source_y = pActors[source_id].vPosition.y;
-        //source_z = pActors[source_id].vPosition.z;
-        int sound_strength = GetSoundStrengthByDistanceFromParty(pActors[source_id].vPosition.x,
-                                                                 pActors[source_id].vPosition.y,
-                                                                 pActors[source_id].vPosition.z);
-        if ( sound_strength )
-        {
-          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
-          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pActors[source_id].vPosition.x,
-                                                                   pActors[source_id].vPosition.y));
-        }
-        else
-        {
-          AIL_end_sample(pMixerChannels[i].hSample);
-          FreeChannel(&pMixerChannels[i]);
-        }
-      }
-      continue;
-
-      default:
-        assert(false);
-        continue;
-    }
-
-    /*if (int sound_strength = GetSoundStrengthByDistanceFromParty(source_x, source_y, source_z))
-    {
-      AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
-      AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(source_x, source_y));
-    }
-    else
-    {
-      AIL_end_sample(pMixerChannels[i].hSample);
-      FreeChannel(&pMixerChannels[i]);
-    } */
-  }
-
-  if (pCurrentScreen != SCREEN_GAME) //îòêëþ÷åíèå çâóêà äåêîðàöèé ïðè ïåðåêëþ÷åíèè îêíà èãðû
-  {
-    if (AIL_sample_status(pMixerChannels[4].hSample) == AIL::Sample::Playing)
-      AIL_end_sample(pMixerChannels[4].hSample);
-    return;
-  }
-  if (!_6807E0_num_decorations_with_sounds_6807B8)
-    return;
-
-  v55 = 0;
-      //v59 = 0;
-  for (uint i = 0; i < _6807E0_num_decorations_with_sounds_6807B8; ++i)
-  {
-    LODWORD(v56) = 1;
-        //v43 = _6807B8_level_decorations_ids[v59];
-        //v44 = &pLevelDecorations[_6807B8_level_decorations_ids[v59]];
-        //v45 = abs(v44->vPosition.z - pParty->vPosition.z);
-        //v46 = abs(v44->vPosition.y - pParty->vPosition.y);
-        //v47 = abs(v44->vPosition.x - pParty->vPosition.x);
-    LevelDecoration* decor = &pLevelDecorations[_6807B8_level_decorations_ids[i]];
-    if (int_get_vector_length(abs(decor->vPosition.x - pParty->vPosition.x),
-                              abs(decor->vPosition.y - pParty->vPosition.y),
-                              abs(decor->vPosition.z - pParty->vPosition.z)) > 0x2000)
-      continue;
-
-    DecorationDesc* decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID];
-      //v48 = &pDecorationList->pDecorations[decor->uDecorationDescID];
-      //v49 = v48->uFlags;
-      uNumRepeats = (~(unsigned __int8)decor_desc->uFlags & DECORATION_DESC_SLOW_LOOP) >> 6;
- 
-    if (decor_desc->SoundOnDawn() || decor_desc->SoundOnDusk())
-    {
-        //v50 = decor->field_1A;
-        v55 = 0.0;
-        uNumRepeats = 2;
-        if (decor->field_1A)
-        {
-          //v51 = decor->field_1A - 32;
-          decor->field_1A = decor->field_1A - 32;
-          if ( decor->field_1A < 0 )
-            decor->field_1A = 0;
-        }
-    }
-
-      //v52 = v48->uFlags;
-    if (!decor_desc->SoundOnDawn())
-    {
-      if (!decor_desc->SoundOnDusk())
-      {
-        if ( v55 == 0.0 )
-        {
-          if ( v56 != 0.0 )
-          {
-            v53 = 8 * _6807B8_level_decorations_ids[i];
-            LOBYTE(v53) = v53 | OBJECT_Decoration;
-            PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);//sound of Boat and water(çâóêè êîðàáëÿ, ïëåñêàíèÿ âîäû)
-          }
-          continue;
-        }
-        if ( !decor->field_1A )
-          decor->field_1A = (rand() % 15 + 1) << 7;
-        if ( v56 != 0.0 )
-        {
-          v53 = 8 * _6807B8_level_decorations_ids[i];
-          LOBYTE(v53) = v53 | OBJECT_Decoration;
-          PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
-        }
-        continue;
-      }
-      if ( v55 != 0.0 )
-      {
-        if ( !decor->field_1A )
-          decor->field_1A = (rand() % 15 + 1) << 7;
-        if ( v56 != 0.0 )
-        {
-          v53 = 8 * _6807B8_level_decorations_ids[i];
-          LOBYTE(v53) = v53 | OBJECT_Decoration;
-          PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
-        }
-        continue;
-      }
-    }
-    v56 = 0.0;
-
-    if (pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 6 ||
-        pParty->uCurrentHour >= 20 && pParty->uCurrentHour < 21)
-    {
-        if ( !decor->field_1A && rand() % 100 < 100 )
-          LODWORD(v56) = 1;
-        LODWORD(v55) = 1;
-    }
-    if ( v55 == 0.0 )
-    {
-      if ( v56 != 0.0 )
-      {
-        v53 = 8 * _6807B8_level_decorations_ids[i];
-        LOBYTE(v53) = v53 | OBJECT_Decoration;
-        PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
-      }
-      continue;
-    }
-    if ( !decor->field_1A )
-      decor->field_1A = (rand() % 15 + 1) << 7;
-    if ( v56 != 0.0 )
-    {
-      v53 = 8 * _6807B8_level_decorations_ids[i];
-      LOBYTE(v53) = v53 | OBJECT_Decoration;
-      PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
-    }
-    continue;
-  }
-  }
-}
-
-//----- (004AB66C) --------------------------------------------------------
-int __fastcall sub_4AB66C(int a1, int a2)
-{
-  signed int v2; // eax@1
-
-  v2 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->Atan2(a1 - pParty->vPosition.x, a2 - pParty->vPosition.y)
-                                  - stru_5C6E00->uIntegerHalfPi - pParty->sRotationY);
-  if ( v2 > (signed int)stru_5C6E00->uIntegerPi )
-    v2 = 2 * stru_5C6E00->uIntegerPi - v2;
-  return (v2 >> 3) - (v2 >> 10);
-}
-// 4AB66C: using guessed type int __fastcall sub_4AB66C(int, int);
-
-//----- (004AB6B1) --------------------------------------------------------
-int GetSoundStrengthByDistanceFromParty(int x, int y, int z)
-{
-  int dir_x; // ST08_4@1
-  int dir_y; // esi@1
-  int dir_z; // eax@1
-  int length; // [sp+10h] [bp+8h]@1
-
-  dir_z = abs(z - pParty->vPosition.z);
-  dir_y = abs(y - pParty->vPosition.y);
-  dir_x = abs(x - pParty->vPosition.x);
-  length = int_get_vector_length(dir_x, dir_y, dir_z);
-  if ( length <= 0x2000 )
-    return 114 - (unsigned __int64)(signed __int64)((double)length * 0.0001220703125 * 100.0);
-  else
-    return 0;
-}
-
-//----- (004AB71F) --------------------------------------------------------
-void AudioPlayer::StopChannels(int uStartChannel, int uEndChannel)
-{
-  if ( bPlayerReady )
-  {
-    if ( b3DSoundInitialized )
-    {
-      for ( uint i = 0; i < uNum3DSamples; ++i )
-      {
-        if ( (uStartChannel == -1 || i < uStartChannel || i > uEndChannel)
-            && p3DSamples[i].field_8 && pSoundList->pSL_Sounds[p3DSamples[i].field_8].eType != SOUND_DESC_SYSTEM)
-        {
-          AIL_end_3D_sample(p3DSamples[i].hSample);
-          _4ABF23(&p3DSamples[i]);
-          p3DSamples[i].field_4 = 0;
-        }
-      }
-    }
-    if ( hDigDriver )
-    {
-      for ( int i = 0; i < uMixerChannels; ++i )
-      {
-        if ( (uStartChannel == -1 || i < uStartChannel || i > uEndChannel)
-          && pSoundList->pSL_Sounds[pMixerChannels[i].uSourceTrackIdx].eType != SOUND_DESC_SYSTEM)//âñå, êðîìå ñèñòåìíûõ çâóêîâ, îòêëþ÷àþòñÿ
-        {
-          AIL_end_sample(pMixerChannels[i].hSample);
-          FreeChannel(&pMixerChannels[i]);
-          pMixerChannels[i].source_pid = 0;
-        }
-      }
-    }
-    if (hSequence)
-      AIL_end_sequence(hSequence);
-    if (hStream)
-      AIL_pause_stream(hStream, 1);
-  }
-}
-
-//----- (004AB818) --------------------------------------------------------
-void AudioPlayer::LoadAudioSnd()
-{
-  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3
-
-  hAudioSnd = CreateFileA("Sounds\\Audio.snd", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, 0);
-  if (hAudioSnd == INVALID_HANDLE_VALUE)
-  {
-    Log::Warning(L"Can't open file: %s", L"Sounds\\Audio.snd");
-    return;
-  }
-
-  ReadFile(hAudioSnd, &uNumSoundHeaders, 4, &NumberOfBytesRead, 0);
-  pSoundHeaders = nullptr;
-  pSoundHeaders = (SoundHeader *)malloc(52 * uNumSoundHeaders + 2);
-  ReadFile(hAudioSnd, pSoundHeaders, 52 * uNumSoundHeaders, &NumberOfBytesRead, 0);
-}
-
-//----- (004AB8CE) --------------------------------------------------------
-void AudioPlayer::Initialize()
-{
-  int v3; // ebx@1
-  _PROVIDER *v6; // eax@9
-  int v12; // [sp+Ch] [bp-Ch]@9
-  char *Str1; // [sp+10h] [bp-8h]@6
-  int v14; // [sp+14h] [bp-4h]@5
-
-  //WriteWindowsRegistryString( "3DSoundProvider", "Aureal A3D Interactive(TM)");//çàïèñü â ðååñòð äëÿ 3D çâóêà(Microsoft DirectSound3D with Creative Labs EAX(TM))
-
-  v3 = 0;
-  //this->hWindow = hWnd;
-  this->hAILRedbook = 0;
-  this->hDigDriver = 0;
-  this->dword_0002AC = 0;
-  this->hSequence = 0;
-  this->uMasterVolume = 127;
-  this->dword_0002C8 = 64;
-  this->dword_0002CC = 2;
-
-  MSS32_DLL_Initialize();
-  BINKW32_DLL_Initialize();
-  SMACKW32_DLL_Initialize();
-  
-  AIL_startup();
-  if (bCanLoadFromCD)
-    hAILRedbook = AIL_redbook_open_drive(cMM7GameCDDriveLetter/*cGameCDDriveLetter*/);
-  //else
-  //  hAILRedbook = AIL_redbook_open(0);
-  //v4 = Audio_GetFirstHardwareDigitalDriver();
-
-  hDigDriver = Audio_GetFirstHardwareDigitalDriver();
-  if ( hDigDriver )
-    SmackSoundUseMSS(hDigDriver);
-  if ( ReadWindowsRegistryInt("Disable3DSound", 0) != 1 && true)//pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
-  {
-    v14 = 0;
-    bEAXSupported = 0;
-    b3DSoundInitialized = 0;
-    ReadWindowsRegistryString("3DSoundProvider", p3DSoundProvider, 128, "NONE");
-    CheckA3DSupport(true);
-    HPROVIDER prov;
-    while ( AIL_enumerate_3D_providers(&v14, &prov, &Str1) )
-    {
-      if ( !strcmp(Str1, p3DSoundProvider) )
-      {
-        if ( AIL_open_3D_provider(prov) )
-        {
-          bEAXSupported = 0;
-          b3DSoundInitialized = 0;
-          h3DSoundProvider = 0;
-        }
-        else
-        {
-          v6 = prov;
-          //v7 = prov;
-          b3DSoundInitialized = 1;
-          h3DSoundProvider = v6;
-          uNum3DSamples = 4;
-          AIL_3D_provider_attribute(prov, "EAX environment selection", &v12);
-          if ( v12 != -1 )
-            bEAXSupported = 1;
-        }
-        pAudioPlayer->_4AC0A2();
-        break;
-      }
-    }
-  }
-  for ( v3; v3 < uMixerChannels; ++v3 )
-  {
-    pMixerChannels[v3].hSample = AIL_allocate_sample_handle(hDigDriver);
-    if ( !pMixerChannels[v3].hSample )
-      break;
-  }
-  uMixerChannels = v3;
-  if ( bPlayerReady )
-    StopChannels(-1, -1);
-  //v10 = hAILRedbook;
-  bPlayerReady = true;
-  if ( hAILRedbook )
-  {
-    AIL_redbook_stop(hAILRedbook);
-    uNumRedbookTracks = AIL_redbook_tracks(hAILRedbook);
-  }
-  pAudioPlayer->sRedbookVolume = AIL_redbook_volume(hAILRedbook);
-  pAudioPlayer->SetMasterVolume(pSoundVolumeLevels[uSoundVolumeMultiplier] * 128.0f);
-  //unsigned __int64 t = (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 128.0f);
-  if ( bPlayerReady && hAILRedbook )
-    //AIL_redbook_set_volume(hAILRedbook, (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 128.0f));
-	AIL_redbook_set_volume(hAILRedbook, (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f) >> 32);
-  //int v = AIL_redbook_volume(pAudioPlayer->hAILRedbook);
-  //if (v)
-    //__debugbreak();
-  LoadAudioSnd();
-}
-
-//----- (004ABAF7) --------------------------------------------------------
-_DIG_DRIVER *Audio_GetFirstHardwareDigitalDriver(void)
-{
-  int v0; // ecx@1
-  size_t v2; // eax@4
-  signed int v3; // kr14_4@9
-  int v5; // [sp+10h] [bp-Ch]@2
-  unsigned int pNum_devices; // [sp+14h] [bp-8h]@1
-  _DIG_DRIVER *hDrv; // [sp+18h] [bp-4h]@3
-  
-  static int sample_Rate = 22050;
-  static int bitsPerSample = 16;
-  static int channels = 2;
-
-  AIL_set_preference(15, 0);
-  AIL_set_preference(33, 1);
-  v0 = sample_Rate;
-  pAudioPlayer->pDeviceNames[0][0] = 0;
-  pAudioPlayer->uNumDevices = 0;
-  pNum_devices = 0;
-
-  if ( sample_Rate < 11025 )
-    return 0;
-  v5 = 0;
-  while ( 1 )
-  {
-    while ( 1 )
-    {
-      pcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;
-      pcmWaveFormat.wf.nChannels = channels;                                   // Channels: 1 = mono, 2 = stereo
-      pcmWaveFormat.wf.nSamplesPerSec = v0;                                    //÷àñòîòà îöèôðîâêè
-      pcmWaveFormat.wf.nBlockAlign = channels * bitsPerSample / 8;             //êîëè÷åñòâî äàííûõ â áëîêå
-      pcmWaveFormat.wBitsPerSample = bitsPerSample;
-      pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
-      if ( !AIL_waveOutOpen(&hDrv, 0, -1, &pcmWaveFormat.wf) )
-      {
-        strcpy(pAudioPlayer->pDeviceNames[v5], "Device: ");
-        v2 = strlen(pAudioPlayer->pDeviceNames[v5]);
-        AIL_digital_configuration(hDrv, (int *)pAudioPlayer->array_000BF0 + v5, (int *)pAudioPlayer->array_000C30 + v5, (char *)pAudioPlayer->pDeviceNames + v2 + v5 * 32);
-        ++pNum_devices;
-        v5++;
-        pAudioPlayer->uNumDevices = pNum_devices;
-        if ( AIL_get_preference(15) )
-          return hDrv;
-        if ( !strstr(pAudioPlayer->pDeviceNames[v5 - 1], "Emulated") )
-          return hDrv;
-        AIL_waveOutClose(hDrv);
-        AIL_set_preference(15, 1);
-        break;
-	  }
-      if ( !AIL_get_preference(15) )
-      {
-        AIL_set_preference(15, 1);
-        if ( sample_Rate < 11025 )
-          return 0;
-	    break;
-      }
-      //v3 = sample_Rate;
-      v0 = sample_Rate / 2;
-      sample_Rate /= 2;
-      if ( sample_Rate / 2 < 11025 )
-      {
-        if ( bitsPerSample == 8 )
-       {
-          v0 = 22050;
-          bitsPerSample = 8;
-          sample_Rate = 22050;
-        }
-        if ( v0 < 11025 )
-          return 0;
-		break;
-      }
-    }
-  }
-}
-
-//----- (004ABC9B) --------------------------------------------------------
-void AudioPlayer::CheckA3DSupport(bool query)
-{
-  DWORD cbData; // [sp+8h] [bp-Ch]@1
-  HKEY hKey; // [sp+10h] [bp-4h]@1
-  hKey = 0;
-  cbData = 4;
-  if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Aureal\\A3D", 0, KEY_READ|KEY_WOW64_32KEY, &hKey))
-  {
-    int Aureal3D_SplashAudio = 0;
-    if (query)
-      RegQueryValueExA(hKey, "SplashAudio", 0, 0, (LPBYTE)&Aureal3D_SplashAudio, &cbData);
-    RegSetValueExA(hKey, "SplashAudio", 0, 4, (const BYTE *)&Aureal3D_SplashAudio, 4);
-
-    int Aureal3D_SplashScreen = 0;
-    if (query)
-      RegQueryValueExA(hKey, "SplashScreen", 0, 0, (LPBYTE)&Aureal3D_SplashScreen, &cbData);
-    RegSetValueExA(hKey, "SplashScreen", 0, 4, (const BYTE *)&Aureal3D_SplashScreen, 4);
-    RegCloseKey(hKey);
-  }
-}
-
-
-//----- (004ABD5B) --------------------------------------------------------
-void AudioPlayer::Release() //Îñâîáîäèòü
-{
-  MixerChannel *pMixerChannel; // ebx@3
-//  char v4; // dl@5
-  AudioPlayer_3DSample *p3DSample; // edi@7
-  void *v9; // ecx@15
-
-  if ( this->bPlayerReady )
-  {
-	free(pSoundHeaders);
-    CloseHandle(pMediaPlayer->hMagicVid);
-    CloseHandle(pMediaPlayer->hMightVid);
-    pAudioPlayer->StopChannels(-1, -1);
-    if ( pAudioPlayer->uMixerChannels > 0 )
-    {
-      pMixerChannel = pAudioPlayer->pMixerChannels;
-      for ( uint i = 0; i < pAudioPlayer->uMixerChannels; ++i )
-      {
-        AIL_release_sample_handle(pMixerChannel->hSample);
-        ++pMixerChannel;
-      }
-    }
-    if ( ReadWindowsRegistryInt("Disable3DSound", 0) != 1 )
-    {
-      CheckA3DSupport(false);
-      if ( pAudioPlayer->uNum3DSamples > 0 )
-      {
-        p3DSample = pAudioPlayer->p3DSamples;
-        for ( uint i = 0; i < pAudioPlayer->uNum3DSamples; ++i )
-        {
-          if ( p3DSample->hSample )
-          {
-            AIL_release_3D_sample_handle(p3DSample->hSample);
-            p3DSample->hSample = 0;
-          }
-          ++p3DSample;
-        }
-      }
-      if ( pAudioPlayer->h3DSoundProvider )
-      {
-        AIL_close_3D_provider(pAudioPlayer->h3DSoundProvider);
-        pAudioPlayer->h3DSoundProvider = 0;
-      }
-    }
-    if ( pAudioPlayer->hAILRedbook )
-    {
-      AIL_redbook_stop(pAudioPlayer->hAILRedbook);
-      AIL_redbook_set_volume((HREDBOOK)&pAudioPlayer->hAILRedbook, pAudioPlayer->sRedbookVolume);
-      AIL_redbook_close(pAudioPlayer->hAILRedbook);
-    }
-    AIL_shutdown();
-    pSoundList->Release();
-    v9 = *(void **)&pAudioPlayer->field_C78[0];
-    if ( v9 )
-      ReleaseSoundData(v9);
-    CloseHandle(pAudioPlayer->hAudioSnd);
-  }
-}
-
-//----- (004ABE55) --------------------------------------------------------
-void AudioPlayer::FreeChannel(MixerChannel *pChannel)
-{
-  int num_same_sound_on_channels; // eax@8
-  int v10; // ecx@12
-  int v12; // eax@13
-  int v14[16]; // [sp+Ch] [bp-48h]@8
-  int num_playing_channels; // [sp+4Ch] [bp-8h]@5
-
-  if (!pSoundList->pSL_Sounds)
-    return;
-
-  //v4 = &pSoundList->pSounds[pChannel->uSourceTrackIdx];
-  if ( pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].eType == SOUND_DESC_SWAP)
-  {
-    if ( pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].pSoundData[0] && 
-       !(pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].uFlags & SOUND_DESC_SYSTEM) )
-    {
-      num_playing_channels = 0;
-      num_same_sound_on_channels = 0;
-      if ( this->uMixerChannels <= 0 )
-        goto LABEL_16;
-      for ( uint i = 0; i < uMixerChannels; i++ )
-      {
-        if ( pChannel->uSourceTrackID == pMixerChannels[i].uSourceTrackID )
-        {
-          v14[num_same_sound_on_channels++] = i;
-          if ( AIL_sample_status((HSAMPLE)pMixerChannels[i].hSample) == AIL::Sample::Playing)
-            ++num_playing_channels;
-        }
-      }
-      if ( !num_playing_channels )
-      {
-LABEL_16:
-        pSoundList->UnloadSound(pChannel->uSourceTrackIdx, 1);
-        for ( v10 = 0; v10 < num_same_sound_on_channels; v10++ )
-        {
-          v12 = 16 * (v14[v10] + 47);
-          pMixerChannels[v14[v10]].uSourceTrackID = 0;
-          *(unsigned int *)((char *)&bEAXSupported + v12) = 0;
-        }
-      }
-    }
-  }
-}
-
-//----- (004ABF23) --------------------------------------------------------
-void AudioPlayer::_4ABF23(AudioPlayer_3DSample *a2)
-{
-  int v2; // ebx@1
-  unsigned __int8 v5; // zf@5
-  unsigned __int8 v6; // sf@5
-  char *v7; // edi@6
-  int v8; // eax@8
-  int v10; // ecx@12
-  int v11; // eax@13
-  int v13[16]; // [sp+Ch] [bp-48h]@8
-  int v14; // [sp+4Ch] [bp-8h]@5
-  int v15; // [sp+50h] [bp-4h]@5
-
-  if ( pSoundList->pSL_Sounds )
-  {
-    //v4 = &pSoundList->pSounds[a2->field_8];
-    if ( pSoundList->pSL_Sounds[a2->field_8].eType == SOUND_DESC_SWAP)
-    {
-      if ( pSoundList->pSL_Sounds[a2->field_8].p3DSound && !(pSoundList->pSL_Sounds[a2->field_8].uFlags & SOUND_DESC_SYSTEM) )
-      {
-        v5 = this->uNum3DSamples == 0;
-        v6 = this->uNum3DSamples < 0;
-        v14 = 0;
-        v15 = 0;
-        if ( v6 | v5 )
-          goto LABEL_16;
-        v7 = (char *)this->p3DSamples;
-        __debugbreak();//Ritor1
-        for ( v2 = 0; v2 < uNum3DSamples; ++v2 )
-        {
-          if ( a2->field_C == *((int *)v7 + 3) )
-          {
-            v8 = v15;
-            //v9 = this->p3DSamples[v2];
-            ++v15;
-            v13[v8] = v2;
-            if ( AIL_3D_sample_status(&this->p3DSamples[v2]) == 4 )
-              ++v14;
-          }
-          v7 += 16;
-        }
-        if ( !v14 )
-        {
-LABEL_16:
-          pSoundList->UnloadSound(a2->field_8, 1);
-          for ( v10 = 0; v10 < v15; v10++ )
-          {
-            v11 = v13[v10];
-            *(&bEAXSupported + 4 * (v11 + 2)) = 0;
-            p3DSamples[v11].field_8 = 0;
-          }
-        }
-      }
-    }
-  }
-}
-
-//----- (004ABFDB) --------------------------------------------------------
-void PlayLevelMusic()
-{
-  unsigned int v0; // eax@1
-
-  v0 = pMapStats->GetMapInfo(pCurrentMapName);
-  if ( v0 )
-    pAudioPlayer->PlayMusicTrack((MusicID)pMapStats->pInfos[v0].uRedbookTrackID);
-}
-
-//----- (004AC004) --------------------------------------------------------
-void AudioPlayer::SetEAXPreferences()
-{
-  float v4; // [sp+4h] [bp-4h]@2
-
-  if ( this->bEAXSupported )
-  {
-    v4 = 0.0;
-    AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX effect volume", (int *)&v4);
-    v4 = 1.0;
-    AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX damping", (int *)&v4);
-  }
-}
-// 4D82DC: using guessed type int __stdcall AIL_set_3D_provider_preference(int, int, int);
-
-//----- (004AC041) --------------------------------------------------------
-void AudioPlayer::SetMapEAX()
-{
-  unsigned int pMapID; // eax@1
-  int v3; // [sp+4h] [bp-4h]@3
-
-  pMapID = pMapStats->GetMapInfo(pCurrentMapName);
-  if ( this->b3DSoundInitialized && this->bEAXSupported )
-  {
-    v3 = pMapStats->pInfos[pMapID].uEAXEnv;
-    if ( (unsigned int)v3 >= 0x1A )
-    {
-      SetEAXPreferences();
-      this->field_214 = -1;
-    }
-    else
-    {
-      AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX environment selection", &v3);
-      this->field_214 = v3;
-    }
-  }
-}
-// 4D82DC: using guessed type int __stdcall AIL_set_3D_provider_preference(int, int, int);
-
-//----- (004AC0A2) --------------------------------------------------------
-int AudioPlayer::_4AC0A2()
-{
-  unsigned int map_id; // eax@1
-  void *v9; // eax@8
-  int v12; // [sp+1Ch] [bp-8h]@1
-
-  if ( this->b3DSoundInitialized )
-  {
-    //v5 = &this->uNum3DSamples;
-    AIL_3D_provider_attribute(this->h3DSoundProvider, "Maximum supported samples", &this->uNum3DSamples);
-    if ( this->uNum3DSamples > 32 )
-      this->uNum3DSamples = 32;
-    //v6 = this->uNum3DSamples;
-    if ( !this->uNum3DSamples )
-    {
-      this->b3DSoundInitialized = 0;
-      return -1;
-    }
-    //v13 = 0;
-    //if ( this->uNum3DSamples > 0 )
-    //{
-      //v8 = this->p3DSamples;
-      //while ( 1 )
-      for ( int i = 0; i < this->uNum3DSamples; ++i )
-      {
-        v9 = (void *)AIL_allocate_3D_sample_handle(this->h3DSoundProvider);
-        this->p3DSamples[i].hSample = v9;
-        if ( !v9 )
-          this->uNum3DSamples = i;
-        AIL_set_3D_sample_float_distances(v9, 4096.0, 256.0, 4096.0, 256.0);
-        AIL_set_3D_sample_volume(this->p3DSamples[i].hSample, this->s3DSoundVolume);
-        //++v8;
-      }
-    //}
-    if ( this->bEAXSupported )
-    {
-      //v10 = v4;
-      //v11 = pMapStats->pInfos[map_id].uEAXEnv;
-      map_id = pMapStats->GetMapInfo(pCurrentMapName);
-      v12 = pMapStats->pInfos[map_id].uEAXEnv;
-      if ( pMapStats->pInfos[map_id].uEAXEnv >= 0x1A )
-      {
-        pAudioPlayer->SetEAXPreferences();
-        this->field_214 = -1;
-      }
-      else
-      {
-        AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX environment selection", &v12);
-        this->field_214 = v12;
-      }
-    }
-  }
-  return 1;
-}
-
-//----- (004A96BE) --------------------------------------------------------
-void ReleaseSoundData(void *_this)
-{
-  //for ( uint i = 0; (void *)&pSounds[i].pSoundData < (void *)&pSounds[2999].pSoundData; i++ )
-  for ( uint i = 0; i < 2999; i++ )
-  {
-    if ( pSounds[i].pSoundData == _this )
-    {
-      free(_this);
-      memset(&pSounds[i], 0, sizeof(pSounds[i]));
-    }
-  }
-
-}
-
-//----- (004A96FF) --------------------------------------------------------
-struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName)
-{
-/*  SoundHeader *result; // eax@2
-  SoundHeader *pSound;
-  signed int v6; // ebx@11
-
-  while ( 1 )
-  {
-    v6 = uEnd - uStart;
-    pSound = &pAudioPlayer->pSoundHeaders[v6 / 2 + uStart];
-    if ( !pSound )
-      return false;
-    result = (SoundHeader *)_stricmp(pName, pSound->pSoundName);
-    if ( !_stricmp(pName, pSound->pSoundName) )
-      uFindSound_BinSearch_ResultID = v6 / 2 + uStart;
-    if ( uStart == uEnd )
-    {
-      uFindSound_BinSearch_ResultID = -1;
-      return result;
-    }
-    if ( (signed int)result < 0 )
-      break;
-
-    if ( v6 <= 4 )
-    {
-      if ( (signed int)uStart < (signed int)uEnd )
-      {
-        for ( uint i = uStart; i < (signed int)uEnd; ++i )
-        {
-          if ( !_stricmp(pName, pAudioPlayer->pSoundHeaders[i].pSoundName) )
-          {
-            uFindSound_BinSearch_ResultID = i;
-            return &pAudioPlayer->pSoundHeaders[i];
-          }
-        }
-      }
-      uFindSound_BinSearch_ResultID = -1;
-      return false;
-    }
-
-    uStart += v6 / 2;
-LABEL_10:
-	;
-  }
-  if ( v6 > 4 )
-  {
-    uEnd = v6 / 2 + uStart;
-    goto LABEL_10;
-  }
-  if ( (signed int)uStart >= (signed int)uEnd )
-  {
-    uFindSound_BinSearch_ResultID = -1;
-    return false;
-  }*/
-  for ( uint i = uStart; i < (signed int)uEnd; ++i )
-  {
-    if ( !_stricmp(pName, pAudioPlayer->pSoundHeaders[i].pSoundName) )
-    {
-      uFindSound_BinSearch_ResultID = i;
-      return &pAudioPlayer->pSoundHeaders[i];
-    }
-  }
-  uFindSound_BinSearch_ResultID = -1;
-  return false;
-}
-// F1B4C8: using guessed type int uFindSound_BinSearch_ResultID;
-
-//----- (004A97C6) --------------------------------------------------------
-SoundData *LoadSound(const char *pSoundName, SoundData *pOutBuff, unsigned int uID)
-{
-  DWORD NumberOfBytesRead; // [sp+14h] [bp-8h]@8
-
-  for (uint i = 0; i < 3000; ++i)
-  {
-    if (pSounds[i].uID == uID)
-      return pSounds[i].pSoundData;
-  }
-  FindSound_BinSearch(0, pAudioPlayer->uNumSoundHeaders, pSoundName);
-  if ( uFindSound_BinSearch_ResultID == -1 )
-    return 0;
-  if ( pOutBuff == (SoundData *)-1 )
-    pOutBuff = (SoundData *)malloc(pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize + 4);
-  SetFilePointer(pAudioPlayer->hAudioSnd, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uFileOffset, 0, 0);
-  if ( (signed int)pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize >= (signed int)pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize )
-  {
-    pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize = pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
-    if ( pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize )
-    {
-      ReadFile(pAudioPlayer->hAudioSnd, pOutBuff->pData, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize, &NumberOfBytesRead, 0);// Ritor1: pSounds[20]
-    }
-    else
-    {
-      MessageBoxW(nullptr, L"Can't load sound file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Sound.cpp:448", 0);
-    }
-  }
-  else
-  {
-    uID = (unsigned int)malloc(pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize);
-    ReadFile(pAudioPlayer->hAudioSnd, (LPVOID)uID, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize, &NumberOfBytesRead, 0);
-    zlib::MemUnzip(pOutBuff->pData, &pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize, (const void *)uID, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize);
-    free((void *)uID);
-  }
-  if ( pOutBuff )
-  {
-    pOutBuff->uDataSize = pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
-    uLastLoadedSoundID = 0;
-    if ( pSounds[0].pSoundData )
-    {
-      for ( uint i = 0; pSounds[i].pSoundData; i++ )
-        ++uLastLoadedSoundID;
-    }
-    strcpy((char *)pSounds[uLastLoadedSoundID].SoundName, pSoundName);
-    pSoundList->uTotalLoadedSoundSize += pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
-    pSounds[uLastLoadedSoundID].pSoundData = pOutBuff;
-    return pOutBuff;
-  }
-  else
-    return 0;
-}
--- a/AudioPlayer.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,363 +0,0 @@
-#pragma once
-#include "OSAPI.h"
-#include "MediaPlayer.h"
-
-
-
-
-
-
-#pragma pack(push, 1)
-struct _PROVIDER {char unk_0;};
-struct _SAMPLE   {char unk_0;};
-//struct _STREAM   {char unk_0;};
-struct _REDBOOK  {char unk_0;};
-struct _DIG_DRIVER {char unk_0;};
-struct _SEQUENCE {char unk_0;};
-#pragma pack(pop)
-
-
-
-/*   22 */
-#pragma pack(push, 1)
-struct AudioPlayer_3DSample
-{
-  inline AudioPlayer_3DSample()
-  {
-    hSample = 0;
-    field_4 = 0;
-    field_8 = 0;
-    field_C = 0;
-  }
-
-  void *hSample;
-  int field_4;
-  int field_8;
-  int field_C;
-};
-#pragma pack(pop)
-
-
-
-
-/*   26 */
-/*#pragma pack(push, 1)
-struct SoundHeader
-{
-  char pSoundName[40];
-  unsigned int uFileOffset;
-  unsigned int uCompressedSize;
-  unsigned int uDecompressedSize;
-};
-#pragma pack(pop)*/
-
-/*   27 */
-#pragma pack(push, 1)
-struct MixerChannel
-{
-  inline MixerChannel():
-    hSample(nullptr), source_pid(0), uSourceTrackIdx(0), uSourceTrackID(0)
-  {}
-
-  _SAMPLE *hSample;
-  int source_pid;
-  unsigned int uSourceTrackIdx;
-  unsigned int uSourceTrackID;
-};
-#pragma pack(pop)
-
-
-
-
-
-/*  308 */
-enum SoundID
-{
-  SOUND_Invalid = 0,
-  SOUND_EnteringAHouse = 6,
-  SOUND_7 = 7,
-  SOUND_8 = 0x8,
-  SOUND_24 = 24,
-  SOUND_error = 27,
-  SOUND_RunAlongWater = 63,
-  SOUND_RunAlong3DModel = 64,
-  SOUND_Button = 66,
-  SOUND_67 = 67,
-  SOUND_71 = 71,
-  SOUND_Button2 = 75,
-  SOUND_78 = 78,
-  SOUND_80 = 80,
-  SOUND_81 = 81,
-  SOUND_83 = 83,
-  SOUND_84 = 84,
-  SOUND_85 = 85,
-  SOUND_WalkAlongWater = 102,
-  SOUND_WalkAlong3DModel = 103,
-  SOUND_Arcomage_LoseResources = 0x78,
-  SOUND_Arcomage_AddResources = 0x79,
-  SOUND_Arcomage_TowerWallDamage = 0x7A,
-  SOUND_Arcomage_DrawCard = 0x7B,
-  SOUND_Arcomage_124 = 0x7C,
-  SOUND_Arcomage_ProductionDamage = 0x7D,
-  SOUND_Arcomage_ProductionUpgrade = 0x7E,
-  SOUND_Arcomage_127 = 0x7F,
-  SOUND_Arcomage_128 = 0x80,
-  SOUND_Arcomage_TowerUpgrade = 0x81,
-  SOUND_Arcomage_130 = 0x82,
-  SOUND_Arcomage_131 = 0x83,
-  SOUND_Arcomage_WallUpgrade = 0x84,
-  SOUND_PlayLute = 133, // 85
-  SOUND_PlayFaeriePipes = 134, // 86
-  SOUND_PlayGryphonheartsTrumpet = 135, // 87
-  SOUND_GoldReceived = 0xC8,
-  SOUND_203 = 203,
-  SOUND_206 = 206,
-  SOUND_207 = 207,
-  SOUND_OpenChest = 208,
-  SOUND_PlayerCantCastSpell = 0xD1,
-  SOUND_EatApple = 211, // D3
-  SOUND_Bell = 0xD9,
-  SOUND_OpenBook = 230,
-  SOUND_CloseBook = 231,
-  SOUND_11090 = 11090,
-  SOUND_12040 = 12040,
-  SOUND_Arena_Welcome = 14060,
-  SOUND_20001 = 0x4E21,
-};
-
-
-enum MusicID: unsigned __int32
-{
-  MUSIC_Credits = 15
-};
-
-/*   20 */
-#pragma pack(push, 1)
-struct AudioPlayer
-{
-  //----- (004A9669) --------------------------------------------------------
-  AudioPlayer():
-    bPlayerReady(false), b3DSoundInitialized(false),
-    hAILRedbook(nullptr), hStream(nullptr)
-  {
-	/*AudioPlayer_3DSample *v0; //ecx@1
-	signed int v1; //edi@1
-
-	v0 = p3DSamples;
-	v1 = 32;
-	do
-	{
-		v0->field_4 = 0;
-		v0->field_8 = 0;
-		v0->field_C = 0;
-		v0->hSample = 0;
-		++v0;
-		--v1;
-	}
-	while (v1);*/
-    uMixerChannels = 16;
-    field_2D0_time_left = 256;
-    uNumRedbookTracks = 0;
-    uCurrentMusicTrackLength = 0;
-    field_2D4 = 0;
-    s3DSoundVolume = 127;
-  }
-  inline ~AudioPlayer(){ Release(); };
-  void SetMusicVolume(int vol);
-  void SetMasterVolume(float fVolume);
-  void _4AA258(int a2);
-  void PlaySound(SoundID eSoundID, signed int a3, unsigned int uNumRepeats, signed int a5, signed int a6, int a7, float uVolume, int sPlaybackRate);
-  void UpdateSounds();
-  void StopChannels(int uStartChannel, int uEndChannel);
-  void LoadAudioSnd();//
-  void Initialize();//
-  void CheckA3DSupport(bool query);
-  void Release();
-  void FreeChannel(MixerChannel *pChannel);
-  void _4ABF23(AudioPlayer_3DSample *a2);
-  void SetEAXPreferences();
-  void SetMapEAX();
-  int _4AC0A2();
-  void PlayMusicTrack(enum MusicID eTrack);
-  void  MessWithChannels();
-
-
-  unsigned int bEAXSupported;
-  unsigned int b3DSoundInitialized;
-  int s3DSoundVolume;
-  struct _PROVIDER *h3DSoundProvider;
-  int uNum3DSamples;
-  struct AudioPlayer_3DSample p3DSamples[32];
-  int field_214;
-  int sRedbookVolume;
-  char p3DSoundProvider[128];
-  unsigned int bPlayerReady;
-  //HWND hWindow;
-  class OSWindow *window;
-  struct _REDBOOK *hAILRedbook;
-  struct _DIG_DRIVER *hDigDriver;
-  int dword_0002AC;
-  struct _SEQUENCE *hSequence;
-  int dword_0002B4;
-  struct SoundHeader *pSoundHeaders;
-  HANDLE hAudioSnd;
-  unsigned int uNumSoundHeaders;
-  unsigned int uMasterVolume;
-  int dword_0002C8;
-  int dword_0002CC;
-  int field_2D0_time_left;
-  int field_2D4;
-  unsigned int uCurrentMusicTrackLength;
-  unsigned int uNumRedbookTracks;
-  unsigned int uCurrentMusicTrackStartMS;
-  unsigned int uCurrentMusicTrackEndMS;
-  struct MixerChannel pMixerChannels[16];
-  int uMixerChannels;
-  int field_3EC;
-  char pDeviceNames[16][128];
-  int array_000BF0[16];
-  int array_000C30[16];
-  unsigned int uNumDevices;
-  struct _STREAM *hStream;
-  char field_C78[8];
-  int cGameCDDriveLetter;
-};
-#pragma pack(pop)
-
-
-
-
-
-
-
-
-/*  325 */
-enum SOUND_DESC_TYPE : __int32
-{
-  SOUND_DESC_LEVEL = 0x0,
-  SOUND_DESC_SYSTEM = 0x1,
-  SOUND_DESC_SWAP = 0x2,
-  SOUND_DESC_3 = 0x3,
-  SOUND_DESC_LOCK = 0x4,
-};
-
-/*  326 */
-enum SOUND_DESC_FLAGS
-{
-  SOUND_DESC_LOCKED = 0x1,
-  SOUND_DESC_3D = 0x2,
-};
-
-
-#pragma pack(push, 1)
-struct SoundData
-{
-  unsigned int uDataSize;
-  char         pData[1];
-};
-
-struct SoundDesc_mm6
-{
-  inline bool Is3D()  {return (uFlags & SOUND_DESC_3D) != 0;}
-
-  char pSoundName[32];
-  unsigned int uSoundID;
-  SOUND_DESC_TYPE eType;
-  int uFlags;
-  SoundData *pSoundData[17];
-};
-
-struct SoundDesc: public SoundDesc_mm6
-{
-  void *p3DSound;
-  int bDecompressed;
-};
-#pragma pack(pop)
-
-
-
-#pragma pack(push, 1)
-struct SoundList
-{
-  inline SoundList():
-    sNumSounds(0), pSL_Sounds(nullptr), uTotalLoadedSoundSize(0)
-  {}
-
-  void Initialize();
-  __int16 LoadSound(int a1, unsigned int a3);
-  int LoadSound(unsigned int a2, LPVOID lpBuffer, int uBufferSizeLeft, int *pOutSoundSize, int a6);
-  SoundDesc *Release();
-  void _4A9D79(int a2);
-  void UnloadSound(unsigned int uSoundID, char a3);
-  void ToFile();
-  void FromFile(void *data_mm6, void *data_mm7, void *data_mm8);
-  int FromFileTxt(const char *Args);
-
-  signed int sNumSounds;
-  SoundDesc *pSL_Sounds;
-  unsigned int uTotalLoadedSoundSize;
-};
-#pragma pack(pop)
-
-
-
-
-
-/*  241 */
-#pragma pack(push, 1)
-struct Sound
-{
-  unsigned int uID;
-  char SoundName[120];
-  SoundData *pSoundData;
-};
-#pragma pack(pop)
-
-
-
-
-extern int Aureal3D_SplashScreen;
-extern int Aureal3D_SplashAudio;
-extern int uFindSound_BinSearch_ResultID; // weak
-extern int uLastLoadedSoundID; // weak
-extern int sLastTrackLengthMS;
-extern std::array<Sound, 3000> pSounds;
-extern AudioPlayer *pAudioPlayer;
-extern SoundList *pSoundList;
-
-extern unsigned __int8 uSoundVolumeMultiplier;
-extern unsigned __int8 uVoicesVolumeMultiplier;
-extern unsigned __int8 uMusicVolimeMultiplier;
-extern int bWalkSound; // idb
-
-extern std::array<float, 10> pSoundVolumeLevels; // idb
-
-
-
-
-
-
-
-
-/*  379 */
-#pragma pack(push, 1)
-struct stru339_spell_sound
-{
-  int AddPartySpellSound(int uSoundID, int a6);
-
-  char pSounds[44744];
-  int field_AEC8[45];
-  int field_AF7C[18];
-  int field_AFC4;
-  int pSoundsSizes[2];
-  int pSoundsOffsets[2];
-};
-#pragma pack(pop)
-extern std::array<stru339_spell_sound, 4> stru_A750F8;
-extern std::array<stru339_spell_sound, 4> AA1058_PartyQuickSpellSound;
-
-struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName);
-struct SoundData *LoadSound(const char *pSoundName, struct SoundData *pOutBuff, unsigned int uID);
-int __fastcall sub_4AB66C(int, int); // weak
-int GetSoundStrengthByDistanceFromParty(int x, int y, int z);
-void PlayLevelMusic();
--- a/Bink_Smacker.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,336 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "Bink_Smacker.h"
-
-
-
-
-
-
-
-int (__stdcall *smackw32_SmackSoundUseMSS)(HDIGDRIVER) = 0;
-unsigned int (__stdcall *smackw32_SmackUseMMX)(unsigned int) = 0;
-HSMACK (__stdcall *smackw32_SmackOpen)(HANDLE, unsigned int, unsigned int) = 0;
-HSMACKBLIT (__stdcall *smackw32_SmackBlitOpen)(unsigned int) = 0;
-void (__stdcall *smackw32_SmackToBuffer)(HSMACK, unsigned int, unsigned int, unsigned int, unsigned int, void *, unsigned int) = 0;
-void (__stdcall *smackw32_SmackBlitSetPalette)(HSMACKBLIT, void *, unsigned int) = 0;
-unsigned int (__stdcall *smackw32_SmackDoFrame)(HSMACK) = 0;
-unsigned int (__stdcall *smackw32_SmackToBufferRect)(HSMACK, unsigned int) = 0;
-void (__stdcall *smackw32_SmackBlit)(HSMACKBLIT, void *, unsigned int, unsigned int, unsigned int, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) = 0;
-void (__stdcall *smackw32_SmackNextFrame)(HSMACK) = 0;
-unsigned int (__stdcall *smackw32_SmackWait)(HSMACK) = 0;
-unsigned int (__stdcall *smackw32_SmackSoundOnOff)(HSMACK, unsigned int) = 0;
-void (__stdcall *smackw32_SmackClose)(HSMACK) = 0;
-void (__stdcall *smackw32_SmackBufferClose)(HSMACKBUF) = 0;
-void (__stdcall *smackw32_SmackBlitClose)(HSMACKBLIT) = 0;
-int  (__stdcall *smackw32_SmackBlitClear)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int) = 0;
-int  (__stdcall *smackw32_SmackGoto)(_SMACK *, long) = 0;
-int  (__stdcall *smackw32_SmackBufferOpen)(HWND a1, long a2, long a3, long a4, long a5, long a6) = nullptr;
-void(__stdcall *smackw32_SmackBufferNewPalette)(HSMACKBUF, void *, unsigned int) = nullptr;
-void(__stdcall *smackw32_SmackColorRemapWithTrans)(_SMACK *, void *, unsigned int, unsigned int, unsigned int) = nullptr;
-void SMACKW32_DLL_Initialize()
-{
-  HMODULE pDll = LoadLibraryW(L"SmackW32.dll");
-  
-  #define LOAD(x) smackw32_##x = (decltype(smackw32_##x))GetProcAddress(pDll, #x)
-  {
-    smackw32_SmackSoundUseMSS = (int (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_SmackSoundUseMSS@4");
-    smackw32_SmackUseMMX = (unsigned int (__stdcall *)(unsigned int))GetProcAddress(pDll, "_SmackUseMMX@4");
-    smackw32_SmackOpen = (HSMACK (__stdcall *)(HANDLE, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackOpen@12");
-    smackw32_SmackBlitOpen = (HSMACKBLIT (__stdcall *)(unsigned int))GetProcAddress(pDll, "_SmackBlitOpen@4");
-    smackw32_SmackToBuffer = (void (__stdcall *)(HSMACK, unsigned int, unsigned int, unsigned int, unsigned int, void *, unsigned int))GetProcAddress(pDll, "_SmackToBuffer@28");
-    smackw32_SmackBlitSetPalette = (void (__stdcall *)(HSMACKBLIT, void *, unsigned int))GetProcAddress(pDll, "_SmackBlitSetPalette@12");
-    smackw32_SmackDoFrame = (unsigned int (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackDoFrame@4");
-    smackw32_SmackToBufferRect = (unsigned int (__stdcall *)(HSMACK, unsigned int))GetProcAddress(pDll, "_SmackToBufferRect@8");
-    smackw32_SmackBlit = (void (__stdcall *)(HSMACKBLIT, void *, unsigned int, unsigned int, unsigned int, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackBlit@44");
-    smackw32_SmackNextFrame = (void (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackNextFrame@4");
-    smackw32_SmackWait = (unsigned int (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackWait@4");
-    smackw32_SmackSoundOnOff = (unsigned int (__stdcall *)(HSMACK, unsigned int))GetProcAddress(pDll, "_SmackSoundOnOff@8");
-    smackw32_SmackClose = (void (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackClose@4");
-    smackw32_SmackBufferClose = (void (__stdcall *)(HSMACKBUF))GetProcAddress(pDll, "_SmackBufferClose@4");
-    smackw32_SmackBlitClose = (void (__stdcall *)(HSMACKBLIT))GetProcAddress(pDll, "_SmackBlitClose@4");
-    smackw32_SmackBlitClear = (int (__stdcall *)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int))GetProcAddress(pDll, "_SmackBlitClear@32");
-    smackw32_SmackGoto = (int  (__stdcall *)(_SMACK *, long))GetProcAddress(pDll, "_SmackGoto@8");
-    smackw32_SmackBufferOpen = (int  (__stdcall *)(HWND, long, long, long, long, long))GetProcAddress(pDll, "_SmackBufferOpen@24");
-	smackw32_SmackBufferNewPalette = (void(__stdcall *)(HSMACKBUF, void *, unsigned int))GetProcAddress(pDll, "_SmackBufferNewPalette@12");
-	smackw32_SmackColorRemapWithTrans = (void(__stdcall *)(_SMACK *, void *, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackColorRemapWithTrans@20");
-    //LOAD(SmackBufferNewPalette);
-    //LOAD(SmackColorRemapWithTrans);
-  }
-}
-
-
-
-
-void __stdcall SmackColorRemapWithTrans(_SMACK *a1, void *a2, unsigned int a3, unsigned int a4, unsigned int a5)
-{
-  return (smackw32_SmackColorRemapWithTrans)(a1, a2, a3, a4, a5);
-}
-
-void __stdcall SmackBlitClose(HSMACKBLIT hBlit)
-{
- (smackw32_SmackBlitClose)(hBlit);
-}
-
-void __stdcall SmackBufferClose(HSMACKBUF hBuf)
-{
- (smackw32_SmackBufferClose)(hBuf);
-}
-
-void __stdcall SmackClose(HSMACK hSmack)
-{
- (smackw32_SmackClose)(hSmack);
-}
-
-unsigned int __stdcall SmackSoundOnOff(HSMACK hSmack, unsigned int bOn)
-{
- return (smackw32_SmackSoundOnOff)(hSmack, bOn);
-}
-
-unsigned int __stdcall SmackWait(HSMACK hSmack)
-{
- return (smackw32_SmackWait)(hSmack);
-}
-
-void __stdcall SmackNextFrame(HSMACK hSmack)
-{
- (smackw32_SmackNextFrame)(hSmack);
-}
-
-void __stdcall SmackBlit(HSMACKBLIT hBlit, void *pDest, unsigned int uDestPitch, unsigned int uDestX, unsigned int uDestY, void *pSrc, unsigned int uSrcPitch, unsigned int uSrcX, unsigned int uSrcY, unsigned int uSrcZ, unsigned int uSrcW)
-{
- (smackw32_SmackBlit)(hBlit, pDest, uDestPitch, uDestX, uDestY, pSrc, uSrcPitch, uSrcX, uSrcY, uSrcZ, uSrcW);
-}
-
-unsigned int __stdcall SmackToBufferRect(HSMACK hSmack, unsigned int uSmackSurface)
-{
- return (smackw32_SmackToBufferRect)(hSmack, uSmackSurface);
-}
-
-unsigned int __stdcall SmackDoFrame(HSMACK hSmack)
-{
- return (smackw32_SmackDoFrame)(hSmack);
-}
-
-void __stdcall SmackBlitSetPalette(HSMACKBLIT hBlit, void *pPalette, unsigned int uPalType)
-{
- (smackw32_SmackBlitSetPalette)(hBlit, pPalette, uPalType);
-}
-
-int __stdcall SmackSoundUseMSS(HDIGDRIVER hDrv)
-{
- return (smackw32_SmackSoundUseMSS)(hDrv);
-}
-
-unsigned int __stdcall SmackUseMMX(unsigned int flag)
-{
- return (smackw32_SmackUseMMX)(flag);
-}
-
-HSMACK __stdcall SmackOpen(HANDLE hSourceFile, unsigned int uFlags, unsigned int uExtraBuffers)
-{
- return (smackw32_SmackOpen)(hSourceFile, uFlags, uExtraBuffers);
-}
-
-HSMACKBLIT __stdcall SmackBlitOpen(unsigned int uSurfaceFormat)
-{
- return (smackw32_SmackBlitOpen)(uSurfaceFormat);
-}
-
-void __stdcall SmackToBuffer(HSMACK hSmack, unsigned int uX, unsigned int uY, unsigned int uPitch, unsigned int uHeight, void *pBuffer, unsigned int uFlags)
-{
- (smackw32_SmackToBuffer)(hSmack, uX, uY, uPitch, uHeight, pBuffer, uFlags);
-}
-
-int __stdcall SmackBlitClear(HSMACKBLIT a1, unsigned short *pFrameData, unsigned int uTargetSurfacePitch, unsigned int uOutX, unsigned int uOutY, unsigned int uOutZ, unsigned int uOutW, int a8)
-{
- return (smackw32_SmackBlitClear)(a1, pFrameData, uTargetSurfacePitch, uOutX, uOutY, uOutZ, uOutW, a8);
-}
-
-int __stdcall SmackGoto(_SMACK *a1, long a2)
-{
- return (smackw32_SmackGoto)(a1, a2);
-}
-
-
-int __stdcall SmackBufferOpen(HWND a1, long a2, long a3, long a4, long a5, long a6)
-{
-  return (smackw32_SmackBufferOpen)(a1, a2, a3, a4, a5, a6);
-}
-
-int __fastcall SmackVolumePan(_SMACK *a3, long a4, long a5, long a6)
-{
- //__asm int 3
- return 0;
-}
-
-
-// sub_4D83D0: using guessed type int __stdcall SmackBufferNewPalette(_DWORD, _DWORD, _DWORD);
-void __stdcall SmackBufferNewPalette(HSMACKBUF a1, void *a2, unsigned int a3)
-{
- (smackw32_SmackBufferNewPalette)(a1, a2, a3);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-int (__stdcall *binkw32_BinkDDSurfaceType)(struct IDirectDrawSurface *) = 0;
-int (__stdcall *binkw32_BinkSetSoundSystem)(void *, HDIGDRIVER) = 0;
-int (__stdcall *binkw32_BinkOpenMiles)(int) = 0;
-HBINK (__stdcall *binkw32_BinkOpen)(void *, unsigned int) = 0;
-int (__stdcall *binkw32_BinkWait)(HBINK) = 0;
-int (__stdcall *binkw32_BinkDoFrame)(HBINK) = 0;
-int (__stdcall *binkw32_BinkNextFrame)(HBINK) = 0;
-int (__stdcall *binkw32_BinkGetRects)(HBINK, unsigned int) = 0;
-int (__stdcall *binkw32_BinkCopyToBuffer)(HBINK, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) = 0;
-int (__stdcall *binkw32_BinkPause)(HBINK, int) = 0;
-int (__stdcall *binkw32_BinkClose)(HBINK) = 0;
-int (__stdcall *binkw32_BinkBufferSetOffset)(void *, int, int) = 0;
-int (__stdcall *binkw32_BinkBufferSetScale)(void *, unsigned int, unsigned int) = 0;
-void BINKW32_DLL_Initialize()
-{
- HMODULE pDll = LoadLibraryW(L"BinkW32.dll");
-
- binkw32_BinkDDSurfaceType = (int (__stdcall *)(struct IDirectDrawSurface *))GetProcAddress(pDll, "_BinkDDSurfaceType@4");
- binkw32_BinkSetSoundSystem = (int (__stdcall *)(void *, HDIGDRIVER))GetProcAddress(pDll, "_BinkSetSoundSystem@8");
- binkw32_BinkOpenMiles = (int (__stdcall *)(int))GetProcAddress(pDll, "_BinkOpenMiles@4");
- binkw32_BinkOpen = (HBINK (__stdcall *)(void *, unsigned int))GetProcAddress(pDll, "_BinkOpen@8");
- binkw32_BinkWait = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkWait@4");
- binkw32_BinkBufferSetOffset = (int (__stdcall *)(void *, int, int))GetProcAddress(pDll, "_BinkBufferSetOffset@12");
- binkw32_BinkBufferSetScale = (int (__stdcall *)(void *, unsigned int, unsigned int))GetProcAddress(pDll, "_BinkBufferSetScale@12");
- binkw32_BinkDoFrame = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkDoFrame@4");
- binkw32_BinkNextFrame = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkNextFrame@4");
- binkw32_BinkGetRects = (int (__stdcall *)(HBINK, unsigned int))GetProcAddress(pDll, "_BinkGetRects@8");
- binkw32_BinkCopyToBuffer = (int (__stdcall *)(HBINK, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_BinkCopyToBuffer@28");
- binkw32_BinkPause = (int (__stdcall *)(HBINK, int))GetProcAddress(pDll, "_BinkPause@8");
- binkw32_BinkClose = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkClose@4");
-}
-
-
-int __stdcall BinkPause(HBINK hBink, int bPause)
-{
- return (binkw32_BinkPause)(hBink, bPause);
-}
-
-int __stdcall BinkClose(HBINK hBink)
-{
- return (binkw32_BinkClose)(hBink);
-}
-
-int __stdcall BinkGetRects(HBINK hBink, unsigned int uFlags)
-{
- return (binkw32_BinkGetRects)(hBink, uFlags);
-}
-
-int __stdcall BinkCopyToBuffer(HBINK hBink, void *pBuffer, unsigned int lPitch, unsigned int uNumScanlines, unsigned int uX, unsigned int uY, unsigned int uFlags)
-{
- return (binkw32_BinkCopyToBuffer)(hBink, pBuffer, lPitch, uNumScanlines, uX, uY, uFlags);
-}
-
-int __stdcall BinkDoFrame(HBINK hBink)
-{
- return (binkw32_BinkDoFrame)(hBink);
-}
-
-int __stdcall BinkNextFrame(HBINK hBink)
-{
- return (binkw32_BinkNextFrame)(hBink);
-}
-
-HBINK __stdcall BinkOpen(void *hFileHandle, unsigned int uFlags)
-{
- return (binkw32_BinkOpen)(hFileHandle, uFlags);
-}
-
-int __stdcall BinkOpenMiles(int unk)
-{
- return (binkw32_BinkOpenMiles)(unk);
-}
-
-int __stdcall BinkWait(HBINK hBink)
-{
- return (binkw32_BinkWait)(hBink);
-}
-
-
-
-int __stdcall BinkBufferSetOffset(void *pStruct, int b, int c)
-{
- return (binkw32_BinkBufferSetOffset)(pStruct, b, c);
-}
-
-int __stdcall BinkBufferSetScale(void *pStruct, unsigned int uWidth, unsigned int uHeight)
-{
- return (binkw32_BinkBufferSetScale)(pStruct, uWidth, uHeight);
-}
-
-int __stdcall BinkDDSurfaceType(struct IDirectDrawSurface *pDDS)
-{
- return (binkw32_BinkDDSurfaceType)(pDDS);
-}
-
-int __stdcall BinkSetSoundSystem(void *pSoundSystem, HDIGDRIVER hDrv)
-{
- return (binkw32_BinkSetSoundSystem)(pSoundSystem, hDrv);
-}
-
-
-
-
-
-
-int __stdcall BinkGoto(_BINK *a1, long a2, long a3)
-{
- __asm int 3
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/Bink_Smacker.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-#pragma once
-#include "AIL.h"
-
-
-
-
-void BINKW32_DLL_Initialize();
-
-
-int __stdcall BinkDDSurfaceType(struct IDirectDrawSurface *);
-int __stdcall BinkSetSoundSystem(void *pSoundSystem, HDIGDRIVER hDrv);
-int __stdcall BinkOpenMiles(int);
-HBINK __stdcall BinkOpen(void *hFileHandle, unsigned int uFlags);
-int __stdcall BinkWait(HBINK);
-int __stdcall BinkDoFrame(HBINK);
-int __stdcall BinkNextFrame(HBINK);
-int __stdcall BinkGetRects(HBINK hBink, unsigned int uFlags);
-int __stdcall BinkCopyToBuffer(HBINK hBink, void *pBuffer, unsigned int lPitch, unsigned int uNumLines, unsigned int uX, unsigned int uY, unsigned int uFlags);
-int __stdcall BinkPause(HBINK, int bPause);
-int __stdcall BinkClose(HBINK);
-int __stdcall BinkGoto(HBINK, long a2, long a3);
-
-int __stdcall BinkBufferSetOffset(void *, int, int);
-int __stdcall BinkBufferSetScale(void *, unsigned int uWidth, unsigned int uHeight);
-
-  void SMACKW32_DLL_Initialize();
-
-struct _SMACK
-{
-  unsigned int Version;           // SMK2 only right now
-  unsigned int Width;             // Width (1 based, 640 for example)
-  unsigned int Height;            // Height (1 based, 480 for example)
-  unsigned int Frames;            // Number of frames (1 based, 100 = 100 frames)
-  unsigned int MSPerFrame;        // Frame Rate
-  unsigned int SmackerType;       // bit 0 set=ring frame
-  unsigned int LargestInTrack[7]; // Largest single size for each track
-  unsigned int tablesize;         // Size of the init tables
-  unsigned int codesize;          // Compression info   
-  unsigned int absize;            // ditto
-  unsigned int detailsize;        // ditto
-  unsigned int typesize;          // ditto
-  unsigned int TrackType[7];      // high byte=0x80-Comp,0x40-PCM data,0x20-16 bit,0x10-stereo
-  unsigned int extra;             // extra value (should be zero)
-  unsigned int NewPalette;        // set to one if the palette changed
-  unsigned char Palette[772];      // palette data
-  unsigned int PalType;           // type of palette
-  unsigned int FrameNum;          // 0374 Frame Number to be displayed
-  unsigned int FrameSize;         // The current frame's size in bytes
-  unsigned int SndSize;           // The current frame sound tracks' size in bytes
-  int LastRectx;                  // 0380 Rect set in from SmackToBufferRect (X coord)
-  int LastRecty;                  // Rect set in from SmackToBufferRect (Y coord)
-  int LastRectw;                  // Rect set in from SmackToBufferRect (Width)
-  int LastRecth;                  // 038C Rect set in from SmackToBufferRect (Height)
-  unsigned int OpenFlags;         // flags used on open
-  unsigned int LeftOfs;           // Left Offset used in SmackTo
-  unsigned int TopOfs;            // Top Offset used in SmackTo
-  unsigned int LargestFrameSize;  // Largest frame size
-  unsigned int Highest1SecRate;   // Highest 1 sec data rate
-  unsigned int Highest1SecFrame;  // Highest 1 sec data rate starting frame
-  unsigned int ReadError;         // Set to non-zero if a read error has ocurred
-  unsigned int addr32;            // translated address for 16 bit interface
-};
-
-
-
-struct _SMACKBLIT
-{
-  unsigned int    Flags;
-  unsigned char  *Palette;
-  unsigned int    PalType;
-  unsigned short *SmoothTable;
-  unsigned short *Conv8to16Table;
-  unsigned int    whichmode;
-  unsigned int    palindex;
-  unsigned int    t16index;
-  unsigned int    smoothindex;
-  unsigned int    smoothtype;
-  unsigned int    firstpalette;
-};
-
-struct _SMACKBUF
-{
-        unsigned int Reversed;             // 1 if the buffer is upside down
-        unsigned int SurfaceType;          // SMACKSURFACExxxx defines
-        unsigned int BlitType;             // SMACKxxxxBLIT defines
-        unsigned int FullScreen;           // 1 if full-screen
-        unsigned int Width;
-        unsigned int Height;
-        unsigned int Pitch;
-        unsigned int Zoomed;
-        unsigned int ZWidth;
-        unsigned int ZHeight;
-        unsigned int DispColors;           // colors on the screen
-        unsigned int MaxPalColors;         // total possible colors in palette (usually 256)
-        unsigned int PalColorsInUse;       // Used colors in palette (usually 236)
-        unsigned int StartPalColor;        // first usable color index (usually 10)
-        unsigned int EndPalColor;          // last usable color index (usually 246)
-        RGBQUAD Palette[256];
-        unsigned int PalType;
-        unsigned int forceredraw;  // force a complete redraw on next blit (for >8bit)
-        unsigned int didapalette;  // force an invalidate on the next palette change
-
-        void * Buffer;
-        void * DIBRestore;
-        unsigned int OurBitmap;
-        unsigned int OrigBitmap;
-        unsigned int OurPalette;
-        unsigned int WinGDC;
-        unsigned int FullFocused;
-        unsigned int ParentHwnd;
-        unsigned int OldParWndProc;
-        unsigned int OldDispWndProc;
-        unsigned int DispHwnd;
-        unsigned int WinGBufHandle;
-        void * lpDD;
-        void * lpDDSP;
-        unsigned int DDSurfaceType;
-        struct _SMACKBLIT DDblit;
-        int ddSoftwarecur;
-        int didaddblit;
-        int lastwasdd;
-        RECT ddscreen;
-        int manyblits;
-        int * blitrects;
-        int * rectsptr;
-        int maxrects;
-        int numrects;
-        HDC lastdc;
-};
-#define BINKFRAMERATE            0x00001000L // Override fr (call BinkFrameRate first)
-#define BINKPRELOADALL            0x00002000L // Preload the entire animation
-#define BINKSNDTRACK            0x00004000L // Set the track number to play
-#define BINKOLDFRAMEFORMAT        0x00008000L // using the old Bink frame format (internal use only)
-#define BINKRBINVERT            0x00010000L // use reversed R and B planes (internal use only)
-#define BINKGRAYSCALE            0x00020000L // Force Bink to use grayscale
-#define BINKNOMMX                0x00040000L // Don't use MMX
-#define BINKNOSKIP                0x00080000L // Don't skip frames if falling behind
-#define BINKALPHA                0x00100000L // Decompress alpha plane (if present)
-#define BINKNOFILLIOBUF            0x00200000L // Fill the IO buffer in SmackOpen
-#define BINKSIMULATE            0x00400000L // Simulate the speed (call BinkSim first)
-#define BINKFILEHANDLE            0x00800000L // Use when passing in a file handle
-#define BINKIOSIZE                0x01000000L // Set an io size (call BinkIOSize first)
-#define BINKIOPROCESSOR            0x02000000L // Set an io processor (call BinkIO first)
-#define BINKFROMMEMORY            0x04000000L // Use when passing in a pointer to the file
-#define BINKNOTHREADEDIO        0x08000000L // Don't use a background thread for IO
-
-#define BINKSURFACEFAST            0x00000000L
-#define BINKSURFACESLOW            0x08000000L
-#define BINKSURFACEDIRECT        0x04000000L
-
-#define BINKCOPYALL                0x80000000L // copy all pixels (not just changed)
-#define BINKCOPY2XH                0x10000000L // Force doubling height scaling
-#define BINKCOPY2XHI            0x20000000L // Force interleaving height scaling
-#define BINKCOPY2XW                0x30000000L // copy the width zoomed by two
-#define BINKCOPY2XWH            0x40000000L // copy the width and height zoomed by two
-#define BINKCOPY2XWHI            0x50000000L // copy the width and height zoomed by two
-#define BINKCOPY1XI                0x60000000L // copy the width and height zoomed by two
-#define BINKCOPYNOSCALING        0x70000000L // Force scaling off
-
-#define SMACKNEEDPAN    0x00020L // Will be setting the pan
-#define SMACKNEEDVOLUME 0x00040L // Will be setting the volume
-#define SMACKFRAMERATE  0x00080L // Override fr (call SmackFrameRate first)
-#define SMACKLOADEXTRA  0x00100L // Load the extra buffer during SmackOpen
-#define SMACKPRELOADALL 0x00200L // Preload the entire animation
-#define SMACKNOSKIP     0x00400L // Don't skip frames if falling behind
-#define SMACKSIMULATE   0x00800L // Simulate the speed (call SmackSim first)
-#define SMACKFILEHANDLE 0x01000L // Use when passing in a file handle
-#define SMACKTRACK1     0x02000L // Play audio track 1
-#define SMACKTRACK2     0x04000L // Play audio track 2
-#define SMACKTRACK3     0x08000L // Play audio track 3
-#define SMACKTRACK4     0x10000L // Play audio track 4
-#define SMACKTRACK5     0x20000L // Play audio track 5
-#define SMACKTRACK6     0x40000L // Play audio track 6
-#define SMACKTRACK7     0x80000L // Play audio track 7
-
-
-#define SMACKBUFFER555      0x80000000
-#define SMACKBUFFER565      0xC0000000
-
-#define SMACKBLIT1X                1
-#define SMACKBLIT2X                2
-#define SMACKBLIT2XSMOOTHING       4
-#define SMACKBLIT2XINTERLACE       8
-
-
-int __stdcall SmackSoundUseMSS(HDIGDRIVER hDrv);
-unsigned int __stdcall SmackUseMMX(unsigned int flag);
-HSMACK __stdcall SmackOpen(HANDLE hSourceFile, unsigned int uFlags, unsigned int uExtraBuffers);
-HSMACKBLIT __stdcall SmackBlitOpen(unsigned int uSurfaceFormat);
-void __stdcall SmackToBuffer(HSMACK, unsigned int uX, unsigned int uY, unsigned int uPitch, unsigned int uHeight, void *pBuffer, unsigned int uFlags);
-void __stdcall SmackBlitSetPalette(HSMACKBLIT hBlit, void *pPalette, unsigned int uPalType);
-unsigned int __stdcall SmackDoFrame(HSMACK);
-unsigned int __stdcall SmackToBufferRect(HSMACK, unsigned int uSmackSurface);
-void __stdcall SmackBlit(HSMACKBLIT, void *pDest, unsigned int uDestPitch, unsigned int uDestX, unsigned int uDestY, void *pSrc, unsigned int uSrcPitch, unsigned int uSrcX, unsigned int uSrcY, unsigned int uSrcZ, unsigned int uSrcW);
-void __stdcall SmackNextFrame(HSMACK);
-unsigned int __stdcall SmackWait(HSMACK);
-unsigned int __stdcall SmackSoundOnOff(HSMACK, unsigned int bOn);
-void __stdcall SmackClose(HSMACK);
-void __stdcall SmackBufferClose(HSMACKBUF);
-void __stdcall SmackBlitClose(HSMACKBLIT);
-int __stdcall SmackBlitClear(HSMACKBLIT a1, unsigned short *pFrameData, unsigned int uTargetSurfacePitch, unsigned int uOutX, unsigned int uOutY, unsigned int uOutZ, unsigned int uOutW, int a8);
-
-
-
-
-
-int __stdcall SmackBufferOpen(HWND a1, long a2, long a3, long a4, long a5, long a6);
-int __fastcall SmackVolumePan(_SMACK *a3, long a4, long a5, long a6);
-
-int __stdcall SmackGoto(_SMACK *a1, long a2);
-
-// sub_4D83D0: using guessed type int __stdcall SmackBufferNewPalette(_DWORD, _DWORD, _DWORD);
-void __stdcall SmackBufferNewPalette(HSMACKBUF a1, void *a2, unsigned int a3);
-
-// sub_4D83D4: using guessed type int __stdcall SmackColorRemapWithTrans(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD);
-void __stdcall SmackColorRemapWithTrans(_SMACK *a1, void *a2, unsigned int a3, unsigned int a4, unsigned int a5);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Fri Sep 19 04:21:12 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj	Fri Sep 19 05:13:32 2014 +0600
@@ -90,11 +90,8 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <ClCompile Include="..\..\AIL.cpp" />
     <ClCompile Include="..\..\Arcomage\Arcomage.cpp" />
     <ClCompile Include="..\..\Arcomage\ArcomageCards.cpp" />
-    <ClCompile Include="..\..\AudioPlayer.cpp" />
-    <ClCompile Include="..\..\Bink_Smacker.cpp" />
     <ClCompile Include="..\..\Engine\Conditions.cpp" />
     <ClCompile Include="..\..\Engine\Events.cpp" />
     <ClCompile Include="..\..\Engine\Game.cpp" />
@@ -155,10 +152,10 @@
     <ClCompile Include="..\..\Engine\TurnEngine\TurnEngine.cpp" />
     <ClCompile Include="..\..\Engine\VectorTypes.cpp" />
     <ClCompile Include="..\..\Engine\ZlibWrapper.cpp" />
-    <ClCompile Include="..\..\GUIButton.cpp" />
-    <ClCompile Include="..\..\GUIFont.cpp" />
-    <ClCompile Include="..\..\GUIProgressBar.cpp" />
-    <ClCompile Include="..\..\GUIWindow.cpp" />
+    <ClCompile Include="..\..\GUI\GUIButton.cpp" />
+    <ClCompile Include="..\..\GUI\GUIFont.cpp" />
+    <ClCompile Include="..\..\GUI\GUIProgressBar.cpp" />
+    <ClCompile Include="..\..\GUI\GUIWindow.cpp" />
     <ClCompile Include="..\..\GUI\NewUI\Core\UIControlModule_wrap.cxx" />
     <ClCompile Include="..\..\GUI\NewUI\MainMenu.cpp" />
     <ClCompile Include="..\..\GUI\UI\Books\UIMapBook.cpp" />
@@ -179,7 +176,8 @@
     <ClCompile Include="..\..\GUI\UI\UISaveLoad.cpp" />
     <ClCompile Include="..\..\GUI\UI\UIShops.cpp" />
     <ClCompile Include="..\..\GUI\UI\UITransition.cpp" />
-    <ClCompile Include="..\..\Keyboard.cpp" />
+    <ClCompile Include="..\..\IO\Keyboard.cpp" />
+    <ClCompile Include="..\..\IO\Mouse.cpp" />
     <ClCompile Include="..\..\lib\libpng\png.c" />
     <ClCompile Include="..\..\lib\libpng\pngerror.c" />
     <ClCompile Include="..\..\lib\libpng\pngget.c" />
@@ -241,18 +239,17 @@
     <ClCompile Include="..\..\lib\zlib\trees.c" />
     <ClCompile Include="..\..\lib\zlib\uncompr.c" />
     <ClCompile Include="..\..\lib\zlib\zutil.c" />
-    <ClCompile Include="..\..\MediaPlayer.cpp" />
-    <ClCompile Include="..\..\Mouse.cpp" />
+    <ClCompile Include="..\..\Media\Audio\AIL.cpp" />
+    <ClCompile Include="..\..\Media\Audio\AudioPlayer.cpp" />
+    <ClCompile Include="..\..\Media\MediaPlayer.cpp" />
+    <ClCompile Include="..\..\Media\Video\Bink_Smacker.cpp" />
     <ClCompile Include="..\..\OSAPI.cpp" />
     <ClCompile Include="..\..\OSWindow.cpp" />
     <ClCompile Include="..\..\stru6.cpp" />
     <ClCompile Include="..\..\_deleted.cpp" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\AIL.h" />
     <ClInclude Include="..\..\Arcomage\Arcomage.h" />
-    <ClInclude Include="..\..\AudioPlayer.h" />
-    <ClInclude Include="..\..\Bink_Smacker.h" />
     <ClInclude Include="..\..\Engine\Autonotes.h" />
     <ClInclude Include="..\..\Engine\Awards.h" />
     <ClInclude Include="..\..\Engine\Conditions.h" />
@@ -327,10 +324,10 @@
     <ClInclude Include="..\..\Engine\TurnEngine\TurnEngine.h" />
     <ClInclude Include="..\..\Engine\VectorTypes.h" />
     <ClInclude Include="..\..\Engine\ZlibWrapper.h" />
-    <ClInclude Include="..\..\GUIButton.h" />
-    <ClInclude Include="..\..\GUIFont.h" />
-    <ClInclude Include="..\..\GUIProgressBar.h" />
-    <ClInclude Include="..\..\GUIWindow.h" />
+    <ClInclude Include="..\..\GUI\GUIButton.h" />
+    <ClInclude Include="..\..\GUI\GUIFont.h" />
+    <ClInclude Include="..\..\GUI\GUIProgressBar.h" />
+    <ClInclude Include="..\..\GUI\GUIWindow.h" />
     <ClInclude Include="..\..\GUI\NewUI\Core\UIControl.h" />
     <ClInclude Include="..\..\GUI\NewUI\MainMenu.h" />
     <ClInclude Include="..\..\GUI\UI\Books\UIMapBook.h" />
@@ -351,7 +348,8 @@
     <ClInclude Include="..\..\GUI\UI\UISaveLoad.h" />
     <ClInclude Include="..\..\GUI\UI\UIShops.h" />
     <ClInclude Include="..\..\GUI\UI\UITransition.h" />
-    <ClInclude Include="..\..\Keyboard.h" />
+    <ClInclude Include="..\..\IO\Keyboard.h" />
+    <ClInclude Include="..\..\IO\Mouse.h" />
     <ClInclude Include="..\..\lib\legacy_dx\d3d.h" />
     <ClInclude Include="..\..\lib\legacy_dx\d3dcaps.h" />
     <ClInclude Include="..\..\lib\legacy_dx\d3drm.h" />
@@ -493,9 +491,11 @@
     <ClInclude Include="..\..\lib\zlib\zconf.h" />
     <ClInclude Include="..\..\lib\zlib\zlib.h" />
     <ClInclude Include="..\..\lib\zlib\zutil.h" />
-    <ClInclude Include="..\..\MediaPlayer.h" />
-    <ClInclude Include="..\..\Mouse.h" />
-    <ClInclude Include="..\..\OpenALSoundProvider.h" />
+    <ClInclude Include="..\..\Media\Audio\AIL.h" />
+    <ClInclude Include="..\..\Media\Audio\AudioPlayer.h" />
+    <ClInclude Include="..\..\Media\Audio\OpenALSoundProvider.h" />
+    <ClInclude Include="..\..\Media\MediaPlayer.h" />
+    <ClInclude Include="..\..\Media\Video\Bink_Smacker.h" />
     <ClInclude Include="..\..\OSAPI.h" />
     <ClInclude Include="..\..\OSInfo.h" />
     <ClInclude Include="..\..\OSWindow.h" />
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Fri Sep 19 04:21:12 2014 +0600
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.filters	Fri Sep 19 05:13:32 2014 +0600
@@ -103,6 +103,9 @@
     <Filter Include="GUI\NewUI\Core">
       <UniqueIdentifier>{80539c98-aa5a-44ca-ad0e-68f50d81de6c}</UniqueIdentifier>
     </Filter>
+    <Filter Include="lib\legacy_dx\lib">
+      <UniqueIdentifier>{20adc48e-74d5-48a4-a357-a8b133eef51f}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\lib\zlib\adler32.c">
@@ -291,36 +294,6 @@
     <ClCompile Include="..\..\_deleted.cpp" />
     <ClCompile Include="..\..\OSAPI.cpp" />
     <ClCompile Include="..\..\OSWindow.cpp" />
-    <ClCompile Include="..\..\Keyboard.cpp">
-      <Filter>IO</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Mouse.cpp">
-      <Filter>IO</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\AIL.cpp">
-      <Filter>Media\Audio</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\AudioPlayer.cpp">
-      <Filter>Media\Audio</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\Bink_Smacker.cpp">
-      <Filter>Media\Video</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\MediaPlayer.cpp">
-      <Filter>Media</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\GUIButton.cpp">
-      <Filter>GUI</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\GUIFont.cpp">
-      <Filter>GUI</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\GUIProgressBar.cpp">
-      <Filter>GUI</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\GUIWindow.cpp">
-      <Filter>GUI</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Arcomage\Arcomage.cpp">
       <Filter>Arcomage</Filter>
     </ClCompile>
@@ -568,6 +541,36 @@
     <ClCompile Include="..\..\GUI\UI\UiGame.cpp">
       <Filter>GUI\UI</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\GUI\GUIProgressBar.cpp">
+      <Filter>GUI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\GUI\GUIWindow.cpp">
+      <Filter>GUI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\GUI\GUIButton.cpp">
+      <Filter>GUI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\GUI\GUIFont.cpp">
+      <Filter>GUI</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\IO\Mouse.cpp">
+      <Filter>IO</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\IO\Keyboard.cpp">
+      <Filter>IO</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Media\Audio\AIL.cpp">
+      <Filter>Media\Audio</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Media\Audio\AudioPlayer.cpp">
+      <Filter>Media\Audio</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Media\Video\Bink_Smacker.cpp">
+      <Filter>Media\Video</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Media\MediaPlayer.cpp">
+      <Filter>Media</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\lib\libavcodec\avcodec.h">
@@ -996,39 +999,6 @@
     <ClInclude Include="..\..\OSAPI.h" />
     <ClInclude Include="..\..\OSInfo.h" />
     <ClInclude Include="..\..\OSWindow.h" />
-    <ClInclude Include="..\..\Keyboard.h">
-      <Filter>IO</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Mouse.h">
-      <Filter>IO</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\AIL.h">
-      <Filter>Media\Audio</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\AudioPlayer.h">
-      <Filter>Media\Audio</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\OpenALSoundProvider.h">
-      <Filter>Media\Audio</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\Bink_Smacker.h">
-      <Filter>Media\Video</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\MediaPlayer.h">
-      <Filter>Media</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\GUIButton.h">
-      <Filter>GUI</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\GUIFont.h">
-      <Filter>GUI</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\GUIProgressBar.h">
-      <Filter>GUI</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\GUIWindow.h">
-      <Filter>GUI</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Arcomage\Arcomage.h">
       <Filter>Arcomage</Filter>
     </ClInclude>
@@ -1315,6 +1285,39 @@
     <ClInclude Include="..\..\GUI\UI\UICharacter.h">
       <Filter>GUI\UI</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\GUI\GUIFont.h">
+      <Filter>GUI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\GUI\GUIProgressBar.h">
+      <Filter>GUI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\GUI\GUIWindow.h">
+      <Filter>GUI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\GUI\GUIButton.h">
+      <Filter>GUI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\IO\Keyboard.h">
+      <Filter>IO</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\IO\Mouse.h">
+      <Filter>IO</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Media\Audio\AudioPlayer.h">
+      <Filter>Media\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Media\Audio\OpenALSoundProvider.h">
+      <Filter>Media\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Media\Audio\AIL.h">
+      <Filter>Media\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Media\Video\Bink_Smacker.h">
+      <Filter>Media\Video</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Media\MediaPlayer.h">
+      <Filter>Media</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\lib\OpenAL\lib\x86\avcodec-55.def">
@@ -1382,10 +1385,20 @@
     <Library Include="..\..\lib\OpenAL\lib\x86\swscale.lib">
       <Filter>lib\OpenAL\lib\x86</Filter>
     </Library>
-    <Library Include="..\..\lib\legacy_dx\lib\d3dxof.lib" />
-    <Library Include="..\..\lib\legacy_dx\lib\ddraw.lib" />
-    <Library Include="..\..\lib\legacy_dx\lib\dinput.lib" />
-    <Library Include="..\..\lib\legacy_dx\lib\dinput8.lib" />
-    <Library Include="..\..\lib\legacy_dx\lib\dxguid.lib" />
+    <Library Include="..\..\lib\legacy_dx\lib\d3dxof.lib">
+      <Filter>lib\legacy_dx\lib</Filter>
+    </Library>
+    <Library Include="..\..\lib\legacy_dx\lib\ddraw.lib">
+      <Filter>lib\legacy_dx\lib</Filter>
+    </Library>
+    <Library Include="..\..\lib\legacy_dx\lib\dinput.lib">
+      <Filter>lib\legacy_dx\lib</Filter>
+    </Library>
+    <Library Include="..\..\lib\legacy_dx\lib\dinput8.lib">
+      <Filter>lib\legacy_dx\lib</Filter>
+    </Library>
+    <Library Include="..\..\lib\legacy_dx\lib\dxguid.lib">
+      <Filter>lib\legacy_dx\lib</Filter>
+    </Library>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- a/DirectX11.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#define WIN32_LEAN_AND_MEAN
-
-#include "DirectX11.h"
-#include "RenderStruct.h"
-
-HRESULT D3D11::InitDevice()
-{
-  HRESULT hr = S_OK;
-  RECT rc;
-  GetClientRect( g_hWnd, &rc );
-  UINT width = rc.right - rc.left;           // ïîëó÷àåì øèðèíó
-  UINT height = rc.bottom - rc.top;          // è âûñîòó îêíà
-  UINT createDeviceFlags = 0;
-  D3D_DRIVER_TYPE driverTypes[] =
-  {
-    D3D_DRIVER_TYPE_HARDWARE,
-    D3D_DRIVER_TYPE_WARP,
-    D3D_DRIVER_TYPE_REFERENCE,
-  };
-  UINT numDriverTypes = ARRAYSIZE( driverTypes );
-
- // Òóò ìû ñîçäàåì ñïèñîê ïîääåðæèâàåìûõ âåðñèé DirectX
-  D3D_FEATURE_LEVEL featureLevels[] =
-  {
-    D3D_FEATURE_LEVEL_11_0,
-    D3D_FEATURE_LEVEL_10_1,
-    D3D_FEATURE_LEVEL_10_0,
-  };
-  UINT numFeatureLevels = ARRAYSIZE( featureLevels );
-
-  // Ñåé÷àñ ìû ñîçäàäèì óñòðîéñòâà DirectX. Äëÿ íà÷àëà çàïîëíèì ñòðóêòóðó,
-  // êîòîðàÿ îïèñûâàåò ñâîéñòâà ïåðåäíåãî áóôåðà è ïðèâÿçûâàåò åãî ê íàøåìó îêíó.
-  DXGI_SWAP_CHAIN_DESC sd;            // Ñòðóêòóðà, îïèñûâàþùàÿ öåïü ñâÿçè (Swap Chain)
-  ZeroMemory( &sd, sizeof( sd ) );    // î÷èùàåì åå
-  sd.BufferCount = 1;                               // ó íàñ îäèí çàäíèé áóôåð
-  sd.BufferDesc.Width = width;                     // øèðèíà áóôåðà
-  sd.BufferDesc.Height = height;                          // âûñîòà áóôåðà
-  sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;      // ôîðìàò ïèêñåëÿ â áóôåðå
-  sd.BufferDesc.RefreshRate.Numerator = 75;         // ÷àñòîòà îáíîâëåíèÿ ýêðàíà
-  sd.BufferDesc.RefreshRate.Denominator = 1;
-  sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // íàçíà÷åíèå áóôåðà - çàäíèé áóôåð
-  sd.OutputWindow = g_hWnd;                               // ïðèâÿçûâàåì ê íàøåìó îêíó
-  sd.SampleDesc.Count = 1;
-  sd.SampleDesc.Quality = 0;
-  sd.Windowed = TRUE;                               // íå ïîëíîýêðàííûé ðåæèì
-
-  for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
-  {
-    g_driverType = driverTypes[driverTypeIndex];
-    hr = D3D11CreateDeviceAndSwapChain ( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
-    if (SUCCEEDED(hr)) // Åñëè óñòðîéñòâà ñîçäàíû óñïåøíî, òî âûõîäèì èç öèêëà
-      break;
-  }
-  if (FAILED(hr)) return hr;
-
-  // Òåïåðü ñîçäàåì çàäíèé áóôåð. Îáðàòèòå âíèìàíèå, â SDK
-  // RenderTargetOutput - ýòî ïåðåäíèé áóôåð, à RenderTargetView - çàäíèé.
-  pBackBuffer = NULL;
-  hr = g_pSwapChain->GetBuffer( 0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer );
-  if (FAILED(hr)) return hr;
-
-  // èíòåðôåéñ g_pd3dDevice áóäåò èñïîëüçîâàòüñÿ äëÿ ñîçäàíèÿ îñòàëüíûõ îáúåêòîâ
-  hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
-  pBackBuffer->Release();
-  if (FAILED(hr)) return hr;
-
-  // Ïîäêëþ÷àåì îáúåêò çàäíåãî áóôåðà ê êîíòåêñòó óñòðîéñòâà
-  g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
-
-  // Íàñòðîéêà âüþïîðòà
-  D3D11_VIEWPORT vp;
-  vp.Width = (FLOAT)width;
-  vp.Height = (FLOAT)height;
-  vp.MinDepth = 0.0f;
-  vp.MaxDepth = 1.0f;
-  vp.TopLeftX = 0;
-  vp.TopLeftY = 0;
-
-  // Ïîäêëþ÷àåì âüþïîðò ê êîíòåêñòó óñòðîéñòâà
-  g_pImmediateContext->RSSetViewports (1, &vp);
-
-  return S_OK;
-}
-
-//--------------------------------------------------------------------------------------
-// Óäàëèòü âñå ñîçäàííûå îáúåêòû
-//--------------------------------------------------------------------------------------
-void D3D11::CleanupDevice()
-{
-  // Ñíà÷àëà îòêëþ÷èì êîíòåêñò óñòðîéñòâà, ïîòîì îòïóñòèì îáúåêòû.
-  if( g_pImmediateContext ) g_pImmediateContext->ClearState();
-
-  //  óäàëåÿì îáúåêòû â ïîðÿäêå, îáðàòíîì òîìó, â êîòîðîì ñîçäàâàëè.
-  if( g_pRenderTargetView ) g_pRenderTargetView->Release();
-
-  if( g_pSwapChain ) g_pSwapChain->Release();
-
-  if( g_pImmediateContext ) g_pImmediateContext->Release();
-
-  if( g_pd3dDevice ) g_pd3dDevice->Release();
-}
-
-void Render()
-{
-
-}*/
\ No newline at end of file
--- a/DirectX11.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-/*#pragma once
-#define WIN32_LEAN_AND_MEAN
-
-#include "OSWindow.h"
-#include <cstdint>
-#include <cstdio>
-
-//#include "lib\legacy_dx\d3d.h"
-
-#include "VectorTypes.h"
-
-#include <d3d11.h>
-#include "RenderStruct.h"
-#pragma comment(lib, "d3d11.lib")
-
-class D3D11
-{
-  HINSTANCE               g_hInst;
-  HWND                    g_hWnd;
-  D3D_DRIVER_TYPE         g_driverType;       //Ýòîò ïàðàìåòð óêàçûâàåò, ïðîèçâîäèòü âû÷èñëåíèÿ â âèäåîêàðòå èëè â öåíòðàëüíîì ïðîöåññîðå. 
-  D3D_FEATURE_LEVEL       g_featureLevel;     //ïàðàìåòð, óêàçûâàþùèé, êàêóþ âåðñèþ DirectX ïîääåðæèâàåò íàøà âèäåîêàðòà.
-  ID3D11Device*           g_pd3dDevice;       //óñòðîéñòâî d3d11
-  ID3D11DeviceContext*    g_pImmediateContext;// êîíòåêñò óñòðîéñòâà
-  IDXGISwapChain*         g_pSwapChain;       // öåïî÷êà îáìåíà
-  ID3D11RenderTargetView* g_pRenderTargetView;
-
-
-public:
-
-  int *pActiveZBuffer;
-  //IDirectDraw4 *pDirectDraw4;
-  //IDirectDrawSurface4 *pFrontBuffer4;
-  //IDirectDrawSurface4 *pBackBuffer4;
-  ID3D11Texture2D* pBackBuffer;
-  void        *pTargetSurface;
-  unsigned int uTargetSurfacePitch;
-  unsigned int bUseColoredLights;
-  unsigned int bTinting;
-  unsigned int bUsingSpecular;
-  uint32_t uFogColor;
-  unsigned int pHDWaterBitmapIDs[7];
-  int hd_water_current_frame;
-  int hd_water_tile_id;
-  void (*pBeforePresentFunction)();
-  uint32_t bFogEnabled;
-  RenderBillboardD3D pBillboardRenderListD3D[1000];
-  unsigned int uNumBillboardsToDraw;
-
-  D3D11():
-  g_hInst(NULL), g_hWnd(NULL), g_driverType(D3D_DRIVER_TYPE_NULL), g_featureLevel(D3D_FEATURE_LEVEL_11_0),
-  g_pd3dDevice(NULL), g_pImmediateContext(NULL), g_pSwapChain(NULL), g_pRenderTargetView(NULL){}
-
-  HRESULT InitDevice();      // Èíèöèàëèçàöèÿ óñòðîéñòâ DirectX
-  void CleanupDevice();      // Óäàëåíèå ñîçäàíííûõ óñòðîéñòâ DirectX
-  //void Render();             // Ôóíêöèÿ ðèñîâàíèÿ
-
-  bool Initialize(OSWindow *window, bool bColoredLights, uint32_t uDetailLevel, bool bTinting);
-
-
-  void ClearBlack();
-  void PresentBlackScreen();
-
-  void SaveWinnersCertificate(const char *a1);
-  void ClearTarget(unsigned int uColor);
-  void Present();
-
-  void _49FD3A_fullscreen();
-  bool InitializeFullscreen();
-
-  void CreateZBuffer();
-  void Release();
-
-  bool SwitchToWindow();
-  void RasterLine2D(signed int uX, signed int uY, signed int uZ, signed int uW, unsigned __int16 uColor);
-  void ClearZBuffer(int a2, int a3);
-  void SetRasterClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW);
-  bool LockSurface_DDraw4(IDirectDrawSurface4 *pSurface, DDSURFACEDESC2 *pDesc, unsigned int uLockFlags);
-  void GetTargetPixelFormat(DDPIXELFORMAT *pOut);
-  void LockRenderSurface(void **pOutSurfacePtr, unsigned int *pOutPixelsPerRow);
-
-  void UnlockBackBuffer();
-  void RestoreBackBuffer();
-
-  void LockFrontBuffer(void **pOutSurface, unsigned int *pOutPixelsPerRow);
-  void UnlockFrontBuffer();
-  void RestoreFrontBuffer();
-
-  void BltToFront(RECT *pDstRect, IDirectDrawSurface *pSrcSurface, RECT *pSrcRect, unsigned int uBltFlags);
-  void BltBackToFontFast(int a2, int a3, RECT *a4);
-  void BeginSceneD3D();
-
-  unsigned int GetActorTintColor(float a2, int tint, int a4, int a5, RenderBillboard *a6);
-
-  void DrawPolygon(unsigned int uNumVertices, struct Polygon *a3, ODMFace *a4, IDirect3DTexture2 *pTexture);
-  void DrawTerrainPolygon(unsigned int uNumVertices, struct Polygon *a4, IDirect3DTexture2 *a5, bool transparent, bool clampAtTextureBorders);
-  void DrawIndoorPolygon(unsigned int uNumVertices, struct BLVFace *a3, IDirect3DTexture2 *pHwTex, struct Texture *pTex, int uPackedID, unsigned int uColor, int a8);
-
-  void MakeParticleBillboardAndPush_BLV(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle);
-  void MakeParticleBillboardAndPush_ODM(RenderBillboardTransform_local0 *a2, IDirect3DTexture2 *a3, unsigned int uDiffuse, int angle);
-
-  void DrawBillboards_And_MaybeRenderSpecialEffects_And_EndScene();
-  void DrawBillboard_Indoor(RenderBillboardTransform_local0 *pSoftBillboard, Sprite *pSprite, int dimming_level);
-  void _4A4CC9_AddSomeBillboard(struct stru6_stru1_indoor_sw_billboard *a1, int diffuse);
-  void TransformBillboardsAndSetPalettesODM();
-  void DrawBillboardList_BLV();
-
-  void DrawProjectile(float srcX, float srcY, float a3, float a4, float dstX, float dstY, float a7, float a8, IDirect3DTexture2 *a9);
-  bool LoadTexture(const char *pName, unsigned int bMipMaps, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture);
-  bool MoveSpriteToDevice(Sprite *pSprite);
-
-  void BeginScene();
-  void EndScene();
-  void ScreenFade(unsigned int color, float t);
-
-  void SetTextureClipRect(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW);
-  void ResetTextureClipRect();
-  void DrawTextureRGB(unsigned int uOutX, unsigned int uOutY, RGBTexture *a4);
-  void CreditsTextureScroll(unsigned int pX, unsigned int pY, int move_X, int move_Y, RGBTexture *pTexture);
-  void DrawTextureIndexed(unsigned int uX, unsigned int uY, struct Texture *a4);
-
-  void ZBuffer_Fill_2(signed int a2, signed int a3, struct Texture *pTexture, int a5);
-  void DrawMaskToZBuffer(signed int uOutX, unsigned int uOutY, struct Texture *pTexture, int zVal);
-  void DrawTextureTransparent(unsigned int uX, unsigned int uY, struct Texture *pTexture);
-  void DrawAura(unsigned int a2, unsigned int a3, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8);
-  void _4A65CC(unsigned int x, unsigned int y, struct Texture *a4, struct Texture *a5, int a6, int a7, int a8);
-
-  void DrawTransparentRedShade(unsigned int a2, unsigned int a3, struct Texture *a4);
-  void DrawTransparentGreenShade(signed int a2, signed int a3, struct Texture *pTexture);
-  void DrawFansTransparent(const RenderVertexD3D3 *vertices, unsigned int num_vertices);
-
-  void DrawMasked(signed int a2, signed int a3, struct Texture *pTexture, unsigned __int16 mask);
-  void GetLeather(unsigned int a2, unsigned int a3, struct Texture *a4, __int16 height);
-
-  void DrawTextPalette(int x, int y, unsigned char* font_pixels, int a5, unsigned int uFontHeight, unsigned __int16 *pPalette, int a8);
-  void DrawText(signed int uOutX, signed int uOutY, unsigned __int8 *pFontPixels, unsigned int uCharWidth, unsigned int uCharHeight, unsigned __int16 *pFontPalette, unsigned __int16 uFaceColor, unsigned __int16 uShadowColor);
-
-  void FillRectFast(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight, unsigned int uColor16);
-  void _4A6DF5(unsigned __int16 *pBitmap, unsigned int uBitmapPitch, struct Vec2_int_ *pBitmapXY, void *pTarget, unsigned int uTargetPitch, Vec4_int_ *a7);
-  void DrawTranslucent(unsigned int a2, unsigned int a3, struct Texture *a4);
-
-  void DrawBuildingsD3D();
-  //struct BSPModel *DrawBuildingsSW();
-  //int OnOutdoorRedrawSW();
-
-  void DrawIndoorSky(unsigned int uNumVertices, unsigned int uFaceID);
-  void DrawOutdoorSkyD3D();
-  //int DrawSkySW(struct Span *a1, Polygon *a2, int a3);
-  void DrawOutdoorSkyPolygon(unsigned int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture);
-  void DrawIndoorSkyPolygon(signed int uNumVertices, struct Polygon *pSkyPolygon, IDirect3DTexture2 *pTexture);
-
-  void PrepareDecorationsRenderList_ODM();
-  void DrawSpriteObjects_ODM();
-
-  //float DrawBezierTerrain();
-  void RenderTerrainD3D();
-  void DrawTerrainD3D(int a1, int edx0, int a3, int unk4);
-  //void DrawTerrainSW(int a1, int a2, int a3, int a4);
-
-  //void ExecOutdoorDrawSW();
-  void ChangeBetweenWinFullscreenModes();
-  bool AreRenderSurfacesOk();
-  bool IsGammaSupported();
-
-  void SaveScreenshot(const char *pFilename, unsigned int width, unsigned int height);
-  void PackScreenshot(unsigned int width, unsigned int height, void *out_data, unsigned int data_size, unsigned int *screenshot_size);
-  void SavePCXScreenshot();
-
-  int _46À6ÀÑ_GetActorsInViewport(int pDepth);
-
-  void BeginLightmaps();
-  void EndLightmaps();  
-  void BeginLightmaps2();
-  void EndLightmaps2();
-  bool DrawLightmap(struct Lightmap *pLightmap, struct Vec3_float_ *pColorMult, float z_bias);
-
-  void BeginDecals();
-  void EndDecals();
-  void DrawDecal(struct Decal *pDecal, float z_bias);
-  
-  void do_draw_debug_line_d3d(const RenderVertexD3D3 *pLineBegin, signed int sDiffuseBegin, const RenderVertexD3D3 *pLineEnd, signed int sDiffuseEnd, float z_stuff);
-  void DrawLines(const RenderVertexD3D3 *vertices, unsigned int num_vertices);
-
-  void DrawSpecialEffectsQuad(const RenderVertexD3D3 *vertices, IDirect3DTexture2 *texture);
-
-  void am_Blt_Copy(RECT *pSrcRect, POINT *pTargetXY, int a3);
-  void am_Blt_Chroma(RECT *pSrcRect, POINT *pTargetPoint, int a3, int blend_mode);
-
-  inline void ToggleTint()          {bTinting = !bTinting;}
-  inline void ToggleColoredLights() {bUseColoredLights = !bUseColoredLights;}
-
-  inline unsigned int GetRenderWidth() {return window->GetWidth();}
-  inline unsigned int GetRenderHeight() {return window->GetHeight();}
-
-
-  friend void Present_NoColorKey();
-
-};
-*/
\ No newline at end of file
--- a/Engine/Events.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Events.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -9,14 +9,14 @@
 #include "Graphics/Weather.h"
 #include "Graphics/Texture.h"
 #include "mm7_data.h"
-#include "MediaPlayer.h"
-#include "Mouse.h"
+#include "Media/MediaPlayer.h"
+#include "IO/Mouse.h"
 
 #include "MapInfo.h"
 #include "Game.h"
 #include "Graphics/Render.h"
-#include "GUIWindow.h"
-#include "GUIProgressBar.h"
+#include "GUI/GUIWindow.h"
+#include "GUI/GUIProgressBar.h"
 #include "Objects/SpriteObject.h"
 #include "Objects/Chest.h"
 #include "MapsLongTimer.h"
@@ -24,7 +24,7 @@
 #include "Objects/Actor.h"
 #include "Party.h"
 #include "OurMath.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Graphics/Indoor.h"
 #include "Graphics/Viewport.h"
 #include "texts.h"
--- a/Engine/Game.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Game.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -10,8 +10,8 @@
 #include "Engine/Graphics/LightmapBuilder.h"
 #include "Engine/Graphics/DecalBuilder.h"
 #include "Engine/Graphics/ParticleEngine.h"
-#include "Mouse.h"
-#include "Keyboard.h"
+#include "IO/Mouse.h"
+#include "IO/Keyboard.h"
 #include "Engine/Graphics/GammaControl.h"
 #include "stru6.h"
 #include "Engine/Graphics/stru9.h"
@@ -24,20 +24,20 @@
 #include "Timer.h"
 #include "Engine/Graphics/Outdoor.h"
 #include "Engine/Graphics/Overlays.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "LOD.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "TurnEngine/TurnEngine.h"
-#include "Bink_Smacker.h"
+#include "Media/Video/Bink_Smacker.h"
 #include "Events.h"
 #include "texts.h"
-#include "GUIFont.h"
+#include "GUI/GUIFont.h"
 #include "Log.h"
 #include "Graphics/Lights.h"
 #include "Spells/CastSpellInfo.h"
 #include "Tables/FrameTableInc.h"
 #include "Objects/Actor.h"
-#include "GUIProgressBar.h"
+#include "GUI/GUIProgressBar.h"
 #include "Objects/ObjectList.h"
 #include "Graphics/Level/Decoration.h"
 #include "Graphics/PaletteManager.h"
--- a/Engine/Graphics/Indoor.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Graphics/Indoor.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -25,9 +25,9 @@
 #include "../Objects/ObjectList.h"
 #include "../Objects/Actor.h"
 #include "../Objects/Chest.h"
-#include "GUIProgressBar.h"
+#include "GUI/GUIProgressBar.h"
 #include "../stru123.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Log.h"
 #include "../TurnEngine/TurnEngine.h"
 #include "PaletteManager.h"
@@ -38,7 +38,7 @@
 #include "stru6.h"
 #include "ParticleEngine.h"
 #include "../texts.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "Level/Decoration.h"
 #include "Overlays.h"
 
--- a/Engine/Graphics/Outdoor.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Graphics/Outdoor.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -14,8 +14,8 @@
 #include "../Objects/SpriteObject.h"
 #include "../LOD.h"
 #include "PaletteManager.h"
-#include "GUIProgressBar.h"
-#include "AudioPlayer.h"
+#include "GUI/GUIProgressBar.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "DecorationList.h"
 #include "../OurMath.h"
 #include "../Objects/ObjectList.h"
@@ -32,7 +32,7 @@
 #include "../MM7.h"
 #include "Lights.h"
 
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "Level/Decoration.h"
 #include "../ZlibWrapper.h"
 #include "../MMT.h"
--- a/Engine/Graphics/Overlays.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Graphics/Overlays.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -16,7 +16,7 @@
 #include "../TurnEngine/TurnEngine.h"
 #include "../LOD.h"
 #include "Render.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 
 #include "../mm7_data.h"
 
--- a/Engine/Graphics/Render.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Graphics/Render.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,12 +8,12 @@
 #include "../ErrorHandling.h"
 
 #include "Render.h"
-#include "MediaPlayer.h"
+#include "Media/MediaPlayer.h"
 #include "Sprites.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "GammaControl.h"
 #include "stru6.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "DecalBuilder.h"
 #include "ParticleEngine.h"
 #include "Outdoor.h"
--- a/Engine/Graphics/Viewport.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Graphics/Viewport.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -11,7 +11,7 @@
 #include "../Objects/Actor.h"
 #include "Outdoor.h"
 #include "../Events.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "../Objects/SpriteObject.h"
 #include "../Objects/ObjectList.h"
 #include "DecorationList.h"
@@ -19,7 +19,7 @@
 #include "../Game.h"
 #include "Vis.h"
 #include "../LOD.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "../TurnEngine/TurnEngine.h"
 #include "../stru123.h"
 #include "../MM7.h"
--- a/Engine/MMT.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/MMT.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -5,17 +5,17 @@
 #define _CRT_SECURE_NO_WARNINGS
 
 #include "MMT.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 
 #include "mm7_data.h"
-#include "AudioPlayer.h"
-#include "Mouse.h"
+#include "Media/Audio/AudioPlayer.h"
+#include "IO/Mouse.h"
 #include "LOD.h"
 #include "Engine/Graphics/Render.h"
-#include "GUIFont.h"
+#include "GUI/GUIFont.h"
 #include "lib/libpng/png.h"
 #include "Engine/ErrorHandling.h"
-#include "Bink_Smacker.h"
+#include "Media/Video/Bink_Smacker.h"
 #include "Game.h"
 #include "Log.h"
 
--- a/Engine/Objects/Actor.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/Actor.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -16,7 +16,7 @@
 #include "Actor.h"
 #include "../OurMath.h"
 #include "../Graphics/Outdoor.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Game.h"
 #include "ObjectList.h"
 #include "../Graphics/Overlays.h"
@@ -26,7 +26,7 @@
 #include "../Timer.h"
 #include "../LOD.h"
 #include "../Party.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 
 #include "../MM7.h"
 #include "SpriteObject.h"
--- a/Engine/Objects/Chest.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/Chest.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -16,16 +16,16 @@
 #include "../Graphics/Outdoor.h"
 #include "../Graphics/DecorationList.h"
 #include "../Party.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../OurMath.h"
 #include "../Texts.h"
 #include "ObjectList.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "../Timer.h"
 
 #include "../MM7.h"
 #include "SpriteObject.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "../Graphics/Viewport.h"
 #include "../Graphics/Level/Decoration.h"
 
--- a/Engine/Objects/Items.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/Items.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -6,13 +6,13 @@
 #include <stdlib.h>
 #include <string>
 #include "..\..\GUI\UI\UIHouses.h"
-#include "GUIButton.h"
+#include "GUI/GUIButton.h"
 
 #include "../ErrorHandling.h"
 
 #include "Items.h"
 #include "../MapInfo.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "Chest.h"
 #include "../LOD.h"
 #include "Monsters.h"
--- a/Engine/Objects/NPC.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/NPC.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -9,13 +9,13 @@
 #include "../Awards.h"
 #include "../Party.h"
 #include "NPC.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "../Events.h"
 #include "..\..\GUI\UI\UIHouses.h"
 #include "../Graphics/Indoor.h"
 #include "../MapInfo.h"
 #include "Actor.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Spells/CastSpellInfo.h"
 #include "../Graphics/Overlays.h"
 
--- a/Engine/Objects/Player.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/Player.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -9,14 +9,14 @@
 
 #include "Player.h"
 #include "../Tables/PlayerFrameTable.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Party.h"
 #include "../LOD.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "../Graphics/Viewport.h"
 #include "Actor.h"
 #include "../Game.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "../TurnEngine/TurnEngine.h"
 #include "../Events.h"
 #include "../Events2D.h"
--- a/Engine/Objects/SpriteObject.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Objects/SpriteObject.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -17,7 +17,7 @@
 #include "../LOD.h"
 #include "Actor.h"
 #include "../Events.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Engine/Graphics/Level/Decoration.h"
 
 #include "../MM7.h"
--- a/Engine/Party.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Party.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -7,14 +7,14 @@
 
 #include "Party.h"
 #include "Timer.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Engine/Tables/IconFrameTable.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "Engine/Tables/PlayerFrameTable.h"
 #include "Engine/TurnEngine/TurnEngine.h"
 #include "Engine/Graphics/Viewport.h"
 #include "Engine/Objects/Actor.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "texts.h"
 
 #include "MM7.h"
--- a/Engine/SaveLoad.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/SaveLoad.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -13,12 +13,12 @@
 #include "Party.h"
 #include "LOD.h"
 #include "Engine/Graphics/Outdoor.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Engine/Objects/Actor.h"
 #include "Engine/Objects/Chest.h"
 #include "Timer.h"
-#include "GUIWindow.h"
-#include "GUIFont.h"
+#include "GUI/GUIWindow.h"
+#include "GUI/GUIFont.h"
 #include "Engine/Graphics/Overlays.h"
 #include "Engine/Objects/SpriteObject.h"
 #include "Engine/Graphics/Viewport.h"
--- a/Engine/Spells/CastSpellInfo.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Spells/CastSpellInfo.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -7,11 +7,11 @@
 #include "../Objects/Actor.h"
 #include "../Party.h"
 #include "../MM7.h"
-#include "Mouse.h"
+#include "IO/Mouse.h"
 #include "../../stru6.h"
 #include "../Game.h"
-#include "GUIWindow.h"
-#include "AudioPlayer.h"
+#include "GUI/GUIWindow.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "../Graphics/Outdoor.h"
 #include "../Graphics/Overlays.h"
 #include "../Events.h"
--- a/Engine/Spells/Spells.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Spells/Spells.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -16,7 +16,7 @@
 #include "Engine/Objects/SpriteObject.h"
 #include "Engine/Objects/ObjectList.h"
 #include "Engine/Graphics/Indoor.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Engine/Objects/Actor.h"
 #include "../Game.h"
 #include "stru6.h"
--- a/Engine/Timer.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/Timer.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -5,7 +5,7 @@
 #define _CRT_SECURE_NO_WARNINGS
 
 #include "Timer.h"
-#include "Keyboard.h"
+#include "IO/Keyboard.h"
 
 #include "OSAPI.h"
 
--- a/Engine/TurnEngine/TurnEngine.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/TurnEngine/TurnEngine.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -9,7 +9,7 @@
 #include "../mm7_data.h"
 #include "Engine/Objects/Actor.h"
 #include "../Party.h"
-#include "AudioPlayer.h"
+#include "Media/Audio/AudioPlayer.h"
 #include "Engine/Objects/SpriteObject.h"
 #include "../Timer.h"
 #include "../stru298.h"
--- a/Engine/mm7_data.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/Engine/mm7_data.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -5,7 +5,7 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "mm7_data.h"
 
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "Party.h"
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIButton.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,247 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "GUIButton.h"
+#include "GUIWindow.h"
+#include "GUIFont.h"
+
+#include "Engine/mm7_data.h"
+#include "Engine/LOD.h"
+#include "Engine/Texts.h"
+#include "OSWindow.h"
+
+
+
+struct GUIButton *pBtn_CloseBook;
+struct GUIButton *pBtn_InstallRemoveSpell;
+struct GUIButton *pBtn_Autonotes_Instructors;
+struct GUIButton *pBtn_Autonotes_Misc;
+struct GUIButton *pBtn_Book_6;
+struct GUIButton *pBtn_Book_5;
+struct GUIButton *pBtn_Book_4;
+struct GUIButton *pBtn_Book_3;
+struct GUIButton *pBtn_Book_2;
+struct GUIButton *pBtn_Book_1;
+
+
+struct GUIButton *pPlayerCreationUI_BtnReset;
+struct GUIButton *pPlayerCreationUI_BtnOK;
+struct GUIButton *pBtn_ExitCancel;
+struct GUIButton *pBtn_YES;
+struct GUIButton *pPlayerCreationUI_BtnPlus;
+struct GUIButton *pPlayerCreationUI_BtnMinus;
+
+
+struct GUIButton *pButton_RestUI_Main;
+struct GUIButton *pButton_RestUI_Exit;
+struct GUIButton *pButton_RestUI_Wait5Minutes;
+struct GUIButton *pButton_RestUI_WaitUntilDawn;
+struct GUIButton *pButton_RestUI_Wait1Hour;
+
+
+struct GUIButton *pCharacterScreen_ExitBtn;
+struct GUIButton *pCharacterScreen_AwardsBtn;
+struct GUIButton *pCharacterScreen_InventoryBtn;
+struct GUIButton *pCharacterScreen_SkillsBtn;
+struct GUIButton *pCharacterScreen_StatsBtn;
+struct GUIButton *pCharacterScreen_DollBtn;
+struct GUIButton *pCharacterScreen_DetalizBtn;
+
+
+struct GUIButton *pBtn_NPCRight;
+struct GUIButton *pBtn_NPCLeft;
+struct GUIButton *pBtn_GameSettings;
+struct GUIButton *pBtn_QuickReference;
+struct GUIButton *pBtn_CastSpell;
+struct GUIButton *pBtn_Rest;
+struct GUIButton *pBtn_History;
+struct GUIButton *pBtn_Calendar;
+struct GUIButton *pBtn_Maps;
+struct GUIButton *pBtn_Autonotes;
+struct GUIButton *pBtn_Quests;
+
+
+struct GUIButton *pMMT_MainMenu_BtnMM6;
+struct GUIButton *pMMT_MainMenu_BtnMM7;
+struct GUIButton *pMMT_MainMenu_BtnMM8;
+struct GUIButton *pMMT_MainMenu_BtnContinue;
+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;
+
+
+struct GUIWindow *pPrimaryWindow;
+struct GUIWindow *pChestWindow;
+struct GUIWindow *pDialogueWindow;
+struct GUIWindow *window_SpeakInHouse;
+struct GUIWindow *pGUIWindow_ScrollWindow;
+struct GUIWindow *ptr_507BC8;
+struct GUIWindow *pGUIWindow_CurrentMenu;
+struct GUIWindow *ptr_507BD0;
+struct GUIWindow *pGUIWindow_Settings;
+struct GUIWindow *pModalWindow;
+struct GUIWindow *pGUIWindow_EscMessageWindow;
+struct GUIWindow *pBooksWindow;
+struct GUIWindow *pGUIWindow2;
+
+
+struct GUIButton *pBtn_Resume;
+struct GUIButton *pBtn_QuitGame;
+struct GUIButton *pBtn_GameControls;
+struct GUIButton *pBtn_LoadGame;
+struct GUIButton *pBtn_SaveGame;
+struct GUIButton *pBtn_NewGame;
+
+struct GUIButton *pBtn_SliderRight;
+struct GUIButton *pBtn_SliderLeft;
+
+
+struct GUIButton *pBtnDownArrow;
+struct GUIButton *pBtnArrowUp;
+struct GUIButton *pBtnCancel;
+struct GUIButton *pBtnLoadSlot;
+
+
+std::array<GUIButton*, 4> pCreationUI_BtnPressRight2;
+std::array<GUIButton*, 4> pCreationUI_BtnPressLeft2;
+std::array<GUIButton*, 4> pCreationUI_BtnPressLeft;
+std::array<GUIButton*, 4> pCreationUI_BtnPressRight;
+
+
+
+
+
+
+//----- (0041D0D8) --------------------------------------------------------
+void GUIButton::Release()
+{
+  if ( this )
+  {
+    if ( this == this->pParent->pControlsHead )
+    {
+      if ( this->pNext )
+      {
+        this->pParent->pControlsHead = this->pNext;
+        this->pNext->pPrev = 0;
+      }
+      else
+      {
+        this->pParent->pControlsHead = 0;
+        this->pParent->pControlsTail = 0;
+      }
+    }
+    else
+    {
+      if ( this->pNext )
+      {
+        this->pPrev->pNext = this->pNext;
+        this->pNext->pPrev = this->pPrev;
+      }
+      else
+      {
+        this->pPrev->pNext = 0;
+        this->pParent->pControlsTail = this->pPrev;
+      }
+    }
+    --this->pParent->uNumControls;
+  }
+}
+
+//----- (00415180) --------------------------------------------------------
+void GUIButton::DrawLabel( const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor )
+{
+  //strlen(edx0);
+  return pParent->DrawText(pFont,
+           this->uX + (signed int)(this->uWidth - pFont->GetLineWidth(label_text)) / 2,
+           this->uY + (signed int)(this->uHeight - pFont->uFontHeight) / 2,
+           a5, label_text, 0, 0, uFontShadowColor);
+}
+//----- (004B36CC) --------------------------------------------------------
+void CreateButtonInColumn( int column_pos, unsigned int control_id )
+{
+  pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, UIMSG_SelectShopDialogueOption,  control_id,  0,   "",   0);
+}
+//----- (00419379) --------------------------------------------------------
+void ReleaseAwardsScrollBar()
+{
+  GUIButton *pButton; // esi@2
+
+  if ( awards_scroll_bar_created )
+  {
+    awards_scroll_bar_created = false;
+	ptr_507BA4->Release();
+    pBtn_Up->Release();
+    pBtn_Down->Release();
+    pBtn_Down = 0;
+    pBtn_Up = 0;
+    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
+    {
+      if ( pButton->msg == UIMSG_InventoryLeftClick )
+      {
+        pButton->uX = dword_50698C_uX;
+        pButton->uY = dword_506988_uY;
+        pButton->uZ = dword_506984_uZ;
+        pButton->uW = dword_506980_uW;
+        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
+      }
+    }
+  }
+}
+//----- (00419220) --------------------------------------------------------
+void CreateAwardsScrollBar()
+{
+  GUIButton *pButton; // eax@2
+
+  if ( !awards_scroll_bar_created )
+  {
+    awards_scroll_bar_created = 1;
+    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
+    {
+      if ( pButton->msg == UIMSG_InventoryLeftClick )
+      {
+        dword_50698C_uX = pButton->uX;
+        dword_506988_uY = pButton->uY;
+        dword_506984_uZ = pButton->uZ;
+        dword_506980_uW = pButton->uW;
+        pButton->uW = 0;
+        pButton->uZ = 0;
+        pButton->uY = 0;
+        pButton->uX = 0;
+      }
+    }
+    pBtn_Up = pGUIWindow_CurrentMenu->CreateButton(438, 46,
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureWidth,
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureHeight,
+                   1, 0, UIMSG_ClickAwardsUpBtn, 0, 0, "",
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_up),
+                   pIcons_LOD->GetTexture(uTextureID_ar_up_dn), 0);
+    pBtn_Down = pGUIWindow_CurrentMenu->CreateButton(438, 292,
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureWidth,
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureHeight,
+                   1, 0, UIMSG_ClickAwardsDownBtn, 0, 0, "",
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up),
+                   pIcons_LOD->GetTexture(uTextureID_ar_dn_dn), 0);
+    ptr_507BA4 = pGUIWindow_CurrentMenu->CreateButton(440, 62, 16, 232, 1, 0, UIMSG_ClickAwardScrollBar, 0, 0, "", 0);
+  }
+}
+//----- (004BCA33) --------------------------------------------------------
+void UI_CreateEndConversationButton()
+{
+  pDialogueWindow->Release();
+  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 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);
+  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIButton.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,3 @@
+#pragma once
+void CreateButtonInColumn(int a1, unsigned int a2);
+void UI_CreateEndConversationButton();
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIFont.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,654 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <string>
+#include "Engine/ErrorHandling.h"
+
+#include "Engine/LOD.h"
+#include "GUIFont.h"
+#include "GUIWindow.h"
+#include "Engine/Graphics/Render.h"
+
+#include "Engine/mm7_data.h"
+
+
+extern LODFile_IconsBitmaps *pIcons_LOD;
+
+
+struct GUIFont *pAutonoteFont;
+struct GUIFont *pSpellFont;
+struct GUIFont *pFontArrus;
+struct GUIFont *pFontLucida;
+struct GUIFont *pBook2Font;
+struct GUIFont *pBookFont;
+struct GUIFont *pFontCreate;
+struct GUIFont *pFontCChar;
+struct GUIFont *pFontComic;
+struct GUIFont *pFontSmallnum;
+
+char temp_string[2048];
+
+std::array<char, 10000> pTmpBuf3;
+
+void DrawCharToBuff(unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight, unsigned __int16* pFontPalette, __int16 draw_color, int line_width);
+
+
+//----- (0044C448) --------------------------------------------------------
+GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...)
+{	
+    int pallete_index; // eax@3
+    GUIFont *pFont;
+    unsigned int palletes_count =0;
+    va_list palettes_ptr;
+
+    pFont = (GUIFont *)pIcons_LOD->LoadRaw(pFontFile, 0);
+    va_start(palettes_ptr, pFontFile);
+
+    while  (NULL!=(pFontPalette=va_arg(palettes_ptr, const char *)))
+        {
+        pallete_index =pIcons_LOD->LoadTexture(pFontPalette, TEXTURE_16BIT_PALETTE);
+        if (pallete_index == -1)
+            Error("Unable to open %s", pFontPalette);
+
+        pFont->pFontPalettes[palletes_count] = pIcons_LOD->pTextures[pallete_index].pPalette16;
+        ++palletes_count;
+        }
+    va_end(palettes_ptr);
+    pFont->palletes_count = palletes_count;
+    return pFont;
+}
+
+//----- (0044D2FD) --------------------------------------------------------
+void GUIFont::_44D2FD_prolly_draw_credits_entry( GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h, 
+                                                 unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString, 
+                                                 unsigned __int16 *pPixels, unsigned int uPixelsWidth )
+    {
+  char *work_string; // eax@1
+  unsigned __int16 *curr_pixel_pos; // esi@1
+  GUIFont *currentFont; // edi@4
+  signed int start_str_pos; // ecx@4
+  signed int line_w; // eax@6
+  GUIWindow draw_window; // [sp+Ch] [bp-5Ch]@
+  int currentColor; // [sp+74h] [bp+Ch]@4
+  int half_frameX; // [sp+80h] [bp+18h]@2
+
+  draw_window.uFrameHeight = h;
+  draw_window.uFrameW = uFrameY + h - 1;
+  draw_window.uFrameWidth = w;
+  draw_window.uFrameZ = uFrameX + w - 1;
+  ui_current_text_color = firstColor;
+  draw_window.uFrameX = uFrameX;
+  draw_window.uFrameY = uFrameY;
+
+  work_string = GUIFont::FitTwoFontStringINWindow(pString, this, pSecondFont, &draw_window, 0, 1);
+  work_string = strtok(work_string, "\n");
+  curr_pixel_pos = &pPixels[uPixelsWidth * uFrameY];
+  if ( work_string )
+  {
+    half_frameX = uFrameX >> 1;
+    while ( 1 )
+    {
+      currentFont = this;
+      ui_current_text_color = firstColor;
+      start_str_pos = 0;
+      currentColor = firstColor;
+      if ( *work_string == '_' )
+      {
+        currentFont = pSecondFont;
+        currentColor = secondColor;
+        ui_current_text_color = secondColor;
+        start_str_pos = 1;
+      }
+      line_w = (signed int)(w - currentFont->GetLineWidth(&work_string[start_str_pos]))/2;
+      if ( line_w < 0 )
+        line_w = 0;
+      currentFont->DrawTextLineToBuff(currentColor, secondColor, &curr_pixel_pos[line_w + half_frameX], work_string, uPixelsWidth);
+      curr_pixel_pos += uPixelsWidth * (currentFont->uFontHeight - 3);
+      work_string = strtok(0, "\n");
+      if ( !work_string )
+        break;
+    }
+  }
+}
+
+//----- (0044D1E7) --------------------------------------------------------
+void GUIFont::DrawTextLine( unsigned int uDefaultColor, signed int uX, signed int uY, 
+                            const char *text, int max_len_pix )
+{
+    signed int uX_pos; // edi@3
+    unsigned char c; // cl@4
+    unsigned __int16 draw_color; // cx@12
+    unsigned __int8 *pCharPixels; // eax@12
+    char color_code[20]; // [sp+Ch] [bp-1Ch]@16
+    int text_length; // [sp+20h] [bp-8h]@2
+    int text_color; // [sp+24h] [bp-4h]@1
+    int uCharWidth; // [sp+30h] [bp+8h]@9
+
+    if ( !text )
+        return;
+    text_color = ui_current_text_color;
+    text_length = strlen(text);
+    uX_pos=uX;
+    for (int i=0; i<text_length; ++i )
+        {
+        c = text[i];
+        if ( IsCharValid(c) )
+            {
+            switch (c)
+                {
+            case '\n':	//Line Feed 0A 10:
+                return;
+                break;
+            case '\f':  //Form Feed, page eject  0C 12 
+                strncpy(color_code, &text[i + 1], 5);
+                color_code[5] = 0;
+                text_color = atoi(color_code);
+                ui_current_text_color = text_color;
+                i += 5;	  
+                break;
+            case '\t':	// Horizontal tab 09
+            case '\r':   //Carriage Return 0D 13                 
+                break;
+            default:
+                uCharWidth = pMetrics[c].uWidth;
+                if ( uCharWidth )
+                    {
+                    if ( i > 0 )
+                        uX_pos += pMetrics[c].uLeftSpacing;
+                    draw_color = text_color;
+                    pCharPixels = &pFontData[font_pixels_offset[c]];
+                    if ( !text_color )
+                        draw_color = -1;
+                    pRenderer->DrawText(uX_pos, uY, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, 0);
+                    uX_pos += uCharWidth;
+                    if ( i < text_length )
+                        uX_pos += pMetrics[c].uRightSpacing;
+                    }
+                }
+            }
+        }
+    
+}
+
+//----- (0040F845) --------------------------------------------------------
+void DrawCharToBuff( unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight, 
+                            unsigned __int16* pFontPalette, __int16 draw_color, int line_width )
+    {
+    unsigned __int16* draw_buff; // edi@1
+    unsigned char* pPixels; // esi@1
+    unsigned char char_pxl; // eax@3
+
+    draw_buff = uXpos;
+    pPixels = pCharPixels;
+    for(int i=0; i<uCharHeight; ++i)
+        {
+        for(int j=0; j<uCharWidth; ++j)
+            {
+            char_pxl = *pPixels++;
+            if ( char_pxl )
+                {
+                if ( char_pxl == 1 )
+                    *draw_buff = pFontPalette[1];     
+                else         
+                    *draw_buff = draw_color;         
+                }
+            ++draw_buff;
+            }
+        draw_buff+=line_width-uCharWidth;
+        }
+
+}
+
+//----- (0044D0B5) --------------------------------------------------------
+void GUIFont::DrawTextLineToBuff( int uColor, int a3, unsigned short* uX_buff_pos, const char *text, int line_width )
+    {
+  
+  unsigned short* uX_pos; // edi@3
+  unsigned char c; // cl@4
+  unsigned __int16 draw_color; // cx@12
+  unsigned __int8 *pCharPixels; // eax@12
+  char color_code[20]; // [sp+Ch] [bp-1Ch]@16
+  int text_length; // [sp+20h] [bp-8h]@2
+  int text_color; // [sp+24h] [bp-4h]@1
+  int uCharWidth; // [sp+30h] [bp+8h]@9
+
+  if ( !text )
+      return;
+  text_color = ui_current_text_color;
+  text_length = strlen(text);
+  uX_pos=uX_buff_pos;
+  for (int i=0; i<text_length; ++i )
+      {
+      c = text[i];
+      if ( IsCharValid(c) )
+          {
+          switch (c)
+              {
+          case '\n':	//Line Feed 0A 10:
+              return;
+              break;
+          case '\f':  //Form Feed, page eject  0C 12 
+              strncpy(color_code, &text[i + 1], 5);
+              color_code[5] = 0;
+              text_color = atoi(color_code);
+              ui_current_text_color = text_color;
+              i += 5;	  
+              break;
+          case '\t':	// Horizontal tab 09
+          case '_':                   
+              break;
+          default:
+              uCharWidth = pMetrics[c].uWidth;
+              if ( uCharWidth )
+                  {
+                  if ( i > 0 )
+                      uX_pos += pMetrics[c].uLeftSpacing;
+                  draw_color = text_color;
+                  pCharPixels = &pFontData[font_pixels_offset[c]];
+                  if ( !text_color )
+                      draw_color = -1;
+                  DrawCharToBuff(uX_pos, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, line_width);
+                  uX_pos += uCharWidth;
+                  if ( i < text_length )
+                      uX_pos += pMetrics[c].uRightSpacing;
+                  }
+              }
+          }
+      }
+}
+
+
+
+//----- (0044C933) --------------------------------------------------------
+char * GUIFont::FitTwoFontStringINWindow( const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6 )
+    {
+ 
+  GUIFont *currentFont; // esi@3
+  unsigned char c;
+  int uInStrLen;
+  char digits[4];
+  int possible_transition_point;
+  int string_pixel_Width;
+  int start_pixel_offset;
+
+  if (!pString)
+      {
+      MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
+      return 0;
+      }
+  currentFont=pFontMain; // esi@3
+  uInStrLen = strlen(pString);
+  Assert(uInStrLen < sizeof(pTmpBuf3));
+  strcpy(pTmpBuf3.data(), pString);
+  if (uInStrLen==0)
+      return pTmpBuf3.data();
+
+  start_pixel_offset=string_pixel_Width=startPixlOff;
+  possible_transition_point=0;
+  for(int i=0; i<uInStrLen; ++i) 
+      {
+      c=pTmpBuf3[i];
+      if (pFontMain->IsCharValid(c))
+          {
+          switch (c)
+              {
+          case '\t':	// Horizontal tab 09
+              {
+              strncpy(digits, &pTmpBuf3[i+1],3);
+              digits[3]=0;
+              string_pixel_Width = atoi(digits)+startPixlOff;
+              i+=3;
+              break;
+              }
+          case  '\n':	//Line Feed 0A 10
+              {
+              string_pixel_Width=start_pixel_offset;
+              possible_transition_point=i;
+              currentFont=pFontMain;
+              break;
+              }
+          case  '\f':   //Form Feed, page eject  0C 12
+              {
+              i+=5;  
+              break;
+              }
+          case  '\r':   //Carriage Return 0D 13
+              {
+              if (!a6)
+                  return (char*)pString;
+              break;
+              }
+          case ' ' :
+              {
+              string_pixel_Width+=currentFont->pMetrics[c].uWidth;
+              possible_transition_point=i;
+              break;
+              }
+          case '_' :
+              currentFont=pFontSecond;
+              break;
+          default:
+
+              if ((string_pixel_Width+currentFont->pMetrics[c].uWidth+ currentFont->pMetrics[c].uLeftSpacing+
+                  currentFont->pMetrics[c].uRightSpacing)<pWindow->uFrameWidth)
+                  {
+                  if(i>possible_transition_point)
+                      string_pixel_Width+=currentFont->pMetrics[c].uLeftSpacing;
+                  string_pixel_Width+=currentFont->pMetrics[c].uWidth;
+                  if (i<uInStrLen)
+                      string_pixel_Width+=currentFont->pMetrics[c].uRightSpacing;
+                  }
+              else
+                  {
+                  pTmpBuf3[possible_transition_point]='\n';
+                      
+                  if ( currentFont== pFontSecond)
+                      {
+
+                      for(int k=uInStrLen-1; k>=possible_transition_point+1; --k)
+                          pTmpBuf3[k] = pTmpBuf3[k-1];
+
+                      ++uInStrLen;
+                      ++possible_transition_point;
+                      pTmpBuf3[possible_transition_point] = '_';
+                      
+                      }
+                     string_pixel_Width=start_pixel_offset;
+
+                      for(int j=possible_transition_point;j<i; ++j ) 
+                          {
+                          c=pTmpBuf3[j];
+                          if (pFontMain->IsCharValid(c))
+                              {
+                              if(j>possible_transition_point)
+                                  string_pixel_Width+=pFontMain->pMetrics[c].uLeftSpacing;
+                              string_pixel_Width+=pFontMain->pMetrics[c].uWidth;
+                              if (j<i)
+                                  string_pixel_Width+=pFontMain->pMetrics[c].uRightSpacing;
+
+                              }
+                          }                    
+                  }
+              }
+          }
+      }
+  return pTmpBuf3.data();
+
+}
+
+
+//----- (0044C6C2) --------------------------------------------------------
+char* GUIFont::GetPageTop( const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5 )
+{
+  int text_height; // edi@1
+  char *text_str; // ebx@3
+  unsigned char c; // cl@4
+  int text_length; 
+
+  text_height = 0;
+
+  if ( !pInString )
+    return 0;
+  text_str = FitTextInAWindow(pInString, this, pWindow, uX, 0);
+  text_length = strlen(text_str);
+  for ( int i = 0; i < text_length; ++i )
+  {
+    c = text_str[i];
+    if ( IsCharValid(c) )
+    {
+      switch (c)
+      {
+        case '\n':	//Line Feed 0A 10:
+          text_height = text_height + (uFontHeight - 3);
+          if ( text_height >= (signed int)(a5 * (pWindow->uFrameHeight - (uFontHeight - 3))) )
+            return &text_str[i];
+          break;
+        case '\f':  //Form Feed, page eject  0C 12
+          i += 5;
+          break;
+        case '\t':	// Horizontal tab 09
+        case '\r':   //Carriage Return 0D 13 
+          i += 3;
+          break;
+      }
+      if ( text_height >= (signed int)(a5 * pWindow->uFrameHeight) )
+        break;
+    }
+  }
+  return &text_str[0];
+}
+
+//----- (0044C62E) --------------------------------------------------------
+int GUIFont::GetStringHeight2( GUIFont *secondFont, const char *text_str, GUIWindow* pWindow, int startX, int a6 )
+    {
+ 
+  int uAllHeght; 
+  int uStringLen; 
+  unsigned char c; 
+  char *test_string; 
+
+  if ( !text_str )
+    return 0;
+  uAllHeght = uFontHeight - 3;
+  test_string = FitTwoFontStringINWindow(text_str, this, secondFont, pWindow, startX, 0);
+  uStringLen = strlen(test_string);
+  for (int i = 0; i < uStringLen; ++i)
+      {
+      c = test_string[i];
+      if (IsCharValid(c))
+          {
+          switch (c)
+              {
+          case '\n':	//Line Feed 0A 10:
+              uAllHeght+= uFontHeight - 3;
+              break;
+          case '\f':  //Form Feed, page eject  0C 12 
+              i += 5;		  
+              break;
+          case '\t':	// Horizontal tab 09
+          case '\r':   //Carriage Return 0D 13
+              if (a6 != 1)
+                  i += 3;
+              break;
+              }
+          }
+      }
+
+  return uAllHeght;
+}
+
+//----- (0044C59D) --------------------------------------------------------
+int GUIFont::CalcTextHeight( const char *pString, struct GUIWindow *pWindow, int uXOffset, int a5 )
+{
+  int uAllHeght; 
+  int uStringLen; 
+  unsigned char c; 
+  char *test_string; 
+
+  if (!pString)
+    return 0;
+  uAllHeght = uFontHeight - 6;
+  test_string = FitTextInAWindow(pString, this, pWindow, uXOffset, 0);
+  uStringLen = strlen(pString);
+  for (int i = 0; i < uStringLen; ++i)
+  {
+    c = test_string[i];
+    if (IsCharValid(c))
+    {
+      switch (c)
+      {
+        case '\n':	//Line Feed 0A 10:
+          uAllHeght += uFontHeight - 3;
+          break;
+        case '\f':  //Form Feed, page eject  0C 12 
+          i += 5;
+          break;
+        case '\t':	// Horizontal tab 09
+        case '\r':   //Carriage Return 0D 13
+          if (a5 != 1)
+            i += 3;
+          break;
+      }
+   }
+  }
+  return uAllHeght;
+}
+
+//----- (0044C51E) --------------------------------------------------------
+int GUIFont::GetLineWidth(const char *pString)
+	{
+	int str_len; // ebp@3
+	int string_line_width; // esi@3
+	unsigned char c;
+
+	if (!pString)
+		return 0;
+	str_len = strlen(pString);
+	string_line_width = 0;
+	for ( int i = 0; i < str_len; ++i )
+		{
+		c = pString[i];
+		if (IsCharValid(c))
+			{
+			switch (c)
+				{
+			case '\t':
+			case '\n':
+			case '\r':
+				return string_line_width;
+			case '\f':
+				i += 5;	  
+				break;
+			default:
+				if (i > 0)
+					string_line_width += pMetrics[c].uLeftSpacing;
+				string_line_width += pMetrics[c].uWidth;
+				if (i < str_len)
+					string_line_width +=pMetrics[c].uRightSpacing;
+				}
+			}
+		}
+	return string_line_width;
+	}
+
+
+//----- (0044C502) --------------------------------------------------------
+int GUIFont::AlignText_Center(unsigned int uCenterX, const char *pString)
+{
+  signed int position; // esi@1
+ 
+  position = (signed int)(uCenterX - GetLineWidth(pString)) >> 1;
+  if ( position >= 0 )
+    return position;
+  else
+    return  0;
+}
+
+//----- (0044C768) --------------------------------------------------------
+char * FitTextInAWindow( const char *pInString, GUIFont *pFont, GUIWindow *pWindow, signed int uX, int a5 )
+{
+  unsigned char c;
+  int uInStrLen;
+  char digits[4];
+  int possible_transition_point;
+  int string_pixel_Width;
+  int start_pixel_offset;
+
+  if (!pInString)
+  {
+    MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
+    return 0;
+  }
+  uInStrLen = strlen(pInString);
+  strcpy(&temp_string[0], pInString);
+  if (uInStrLen == 0)
+    return &temp_string[0];
+
+  start_pixel_offset = string_pixel_Width=uX;
+  possible_transition_point = 0;
+  for ( int i = 0; i < uInStrLen; ++i )
+  {
+    c = temp_string[i];
+    if (pFont->IsCharValid(c))
+    {
+      switch (c)
+      {
+        case '\t':	// Horizontal tab 09
+        {
+          strncpy(digits, &temp_string[i + 1],3);
+          digits[3] = 0;
+          string_pixel_Width = atoi(digits)+uX;
+          i += 3;
+          break;
+        }
+        case  '\n':	//Line Feed 0A 10 (êîíåö ñòðîêè)
+        {
+          string_pixel_Width = start_pixel_offset;
+          possible_transition_point = i;
+          break;
+        }
+        case  '\f':   //Form Feed, page eject  0C 12
+        {
+          i += 5;  
+          break;
+        }
+        case  '\r':   //Carriage Return 0D 13
+        {
+          if ( !a5 )
+            return (char*)pInString;
+          break;
+        }
+        case ' '://ïðîáåë
+        {
+          string_pixel_Width += pFont->pMetrics[c].uWidth;
+          possible_transition_point = i;
+          break;
+        }
+        default:
+          if ((string_pixel_Width + pFont->pMetrics[c].uWidth + pFont->pMetrics[c].uLeftSpacing +
+               pFont->pMetrics[c].uRightSpacing) < pWindow->uFrameWidth )//íàðàùèâàíèå äëèíû ñòðîêè èëè ïåðåíîñ
+          {
+            if ( i > possible_transition_point )
+              string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
+            string_pixel_Width += pFont->pMetrics[c].uWidth;
+            if (i < uInStrLen)
+              string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
+          }
+          else//ïåðåíîñ ñòðîêè è ñëîâà
+          {
+            temp_string[possible_transition_point] ='\n';
+            string_pixel_Width = start_pixel_offset;
+            if ( i > possible_transition_point )
+            {
+              for ( int j = possible_transition_point; j < i; ++j )
+              {
+                c = temp_string[j];
+                if (pFont->IsCharValid(c))
+                {
+                  if ( j > possible_transition_point )
+                    string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
+                  string_pixel_Width += pFont->pMetrics[c].uWidth;
+                  if ( j < i )
+                    string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
+                }
+              }
+            }
+          }
+        }
+    }
+  }
+  return &temp_string[0];
+}
+//----- (00414162) --------------------------------------------------------
+void uGameUIFontMain_initialize()
+{
+  uGameUIFontMain = Color16(0xAu, 0, 0);
+}
+
+//----- (00414174) --------------------------------------------------------
+void uGameUIFontShadow_initialize()
+{
+  uGameUIFontShadow = Color16(0xE6u, 214, 193);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIFont.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,68 @@
+#pragma once
+
+
+/*  171 */
+#pragma pack(push, 1)
+struct GUICharMetric
+{
+  unsigned int uLeftSpacing;
+  unsigned int uWidth;
+  unsigned int uRightSpacing;
+};
+#pragma pack(pop)
+
+/*  170 */
+#pragma warning( push )
+#pragma warning( disable : 4200 )
+#pragma pack(push, 1)
+struct GUIFont
+{
+	
+//----- (0044C4DE) --------------------------------------------------------
+  bool IsCharValid(unsigned char c) {	return (c >= cFirstChar) && (c <= cLastChar) || (c == '\f') || (c == '\r') || (c == '\t') || (c == '\n');}
+  int AlignText_Center(unsigned int uCenterX, const char *pString);
+  int GetLineWidth(const char *pString);
+  int CalcTextHeight(const  char *pString, struct GUIWindow *pWindow, int uXOffset, int a5);
+  int GetStringHeight2(GUIFont *secondFont, const char *text_str, GUIWindow* pWindow, int startX, int a6);
+  char* GetPageTop(const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5);
+  void DrawTextLineToBuff(int uColor, int a3, unsigned short* uX_buff_pos, const char *text, int line_width);
+  void DrawTextLine(unsigned int uDefaultColor, signed int uX, signed int uY, const char *text, int max_len_pix);
+  void _44D2FD_prolly_draw_credits_entry(GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h, 
+                                        unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString, 
+                                        unsigned __int16 *pPixels, unsigned int uPixelsWidth);
+
+  static char * FitTwoFontStringINWindow(const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6);
+  static void uGameUIFontMain_initialize();
+  static void uGameUIFontShadow_initialize();
+
+  unsigned char cFirstChar;  //0
+  unsigned char cLastChar;  //1
+  char field_2;
+  char field_3;
+  char field_4;
+  __int16 uFontHeight;  //5-6
+  char field_7;
+  int palletes_count;
+  unsigned __int16 *pFontPalettes[5];
+  GUICharMetric pMetrics[256];
+  int font_pixels_offset[256];
+  unsigned char pFontData[0]; //array of font pixels
+
+};
+#pragma pack(pop)
+#pragma warning( pop )
+
+GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...);
+char * FitTextInAWindow(const char *pInString, GUIFont *pFont, GUIWindow *pWindow, signed int uX, int a5);
+
+
+extern struct GUIFont *pAutonoteFont;
+extern struct GUIFont *pSpellFont;
+extern struct GUIFont *pFontArrus;
+extern struct GUIFont *pFontLucida;
+extern struct GUIFont *pBook2Font;
+extern struct GUIFont *pBookFont;
+extern struct GUIFont *pFontCreate;
+extern struct GUIFont *pFontCChar;
+extern struct GUIFont *pFontComic;
+extern struct GUIFont *pFontSmallnum;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIProgressBar.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,186 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "GUIProgressBar.h"
+#include "Engine/ErrorHandling.h"
+#include "Engine/LOD.h"
+#include "Engine/Party.h"
+#include "Engine/Graphics/Render.h"
+#include "Engine/Tables/IconFrameTable.h"
+
+#include "Engine/mm7_data.h"
+
+
+
+
+struct GUIProgressBar *pGameLoadingUI_ProgressBar = new GUIProgressBar;
+
+
+
+
+//----- (00Initialize) --------------------------------------------------------
+bool GUIProgressBar::Initialize(Type type)
+{
+  //GUIProgressBar *v2; // esi@1
+  signed int v4; // eax@7
+  int v5; // ecx@8
+  //int v6; // edi@8
+  int v7; // edx@14
+  //const char *v8; // [sp-8h] [bp-84h]@20
+  //unsigned int v9; // [sp-4h] [bp-80h]@20
+  char Str1[64]; // [sp+4h] [bp-78h]@16
+
+  switch (type)
+  {
+    case TYPE_None:
+      return true;
+
+    case TYPE_Box:
+    case TYPE_Fullscreen:
+      break;
+
+    default:
+      Error("Invalid GUIProgressBar type: %u", type);
+  }
+
+  //v2 = this;
+  if (pLoadingBg.pPixels)
+    return false;
+
+  uType = type;
+
+  v4 = 1;
+  if (uType == TYPE_Fullscreen)
+  {
+    v5 = 0;
+    //v6 = (int)&field_10;
+    do
+    {
+      if ( field_10[v4] == 1 )
+        ++v5;
+      ++v4;
+    }
+    while ( v4 <= 5 );
+    if ( v5 == 5 )
+      memset(field_10, 0, 8);
+    v7 = rand() % 5 + 1;
+    if ( field_10[v7] == 1 )
+    {
+      do
+        v7 = rand() % 5 + 1;
+      while ( field_10[v7] == 1 );
+    }
+    sprintf(Str1, "loading%d.pcx", v7);
+    pLoadingBg.Load(Str1, 2);
+    uProgressCurrent = 0;
+    uX = 122;
+    uY = 151;
+    uWidth = 449;
+    uHeight = 56;
+    uProgressMax = 26;
+    pIcons_LOD->_410522(&pLoadingProgress, "loadprog", 2u);
+    Draw();
+    return true;
+  }
+
+  switch (pParty->alignment)
+  {
+    case PartyAlignment_Good:    pIcons_LOD->_410522(&pBardata, "bardata-b", 2); break;
+    case PartyAlignment_Neutral: pIcons_LOD->_410522(&pBardata, "bardata", 2); break;
+    case PartyAlignment_Evil:    pIcons_LOD->_410522(&pBardata, "bardata-c", 2); break;
+    default: Error("Invalid alignment type: %u", pParty->alignment);
+  }
+
+  uProgressCurrent = 0;
+  uProgressMax = 26;
+  Draw();
+  return true;
+}
+
+//----- (004435BB) --------------------------------------------------------
+void GUIProgressBar::Reset(unsigned __int8 uMaxProgress)
+{
+  field_9 = 0;
+  uProgressCurrent = 0;
+  uProgressMax = uMaxProgress;
+}
+
+//----- (004435CD) --------------------------------------------------------
+void GUIProgressBar::Progress()
+{
+  ++this->uProgressCurrent;
+  if ( this->uProgressCurrent > this->uProgressMax )
+    this->uProgressCurrent = this->uProgressMax;
+  Draw();
+}
+
+//----- (004435E2) --------------------------------------------------------
+void GUIProgressBar::Release()
+{
+  int v3; // edi@7
+
+  pLoadingBg.Release();
+  if ( this->uType == 1 )
+  {
+    if ( this->uProgressCurrent != this->uProgressMax )
+    {
+      this->uProgressCurrent = this->uProgressMax - 1;
+      Progress();
+    }
+    v3 = (int)&this->pLoadingProgress.pLevelOfDetail0_prolly_alpha_mask;
+    free(this->pLoadingProgress.pLevelOfDetail0_prolly_alpha_mask);
+    free(this->pLoadingProgress.pPalette16);
+    this->pLoadingProgress.pPalette16 = 0;
+  }
+  else
+  {
+    if ( !this->pBardata.pLevelOfDetail0_prolly_alpha_mask )
+      return;
+    free(this->pBardata.pLevelOfDetail0_prolly_alpha_mask);
+    v3 = (int)&this->pBardata.pPalette16;
+    free(this->pBardata.pPalette16);
+    this->pBardata.pLevelOfDetail0_prolly_alpha_mask = 0;
+  }
+  *(int *)v3 = 0;
+}
+
+//----- (00443670) --------------------------------------------------------
+void GUIProgressBar::Draw()
+{
+  pRenderer->BeginScene();
+  if (uType != TYPE_Fullscreen)
+  {
+    if (pBardata.pLevelOfDetail0_prolly_alpha_mask)
+    {
+      pRenderer->Sub01();
+
+      pRenderer->DrawTextureIndexed(80, 122, &pBardata);//ïðîãðåññáàð äëÿ äàíæåé
+      pRenderer->DrawTextureTransparent(100, 146, &pIcons_LOD->pTextures[pIconsFrameTable->GetFrame(uIconID_TurnHour, 0)->uTextureID]);
+      //pRenderer->FillRectFast(174, 164, floorf(((double)(113 * uProgressCurrent) / (double)uProgressMax) + 0.5f),//COERCE_UNSIGNED_INT64(v4 + 6.7553994e15),
+        //16, pRenderer->uTargetRMask);
+      pRenderer->FillRectFast(174, 164, floorf(((double)(113 * uProgressCurrent) / (double)uProgressMax) + 0.5f),//COERCE_UNSIGNED_INT64(v4 + 6.7553994e15),
+        16, 0xF800);
+      pRenderer->EndScene();
+      pRenderer->Present();
+      return;
+    }
+    pRenderer->EndScene();
+    return;
+  }
+
+  if (!pLoadingBg.pPixels)
+  {
+    pRenderer->EndScene();
+    return;
+  }
+
+  pRenderer->DrawTextureRGB(0, 0, &pLoadingBg);
+  pRenderer->SetRasterClipRect(0, 0, 639, 479);
+  pRenderer->SetTextureClipRect(172, 459, 15 * (signed int)(signed __int64)((double)(300 * uProgressCurrent) / (double)uProgressMax) / 15 + 172, 471);
+  pRenderer->DrawTextureTransparent(172, 459, &pLoadingProgress);
+  pRenderer->ResetTextureClipRect();
+  pRenderer->EndScene();
+  pRenderer->Present();
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIProgressBar.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,52 @@
+#pragma once
+#include "Engine/Graphics/Texture.h"
+
+
+/*  278 */
+#pragma pack(push, 1)
+struct GUIProgressBar
+{
+  enum Type: unsigned __int32
+  {
+    TYPE_None = 0,
+    TYPE_Fullscreen = 1,
+    TYPE_Box = 2
+  };
+
+  bool Initialize(Type type);
+  void Reset(unsigned __int8 uMaxProgress);
+  void Progress();
+  void Release();
+  void Draw();
+
+  __int16 uX;
+  __int16 uY;
+  __int16 uWidth;
+  __int16 uHeight;
+  char field_8;
+  char field_9;
+  char uProgressMax;
+  char uProgressCurrent;
+  Type uType;
+  char field_10[8];
+  //char field_11;
+  //char field_12;
+  //char field_13;
+  //char field_14;
+  //char field_15;
+  //char field_16;
+  //char field_17;
+  RGBTexture pLoadingBg;
+  RGBTexture field_40;
+  RGBTexture field_68;
+  RGBTexture field_90;
+  RGBTexture field_B8;
+  struct Texture field_E0;
+  struct Texture pBardata;
+  struct Texture pLoadingProgress;
+};
+#pragma pack(pop)
+
+
+
+extern struct GUIProgressBar *pGameLoadingUI_ProgressBar;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIWindow.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,4027 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "Engine/ErrorHandling.h"
+
+#include "GUIWindow.h"
+#include "GUIFont.h"
+#include "Engine/Party.h"
+#include "Engine/LOD.h"
+#include "IO/Keyboard.h"
+#include "Engine/OurMath.h"
+#include "Engine/Timer.h"
+#include "Media/Audio/AudioPlayer.h"
+#include "IO/Mouse.h"
+#include "Engine/Graphics/Viewport.h"
+#include "Engine/Tables/StorylineTextTable.h"
+#include "GUI\UI\UIHouses.h"
+#include "GUI\UI\UIBooks.h"
+#include "Engine/texts.h"
+#include "Engine/Autonotes.h"
+#include "Engine/Awards.h"
+#include "Engine/Objects/Chest.h"
+#include "Engine/Graphics/Outdoor.h"
+#include "Engine/Game.h"
+#include "Engine/Tables/IconFrameTable.h"
+#include "Engine/Objects/Actor.h"
+
+#include "GUI\UI\UIArena.h"
+#include "Engine/Events.h"
+#include "Engine/Graphics/Level\Decoration.h"
+
+typedef struct _RGBColor
+    {
+    unsigned char R;
+    unsigned char B;
+    unsigned char G;
+    }RGBColor;
+
+
+std::array<RGBColor, 20> spell_tooltip_colors={{ 
+    {0x96, 0xD4, 0xFF},
+    {0xFF, 0x80, 0x00},
+    {0xFF, 0xFF, 0x9B},
+    {0xE1, 0xE1, 0xE1},
+    {0x80, 0x80, 0x80},
+    {0x96, 0xD4, 0xFF},
+    {0xFF, 0x55, 0x00},
+    {0x96, 0xD4, 0xFF},
+    {0xFF, 0x55, 0x00},
+    {0xE1, 0xE1, 0xE1},
+    {0xFF, 0x55, 0x00},
+    {0x96, 0xD4, 0xFF},
+    {0xEB, 0x0F, 0xFF},
+    {0xFF, 0x80, 0x00},
+    {0x96, 0xD4, 0xFF},
+    {0x80, 0x80, 0x80},
+    {0xFF, 0x55, 0x00},
+    {0x00, 0x80, 0xFF},
+    {0x00, 0x80, 0xFF},
+    {0x96, 0xD4, 0xFF}}};
+
+
+int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[1]; // idb
+struct GUIWindow *pWindow_MMT_MainMenu;
+struct GUIWindow *pWindow_MainMenu;
+std::array<struct GUIWindow, 20> pWindowList;
+
+struct GUIMessageQueue *pMessageQueue_50CBD0 = new GUIMessageQueue;
+struct GUIMessageQueue *pMessageQueue_50C9E8 = new GUIMessageQueue;
+
+
+
+
+
+
+// inlined
+//----- (mm6c::00420520) --------------------------------------------------
+void GUIMessageQueue::Flush()
+{
+  if (uNumMessages)
+    uNumMessages = pMessages[0].field_8 != 0;
+}
+
+//----- (004356B9) --------------------------------------------------------
+void GUIMessageQueue::PopMessage(enum UIMessageType *pType, int *pParam, int *a4)
+{
+  if ( this->uNumMessages )
+  {
+    *pType = this->pMessages[0].eType;
+    *pParam = this->pMessages[0].param;
+    *a4 = this->pMessages[0].field_8;
+    if ( (signed int)(this->uNumMessages - 1) > 0 )
+    {
+      for ( uint i = 0; i < (signed int)(this->uNumMessages - 1); ++i )
+      {
+        this->pMessages[i].eType = this->pMessages[i + 1].eType;
+        this->pMessages[i].param = this->pMessages[i + 1].param;
+        this->pMessages[i].field_8 = this->pMessages[i + 1].field_8;
+      }
+    }
+    --this->uNumMessages;
+  }
+}
+
+//----- (0041B4E1) --------------------------------------------------------
+int __fastcall 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
+  GUIButton *l; // ecx@8
+  unsigned __int8 v9; // [sp+4h] [bp-8h]@1
+  char old_hot_key; // [sp+8h] [bp-4h]@1
+
+  //v3 = uNewHotkey;
+  old_hot_key = toupper(uOldHotkey);
+  result = toupper(uNewHotkey);
+  v9 = result;
+  if ( bFirstCall )
+  {
+    for ( i = uNumVisibleWindows; i >= 0; --i )
+    {
+      result = 84 * pVisibleWindowsIdxs[i];
+      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 )
+    {
+      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) --------------------------------------------------------
+GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey)
+{
+  char Hot_key_num; // al@1
+  GUIWindow *current_window; // ecx@2
+  GUIButton *result; // eax@2
+
+  Hot_key_num = toupper(uHotkey);
+  for( int i = uNumVisibleWindows; i >= 0 && pVisibleWindowsIdxs[i] > 0; i-- )
+  {
+	current_window = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+	for ( result = current_window->pControlsHead; result; result = result->pNext )
+	{
+	  if ( result->uHotkey == Hot_key_num )
+	  {
+		pMessageQueue_50CBD0->AddGUIMessage(result->msg, result->msg_param, 0);
+		return result;
+	  }
+	}
+	if ( !current_window->uFrameX && !current_window->uFrameY
+		&& (current_window->uFrameWidth == window->GetWidth() && current_window->uFrameHeight == window->GetWidth()) )
+	  break;
+  }
+  return 0;
+}
+// 5075E0: using guessed type int pVisibleWindowsIdxs[20];
+
+//----- (0041D73D) --------------------------------------------------------
+void GUIWindow::_41D73D_draw_buff_tooltip()
+{
+  __int64 remaing_time; // ST28_8@11
+  unsigned short text_color;
+  int Y_pos; // esi@11
+  int string_count; // [sp+20h] [bp-4h]@7
+
+  string_count = 0;
+  for (int i=0; i<20; ++i)
+    if ( pParty->pPartyBuffs[i].uExpireTime > 0i64 )
+      ++string_count;
+
+  uFrameHeight = pFontArrus->uFontHeight + 72;
+  uFrameHeight += (string_count - 1) * pFontArrus->uFontHeight;
+  uFrameZ = uFrameWidth + uFrameX - 1;
+  uFrameW = uFrameY + uFrameHeight - 1;
+  DrawMessageBox(0);
+  DrawTitleText(pFontArrus, 0, 12, 0, pGlobalTXT_LocalizationStrings[451], 3);
+  if ( !string_count )
+     DrawTitleText(pFontComic, 0, 40, 0, pGlobalTXT_LocalizationStrings[153], 3);
+
+  GetTickCount();
+  string_count = 0;
+  for (int i=0; i<20; ++i)
+  {
+    if ( pParty->pPartyBuffs[i].uExpireTime>0i64 )//!!!
+    {
+      remaing_time = pParty->pPartyBuffs[i].uExpireTime- pParty->uTimePlayed;//!!!
+      Y_pos = string_count * pFontComic->uFontHeight + 40; 
+      text_color = Color16(spell_tooltip_colors[i].R, spell_tooltip_colors[i].G, spell_tooltip_colors[i].B);
+      DrawText(pFontComic, 52, Y_pos, text_color, aSpellNames[i], 0, 0, 0);
+      DrawBuff_remaining_time_string(Y_pos, this, remaing_time, pFontComic); 
+      ++string_count;
+    }
+  }
+}
+
+
+//----- (0041D08F) --------------------------------------------------------
+void GUIWindow::_41D08F_set_keyboard_control_group(int num_buttons, int a3, int a4, int a5)
+{
+  if (num_buttons)
+  {
+    this->pNumPresenceButton = num_buttons;
+    this->field_30 = a3;
+    this->field_34 = a4;
+    this->pCurrentPosActiveItem = a5;
+    this->pStartingPosActiveItem = a5;
+    this->receives_keyboard_input = true;
+  }
+  else
+  {
+    this->pNumPresenceButton = 0;
+    this->field_30 = a3;
+    this->field_34 = a4;
+    this->pCurrentPosActiveItem = 0;
+    this->pStartingPosActiveItem = 0;
+    this->receives_keyboard_input = false;
+  }
+}
+
+
+//----- (0041C26A) --------------------------------------------------------
+void GUIWindow::Release()
+{
+  //GUIWindow *v1; // esi@1
+  int i; // edi@20
+  //GUIButton *v8; // eax@26
+  GUIButton *pNextBtn; // edi@27
+  //int v10; // esi@28
+  //int v11; // ecx@28
+  int v12; // edx@29
+
+  //v1 = this;
+  if ( !this )
+    return;
+  
+  switch( this->eWindowType )
+  {
+	case WINDOW_GreetingNPC:
+		{
+		pIcons_LOD->SyncLoadedFilesCount();
+		pCurrentScreen = pMainScreenNum;
+		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);
+          pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY;
+		}
+		pParty->uFlags |= 2u;
+		break;
+		}
+	case WINDOW_Transition:
+		{
+		//pVideoPlayer->Unload();
+		pTexture_outside->Release();
+		pTexture_Dialogue_Background->Release();
+		pIcons_LOD->SyncLoadedFilesCount();
+		pCurrentScreen = pMainScreenNum;
+		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();
+        pCurrentScreen = pMainScreenNum;
+        break;
+		}
+	case WINDOW_Dialogue:
+		{
+        if ( !dword_591084 )
+	        pDialogueNPCPortraits[0]->Release();
+        uNumDialogueNPCPortraits = 0;
+        pTexture_Dialogue_Background->Release();
+
+        pIcons_LOD->SyncLoadedFilesCount();
+        pCurrentScreen = pMainScreenNum;
+        break;
+		}
+  case WINDOW_null:
+    return;
+	default:
+		break;
+  }
+  //v8 = this->pControlsHead;
+  if ( this->pControlsHead )
+  {
+    do
+    {
+      pNextBtn = this->pControlsHead->pNext;
+      free(this->pControlsHead);
+      this->pControlsHead = pNextBtn;
+    }
+    while ( pNextBtn );
+  }
+  this->pControlsHead = 0;
+  this->pControlsTail = 0;
+  this->uNumControls = 0;
+  this->eWindowType = WINDOW_null;
+  while ( this->numVisibleWindows < uNumVisibleWindows )
+  {
+    v12 = pVisibleWindowsIdxs[this->numVisibleWindows + 1];
+    pVisibleWindowsIdxs[this->numVisibleWindows] = v12;
+    --pWindowList[v12 - 1].numVisibleWindows;
+    ++this->numVisibleWindows;
+  }
+  pVisibleWindowsIdxs[uNumVisibleWindows] = 0;
+  uNumVisibleWindows = uNumVisibleWindows - 1;
+}
+
+//----- (0041CD3B) --------------------------------------------------------
+GUIButton *GUIWindow::GetControl(unsigned int uID)
+{
+  GUIButton *result; // eax@1
+
+  result = this->pControlsHead;
+  for ( uID; uID; --uID )
+    result = result->pNext;
+  return result;
+}
+
+//----- (00411BFC) --------------------------------------------------------
+void GUIWindow::InitializeBookView()
+{
+  char *pString; // eax@12
+  int pTextHeight; // eax@12
+  //__int64 page_count; // qax@12
+  unsigned int page_count; // esi@12
+  unsigned __int16 v18; // ax@38
+  signed int max_beacons; // [sp+10h] [bp-5Ch]@38
+  GUIWindow journal_window; // [sp+18h] [bp-54h]@8
+
+  pAudioPlayer->StopChannels(-1, -1);
+  InitializeBookFonts();
+  this->CreateButton(475, 445, 158, 34, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0); // Close
+  pCurrentScreen = SCREEN_BOOKS;
+  full_num_items_in_book = 0;
+  books_primary_item_per_page = 0;
+  books_page_number = 0;
+  num_achieved_awards = 0; 
+  switch (this->par1C)
+  {
+    case WINDOW_LloydsBeacon:
+    {
+      byte_506360 = 0;
+      pTexture_CurrentBook = pIcons_LOD->LoadTexturePtr("lb_bordr", TEXTURE_16BIT_PALETTE);
+      pTexture_LloydBeacons[0] = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
+      pTexture_LloydBeacons[1] = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
+
+      pBtn_Book_1 = this->CreateButton(415, 13, 39, 36, 1, 0, UIMSG_LloydsBeacon_FlippingBtn, 0, 0, pGlobalTXT_LocalizationStrings[375], 0); // Set Beacon
+      pBtn_Book_2 = this->CreateButton(415, 48, 39, 36, 1, 0, UIMSG_LloydsBeacon_FlippingBtn, 1, 0, pGlobalTXT_LocalizationStrings[523], 0); // Recall Beacon
+
+      max_beacons = 1;
+      v18 = pParty->pPlayers[_506348_current_lloyd_playerid].pActiveSkills[PLAYER_SKILL_WATER];
+      if ( v18 & 0x100 || (v18 & 0x80) )
+          max_beacons = 5;
+      else if ( v18 & 0x40 )
+          max_beacons = 3;
+
+      for ( int i = 0; i < max_beacons; ++i )
+            CreateButton(pLloydsBeaconsPreviewXs[i], pLloydsBeaconsPreviewYs[i],
+                           92, 68, 1, 180, UIMSG_InstallBeacon, i, 0, "", 0);
+
+      for ( int i = 0; i < 5; ++i )
+      {
+        if (pParty->pPlayers[_506348_current_lloyd_playerid].pInstalledBeacons[i].uBeaconTime  >= (signed __int64)pParty->uTimePlayed)
+            LoadThumbnailLloydTexture(i, _506348_current_lloyd_playerid + 1);
+        else 
+          memset(&pParty->pPlayers[_506348_current_lloyd_playerid].pInstalledBeacons[i], 0, sizeof(LloydBeacon));
+      }
+    }
+    break;
+
+    case WINDOW_TownPortal:
+    {
+      pTexture_CurrentBook        = pIcons_LOD->LoadTexturePtr("townport", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[0] = pIcons_LOD->LoadTexturePtr("tpharmndy", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[1] = pIcons_LOD->LoadTexturePtr("tpelf", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[2] = pIcons_LOD->LoadTexturePtr("tpwarlock", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[3] = pIcons_LOD->LoadTexturePtr("tpisland", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[4] = pIcons_LOD->LoadTexturePtr("tpheaven", TEXTURE_16BIT_PALETTE);
+      pTexture_TownPortalIcons[5] = pIcons_LOD->LoadTexturePtr("tphell", TEXTURE_16BIT_PALETTE);
+      
+      static int pTownPortalBook_ws[6] = { 80,  66,  68,  72,  67,  74};
+      static int pTownPortalBook_hs[6] = { 55,  56,  65,  67,  67,  59};
+      for ( uint i = 0; i < 6; ++i )
+        this->CreateButton(pTownPortalBook_xs[i], pTownPortalBook_ys[i], pTownPortalBook_ws[i], pTownPortalBook_hs[i], 1, 182, UIMSG_ClickTownInTP, i, 0, "", nullptr);
+      
+    }
+    break;
+
+  case WINDOW_QuestBook:
+  {
+      pTexture_CurrentBook    = pIcons_LOD->LoadTexturePtr("sbquiknot", TEXTURE_16BIT_PALETTE);
+      pSpellBookPagesTextr_10 = pIcons_LOD->LoadTexturePtr( "divbar", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_on = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_on = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
+      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398,         pViewport->uViewportTL_Y + 1,
+                                     pTex_book_button1_on->uTextureWidth, pTex_book_button1_on->uTextureHeight,
+                                     1, 0, UIMSG_ClickBooksBtn, 0xBu, 0, pGlobalTXT_LocalizationStrings[192],// "Scroll Up"
+                                     pTex_book_button1_on, 0);
+      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398,          pViewport->uViewportTL_Y + 38,
+                                     pTex_book_button2_on->uTextureHeight, pTex_book_button2_on->uTextureHeight,
+                                     1, 0, UIMSG_ClickBooksBtn, 0xAu, 0, pGlobalTXT_LocalizationStrings[193],// "Scroll Down"
+                                     pTex_book_button2_on, 0);
+      num_achieved_awards = 0;
+      memset(achieved_awards.data(), 0, 4000);
+      for ( uint i = books_primary_item_per_page; i < 512; ++i )
+      {
+        if ( _449B57_test_bit(pParty->_quest_bits, i) && pQuestTable[i] )
+        {
+          achieved_awards[num_achieved_awards] = (AwardType)i;
+          ++num_achieved_awards;
+        }
+      }
+      full_num_items_in_book = num_achieved_awards;
+      num_achieved_awards = 0;
+    }
+    break;
+
+    case WINDOW_AutonotesBook:
+    {
+      pTexture_AutonotesBook   = pIcons_LOD->LoadTexturePtr("sbautnot", TEXTURE_16BIT_PALETTE);
+      pSpellBookPagesTextr_10  = pIcons_LOD->LoadTexturePtr("divbar", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button3_on = pIcons_LOD->LoadTexturePtr("tab-an-1b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button3_off = pIcons_LOD->LoadTexturePtr("tab-an-1a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button4_on = pIcons_LOD->LoadTexturePtr("tab-an-2b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button4_off = pIcons_LOD->LoadTexturePtr("tab-an-2a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button5_on = pIcons_LOD->LoadTexturePtr("tab-an-3b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button5_off = pIcons_LOD->LoadTexturePtr("tab-an-3a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button6_on = pIcons_LOD->LoadTexturePtr("tab-an-5b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button6_off = pIcons_LOD->LoadTexturePtr("tab-an-5a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button7_on = pIcons_LOD->LoadTexturePtr("tab-an-4b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button7_off = pIcons_LOD->LoadTexturePtr("tab-an-4a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button8_on = pIcons_LOD->LoadTexturePtr("tab-an-8b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button8_off = pIcons_LOD->LoadTexturePtr("tab-an-8a", TEXTURE_16BIT_PALETTE);
+
+      pBtn_Book_1                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,   50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn, 11, 0, pGlobalTXT_LocalizationStrings[193], pTex_book_button1_on, 0);
+      pBtn_Book_2                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38,  50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn, 10, 0, pGlobalTXT_LocalizationStrings[192], pTex_book_button2_on, 0);
+      pBtn_Book_3                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 113, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  2, 0, pGlobalTXT_LocalizationStrings[85], pTex_book_button3_on, 0); // "Potion Notes"
+      pBtn_Book_4                = this->CreateButton(pViewport->uViewportTL_X + 399, pViewport->uViewportTL_Y + 150, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  3, 0, pGlobalTXT_LocalizationStrings[137], pTex_book_button4_on, 0); // "Fountain Notes"
+      pBtn_Book_5                = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  4, 0, pGlobalTXT_LocalizationStrings[8], pTex_book_button5_on, 0); // "Obelisk Notes"
+      pBtn_Book_6                = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  5, 0, pGlobalTXT_LocalizationStrings[141], pTex_book_button6_on, 0); // "Seer Notes"
+      pBtn_Autonotes_Misc        = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 264, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  6, 0, pGlobalTXT_LocalizationStrings[123], pTex_book_button7_on, 0); // "Miscellaneous Notes"
+      pBtn_Autonotes_Instructors = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 302, 50, 34, 1, 0, 
+                                                    UIMSG_ClickBooksBtn,  7, 0, pGlobalTXT_LocalizationStrings[662], pTex_book_button8_on, 0); // "Instructors"
+
+      num_achieved_awards = 0;
+      for ( uint i = books_primary_item_per_page; i < 196; ++i )
+      {
+        if ( _506568_autonote_type == pAutonoteTxt[i].eType)//dword_72371C[2 * v10] )
+        {
+          if ( i )
+          {
+            if ( _449B57_test_bit(pParty->_autonote_bits, i) && pAutonoteTxt[i].pText )
+            {
+              achieved_awards[num_achieved_awards] = (AwardType)i;
+              ++num_achieved_awards;
+            }
+          }
+        }
+      }
+      full_num_items_in_book = num_achieved_awards;
+      num_achieved_awards = 0;
+    }
+    break;
+
+    case WINDOW_MapsBook:
+    {
+      dword_506364 = 1;
+      pSpellBookPagesTextr_12  = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("zoom-on", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("zoot-on", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("zoom-off", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("zoot-off", TEXTURE_16BIT_PALETTE);
+      pTex_book_button3_on = pIcons_LOD->LoadTexturePtr("tabNon", TEXTURE_16BIT_PALETTE);
+      pTex_book_button3_off = pIcons_LOD->LoadTexturePtr("tabNoff", TEXTURE_16BIT_PALETTE);
+      pTex_book_button4_on = pIcons_LOD->LoadTexturePtr("tabSon", TEXTURE_16BIT_PALETTE);
+      pTex_book_button4_off = pIcons_LOD->LoadTexturePtr("tabSoff", TEXTURE_16BIT_PALETTE);
+      pTex_book_button5_on = pIcons_LOD->LoadTexturePtr("tabEon", TEXTURE_16BIT_PALETTE);
+      pTex_book_button5_off = pIcons_LOD->LoadTexturePtr("tabEoff", TEXTURE_16BIT_PALETTE);
+      pTex_book_button6_on = pIcons_LOD->LoadTexturePtr("tabWon", TEXTURE_16BIT_PALETTE);
+      pTex_book_button6_off = pIcons_LOD->LoadTexturePtr("tabWoff", TEXTURE_16BIT_PALETTE);
+
+      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,   50, 34, 1, 0, 
+                                     UIMSG_ClickBooksBtn, 0, 0, pGlobalTXT_LocalizationStrings[251], pTex_book_button1_on, 0);// "Zoom In"
+      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38,  50, 34, 1, 0, 
+                                     UIMSG_ClickBooksBtn, 1, 0, pGlobalTXT_LocalizationStrings[252], pTex_book_button2_on, 0);// "Zoom Out"
+      pBtn_Book_3 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 113, 50, 34, 1, 0, 
+                                     UIMSG_ClickBooksBtn, 2, 0, pGlobalTXT_LocalizationStrings[192], (Texture *)"", 0);// Scroll Up
+      pBtn_Book_4 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 150, 50, 34, 1, 0, 
+                                     UIMSG_ClickBooksBtn, 3, 0, pGlobalTXT_LocalizationStrings[193], (Texture *)"", 0);// Scroll Down
+      pBtn_Book_5 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 50, 34, 1, 0, 
+                                     UIMSG_ClickBooksBtn, 4, 0, pGlobalTXT_LocalizationStrings[573], (Texture *)"", 0);// "Scroll Right"
+      pBtn_Book_6 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 50, 34, 1, 0, 
+                                      UIMSG_ClickBooksBtn, 5, 0, pGlobalTXT_LocalizationStrings[572], (Texture *)"", 0);// "Scroll Left"
+    }
+    break;
+
+    case WINDOW_CalendarBook:
+    {
+      pSpellBookPagesTextr_13 = pIcons_LOD->LoadTexturePtr("sbdate-time", TEXTURE_16BIT_PALETTE);
+      pTex_moon_new = pIcons_LOD->LoadTexturePtr("moon_new", TEXTURE_16BIT_PALETTE);
+      pTex_moon_4   = pIcons_LOD->LoadTexturePtr("moon_4", TEXTURE_16BIT_PALETTE);
+      pTex_moon_2   = pIcons_LOD->LoadTexturePtr("moon_2", TEXTURE_16BIT_PALETTE);
+      pTex_moon_2_2 = pIcons_LOD->LoadTexturePtr("moon_2", TEXTURE_16BIT_PALETTE);
+      pTex_moon_ful = pIcons_LOD->LoadTexturePtr("moon_ful", TEXTURE_16BIT_PALETTE);
+    }
+    break;
+
+    case WINDOW_JournalBook:
+    {
+      pSpellBookPagesTextr_11  = pIcons_LOD->LoadTexturePtr("sbplayrnot", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
+      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
+      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
+
+      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,  
+                      pTex_book_button1_on->uTextureWidth,  pTex_book_button1_on->uTextureHeight, 1, 0, 
+                      UIMSG_ClickBooksBtn, 11, 0, pGlobalTXT_LocalizationStrings[192], pTex_book_button1_on, 0);
+      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, pTex_book_button2_on->uTextureHeight,
+                                      pTex_book_button2_on->uTextureHeight, 1, 0, UIMSG_ClickBooksBtn, 10, 0, 
+                                      pGlobalTXT_LocalizationStrings[193], pTex_book_button2_on, 0);
+
+      num_achieved_awards = 0;
+      journal_window.uFrameX = 48;
+      journal_window.uFrameY = 70;
+      journal_window.uFrameWidth = 360;
+      journal_window.uFrameHeight = 264;
+      journal_window.uFrameZ = 407;
+      journal_window.uFrameHeight = (LOBYTE(pAutonoteFont->uFontHeight) - 3) * 264 / LOBYTE(pAutonoteFont->uFontHeight) - 3;
+      journal_window.uFrameW = journal_window.uFrameHeight + 69;
+      memset(&achieved_awards, 0, 4000);
+      memset(Journal_limitation_factor.data(), 0, 100);
+      if ( books_primary_item_per_page < 29 )
+      {
+        for ( int i = books_primary_item_per_page; i < books_primary_item_per_page + 29; i++ )
+        {
+          if ( pParty->PartyTimes.HistoryEventTimes[i] > 0 )
+          {
+            if ( pStorylineText->StoreLine[i + 1].pText )
+            {
+              pString = BuildDialogueString(pStorylineText->StoreLine[i + 1].pText, uActiveCharacter - 1, 0, 0, 0, &pParty->PartyTimes.HistoryEventTimes[i]);
+              pTextHeight = pAutonoteFont->CalcTextHeight(pString, &journal_window, 1, 0);
+              page_count = ((pTextHeight - (pAutonoteFont->uFontHeight - 3)) / (signed int)journal_window.uFrameHeight) + 1;
+              memset32((char *)&achieved_awards[num_achieved_awards] , i + 1, page_count);
+              for ( uint j = 0; j <= page_count - 1; ++j )
+                Journal_limitation_factor[num_achieved_awards++] = j;
+            }
+          }
+        }
+      }
+      full_num_items_in_book = num_achieved_awards;
+      num_achieved_awards = 0;
+    }
+    break;
+  }
+}
+
+//----- (00415551) --------------------------------------------------------
+void GUIWindow::DrawMessageBox(int arg0)
+{
+  unsigned int v2; // edi@1
+  signed int v4; // esi@2
+  unsigned int v5; // eax@2
+  unsigned int v16; // esi@19
+  GUIWindow current_window; // [sp+Ch] [bp-60h]@18
+  POINT cursor; // [sp+60h] [bp-Ch]@8
+  unsigned int v22; // [sp+74h] [bp+8h]@2
+
+  v2 = 0;
+  if ( arg0 )
+  {
+    v4 = pViewport->uViewportTL_X;
+    v5 = pViewport->uViewportBR_X;
+    v2 = pViewport->uViewportTL_Y;
+    v22 = pViewport->uViewportBR_Y;
+  }
+  else
+  {
+    v4 = 0;
+    v5 = window->GetWidth();
+    v22 = window->GetHeight();
+  }
+  pMouse->GetCursorPos(&cursor);
+  if ( (signed int)this->uFrameX >= v4 )
+  {
+    if ( (signed int)(this->uFrameWidth + this->uFrameX) > (signed int)v5 )
+    {
+      this->uFrameX = v5 - this->uFrameWidth;
+      this->uFrameY = cursor.y + 30;
+    }
+  }
+  else
+  {
+    this->uFrameX = v4;
+    this->uFrameY = cursor.y + 30;
+  }
+
+  if ( (signed int)this->uFrameY >= (signed int)v2 )
+  {
+    if ( (signed int)(this->uFrameY + this->uFrameHeight) > (signed int)v22 )
+      this->uFrameY = cursor.y - this->uFrameHeight - 30;
+  }
+  else
+    this->uFrameY = cursor.y + 30;
+  if ( (signed int)this->uFrameY < (signed int)v2 )
+    this->uFrameY = v2;
+  if ( (signed int)this->uFrameX < v4 )
+    this->uFrameX = v4;
+  this->uFrameZ = this->uFrameWidth + this->uFrameX - 1;
+  this->uFrameW = this->uFrameHeight + this->uFrameY - 1;
+  memcpy(&current_window, this, sizeof(current_window));
+  current_window.uFrameX += 12;
+  current_window.uFrameWidth -= 24;
+  current_window.uFrameY += 12;
+  current_window.uFrameHeight -= 12;
+  current_window.uFrameZ = current_window.uFrameWidth + current_window.uFrameX - 1;
+  current_window.uFrameW = current_window.uFrameHeight + current_window.uFrameY - 1;
+  if ( this->Hint )
+    v16 = pFontLucida->CalcTextHeight(this->Hint, &current_window, 0, 0) + 24;
+  else
+    v16 = this->uFrameHeight;
+  if ( (signed int)v16 < 64 )
+    v16 = 64;
+  if ( (signed int)(v16 + this->uFrameY) > 479 )
+    v16 = 479 - this->uFrameY;
+  DrawPopupWindow(this->uFrameX, this->uFrameY, this->uFrameWidth, v16);
+  if ( this->Hint )
+    current_window.DrawTitleText(pFontLucida, 0, (signed int)(v16 - pFontLucida->CalcTextHeight(this->Hint, &current_window, 0, 0)) / 2 - 14, 0, this->Hint, 3);
+}
+
+//----- (00411B59) --------------------------------------------------------
+void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer)
+{
+  //unsigned int v2; // esi@1
+  //unsigned int v3; // edi@1
+  FILE *v4; // ebx@1
+  FILE *v5; // eax@2
+  char pContainerName[64]; // [sp+Ch] [bp-44h]@1
+  //unsigned int v7; // [sp+4Ch] [bp-4h]@1
+
+  //v2 = uSlot;
+  //v7 = uPlayer;
+  //v3 = uSlot + 1;
+  sprintf(pContainerName, "data\\lloyd%d%d.pcx", uPlayer, uSlot + 1);
+  v4 = fopen(pContainerName, "rb");
+  if ( v4 )
+  {
+    pSavegameThumbnails[uSlot].LoadFromFILE(v4, 0, 1);
+    fclose(v4);
+  }
+  else
+  {
+    sprintf(pContainerName, "lloyd%d%d.pcx", uPlayer, uSlot + 1);
+    v5 = pNew_LOD->FindContainer(pContainerName, 1);
+    if ( v5 )
+      pSavegameThumbnails[uSlot].LoadFromFILE(v5, 0, 0);
+    else
+      *((int *)&pSavegameThumbnails.data()->pPixels + 10 * uSlot) = 0;
+  }
+}
+
+
+//----- (00411621) --------------------------------------------------------
+void GUIWindow::OpenSpellBook()
+{
+  Player *pPlayer; // edi@1
+  //GUIWindow *pWindow; // esi@1
+  //unsigned int v3; // ebp@1
+  int v4; // eax@3
+  ///GUIButton *result; // eax@25
+  int a2; // [sp+10h] [bp-8h]@1
+  //int v7; // [sp+14h] [bp-4h]@1
+
+  pPlayer = pPlayers[uActiveCharacter];
+  //pWindow = this;
+  LoadSpellbook(pPlayer->lastOpenedSpellbookPage);
+  //v3 = 0;
+  a2 = 0;
+
+  PlayerSpellbookChapter* chapter = &pPlayer->spellbook.pChapters[pPlayer->lastOpenedSpellbookPage];
+  for (uint i = 0; i < 11; ++i)
+  {
+    if (!chapter->bIsSpellAvailable[i])
+      continue;
+		v4= pPlayer->lastOpenedSpellbookPage;
+      //v4 = (12 * pPlayer->lastOpenedSpellbookPage + pSpellbookSpellIndices[pPlayer->lastOpenedSpellbookPage][i + 1]);
+      CreateButton(pViewport->uViewportTL_X +  pIconPos[v4][pSpellbookSpellIndices[v4][i+1]].Xpos,
+                   pViewport->uViewportTL_Y +  pIconPos[v4][pSpellbookSpellIndices[v4][i+1]].Ypos,  //dword_4E20D0
+                   SBPageSSpellsTextureList[i + 1]->uTextureWidth,
+                   SBPageSSpellsTextureList[i + 1]->uTextureHeight,
+                   1, 79, UIMSG_SelectSpell, i, 0, "", 0);
+      ++a2;
+    //++v3;
+  }
+  //while ( (signed int)v3 < 11 );
+
+  CreateButton(0, 0, 0, 0, 1, 0, UIMSG_SpellBook_PressTab, 0, '\t', "", 0);
+  if ( a2 )
+    _41D08F_set_keyboard_control_group(a2, 0, 0, 0);
+
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_FIRE])   CreateButton(399,  10, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 0, 0, aSpellSchoolNames[0], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_AIR])    CreateButton(399,  46, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 1, 0, aSpellSchoolNames[1], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_WATER])  CreateButton(399,  83, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 2, 0, aSpellSchoolNames[2], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_EARTH])  CreateButton(399, 121, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 3, 0, aSpellSchoolNames[3], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_SPIRIT]) CreateButton(399, 158, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 4, 0, aSpellSchoolNames[4], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_MIND])   CreateButton(400, 196, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 5, 0, aSpellSchoolNames[5], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_BODY])   CreateButton(400, 234, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 6, 0, aSpellSchoolNames[6], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_LIGHT])  CreateButton(400, 271, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 7, 0, aSpellSchoolNames[7], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_DARK])   CreateButton(400, 307, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 8, 0, aSpellSchoolNames[8], 0);
+
+                            CreateButton(476, 450, pSBClickQuickSpellBtnTextr->uTextureWidth, pSBClickQuickSpellBtnTextr->uTextureHeight, 1, 78, UIMSG_ClickInstallRemoveQuickSpellBtn, 0, 0, "", 0);
+  pBtn_InstallRemoveSpell = CreateButton(476, 450, 48, 32, 1, 78, UIMSG_ClickInstallRemoveQuickSpellBtn, 0, 0, "", pSBClickQuickSpellBtnTextr, 0);
+                            CreateButton(561, 450, pSpellBookClickCloseBtnTextr->uTextureWidth, pSpellBookClickCloseBtnTextr->uTextureHeight, 1,  0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
+  pBtn_CloseBook          = CreateButton(561, 450, 48, 32, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], pSpellBookClickCloseBtnTextr, 0);
+}
+// 50640C: using guessed type int dword_50640C[];
+
+//----- (004B3157) --------------------------------------------------------
+void GUIWindow::HouseDialogManager()
+{
+  unsigned __int16 pWhiteColor; // di@2
+  const char *pHouseName; // edx@4
+  signed int v3; // edx@5
+  char *v4; // edi@9
+  int pTextHeight; // eax@45
+  int v6; // edi@45
+  char *v7; // eax@45
+  int v8; // edi@46
+  int v9; // eax@50
+  unsigned int v10; // [sp-10h] [bp-C8h]@53
+  char *pTitleText; // [sp-8h] [bp-C0h]@50
+  GUIWindow pDialogWindow; // [sp+Ch] [bp-ACh]@4
+  GUIWindow pWindow; // [sp+60h] [bp-58h]@2
+  int pColor2; // [sp+B4h] [bp-4h]@2
+
+  if ( !window_SpeakInHouse )
+    return;
+  memcpy(&pWindow, this, sizeof(pWindow));
+  pWindow.uFrameWidth -= 18;
+  pWindow.uFrameZ -= 18;
+  pWhiteColor = Color16(0xFFu, 0xFFu, 0xFFu);
+  pColor2 = Color16(0x15u, 0x99u, 0xE9u);
+  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
+  pRenderer->DrawTextureTransparent(0x1D4u, 0, &pIcons_LOD->pTextures[uTextureID_right_panel_loop]);
+  if ( pDialogueNPCCount != uNumDialogueNPCPortraits || !uHouse_ExitPic )
+  {
+    pDialogWindow.uFrameWidth = 130;
+    pDialogWindow.uFrameHeight = 2 * LOBYTE(pFontCreate->uFontHeight);
+    pHouseName = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pName;
+    if ( pHouseName )
+    {
+      v3 = 2 * LOBYTE(pFontCreate->uFontHeight) - 6 - pFontCreate->CalcTextHeight(pHouseName, &pDialogWindow, 0, 0);
+      if ( v3 < 0 )
+        v3 = 0;
+      pWindow.DrawTitleText(pFontCreate, 0x1EAu, v3 / 2 + 4, pWhiteColor,
+        //(const char *)p2DEvents_minus1_::04[13 * (unsigned int)ptr_507BC0->ptr_1C],
+        p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pName, 3);
+    }
+  }
+  pWindow.uFrameWidth += 8;
+  pWindow.uFrameZ += 8;
+  if ( !pDialogueNPCCount )
+  {
+    if ( in_current_building_type == BuildingType_Jail )
+    {
+      JailDialog();
+      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+      {
+        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
+        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
+      }
+      else
+        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
+      return;
+    }
+    if ( current_npc_text )
+    {
+      pDialogWindow.uFrameWidth = 458;
+      pDialogWindow.uFrameZ = 457;
+      pTextHeight = pFontArrus->CalcTextHeight(current_npc_text, &pDialogWindow, 13, 0);
+      v6 = pTextHeight + 7;
+      pRenderer->GetLeather(8, 352 - (pTextHeight + 7), &pIcons_LOD->pTextures[uTextureID_Leather], 
+          pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - (pTextHeight + 7));
+      pRenderer->DrawTextureIndexed(8, 347 - v6, pTexture_591428);
+      v7 = FitTextInAWindow(current_npc_text, pFontArrus, &pDialogWindow, 0xDu, 0);
+      window_SpeakInHouse->DrawText(pFontArrus, 13, 354 - v6, 0, v7, 0, 0, 0);
+    }
+    if ( uNumDialogueNPCPortraits <= 0 )
+    {
+      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+      {
+        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
+        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
+      }
+      else
+        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
+      return;
+    }
+    for ( v8 = 0; v8 < uNumDialogueNPCPortraits; ++v8 )
+    {
+      pRenderer->DrawTextureIndexed(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v8] - 4,
+                                    pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8] - 4, &pIcons_LOD->pTextures[uTextureID_50795C]);
+      pRenderer->DrawTextureIndexed(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v8],
+                                    pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8], pDialogueNPCPortraits[v8]);
+      if ( uNumDialogueNPCPortraits < 4 )
+      {
+        if ( v8 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
+        {
+          pTitleText = pMapStats->pInfos[uHouse_ExitPic].pName;
+          v9 = 94 * v8 + 113;
+        }
+        else
+        {
+          if ( !v8 && dword_591080 )
+          {
+            pTitleText = (char *)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterTitle;
+            pWindow.DrawTitleText(pFontCreate, 0x1E3u, 113, pColor2, pTitleText, 3);
+            continue;
+          }
+          pTitleText = HouseNPCData[v8 +1 - (dword_591080 != 0)]->pName;
+          v9 = pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8] + pDialogueNPCPortraits[v8]->uTextureHeight + 2;
+        }
+        v10 = v9;
+        pWindow.DrawTitleText(pFontCreate, 483, v10, pColor2, pTitleText, 3);
+      }
+    }
+      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+      {
+        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
+        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
+      }
+      else
+        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
+      return;
+  }
+  v4 = (char *)pDialogueNPCCount - 1;
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, &pIcons_LOD->pTextures[uTextureID_50795C]);
+  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[(signed int)v4]);
+  if ( pCurrentScreen == SCREEN_E )
+  {
+    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
+    if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+    {
+      pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
+      pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
+    }
+    else
+      pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
+    return;
+  }
+  if ( v4 || !dword_591080 )//íà èçóìðóäíîì îñòðîâå çàõîäèò íà êîðàáëå ïîêà íå âûïîëíåíû êâåñòû
+    SimpleHouseDialog();
+  else
+  {
+    sprintfex( pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429],
+      p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterName,
+      p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterTitle);
+    pWindow.DrawTitleText(pFontCreate, 0x1E3u, 0x71u, pColor2, pTmpBuf.data(), 3);
+      switch ( in_current_building_type )
+      {
+        case BuildingType_WeaponShop:
+          WeaponShopDialog();
+          break;
+        case BuildingType_ArmorShop:
+          ArmorShopDialog();
+          break;
+        case BuildingType_MagicShop:
+          MagicShopDialog();
+          break;
+        case BuildingType_AlchemistShop:
+          AlchemistDialog();
+          break;
+        case BuildingType_FireGuild:
+        case BuildingType_AirGuild:
+        case BuildingType_WaterGuild:
+        case BuildingType_EarthGuild:
+        case BuildingType_SpiritGuild:
+        case BuildingType_MindGuild:
+        case BuildingType_BodyGuild:
+        case BuildingType_LightGuild:
+        case BuildingType_DarkGuild:
+          GuildDialog();
+          break;
+        case BuildingType_18:
+          __debugbreak(); //What over the dialog?
+          sub_4B6478();
+          break;
+        case BuildingType_TownHall:
+          TownHallDialog();
+          break;
+        case BuildingType_Tavern:
+          TavernDialog();
+          break;
+        case BuildingType_Bank:
+          BankDialog();
+          break;
+        case BuildingType_Temple:
+          TempleDialog();
+          break;
+        case BuildingType_Stables:
+        case BuildingType_Boats:
+          TravelByTransport();
+          break;
+        case BuildingType_Training:
+          TrainingDialog();
+          break;
+        case BuildingType_Jail:
+          JailDialog();
+          break;
+        default:
+          //__debugbreak();//New BuildingType (if enter Boat)
+          break;
+      }
+  }
+  if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
+  {
+    pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
+    pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
+  }
+  else
+    pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
+}
+
+//----- (004B1854) --------------------------------------------------------
+void GUIWindow::DrawShops_next_generation_time_string( __int64 next_generation_time )
+{
+  unsigned int full_time; // esi@1
+  signed __int64 hours; // kr00_8@1
+  const char *text; // eax@2
+  signed __int64 minutes; // [sp+Ch] [bp-10h]@1
+  signed __int64 seconds; // [sp+14h] [bp-8h]@1
+  unsigned int days; // [sp+20h] [bp+4h]@1
+
+  full_time = (signed __int64)((double)next_generation_time * 0.234375);
+  seconds = (signed __int64)full_time % 60;
+  minutes = (signed __int64)(full_time / 60) % 60;
+  hours = ((full_time / 60) / 60) % 24;
+  days = (unsigned int)((full_time / 60) / 60) / 24;
+  strcpy(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[532]);
+  if ( days )
+  {
+    text = pGlobalTXT_LocalizationStrings[57];//Days
+    if ( days <= 1 )
+      text = pGlobalTXT_LocalizationStrings[56];//Day
+    sprintfex(pTmpBuf2.data(), "%d %s ", days, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( hours )
+  {
+    if ( hours <= 1 )
+      text = pGlobalTXT_LocalizationStrings[109];//Hour
+    else
+      text = pGlobalTXT_LocalizationStrings[110];//Hours
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)hours, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( minutes && !days )
+  {
+    if ( minutes <= 1 )
+      text = pGlobalTXT_LocalizationStrings[437];//"Minute"
+    else
+      text = pGlobalTXT_LocalizationStrings[436]; //"Minutes"
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)minutes, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( seconds && !hours )
+  {
+    if ( seconds <= 1 )
+      text = pGlobalTXT_LocalizationStrings[439]; //"Second"	
+    else
+      text = pGlobalTXT_LocalizationStrings[438]; //"Seconds"
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)seconds, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  this->DrawTitleText(pFontArrus, 0, (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), this, 0, 0)) / 2 + 101, Color16(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
+}
+
+//----- (0044D406) --------------------------------------------------------
+void GUIWindow::DrawTitleText( GUIFont *a2, signed int uHorizontalMargin, unsigned int uVerticalMargin, unsigned __int16 uDefaultColor, 
+                               const char *pInString, unsigned int uLineSpacing )
+{
+  //GUIWindow *pWindow; // esi@1
+  unsigned int v8; // ebx@1
+  char *v9; // eax@1
+  unsigned int v11; // edi@1
+  signed int v12; // esi@1
+  int v13; // eax@2
+  GUIFont *pFont; // [sp+Ch] [bp-4h]@1
+  const char *Stra; // [sp+24h] [bp+14h]@5
+
+  //pWindow = this;
+  pFont = a2;
+  v8 = this->uFrameWidth - uHorizontalMargin;
+  ui_current_text_color = uDefaultColor;
+  v9 = FitTextInAWindow(pInString, a2, this, uHorizontalMargin, 0);
+  Stra = strtok(v9, "\n");
+  v11 = uHorizontalMargin + this->uFrameX;
+  v12 = uVerticalMargin + this->uFrameY;
+  while ( 1 )
+  {
+    if ( !Stra )
+      break;
+    v13 = (signed int)(v8 - pFont->GetLineWidth(Stra)) >> 1;
+    if ( v13 < 0 )
+      v13 = 0;
+    pFont->DrawTextLine(uDefaultColor, v11 + v13, v12, Stra, window->GetWidth());
+    v12 += pFont->uFontHeight - uLineSpacing;
+    Stra = strtok(0, "\n");
+  }
+}
+// 5C6DB4: using guessed type int ui_current_text_color;
+
+//----- (0044CE08) --------------------------------------------------------
+void GUIWindow::DrawText( GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, signed int uFontShadowColor )
+    {
+  GUIWindow *v9; // edi@1
+  GUIFont *v10; // ebx@1
+  int v11; // eax@2
+  signed int v12; // esi@9
+  signed int v13; // edi@9
+  int v14; // edx@9
+  int v15; // eax@25
+  unsigned int v16; // ecx@25
+  int v17; // eax@27
+  int v18; // edi@32
+  int v19; // esi@38
+  std::string v21; // [sp-18h] [bp-50h]@2
+//  const char *v22; // [sp-8h] [bp-40h]@2
+//  int v23; // [sp-4h] [bp-3Ch]@2
+  char Dest[6]; // [sp+Ch] [bp-2Ch]@32
+  //char v25; // [sp+Fh] [bp-29h]@32
+  //char v26; // [sp+11h] [bp-27h]@34
+  const char *v27; // [sp+20h] [bp-18h]@25
+  int v28; // [sp+24h] [bp-14h]@25
+  int v29; // [sp+28h] [bp-10h]@1
+  size_t v30; // [sp+2Ch] [bp-Ch]@4
+  GUIWindow *v31; // [sp+30h] [bp-8h]@1
+  const char *v32; // [sp+34h] [bp-4h]@7
+  size_t pInString; // [sp+4Ch] [bp+14h]@11
+  
+  GUIWindow* a1 = this;
+  v29 = 0;
+  v9 = a1;
+  v10 = a2;
+  v31 = a1;
+  if ( !Str )
+  {
+    MessageBoxW(nullptr, L"Invalid string passed!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:859", 0);
+    return;
+  }
+  v11 = strcmp(Str, "null");
+  if ( v11 )
+  {
+    v30 = strlen(Str);
+    LOBYTE(v11) = 0;
+    if ( !uX )
+      uX = 12;
+    if ( a8 )
+      v32 = Str;
+    else
+    {
+      v11 = (int)FitTextInAWindow(Str, v10, v9, uX, 0);
+      v32 = (const char *)v11;
+    }
+    v12 = uX + v9->uFrameX;
+    v13 = uY + v9->uFrameY;
+    v14 = 0;
+    if ( !a8 || (v11 = v13 + LOBYTE(v10->uFontHeight), v11 <= a8) )
+    {
+      pInString = 0;
+      if ( (signed int)v30 > 0 )
+      {
+        do
+        {
+          LOBYTE(v11) = v32[v14];
+          if ( (unsigned __int8)v11 >= v10->cFirstChar && (unsigned __int8)v11 <= v10->cLastChar
+            || (char)v11 == 12
+            || (char)v11 == 13
+            || (char)v11 == 9
+            || (char)v11 == 10 )
+          {
+            switch ( (unsigned __int8)v11 )
+            {
+              case 9u:
+                strncpy(Dest, &v32[v14 + 1], 3);
+                Dest[3] = 0;
+                pInString += 3;
+                v29 = atoi(Dest);
+                v19 = atoi(Dest);
+                LOBYTE(v11) = (char)v31;
+                v12 = uX + v31->uFrameX + v19;
+                break;
+              case 0xAu:
+                v11 = LOBYTE(v10->uFontHeight);
+                uY = uY + v11 - 3;
+                v13 = uY + v31->uFrameY;
+                v12 = uX + v29 + v31->uFrameX;
+                if ( a8 )
+                {
+                  v11 = v11 + v13 - 3;
+                  if ( v11 > a8 )
+                    return;
+                }
+                break;
+              case 0xCu:
+                strncpy(Dest, &v32[v14 + 1], 5);
+                Dest[5] = 0;
+                v11 = atoi(Dest);
+                pInString += 5;
+                uFontColor = v11;
+                break;
+              case 0xDu:
+                strncpy(Dest, &v32[v14 + 1], 3);
+                Dest[3] = 0;
+                pInString += 3;
+                v18 = atoi(Dest);
+                v11 = v10->GetLineWidth(&v32[pInString]);
+                v12 = v31->uFrameZ - v11 - v18;
+                v13 = uY + v31->uFrameY;
+                if ( a8 )
+                {
+                  v11 = LOBYTE(v10->uFontHeight);
+                  v11 = v11 + v13 - 3;
+                  if ( v11 > a8 )
+                    return;
+                  break;
+                }
+                break;
+              default:
+                if ( (char)v11 == 34 && v32[v14 + 1] == 34 )
+                {
+                  ++v14;
+                  pInString = v14;
+                }
+                v27 = &v32[v14];
+                v15 = (unsigned __int8)v32[v14];
+                v16 = *((int *)&v10->cFirstChar + 3 * v15 + 9);
+                v28 = *((int *)&v10->cFirstChar + 3 * v15 + 9);
+                if ( v14 > 0 )
+                  v12 += v10->pMetrics[v15].uLeftSpacing;
+                v17 = (int)((char *)&v10[1] + v10->font_pixels_offset[v15]);
+                if ( (short)uFontColor )
+                  pRenderer->DrawText(v12, v13, (unsigned __int8 *)v17, v16, LOBYTE(v10->uFontHeight),
+                    v10->pFontPalettes[0], uFontColor, uFontShadowColor);
+                else
+                  pRenderer->DrawTextPalette(v12, v13, (unsigned char*)v17, v16, LOBYTE(v10->uFontHeight),
+                    v10->pFontPalettes[0], a7);
+                LOBYTE(v11) = v30;
+                v12 += v28;
+                if ( (signed int)pInString < (signed int)v30 )
+                {
+                  LOBYTE(v11) = 3 * *v27;
+                  v12 += v10->pMetrics[(unsigned __int8)*v27].uRightSpacing;
+                }
+                break;
+            }
+          }
+          v14 = pInString++ + 1;
+        }
+        while ( (signed int)pInString < (signed int)v30 );
+      }
+    }
+  }
+  return;
+}
+
+
+//----- (0044CB4F) --------------------------------------------------------
+int GUIWindow::DrawTextInRect( GUIFont *pFont, unsigned int uX, unsigned int uY, unsigned int uColor, const char *text, int rect_width, int reverse_text )
+{
+  int pLineWidth; // ebx@1
+  int text_width; // esi@3
+  unsigned __int8 v12; // cl@7
+  signed int v13; // esi@19
+  signed int v14; // ebx@19
+  unsigned __int8 v15; // cl@21
+//  int v16; // eax@22
+//  int v17; // ecx@22
+//  int v18; // ecx@23
+//  int v19; // ecx@24
+  unsigned int v20; // ecx@26
+  unsigned char* v21; // eax@28
+//  int v22; // ebx@34
+  int v23; // eax@34
+  int v24; // ebx@36
+  char Str[6]; // [sp+Ch] [bp-20h]@34
+//  char v26; // [sp+Fh] [bp-1Dh]@34
+//  char v27; // [sp+11h] [bp-1Bh]@35
+  int v28; // [sp+20h] [bp-Ch]@17
+  GUIWindow *pWindow; // [sp+24h] [bp-8h]@1
+  size_t pNumLen; // [sp+28h] [bp-4h]@1
+  size_t Str1a; // [sp+40h] [bp+14h]@5
+//  size_t Str1b; // [sp+40h] [bp+14h]@19
+//  const char *Sourcea; // [sp+44h] [bp+18h]@20
+//  int v34; // [sp+48h] [bp+1Ch]@26
+  int i;
+
+
+  pWindow = this;
+  pNumLen = strlen(text);
+  pLineWidth = pFont->GetLineWidth(text);
+  if ( pLineWidth < rect_width )
+  {
+    pWindow->DrawText(pFont, uX, uY, uColor, text, 0, 0, 0);
+    return pLineWidth;
+  }
+  strcpy(pTmpBuf2.data(), text);
+  text_width = 0;
+  if ( reverse_text )
+    _strrev(pTmpBuf2.data());
+  Str1a = 0;
+  for ( i = 0; i < pNumLen; ++i )
+    {
+      if ( text_width >= rect_width )
+        break;
+      v12 = pTmpBuf2[i];
+      if ( pFont->IsCharValid(v12) )
+      {
+      switch (v12)
+          {
+      case '\t':// Horizontal tab 09
+      case '\n': //Line Feed 0A 10
+      case '\r': //Form Feed, page eject  0C 12
+          break;
+      case '\f': //Carriage Return 0D 13
+          i += 5;	  
+          break;
+      default:
+          if ( i > 0 )
+            text_width += pFont->pMetrics[v12].uLeftSpacing;
+          text_width += pFont->pMetrics[v12].uWidth;
+          if ( i < pNumLen )
+              text_width += pFont->pMetrics[v12].uRightSpacing;
+          }
+      }
+    }
+  pTmpBuf2[i - 1] = 0;
+
+
+  pNumLen = strlen(pTmpBuf2.data());
+  v28 = pFont->GetLineWidth(pTmpBuf2.data());
+  if ( reverse_text )
+    _strrev(pTmpBuf2.data());
+
+  v13 = uX + pWindow->uFrameX;
+  v14 = uY + pWindow->uFrameY;
+  for (i=0; i<pNumLen; ++i)
+  {
+      v15 = pTmpBuf2[i];
+      if ( pFont->IsCharValid(v15) )
+      {
+      switch (v12)
+          {
+      case '\t':// Horizontal tab 09
+          {
+          strncpy(Str,  &pTmpBuf2[i+1], 3);
+          Str[3] = 0;
+       //   atoi(Str);
+          i += 3;
+          break;
+          }
+      case '\n': //Line Feed 0A 10
+          {
+          v24 = pFont->uFontHeight;
+          v13 = uX;
+          uY = uY + pFont->uFontHeight - 3;
+          v14 = uY+pFont->uFontHeight - 3;
+          break;
+          }
+      case '\r': //Form Feed, page eject  0C 12
+          {
+          strncpy(Str, &pTmpBuf2[i+1], 5);
+          Str[5] = 0;
+          i += 5;
+          uColor = atoi(Str);
+          break;
+          }
+      case '\f': //Carriage Return 0D 13
+          {
+          strncpy(Str, &pTmpBuf2[i+1], 3);
+          Str[3] = 0;
+          i += 3;
+          v23 = pFont->GetLineWidth(&pTmpBuf2[i]);
+          v13 = pWindow->uFrameZ - v23 - atoi(Str);
+          v14 = uY;
+          break;
+          }
+      default:
+          v20 = pFont->pMetrics[v15].uWidth;
+          if ( i > 0 )
+              v13 += pFont->pMetrics[v15].uLeftSpacing;
+          v21 = &pFont->pFontData[pFont->font_pixels_offset[v15]];
+          if ( uColor )
+              pRenderer->DrawText(v13, v14,  v21, v20, pFont->uFontHeight, pFont->pFontPalettes[0], uColor, 0);
+          else
+              pRenderer->DrawTextPalette(v13, v14, v21, v20, pFont->uFontHeight, pFont->pFontPalettes[0], 0);
+          v13 += v20;
+          if ( i < (signed int)pNumLen )
+              v13 += pFont->pMetrics[v15].uRightSpacing;
+          }
+      }
+  }
+  return v28;
+}
+
+//----- (0041D12F) --------------------------------------------------------
+GUIButton *GUIWindow::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, Texture *pTextures, ...)
+{
+  GUIButton *pButton; // esi@1
+//  unsigned int v13; // eax@1
+//  unsigned int v14; // ebx@4
+//  unsigned int v15; // eax@4
+  unsigned int TextureNum=0; // ebx@4
+//  unsigned int v17; // eax@4
+//  Texture *v18; // eax@4
+//  Texture **v19; // ecx@5
+//  Texture **v20; // edx@5
+//  GUIButton *v21; // eax@7
+  va_list texturs_ptr;
+
+  pButton = (GUIButton *)malloc(0xBC);
+  pButton->pParent = this;
+  pButton->uWidth = uWidth;
+  pButton->uHeight = uHeight;
+  
+  if ( a6 == 2 && !uHeight )
+    pButton->uHeight = uWidth;
+
+  pButton->uButtonType = a6;
+  pButton->uX = uX + this->uFrameX;
+  pButton->uY = uY + this->uFrameY;
+  pButton->uZ = pButton->uX + uWidth - 1;
+  pButton->uW = pButton->uY + uHeight - 1;
+  pButton->field_2C_is_pushed = 0;
+  pButton->field_1C = a7;
+  pButton->msg = msg;
+  pButton->msg_param = msg_param;
+  pButton->uHotkey = uHotkey;
+  //strlen(pName);
+  strcpy(pButton->pButtonName, pName);
+  va_start(texturs_ptr, pName);
+  while  (NULL!=(pTextures=va_arg(texturs_ptr, Texture *)))
+  {
+	pButton->pTextures[TextureNum]=pTextures;
+	++TextureNum;	
+  }
+  va_end(texturs_ptr);
+  pButton->uNumTextures = TextureNum;
+  if ( this->pControlsTail )
+    this->pControlsTail->pNext = pButton;
+  else
+    this->pControlsHead = pButton;
+  pButton->pPrev = this->pControlsTail;
+  this->pControlsTail = pButton;
+  pButton->pNext = 0;
+  ++this->uNumControls;
+  return pButton;
+}
+
+//----- (00459C2B) --------------------------------------------------------
+void GUIWindow::DrawFlashingInputCursor( signed int uX, int uY, struct GUIFont *a2 )
+{
+  if ( GetTickCount() % 1000 > 500 )
+    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
+
+  for (uNextFreeWindowID = 0; uNextFreeWindowID < 20; ++uNextFreeWindowID)
+  {
+    if (pWindowList[uNextFreeWindowID].eWindowType == WINDOW_null)
+      break;
+  }
+
+  GUIWindow* pWindow = &pWindowList[uNextFreeWindowID];
+  pWindow->uFrameWidth = uWidth;
+  pWindow->uFrameHeight = uHeight;
+
+  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)
+    {
+      switch (eWindowType)
+      {
+        case WINDOW_Book: {
+          pWindow->InitializeBookView();
+          break;
+          }
+        case WINDOW_Dialogue: {
+          pMainScreenNum = pCurrentScreen;
+          pCurrentScreen = 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:
+        {
+          pMainScreenNum = pCurrentScreen;
+          pCurrentScreen = 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: {// îêíî ïðèâåòñòâèÿ ÍÏÑ
+          pMainScreenNum = pCurrentScreen;
+          pKeyActionMap->EnterText(0, 15, pWindow);
+          pCurrentScreen = SCREEN_BRANCHLESS_NPC_DIALOG;
+          break;
+            }
+
+      }
+      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)
+  {
+    pCurrentScreen = 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)
+    {
+      pMainScreenNum = pCurrentScreen;
+      pCurrentScreen = 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;
+      pCurrentScreen = SCREEN_CASTING;
+      if ( !pIcons_LOD->uNumPrevLoadedFiles )
+        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
+    }
+  }
+  return pWindow;
+}
+//----- (004B3EF0) --------------------------------------------------------
+void DrawJoinGuildWindow( int pEventCode )
+{
+  uDialogueType = 81;//enum JoinGuildDialog
+  current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
+  ContractSelectText(pEventCode);
+  pDialogueWindow->Release();
+  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 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->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
+  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
+}
+//----- (0044603D) --------------------------------------------------------
+void  DialogueEnding()
+{
+  sDialogue_SpeakingActorNPC_ID = 0;
+  pDialogueWindow->Release();
+  pDialogueWindow = 0;
+  pMiscTimer->Resume();
+  pEventTimer->Resume();
+}
+//----- (004156F0) --------------------------------------------------------
+void GUI_UpdateWindows() 
+{
+  GUIWindow *pWindow; // esi@4
+  //unsigned int pWindowType; // eax@4
+  const char *pHint; // edx@66
+//  GUIButton *pButtonPtr_1C; // ebp@79
+//  char *pHint1; // edx@80
+  int v26; // eax@98
+  unsigned int v27; // ebp@106
+  GUIWindow *pGUIWindow2; // ecx@109
+//  GUIFont *pGUIFont; // ST1C_4@115
+  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
+  //Texture *pTexture; // [sp-14h] [bp-11Ch]@17
+  //Texture *pTexture2; // [sp-14h] [bp-11Ch]@86
+  int i; // [sp+0h] [bp-108h]@3
+//  ItemGen pItemGen; // [sp+4h] [bp-104h]@98
+  GUIButton GUIButton2; // [sp+28h] [bp-E0h]@133
+  ItemGen ItemGen2; // [sp+E4h] [bp-24h]@129
+
+  if (GetCurrentMenuID() != MENU_CREATEPARTY)
+    Mouse::UI_OnKeyDown(VK_NEXT);
+
+  for ( i = 1; i <= uNumVisibleWindows; ++i )
+  {
+    pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
+    switch (pWindow->eWindowType)
+    {
+      case WINDOW_OptionsButtons:
+      {
+        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 ( pCurrentScreen == SCREEN_CHEST )
+        {
+          Chest::DrawChestUI(pWindow->par1C);
+        }
+        else if ( pCurrentScreen == 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->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
+        continue;
+      }
+      case WINDOW_ModalWindow:
+      {
+        ModalWindow_ShowHint();
+        continue;
+      }
+      case WINDOW_50:
+      {
+        v27 = Color16(255, 255, 255);
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
+        {
+          ptr_507BD0->DrawMessageBox(0);
+          ptr_507BD0->DrawText(pFontCreate, 30, 40, v27, pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
+          v31 = pFontCreate->GetLineWidth(pKeyActionMap->pPressedKeysBuffer);
+          ptr_507BD0->DrawFlashingInputCursor(v31 + 30, 40, pFontCreate);
+          continue;
+        }
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
+        {
+          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+          pMessageQueue_50CBD0->AddGUIMessage((UIMessageType)(int)ptr_507BD0->ptr_1C, 0, 0);
+          pEventTimer->Resume();
+          ptr_507BD0->Release();
+          pCurrentScreen = SCREEN_GAME;
+          viewparams->bRedrawGameUI = true;
+          continue;
+        }
+        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
+        {
+          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
+          pEventTimer->Resume();
+          ptr_507BD0->Release();
+          continue;
+        }
+      }
+      case WINDOW_59:
+      {
+        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();
+          pCurrentScreen = 0;
+          viewparams->bRedrawGameUI = true;
+          v26 = atoi(pKeyActionMap->pPressedKeysBuffer);
+          if ( v26 > 0 )
+          {
+            if ( v26 < 800 )
+            {
+              ItemGen2.uAttributes |= 1;
+              ItemGen2.uItemID = v26;
+              if ( pItemsTable->pItems[v26].uEquipType == 12 )
+              {
+                ItemGen2.uNumCharges = rand() % 6 + ItemGen2.GetDamageMod() + 1;
+                ItemGen2.uMaxCharges = LOBYTE(ItemGen2.uNumCharges);
+              }
+              else
+              {
+                if ( v26 >= 221 && v26 < 271 )
+                  ItemGen2.uEnchantmentType = rand() % 10 + 1;
+              }
+              pItemsTable->SetSpecialBonus(&ItemGen2);
+              pParty->SetHoldingItem(&ItemGen2);
+            }
+          }
+        }
+        continue;
+      }
+      case WINDOW_PressedButton2:
+      {
+        if ( pWindow->Hint != (char *)1 )
+          pAudioPlayer->PlaySound((SoundID)75, 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((SoundID)75, 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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
+        viewparams->bRedrawGameUI = 1;
+        pWindow->Release();
+        continue;
+      }
+      case WINDOW_SaveLoadBtn:
+      {
+        if (pWindow->Hint != (char *)1)
+          pAudioPlayer->PlaySound(SOUND_Button2, 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 (pCurrentScreen == 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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
+        pButton = (GUIButton *)pWindow->ptr_1C;
+        pRenderer->DrawTextureTransparent(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_Button2, 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_Button2, 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_Button2, 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();
+          pCurrentScreen = 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;
+      }
+      default:
+        continue;
+    }
+  }
+  if ( GetCurrentMenuID() == -1 )
+    GameUI_DrawFoodAndGold();
+  if ( sub_4637E0_is_there_popup_onscreen() )
+    UI_OnMouseRightClick(0);
+}
+//void LoadFonts_and_DrawCopyrightWindow()
+//{
+  //MainMenuUI_LoadFontsAndSomeStuff();
+ // DrawCopyrightWindow();
+//}
+//----- (00415485) --------------------------------------------------------
+void DrawMM7CopyrightWindow()
+{
+  GUIWindow Dst; // [sp+8h] [bp-54h]@1
+
+  memset(&Dst, 0, sizeof(Dst));
+  Dst.uFrameWidth = 624;
+  Dst.uFrameHeight = 256;
+  Dst.uFrameX = 8;
+  Dst.uFrameY = 30;                             // c 1999 The 3DO Company.
+  Dst.uFrameHeight = pFontSmallnum->CalcTextHeight(pGlobalTXT_LocalizationStrings[157], &Dst, 24, 0)
+                   + 2 * LOBYTE(pFontSmallnum->uFontHeight)
+                   + 24;
+  Dst.uFrameY = 470 - Dst.uFrameHeight;
+  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
+  Dst.uFrameW = 469;
+  //Dst.Hint = "abcagfdsgsg ljsrengvlkjesnfkjwnef";
+  Dst.DrawMessageBox(0);
+
+  Dst.uFrameWidth -= 24;
+  Dst.uFrameX += 12;
+  Dst.uFrameY += 12;
+  Dst.uFrameHeight -= 12;
+  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
+  Dst.uFrameW = Dst.uFrameY + Dst.uFrameHeight - 1;
+  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, ui_mainmenu_copyright_color, pGlobalTXT_LocalizationStrings[157], 3);
+}
+
+int modal_window_prev_screen;
+
+//----- (004141CA) --------------------------------------------------------
+void ModalWindow(const char *pStrHint, UIMessageType OnRelease_message)
+{
+  pEventTimer->Pause();
+  modal_window_prev_screen = pCurrentScreen;
+  pModalWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_ModalWindow, OnRelease_message, pStrHint);
+  pCurrentScreen = SCREEN_MODAL_WINDOW;
+}
+
+//----- (0041420D) --------------------------------------------------------
+void  ModalWindow_ShowHint()
+{
+  GUIWindow pWindow; // [sp+4h] [bp-54h]@1
+
+  sprintf(pTmpBuf2.data(), "%s\n \n%s", pModalWindow->Hint, pGlobalTXT_LocalizationStrings[61]);// Press Escape
+  pWindow.Hint = pTmpBuf2.data();
+  pWindow.uFrameWidth = 400;
+  pWindow.uFrameHeight = 100;
+  pWindow.uFrameX = 120;
+  pWindow.uFrameY = 140;
+  pWindow.uFrameZ = 519;
+  pWindow.uFrameW = 239;
+  pWindow.DrawMessageBox(0);
+}
+
+//----- (0041426F) --------------------------------------------------------
+void ModalWindow_Release()
+{
+  pMessageQueue_50CBD0->AddGUIMessage((UIMessageType)pModalWindow->par1C, 0, 0);
+
+  pModalWindow->Release();
+  pModalWindow = nullptr;
+
+  pCurrentScreen = modal_window_prev_screen;
+  pEventTimer->Resume();
+}
+
+//----- (00467FB6) --------------------------------------------------------
+void CreateScrollWindow()
+{
+  unsigned int v0; // eax@1
+  char *v1; // ST18_4@3
+  GUIWindow a1; // [sp+Ch] [bp-54h]@1
+
+  memcpy(&a1, pGUIWindow_ScrollWindow, sizeof(a1));
+  a1.Hint = 0;
+  a1.uFrameX = 1;
+  a1.uFrameY = 1;
+  a1.uFrameWidth = 468;
+  v0 = pFontSmallnum->CalcTextHeight(pScrolls[pGUIWindow_ScrollWindow->par1C], &a1, 0, 0)
+     + 2 * LOBYTE(pFontCreate->uFontHeight) + 24;
+  a1.uFrameHeight = v0;
+  if ( (signed int)(v0 + a1.uFrameY) > 479 )
+  {
+    v0 = 479 - a1.uFrameY;
+    a1.uFrameHeight = 479 - a1.uFrameY;
+  }
+  a1.uFrameZ = a1.uFrameWidth + a1.uFrameX - 1;
+  a1.uFrameW = v0 + a1.uFrameY - 1;
+  a1.DrawMessageBox(0);
+  a1.uFrameX += 12;
+  a1.uFrameWidth -= 24;
+  a1.uFrameY += 12;
+  a1.uFrameHeight -= 12;
+  a1.uFrameZ = a1.uFrameWidth + a1.uFrameX - 1;
+  a1.uFrameW = a1.uFrameHeight + a1.uFrameY - 1;
+  v1 = pItemsTable->pItems[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C + 700].pName;
+  sprintf(pTmpBuf.data(), format_4E2D80, Color16(0xFFu, 0xFFu, 0x9Bu), v1);
+  a1.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf.data(), 3);
+  a1.DrawText(pFontSmallnum, 1, LOBYTE(pFontCreate->uFontHeight) - 3, 0,
+              pScrolls[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C], 0, 0, 0);
+}
+//----- (00467F48) --------------------------------------------------------
+void CreateMsgScrollWindow( signed int mscroll_id )
+{
+  if ( !pGUIWindow_ScrollWindow && mscroll_id >= 700 )
+  {
+    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);
+    }
+  }
+}
+//----- (00467F9F) --------------------------------------------------------
+void  free_book_subwindow()
+{
+  if ( pGUIWindow_ScrollWindow )
+  {
+    pGUIWindow_ScrollWindow->Release();
+    pGUIWindow_ScrollWindow = 0;
+  }
+}
+//----- (004226EF) --------------------------------------------------------
+void SetUserInterface(PartyAlignment align, bool bReplace)
+{
+  extern void set_default_ui_skin();
+  set_default_ui_skin();
+
+  if (align == PartyAlignment_Evil)
+  {
+    if ( bReplace )
+    {
+      pTexture_RightFrame->Reload("ib-r-C.pcx");
+      pTexture_BottomFrame->Reload("ib-b-C.pcx");
+      pTexture_TopFrame->Reload("ib-t-C.pcx");
+      pTexture_LeftFrame->Reload("ib-l-C.pcx");
+      pTexture_StatusBar->Reload("IB-Foot-c.pcx");
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-C", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-c", 2);
+
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-c", 2);
+
+      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeC");
+      pIconsFrameTable->InitializeAnimation(pUIAnim_WizardEye->uIconID);
+      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchC");
+      pIconsFrameTable->InitializeAnimation(pUIAnum_Torchlight->uIconID);
+
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt-c", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top-c", 2);
+      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap-c", 2);
+    }
+    else
+    {
+      pTexture_RightFrame->Load("ib-r-C.pcx", 0);
+      pTexture_BottomFrame->Load("ib-b-c.pcx", 0);
+      pTexture_TopFrame->Load("ib-t-C.pcx", 0);
+      pTexture_LeftFrame->Load("ib-l-C.pcx", 0);
+      pTexture_StatusBar->Load("IB-Foot-c.pcx", 0);
+      uTextureID_right_panel = pIcons_LOD->LoadTexture("ib-mb-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_Minimap_Loop = pIcons_LOD->LoadTexture("ib-autmask-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_Compas = pIcons_LOD->LoadTexture("IB-COMP-C", TEXTURE_16BIT_PALETTE);
+      dword_5079D0 = pIcons_LOD->LoadTexture("IB-InitG-c", TEXTURE_16BIT_PALETTE);
+      dword_5079C8 = pIcons_LOD->LoadTexture("IB-InitY-c", TEXTURE_16BIT_PALETTE);
+      dword_5079CC = pIcons_LOD->LoadTexture("IB-InitR-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_NPCLeft = pIcons_LOD->LoadTexture("IB-NPCLD-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_NPCRight = pIcons_LOD->LoadTexture("IB-NPCRD-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_ZoomIn = pIcons_LOD->LoadTexture("ib-autout-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_ZoomOut = pIcons_LOD->LoadTexture("ib-autin-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_GameUI_CharSelectionFrame = pIcons_LOD->LoadTexture("IB-selec-C", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_CastSpell = pIcons_LOD->LoadTexture("ib-m1d-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_Rest = pIcons_LOD->LoadTexture("ib-m2d-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_QuickReference = pIcons_LOD->LoadTexture("ib-m3d-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_GameSettings = pIcons_LOD->LoadTexture("ib-m4d-c", TEXTURE_16BIT_PALETTE);
+      uExitCancelTextureId = pIcons_LOD->LoadTexture("ib-bcu-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Bless = pIcons_LOD->LoadTexture("isg-01-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Preservation = pIcons_LOD->LoadTexture("isg-02-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Hammerhands = pIcons_LOD->LoadTexture("isg-03-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_PainReflection = pIcons_LOD->LoadTexture("isg-04-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_50795C = pIcons_LOD->LoadTexture("evtnpc-c", TEXTURE_16BIT_PALETTE);
+      uTextureID_CharacterUI_InventoryBackground = pIcons_LOD->LoadTexture("fr_inven", TEXTURE_16BIT_PALETTE);
+      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeC");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
+      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchC");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
+    }
+    uGameUIFontMain = Color16(0xC8u, 0, 0);
+    uGameUIFontShadow = Color16(10, 0, 0);
+  }
+  else if (align == PartyAlignment_Neutral)
+  {
+    if ( bReplace )
+    {
+      pTexture_RightFrame->Reload("ib-r-a.pcx");
+      pTexture_BottomFrame->Reload("ib-b-a.pcx");
+      pTexture_TopFrame->Reload("ib-t-a.pcx");
+      pTexture_LeftFrame->Reload("ib-l-a.pcx");
+      pTexture_StatusBar->Reload("IB-Foot-a.pcx");
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-a", 2);
+      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeA");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
+      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchA");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-a", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top", 2);
+      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap", 2);
+    }
+    else
+    {
+      pTexture_RightFrame->Load("ib-r-A.pcx", 0);
+      pTexture_BottomFrame->Load("ib-b-A.pcx", 0);
+      pTexture_TopFrame->Load("ib-t-A.pcx", 0);
+      pTexture_LeftFrame->Load("ib-l-A.pcx", 0);
+      pTexture_StatusBar->Load("IB-Foot-a.pcx", 0);
+      uTextureID_right_panel = pIcons_LOD->LoadTexture("ib-mb-A", TEXTURE_16BIT_PALETTE);
+      uTextureID_Minimap_Loop = pIcons_LOD->LoadTexture("ib-autmask-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Compas = pIcons_LOD->LoadTexture("IB-COMP-A", TEXTURE_16BIT_PALETTE);
+      dword_5079D0 = pIcons_LOD->LoadTexture("IB-InitG-a", TEXTURE_16BIT_PALETTE);
+      dword_5079C8 = pIcons_LOD->LoadTexture("IB-InitY-a", TEXTURE_16BIT_PALETTE);
+      dword_5079CC = pIcons_LOD->LoadTexture("IB-InitR-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_NPCLeft = pIcons_LOD->LoadTexture("IB-NPCLD-A", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_NPCRight = pIcons_LOD->LoadTexture("IB-NPCRD-A", TEXTURE_16BIT_PALETTE);
+      uTextureID_GameUI_CharSelectionFrame = pIcons_LOD->LoadTexture("IB-selec-A", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_CastSpell = pIcons_LOD->LoadTexture("ib-m1d-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_Rest = pIcons_LOD->LoadTexture("ib-m2d-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_QuickReference = pIcons_LOD->LoadTexture("ib-m3d-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_GameSettings = pIcons_LOD->LoadTexture("ib-m4d-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_ZoomIn = pIcons_LOD->LoadTexture("ib-autout-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_Btn_ZoomOut = pIcons_LOD->LoadTexture("ib-autin-a", TEXTURE_16BIT_PALETTE);
+      uExitCancelTextureId = pIcons_LOD->LoadTexture("ib-bcu-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Bless = pIcons_LOD->LoadTexture("isg-01-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Preservation = pIcons_LOD->LoadTexture("isg-02-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_Hammerhands = pIcons_LOD->LoadTexture("isg-03-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_PlayerBuff_PainReflection = pIcons_LOD->LoadTexture("isg-04-a", TEXTURE_16BIT_PALETTE);
+      uTextureID_50795C = pIcons_LOD->LoadTexture("evtnpc", TEXTURE_16BIT_PALETTE);
+      uTextureID_CharacterUI_InventoryBackground = pIcons_LOD->LoadTexture("fr_inven", TEXTURE_16BIT_PALETTE);
+      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeA");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
+      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchA");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
+      uTextureID_Parchment = pIcons_LOD->LoadTexture("parchment", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076B4 = pIcons_LOD->LoadTexture("cornr_ll", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076B0 = pIcons_LOD->LoadTexture("cornr_lr", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076AC = pIcons_LOD->LoadTexture("cornr_ul", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076A8 = pIcons_LOD->LoadTexture("cornr_ur", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076A4 = pIcons_LOD->LoadTexture("edge_btm", TEXTURE_16BIT_PALETTE);
+      uTextureID_5076A0 = pIcons_LOD->LoadTexture("edge_lf", TEXTURE_16BIT_PALETTE);
+      uTextureID_50769C = pIcons_LOD->LoadTexture("edge_rt", TEXTURE_16BIT_PALETTE);
+      uTextureID_507698 = pIcons_LOD->LoadTexture("edge_top", TEXTURE_16BIT_PALETTE);
+      pTexture_591428 = pIcons_LOD->LoadTexturePtr("endcap", TEXTURE_16BIT_PALETTE);
+    }
+    uGameUIFontMain = Color16(0xAu, 0, 0);
+    uGameUIFontShadow = Color16(230, 214, 193);
+  }
+  else if (align == PartyAlignment_Good)
+  {
+    if ( bReplace )
+    {
+      pTexture_RightFrame->Reload("ib-r-B.pcx");
+      pTexture_BottomFrame->Reload("ib-b-B.pcx");
+      pTexture_TopFrame->Reload("ib-t-B.pcx");
+      pTexture_LeftFrame->Reload("ib-l-B.pcx");
+      pTexture_StatusBar->Reload("IB-Foot-b.pcx");
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-B", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-b", 2);
+      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeB");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
+      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchB");
+      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt-b", 2);
+      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top-b", 2);
+      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap-b", 2);
+    }
+    uGameUIFontMain = Color16(0, 0, 0xC8u);
+    uGameUIFontShadow = Color16(255, 255, 255);
+  }
+  else Error("Invalid alignment type: %u", align);
+}
+//----- (0041D20D) --------------------------------------------------------
+void DrawBuff_remaining_time_string( int uY, struct GUIWindow *window, __int64 remaining_time, struct GUIFont *Font )
+{
+  unsigned int full_time; // esi@1
+  signed __int64 hours; // kr00_8@1
+  const char *text; // eax@2
+  signed __int64 minutes; // [sp+10h] [bp-10h]@1
+  signed __int64 seconds; // [sp+18h] [bp-8h]@1
+  unsigned int day; // [sp+24h] [bp+4h]@1
+
+  full_time = (signed __int64)((double)remaining_time * 0.234375);
+  day = (unsigned int)((full_time / 60) / 60) / 24;
+  hours = ((full_time / 60) / 60) % 24;
+  minutes = (signed __int64)(full_time / 60) % 60;
+  seconds = (signed __int64)full_time % 60;
+  strcpy(pTmpBuf.data(), "\r020");
+  if ( day )
+  {
+    text = pGlobalTXT_LocalizationStrings[57];   // Days
+    if ( day <= 1 )
+      text = pGlobalTXT_LocalizationStrings[56]; // Day
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)day, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( hours )
+  {
+    if ( hours <= 1 )
+      text = pGlobalTXT_LocalizationStrings[109];// Hour
+    else
+      text = pGlobalTXT_LocalizationStrings[110];// Hours
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)hours, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( minutes && !day )
+  {
+    if ( minutes <= 1 )
+      text = pGlobalTXT_LocalizationStrings[437];// Minute
+    else
+      text = pGlobalTXT_LocalizationStrings[436];// Minutes
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)minutes, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  if ( seconds && !hours )
+  {
+    if ( seconds <= 1 )
+      text = pGlobalTXT_LocalizationStrings[439];// Second
+    else
+      text = pGlobalTXT_LocalizationStrings[438];// Seconds
+    sprintfex(pTmpBuf2.data(), "%d %s ", (int)seconds, text);
+    strcat(pTmpBuf.data(), pTmpBuf2.data());
+  }
+  window->DrawText(Font, 32, uY, 0, pTmpBuf.data(), 0, 0, 0);
+}
+
+
+//----- (0042EB8D) --------------------------------------------------------
+void GUIMessageQueue::AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file, int line)
+{
+  //Log::Warning(L"%s @ (%S %u)", UIMessage2String(msg), file, line);
+  if (uNumMessages < 40)
+  {
+    files[uNumMessages] = file;
+    lines[uNumMessages] = line;
+
+    pMessages[uNumMessages].eType = msg;
+    pMessages[uNumMessages].param = param;
+    pMessages[uNumMessages++].field_8 = a4;
+  }
+}
+
+//----- (004637E0) --------------------------------------------------------
+char  sub_4637E0_is_there_popup_onscreen()
+{
+  return dword_507BF0_is_there_popup_onscreen == 1;
+}
+// 507BF0: using guessed type int dword_507BF0_is_there_popup_onscreen;
+
+//----- (00417AD4) --------------------------------------------------------
+unsigned int GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level)
+{
+	switch (uPlayerClass % 4)
+	{
+	case 0:
+	{
+			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] >= skill_level)
+				  return ui_character_skillinfo_can_learn;
+			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 1][uPlayerSkillType] < skill_level &&
+				  byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 2][uPlayerSkillType] < skill_level)
+			  {
+				  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 3][uPlayerSkillType] < skill_level)
+					  return ui_character_skillinfo_cant_learn;
+			  }
+			  return ui_character_skillinfo_can_learn_gm;
+	}
+		break;
+
+	case 1:
+	{
+			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] >= skill_level)
+				  return ui_character_skillinfo_can_learn;
+			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 1][uPlayerSkillType] < skill_level)
+			  {
+				  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 2][uPlayerSkillType] < skill_level)
+					  return ui_character_skillinfo_cant_learn;
+			  }
+			  return ui_character_skillinfo_can_learn_gm;
+	}
+		break;
+
+	case 2:
+	case 3:
+	{
+			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] < skill_level)
+				  return ui_character_skillinfo_cant_learn;
+			  return ui_character_skillinfo_can_learn;
+	}
+		break;
+	}
+	Error("Invalid player class: %u", uPlayerClass);
+}
+
+//----- (0040F92A) --------------------------------------------------------
+void __fastcall ZBuffer_DoFill2(int *pZBuffer, Texture *a2, int a3)
+{//ñðàáàòûâàåò â ïîêóïêå â ìàãàçèíå
+	void *v4; // eax@3
+	//int *v5; // edi@5
+	//  int v6; // ecx@6
+	//  int v9; // [sp+18h] [bp-4h]@1
+
+	if (pIcons_LOD->dword_011BA4 && a2->uDecompressedSize)
+		v4 = a2->UnzipPalette();
+	else
+		v4 = a2->pLevelOfDetail0_prolly_alpha_mask;
+	//v5 = pZBuffer;
+	for (uint i = 0; i < a2->uTextureHeight; i++)
+	{
+		for (uint j = 0; j < a2->uTextureWidth; j++)
+		{
+			*pZBuffer = a3;
+			++pZBuffer;
+		}
+		pZBuffer += window->GetWidth() - a2->uTextureWidth;
+	}
+	if (pIcons_LOD->dword_011BA4)
+	{
+		if (a2->uDecompressedSize)
+			free(v4);
+	}
+}
+
+
+// 4E28F8: using guessed type int pCurrentScreen;
+
+//----- (0040F82D) --------------------------------------------------------
+void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue)
+{
+	assert(uTextureId != -1);
+	ZBuffer_DoFill(pZBuffer, pIcons_LOD->GetTexture(uTextureId), iZValue);
+}
+
+//----- (0040F89C) --------------------------------------------------------
+void __fastcall ZBuffer_DoFill(int *pZBuffer, Texture *pTex, int uZValue)
+{//ñðàáàòûâàåò ïðè ïðîäàæå â ìàãàçèíå
+	void *v3; // eax@3
+	//void *v4; // esi@5
+	//int *v5; // edi@5
+	//int v6; // eax@5
+	//  int v7; // ecx@6
+	//  int v11; // [sp+18h] [bp-8h]@1
+	//void *v12; // [sp+1Ch] [bp-4h]@5
+
+	if (pIcons_LOD->dword_011BA4 && pTex->uDecompressedSize)
+		v3 = pTex->UnzipPalette();
+	else
+		v3 = pTex->pLevelOfDetail0_prolly_alpha_mask;
+	//v12 = v3;
+	//v4 = v3;
+	//v5 = pZBuffer;
+	//v6 = 0;
+	for (uint i = 0; i < pTex->uTextureHeight; i++)
+	{
+		for (uint j = 0; j < pTex->uTextureWidth; j++)
+		{
+			//LOBYTE(v6) = *(char *)v4;
+			//v4 = (char *)v4 + 1;
+			//if ( v6 )
+			*pZBuffer = uZValue;
+			++pZBuffer;
+		}
+		pZBuffer += window->GetWidth() - pTex->uTextureWidth;
+	}
+	if (pIcons_LOD->dword_011BA4)
+	{
+		if (pTex->uDecompressedSize)
+			free(v3);
+	}
+}
+
+//----- (004BC49B) --------------------------------------------------------
+void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType)
+{
+	NPCData *speakingNPC; // ebp@1
+	int npc_event_id; // ecx@10
+	char *v13; // [sp-8h] [bp-18h]@60
+
+	speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+	uDialogueType = newDialogueType;
+	if (!speakingNPC->uFlags)
+		speakingNPC->uFlags = 1;
+	if (newDialogueType == DIALOGUE_PROFESSION_DETAILS)
+		dialogue_show_profession_details = ~dialogue_show_profession_details;
+	else if (newDialogueType == DIALOGUE_76)
+	{
+		if (speakingNPC->Hired())
+		{
+			if ((signed int)pNPCStats->uNumNewNPCs > 0)
+			{
+				for (uint i = 0; i < (unsigned int)pNPCStats->uNumNewNPCs; ++i)
+				{
+					if (pNPCStats->pNewNPCData[i].uFlags & 0x80 && !strcmp(speakingNPC->pName, pNPCStats->pNewNPCData[i].pName))
+						pNPCStats->pNewNPCData[i].uFlags &= 0x7Fu;
+				}
+			}
+			if (pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName))
+				memset(&pParty->pHirelings[0], 0, sizeof(NPCData));
+			else if (pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName))
+				memset(&pParty->pHirelings[1], 0, sizeof(NPCData));
+			pParty->hirelingScrollPosition = 0;
+			pParty->CountHirelings();
+			dword_591084 = 0;
+			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+			dword_7241C8 = 0;
+			return;
+		}
+		if (pParty->pHirelings[0].pName && pParty->pHirelings[1].pName)
+			ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
+		else
+		{
+			if (speakingNPC->uProfession != 51) //burglars have no hiring price
+			{
+				if (pParty->uNumGold < pNPCStats->pProfessions[speakingNPC->uProfession].uHirePrice)
+				{
+					ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
+					dialogue_show_profession_details = false;
+					uDialogueType = 13;
+					if (uActiveCharacter)
+						pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
+					if (!dword_7241C8)
+						pGame->Draw();
+					dword_7241C8 = 0;
+					return;
+				}
+				Party::TakeGold(pNPCStats->pProfessions[speakingNPC->uProfession].uHirePrice);
+			}
+			LOBYTE(speakingNPC->uFlags) |= 0x80u;
+			if (pParty->pHirelings[0].pName)
+			{
+				memcpy(&pParty->pHirelings[1], speakingNPC, sizeof(pParty->pHirelings[1]));
+				v13 = pParty->pHireling2Name;
+			}
+			else
+			{
+				memcpy(&pParty->pHirelings[0], speakingNPC, sizeof(pParty->pHirelings[0]));
+				v13 = pParty->pHireling1Name;
+			}
+			strcpy(v13, speakingNPC->pName);
+			pParty->hirelingScrollPosition = 0;
+			pParty->CountHirelings();
+			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+			if (sDialogue_SpeakingActorNPC_ID >= 0)
+				pDialogue_SpeakingActor->uAIState = Removed;
+			if (uActiveCharacter)
+				pPlayers[uActiveCharacter]->PlaySound(SPEECH_61, 0);
+		}
+	}
+	else if ((signed int)newDialogueType > DIALOGUE_84 && (signed int)newDialogueType <= DIALOGUE_ARENA_SELECT_CHAMPION) //âûáîð óðîâíÿ ñëîæíîñòè áîÿ
+	{
+		ArenaFight();
+		return;
+	}
+	else if (newDialogueType == DIALOGUE_USE_NPC_ABILITY)
+	{
+		if (UseNPCSkill((NPCProf)speakingNPC->uProfession) == 0)
+		{
+			if (speakingNPC->uProfession != GateMaster)
+				speakingNPC->bHasUsedTheAbility = 1;
+			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+		}
+		else
+			ShowStatusBarString(pGlobalTXT_LocalizationStrings[140], 2); //"Your packs are already full!"
+	}
+	else if (newDialogueType == DIALOGUE_13)
+	{
+		if (!speakingNPC->Hired())
+		{
+			sub_4B3E1E();
+			dialogue_show_profession_details = false;
+		}
+		else
+		{
+			for (uint i = 0; i < (signed int)pNPCStats->uNumNewNPCs; ++i)
+			{
+				if (pNPCStats->pNewNPCData[i].uFlags & 0x80 && !strcmp(speakingNPC->pName, pNPCStats->pNewNPCData[i].pName))
+					pNPCStats->pNewNPCData[i].uFlags &= 0x7Fu;
+			}
+			if (pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName))
+				memset(&pParty->pHirelings[0], 0, sizeof(NPCData));
+			else if (pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName))
+				memset(&pParty->pHirelings[1], 0, sizeof(NPCData));
+			pParty->hirelingScrollPosition = 0;
+			pParty->CountHirelings();
+			dword_591084 = 0;
+			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+			dword_7241C8 = 0;
+			return;
+		}
+	}
+	else if (newDialogueType >= DIALOGUE_EVT_A && newDialogueType <= DIALOGUE_EVT_F)
+	{
+		switch (newDialogueType)
+		{
+		case DIALOGUE_EVT_A:  npc_event_id = speakingNPC->evt_A; break;
+		case DIALOGUE_EVT_B:  npc_event_id = speakingNPC->evt_B; break;
+		case DIALOGUE_EVT_C:  npc_event_id = speakingNPC->evt_C; break;
+		case DIALOGUE_EVT_D:  npc_event_id = speakingNPC->evt_D; break;
+		case DIALOGUE_EVT_E:  npc_event_id = speakingNPC->evt_E; break;
+		case DIALOGUE_EVT_F:  npc_event_id = speakingNPC->evt_F; break;
+		}
+		if ((npc_event_id >= 200) && (npc_event_id <= 310))
+			_4B3FE5_training_dialogue(npc_event_id); //200-310
+		else if ((npc_event_id >= 400) && (npc_event_id <= 410))
+		{ //400-410
+			dword_F8B1D8 = newDialogueType;
+			DrawJoinGuildWindow(npc_event_id - 400);
+		}
+		else
+		{
+			switch (npc_event_id)
+			{
+			case 139:
+				OracleDialogue();
+				break;
+			case 311:
+				CheckBountyRespawnAndAward();
+				break;
+			case 399:
+				Arena_SelectionFightLevel();
+				break;
+			default:
+				activeLevelDecoration = (LevelDecoration*)1;
+				current_npc_text = 0;
+				EventProcessor(npc_event_id, 0, 1);
+				activeLevelDecoration = nullptr;
+				break;
+			}
+		}
+	}
+	if (!dword_7241C8)
+		pGame->Draw();
+	dword_7241C8 = 0;
+}
+
+//----- (004B3E1E) --------------------------------------------------------
+void  sub_4B3E1E()
+{
+	NPCData *v0; // ST40_4@1
+	signed int v1; // edi@1
+	//GUIWindow *v2; // ecx@1
+
+	__debugbreak();
+	v0 = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+	v1 = 0;
+	pDialogueWindow->eWindowType = WINDOW_MainMenu;
+	pDialogueWindow->Release();
+	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Dialogue, 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);//Ïîäðîáíåå
+		v1 = 1;
+	}
+	pDialogueWindow->CreateButton(480, 30 * v1 + 160, 140, 30, 1, 0, UIMSG_SelectNPCDialogueOption, 76, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
+	pDialogueWindow->_41D08F_set_keyboard_control_group(v1 + 1, 1, 0, 1);
+}
+
+//----- (004B2001) --------------------------------------------------------
+void __fastcall ClickNPCTopic(signed int uMessageParam)
+{
+	//signed int v1; // eax@1
+	NPCData *pCurrentNPCInfo; // ebp@1
+	int pEventNumber; // ecx@8
+	Player *v4; // esi@20
+	//int v5; // eax@28
+	//int v6; // eax@31
+	//int v7; // eax@34
+	//int v8; // eax@37
+	//int v9; // eax@40
+	//unsigned int v10; // eax@43
+	char *v12; // eax@53
+	char *v13; // eax@56
+	char *v14; // eax@57
+	char *v15; // eax@58
+	//unsigned int v16; // ebp@62
+	char *v17; // ecx@63
+	char *v18; // eax@65
+	//  const char *v19; // ecx@68
+	//unsigned int v20; // eax@69
+	signed int pPrice; // ecx@70
+	char *v22; // [sp-Ch] [bp-18h]@73
+	//int v23; // [sp-8h] [bp-14h]@49
+	char *v24; // [sp-8h] [bp-14h]@73
+	//int v25; // [sp-4h] [bp-10h]@49
+
+	uDialogueType = uMessageParam + 1;
+	pCurrentNPCInfo = HouseNPCData[pDialogueNPCCount - ((dword_591080 != 0) ? 1 : 0)];//- 1
+	if (uMessageParam <= 24)
+	{
+		switch (uMessageParam)
+		{
+		case 13:
+			current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
+			current_npc_text = BuildDialogueString(current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
+			NPCHireableDialogPrepare();
+			dialogue_show_profession_details = false;
+			BackToHouseMenu();
+			return;		
+		case 19:
+			pEventNumber = pCurrentNPCInfo->evt_A;
+			break;
+		case 20:
+			pEventNumber = pCurrentNPCInfo->evt_B;
+			break;
+		case 21:
+			pEventNumber = pCurrentNPCInfo->evt_C;
+			break;
+		case 22:
+			pEventNumber = pCurrentNPCInfo->evt_D;
+			break;
+		case 23:
+			pEventNumber = pCurrentNPCInfo->evt_E;
+			break;
+		case 24:
+			pEventNumber = pCurrentNPCInfo->evt_F;
+			break;
+		default:
+			BackToHouseMenu();
+			return;
+		}
+		/*switch ( pEventNumber )
+		{
+		case 139:
+		OracleDialogue();
+		goto _return;
+		case 311:
+		CheckBountyRespawnAndAward();
+		goto _return;
+		}*/
+		if (pEventNumber < 200 || pEventNumber > 310)
+		{
+			if (pEventNumber < 400 || pEventNumber > 410)
+			{
+				if (pEventNumber == 139)
+				{
+					OracleDialogue();
+				}
+				else
+				{
+					if (pEventNumber == 311)
+					{
+						CheckBountyRespawnAndAward();
+					}
+					else
+					{
+						current_npc_text = 0;
+						activeLevelDecoration = (LevelDecoration*)1;
+						EventProcessor(pEventNumber, 0, 1);
+						activeLevelDecoration = nullptr;
+					}
+				}
+			}
+			else
+			{
+				dword_F8B1D8 = uMessageParam;
+				DrawJoinGuildWindow(pEventNumber - 400);
+			}
+		}
+		else
+		{
+			_4B3FE5_training_dialogue(pEventNumber);
+		}
+		BackToHouseMenu();
+		return;
+	}
+	if (uMessageParam != 76)
+	{
+		if (uMessageParam == 77)
+		{
+			//v16 = pCurrentNPCInfo->uProfession;
+			__debugbreak();  // probably hirelings found in buildings, not present in MM7, changed "pCurrentNPCInfo->uProfession - 1" to "pCurrentNPCInfo->uProfession", have to check in other versions whether it's ok
+			if (dialogue_show_profession_details)
+				v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;
+			else
+				v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pBenefits;
+			current_npc_text = v17;
+			v18 = BuildDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
+			dialogue_show_profession_details = ~dialogue_show_profession_details;
+			current_npc_text = v18;
+		}
+		else
+		{
+			if (uMessageParam == 79)
+			{
+				if (contract_approved)
+				{
+					Party::TakeGold(gold_transaction_amount);
+					if (uActiveCharacter)
+					{
+						v12 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+						*(short *)v12 &= 0x3Fu;
+						switch (dword_F8B1B0_MasteryBeingTaught)
+						{
+						case 2:
+							v15 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+							*v15 |= 0x40u;
+							break;
+						case 3:
+							v14 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+							*v14 |= 0x80u;
+							break;
+						case 4:
+							v13 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
+							v13[1] |= 1u;
+							break;
+						}
+						pPlayers[uActiveCharacter]->PlaySound(SPEECH_85, 0);
+					}
+					pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+					/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+					{
+					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
+					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
+					*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+					++pMessageQueue_50CBD0->uNumMessages;
+					}*/
+				}
+			}
+			else
+			{
+				if (uMessageParam == 82 && contract_approved) //join guild
+				{
+					Party::TakeGold(gold_transaction_amount);
+					v4 = pParty->pPlayers.data();
+					do
+					{
+						v4->SetVariable(VAR_Award, dword_F8B1AC_award_bit_number);
+						++v4;
+					} while ((signed int)v4 < (signed int)pParty->pHirelings.data());
+					switch (dword_F8B1D8)
+					{
+					case 19:
+						pEventNumber = pCurrentNPCInfo->evt_A;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_A = 0;
+						break;
+					case 20:
+						pEventNumber = pCurrentNPCInfo->evt_B;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_B = 0;
+						break;
+					case 21:
+						pEventNumber = pCurrentNPCInfo->evt_C;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_C = 0;
+						break;
+					case 22:
+						pEventNumber = pCurrentNPCInfo->evt_D;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_D = 0;
+						break;
+					case 23:
+						pEventNumber = pCurrentNPCInfo->evt_E;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_E = 0;
+						break;
+					case 24:
+						pEventNumber = pCurrentNPCInfo->evt_F;
+						if (pEventNumber >= 400 && pEventNumber <= 416)
+							pCurrentNPCInfo->evt_F = 0;
+						break;
+					}
+					pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+					/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+					{
+					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
+					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
+					*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+					++pMessageQueue_50CBD0->uNumMessages;
+					}*/
+					//v11 = uActiveCharacter;
+					if (uActiveCharacter)
+					{
+						pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_86, 0);
+						BackToHouseMenu();
+						return;
+					}
+				}
+			}
+		}
+		BackToHouseMenu();
+		return;
+	}
+	if (pParty->pHirelings[0].pName && pParty->pHirelings[1].pName)
+	{
+		ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
+		BackToHouseMenu();
+		return;
+	}
+	
+	
+	if (pCurrentNPCInfo->uProfession != 51) //burglars have no hiring price
+	{
+		__debugbreak();  // probably hirelings found in buildings, not present in MM7, changed "pCurrentNPCInfo->uProfession - 1" to "pCurrentNPCInfo->uProfession", have to check in other versions whether it's ok
+		pPrice = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].uHirePrice;
+		if (pParty->uNumGold < (unsigned int)pPrice)
+		{
+			ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+			dialogue_show_profession_details = false;
+			uDialogueType = 13;
+			current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;
+			current_npc_text = BuildDialogueString(current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
+			if (uActiveCharacter)
+				pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
+			ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
+			BackToHouseMenu();
+			return;
+		}
+		else
+			Party::TakeGold(pPrice);
+	}
+	//LOBYTE(v2->uFlags) |= 0x80u;
+	pCurrentNPCInfo->uFlags |= 128;
+	pParty->hirelingScrollPosition = 0;
+	pParty->CountHirelings();
+	if (pParty->pHirelings[0].pName)
+	{
+		memcpy(&pParty->pHirelings[1], pCurrentNPCInfo, sizeof(pParty->pHirelings[1]));
+		v24 = pCurrentNPCInfo->pName;
+		v22 = pParty->pHireling2Name;
+	}
+	else
+	{
+		memcpy(pParty->pHirelings.data(), pCurrentNPCInfo, 0x4Cu);
+		v24 = pCurrentNPCInfo->pName;
+		v22 = pParty->pHireling1Name;
+	}
+	strcpy(v22, v24);
+	pParty->hirelingScrollPosition = 0;
+	pParty->CountHirelings();
+	PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
+	dialog_menu_id = HOUSE_DIALOGUE_MAIN;
+
+	pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
+	/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+	{
+	pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
+	pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
+	*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+	++pMessageQueue_50CBD0->uNumMessages;
+	}*/
+	if (uActiveCharacter)
+		pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)61, 0);
+
+_return:
+	BackToHouseMenu();
+}
+
+//----- (004B3FE5) --------------------------------------------------------
+//Originally called _4B254D_SkillMasteryTeacher to have contract_approved assigned, to be able to set some button name. 
+//But it the name gets immediately overwritten
+void _4B3FE5_training_dialogue(int a4)
+{
+	const char *v2; // edi@1
+
+	//__debugbreak();
+	uDialogueType = DIALOGUE_SKILL_TRAINER;
+	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);
+	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);
+	v2 = "";
+	if (contract_approved)
+		v2 = pGlobalTXT_LocalizationStrings[535];
+	pDialogueWindow->CreateButton(480, 160, 0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x4Fu, 0, v2, 0);
+	pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
+	dialog_menu_id = HOUSE_DIALOGUE_OTHER;
+}
+// F8B19C: using guessed type int dword_F8B19C;
+// F8B1A8: using guessed type int dword_F8B1A8;
+//----- (004B1ECE) --------------------------------------------------------
+void OracleDialogue()
+{
+	__int16 *v0; // edi@1
+	signed int v4; // eax@9
+	int v5; // ebx@11
+	signed int v8; // edi@14
+	ItemGen *v9; // [sp+Ch] [bp-Ch]@11
+	signed int v10; // [sp+10h] [bp-8h]@13
+	int v11; // [sp+14h] [bp-4h]@1
+
+	contract_approved = 0;
+	v11 = 0;
+	uDialogueType = 84;
+	current_npc_text = (char *)pNPCTopics[667].pText;
+	v0 = _4F0882_evt_VAR_PlayerItemInHands_vals.data();
+	//while ( 1 )
+	for (uint i = 0; i <= 53; i++)
+	{
+		if ((unsigned __int16)_449B57_test_bit(pParty->_quest_bits, *v0))
+		{
+			//v1 = 0;
+			//v2 = pParty->pPlayers.data();
+			for (uint pl = 0; pl < 4; pl++)
+			{
+				//LOBYTE(v3) = pParty->pPlayers[pl].CompareVariable(VAR_PlayerItemInHands, *(v0+1));
+				if (pParty->pPlayers[pl].CompareVariable(VAR_PlayerItemInHands, *(v0 + 1)))
+					break;
+				//++v2;
+				//++v1;
+			}
+			//while ( (signed int)v2 < (signed int)pParty->pHirelings.data() );
+			//if ( v1 == 4 )
+			//break;
+		}
+		++v11;
+		//v0 += 2;
+		//if ( v0 > &_4F0882_evt_VAR_PlayerItemInHands_vals[53] )
+		//break;
+	}
+	if (v0 <= &_4F0882_evt_VAR_PlayerItemInHands_vals[53])
+	{
+		current_npc_text = (char *)pNPCTopics[666].pText; // Here's %s that you lost. Be careful
+		v4 = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
+		contract_approved = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
+		pParty->pPlayers[0].AddVariable(VAR_PlayerItemInHands, v4);
+	}
+	if (contract_approved == 601)
+	{
+		v5 = 0;
+		//v12 = pParty->pPlayers.data();//[0].uClass;
+		v9 = 0;
+		//while ( 1 )
+		for (uint i = 0; i < 4; i++)
+		{
+			if (pParty->pPlayers[i].classType == PLAYER_CLASS_LICH)
+			{
+				v10 = 0;
+				//v6 = pParty->pPlayers.data();//[0].pInventoryItems[0].field_1A;
+				for (uint pl = 0; pl < 4; pl++)
+				{
+					for (v8 = 0; v8 < 126; v8++)//138
+					{
+						if (pParty->pPlayers[pl].pInventoryItemList[v8].uItemID == ITEM_LICH_JAR_FULL)
+						{
+							if (!pParty->pPlayers[pl].pInventoryItemList[v8].uHolderPlayer)
+								v9 = &pParty->pPlayers[pl].pInventoryItemList[v8];
+							if (pParty->pPlayers[pl].pInventoryItemList[v8].uHolderPlayer == v5)
+								v10 = 1;
+						}
+					}
+				}
+				if (!v10)
+					break;
+			}
+			//      ++v12;
+			++v5;
+			//  if ( v12 > &pParty->pPlayers[3] )
+			//  return;
+		}
+		if (v9)
+			v9->uHolderPlayer = v5;
+	}
+}
+
+//----- (004B46A5) --------------------------------------------------------
+void __fastcall DrawTextAtStatusBar(const char *Str, int a5)
+{
+	pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar);
+	pPrimaryWindow->DrawText(pFontLucida, pFontLucida->AlignText_Center(450, Str) + 11, 357, a5, Str, 0, 0, 0);
+}
+
+//----- (004BBA85) --------------------------------------------------------
+void CheckBountyRespawnAndAward()
+{
+	int i; // eax@2
+	int rand_monster_id; // edx@3
+
+	uDialogueType = 83;
+	pDialogueWindow->Release();
+	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 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);
+	pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_0, 83, 0, "", 0);
+	pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
+	dialog_menu_id = HOUSE_DIALOGUE_OTHER;
+	//get new monster for hunting
+	if (pParty->PartyTimes.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] < (signed __int64)pParty->uTimePlayed)
+	{
+		pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
+		pParty->PartyTimes.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = (signed __int64)((double)(0x12750000 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
+		for (i = rand();; i = rand())
+		{
+			rand_monster_id = i % 258 + 1;
+			pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = rand_monster_id;
+			if ((unsigned __int16)rand_monster_id < 0x73u || (unsigned __int16)rand_monster_id > 0x84u)
+			{
+				if (((unsigned __int16)rand_monster_id < 0xEBu || (unsigned __int16)rand_monster_id > 0xFCu)
+					&& ((unsigned __int16)rand_monster_id < 0x85u || (unsigned __int16)rand_monster_id > 0x96u)
+					&& ((unsigned __int16)rand_monster_id < 0x97u || (unsigned __int16)rand_monster_id > 0xBAu)
+					&& ((unsigned __int16)rand_monster_id < 0xC4u || (unsigned __int16)rand_monster_id > 0xC6u))
+					break;
+			}
+		}
+	}
+	bountyHunting_monster_id_for_hunting = pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)];
+	if (!pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
+	{
+		bountyHunting_text = pNPCTopics[351].pText;
+		if (!pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
+			bountyHunting_text = pNPCTopics[353].pText;
+	}
+	else//get prize
+	{
+		if (pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
+		{
+			pParty->PartyFindsGold(100 * pMonsterStats->pInfos[(unsigned __int16)pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel, 0);
+			for (uint i = 0; i < 4; ++i)
+				pParty->pPlayers[i].SetVariable(VAR_Award, 86);
+			pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel;
+			pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = 0;
+			pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
+		}
+		bountyHunting_text = pNPCTopics[352].pText;
+	}
+}
+
+//----- (004B254D) --------------------------------------------------------
+const char * _4B254D_SkillMasteryTeacher(int trainerInfo)
+{
+	int teacherLevel; // edx@1
+	int skillBeingTaught; // ecx@1
+	int pClassType; // eax@7
+	int currClassMaxMastery; // eax@7
+	int pointsInSkillWOutMastery; // ebx@7
+	int classBaseId; // eax@8
+	unsigned int skillMastery; // eax@29
+	unsigned __int16 pointsInSkill; // [sp+1Ch] [bp-10h]@7
+	int masteryLevelBeingTaught; // [sp+24h] [bp-8h]@7
+
+	contract_approved = 0;
+	teacherLevel = (trainerInfo - 200) % 3;
+	skillBeingTaught = (trainerInfo - 200) / 3;
+	Player* activePlayer = pPlayers[uActiveCharacter];
+	pClassType = activePlayer->classType;
+	currClassMaxMastery = byte_4ED970_skill_learn_ability_by_class_table[pClassType][skillBeingTaught];
+	masteryLevelBeingTaught = teacherLevel + 2;
+	dword_F8B1B0_MasteryBeingTaught = masteryLevelBeingTaught;
+	if (currClassMaxMastery < masteryLevelBeingTaught)
+	{
+		classBaseId = pClassType - pClassType % 4;
+		if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 1][skillBeingTaught] >= masteryLevelBeingTaught)
+			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 1]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
+		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught
+			&& byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught)
+			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[634], pClassNames[classBaseId + 2], pClassNames[classBaseId + 3]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s èëè %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s or %s to learn this skill level.
+		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught)
+			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 2]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
+		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught)
+			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 3]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
+		else
+			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[632], pClassNames[pClassType]);//Ýòîò óðîâåíü íàâûêà íå ìîæåò áûòü ïîñòèãíóò êëàññîì %s. This skill level can not be learned by the %s class.
+		return pTmpBuf.data();
+	}
+	if (!activePlayer->CanAct())
+		return pNPCTopics[122].pText; //Not in your condition!
+	pointsInSkill = activePlayer->pActiveSkills[skillBeingTaught];
+	pointsInSkillWOutMastery = pointsInSkill & 0x3F;
+	if (!pointsInSkillWOutMastery)
+		return pNPCTopics[131].pText; //You must know the skill before you can become an expert in it!
+	skillMastery = SkillToMastery(pointsInSkill);
+	if ((signed int)skillMastery > teacherLevel + 1)
+		return pNPCTopics[teacherLevel + 128].pText;    // You are already an SKILLLEVEL in this skill.	
+	dword_F8B1AC_award_bit_number = skillBeingTaught;
+	if (masteryLevelBeingTaught == 2 && pointsInSkillWOutMastery < 4
+		|| masteryLevelBeingTaught == 3 && pointsInSkillWOutMastery < 7
+		|| masteryLevelBeingTaught == 4 && pointsInSkillWOutMastery < 10
+		)
+		return pNPCTopics[127].pText;  //"You don't meet the requirements, and cannot be taught until you do."
+	switch (dword_F8B1AC_award_bit_number)
+	{
+	case PLAYER_SKILL_STAFF:
+	case PLAYER_SKILL_SWORD:
+	case PLAYER_SKILL_DAGGER:
+	case PLAYER_SKILL_AXE:
+	case PLAYER_SKILL_SPEAR:
+	case PLAYER_SKILL_BOW:
+	case PLAYER_SKILL_MACE:
+	case PLAYER_SKILL_ARMSMASTER:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_BLASTER:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 0;
+			break;
+		case 3:
+			gold_transaction_amount = 0;
+			break;
+		case 4:
+			gold_transaction_amount = 0;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_SHIELD:
+	case PLAYER_SKILL_LEATHER:
+	case PLAYER_SKILL_CHAIN:
+	case PLAYER_SKILL_PLATE:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 1000;
+			break;
+		case 3:
+			gold_transaction_amount = 3000;
+			break;
+		case 4:
+			gold_transaction_amount = 7000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_FIRE:
+	case PLAYER_SKILL_AIR:
+	case PLAYER_SKILL_WATER:
+	case PLAYER_SKILL_EARTH:
+	case PLAYER_SKILL_SPIRIT:
+	case PLAYER_SKILL_MIND:
+	case PLAYER_SKILL_BODY:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 1000;
+			break;
+		case 3:
+			gold_transaction_amount = 4000;
+			break;
+		case 4:
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_LIGHT:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 114))
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x22u, 1) ||
+				!activePlayer->ProfessionOrGuildFlagsCorrect(0x1Au, 1))
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_DARK:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 110))
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x23u, 1)
+				|| !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Bu, 1))
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_ITEM_ID:
+	case PLAYER_SKILL_REPAIR:
+	case PLAYER_SKILL_MEDITATION:
+	case PLAYER_SKILL_PERCEPTION:
+	case PLAYER_SKILL_TRAP_DISARM:
+	case PLAYER_SKILL_MONSTER_ID:
+	case PLAYER_SKILL_STEALING:
+	case PLAYER_SKILL_ALCHEMY:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 500;
+			break;
+		case 3:
+			gold_transaction_amount = 2500;
+			break;
+		case 4:
+			gold_transaction_amount = 6000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_MERCHANT:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			if (activePlayer->GetBaseWillpower() < 50)
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_BODYBUILDING:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 500;
+			break;
+		case 3:
+			if (activePlayer->GetBaseEndurance() < 50)
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 2500;
+			break;
+		case 4:
+			gold_transaction_amount = 6000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_DIPLOMACY:
+		Error("Diplomacy not used");
+		break;
+	case PLAYER_SKILL_TIEVERY:
+		Error("Thievery not used");
+		break;
+	case PLAYER_SKILL_DODGE:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			if ((activePlayer->pActiveSkills[PLAYER_SKILL_UNARMED] & 63) < 0xA)
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_UNARMED:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			if ((activePlayer->pActiveSkills[PLAYER_SKILL_DODGE] & 63) < 0xA)
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	case PLAYER_SKILL_LEARNING:
+		switch (masteryLevelBeingTaught)
+		{
+		case 2:
+			gold_transaction_amount = 2000;
+			break;
+		case 3:
+			if (activePlayer->GetBaseIntelligence() < 50)
+				return pNPCTopics[127].pText;
+			gold_transaction_amount = 5000;
+			break;
+		case 4:
+			gold_transaction_amount = 8000;
+			break;
+		}
+		break;
+	default:
+		Error("Unknown skill");
+	}
+	if (gold_transaction_amount > pParty->uNumGold)
+		return pNPCTopics[124].pText;  //You don't have enough gold!
+	contract_approved = 1;
+	if (masteryLevelBeingTaught == 2)
+	{
+		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],//Ïîëó÷èòü ñòåïåíü ^Pr[%s] â íàâûêå ^Pr[%s] çà ^I[%lu] çîëîò^L[îé;ûõ;ûõ]
+			pGlobalTXT_LocalizationStrings[433], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Ýêñïåðò
+	}
+	else if (masteryLevelBeingTaught == 3)
+	{
+		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],
+			pGlobalTXT_LocalizationStrings[432], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Ìàñòåð
+	}
+	else if (masteryLevelBeingTaught == 4)
+		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],
+		pGlobalTXT_LocalizationStrings[225], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Âåëèêèé Ìàãèñòð
+	return pTmpBuf2.data();
+}
+
+//----- (00495461) --------------------------------------------------------
+char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6)
+{
+	Player *pPlayer; // ebx@3
+	const char *pText; // esi@7
+	int v17; // eax@10
+	signed __int64 v18; // qax@18
+	unsigned __int8 *v20; // ebx@32
+	int v21; // ecx@34
+	int pReputation; // eax@45
+	int v29; // eax@68
+	__int16 v55[56]; // [sp+10h] [bp-128h]@34
+	stru351_summoned_item v56; // [sp+80h] [bp-B8h]@107
+	char a1[100]; // [sp+B8h] [bp-80h]@3
+	int v63; // [sp+12Ch] [bp-Ch]@32
+
+	if (IsBadStringPtrA(lpsz, 1))
+		return "Invalid String Passed";
+
+	a1[0] = 0;
+	pPlayer = &pParty->pPlayers[uPlayerID];
+	memset(pTmpBuf2.data(), 0, sizeof(pTmpBuf2));
+
+	NPCData *npc = nullptr;
+	if (dword_5C35D4)
+		npc = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0))]; //- 1
+	else
+		npc = GetNPCData(sDialogue_SpeakingActorNPC_ID);
+
+	//pText = a4;
+	uint len = strlen(lpsz);
+	for (int i = 0, dst = 0; i < len; ++i)
+	{
+		char c = lpsz[i];
+		if (c != '%')
+			pTmpBuf2[dst++] = c;
+		else
+		{
+			v17 = 10 * (int)(lpsz[i + 1] - '0') + lpsz[i + 2] - '0';
+
+			switch (v17)
+			{
+			case 1://Ïîäðîáíåå
+				strcat(pTmpBuf2.data(), npc->pName);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 2:
+				strcat(pTmpBuf2.data(), pPlayer->pName);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 3:
+			case 4:
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 5:
+				v18 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60 / 60 % 24;
+				pText = pGlobalTXT_LocalizationStrings[397];// "evening"
+				if (SHIDWORD(v18) <= 0 && SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 5 && SHIDWORD(v18) <= 0)
+				{
+					if (SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 11)
+					{
+						if (v18 < 20)
+							pText = pGlobalTXT_LocalizationStrings[396];// "day"
+					}
+					else
+					{
+						pText = pGlobalTXT_LocalizationStrings[395];// "morning"
+					}
+				}
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 6:
+				if (pPlayer->uSex)
+					pText = pGlobalTXT_LocalizationStrings[387];// "lady"
+				else
+					pText = pGlobalTXT_LocalizationStrings[385];// "sir"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 7:
+				if (pPlayer->uSex)
+					pText = pGlobalTXT_LocalizationStrings[389];// "Lady"
+				else
+					pText = pGlobalTXT_LocalizationStrings[386];// "Sir"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 8:
+				v63 = 0;
+				v20 = (unsigned __int8 *)pPlayer->_achieved_awards_bits;
+				for (uint _i = 0; _i < 28; ++_i)
+				{
+					if ((unsigned __int16)_449B57_test_bit(v20, word_4EE150[i]))
+					{
+						v21 = v63;
+						++v63;
+						v55[v63] = word_4EE150[i];
+					}
+				}
+				if (v63)
+				{
+					if (dword_A74CDC == -1)
+						dword_A74CDC = rand() % v63;
+					pText = (char *)pAwards[v55[dword_A74CDC]].pText;//(char *)dword_723E80_award_related[2 * v55[v24]];
+				}
+				else
+					pText = (char *)pNPCTopics[55].pText;
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 9:
+				if (npc->uSex)
+					pText = pGlobalTXT_LocalizationStrings[384];// "her"
+				else
+					pText = pGlobalTXT_LocalizationStrings[383];// "his"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 10:
+				if (pPlayer->uSex)
+					pText = pGlobalTXT_LocalizationStrings[389];// "Lady"
+				else
+					pText = pGlobalTXT_LocalizationStrings[388];// "Lord"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 11:
+				pReputation = pParty->GetPartyReputation();
+				if (pReputation >= 25)
+					pText = pGlobalTXT_LocalizationStrings[379];
+				else//v25 < 25
+				{
+					if (pReputation < 6)
+					{
+						if (pReputation >= -5)//6 >= v25 >= -5
+							pText = pGlobalTXT_LocalizationStrings[399];
+						else// v25 < -5
+						{
+							if (pReputation < -24)//-24 > v25
+								pText = pGlobalTXT_LocalizationStrings[434];
+							else// -5 > v25 > -24
+								pText = pGlobalTXT_LocalizationStrings[402];
+						}
+					}
+					else//25 > v25 > 6
+						pText = pGlobalTXT_LocalizationStrings[392];
+				}
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 12:
+				pReputation = npc->rep;
+				if (pReputation >= 25)
+					pText = pGlobalTXT_LocalizationStrings[379];//Íåíàâèñòíûé
+				else
+				{
+					if (pReputation < 6)
+					{
+						if (pReputation >= -5)
+							pText = pGlobalTXT_LocalizationStrings[399];//Íåéòðàëüíàÿ
+						else
+						{
+							if (pReputation < -24)
+								pText = pGlobalTXT_LocalizationStrings[434];//Ïî÷òåííàÿ
+							else
+								pText = pGlobalTXT_LocalizationStrings[402];//Äðóæåëþáíûé
+						}
+					}
+					else
+						pText = pGlobalTXT_LocalizationStrings[392];//Íåäðóæåëþáíûé
+				}
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 13:
+				strcat(pTmpBuf2.data(), pNPCStats->sub_495366_MispronounceName(pPlayer->pName[0], pPlayer->uSex));
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 14:
+				if (npc->uSex)
+					pText = pGlobalTXT_LocalizationStrings[391];// "sister"
+				else
+					pText = pGlobalTXT_LocalizationStrings[390];// "brother"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 15:
+				strcat(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[393]);// "daughter"
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 16:
+				if (npc->uSex)
+					pText = pGlobalTXT_LocalizationStrings[391];// "sister"
+				else
+					pText = pGlobalTXT_LocalizationStrings[390];// "brother"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 17://òåêñò íà¸ìíîãî ÍÏÑ
+			{
+						uint pay_percentage = pNPCStats->pProfessions[npc->uProfession].uHirePrice / 100;
+						if (!pay_percentage)
+							pay_percentage = 1;
+						sprintf(a1, "%lu", pay_percentage);
+						strcat(pTmpBuf2.data(), a1);
+						dst = strlen(pTmpBuf2.data());
+						i += 2;
+						break;
+			}
+			case 18:
+			case 19:
+			case 20:
+			case 21:
+			case 22:
+			case 26:
+				strncpy(a1, lpsz + i + 1, 2);
+				sprintf(a1, "%lu", atoi(a1));
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 23:
+				if (pMapStats->GetMapInfo(pCurrentMapName))
+					pText = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName;
+				else
+					pText = pGlobalTXT_LocalizationStrings[394];// "Unknown"
+				strcat(pTmpBuf2.data(), pText);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 24://íàçâàíèå òîâàðà â ïðîäàæå
+				sprintfex(a1, format_4E2D80, Color16(255, 255, 155), a3->GetDisplayName());
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 25:
+				v29 = pPlayer->GetBaseBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+				switch (a5)
+				{
+				case 3:
+					v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+					break;
+				case 4:
+					v29 = pPlayer->GetBaseIdentifyPrice(p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+					break;
+				case 5:
+					v29 = pPlayer->GetBaseRepairPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+					break;
+				case 6:
+					v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2;
+					break;
+				}
+				sprintfex(a1, "%lu", v29);
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 27://òåêñò ïðîäàæè
+				v29 = pPlayer->GetBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+				if (a5 == 3)
+				{
+					v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+					if (a3->IsBroken())
+						v29 = 1;
+					sprintfex(a1, "%lu", v29);
+					strcat(pTmpBuf2.data(), a1);
+					dst = strlen(pTmpBuf2.data());
+					i += 2;
+					break;
+				}
+				if (a5 != 4)
+				{
+					if (a5 == 5)
+						v29 = pPlayer->GetPriceRepair(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
+					else
+					{
+						if (a5 == 6)
+						{
+							v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2;
+							if (a3->IsBroken())
+								v29 = 1;
+							if (!v29)
+								v29 = 1;
+							sprintfex(a1, "%lu", v29);
+							strcat(pTmpBuf2.data(), a1);
+							dst = strlen(pTmpBuf2.data());
+							i += 2;
+							break;
+						}
+					}
+					sprintfex(a1, "%lu", v29);
+					strcat(pTmpBuf2.data(), a1);
+					dst = strlen(pTmpBuf2.data());
+					i += 2;
+					break;
+				}
+				sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier));
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 28://ïðîôåññèÿ
+				strcat(pTmpBuf2.data(), (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 29:
+				sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier));
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 30:
+				if (!a6)
+				{
+					strcat(pTmpBuf2.data(), a4);
+					dst = strlen(pTmpBuf2.data());
+					i += 2;
+					break;
+				}
+				init_summoned_item(&v56, *a6);
+				sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year);
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			case 31:
+			case 32:
+			case 33:
+			case 34:
+				strcat(pTmpBuf2.data(), pParty->pPlayers[v17 - 31].pName);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			default:
+				if (v17 <= 50 || v17 > 70)
+				{
+					strncpy(a1, lpsz + i + 1, 2);
+					sprintf(a1, "%lu", atoi(a1));
+					strcat(pTmpBuf2.data(), a1);
+					dst = strlen(pTmpBuf2.data());
+					i += 2;
+					break;
+				}
+				if (v17 - 51 >= 20)
+				{
+					strcat(pTmpBuf2.data(), a4);
+					dst = strlen(pTmpBuf2.data());
+					i += 2;
+					break;
+				}
+				init_summoned_item(&v56, pParty->PartyTimes._s_times[v17 - 51]);
+				sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year);
+				strcat(pTmpBuf2.data(), a1);
+				dst = strlen(pTmpBuf2.data());
+				i += 2;
+				break;
+			}
+		}
+	}
+	return pTmpBuf2.data();
+}
+
+//----- (0044C175) --------------------------------------------------------
+void ShowStatusBarString(const char *pString, unsigned int uNumSeconds)
+{
+	strcpy(GameUI_Footer_TimedString.data(), pString);
+	GameUI_Footer_TimeLeft = 1000 * uNumSeconds + GetTickCount();
+
+	for (int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); i > 450;
+		i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()))
+		GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0;
+}
+
+//----- (0044C1D0) --------------------------------------------------------
+void ShowNothingHereStatus()
+{
+	if (!GameUI_Footer_TimeLeft)
+		ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here
+}
+
+//----- (0044C28B) --------------------------------------------------------
+int const_2()
+{
+	return 2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GUI/GUIWindow.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,841 @@
+#pragma once
+
+#include <cstdint>
+#include <array>
+
+#include "Engine/Objects/Player.h"
+
+enum UIMessageType: unsigned __int32
+{
+  UIMSG_0 = 0,
+
+  UIMSG_ChangeGameState = 5,
+
+  UIMSG_MouseLeftClickInGame = 10,
+
+  UIMSG_CHEST_ClickItem = 12,
+
+  UIMSG_MouseLeftClickInScreen = 14,
+  UIMSG_F = 15,
+
+  UIMSG_ChangeCursor = 17,
+
+  UIMSG_Attack = 23,
+
+  UIMSG_CastQuickSpell = 25,
+
+  UIMSG_STEALFROMACTOR = 27,
+  UIMSG_1C = 28,
+  UIMSG_PlayArcomage = 29,
+
+  UIMSG_31 = 49,
+  UIMSG_32 = 50,
+  UIMSG_SpellBook_PressTab = 51,
+  UIMSG_34 = 52,
+  UIMSG_35 = 53,
+  UIMSG_MainMenu_ShowPartyCreationWnd = 54,
+  UIMSG_MainMenu_ShowLoadWindow = 55,
+  UIMSG_ShowCredits = 56,
+  UIMSG_ExitToWindows = 57,
+  UIMSG_3A = 58,
+
+  UIMSG_PlayerCreationChangeName = 60,
+
+  UIMSG_PlayerCreationClickPlus = 62,
+  UIMSG_PlayerCreationClickMinus = 63,
+  UIMSG_PlayerCreationSelectActiveSkill = 64,
+  UIMSG_PlayerCreationSelectClass = 65,
+  UIMSG_PlayerCreationClickOK = 66,
+  UIMSG_PlayerCreationClickReset = 67,
+  UIMSG_44 = 68,
+  UIMSG_CastSpell_Character_Big_Improvement = 69,
+  UIMSG_CastSpell_Shoot_Monster = 70,
+  UIMSG_ClickBooksBtn = 71,
+  UIMSG_48 = 72,
+  UIMSG_49 = 73,
+  UIMSG_PlayerCreationRemoveUpSkill = 74,
+  UIMSG_PlayerCreationRemoveDownSkill = 75,
+
+  UIMSG_HintSelectRemoveQuickSpellBtn = 78,
+  UIMSG_SPellbook_ShowHightlightedSpellInfo = 79,
+
+  UIMSG_BuyInShop_Identify_Repair = 81,
+  UIMSG_LoadGame = 82,
+  UIMSG_SaveGame = 83,
+  UIMSG_54 = 84,
+  UIMSG_ChangeDetaliz = 85,
+  UIMSG_SelectSpell = 86,
+  UIMSG_OpenSpellbookPage = 87,
+  UIMSG_ClickInstallRemoveQuickSpellBtn = 88,
+
+  UIMSG_OnTravelByFoot = 90,
+  UIMSG_CHANGE_LOCATION_ClickCencelBtn = 91,
+  UIMSG_ShowStatus_DateTime = 92,
+  UIMSG_ShowStatus_ManaHP = 93,
+  UIMSG_ShowStatus_Player = 94,
+  UIMSG_Wait5Minutes  = 95,
+  UIMSG_Wait1Hour = 96,
+  UIMSG_Rest8Hour = 97,
+
+  UIMSG_ShowStatus_Food = 100,
+  UIMSG_ShowStatus_Funds = 101,
+
+  UIMSG_RestWindow = 104,
+  UIMSG_SpellBookWindow = 105,
+  UIMSG_QuickReference = 106,
+  UIMSG_GameMenuButton = 107,
+
+  UIMSG_AlreadyResting = 109,
+  UIMSG_SelectCharacter = 110,
+  UIMSG_ChangeSoundVolume = 111,
+  UIMSG_ChangeMusicVolume = 112,
+  UIMSG_Escape = 113,
+  UIMSG_ClickSkillsBtn = 114,
+  UIMSG_ClickStatsBtn = 115,
+  UIMSG_ClickInventoryBtn = 116,
+  UIMSG_ClickAwardsBtn = 117,
+  UIMSG_PlayerCreation_SelectAttribute = 118,
+
+  UIMSG_InventoryLeftClick = 120,
+  UIMSG_SkillUp = 121,
+  UIMSG_7A = 122,
+  UIMSG_GameMenu_ReturnToGame = 123,
+  UIMSG_StartNewGame = 124,
+  UIMSG_Game_OpenLoadGameDialog = 125,
+  UIMSG_Game_OpenSaveGameDialog = 126,
+  UIMSG_Game_OpenOptionsDialog = 127,
+  UIMSG_80 = 128,
+
+  UIMSG_SetGraphicsMode = 131,
+  UIMSG_Quit = 132,
+  UIMSG_ClickPaperdoll = 133,
+  UIMSG_StartHireling1Dialogue = 134,
+  UIMSG_StartHireling2Dialogue = 135,
+  UIMSG_SelectNPCDialogueOption = 136,
+
+  UIMSG_CastSpell_Monster_Improvement = 140,
+  UIMSG_CastSpell_Character_Small_Improvement = 141,
+  UIMSG_CastSpellFromBook = 142,
+  UIMSG_HiredNPC_CastSpell = 143,
+  UIMSG_PlayerCreation_VoicePrev = 144,
+  UIMSG_PlayerCreation_VoiceNext = 145,
+  UIMSG_SpellScrollUse = 146,
+
+  UIMSG_StartNPCDialogue = 161,
+  UIMSG_ArrowUp = 162,
+  UIMSG_DownArrow = 163,
+  UIMSG_SaveLoadBtn = 164,
+  UIMSG_SelectLoadSlot = 165,
+  UIMSG_Cancel = 166,
+  UIMSG_ExitRest = 167,
+  UIMSG_ClickExitCharacterWindowBtn = 168,
+  UIMSG_ClickAwardsUpBtn = 169,
+  UIMSG_ClickAwardsDownBtn = 170,
+  UIMSG_PlayerCreation_FacePrev = 171,
+  UIMSG_PlayerCreation_FaceNext = 172,
+  UIMSG_AD = 173,
+  UIMSG_AE = 174,
+  UIMSG_ClickNPCTopic = 175,
+  UIMSG_CycleCharacters = 176,
+  UIMSG_OnCastLloydsBeacon = 177,
+  UIMSG_LloydsBeacon_FlippingBtn = 178,
+  UIMSG_InstallBeacon = 179,
+  UIMSG_HintBeaconSlot = 180,
+  UIMSG_CloseAfterInstallBeacon = 181,
+  UIMSG_HintTownPortal = 182,
+  UIMSG_ClickTownInTP = 183,
+  UIMSG_SetTurnSpeed = 184,
+  UIMSG_ToggleWalkSound = 185,
+  UIMSG_ChangeVoiceVolume = 186,
+  UIMSG_ToggleShowDamage = 187,
+  UIMSG_ScrollNPCPanel = 188,
+  UIMSG_BD = 189,
+  UIMSG_CastSpell_Telekinesis = 190,
+  UIMSG_BF = 191,
+  UIMSG_ClickAwardScrollBar = 192,
+  UIMSG_C1 = 192,
+  UIMSG_C2 = 192,
+
+  UIMSG_OnCastTownPortal = 195,
+  UIMSG_OnFinalWindowClose = 196,
+  UIMSG_ShowFinalWindow = 197,
+  UIMSG_C6 = 198,
+  UIMSG_C7 = 199,
+  UIMSG_OpenQuestBook = 200,
+  UIMSG_OpenAutonotes = 201,
+  UIMSG_OpenMapBook = 202,
+  UIMSG_OpenCalendar = 203,
+  UIMSG_CC = 204,
+  UIMSG_CD = 205,
+  UIMSG_CE = 206,
+  UIMSG_CF = 207,
+  UIMSG_D0 = 208,
+  UIMSG_D1 = 209,
+  UIMSG_D2 = 210,
+  UIMSG_D3 = 211,
+  UIMSG_D4 = 212,
+  UIMSG_D5 = 213,
+  UIMSG_D6 = 214,
+
+  UIMSG_DD = 221,
+
+  UIMSG_OpenHistoryBook = 224,
+  UIMSG_ToggleAlwaysRun = 225,
+  UIMSG_ToggleFlipOnExit = 226,
+
+  UIMSG_ClickZoomOutBtn = 367,
+  UIMSG_ClickZoomInBtn = 368,
+
+  UIMSG_Game_Action = 404,
+  UIMSG_SelectShopDialogueOption = 405,
+
+  UIMSG_RentRoom = 409,
+  UIMSG_ClickHouseNPCPortrait = 410,
+  UIMSG_TransitionUI_Confirm = 411,
+  UIMSG_TransitionWindowCloseBtn = 412,
+
+  UIMSG_OpenKeyMappingOptions = 415,
+  UIMSG_SelectKeyPage1 = 416,
+  UIMSG_SelectKeyPage2 = 417,
+  UIMSG_ResetKeyMapping = 418,
+  UIMSG_ChangeKeyButton = 419,
+
+  UIMSG_OpenVideoOptions = 421,
+  UIMSG_ToggleBloodsplats = 422,
+  UIMSG_ToggleColoredLights = 423,
+  UIMSG_ToggleTint = 424,
+  UIMSG_1A9 = 425,
+
+  UIMSG_MMT_MainMenu_MM6 = 426,
+  UIMSG_MMT_MainMenu_MM7 = 427,
+  UIMSG_MMT_MainMenu_MM8 = 428,
+  UIMSG_MMT_MainMenu_Continue = 429,
+
+};
+
+
+/*  251 */
+enum MENU_STATE : __int32
+{
+  MENU_MAIN = 0,
+  MENU_NEWGAME = 1,
+  MENU_CREDITS = 2,
+  MENU_SAVELOAD = 3,
+  MENU_EXIT_GAME = 4,
+  MENU_5 = 5,
+  MENU_CREATEPARTY = 6,
+  MENU_NAMEPANELESC = 7,
+  MENU_CREDITSPROC = 8,
+  MENU_LoadingProcInMainMenu = 9,
+  MENU_DebugBLVLevel = 10,
+  MENU_CREDITSCLOSE = 11,
+  MENU_MMT_MAIN_MENU = 12,
+};
+
+
+enum DIALOGUE_TYPE
+{
+  DIALOGUE_USE_NPC_ABILITY = 9,
+  DIALOGUE_13 = 0xD,
+  DIALOGUE_18 = 18,
+  DIALOGUE_EVT_A = 19,
+  DIALOGUE_EVT_B = 20,
+  DIALOGUE_EVT_C = 21,
+  DIALOGUE_EVT_D = 22,
+  DIALOGUE_EVT_E = 23,
+  DIALOGUE_EVT_F = 0x18,
+  DIALOGUE_76 = 76,
+  DIALOGUE_PROFESSION_DETAILS = 77,
+  DIALOGUE_SKILL_TRAINER = 78,
+  DIALOGUE_84 = 84,
+  DIALOGUE_ARENA_SELECT_PAGE = 85,
+  DIALOGUE_ARENA_SELECT_SQUIRE = 86,
+  DIALOGUE_ARENA_SELECT_KNIGHT = 87,
+  DIALOGUE_ARENA_SELECT_CHAMPION = 88,
+  DIALOGUE_ARENA_WELCOME = 89,
+  DIALOGUE_ARENA_FIGHT_NOT_OVER_YET = 90,
+  DIALOGUE_ARENA_REWARD = 91,
+  DIALOGUE_ARENA_ALREADY_WON = 92,
+};
+
+
+
+
+
+/*  298 */
+enum WindowType: unsigned __int32
+{
+  WINDOW_null            = 0,
+  WINDOW_MainMenu        = 1,
+  WINDOW_OptionsButtons  = 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_SaveLoadButtons = 23,
+  WINDOW_MainMenu_Load = 0x18,
+  WINDOW_HouseInterior = 0x19,
+  WINDOW_Transition = 26,
+  WINDOW_CastSpell = 27,
+  WINDOW_Scroll = 0x1E,
+  WINDOW_CastSpell_InInventory = 31,
+  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_CharacterWindow_Inventory = 0x67,
+  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,
+};
+
+struct GUIButton;
+struct Texture;
+
+
+#define WINDOW_INPUT_NONE        0
+#define WINDOW_INPUT_IN_PROGRESS 1
+#define WINDOW_INPUT_CONFIRMED   2
+#define WINDOW_INPUT_CANCELLED   3
+
+/*  155 */
+#pragma pack(push, 1)
+struct GUIWindow
+{
+  inline GUIWindow()
+  {
+    pControlsHead = pControlsTail = nullptr;
+    eWindowType = WINDOW_null;
+  }
+
+  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, ...);
+  void DrawFlashingInputCursor(signed int uX, int uY, struct GUIFont *a2);
+  int DrawTextInRect(GUIFont *pFont, unsigned int uX, unsigned int uY, unsigned int uColor, const char *text, int rect_width, int reverse_text);
+  void DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, signed int uFontShadowColor);
+  void DrawTitleText(GUIFont *a2, signed int uHorizontalMargin, unsigned int uVerticalMargin, unsigned __int16 uDefaultColor, const char *pInString, unsigned int uLineSpacing);
+  void DrawShops_next_generation_time_string(__int64 next_generation_time);
+  void HouseDialogManager();
+  void OpenSpellBook();
+  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);
+
+  unsigned int uFrameX;
+  unsigned int uFrameY;
+  unsigned int uFrameWidth;
+  unsigned int uFrameHeight;
+  unsigned int uFrameZ;
+  unsigned int uFrameW;
+  WindowType   eWindowType;
+  union{
+  void *ptr_1C;// sometimes BuildID_2Events
+  unsigned int par1C;
+	};
+  unsigned int uNumControls;
+  int field_24;
+  int pNumPresenceButton; 
+  int pCurrentPosActiveItem;
+  int field_30;
+  int field_34;
+  int pStartingPosActiveItem;
+  int numVisibleWindows;
+  int receives_keyboard_input_2; //  0  no input   1 currently typing   2 enter pressed   3 escape pressed
+  int receives_keyboard_input;
+  const char *Hint;
+  GUIButton *pControlsHead;
+  GUIButton *pControlsTail;
+};
+#pragma pack(pop)
+
+
+
+
+
+
+
+
+enum CURRENT_SCREEN
+{
+  SCREEN_GAME = 0x0,
+  SCREEN_MENU = 0x1,
+  SCREEN_OPTIONS = 0x2,
+  SCREEN_BOOKS = 0x3,
+  SCREEN_NPC_DIALOGUE = 0x4,
+  SCREEN_REST = 0x5,
+  SCREEN_CHARACTERS = 0x7,
+  SCREEN_SPELL_BOOK = 0x8,
+  SCREEN_CREATORS = 0x9,
+  SCREEN_CHEST = 0xA,
+  SCREEN_SAVEGAME = 0xB,
+  SCREEN_LOADGAME = 0xC,
+  SCREEN_HOUSE = 0xD,
+  SCREEN_E = 0xE,
+  SCREEN_CHEST_INVENTORY = 0xF,
+  SCREEN_VIDEO = 0x10,
+  SCREEN_CHANGE_LOCATION = 0x11,
+  SCREEN_INPUT_BLV = 0x12,
+  SCREEN_BRANCHLESS_NPC_DIALOG = 0x13,
+  SCREEN_PARTY_CREATION = 0x15,
+  SCREEN_MODAL_WINDOW = 0x16,
+  SCREEN_CASTING = 0x17,
+  SCREEN_19 = 0x19,
+  SCREEN_KEYBOARD_OPTIONS = 0x1A,
+  SCREEN_1B = 0x1B,
+  SCREEN_VIDEO_OPTIONS = 0x1C,
+  SCREEN_63 = 0x63,
+  SCREEN_64 = 0x64,
+  SCREEN_67 = 0x67,
+  SCREEN_QUICK_REFERENCE = 0x68,
+};
+
+
+
+
+/*  249 */
+#pragma pack(push, 1)
+struct GUIMessage
+{
+  enum UIMessageType eType;
+  int param;
+  int field_8;
+};
+#pragma pack(pop)
+
+
+
+
+#define AddGUIMessage(msg, param, a4) AddMessageImpl((msg), (param), (a4), __FILE__, __LINE__)
+/*  250 */
+#pragma pack(push, 1)
+struct GUIMessageQueue
+{
+  inline GUIMessageQueue():
+    uNumMessages(0)
+  {}
+
+  void Flush();
+  void PopMessage(UIMessageType *pMsg, int *pParam, int *a4);
+  void AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file = nullptr, int line = 0);
+
+  unsigned int uNumMessages;
+  GUIMessage pMessages[40];
+
+  const char *files[40];
+  int          lines[40];
+};
+#pragma pack(pop)
+
+extern struct GUIMessageQueue *pMessageQueue_50CBD0; // idb
+
+extern struct GUIMessageQueue *pMessageQueue_50C9E8; // idb
+
+
+
+void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType);
+
+
+
+extern int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[]; // idb
+extern struct GUIWindow *pWindow_MMT_MainMenu;
+extern struct GUIWindow *pWindow_MainMenu;
+extern std::array<struct GUIWindow, 20> pWindowList;
+
+
+
+
+void ModalWindow(const char *pStrHint, UIMessageType OnRelease_message);
+void ModalWindow_ShowHint();
+void ModalWindow_Release();
+
+
+
+void draw_leather();
+
+
+// main menu ui
+void MainMenuUI_LoadFontsAndSomeStuff();
+void MainMenuUI_Create();
+MENU_STATE MainMenuUI_Credits_Loop();
+
+// save & load ui
+void SaveUI_Load();
+void SaveUI_Draw();
+
+void LoadUI_Draw();
+void LoadUI_Load(unsigned int uDialogueType); // idb
+
+// game ui
+void GameUI_DrawRightPanel();
+void GameUI_DrawRightPanelFrames();
+void GameUI_DrawRightPanelItems();
+void GameUI_QuickRef_Draw();
+void GameUI_DrawFoodAndGold();
+void GameUI_DrawLifeManaBars();
+void GameUI_DrawHiredNPCs();
+void GameUI_DrawPortraits(unsigned int _this);
+void GameUI_Footer();
+void GameUI_Footer_2();
+void GameUI_SetFooterString(const char *pStr);
+void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap);
+auto GameUI_GetMinimapHintText() -> const char *;
+void GameUI_DrawPartySpells();
+void GameUI_DrawTorchlightAndWizardEye();
+void GameUI_DrawCharacterSelectionFrame();
+void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player);
+void GameUI_DrawNPCPopup(void *_this);
+
+void GameUI_InitializeDialogue(struct Actor *actor, int bPlayerSaysHello);
+void GameUI_DrawBranchlessDialogue();
+void GameUI_DrawDialogue();
+
+
+// game menu ui
+void GameMenuUI_DrawKeyBindings();
+void GameMenuUI_DrawVideoOptions();
+void GameMenuUI_Options_Draw();
+
+
+
+
+// character ui
+struct GUIWindow *CharacterUI_Initialize(unsigned int _this);
+const char *CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType);
+void CharacterUI_SkillsTab_ShowHint();
+void CharacterUI_StatsTab_ShowHint();
+void CharacterUI_StatsTab_Draw(Player *player);
+void CharacterUI_SkillsTab_CreateButtons();
+void CharacterUI_SkillsTab_Draw(Player *player);
+void CharacterUI_AwardsTab_Draw(Player *player);
+void CharacterUI_InventoryTab_Draw(Player *player, bool a2);
+void CharacterUI_CharacterScreen_Draw(Player *player);
+void CharacterUI_DrawPaperdoll(Player *player);
+void CharacterUI_DrawPaperdollWithRingOverlay(Player *player);
+void CharacterUI_ReleaseButtons();
+
+unsigned int GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level);
+
+
+
+
+
+// book ui
+void BookUI_Draw(WindowType book);
+void BookUI_Questbook_Draw();
+void BookUI_Autonotes_Draw();
+void BookUI_Map_Draw();
+void BookUI_Calendar_Draw();
+void BookUI_Journal_Draw();
+
+void OnCloseBook();
+void InitializeBookTextures();
+void InitializeBookFonts();
+void DrawSpellBookContent(Player *player);
+unsigned int  DrawLloydBeaconsScreen();
+void BookUI_DrawTownPortalMap();
+void LoadSpellbook(unsigned int uID); // idb
+void DrawSpellDescriptionPopup(int spell_index);
+void OnCloseSpellBookPage();
+void OnCloseSpellBook();
+
+
+
+// rest ui
+void RestUI_Load();
+void RestUI_Draw();
+
+
+// transition & travel ui
+void TransitionUI_Load(uint32_t anim_id, uint32_t exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName);
+void TransitionUI_Draw();
+
+void TravelUI_Load();
+void TravelUI_Draw();
+
+
+
+
+
+void UI_OnMouseRightClick(Vec2_int_ *_this);
+
+void __fastcall DrawPopupWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight); // idb
+void DrawMM7CopyrightWindow();
+//void LoadFonts_and_DrawCopyrightWindow();
+void GUI_UpdateWindows();
+int GetConditionDrawColor(unsigned int uConditionIdx); // idb
+void FillAwardsData();
+void CreateAwardsScrollBar();
+void ReleaseAwardsScrollBar();
+void Inventory_ItemPopupAndAlchemy();
+void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer);
+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 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);
+void SetUserInterface(enum PartyAlignment alignment, bool bReplace);
+void CreateMsgScrollWindow(signed int mscroll_id);
+void free_book_subwindow();
+void CreateScrollWindow();
+void OnPaperdollLeftClick();
+void DrawJoinGuildWindow(int pEventCode);
+void  DialogueEnding();
+char sub_4637E0_is_there_popup_onscreen();
+void sub_4B3E1E();
+void __fastcall ClickNPCTopic(signed int uMessageParam);
+void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
+void _4B3FE5_training_dialogue(int a4);
+void OracleDialogue();
+void CheckBountyRespawnAndAward();
+const char * _4B254D_SkillMasteryTeacher(int trainerInfo);
+char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6);
+void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
+void ShowStatusBarString(const char *pString, unsigned int uNumSeconds);
+void ShowNothingHereStatus();
+int const_2();
+
+
+void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue);
+void __fastcall ZBuffer_DoFill(int *pZBuffer, struct Texture *pTex, int uZValue);
+void __fastcall ZBuffer_DoFill2(int *pZBuffer, struct Texture *a2, int a3); // idb
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#pragma pack(push, 1)
+struct GUIButton
+{
+void DrawLabel(const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor);
+
+  void Release();
+
+
+  unsigned int uX;
+  unsigned int uY;
+  unsigned int uWidth;
+  unsigned int uHeight;
+  unsigned int uZ;
+  unsigned int uW;
+  int uButtonType;
+  int field_1C;//may be pMessageType
+  UIMessageType msg;
+  unsigned int  msg_param;
+  int field_28;
+  int field_2C_is_pushed;
+  GUIButton *pPrev;
+  GUIButton *pNext;
+  struct GUIWindow *pParent;
+  struct Texture *pTextures[5];
+  unsigned int uNumTextures;
+  unsigned __int8 uHotkey;
+  char pButtonName[32];
+  char field_75[71];
+};
+#pragma pack(pop)
+
+
+
+
+extern struct GUIButton *pBtn_CloseBook;
+extern struct GUIButton *pBtn_InstallRemoveSpell;
+extern struct GUIButton *pBtn_Autonotes_Instructors;
+extern struct GUIButton *pBtn_Autonotes_Misc;
+extern struct GUIButton *pBtn_Book_6;
+extern struct GUIButton *pBtn_Book_5;
+extern struct GUIButton *pBtn_Book_4;
+extern struct GUIButton *pBtn_Book_3;
+extern struct GUIButton *pBtn_Book_2;
+extern struct GUIButton *pBtn_Book_1;
+
+
+extern struct GUIButton *pPlayerCreationUI_BtnReset;
+extern struct GUIButton *pPlayerCreationUI_BtnOK;
+extern struct GUIButton *pBtn_ExitCancel;
+extern struct GUIButton *pBtn_YES;
+extern struct GUIButton *pPlayerCreationUI_BtnPlus;
+extern struct GUIButton *pPlayerCreationUI_BtnMinus;
+
+
+extern struct GUIButton *pButton_RestUI_Main;
+extern struct GUIButton *pButton_RestUI_Exit;
+extern struct GUIButton *pButton_RestUI_Wait5Minutes;
+extern struct GUIButton *pButton_RestUI_WaitUntilDawn;
+extern struct GUIButton *pButton_RestUI_Wait1Hour;
+
+
+extern struct GUIButton *pCharacterScreen_ExitBtn;
+extern struct GUIButton *pCharacterScreen_AwardsBtn;
+extern struct GUIButton *pCharacterScreen_InventoryBtn;
+extern struct GUIButton *pCharacterScreen_SkillsBtn;
+extern struct GUIButton *pCharacterScreen_StatsBtn;
+extern struct GUIButton *pCharacterScreen_DollBtn;
+extern struct GUIButton *pCharacterScreen_DetalizBtn;
+
+
+extern struct GUIButton *pBtn_NPCRight;
+extern struct GUIButton *pBtn_NPCLeft;
+extern struct GUIButton *pBtn_GameSettings;
+extern struct GUIButton *pBtn_QuickReference;
+extern struct GUIButton *pBtn_CastSpell;
+extern struct GUIButton *pBtn_Rest;
+extern struct GUIButton *pBtn_History;
+extern struct GUIButton *pBtn_Calendar;
+extern struct GUIButton *pBtn_Maps;
+extern struct GUIButton *pBtn_Autonotes;
+extern struct GUIButton *pBtn_Quests;
+
+
+extern struct GUIButton *pMMT_MainMenu_BtnMM6;
+extern struct GUIButton *pMMT_MainMenu_BtnMM7;
+extern struct GUIButton *pMMT_MainMenu_BtnMM8;
+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;
+extern struct GUIButton *ptr_507BA4;
+
+
+extern struct GUIWindow *pPrimaryWindow;
+extern struct GUIWindow *pChestWindow;
+extern struct GUIWindow *pDialogueWindow;
+extern struct GUIWindow *window_SpeakInHouse;
+extern struct GUIWindow *pGUIWindow_ScrollWindow;
+extern struct GUIWindow *ptr_507BC8;
+extern struct GUIWindow *pGUIWindow_CurrentMenu;
+extern struct GUIWindow *ptr_507BD0;
+extern struct GUIWindow *pGUIWindow_Settings;
+extern struct GUIWindow *pModalWindow;
+extern struct GUIWindow *pGUIWindow_EscMessageWindow;
+extern struct GUIWindow *pBooksWindow;
+extern struct GUIWindow *pGUIWindow2;
+
+
+extern struct GUIButton *pBtn_Resume;
+extern struct GUIButton *pBtn_QuitGame;
+extern struct GUIButton *pBtn_GameControls;
+extern struct GUIButton *pBtn_LoadGame;
+extern struct GUIButton *pBtn_SaveGame;
+extern struct GUIButton *pBtn_NewGame;
+
+extern struct GUIButton *pBtn_SliderRight;
+extern struct GUIButton *pBtn_SliderLeft;
+
+
+extern struct GUIButton *pBtnDownArrow;
+extern struct GUIButton *pBtnArrowUp;
+extern struct GUIButton *pBtnCancel;
+extern struct GUIButton *pBtnLoadSlot;
+
+
+extern std::array<GUIButton*, 4> pCreationUI_BtnPressRight2;
+extern std::array<GUIButton*, 4> pCreationUI_BtnPressLeft2;
+extern std::array<GUIButton*, 4> pCreationUI_BtnPressLeft;
+extern std::array<GUIButton*, 4> pCreationUI_BtnPressRight;
+
+extern int uTextureID_GameUI_CharSelectionFrame; // 50C98C
+
+extern unsigned int ui_mainmenu_copyright_color;
+extern unsigned int ui_character_tooltip_header_default_color;
+extern unsigned int ui_character_default_text_color;
+extern unsigned int ui_character_skill_highlight_color;
+extern unsigned int ui_character_header_text_color;
+extern unsigned int ui_character_bonus_text_color;
+extern unsigned int ui_character_bonus_text_color_neg;
+extern unsigned int ui_character_skill_upgradeable_color;
+extern unsigned int ui_character_skill_default_color;
+extern unsigned int ui_character_stat_default_color;
+extern unsigned int ui_character_stat_buffed_color;
+extern unsigned int ui_character_stat_debuffed_color;
+extern unsigned int ui_character_skillinfo_can_learn;
+extern unsigned int ui_character_skillinfo_can_learn_gm;
+extern unsigned int ui_character_skillinfo_cant_learn;
+extern unsigned int ui_character_condition_normal_color;
+extern unsigned int ui_character_condition_light_color;
+extern unsigned int ui_character_condition_moderate_color;
+extern unsigned int ui_character_condition_severe_color;
+extern std::array<unsigned int, 6> ui_character_award_color;
+extern unsigned int ui_game_minimap_outline_color;
+extern unsigned int ui_game_minimap_actor_friendly_color;
+extern unsigned int ui_game_minimap_actor_hostile_color;
+extern unsigned int ui_game_minimap_actor_corpse_color;
+extern unsigned int ui_game_minimap_decoration_color_1;
+extern unsigned int ui_game_minimap_projectile_color;
+extern unsigned int ui_game_minimap_treasure_color;
+extern std::array<unsigned int, 24> ui_game_character_record_playerbuff_colors;
+extern unsigned int ui_gamemenu_video_gamma_title_color;
+extern unsigned int ui_gamemenu_keys_action_name_color;
+extern unsigned int ui_gamemenu_keys_key_selection_blink_color_1;
+extern unsigned int ui_gamemenu_keys_key_selection_blink_color_2;
+extern unsigned int ui_gamemenu_keys_key_default_color;
+extern unsigned int ui_book_quests_title_color;
+extern unsigned int ui_book_quests_text_color;
+extern unsigned int ui_book_autonotes_title_color;
+extern unsigned int ui_book_autonotes_text_color;
+extern unsigned int ui_book_map_title_color;
+extern unsigned int ui_book_map_coordinates_color;
+extern unsigned int ui_book_calendar_title_color;
+extern unsigned int ui_book_calendar_time_color;
+extern unsigned int ui_book_calendar_day_color;
+extern unsigned int ui_book_calendar_month_color;
+extern unsigned int ui_book_calendar_year_color;
+extern unsigned int ui_book_calendar_moon_color;
+extern unsigned int ui_book_calendar_location_color;
+extern unsigned int ui_book_journal_title_color;
+extern unsigned int ui_book_journal_text_color;
+extern unsigned int ui_book_journal_text_shadow;
+extern unsigned int ui_game_dialogue_npc_name_color;
+extern unsigned int ui_game_dialogue_option_highlight_color;
+extern unsigned int ui_game_dialogue_option_normal_color;
+extern unsigned int ui_house_player_cant_interact_color;
\ No newline at end of file
--- a/GUI/UI/Books/UIMapBook.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/Books/UIMapBook.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -3,13 +3,13 @@
 #include "..\..\..\Engine/Events.h"
 #include "..\..\..\Engine/MM7.h"
 #include "..\..\..\Engine/Graphics/Render.h"
-#include "..\..\..\Mouse.h"
+#include "..\..\..\IO/Mouse.h"
 #include "..\UIBooks.h"
 #include "..\..\..\Engine/MapInfo.h"
-#include "..\..\..\GUIWindow.h"
-#include "..\..\..\GUIFont.h"
+#include "..\..\..\GUI/GUIWindow.h"
+#include "..\..\..\GUI/GUIFont.h"
 #include "..\..\..\Engine/Party.h"
-#include "..\..\..\AudioPlayer.h"
+#include "..\..\..\Media/Audio/AudioPlayer.h"
 #include "..\..\..\Engine/Graphics/Outdoor.h"
 #include "..\..\..\Engine/LOD.h"
 #include "..\..\..\Engine/Graphics/Viewport.h"
--- a/GUI/UI/Books/UINotesBooks.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/Books/UINotesBooks.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -1,13 +1,13 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "..\..\..\Engine/MM7.h"
 #include "..\..\..\Engine/Graphics/Render.h"
-#include "..\..\..\Mouse.h"
+#include "..\..\..\IO/Mouse.h"
 #include "..\UIBooks.h"
 #include "..\..\..\Engine/MapInfo.h"
-#include "..\..\..\GUIWindow.h"
-#include "..\..\..\GUIFont.h"
+#include "..\..\..\GUI/GUIWindow.h"
+#include "..\..\..\GUI/GUIFont.h"
 #include "..\..\..\Engine/Party.h"
-#include "..\..\..\AudioPlayer.h"
+#include "..\..\..\Media/Audio/AudioPlayer.h"
 #include "..\..\..\Engine/LOD.h"
 #include "..\..\..\Engine/Graphics/Viewport.h"
 #include "..\..\..\Engine/Awards.h"
--- a/GUI/UI/Books/UISpellBook.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/Books/UISpellBook.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -1,12 +1,12 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "..\..\..\Engine/MM7.h"
 #include "..\..\..\Engine/Graphics/Render.h"
-#include "..\..\..\Mouse.h"
+#include "..\..\..\IO/Mouse.h"
 #include "..\UIBooks.h"
-#include "..\..\..\GUIWindow.h"
-#include "..\..\..\GUIFont.h"
+#include "..\..\..\GUI/GUIWindow.h"
+#include "..\..\..\GUI/GUIFont.h"
 #include "..\..\..\Engine/Party.h"
-#include "..\..\..\AudioPlayer.h"
+#include "..\..\..\Media/Audio/AudioPlayer.h"
 #include "..\..\..\Engine/LOD.h"
 #include "..\..\..\Engine/Graphics/Viewport.h"
 #include "..\..\..\Engine/texts.h"
--- a/GUI/UI/UIArena.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIArena.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -7,10 +7,10 @@
 #include "../../Engine/mm7_data.h"
 #include "../../Engine/Graphics/Sprites.h"
 
-#include "../../GUIWindow.h"
-#include "../../GUIFont.h"
+#include "../../GUI/GUIWindow.h"
+#include "../../GUI/GUIFont.h"
 #include "../../Engine/Party.h"
-#include "../../AudioPlayer.h"
+#include "../../Media/Audio/AudioPlayer.h"
 #include "../../Engine/Graphics/Outdoor.h"
 #include "../../Engine/LOD.h"
 #include "../../Engine/Objects/Actor.h"
--- a/GUI/UI/UIBooks.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIBooks.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -6,9 +6,9 @@
 #include "..\../Engine/MM7.h"
 #include "UIBooks.h"
 #include "..\../Engine/Graphics/Render.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
-#include "..\../AudioPlayer.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/LOD.h"
 
 #include "..\../Engine/mm7_data.h"
--- a/GUI/UI/UICharacter.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UICharacter.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,11 +8,11 @@
 #include "..\../Engine/MM7.h"
 #include "..\../Engine/MapInfo.h"
 #include "..\../Engine/Game.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
-#include "..\../GUIProgressBar.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
+#include "..\../GUI/GUIProgressBar.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Graphics/Viewport.h"
@@ -20,7 +20,7 @@
 #include "..\../Engine/Awards.h"
 #include "..\../Engine/Spells/CastSpellInfo.h"
 #include "..\../Engine/texts.h"
-#include "..\../Mouse.h"
+#include "..\../IO/Mouse.h"
 
 #include "..\../Engine/mm7_data.h"
 
--- a/GUI/UI/UIGuilds.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIGuilds.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -4,17 +4,17 @@
 
 #define _CRT_SECURE_NO_WARNINGS
 #include "..\../Engine/Objects/Items.h"
-#include "..\../GUIWindow.h"
+#include "..\../GUI/GUIWindow.h"
 #include "..\../Engine/mm7_data.h"
 #include "..\../Engine/texts.h"
 #include "UIHouses.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/Party.h"
 #include "..\../Engine/Graphics/Texture.h"
-#include "..\../Mouse.h"
+#include "..\../IO/Mouse.h"
 #include "..\../Engine/Events2D.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/LOD.h"
 
 //----- (004B5D7C) --------------------------------------------------------
--- a/GUI/UI/UIHouses.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIHouses.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -6,7 +6,7 @@
 #include "UIGuilds.h"
 #include "UIPartyCreation.h"
 #include "UIShops.h"
-#include "..\../GUIButton.h"
+#include "..\../GUI/GUIButton.h"
 #include "..\../Engine/SaveLoad.h"
 #include "..\../Engine/Graphics/Texture.h"
 #include "..\../Engine/mm7_data.h"
@@ -17,16 +17,16 @@
 #include "..\../Engine/Events.h"
 #include "..\../Arcomage/Arcomage.h"
 #include "..\../Engine/LOD.h"
-#include "..\../Mouse.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../IO/Mouse.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Graphics/Overlays.h"
 #include "..\../Engine/Graphics/Outdoor.h"
-#include "..\../AudioPlayer.h"
-#include "..\../MediaPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
+#include "..\../Media/MediaPlayer.h"
 #include "..\../Engine/Objects/Monsters.h"
 #include "..\../Engine/Graphics/Viewport.h"
-#include "..\../Keyboard.h"
+#include "..\../IO/Keyboard.h"
 #include "..\../Engine/MapInfo.h"
 #include "..\../Engine/Log.h"
 #include "..\../Engine/Game.h"
--- a/GUI/UI/UIMainMenu.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIMainMenu.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -3,13 +3,13 @@
 #include <crtdbg.h>
 
 #define _CRT_SECURE_NO_WARNINGS
-#include "..\../Mouse.h"
-#include "..\../Keyboard.h"
+#include "..\../IO/Mouse.h"
+#include "..\../IO/Keyboard.h"
 #include "..\../Engine/ErrorHandling.h"
 
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
-#include "..\../AudioPlayer.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Graphics/PaletteManager.h"
--- a/GUI/UI/UIOptions.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIOptions.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -5,15 +5,15 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "..\../Engine/MM7.h"
 
-#include "..\../Keyboard.h"
+#include "..\../IO/Keyboard.h"
 #include "..\../Engine/Graphics/IndoorCameraD3D.h"
 #include "..\../Engine/Graphics/GammaControl.h"
 #include "..\../Engine/Graphics/Render.h"
 
 #include "..\../Engine/Game.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
-#include "..\../AudioPlayer.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/texts.h"
 
--- a/GUI/UI/UIPartyCreation.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIPartyCreation.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -4,15 +4,15 @@
 
 #define _CRT_SECURE_NO_WARNINGS
 #include "UIPartyCreation.h"
-#include "..\../Mouse.h"
-#include "..\../Keyboard.h"
+#include "..\../IO/Mouse.h"
+#include "..\../IO/Keyboard.h"
 #include "..\../Engine/ErrorHandling.h"
 
 #include "..\../Engine/Game.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Timer.h"
--- a/GUI/UI/UIPopup.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIPopup.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,15 +8,15 @@
 #include "UIShops.h"
 #include "..\../Engine/MM7.h"
 
-#include "..\../Mouse.h"
+#include "..\../IO/Mouse.h"
 
 #include "..\../Engine/Graphics/Sprites.h"
 #include "..\../Engine/Graphics/Vis.h"
 #include "..\../Engine/Game.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Objects/Actor.h"
 #include "..\../Engine/Graphics/Viewport.h"
--- a/GUI/UI/UIRest.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIRest.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -3,10 +3,10 @@
 #include <crtdbg.h>
 
 #define _CRT_SECURE_NO_WARNINGS
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Outdoor.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Graphics/Viewport.h"
--- a/GUI/UI/UISaveLoad.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UISaveLoad.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,11 +8,11 @@
 #include "..\../Engine/MM7.h"
 #include "..\../Engine/ErrorHandling.h"
 
-#include "..\../Keyboard.h"
+#include "..\../IO/Keyboard.h"
 
 #include "..\../Engine/MapInfo.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/SaveLoad.h"
--- a/GUI/UI/UIShops.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UIShops.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -5,17 +5,17 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "UIShops.h"
 #include "..\../Engine/Objects/Items.h"
-#include "..\../GUIWindow.h"
+#include "..\../GUI/GUIWindow.h"
 #include "..\../Engine/mm7_data.h"
 #include "..\../Engine/texts.h"
 #include "UIHouses.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Graphics/Render.h"
 #include "..\../Engine/Party.h"
 #include "..\../Engine/Graphics/Texture.h"
-#include "..\../Mouse.h"
+#include "..\../IO/Mouse.h"
 #include "..\../Engine/Events2D.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/MapInfo.h"
 #include "..\../Engine/Graphics/Viewport.h"
 #include "..\../Engine/Graphics/Outdoor.h"
--- a/GUI/UI/UITransition.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UITransition.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -7,13 +7,13 @@
 
 #include "..\../Engine/ErrorHandling.h"
 #include "..\../Engine/mm7_data.h"
-#include "..\../MediaPlayer.h"
+#include "..\../Media/MediaPlayer.h"
 #include "..\../Engine/MapInfo.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
-#include "..\../GUIProgressBar.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
+#include "..\../GUI/GUIProgressBar.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Outdoor.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Timer.h"
--- a/GUI/UI/UiGame.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/GUI/UI/UiGame.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -8,17 +8,17 @@
 #include "..\../Engine/MM7.h"
 #include "..\../Engine/ErrorHandling.h"
 
-#include "..\../Mouse.h"
-#include "..\../Keyboard.h"
+#include "..\../IO/Mouse.h"
+#include "..\../IO/Keyboard.h"
 #include "..\../Engine/mm7_data.h"
 
 #include "..\../Engine/Graphics/Vis.h"
 #include "..\../Engine/MapInfo.h"
 #include "..\../Engine/Game.h"
-#include "..\../GUIWindow.h"
-#include "..\../GUIFont.h"
+#include "..\../GUI/GUIWindow.h"
+#include "..\../GUI/GUIFont.h"
 #include "..\../Engine/Party.h"
-#include "..\../AudioPlayer.h"
+#include "..\../Media/Audio/AudioPlayer.h"
 #include "..\../Engine/Graphics/Outdoor.h"
 #include "..\../Engine/LOD.h"
 #include "..\../Engine/Objects/Actor.h"
--- a/GUIButton.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,247 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "GUIButton.h"
-#include "GUIWindow.h"
-#include "GUIFont.h"
-
-#include "Engine/mm7_data.h"
-#include "Engine/LOD.h"
-#include "Engine/Texts.h"
-#include "OSWindow.h"
-
-
-
-struct GUIButton *pBtn_CloseBook;
-struct GUIButton *pBtn_InstallRemoveSpell;
-struct GUIButton *pBtn_Autonotes_Instructors;
-struct GUIButton *pBtn_Autonotes_Misc;
-struct GUIButton *pBtn_Book_6;
-struct GUIButton *pBtn_Book_5;
-struct GUIButton *pBtn_Book_4;
-struct GUIButton *pBtn_Book_3;
-struct GUIButton *pBtn_Book_2;
-struct GUIButton *pBtn_Book_1;
-
-
-struct GUIButton *pPlayerCreationUI_BtnReset;
-struct GUIButton *pPlayerCreationUI_BtnOK;
-struct GUIButton *pBtn_ExitCancel;
-struct GUIButton *pBtn_YES;
-struct GUIButton *pPlayerCreationUI_BtnPlus;
-struct GUIButton *pPlayerCreationUI_BtnMinus;
-
-
-struct GUIButton *pButton_RestUI_Main;
-struct GUIButton *pButton_RestUI_Exit;
-struct GUIButton *pButton_RestUI_Wait5Minutes;
-struct GUIButton *pButton_RestUI_WaitUntilDawn;
-struct GUIButton *pButton_RestUI_Wait1Hour;
-
-
-struct GUIButton *pCharacterScreen_ExitBtn;
-struct GUIButton *pCharacterScreen_AwardsBtn;
-struct GUIButton *pCharacterScreen_InventoryBtn;
-struct GUIButton *pCharacterScreen_SkillsBtn;
-struct GUIButton *pCharacterScreen_StatsBtn;
-struct GUIButton *pCharacterScreen_DollBtn;
-struct GUIButton *pCharacterScreen_DetalizBtn;
-
-
-struct GUIButton *pBtn_NPCRight;
-struct GUIButton *pBtn_NPCLeft;
-struct GUIButton *pBtn_GameSettings;
-struct GUIButton *pBtn_QuickReference;
-struct GUIButton *pBtn_CastSpell;
-struct GUIButton *pBtn_Rest;
-struct GUIButton *pBtn_History;
-struct GUIButton *pBtn_Calendar;
-struct GUIButton *pBtn_Maps;
-struct GUIButton *pBtn_Autonotes;
-struct GUIButton *pBtn_Quests;
-
-
-struct GUIButton *pMMT_MainMenu_BtnMM6;
-struct GUIButton *pMMT_MainMenu_BtnMM7;
-struct GUIButton *pMMT_MainMenu_BtnMM8;
-struct GUIButton *pMMT_MainMenu_BtnContinue;
-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;
-
-
-struct GUIWindow *pPrimaryWindow;
-struct GUIWindow *pChestWindow;
-struct GUIWindow *pDialogueWindow;
-struct GUIWindow *window_SpeakInHouse;
-struct GUIWindow *pGUIWindow_ScrollWindow;
-struct GUIWindow *ptr_507BC8;
-struct GUIWindow *pGUIWindow_CurrentMenu;
-struct GUIWindow *ptr_507BD0;
-struct GUIWindow *pGUIWindow_Settings;
-struct GUIWindow *pModalWindow;
-struct GUIWindow *pGUIWindow_EscMessageWindow;
-struct GUIWindow *pBooksWindow;
-struct GUIWindow *pGUIWindow2;
-
-
-struct GUIButton *pBtn_Resume;
-struct GUIButton *pBtn_QuitGame;
-struct GUIButton *pBtn_GameControls;
-struct GUIButton *pBtn_LoadGame;
-struct GUIButton *pBtn_SaveGame;
-struct GUIButton *pBtn_NewGame;
-
-struct GUIButton *pBtn_SliderRight;
-struct GUIButton *pBtn_SliderLeft;
-
-
-struct GUIButton *pBtnDownArrow;
-struct GUIButton *pBtnArrowUp;
-struct GUIButton *pBtnCancel;
-struct GUIButton *pBtnLoadSlot;
-
-
-std::array<GUIButton*, 4> pCreationUI_BtnPressRight2;
-std::array<GUIButton*, 4> pCreationUI_BtnPressLeft2;
-std::array<GUIButton*, 4> pCreationUI_BtnPressLeft;
-std::array<GUIButton*, 4> pCreationUI_BtnPressRight;
-
-
-
-
-
-
-//----- (0041D0D8) --------------------------------------------------------
-void GUIButton::Release()
-{
-  if ( this )
-  {
-    if ( this == this->pParent->pControlsHead )
-    {
-      if ( this->pNext )
-      {
-        this->pParent->pControlsHead = this->pNext;
-        this->pNext->pPrev = 0;
-      }
-      else
-      {
-        this->pParent->pControlsHead = 0;
-        this->pParent->pControlsTail = 0;
-      }
-    }
-    else
-    {
-      if ( this->pNext )
-      {
-        this->pPrev->pNext = this->pNext;
-        this->pNext->pPrev = this->pPrev;
-      }
-      else
-      {
-        this->pPrev->pNext = 0;
-        this->pParent->pControlsTail = this->pPrev;
-      }
-    }
-    --this->pParent->uNumControls;
-  }
-}
-
-//----- (00415180) --------------------------------------------------------
-void GUIButton::DrawLabel( const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor )
-{
-  //strlen(edx0);
-  return pParent->DrawText(pFont,
-           this->uX + (signed int)(this->uWidth - pFont->GetLineWidth(label_text)) / 2,
-           this->uY + (signed int)(this->uHeight - pFont->uFontHeight) / 2,
-           a5, label_text, 0, 0, uFontShadowColor);
-}
-//----- (004B36CC) --------------------------------------------------------
-void CreateButtonInColumn( int column_pos, unsigned int control_id )
-{
-  pDialogueWindow->CreateButton( 480, 30 * column_pos + 146, 140, 30,  1,  0, UIMSG_SelectShopDialogueOption,  control_id,  0,   "",   0);
-}
-//----- (00419379) --------------------------------------------------------
-void ReleaseAwardsScrollBar()
-{
-  GUIButton *pButton; // esi@2
-
-  if ( awards_scroll_bar_created )
-  {
-    awards_scroll_bar_created = false;
-	ptr_507BA4->Release();
-    pBtn_Up->Release();
-    pBtn_Down->Release();
-    pBtn_Down = 0;
-    pBtn_Up = 0;
-    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
-    {
-      if ( pButton->msg == UIMSG_InventoryLeftClick )
-      {
-        pButton->uX = dword_50698C_uX;
-        pButton->uY = dword_506988_uY;
-        pButton->uZ = dword_506984_uZ;
-        pButton->uW = dword_506980_uW;
-        pGUIWindow_CurrentMenu->_41D08F_set_keyboard_control_group(1, 0, 0, 0);
-      }
-    }
-  }
-}
-//----- (00419220) --------------------------------------------------------
-void CreateAwardsScrollBar()
-{
-  GUIButton *pButton; // eax@2
-
-  if ( !awards_scroll_bar_created )
-  {
-    awards_scroll_bar_created = 1;
-    for ( pButton = pGUIWindow_CurrentMenu->pControlsHead; pButton; pButton = pButton->pNext )
-    {
-      if ( pButton->msg == UIMSG_InventoryLeftClick )
-      {
-        dword_50698C_uX = pButton->uX;
-        dword_506988_uY = pButton->uY;
-        dword_506984_uZ = pButton->uZ;
-        dword_506980_uW = pButton->uW;
-        pButton->uW = 0;
-        pButton->uZ = 0;
-        pButton->uY = 0;
-        pButton->uX = 0;
-      }
-    }
-    pBtn_Up = pGUIWindow_CurrentMenu->CreateButton(438, 46,
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureWidth,
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up)->uTextureHeight,
-                   1, 0, UIMSG_ClickAwardsUpBtn, 0, 0, "",
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_up),
-                   pIcons_LOD->GetTexture(uTextureID_ar_up_dn), 0);
-    pBtn_Down = pGUIWindow_CurrentMenu->CreateButton(438, 292,
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureWidth,
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up)->uTextureHeight,
-                   1, 0, UIMSG_ClickAwardsDownBtn, 0, 0, "",
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_up),
-                   pIcons_LOD->GetTexture(uTextureID_ar_dn_dn), 0);
-    ptr_507BA4 = pGUIWindow_CurrentMenu->CreateButton(440, 62, 16, 232, 1, 0, UIMSG_ClickAwardScrollBar, 0, 0, "", 0);
-  }
-}
-//----- (004BCA33) --------------------------------------------------------
-void UI_CreateEndConversationButton()
-{
-  pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 345, WINDOW_MainMenu, 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);
-  pDialogueWindow->CreateButton(8, 8, 450, 320, 1, 0, UIMSG_BuyInShop_Identify_Repair, 0, 0, "", 0);
-}
\ No newline at end of file
--- a/GUIButton.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-#pragma once
-void CreateButtonInColumn(int a1, unsigned int a2);
-void UI_CreateEndConversationButton();
\ No newline at end of file
--- a/GUIFont.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,654 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include <string>
-#include "Engine/ErrorHandling.h"
-
-#include "Engine/LOD.h"
-#include "GUIFont.h"
-#include "GUIWindow.h"
-#include "Engine/Graphics/Render.h"
-
-#include "Engine/mm7_data.h"
-
-
-extern LODFile_IconsBitmaps *pIcons_LOD;
-
-
-struct GUIFont *pAutonoteFont;
-struct GUIFont *pSpellFont;
-struct GUIFont *pFontArrus;
-struct GUIFont *pFontLucida;
-struct GUIFont *pBook2Font;
-struct GUIFont *pBookFont;
-struct GUIFont *pFontCreate;
-struct GUIFont *pFontCChar;
-struct GUIFont *pFontComic;
-struct GUIFont *pFontSmallnum;
-
-char temp_string[2048];
-
-std::array<char, 10000> pTmpBuf3;
-
-void DrawCharToBuff(unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight, unsigned __int16* pFontPalette, __int16 draw_color, int line_width);
-
-
-//----- (0044C448) --------------------------------------------------------
-GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...)
-{	
-    int pallete_index; // eax@3
-    GUIFont *pFont;
-    unsigned int palletes_count =0;
-    va_list palettes_ptr;
-
-    pFont = (GUIFont *)pIcons_LOD->LoadRaw(pFontFile, 0);
-    va_start(palettes_ptr, pFontFile);
-
-    while  (NULL!=(pFontPalette=va_arg(palettes_ptr, const char *)))
-        {
-        pallete_index =pIcons_LOD->LoadTexture(pFontPalette, TEXTURE_16BIT_PALETTE);
-        if (pallete_index == -1)
-            Error("Unable to open %s", pFontPalette);
-
-        pFont->pFontPalettes[palletes_count] = pIcons_LOD->pTextures[pallete_index].pPalette16;
-        ++palletes_count;
-        }
-    va_end(palettes_ptr);
-    pFont->palletes_count = palletes_count;
-    return pFont;
-}
-
-//----- (0044D2FD) --------------------------------------------------------
-void GUIFont::_44D2FD_prolly_draw_credits_entry( GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h, 
-                                                 unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString, 
-                                                 unsigned __int16 *pPixels, unsigned int uPixelsWidth )
-    {
-  char *work_string; // eax@1
-  unsigned __int16 *curr_pixel_pos; // esi@1
-  GUIFont *currentFont; // edi@4
-  signed int start_str_pos; // ecx@4
-  signed int line_w; // eax@6
-  GUIWindow draw_window; // [sp+Ch] [bp-5Ch]@
-  int currentColor; // [sp+74h] [bp+Ch]@4
-  int half_frameX; // [sp+80h] [bp+18h]@2
-
-  draw_window.uFrameHeight = h;
-  draw_window.uFrameW = uFrameY + h - 1;
-  draw_window.uFrameWidth = w;
-  draw_window.uFrameZ = uFrameX + w - 1;
-  ui_current_text_color = firstColor;
-  draw_window.uFrameX = uFrameX;
-  draw_window.uFrameY = uFrameY;
-
-  work_string = GUIFont::FitTwoFontStringINWindow(pString, this, pSecondFont, &draw_window, 0, 1);
-  work_string = strtok(work_string, "\n");
-  curr_pixel_pos = &pPixels[uPixelsWidth * uFrameY];
-  if ( work_string )
-  {
-    half_frameX = uFrameX >> 1;
-    while ( 1 )
-    {
-      currentFont = this;
-      ui_current_text_color = firstColor;
-      start_str_pos = 0;
-      currentColor = firstColor;
-      if ( *work_string == '_' )
-      {
-        currentFont = pSecondFont;
-        currentColor = secondColor;
-        ui_current_text_color = secondColor;
-        start_str_pos = 1;
-      }
-      line_w = (signed int)(w - currentFont->GetLineWidth(&work_string[start_str_pos]))/2;
-      if ( line_w < 0 )
-        line_w = 0;
-      currentFont->DrawTextLineToBuff(currentColor, secondColor, &curr_pixel_pos[line_w + half_frameX], work_string, uPixelsWidth);
-      curr_pixel_pos += uPixelsWidth * (currentFont->uFontHeight - 3);
-      work_string = strtok(0, "\n");
-      if ( !work_string )
-        break;
-    }
-  }
-}
-
-//----- (0044D1E7) --------------------------------------------------------
-void GUIFont::DrawTextLine( unsigned int uDefaultColor, signed int uX, signed int uY, 
-                            const char *text, int max_len_pix )
-{
-    signed int uX_pos; // edi@3
-    unsigned char c; // cl@4
-    unsigned __int16 draw_color; // cx@12
-    unsigned __int8 *pCharPixels; // eax@12
-    char color_code[20]; // [sp+Ch] [bp-1Ch]@16
-    int text_length; // [sp+20h] [bp-8h]@2
-    int text_color; // [sp+24h] [bp-4h]@1
-    int uCharWidth; // [sp+30h] [bp+8h]@9
-
-    if ( !text )
-        return;
-    text_color = ui_current_text_color;
-    text_length = strlen(text);
-    uX_pos=uX;
-    for (int i=0; i<text_length; ++i )
-        {
-        c = text[i];
-        if ( IsCharValid(c) )
-            {
-            switch (c)
-                {
-            case '\n':	//Line Feed 0A 10:
-                return;
-                break;
-            case '\f':  //Form Feed, page eject  0C 12 
-                strncpy(color_code, &text[i + 1], 5);
-                color_code[5] = 0;
-                text_color = atoi(color_code);
-                ui_current_text_color = text_color;
-                i += 5;	  
-                break;
-            case '\t':	// Horizontal tab 09
-            case '\r':   //Carriage Return 0D 13                 
-                break;
-            default:
-                uCharWidth = pMetrics[c].uWidth;
-                if ( uCharWidth )
-                    {
-                    if ( i > 0 )
-                        uX_pos += pMetrics[c].uLeftSpacing;
-                    draw_color = text_color;
-                    pCharPixels = &pFontData[font_pixels_offset[c]];
-                    if ( !text_color )
-                        draw_color = -1;
-                    pRenderer->DrawText(uX_pos, uY, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, 0);
-                    uX_pos += uCharWidth;
-                    if ( i < text_length )
-                        uX_pos += pMetrics[c].uRightSpacing;
-                    }
-                }
-            }
-        }
-    
-}
-
-//----- (0040F845) --------------------------------------------------------
-void DrawCharToBuff( unsigned short* uXpos,unsigned char* pCharPixels, int uCharWidth, int uCharHeight, 
-                            unsigned __int16* pFontPalette, __int16 draw_color, int line_width )
-    {
-    unsigned __int16* draw_buff; // edi@1
-    unsigned char* pPixels; // esi@1
-    unsigned char char_pxl; // eax@3
-
-    draw_buff = uXpos;
-    pPixels = pCharPixels;
-    for(int i=0; i<uCharHeight; ++i)
-        {
-        for(int j=0; j<uCharWidth; ++j)
-            {
-            char_pxl = *pPixels++;
-            if ( char_pxl )
-                {
-                if ( char_pxl == 1 )
-                    *draw_buff = pFontPalette[1];     
-                else         
-                    *draw_buff = draw_color;         
-                }
-            ++draw_buff;
-            }
-        draw_buff+=line_width-uCharWidth;
-        }
-
-}
-
-//----- (0044D0B5) --------------------------------------------------------
-void GUIFont::DrawTextLineToBuff( int uColor, int a3, unsigned short* uX_buff_pos, const char *text, int line_width )
-    {
-  
-  unsigned short* uX_pos; // edi@3
-  unsigned char c; // cl@4
-  unsigned __int16 draw_color; // cx@12
-  unsigned __int8 *pCharPixels; // eax@12
-  char color_code[20]; // [sp+Ch] [bp-1Ch]@16
-  int text_length; // [sp+20h] [bp-8h]@2
-  int text_color; // [sp+24h] [bp-4h]@1
-  int uCharWidth; // [sp+30h] [bp+8h]@9
-
-  if ( !text )
-      return;
-  text_color = ui_current_text_color;
-  text_length = strlen(text);
-  uX_pos=uX_buff_pos;
-  for (int i=0; i<text_length; ++i )
-      {
-      c = text[i];
-      if ( IsCharValid(c) )
-          {
-          switch (c)
-              {
-          case '\n':	//Line Feed 0A 10:
-              return;
-              break;
-          case '\f':  //Form Feed, page eject  0C 12 
-              strncpy(color_code, &text[i + 1], 5);
-              color_code[5] = 0;
-              text_color = atoi(color_code);
-              ui_current_text_color = text_color;
-              i += 5;	  
-              break;
-          case '\t':	// Horizontal tab 09
-          case '_':                   
-              break;
-          default:
-              uCharWidth = pMetrics[c].uWidth;
-              if ( uCharWidth )
-                  {
-                  if ( i > 0 )
-                      uX_pos += pMetrics[c].uLeftSpacing;
-                  draw_color = text_color;
-                  pCharPixels = &pFontData[font_pixels_offset[c]];
-                  if ( !text_color )
-                      draw_color = -1;
-                  DrawCharToBuff(uX_pos, pCharPixels, uCharWidth, uFontHeight, pFontPalettes[0], draw_color, line_width);
-                  uX_pos += uCharWidth;
-                  if ( i < text_length )
-                      uX_pos += pMetrics[c].uRightSpacing;
-                  }
-              }
-          }
-      }
-}
-
-
-
-//----- (0044C933) --------------------------------------------------------
-char * GUIFont::FitTwoFontStringINWindow( const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6 )
-    {
- 
-  GUIFont *currentFont; // esi@3
-  unsigned char c;
-  int uInStrLen;
-  char digits[4];
-  int possible_transition_point;
-  int string_pixel_Width;
-  int start_pixel_offset;
-
-  if (!pString)
-      {
-      MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
-      return 0;
-      }
-  currentFont=pFontMain; // esi@3
-  uInStrLen = strlen(pString);
-  Assert(uInStrLen < sizeof(pTmpBuf3));
-  strcpy(pTmpBuf3.data(), pString);
-  if (uInStrLen==0)
-      return pTmpBuf3.data();
-
-  start_pixel_offset=string_pixel_Width=startPixlOff;
-  possible_transition_point=0;
-  for(int i=0; i<uInStrLen; ++i) 
-      {
-      c=pTmpBuf3[i];
-      if (pFontMain->IsCharValid(c))
-          {
-          switch (c)
-              {
-          case '\t':	// Horizontal tab 09
-              {
-              strncpy(digits, &pTmpBuf3[i+1],3);
-              digits[3]=0;
-              string_pixel_Width = atoi(digits)+startPixlOff;
-              i+=3;
-              break;
-              }
-          case  '\n':	//Line Feed 0A 10
-              {
-              string_pixel_Width=start_pixel_offset;
-              possible_transition_point=i;
-              currentFont=pFontMain;
-              break;
-              }
-          case  '\f':   //Form Feed, page eject  0C 12
-              {
-              i+=5;  
-              break;
-              }
-          case  '\r':   //Carriage Return 0D 13
-              {
-              if (!a6)
-                  return (char*)pString;
-              break;
-              }
-          case ' ' :
-              {
-              string_pixel_Width+=currentFont->pMetrics[c].uWidth;
-              possible_transition_point=i;
-              break;
-              }
-          case '_' :
-              currentFont=pFontSecond;
-              break;
-          default:
-
-              if ((string_pixel_Width+currentFont->pMetrics[c].uWidth+ currentFont->pMetrics[c].uLeftSpacing+
-                  currentFont->pMetrics[c].uRightSpacing)<pWindow->uFrameWidth)
-                  {
-                  if(i>possible_transition_point)
-                      string_pixel_Width+=currentFont->pMetrics[c].uLeftSpacing;
-                  string_pixel_Width+=currentFont->pMetrics[c].uWidth;
-                  if (i<uInStrLen)
-                      string_pixel_Width+=currentFont->pMetrics[c].uRightSpacing;
-                  }
-              else
-                  {
-                  pTmpBuf3[possible_transition_point]='\n';
-                      
-                  if ( currentFont== pFontSecond)
-                      {
-
-                      for(int k=uInStrLen-1; k>=possible_transition_point+1; --k)
-                          pTmpBuf3[k] = pTmpBuf3[k-1];
-
-                      ++uInStrLen;
-                      ++possible_transition_point;
-                      pTmpBuf3[possible_transition_point] = '_';
-                      
-                      }
-                     string_pixel_Width=start_pixel_offset;
-
-                      for(int j=possible_transition_point;j<i; ++j ) 
-                          {
-                          c=pTmpBuf3[j];
-                          if (pFontMain->IsCharValid(c))
-                              {
-                              if(j>possible_transition_point)
-                                  string_pixel_Width+=pFontMain->pMetrics[c].uLeftSpacing;
-                              string_pixel_Width+=pFontMain->pMetrics[c].uWidth;
-                              if (j<i)
-                                  string_pixel_Width+=pFontMain->pMetrics[c].uRightSpacing;
-
-                              }
-                          }                    
-                  }
-              }
-          }
-      }
-  return pTmpBuf3.data();
-
-}
-
-
-//----- (0044C6C2) --------------------------------------------------------
-char* GUIFont::GetPageTop( const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5 )
-{
-  int text_height; // edi@1
-  char *text_str; // ebx@3
-  unsigned char c; // cl@4
-  int text_length; 
-
-  text_height = 0;
-
-  if ( !pInString )
-    return 0;
-  text_str = FitTextInAWindow(pInString, this, pWindow, uX, 0);
-  text_length = strlen(text_str);
-  for ( int i = 0; i < text_length; ++i )
-  {
-    c = text_str[i];
-    if ( IsCharValid(c) )
-    {
-      switch (c)
-      {
-        case '\n':	//Line Feed 0A 10:
-          text_height = text_height + (uFontHeight - 3);
-          if ( text_height >= (signed int)(a5 * (pWindow->uFrameHeight - (uFontHeight - 3))) )
-            return &text_str[i];
-          break;
-        case '\f':  //Form Feed, page eject  0C 12
-          i += 5;
-          break;
-        case '\t':	// Horizontal tab 09
-        case '\r':   //Carriage Return 0D 13 
-          i += 3;
-          break;
-      }
-      if ( text_height >= (signed int)(a5 * pWindow->uFrameHeight) )
-        break;
-    }
-  }
-  return &text_str[0];
-}
-
-//----- (0044C62E) --------------------------------------------------------
-int GUIFont::GetStringHeight2( GUIFont *secondFont, const char *text_str, GUIWindow* pWindow, int startX, int a6 )
-    {
- 
-  int uAllHeght; 
-  int uStringLen; 
-  unsigned char c; 
-  char *test_string; 
-
-  if ( !text_str )
-    return 0;
-  uAllHeght = uFontHeight - 3;
-  test_string = FitTwoFontStringINWindow(text_str, this, secondFont, pWindow, startX, 0);
-  uStringLen = strlen(test_string);
-  for (int i = 0; i < uStringLen; ++i)
-      {
-      c = test_string[i];
-      if (IsCharValid(c))
-          {
-          switch (c)
-              {
-          case '\n':	//Line Feed 0A 10:
-              uAllHeght+= uFontHeight - 3;
-              break;
-          case '\f':  //Form Feed, page eject  0C 12 
-              i += 5;		  
-              break;
-          case '\t':	// Horizontal tab 09
-          case '\r':   //Carriage Return 0D 13
-              if (a6 != 1)
-                  i += 3;
-              break;
-              }
-          }
-      }
-
-  return uAllHeght;
-}
-
-//----- (0044C59D) --------------------------------------------------------
-int GUIFont::CalcTextHeight( const char *pString, struct GUIWindow *pWindow, int uXOffset, int a5 )
-{
-  int uAllHeght; 
-  int uStringLen; 
-  unsigned char c; 
-  char *test_string; 
-
-  if (!pString)
-    return 0;
-  uAllHeght = uFontHeight - 6;
-  test_string = FitTextInAWindow(pString, this, pWindow, uXOffset, 0);
-  uStringLen = strlen(pString);
-  for (int i = 0; i < uStringLen; ++i)
-  {
-    c = test_string[i];
-    if (IsCharValid(c))
-    {
-      switch (c)
-      {
-        case '\n':	//Line Feed 0A 10:
-          uAllHeght += uFontHeight - 3;
-          break;
-        case '\f':  //Form Feed, page eject  0C 12 
-          i += 5;
-          break;
-        case '\t':	// Horizontal tab 09
-        case '\r':   //Carriage Return 0D 13
-          if (a5 != 1)
-            i += 3;
-          break;
-      }
-   }
-  }
-  return uAllHeght;
-}
-
-//----- (0044C51E) --------------------------------------------------------
-int GUIFont::GetLineWidth(const char *pString)
-	{
-	int str_len; // ebp@3
-	int string_line_width; // esi@3
-	unsigned char c;
-
-	if (!pString)
-		return 0;
-	str_len = strlen(pString);
-	string_line_width = 0;
-	for ( int i = 0; i < str_len; ++i )
-		{
-		c = pString[i];
-		if (IsCharValid(c))
-			{
-			switch (c)
-				{
-			case '\t':
-			case '\n':
-			case '\r':
-				return string_line_width;
-			case '\f':
-				i += 5;	  
-				break;
-			default:
-				if (i > 0)
-					string_line_width += pMetrics[c].uLeftSpacing;
-				string_line_width += pMetrics[c].uWidth;
-				if (i < str_len)
-					string_line_width +=pMetrics[c].uRightSpacing;
-				}
-			}
-		}
-	return string_line_width;
-	}
-
-
-//----- (0044C502) --------------------------------------------------------
-int GUIFont::AlignText_Center(unsigned int uCenterX, const char *pString)
-{
-  signed int position; // esi@1
- 
-  position = (signed int)(uCenterX - GetLineWidth(pString)) >> 1;
-  if ( position >= 0 )
-    return position;
-  else
-    return  0;
-}
-
-//----- (0044C768) --------------------------------------------------------
-char * FitTextInAWindow( const char *pInString, GUIFont *pFont, GUIWindow *pWindow, signed int uX, int a5 )
-{
-  unsigned char c;
-  int uInStrLen;
-  char digits[4];
-  int possible_transition_point;
-  int string_pixel_Width;
-  int start_pixel_offset;
-
-  if (!pInString)
-  {
-    MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0);
-    return 0;
-  }
-  uInStrLen = strlen(pInString);
-  strcpy(&temp_string[0], pInString);
-  if (uInStrLen == 0)
-    return &temp_string[0];
-
-  start_pixel_offset = string_pixel_Width=uX;
-  possible_transition_point = 0;
-  for ( int i = 0; i < uInStrLen; ++i )
-  {
-    c = temp_string[i];
-    if (pFont->IsCharValid(c))
-    {
-      switch (c)
-      {
-        case '\t':	// Horizontal tab 09
-        {
-          strncpy(digits, &temp_string[i + 1],3);
-          digits[3] = 0;
-          string_pixel_Width = atoi(digits)+uX;
-          i += 3;
-          break;
-        }
-        case  '\n':	//Line Feed 0A 10 (êîíåö ñòðîêè)
-        {
-          string_pixel_Width = start_pixel_offset;
-          possible_transition_point = i;
-          break;
-        }
-        case  '\f':   //Form Feed, page eject  0C 12
-        {
-          i += 5;  
-          break;
-        }
-        case  '\r':   //Carriage Return 0D 13
-        {
-          if ( !a5 )
-            return (char*)pInString;
-          break;
-        }
-        case ' '://ïðîáåë
-        {
-          string_pixel_Width += pFont->pMetrics[c].uWidth;
-          possible_transition_point = i;
-          break;
-        }
-        default:
-          if ((string_pixel_Width + pFont->pMetrics[c].uWidth + pFont->pMetrics[c].uLeftSpacing +
-               pFont->pMetrics[c].uRightSpacing) < pWindow->uFrameWidth )//íàðàùèâàíèå äëèíû ñòðîêè èëè ïåðåíîñ
-          {
-            if ( i > possible_transition_point )
-              string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
-            string_pixel_Width += pFont->pMetrics[c].uWidth;
-            if (i < uInStrLen)
-              string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
-          }
-          else//ïåðåíîñ ñòðîêè è ñëîâà
-          {
-            temp_string[possible_transition_point] ='\n';
-            string_pixel_Width = start_pixel_offset;
-            if ( i > possible_transition_point )
-            {
-              for ( int j = possible_transition_point; j < i; ++j )
-              {
-                c = temp_string[j];
-                if (pFont->IsCharValid(c))
-                {
-                  if ( j > possible_transition_point )
-                    string_pixel_Width += pFont->pMetrics[c].uLeftSpacing;
-                  string_pixel_Width += pFont->pMetrics[c].uWidth;
-                  if ( j < i )
-                    string_pixel_Width += pFont->pMetrics[c].uRightSpacing;
-                }
-              }
-            }
-          }
-        }
-    }
-  }
-  return &temp_string[0];
-}
-//----- (00414162) --------------------------------------------------------
-void uGameUIFontMain_initialize()
-{
-  uGameUIFontMain = Color16(0xAu, 0, 0);
-}
-
-//----- (00414174) --------------------------------------------------------
-void uGameUIFontShadow_initialize()
-{
-  uGameUIFontShadow = Color16(0xE6u, 214, 193);
-}
\ No newline at end of file
--- a/GUIFont.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#pragma once
-
-
-/*  171 */
-#pragma pack(push, 1)
-struct GUICharMetric
-{
-  unsigned int uLeftSpacing;
-  unsigned int uWidth;
-  unsigned int uRightSpacing;
-};
-#pragma pack(pop)
-
-/*  170 */
-#pragma warning( push )
-#pragma warning( disable : 4200 )
-#pragma pack(push, 1)
-struct GUIFont
-{
-	
-//----- (0044C4DE) --------------------------------------------------------
-  bool IsCharValid(unsigned char c) {	return (c >= cFirstChar) && (c <= cLastChar) || (c == '\f') || (c == '\r') || (c == '\t') || (c == '\n');}
-  int AlignText_Center(unsigned int uCenterX, const char *pString);
-  int GetLineWidth(const char *pString);
-  int CalcTextHeight(const  char *pString, struct GUIWindow *pWindow, int uXOffset, int a5);
-  int GetStringHeight2(GUIFont *secondFont, const char *text_str, GUIWindow* pWindow, int startX, int a6);
-  char* GetPageTop(const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5);
-  void DrawTextLineToBuff(int uColor, int a3, unsigned short* uX_buff_pos, const char *text, int line_width);
-  void DrawTextLine(unsigned int uDefaultColor, signed int uX, signed int uY, const char *text, int max_len_pix);
-  void _44D2FD_prolly_draw_credits_entry(GUIFont *pSecondFont, int uFrameX, int uFrameY, unsigned int w, unsigned int h, 
-                                        unsigned __int16 firstColor, unsigned __int16 secondColor, const char *pString, 
-                                        unsigned __int16 *pPixels, unsigned int uPixelsWidth);
-
-  static char * FitTwoFontStringINWindow(const char *pString, GUIFont *pFontMain, GUIFont *pFontSecond, GUIWindow* pWindow, int startPixlOff, int a6);
-  static void uGameUIFontMain_initialize();
-  static void uGameUIFontShadow_initialize();
-
-  unsigned char cFirstChar;  //0
-  unsigned char cLastChar;  //1
-  char field_2;
-  char field_3;
-  char field_4;
-  __int16 uFontHeight;  //5-6
-  char field_7;
-  int palletes_count;
-  unsigned __int16 *pFontPalettes[5];
-  GUICharMetric pMetrics[256];
-  int font_pixels_offset[256];
-  unsigned char pFontData[0]; //array of font pixels
-
-};
-#pragma pack(pop)
-#pragma warning( pop )
-
-GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...);
-char * FitTextInAWindow(const char *pInString, GUIFont *pFont, GUIWindow *pWindow, signed int uX, int a5);
-
-
-extern struct GUIFont *pAutonoteFont;
-extern struct GUIFont *pSpellFont;
-extern struct GUIFont *pFontArrus;
-extern struct GUIFont *pFontLucida;
-extern struct GUIFont *pBook2Font;
-extern struct GUIFont *pBookFont;
-extern struct GUIFont *pFontCreate;
-extern struct GUIFont *pFontCChar;
-extern struct GUIFont *pFontComic;
-extern struct GUIFont *pFontSmallnum;
\ No newline at end of file
--- a/GUIProgressBar.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,186 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "GUIProgressBar.h"
-#include "Engine/ErrorHandling.h"
-#include "Engine/LOD.h"
-#include "Engine/Party.h"
-#include "Engine/Graphics/Render.h"
-#include "Engine/Tables/IconFrameTable.h"
-
-#include "Engine/mm7_data.h"
-
-
-
-
-struct GUIProgressBar *pGameLoadingUI_ProgressBar = new GUIProgressBar;
-
-
-
-
-//----- (00Initialize) --------------------------------------------------------
-bool GUIProgressBar::Initialize(Type type)
-{
-  //GUIProgressBar *v2; // esi@1
-  signed int v4; // eax@7
-  int v5; // ecx@8
-  //int v6; // edi@8
-  int v7; // edx@14
-  //const char *v8; // [sp-8h] [bp-84h]@20
-  //unsigned int v9; // [sp-4h] [bp-80h]@20
-  char Str1[64]; // [sp+4h] [bp-78h]@16
-
-  switch (type)
-  {
-    case TYPE_None:
-      return true;
-
-    case TYPE_Box:
-    case TYPE_Fullscreen:
-      break;
-
-    default:
-      Error("Invalid GUIProgressBar type: %u", type);
-  }
-
-  //v2 = this;
-  if (pLoadingBg.pPixels)
-    return false;
-
-  uType = type;
-
-  v4 = 1;
-  if (uType == TYPE_Fullscreen)
-  {
-    v5 = 0;
-    //v6 = (int)&field_10;
-    do
-    {
-      if ( field_10[v4] == 1 )
-        ++v5;
-      ++v4;
-    }
-    while ( v4 <= 5 );
-    if ( v5 == 5 )
-      memset(field_10, 0, 8);
-    v7 = rand() % 5 + 1;
-    if ( field_10[v7] == 1 )
-    {
-      do
-        v7 = rand() % 5 + 1;
-      while ( field_10[v7] == 1 );
-    }
-    sprintf(Str1, "loading%d.pcx", v7);
-    pLoadingBg.Load(Str1, 2);
-    uProgressCurrent = 0;
-    uX = 122;
-    uY = 151;
-    uWidth = 449;
-    uHeight = 56;
-    uProgressMax = 26;
-    pIcons_LOD->_410522(&pLoadingProgress, "loadprog", 2u);
-    Draw();
-    return true;
-  }
-
-  switch (pParty->alignment)
-  {
-    case PartyAlignment_Good:    pIcons_LOD->_410522(&pBardata, "bardata-b", 2); break;
-    case PartyAlignment_Neutral: pIcons_LOD->_410522(&pBardata, "bardata", 2); break;
-    case PartyAlignment_Evil:    pIcons_LOD->_410522(&pBardata, "bardata-c", 2); break;
-    default: Error("Invalid alignment type: %u", pParty->alignment);
-  }
-
-  uProgressCurrent = 0;
-  uProgressMax = 26;
-  Draw();
-  return true;
-}
-
-//----- (004435BB) --------------------------------------------------------
-void GUIProgressBar::Reset(unsigned __int8 uMaxProgress)
-{
-  field_9 = 0;
-  uProgressCurrent = 0;
-  uProgressMax = uMaxProgress;
-}
-
-//----- (004435CD) --------------------------------------------------------
-void GUIProgressBar::Progress()
-{
-  ++this->uProgressCurrent;
-  if ( this->uProgressCurrent > this->uProgressMax )
-    this->uProgressCurrent = this->uProgressMax;
-  Draw();
-}
-
-//----- (004435E2) --------------------------------------------------------
-void GUIProgressBar::Release()
-{
-  int v3; // edi@7
-
-  pLoadingBg.Release();
-  if ( this->uType == 1 )
-  {
-    if ( this->uProgressCurrent != this->uProgressMax )
-    {
-      this->uProgressCurrent = this->uProgressMax - 1;
-      Progress();
-    }
-    v3 = (int)&this->pLoadingProgress.pLevelOfDetail0_prolly_alpha_mask;
-    free(this->pLoadingProgress.pLevelOfDetail0_prolly_alpha_mask);
-    free(this->pLoadingProgress.pPalette16);
-    this->pLoadingProgress.pPalette16 = 0;
-  }
-  else
-  {
-    if ( !this->pBardata.pLevelOfDetail0_prolly_alpha_mask )
-      return;
-    free(this->pBardata.pLevelOfDetail0_prolly_alpha_mask);
-    v3 = (int)&this->pBardata.pPalette16;
-    free(this->pBardata.pPalette16);
-    this->pBardata.pLevelOfDetail0_prolly_alpha_mask = 0;
-  }
-  *(int *)v3 = 0;
-}
-
-//----- (00443670) --------------------------------------------------------
-void GUIProgressBar::Draw()
-{
-  pRenderer->BeginScene();
-  if (uType != TYPE_Fullscreen)
-  {
-    if (pBardata.pLevelOfDetail0_prolly_alpha_mask)
-    {
-      pRenderer->Sub01();
-
-      pRenderer->DrawTextureIndexed(80, 122, &pBardata);//ïðîãðåññáàð äëÿ äàíæåé
-      pRenderer->DrawTextureTransparent(100, 146, &pIcons_LOD->pTextures[pIconsFrameTable->GetFrame(uIconID_TurnHour, 0)->uTextureID]);
-      //pRenderer->FillRectFast(174, 164, floorf(((double)(113 * uProgressCurrent) / (double)uProgressMax) + 0.5f),//COERCE_UNSIGNED_INT64(v4 + 6.7553994e15),
-        //16, pRenderer->uTargetRMask);
-      pRenderer->FillRectFast(174, 164, floorf(((double)(113 * uProgressCurrent) / (double)uProgressMax) + 0.5f),//COERCE_UNSIGNED_INT64(v4 + 6.7553994e15),
-        16, 0xF800);
-      pRenderer->EndScene();
-      pRenderer->Present();
-      return;
-    }
-    pRenderer->EndScene();
-    return;
-  }
-
-  if (!pLoadingBg.pPixels)
-  {
-    pRenderer->EndScene();
-    return;
-  }
-
-  pRenderer->DrawTextureRGB(0, 0, &pLoadingBg);
-  pRenderer->SetRasterClipRect(0, 0, 639, 479);
-  pRenderer->SetTextureClipRect(172, 459, 15 * (signed int)(signed __int64)((double)(300 * uProgressCurrent) / (double)uProgressMax) / 15 + 172, 471);
-  pRenderer->DrawTextureTransparent(172, 459, &pLoadingProgress);
-  pRenderer->ResetTextureClipRect();
-  pRenderer->EndScene();
-  pRenderer->Present();
-}
\ No newline at end of file
--- a/GUIProgressBar.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#pragma once
-#include "Engine/Graphics/Texture.h"
-
-
-/*  278 */
-#pragma pack(push, 1)
-struct GUIProgressBar
-{
-  enum Type: unsigned __int32
-  {
-    TYPE_None = 0,
-    TYPE_Fullscreen = 1,
-    TYPE_Box = 2
-  };
-
-  bool Initialize(Type type);
-  void Reset(unsigned __int8 uMaxProgress);
-  void Progress();
-  void Release();
-  void Draw();
-
-  __int16 uX;
-  __int16 uY;
-  __int16 uWidth;
-  __int16 uHeight;
-  char field_8;
-  char field_9;
-  char uProgressMax;
-  char uProgressCurrent;
-  Type uType;
-  char field_10[8];
-  //char field_11;
-  //char field_12;
-  //char field_13;
-  //char field_14;
-  //char field_15;
-  //char field_16;
-  //char field_17;
-  RGBTexture pLoadingBg;
-  RGBTexture field_40;
-  RGBTexture field_68;
-  RGBTexture field_90;
-  RGBTexture field_B8;
-  struct Texture field_E0;
-  struct Texture pBardata;
-  struct Texture pLoadingProgress;
-};
-#pragma pack(pop)
-
-
-
-extern struct GUIProgressBar *pGameLoadingUI_ProgressBar;
\ No newline at end of file
--- a/GUIWindow.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4027 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "Engine/ErrorHandling.h"
-
-#include "GUIWindow.h"
-#include "GUIFont.h"
-#include "Engine/Party.h"
-#include "Engine/LOD.h"
-#include "Keyboard.h"
-#include "Engine/OurMath.h"
-#include "Engine/Timer.h"
-#include "AudioPlayer.h"
-#include "Mouse.h"
-#include "Engine/Graphics/Viewport.h"
-#include "Engine/Tables/StorylineTextTable.h"
-#include "GUI\UI\UIHouses.h"
-#include "GUI\UI\UIBooks.h"
-#include "Engine/texts.h"
-#include "Engine/Autonotes.h"
-#include "Engine/Awards.h"
-#include "Engine/Objects/Chest.h"
-#include "Engine/Graphics/Outdoor.h"
-#include "Engine/Game.h"
-#include "Engine/Tables/IconFrameTable.h"
-#include "Engine/Objects/Actor.h"
-
-#include "GUI\UI\UIArena.h"
-#include "Engine/Events.h"
-#include "Engine/Graphics/Level\Decoration.h"
-
-typedef struct _RGBColor
-    {
-    unsigned char R;
-    unsigned char B;
-    unsigned char G;
-    }RGBColor;
-
-
-std::array<RGBColor, 20> spell_tooltip_colors={{ 
-    {0x96, 0xD4, 0xFF},
-    {0xFF, 0x80, 0x00},
-    {0xFF, 0xFF, 0x9B},
-    {0xE1, 0xE1, 0xE1},
-    {0x80, 0x80, 0x80},
-    {0x96, 0xD4, 0xFF},
-    {0xFF, 0x55, 0x00},
-    {0x96, 0xD4, 0xFF},
-    {0xFF, 0x55, 0x00},
-    {0xE1, 0xE1, 0xE1},
-    {0xFF, 0x55, 0x00},
-    {0x96, 0xD4, 0xFF},
-    {0xEB, 0x0F, 0xFF},
-    {0xFF, 0x80, 0x00},
-    {0x96, 0xD4, 0xFF},
-    {0x80, 0x80, 0x80},
-    {0xFF, 0x55, 0x00},
-    {0x00, 0x80, 0xFF},
-    {0x00, 0x80, 0xFF},
-    {0x96, 0xD4, 0xFF}}};
-
-
-int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[1]; // idb
-struct GUIWindow *pWindow_MMT_MainMenu;
-struct GUIWindow *pWindow_MainMenu;
-std::array<struct GUIWindow, 20> pWindowList;
-
-struct GUIMessageQueue *pMessageQueue_50CBD0 = new GUIMessageQueue;
-struct GUIMessageQueue *pMessageQueue_50C9E8 = new GUIMessageQueue;
-
-
-
-
-
-
-// inlined
-//----- (mm6c::00420520) --------------------------------------------------
-void GUIMessageQueue::Flush()
-{
-  if (uNumMessages)
-    uNumMessages = pMessages[0].field_8 != 0;
-}
-
-//----- (004356B9) --------------------------------------------------------
-void GUIMessageQueue::PopMessage(enum UIMessageType *pType, int *pParam, int *a4)
-{
-  if ( this->uNumMessages )
-  {
-    *pType = this->pMessages[0].eType;
-    *pParam = this->pMessages[0].param;
-    *a4 = this->pMessages[0].field_8;
-    if ( (signed int)(this->uNumMessages - 1) > 0 )
-    {
-      for ( uint i = 0; i < (signed int)(this->uNumMessages - 1); ++i )
-      {
-        this->pMessages[i].eType = this->pMessages[i + 1].eType;
-        this->pMessages[i].param = this->pMessages[i + 1].param;
-        this->pMessages[i].field_8 = this->pMessages[i + 1].field_8;
-      }
-    }
-    --this->uNumMessages;
-  }
-}
-
-//----- (0041B4E1) --------------------------------------------------------
-int __fastcall 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
-  GUIButton *l; // ecx@8
-  unsigned __int8 v9; // [sp+4h] [bp-8h]@1
-  char old_hot_key; // [sp+8h] [bp-4h]@1
-
-  //v3 = uNewHotkey;
-  old_hot_key = toupper(uOldHotkey);
-  result = toupper(uNewHotkey);
-  v9 = result;
-  if ( bFirstCall )
-  {
-    for ( i = uNumVisibleWindows; i >= 0; --i )
-    {
-      result = 84 * pVisibleWindowsIdxs[i];
-      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 )
-    {
-      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) --------------------------------------------------------
-GUIButton *__fastcall GUI_HandleHotkey(unsigned __int8 uHotkey)
-{
-  char Hot_key_num; // al@1
-  GUIWindow *current_window; // ecx@2
-  GUIButton *result; // eax@2
-
-  Hot_key_num = toupper(uHotkey);
-  for( int i = uNumVisibleWindows; i >= 0 && pVisibleWindowsIdxs[i] > 0; i-- )
-  {
-	current_window = &pWindowList[pVisibleWindowsIdxs[i] - 1];
-	for ( result = current_window->pControlsHead; result; result = result->pNext )
-	{
-	  if ( result->uHotkey == Hot_key_num )
-	  {
-		pMessageQueue_50CBD0->AddGUIMessage(result->msg, result->msg_param, 0);
-		return result;
-	  }
-	}
-	if ( !current_window->uFrameX && !current_window->uFrameY
-		&& (current_window->uFrameWidth == window->GetWidth() && current_window->uFrameHeight == window->GetWidth()) )
-	  break;
-  }
-  return 0;
-}
-// 5075E0: using guessed type int pVisibleWindowsIdxs[20];
-
-//----- (0041D73D) --------------------------------------------------------
-void GUIWindow::_41D73D_draw_buff_tooltip()
-{
-  __int64 remaing_time; // ST28_8@11
-  unsigned short text_color;
-  int Y_pos; // esi@11
-  int string_count; // [sp+20h] [bp-4h]@7
-
-  string_count = 0;
-  for (int i=0; i<20; ++i)
-    if ( pParty->pPartyBuffs[i].uExpireTime > 0i64 )
-      ++string_count;
-
-  uFrameHeight = pFontArrus->uFontHeight + 72;
-  uFrameHeight += (string_count - 1) * pFontArrus->uFontHeight;
-  uFrameZ = uFrameWidth + uFrameX - 1;
-  uFrameW = uFrameY + uFrameHeight - 1;
-  DrawMessageBox(0);
-  DrawTitleText(pFontArrus, 0, 12, 0, pGlobalTXT_LocalizationStrings[451], 3);
-  if ( !string_count )
-     DrawTitleText(pFontComic, 0, 40, 0, pGlobalTXT_LocalizationStrings[153], 3);
-
-  GetTickCount();
-  string_count = 0;
-  for (int i=0; i<20; ++i)
-  {
-    if ( pParty->pPartyBuffs[i].uExpireTime>0i64 )//!!!
-    {
-      remaing_time = pParty->pPartyBuffs[i].uExpireTime- pParty->uTimePlayed;//!!!
-      Y_pos = string_count * pFontComic->uFontHeight + 40; 
-      text_color = Color16(spell_tooltip_colors[i].R, spell_tooltip_colors[i].G, spell_tooltip_colors[i].B);
-      DrawText(pFontComic, 52, Y_pos, text_color, aSpellNames[i], 0, 0, 0);
-      DrawBuff_remaining_time_string(Y_pos, this, remaing_time, pFontComic); 
-      ++string_count;
-    }
-  }
-}
-
-
-//----- (0041D08F) --------------------------------------------------------
-void GUIWindow::_41D08F_set_keyboard_control_group(int num_buttons, int a3, int a4, int a5)
-{
-  if (num_buttons)
-  {
-    this->pNumPresenceButton = num_buttons;
-    this->field_30 = a3;
-    this->field_34 = a4;
-    this->pCurrentPosActiveItem = a5;
-    this->pStartingPosActiveItem = a5;
-    this->receives_keyboard_input = true;
-  }
-  else
-  {
-    this->pNumPresenceButton = 0;
-    this->field_30 = a3;
-    this->field_34 = a4;
-    this->pCurrentPosActiveItem = 0;
-    this->pStartingPosActiveItem = 0;
-    this->receives_keyboard_input = false;
-  }
-}
-
-
-//----- (0041C26A) --------------------------------------------------------
-void GUIWindow::Release()
-{
-  //GUIWindow *v1; // esi@1
-  int i; // edi@20
-  //GUIButton *v8; // eax@26
-  GUIButton *pNextBtn; // edi@27
-  //int v10; // esi@28
-  //int v11; // ecx@28
-  int v12; // edx@29
-
-  //v1 = this;
-  if ( !this )
-    return;
-  
-  switch( this->eWindowType )
-  {
-	case WINDOW_GreetingNPC:
-		{
-		pIcons_LOD->SyncLoadedFilesCount();
-		pCurrentScreen = pMainScreenNum;
-		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);
-          pGame->pIndoorCameraD3D->sRotationY = pParty->sRotationY;
-		}
-		pParty->uFlags |= 2u;
-		break;
-		}
-	case WINDOW_Transition:
-		{
-		//pVideoPlayer->Unload();
-		pTexture_outside->Release();
-		pTexture_Dialogue_Background->Release();
-		pIcons_LOD->SyncLoadedFilesCount();
-		pCurrentScreen = pMainScreenNum;
-		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();
-        pCurrentScreen = pMainScreenNum;
-        break;
-		}
-	case WINDOW_Dialogue:
-		{
-        if ( !dword_591084 )
-	        pDialogueNPCPortraits[0]->Release();
-        uNumDialogueNPCPortraits = 0;
-        pTexture_Dialogue_Background->Release();
-
-        pIcons_LOD->SyncLoadedFilesCount();
-        pCurrentScreen = pMainScreenNum;
-        break;
-		}
-  case WINDOW_null:
-    return;
-	default:
-		break;
-  }
-  //v8 = this->pControlsHead;
-  if ( this->pControlsHead )
-  {
-    do
-    {
-      pNextBtn = this->pControlsHead->pNext;
-      free(this->pControlsHead);
-      this->pControlsHead = pNextBtn;
-    }
-    while ( pNextBtn );
-  }
-  this->pControlsHead = 0;
-  this->pControlsTail = 0;
-  this->uNumControls = 0;
-  this->eWindowType = WINDOW_null;
-  while ( this->numVisibleWindows < uNumVisibleWindows )
-  {
-    v12 = pVisibleWindowsIdxs[this->numVisibleWindows + 1];
-    pVisibleWindowsIdxs[this->numVisibleWindows] = v12;
-    --pWindowList[v12 - 1].numVisibleWindows;
-    ++this->numVisibleWindows;
-  }
-  pVisibleWindowsIdxs[uNumVisibleWindows] = 0;
-  uNumVisibleWindows = uNumVisibleWindows - 1;
-}
-
-//----- (0041CD3B) --------------------------------------------------------
-GUIButton *GUIWindow::GetControl(unsigned int uID)
-{
-  GUIButton *result; // eax@1
-
-  result = this->pControlsHead;
-  for ( uID; uID; --uID )
-    result = result->pNext;
-  return result;
-}
-
-//----- (00411BFC) --------------------------------------------------------
-void GUIWindow::InitializeBookView()
-{
-  char *pString; // eax@12
-  int pTextHeight; // eax@12
-  //__int64 page_count; // qax@12
-  unsigned int page_count; // esi@12
-  unsigned __int16 v18; // ax@38
-  signed int max_beacons; // [sp+10h] [bp-5Ch]@38
-  GUIWindow journal_window; // [sp+18h] [bp-54h]@8
-
-  pAudioPlayer->StopChannels(-1, -1);
-  InitializeBookFonts();
-  this->CreateButton(475, 445, 158, 34, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0); // Close
-  pCurrentScreen = SCREEN_BOOKS;
-  full_num_items_in_book = 0;
-  books_primary_item_per_page = 0;
-  books_page_number = 0;
-  num_achieved_awards = 0; 
-  switch (this->par1C)
-  {
-    case WINDOW_LloydsBeacon:
-    {
-      byte_506360 = 0;
-      pTexture_CurrentBook = pIcons_LOD->LoadTexturePtr("lb_bordr", TEXTURE_16BIT_PALETTE);
-      pTexture_LloydBeacons[0] = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
-      pTexture_LloydBeacons[1] = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
-
-      pBtn_Book_1 = this->CreateButton(415, 13, 39, 36, 1, 0, UIMSG_LloydsBeacon_FlippingBtn, 0, 0, pGlobalTXT_LocalizationStrings[375], 0); // Set Beacon
-      pBtn_Book_2 = this->CreateButton(415, 48, 39, 36, 1, 0, UIMSG_LloydsBeacon_FlippingBtn, 1, 0, pGlobalTXT_LocalizationStrings[523], 0); // Recall Beacon
-
-      max_beacons = 1;
-      v18 = pParty->pPlayers[_506348_current_lloyd_playerid].pActiveSkills[PLAYER_SKILL_WATER];
-      if ( v18 & 0x100 || (v18 & 0x80) )
-          max_beacons = 5;
-      else if ( v18 & 0x40 )
-          max_beacons = 3;
-
-      for ( int i = 0; i < max_beacons; ++i )
-            CreateButton(pLloydsBeaconsPreviewXs[i], pLloydsBeaconsPreviewYs[i],
-                           92, 68, 1, 180, UIMSG_InstallBeacon, i, 0, "", 0);
-
-      for ( int i = 0; i < 5; ++i )
-      {
-        if (pParty->pPlayers[_506348_current_lloyd_playerid].pInstalledBeacons[i].uBeaconTime  >= (signed __int64)pParty->uTimePlayed)
-            LoadThumbnailLloydTexture(i, _506348_current_lloyd_playerid + 1);
-        else 
-          memset(&pParty->pPlayers[_506348_current_lloyd_playerid].pInstalledBeacons[i], 0, sizeof(LloydBeacon));
-      }
-    }
-    break;
-
-    case WINDOW_TownPortal:
-    {
-      pTexture_CurrentBook        = pIcons_LOD->LoadTexturePtr("townport", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[0] = pIcons_LOD->LoadTexturePtr("tpharmndy", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[1] = pIcons_LOD->LoadTexturePtr("tpelf", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[2] = pIcons_LOD->LoadTexturePtr("tpwarlock", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[3] = pIcons_LOD->LoadTexturePtr("tpisland", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[4] = pIcons_LOD->LoadTexturePtr("tpheaven", TEXTURE_16BIT_PALETTE);
-      pTexture_TownPortalIcons[5] = pIcons_LOD->LoadTexturePtr("tphell", TEXTURE_16BIT_PALETTE);
-      
-      static int pTownPortalBook_ws[6] = { 80,  66,  68,  72,  67,  74};
-      static int pTownPortalBook_hs[6] = { 55,  56,  65,  67,  67,  59};
-      for ( uint i = 0; i < 6; ++i )
-        this->CreateButton(pTownPortalBook_xs[i], pTownPortalBook_ys[i], pTownPortalBook_ws[i], pTownPortalBook_hs[i], 1, 182, UIMSG_ClickTownInTP, i, 0, "", nullptr);
-      
-    }
-    break;
-
-  case WINDOW_QuestBook:
-  {
-      pTexture_CurrentBook    = pIcons_LOD->LoadTexturePtr("sbquiknot", TEXTURE_16BIT_PALETTE);
-      pSpellBookPagesTextr_10 = pIcons_LOD->LoadTexturePtr( "divbar", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_on = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_on = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
-      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398,         pViewport->uViewportTL_Y + 1,
-                                     pTex_book_button1_on->uTextureWidth, pTex_book_button1_on->uTextureHeight,
-                                     1, 0, UIMSG_ClickBooksBtn, 0xBu, 0, pGlobalTXT_LocalizationStrings[192],// "Scroll Up"
-                                     pTex_book_button1_on, 0);
-      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398,          pViewport->uViewportTL_Y + 38,
-                                     pTex_book_button2_on->uTextureHeight, pTex_book_button2_on->uTextureHeight,
-                                     1, 0, UIMSG_ClickBooksBtn, 0xAu, 0, pGlobalTXT_LocalizationStrings[193],// "Scroll Down"
-                                     pTex_book_button2_on, 0);
-      num_achieved_awards = 0;
-      memset(achieved_awards.data(), 0, 4000);
-      for ( uint i = books_primary_item_per_page; i < 512; ++i )
-      {
-        if ( _449B57_test_bit(pParty->_quest_bits, i) && pQuestTable[i] )
-        {
-          achieved_awards[num_achieved_awards] = (AwardType)i;
-          ++num_achieved_awards;
-        }
-      }
-      full_num_items_in_book = num_achieved_awards;
-      num_achieved_awards = 0;
-    }
-    break;
-
-    case WINDOW_AutonotesBook:
-    {
-      pTexture_AutonotesBook   = pIcons_LOD->LoadTexturePtr("sbautnot", TEXTURE_16BIT_PALETTE);
-      pSpellBookPagesTextr_10  = pIcons_LOD->LoadTexturePtr("divbar", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button3_on = pIcons_LOD->LoadTexturePtr("tab-an-1b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button3_off = pIcons_LOD->LoadTexturePtr("tab-an-1a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button4_on = pIcons_LOD->LoadTexturePtr("tab-an-2b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button4_off = pIcons_LOD->LoadTexturePtr("tab-an-2a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button5_on = pIcons_LOD->LoadTexturePtr("tab-an-3b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button5_off = pIcons_LOD->LoadTexturePtr("tab-an-3a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button6_on = pIcons_LOD->LoadTexturePtr("tab-an-5b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button6_off = pIcons_LOD->LoadTexturePtr("tab-an-5a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button7_on = pIcons_LOD->LoadTexturePtr("tab-an-4b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button7_off = pIcons_LOD->LoadTexturePtr("tab-an-4a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button8_on = pIcons_LOD->LoadTexturePtr("tab-an-8b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button8_off = pIcons_LOD->LoadTexturePtr("tab-an-8a", TEXTURE_16BIT_PALETTE);
-
-      pBtn_Book_1                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,   50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn, 11, 0, pGlobalTXT_LocalizationStrings[193], pTex_book_button1_on, 0);
-      pBtn_Book_2                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38,  50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn, 10, 0, pGlobalTXT_LocalizationStrings[192], pTex_book_button2_on, 0);
-      pBtn_Book_3                = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 113, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  2, 0, pGlobalTXT_LocalizationStrings[85], pTex_book_button3_on, 0); // "Potion Notes"
-      pBtn_Book_4                = this->CreateButton(pViewport->uViewportTL_X + 399, pViewport->uViewportTL_Y + 150, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  3, 0, pGlobalTXT_LocalizationStrings[137], pTex_book_button4_on, 0); // "Fountain Notes"
-      pBtn_Book_5                = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  4, 0, pGlobalTXT_LocalizationStrings[8], pTex_book_button5_on, 0); // "Obelisk Notes"
-      pBtn_Book_6                = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  5, 0, pGlobalTXT_LocalizationStrings[141], pTex_book_button6_on, 0); // "Seer Notes"
-      pBtn_Autonotes_Misc        = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 264, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  6, 0, pGlobalTXT_LocalizationStrings[123], pTex_book_button7_on, 0); // "Miscellaneous Notes"
-      pBtn_Autonotes_Instructors = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 302, 50, 34, 1, 0, 
-                                                    UIMSG_ClickBooksBtn,  7, 0, pGlobalTXT_LocalizationStrings[662], pTex_book_button8_on, 0); // "Instructors"
-
-      num_achieved_awards = 0;
-      for ( uint i = books_primary_item_per_page; i < 196; ++i )
-      {
-        if ( _506568_autonote_type == pAutonoteTxt[i].eType)//dword_72371C[2 * v10] )
-        {
-          if ( i )
-          {
-            if ( _449B57_test_bit(pParty->_autonote_bits, i) && pAutonoteTxt[i].pText )
-            {
-              achieved_awards[num_achieved_awards] = (AwardType)i;
-              ++num_achieved_awards;
-            }
-          }
-        }
-      }
-      full_num_items_in_book = num_achieved_awards;
-      num_achieved_awards = 0;
-    }
-    break;
-
-    case WINDOW_MapsBook:
-    {
-      dword_506364 = 1;
-      pSpellBookPagesTextr_12  = pIcons_LOD->LoadTexturePtr("sbmap", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("zoom-on", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("zoot-on", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("zoom-off", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("zoot-off", TEXTURE_16BIT_PALETTE);
-      pTex_book_button3_on = pIcons_LOD->LoadTexturePtr("tabNon", TEXTURE_16BIT_PALETTE);
-      pTex_book_button3_off = pIcons_LOD->LoadTexturePtr("tabNoff", TEXTURE_16BIT_PALETTE);
-      pTex_book_button4_on = pIcons_LOD->LoadTexturePtr("tabSon", TEXTURE_16BIT_PALETTE);
-      pTex_book_button4_off = pIcons_LOD->LoadTexturePtr("tabSoff", TEXTURE_16BIT_PALETTE);
-      pTex_book_button5_on = pIcons_LOD->LoadTexturePtr("tabEon", TEXTURE_16BIT_PALETTE);
-      pTex_book_button5_off = pIcons_LOD->LoadTexturePtr("tabEoff", TEXTURE_16BIT_PALETTE);
-      pTex_book_button6_on = pIcons_LOD->LoadTexturePtr("tabWon", TEXTURE_16BIT_PALETTE);
-      pTex_book_button6_off = pIcons_LOD->LoadTexturePtr("tabWoff", TEXTURE_16BIT_PALETTE);
-
-      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,   50, 34, 1, 0, 
-                                     UIMSG_ClickBooksBtn, 0, 0, pGlobalTXT_LocalizationStrings[251], pTex_book_button1_on, 0);// "Zoom In"
-      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38,  50, 34, 1, 0, 
-                                     UIMSG_ClickBooksBtn, 1, 0, pGlobalTXT_LocalizationStrings[252], pTex_book_button2_on, 0);// "Zoom Out"
-      pBtn_Book_3 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 113, 50, 34, 1, 0, 
-                                     UIMSG_ClickBooksBtn, 2, 0, pGlobalTXT_LocalizationStrings[192], (Texture *)"", 0);// Scroll Up
-      pBtn_Book_4 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 150, 50, 34, 1, 0, 
-                                     UIMSG_ClickBooksBtn, 3, 0, pGlobalTXT_LocalizationStrings[193], (Texture *)"", 0);// Scroll Down
-      pBtn_Book_5 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 188, 50, 34, 1, 0, 
-                                     UIMSG_ClickBooksBtn, 4, 0, pGlobalTXT_LocalizationStrings[573], (Texture *)"", 0);// "Scroll Right"
-      pBtn_Book_6 = this->CreateButton(pViewport->uViewportTL_X + 397, pViewport->uViewportTL_Y + 226, 50, 34, 1, 0, 
-                                      UIMSG_ClickBooksBtn, 5, 0, pGlobalTXT_LocalizationStrings[572], (Texture *)"", 0);// "Scroll Left"
-    }
-    break;
-
-    case WINDOW_CalendarBook:
-    {
-      pSpellBookPagesTextr_13 = pIcons_LOD->LoadTexturePtr("sbdate-time", TEXTURE_16BIT_PALETTE);
-      pTex_moon_new = pIcons_LOD->LoadTexturePtr("moon_new", TEXTURE_16BIT_PALETTE);
-      pTex_moon_4   = pIcons_LOD->LoadTexturePtr("moon_4", TEXTURE_16BIT_PALETTE);
-      pTex_moon_2   = pIcons_LOD->LoadTexturePtr("moon_2", TEXTURE_16BIT_PALETTE);
-      pTex_moon_2_2 = pIcons_LOD->LoadTexturePtr("moon_2", TEXTURE_16BIT_PALETTE);
-      pTex_moon_ful = pIcons_LOD->LoadTexturePtr("moon_ful", TEXTURE_16BIT_PALETTE);
-    }
-    break;
-
-    case WINDOW_JournalBook:
-    {
-      pSpellBookPagesTextr_11  = pIcons_LOD->LoadTexturePtr("sbplayrnot", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_on  = pIcons_LOD->LoadTexturePtr("tab-an-6b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_on  = pIcons_LOD->LoadTexturePtr("tab-an-7b", TEXTURE_16BIT_PALETTE);
-      pTex_book_button1_off = pIcons_LOD->LoadTexturePtr("tab-an-6a", TEXTURE_16BIT_PALETTE);
-      pTex_book_button2_off = pIcons_LOD->LoadTexturePtr("tab-an-7a", TEXTURE_16BIT_PALETTE);
-
-      pBtn_Book_1 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 1,  
-                      pTex_book_button1_on->uTextureWidth,  pTex_book_button1_on->uTextureHeight, 1, 0, 
-                      UIMSG_ClickBooksBtn, 11, 0, pGlobalTXT_LocalizationStrings[192], pTex_book_button1_on, 0);
-      pBtn_Book_2 = this->CreateButton(pViewport->uViewportTL_X + 398, pViewport->uViewportTL_Y + 38, pTex_book_button2_on->uTextureHeight,
-                                      pTex_book_button2_on->uTextureHeight, 1, 0, UIMSG_ClickBooksBtn, 10, 0, 
-                                      pGlobalTXT_LocalizationStrings[193], pTex_book_button2_on, 0);
-
-      num_achieved_awards = 0;
-      journal_window.uFrameX = 48;
-      journal_window.uFrameY = 70;
-      journal_window.uFrameWidth = 360;
-      journal_window.uFrameHeight = 264;
-      journal_window.uFrameZ = 407;
-      journal_window.uFrameHeight = (LOBYTE(pAutonoteFont->uFontHeight) - 3) * 264 / LOBYTE(pAutonoteFont->uFontHeight) - 3;
-      journal_window.uFrameW = journal_window.uFrameHeight + 69;
-      memset(&achieved_awards, 0, 4000);
-      memset(Journal_limitation_factor.data(), 0, 100);
-      if ( books_primary_item_per_page < 29 )
-      {
-        for ( int i = books_primary_item_per_page; i < books_primary_item_per_page + 29; i++ )
-        {
-          if ( pParty->PartyTimes.HistoryEventTimes[i] > 0 )
-          {
-            if ( pStorylineText->StoreLine[i + 1].pText )
-            {
-              pString = BuildDialogueString(pStorylineText->StoreLine[i + 1].pText, uActiveCharacter - 1, 0, 0, 0, &pParty->PartyTimes.HistoryEventTimes[i]);
-              pTextHeight = pAutonoteFont->CalcTextHeight(pString, &journal_window, 1, 0);
-              page_count = ((pTextHeight - (pAutonoteFont->uFontHeight - 3)) / (signed int)journal_window.uFrameHeight) + 1;
-              memset32((char *)&achieved_awards[num_achieved_awards] , i + 1, page_count);
-              for ( uint j = 0; j <= page_count - 1; ++j )
-                Journal_limitation_factor[num_achieved_awards++] = j;
-            }
-          }
-        }
-      }
-      full_num_items_in_book = num_achieved_awards;
-      num_achieved_awards = 0;
-    }
-    break;
-  }
-}
-
-//----- (00415551) --------------------------------------------------------
-void GUIWindow::DrawMessageBox(int arg0)
-{
-  unsigned int v2; // edi@1
-  signed int v4; // esi@2
-  unsigned int v5; // eax@2
-  unsigned int v16; // esi@19
-  GUIWindow current_window; // [sp+Ch] [bp-60h]@18
-  POINT cursor; // [sp+60h] [bp-Ch]@8
-  unsigned int v22; // [sp+74h] [bp+8h]@2
-
-  v2 = 0;
-  if ( arg0 )
-  {
-    v4 = pViewport->uViewportTL_X;
-    v5 = pViewport->uViewportBR_X;
-    v2 = pViewport->uViewportTL_Y;
-    v22 = pViewport->uViewportBR_Y;
-  }
-  else
-  {
-    v4 = 0;
-    v5 = window->GetWidth();
-    v22 = window->GetHeight();
-  }
-  pMouse->GetCursorPos(&cursor);
-  if ( (signed int)this->uFrameX >= v4 )
-  {
-    if ( (signed int)(this->uFrameWidth + this->uFrameX) > (signed int)v5 )
-    {
-      this->uFrameX = v5 - this->uFrameWidth;
-      this->uFrameY = cursor.y + 30;
-    }
-  }
-  else
-  {
-    this->uFrameX = v4;
-    this->uFrameY = cursor.y + 30;
-  }
-
-  if ( (signed int)this->uFrameY >= (signed int)v2 )
-  {
-    if ( (signed int)(this->uFrameY + this->uFrameHeight) > (signed int)v22 )
-      this->uFrameY = cursor.y - this->uFrameHeight - 30;
-  }
-  else
-    this->uFrameY = cursor.y + 30;
-  if ( (signed int)this->uFrameY < (signed int)v2 )
-    this->uFrameY = v2;
-  if ( (signed int)this->uFrameX < v4 )
-    this->uFrameX = v4;
-  this->uFrameZ = this->uFrameWidth + this->uFrameX - 1;
-  this->uFrameW = this->uFrameHeight + this->uFrameY - 1;
-  memcpy(&current_window, this, sizeof(current_window));
-  current_window.uFrameX += 12;
-  current_window.uFrameWidth -= 24;
-  current_window.uFrameY += 12;
-  current_window.uFrameHeight -= 12;
-  current_window.uFrameZ = current_window.uFrameWidth + current_window.uFrameX - 1;
-  current_window.uFrameW = current_window.uFrameHeight + current_window.uFrameY - 1;
-  if ( this->Hint )
-    v16 = pFontLucida->CalcTextHeight(this->Hint, &current_window, 0, 0) + 24;
-  else
-    v16 = this->uFrameHeight;
-  if ( (signed int)v16 < 64 )
-    v16 = 64;
-  if ( (signed int)(v16 + this->uFrameY) > 479 )
-    v16 = 479 - this->uFrameY;
-  DrawPopupWindow(this->uFrameX, this->uFrameY, this->uFrameWidth, v16);
-  if ( this->Hint )
-    current_window.DrawTitleText(pFontLucida, 0, (signed int)(v16 - pFontLucida->CalcTextHeight(this->Hint, &current_window, 0, 0)) / 2 - 14, 0, this->Hint, 3);
-}
-
-//----- (00411B59) --------------------------------------------------------
-void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer)
-{
-  //unsigned int v2; // esi@1
-  //unsigned int v3; // edi@1
-  FILE *v4; // ebx@1
-  FILE *v5; // eax@2
-  char pContainerName[64]; // [sp+Ch] [bp-44h]@1
-  //unsigned int v7; // [sp+4Ch] [bp-4h]@1
-
-  //v2 = uSlot;
-  //v7 = uPlayer;
-  //v3 = uSlot + 1;
-  sprintf(pContainerName, "data\\lloyd%d%d.pcx", uPlayer, uSlot + 1);
-  v4 = fopen(pContainerName, "rb");
-  if ( v4 )
-  {
-    pSavegameThumbnails[uSlot].LoadFromFILE(v4, 0, 1);
-    fclose(v4);
-  }
-  else
-  {
-    sprintf(pContainerName, "lloyd%d%d.pcx", uPlayer, uSlot + 1);
-    v5 = pNew_LOD->FindContainer(pContainerName, 1);
-    if ( v5 )
-      pSavegameThumbnails[uSlot].LoadFromFILE(v5, 0, 0);
-    else
-      *((int *)&pSavegameThumbnails.data()->pPixels + 10 * uSlot) = 0;
-  }
-}
-
-
-//----- (00411621) --------------------------------------------------------
-void GUIWindow::OpenSpellBook()
-{
-  Player *pPlayer; // edi@1
-  //GUIWindow *pWindow; // esi@1
-  //unsigned int v3; // ebp@1
-  int v4; // eax@3
-  ///GUIButton *result; // eax@25
-  int a2; // [sp+10h] [bp-8h]@1
-  //int v7; // [sp+14h] [bp-4h]@1
-
-  pPlayer = pPlayers[uActiveCharacter];
-  //pWindow = this;
-  LoadSpellbook(pPlayer->lastOpenedSpellbookPage);
-  //v3 = 0;
-  a2 = 0;
-
-  PlayerSpellbookChapter* chapter = &pPlayer->spellbook.pChapters[pPlayer->lastOpenedSpellbookPage];
-  for (uint i = 0; i < 11; ++i)
-  {
-    if (!chapter->bIsSpellAvailable[i])
-      continue;
-		v4= pPlayer->lastOpenedSpellbookPage;
-      //v4 = (12 * pPlayer->lastOpenedSpellbookPage + pSpellbookSpellIndices[pPlayer->lastOpenedSpellbookPage][i + 1]);
-      CreateButton(pViewport->uViewportTL_X +  pIconPos[v4][pSpellbookSpellIndices[v4][i+1]].Xpos,
-                   pViewport->uViewportTL_Y +  pIconPos[v4][pSpellbookSpellIndices[v4][i+1]].Ypos,  //dword_4E20D0
-                   SBPageSSpellsTextureList[i + 1]->uTextureWidth,
-                   SBPageSSpellsTextureList[i + 1]->uTextureHeight,
-                   1, 79, UIMSG_SelectSpell, i, 0, "", 0);
-      ++a2;
-    //++v3;
-  }
-  //while ( (signed int)v3 < 11 );
-
-  CreateButton(0, 0, 0, 0, 1, 0, UIMSG_SpellBook_PressTab, 0, '\t', "", 0);
-  if ( a2 )
-    _41D08F_set_keyboard_control_group(a2, 0, 0, 0);
-
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_FIRE])   CreateButton(399,  10, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 0, 0, aSpellSchoolNames[0], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_AIR])    CreateButton(399,  46, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 1, 0, aSpellSchoolNames[1], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_WATER])  CreateButton(399,  83, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 2, 0, aSpellSchoolNames[2], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_EARTH])  CreateButton(399, 121, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 3, 0, aSpellSchoolNames[3], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_SPIRIT]) CreateButton(399, 158, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 4, 0, aSpellSchoolNames[4], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_MIND])   CreateButton(400, 196, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 5, 0, aSpellSchoolNames[5], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_BODY])   CreateButton(400, 234, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 6, 0, aSpellSchoolNames[6], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_LIGHT])  CreateButton(400, 271, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 7, 0, aSpellSchoolNames[7], 0);
-  if (pPlayer->pActiveSkills[PLAYER_SKILL_DARK])   CreateButton(400, 307, 50, 36, 1, 0, UIMSG_OpenSpellbookPage, 8, 0, aSpellSchoolNames[8], 0);
-
-                            CreateButton(476, 450, pSBClickQuickSpellBtnTextr->uTextureWidth, pSBClickQuickSpellBtnTextr->uTextureHeight, 1, 78, UIMSG_ClickInstallRemoveQuickSpellBtn, 0, 0, "", 0);
-  pBtn_InstallRemoveSpell = CreateButton(476, 450, 48, 32, 1, 78, UIMSG_ClickInstallRemoveQuickSpellBtn, 0, 0, "", pSBClickQuickSpellBtnTextr, 0);
-                            CreateButton(561, 450, pSpellBookClickCloseBtnTextr->uTextureWidth, pSpellBookClickCloseBtnTextr->uTextureHeight, 1,  0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
-  pBtn_CloseBook          = CreateButton(561, 450, 48, 32, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], pSpellBookClickCloseBtnTextr, 0);
-}
-// 50640C: using guessed type int dword_50640C[];
-
-//----- (004B3157) --------------------------------------------------------
-void GUIWindow::HouseDialogManager()
-{
-  unsigned __int16 pWhiteColor; // di@2
-  const char *pHouseName; // edx@4
-  signed int v3; // edx@5
-  char *v4; // edi@9
-  int pTextHeight; // eax@45
-  int v6; // edi@45
-  char *v7; // eax@45
-  int v8; // edi@46
-  int v9; // eax@50
-  unsigned int v10; // [sp-10h] [bp-C8h]@53
-  char *pTitleText; // [sp-8h] [bp-C0h]@50
-  GUIWindow pDialogWindow; // [sp+Ch] [bp-ACh]@4
-  GUIWindow pWindow; // [sp+60h] [bp-58h]@2
-  int pColor2; // [sp+B4h] [bp-4h]@2
-
-  if ( !window_SpeakInHouse )
-    return;
-  memcpy(&pWindow, this, sizeof(pWindow));
-  pWindow.uFrameWidth -= 18;
-  pWindow.uFrameZ -= 18;
-  pWhiteColor = Color16(0xFFu, 0xFFu, 0xFFu);
-  pColor2 = Color16(0x15u, 0x99u, 0xE9u);
-  pRenderer->DrawTextureIndexed(0x1DDu, 0, pTexture_Dialogue_Background);
-  pRenderer->DrawTextureTransparent(0x1D4u, 0, &pIcons_LOD->pTextures[uTextureID_right_panel_loop]);
-  if ( pDialogueNPCCount != uNumDialogueNPCPortraits || !uHouse_ExitPic )
-  {
-    pDialogWindow.uFrameWidth = 130;
-    pDialogWindow.uFrameHeight = 2 * LOBYTE(pFontCreate->uFontHeight);
-    pHouseName = p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pName;
-    if ( pHouseName )
-    {
-      v3 = 2 * LOBYTE(pFontCreate->uFontHeight) - 6 - pFontCreate->CalcTextHeight(pHouseName, &pDialogWindow, 0, 0);
-      if ( v3 < 0 )
-        v3 = 0;
-      pWindow.DrawTitleText(pFontCreate, 0x1EAu, v3 / 2 + 4, pWhiteColor,
-        //(const char *)p2DEvents_minus1_::04[13 * (unsigned int)ptr_507BC0->ptr_1C],
-        p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pName, 3);
-    }
-  }
-  pWindow.uFrameWidth += 8;
-  pWindow.uFrameZ += 8;
-  if ( !pDialogueNPCCount )
-  {
-    if ( in_current_building_type == BuildingType_Jail )
-    {
-      JailDialog();
-      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-      {
-        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
-        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
-      }
-      else
-        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
-      return;
-    }
-    if ( current_npc_text )
-    {
-      pDialogWindow.uFrameWidth = 458;
-      pDialogWindow.uFrameZ = 457;
-      pTextHeight = pFontArrus->CalcTextHeight(current_npc_text, &pDialogWindow, 13, 0);
-      v6 = pTextHeight + 7;
-      pRenderer->GetLeather(8, 352 - (pTextHeight + 7), &pIcons_LOD->pTextures[uTextureID_Leather], 
-          pIcons_LOD->pTextures[uTextureID_Leather].uTextureHeight - (pTextHeight + 7));
-      pRenderer->DrawTextureIndexed(8, 347 - v6, pTexture_591428);
-      v7 = FitTextInAWindow(current_npc_text, pFontArrus, &pDialogWindow, 0xDu, 0);
-      window_SpeakInHouse->DrawText(pFontArrus, 13, 354 - v6, 0, v7, 0, 0, 0);
-    }
-    if ( uNumDialogueNPCPortraits <= 0 )
-    {
-      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-      {
-        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
-        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
-      }
-      else
-        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
-      return;
-    }
-    for ( v8 = 0; v8 < uNumDialogueNPCPortraits; ++v8 )
-    {
-      pRenderer->DrawTextureIndexed(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v8] - 4,
-                                    pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8] - 4, &pIcons_LOD->pTextures[uTextureID_50795C]);
-      pRenderer->DrawTextureIndexed(pNPCPortraits_x[uNumDialogueNPCPortraits - 1][v8],
-                                    pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8], pDialogueNPCPortraits[v8]);
-      if ( uNumDialogueNPCPortraits < 4 )
-      {
-        if ( v8 + 1 == uNumDialogueNPCPortraits && uHouse_ExitPic )
-        {
-          pTitleText = pMapStats->pInfos[uHouse_ExitPic].pName;
-          v9 = 94 * v8 + 113;
-        }
-        else
-        {
-          if ( !v8 && dword_591080 )
-          {
-            pTitleText = (char *)p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterTitle;
-            pWindow.DrawTitleText(pFontCreate, 0x1E3u, 113, pColor2, pTitleText, 3);
-            continue;
-          }
-          pTitleText = HouseNPCData[v8 +1 - (dword_591080 != 0)]->pName;
-          v9 = pNPCPortraits_y[uNumDialogueNPCPortraits - 1][v8] + pDialogueNPCPortraits[v8]->uTextureHeight + 2;
-        }
-        v10 = v9;
-        pWindow.DrawTitleText(pFontCreate, 483, v10, pColor2, pTitleText, 3);
-      }
-    }
-      if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-      {
-        pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
-        pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
-      }
-      else
-        pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
-      return;
-  }
-  v4 = (char *)pDialogueNPCCount - 1;
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0] - 4, pNPCPortraits_y[0][0] - 4, &pIcons_LOD->pTextures[uTextureID_50795C]);
-  pRenderer->DrawTextureIndexed(pNPCPortraits_x[0][0], pNPCPortraits_y[0][0], pDialogueNPCPortraits[(signed int)v4]);
-  if ( pCurrentScreen == SCREEN_E )
-  {
-    CharacterUI_InventoryTab_Draw(pPlayers[uActiveCharacter], true);
-    if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-    {
-      pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
-      pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
-    }
-    else
-      pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
-    return;
-  }
-  if ( v4 || !dword_591080 )//íà èçóìðóäíîì îñòðîâå çàõîäèò íà êîðàáëå ïîêà íå âûïîëíåíû êâåñòû
-    SimpleHouseDialog();
-  else
-  {
-    sprintfex( pTmpBuf.data(), pGlobalTXT_LocalizationStrings[429],
-      p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterName,
-      p2DEvents[(unsigned int)window_SpeakInHouse->ptr_1C - 1].pProprieterTitle);
-    pWindow.DrawTitleText(pFontCreate, 0x1E3u, 0x71u, pColor2, pTmpBuf.data(), 3);
-      switch ( in_current_building_type )
-      {
-        case BuildingType_WeaponShop:
-          WeaponShopDialog();
-          break;
-        case BuildingType_ArmorShop:
-          ArmorShopDialog();
-          break;
-        case BuildingType_MagicShop:
-          MagicShopDialog();
-          break;
-        case BuildingType_AlchemistShop:
-          AlchemistDialog();
-          break;
-        case BuildingType_FireGuild:
-        case BuildingType_AirGuild:
-        case BuildingType_WaterGuild:
-        case BuildingType_EarthGuild:
-        case BuildingType_SpiritGuild:
-        case BuildingType_MindGuild:
-        case BuildingType_BodyGuild:
-        case BuildingType_LightGuild:
-        case BuildingType_DarkGuild:
-          GuildDialog();
-          break;
-        case BuildingType_18:
-          __debugbreak(); //What over the dialog?
-          sub_4B6478();
-          break;
-        case BuildingType_TownHall:
-          TownHallDialog();
-          break;
-        case BuildingType_Tavern:
-          TavernDialog();
-          break;
-        case BuildingType_Bank:
-          BankDialog();
-          break;
-        case BuildingType_Temple:
-          TempleDialog();
-          break;
-        case BuildingType_Stables:
-        case BuildingType_Boats:
-          TravelByTransport();
-          break;
-        case BuildingType_Training:
-          TrainingDialog();
-          break;
-        case BuildingType_Jail:
-          JailDialog();
-          break;
-        default:
-          //__debugbreak();//New BuildingType (if enter Boat)
-          break;
-      }
-  }
-  if ( pDialogueNPCCount == uNumDialogueNPCPortraits && uHouse_ExitPic )
-  {
-    pRenderer->DrawTextureIndexed(556, 451, &pIcons_LOD->pTextures[uTextureID_x_x_u]);
-    pRenderer->DrawTextureIndexed(476, 451, &pIcons_LOD->pTextures[uTextureID_x_ok_u]);
-  }
-  else
-    pRenderer->DrawTextureIndexed(471, 445, &pIcons_LOD->pTextures[uExitCancelTextureId]);
-}
-
-//----- (004B1854) --------------------------------------------------------
-void GUIWindow::DrawShops_next_generation_time_string( __int64 next_generation_time )
-{
-  unsigned int full_time; // esi@1
-  signed __int64 hours; // kr00_8@1
-  const char *text; // eax@2
-  signed __int64 minutes; // [sp+Ch] [bp-10h]@1
-  signed __int64 seconds; // [sp+14h] [bp-8h]@1
-  unsigned int days; // [sp+20h] [bp+4h]@1
-
-  full_time = (signed __int64)((double)next_generation_time * 0.234375);
-  seconds = (signed __int64)full_time % 60;
-  minutes = (signed __int64)(full_time / 60) % 60;
-  hours = ((full_time / 60) / 60) % 24;
-  days = (unsigned int)((full_time / 60) / 60) / 24;
-  strcpy(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[532]);
-  if ( days )
-  {
-    text = pGlobalTXT_LocalizationStrings[57];//Days
-    if ( days <= 1 )
-      text = pGlobalTXT_LocalizationStrings[56];//Day
-    sprintfex(pTmpBuf2.data(), "%d %s ", days, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( hours )
-  {
-    if ( hours <= 1 )
-      text = pGlobalTXT_LocalizationStrings[109];//Hour
-    else
-      text = pGlobalTXT_LocalizationStrings[110];//Hours
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)hours, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( minutes && !days )
-  {
-    if ( minutes <= 1 )
-      text = pGlobalTXT_LocalizationStrings[437];//"Minute"
-    else
-      text = pGlobalTXT_LocalizationStrings[436]; //"Minutes"
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)minutes, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( seconds && !hours )
-  {
-    if ( seconds <= 1 )
-      text = pGlobalTXT_LocalizationStrings[439]; //"Second"	
-    else
-      text = pGlobalTXT_LocalizationStrings[438]; //"Seconds"
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)seconds, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  this->DrawTitleText(pFontArrus, 0, (212 - pFontArrus->CalcTextHeight(pTmpBuf.data(), this, 0, 0)) / 2 + 101, Color16(0xFFu, 0xFFu, 0x9Bu), pTmpBuf.data(), 3);
-}
-
-//----- (0044D406) --------------------------------------------------------
-void GUIWindow::DrawTitleText( GUIFont *a2, signed int uHorizontalMargin, unsigned int uVerticalMargin, unsigned __int16 uDefaultColor, 
-                               const char *pInString, unsigned int uLineSpacing )
-{
-  //GUIWindow *pWindow; // esi@1
-  unsigned int v8; // ebx@1
-  char *v9; // eax@1
-  unsigned int v11; // edi@1
-  signed int v12; // esi@1
-  int v13; // eax@2
-  GUIFont *pFont; // [sp+Ch] [bp-4h]@1
-  const char *Stra; // [sp+24h] [bp+14h]@5
-
-  //pWindow = this;
-  pFont = a2;
-  v8 = this->uFrameWidth - uHorizontalMargin;
-  ui_current_text_color = uDefaultColor;
-  v9 = FitTextInAWindow(pInString, a2, this, uHorizontalMargin, 0);
-  Stra = strtok(v9, "\n");
-  v11 = uHorizontalMargin + this->uFrameX;
-  v12 = uVerticalMargin + this->uFrameY;
-  while ( 1 )
-  {
-    if ( !Stra )
-      break;
-    v13 = (signed int)(v8 - pFont->GetLineWidth(Stra)) >> 1;
-    if ( v13 < 0 )
-      v13 = 0;
-    pFont->DrawTextLine(uDefaultColor, v11 + v13, v12, Stra, window->GetWidth());
-    v12 += pFont->uFontHeight - uLineSpacing;
-    Stra = strtok(0, "\n");
-  }
-}
-// 5C6DB4: using guessed type int ui_current_text_color;
-
-//----- (0044CE08) --------------------------------------------------------
-void GUIWindow::DrawText( GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, signed int uFontShadowColor )
-    {
-  GUIWindow *v9; // edi@1
-  GUIFont *v10; // ebx@1
-  int v11; // eax@2
-  signed int v12; // esi@9
-  signed int v13; // edi@9
-  int v14; // edx@9
-  int v15; // eax@25
-  unsigned int v16; // ecx@25
-  int v17; // eax@27
-  int v18; // edi@32
-  int v19; // esi@38
-  std::string v21; // [sp-18h] [bp-50h]@2
-//  const char *v22; // [sp-8h] [bp-40h]@2
-//  int v23; // [sp-4h] [bp-3Ch]@2
-  char Dest[6]; // [sp+Ch] [bp-2Ch]@32
-  //char v25; // [sp+Fh] [bp-29h]@32
-  //char v26; // [sp+11h] [bp-27h]@34
-  const char *v27; // [sp+20h] [bp-18h]@25
-  int v28; // [sp+24h] [bp-14h]@25
-  int v29; // [sp+28h] [bp-10h]@1
-  size_t v30; // [sp+2Ch] [bp-Ch]@4
-  GUIWindow *v31; // [sp+30h] [bp-8h]@1
-  const char *v32; // [sp+34h] [bp-4h]@7
-  size_t pInString; // [sp+4Ch] [bp+14h]@11
-  
-  GUIWindow* a1 = this;
-  v29 = 0;
-  v9 = a1;
-  v10 = a2;
-  v31 = a1;
-  if ( !Str )
-  {
-    MessageBoxW(nullptr, L"Invalid string passed!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:859", 0);
-    return;
-  }
-  v11 = strcmp(Str, "null");
-  if ( v11 )
-  {
-    v30 = strlen(Str);
-    LOBYTE(v11) = 0;
-    if ( !uX )
-      uX = 12;
-    if ( a8 )
-      v32 = Str;
-    else
-    {
-      v11 = (int)FitTextInAWindow(Str, v10, v9, uX, 0);
-      v32 = (const char *)v11;
-    }
-    v12 = uX + v9->uFrameX;
-    v13 = uY + v9->uFrameY;
-    v14 = 0;
-    if ( !a8 || (v11 = v13 + LOBYTE(v10->uFontHeight), v11 <= a8) )
-    {
-      pInString = 0;
-      if ( (signed int)v30 > 0 )
-      {
-        do
-        {
-          LOBYTE(v11) = v32[v14];
-          if ( (unsigned __int8)v11 >= v10->cFirstChar && (unsigned __int8)v11 <= v10->cLastChar
-            || (char)v11 == 12
-            || (char)v11 == 13
-            || (char)v11 == 9
-            || (char)v11 == 10 )
-          {
-            switch ( (unsigned __int8)v11 )
-            {
-              case 9u:
-                strncpy(Dest, &v32[v14 + 1], 3);
-                Dest[3] = 0;
-                pInString += 3;
-                v29 = atoi(Dest);
-                v19 = atoi(Dest);
-                LOBYTE(v11) = (char)v31;
-                v12 = uX + v31->uFrameX + v19;
-                break;
-              case 0xAu:
-                v11 = LOBYTE(v10->uFontHeight);
-                uY = uY + v11 - 3;
-                v13 = uY + v31->uFrameY;
-                v12 = uX + v29 + v31->uFrameX;
-                if ( a8 )
-                {
-                  v11 = v11 + v13 - 3;
-                  if ( v11 > a8 )
-                    return;
-                }
-                break;
-              case 0xCu:
-                strncpy(Dest, &v32[v14 + 1], 5);
-                Dest[5] = 0;
-                v11 = atoi(Dest);
-                pInString += 5;
-                uFontColor = v11;
-                break;
-              case 0xDu:
-                strncpy(Dest, &v32[v14 + 1], 3);
-                Dest[3] = 0;
-                pInString += 3;
-                v18 = atoi(Dest);
-                v11 = v10->GetLineWidth(&v32[pInString]);
-                v12 = v31->uFrameZ - v11 - v18;
-                v13 = uY + v31->uFrameY;
-                if ( a8 )
-                {
-                  v11 = LOBYTE(v10->uFontHeight);
-                  v11 = v11 + v13 - 3;
-                  if ( v11 > a8 )
-                    return;
-                  break;
-                }
-                break;
-              default:
-                if ( (char)v11 == 34 && v32[v14 + 1] == 34 )
-                {
-                  ++v14;
-                  pInString = v14;
-                }
-                v27 = &v32[v14];
-                v15 = (unsigned __int8)v32[v14];
-                v16 = *((int *)&v10->cFirstChar + 3 * v15 + 9);
-                v28 = *((int *)&v10->cFirstChar + 3 * v15 + 9);
-                if ( v14 > 0 )
-                  v12 += v10->pMetrics[v15].uLeftSpacing;
-                v17 = (int)((char *)&v10[1] + v10->font_pixels_offset[v15]);
-                if ( (short)uFontColor )
-                  pRenderer->DrawText(v12, v13, (unsigned __int8 *)v17, v16, LOBYTE(v10->uFontHeight),
-                    v10->pFontPalettes[0], uFontColor, uFontShadowColor);
-                else
-                  pRenderer->DrawTextPalette(v12, v13, (unsigned char*)v17, v16, LOBYTE(v10->uFontHeight),
-                    v10->pFontPalettes[0], a7);
-                LOBYTE(v11) = v30;
-                v12 += v28;
-                if ( (signed int)pInString < (signed int)v30 )
-                {
-                  LOBYTE(v11) = 3 * *v27;
-                  v12 += v10->pMetrics[(unsigned __int8)*v27].uRightSpacing;
-                }
-                break;
-            }
-          }
-          v14 = pInString++ + 1;
-        }
-        while ( (signed int)pInString < (signed int)v30 );
-      }
-    }
-  }
-  return;
-}
-
-
-//----- (0044CB4F) --------------------------------------------------------
-int GUIWindow::DrawTextInRect( GUIFont *pFont, unsigned int uX, unsigned int uY, unsigned int uColor, const char *text, int rect_width, int reverse_text )
-{
-  int pLineWidth; // ebx@1
-  int text_width; // esi@3
-  unsigned __int8 v12; // cl@7
-  signed int v13; // esi@19
-  signed int v14; // ebx@19
-  unsigned __int8 v15; // cl@21
-//  int v16; // eax@22
-//  int v17; // ecx@22
-//  int v18; // ecx@23
-//  int v19; // ecx@24
-  unsigned int v20; // ecx@26
-  unsigned char* v21; // eax@28
-//  int v22; // ebx@34
-  int v23; // eax@34
-  int v24; // ebx@36
-  char Str[6]; // [sp+Ch] [bp-20h]@34
-//  char v26; // [sp+Fh] [bp-1Dh]@34
-//  char v27; // [sp+11h] [bp-1Bh]@35
-  int v28; // [sp+20h] [bp-Ch]@17
-  GUIWindow *pWindow; // [sp+24h] [bp-8h]@1
-  size_t pNumLen; // [sp+28h] [bp-4h]@1
-  size_t Str1a; // [sp+40h] [bp+14h]@5
-//  size_t Str1b; // [sp+40h] [bp+14h]@19
-//  const char *Sourcea; // [sp+44h] [bp+18h]@20
-//  int v34; // [sp+48h] [bp+1Ch]@26
-  int i;
-
-
-  pWindow = this;
-  pNumLen = strlen(text);
-  pLineWidth = pFont->GetLineWidth(text);
-  if ( pLineWidth < rect_width )
-  {
-    pWindow->DrawText(pFont, uX, uY, uColor, text, 0, 0, 0);
-    return pLineWidth;
-  }
-  strcpy(pTmpBuf2.data(), text);
-  text_width = 0;
-  if ( reverse_text )
-    _strrev(pTmpBuf2.data());
-  Str1a = 0;
-  for ( i = 0; i < pNumLen; ++i )
-    {
-      if ( text_width >= rect_width )
-        break;
-      v12 = pTmpBuf2[i];
-      if ( pFont->IsCharValid(v12) )
-      {
-      switch (v12)
-          {
-      case '\t':// Horizontal tab 09
-      case '\n': //Line Feed 0A 10
-      case '\r': //Form Feed, page eject  0C 12
-          break;
-      case '\f': //Carriage Return 0D 13
-          i += 5;	  
-          break;
-      default:
-          if ( i > 0 )
-            text_width += pFont->pMetrics[v12].uLeftSpacing;
-          text_width += pFont->pMetrics[v12].uWidth;
-          if ( i < pNumLen )
-              text_width += pFont->pMetrics[v12].uRightSpacing;
-          }
-      }
-    }
-  pTmpBuf2[i - 1] = 0;
-
-
-  pNumLen = strlen(pTmpBuf2.data());
-  v28 = pFont->GetLineWidth(pTmpBuf2.data());
-  if ( reverse_text )
-    _strrev(pTmpBuf2.data());
-
-  v13 = uX + pWindow->uFrameX;
-  v14 = uY + pWindow->uFrameY;
-  for (i=0; i<pNumLen; ++i)
-  {
-      v15 = pTmpBuf2[i];
-      if ( pFont->IsCharValid(v15) )
-      {
-      switch (v12)
-          {
-      case '\t':// Horizontal tab 09
-          {
-          strncpy(Str,  &pTmpBuf2[i+1], 3);
-          Str[3] = 0;
-       //   atoi(Str);
-          i += 3;
-          break;
-          }
-      case '\n': //Line Feed 0A 10
-          {
-          v24 = pFont->uFontHeight;
-          v13 = uX;
-          uY = uY + pFont->uFontHeight - 3;
-          v14 = uY+pFont->uFontHeight - 3;
-          break;
-          }
-      case '\r': //Form Feed, page eject  0C 12
-          {
-          strncpy(Str, &pTmpBuf2[i+1], 5);
-          Str[5] = 0;
-          i += 5;
-          uColor = atoi(Str);
-          break;
-          }
-      case '\f': //Carriage Return 0D 13
-          {
-          strncpy(Str, &pTmpBuf2[i+1], 3);
-          Str[3] = 0;
-          i += 3;
-          v23 = pFont->GetLineWidth(&pTmpBuf2[i]);
-          v13 = pWindow->uFrameZ - v23 - atoi(Str);
-          v14 = uY;
-          break;
-          }
-      default:
-          v20 = pFont->pMetrics[v15].uWidth;
-          if ( i > 0 )
-              v13 += pFont->pMetrics[v15].uLeftSpacing;
-          v21 = &pFont->pFontData[pFont->font_pixels_offset[v15]];
-          if ( uColor )
-              pRenderer->DrawText(v13, v14,  v21, v20, pFont->uFontHeight, pFont->pFontPalettes[0], uColor, 0);
-          else
-              pRenderer->DrawTextPalette(v13, v14, v21, v20, pFont->uFontHeight, pFont->pFontPalettes[0], 0);
-          v13 += v20;
-          if ( i < (signed int)pNumLen )
-              v13 += pFont->pMetrics[v15].uRightSpacing;
-          }
-      }
-  }
-  return v28;
-}
-
-//----- (0041D12F) --------------------------------------------------------
-GUIButton *GUIWindow::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, Texture *pTextures, ...)
-{
-  GUIButton *pButton; // esi@1
-//  unsigned int v13; // eax@1
-//  unsigned int v14; // ebx@4
-//  unsigned int v15; // eax@4
-  unsigned int TextureNum=0; // ebx@4
-//  unsigned int v17; // eax@4
-//  Texture *v18; // eax@4
-//  Texture **v19; // ecx@5
-//  Texture **v20; // edx@5
-//  GUIButton *v21; // eax@7
-  va_list texturs_ptr;
-
-  pButton = (GUIButton *)malloc(0xBC);
-  pButton->pParent = this;
-  pButton->uWidth = uWidth;
-  pButton->uHeight = uHeight;
-  
-  if ( a6 == 2 && !uHeight )
-    pButton->uHeight = uWidth;
-
-  pButton->uButtonType = a6;
-  pButton->uX = uX + this->uFrameX;
-  pButton->uY = uY + this->uFrameY;
-  pButton->uZ = pButton->uX + uWidth - 1;
-  pButton->uW = pButton->uY + uHeight - 1;
-  pButton->field_2C_is_pushed = 0;
-  pButton->field_1C = a7;
-  pButton->msg = msg;
-  pButton->msg_param = msg_param;
-  pButton->uHotkey = uHotkey;
-  //strlen(pName);
-  strcpy(pButton->pButtonName, pName);
-  va_start(texturs_ptr, pName);
-  while  (NULL!=(pTextures=va_arg(texturs_ptr, Texture *)))
-  {
-	pButton->pTextures[TextureNum]=pTextures;
-	++TextureNum;	
-  }
-  va_end(texturs_ptr);
-  pButton->uNumTextures = TextureNum;
-  if ( this->pControlsTail )
-    this->pControlsTail->pNext = pButton;
-  else
-    this->pControlsHead = pButton;
-  pButton->pPrev = this->pControlsTail;
-  this->pControlsTail = pButton;
-  pButton->pNext = 0;
-  ++this->uNumControls;
-  return pButton;
-}
-
-//----- (00459C2B) --------------------------------------------------------
-void GUIWindow::DrawFlashingInputCursor( signed int uX, int uY, struct GUIFont *a2 )
-{
-  if ( GetTickCount() % 1000 > 500 )
-    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
-
-  for (uNextFreeWindowID = 0; uNextFreeWindowID < 20; ++uNextFreeWindowID)
-  {
-    if (pWindowList[uNextFreeWindowID].eWindowType == WINDOW_null)
-      break;
-  }
-
-  GUIWindow* pWindow = &pWindowList[uNextFreeWindowID];
-  pWindow->uFrameWidth = uWidth;
-  pWindow->uFrameHeight = uHeight;
-
-  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)
-    {
-      switch (eWindowType)
-      {
-        case WINDOW_Book: {
-          pWindow->InitializeBookView();
-          break;
-          }
-        case WINDOW_Dialogue: {
-          pMainScreenNum = pCurrentScreen;
-          pCurrentScreen = 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:
-        {
-          pMainScreenNum = pCurrentScreen;
-          pCurrentScreen = 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: {// îêíî ïðèâåòñòâèÿ ÍÏÑ
-          pMainScreenNum = pCurrentScreen;
-          pKeyActionMap->EnterText(0, 15, pWindow);
-          pCurrentScreen = SCREEN_BRANCHLESS_NPC_DIALOG;
-          break;
-            }
-
-      }
-      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)
-  {
-    pCurrentScreen = 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)
-    {
-      pMainScreenNum = pCurrentScreen;
-      pCurrentScreen = 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;
-      pCurrentScreen = SCREEN_CASTING;
-      if ( !pIcons_LOD->uNumPrevLoadedFiles )
-        pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles;
-    }
-  }
-  return pWindow;
-}
-//----- (004B3EF0) --------------------------------------------------------
-void DrawJoinGuildWindow( int pEventCode )
-{
-  uDialogueType = 81;//enum JoinGuildDialog
-  current_npc_text = (char *)pNPCTopics[pEventCode + 99].pText;
-  ContractSelectText(pEventCode);
-  pDialogueWindow->Release();
-  pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 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->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
-  dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-}
-//----- (0044603D) --------------------------------------------------------
-void  DialogueEnding()
-{
-  sDialogue_SpeakingActorNPC_ID = 0;
-  pDialogueWindow->Release();
-  pDialogueWindow = 0;
-  pMiscTimer->Resume();
-  pEventTimer->Resume();
-}
-//----- (004156F0) --------------------------------------------------------
-void GUI_UpdateWindows() 
-{
-  GUIWindow *pWindow; // esi@4
-  //unsigned int pWindowType; // eax@4
-  const char *pHint; // edx@66
-//  GUIButton *pButtonPtr_1C; // ebp@79
-//  char *pHint1; // edx@80
-  int v26; // eax@98
-  unsigned int v27; // ebp@106
-  GUIWindow *pGUIWindow2; // ecx@109
-//  GUIFont *pGUIFont; // ST1C_4@115
-  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
-  //Texture *pTexture; // [sp-14h] [bp-11Ch]@17
-  //Texture *pTexture2; // [sp-14h] [bp-11Ch]@86
-  int i; // [sp+0h] [bp-108h]@3
-//  ItemGen pItemGen; // [sp+4h] [bp-104h]@98
-  GUIButton GUIButton2; // [sp+28h] [bp-E0h]@133
-  ItemGen ItemGen2; // [sp+E4h] [bp-24h]@129
-
-  if (GetCurrentMenuID() != MENU_CREATEPARTY)
-    Mouse::UI_OnKeyDown(VK_NEXT);
-
-  for ( i = 1; i <= uNumVisibleWindows; ++i )
-  {
-    pWindow = &pWindowList[pVisibleWindowsIdxs[i] - 1];
-    switch (pWindow->eWindowType)
-    {
-      case WINDOW_OptionsButtons:
-      {
-        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 ( pCurrentScreen == SCREEN_CHEST )
-        {
-          Chest::DrawChestUI(pWindow->par1C);
-        }
-        else if ( pCurrentScreen == 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->DrawTextureTransparent(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uTextureID_x_x_u));
-        continue;
-      }
-      case WINDOW_ModalWindow:
-      {
-        ModalWindow_ShowHint();
-        continue;
-      }
-      case WINDOW_50:
-      {
-        v27 = Color16(255, 255, 255);
-        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_IN_PROGRESS)
-        {
-          ptr_507BD0->DrawMessageBox(0);
-          ptr_507BD0->DrawText(pFontCreate, 30, 40, v27, pKeyActionMap->pPressedKeysBuffer, 0, 0, 0);
-          v31 = pFontCreate->GetLineWidth(pKeyActionMap->pPressedKeysBuffer);
-          ptr_507BD0->DrawFlashingInputCursor(v31 + 30, 40, pFontCreate);
-          continue;
-        }
-        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CONFIRMED)
-        {
-          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-          pMessageQueue_50CBD0->AddGUIMessage((UIMessageType)(int)ptr_507BD0->ptr_1C, 0, 0);
-          pEventTimer->Resume();
-          ptr_507BD0->Release();
-          pCurrentScreen = SCREEN_GAME;
-          viewparams->bRedrawGameUI = true;
-          continue;
-        }
-        if ( ptr_507BD0->receives_keyboard_input_2 == WINDOW_INPUT_CANCELLED)
-        {
-          pWindow->receives_keyboard_input_2 = WINDOW_INPUT_NONE;
-          pEventTimer->Resume();
-          ptr_507BD0->Release();
-          continue;
-        }
-      }
-      case WINDOW_59:
-      {
-        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();
-          pCurrentScreen = 0;
-          viewparams->bRedrawGameUI = true;
-          v26 = atoi(pKeyActionMap->pPressedKeysBuffer);
-          if ( v26 > 0 )
-          {
-            if ( v26 < 800 )
-            {
-              ItemGen2.uAttributes |= 1;
-              ItemGen2.uItemID = v26;
-              if ( pItemsTable->pItems[v26].uEquipType == 12 )
-              {
-                ItemGen2.uNumCharges = rand() % 6 + ItemGen2.GetDamageMod() + 1;
-                ItemGen2.uMaxCharges = LOBYTE(ItemGen2.uNumCharges);
-              }
-              else
-              {
-                if ( v26 >= 221 && v26 < 271 )
-                  ItemGen2.uEnchantmentType = rand() % 10 + 1;
-              }
-              pItemsTable->SetSpecialBonus(&ItemGen2);
-              pParty->SetHoldingItem(&ItemGen2);
-            }
-          }
-        }
-        continue;
-      }
-      case WINDOW_PressedButton2:
-      {
-        if ( pWindow->Hint != (char *)1 )
-          pAudioPlayer->PlaySound((SoundID)75, 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((SoundID)75, 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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(pWindow->uFrameX, pWindow->uFrameY, pButton->pTextures[1]);
-        viewparams->bRedrawGameUI = 1;
-        pWindow->Release();
-        continue;
-      }
-      case WINDOW_SaveLoadBtn:
-      {
-        if (pWindow->Hint != (char *)1)
-          pAudioPlayer->PlaySound(SOUND_Button2, 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 (pCurrentScreen == 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((SoundID)75, 0, 0, -1, 0, 0, 0, 0);
-        pButton = (GUIButton *)pWindow->ptr_1C;
-        pRenderer->DrawTextureTransparent(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_Button2, 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_Button2, 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_Button2, 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();
-          pCurrentScreen = 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;
-      }
-      default:
-        continue;
-    }
-  }
-  if ( GetCurrentMenuID() == -1 )
-    GameUI_DrawFoodAndGold();
-  if ( sub_4637E0_is_there_popup_onscreen() )
-    UI_OnMouseRightClick(0);
-}
-//void LoadFonts_and_DrawCopyrightWindow()
-//{
-  //MainMenuUI_LoadFontsAndSomeStuff();
- // DrawCopyrightWindow();
-//}
-//----- (00415485) --------------------------------------------------------
-void DrawMM7CopyrightWindow()
-{
-  GUIWindow Dst; // [sp+8h] [bp-54h]@1
-
-  memset(&Dst, 0, sizeof(Dst));
-  Dst.uFrameWidth = 624;
-  Dst.uFrameHeight = 256;
-  Dst.uFrameX = 8;
-  Dst.uFrameY = 30;                             // c 1999 The 3DO Company.
-  Dst.uFrameHeight = pFontSmallnum->CalcTextHeight(pGlobalTXT_LocalizationStrings[157], &Dst, 24, 0)
-                   + 2 * LOBYTE(pFontSmallnum->uFontHeight)
-                   + 24;
-  Dst.uFrameY = 470 - Dst.uFrameHeight;
-  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
-  Dst.uFrameW = 469;
-  //Dst.Hint = "abcagfdsgsg ljsrengvlkjesnfkjwnef";
-  Dst.DrawMessageBox(0);
-
-  Dst.uFrameWidth -= 24;
-  Dst.uFrameX += 12;
-  Dst.uFrameY += 12;
-  Dst.uFrameHeight -= 12;
-  Dst.uFrameZ = Dst.uFrameX + Dst.uFrameWidth - 1;
-  Dst.uFrameW = Dst.uFrameY + Dst.uFrameHeight - 1;
-  Dst.DrawTitleText(pFontSmallnum, 0, 0xCu, ui_mainmenu_copyright_color, pGlobalTXT_LocalizationStrings[157], 3);
-}
-
-int modal_window_prev_screen;
-
-//----- (004141CA) --------------------------------------------------------
-void ModalWindow(const char *pStrHint, UIMessageType OnRelease_message)
-{
-  pEventTimer->Pause();
-  modal_window_prev_screen = pCurrentScreen;
-  pModalWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_ModalWindow, OnRelease_message, pStrHint);
-  pCurrentScreen = SCREEN_MODAL_WINDOW;
-}
-
-//----- (0041420D) --------------------------------------------------------
-void  ModalWindow_ShowHint()
-{
-  GUIWindow pWindow; // [sp+4h] [bp-54h]@1
-
-  sprintf(pTmpBuf2.data(), "%s\n \n%s", pModalWindow->Hint, pGlobalTXT_LocalizationStrings[61]);// Press Escape
-  pWindow.Hint = pTmpBuf2.data();
-  pWindow.uFrameWidth = 400;
-  pWindow.uFrameHeight = 100;
-  pWindow.uFrameX = 120;
-  pWindow.uFrameY = 140;
-  pWindow.uFrameZ = 519;
-  pWindow.uFrameW = 239;
-  pWindow.DrawMessageBox(0);
-}
-
-//----- (0041426F) --------------------------------------------------------
-void ModalWindow_Release()
-{
-  pMessageQueue_50CBD0->AddGUIMessage((UIMessageType)pModalWindow->par1C, 0, 0);
-
-  pModalWindow->Release();
-  pModalWindow = nullptr;
-
-  pCurrentScreen = modal_window_prev_screen;
-  pEventTimer->Resume();
-}
-
-//----- (00467FB6) --------------------------------------------------------
-void CreateScrollWindow()
-{
-  unsigned int v0; // eax@1
-  char *v1; // ST18_4@3
-  GUIWindow a1; // [sp+Ch] [bp-54h]@1
-
-  memcpy(&a1, pGUIWindow_ScrollWindow, sizeof(a1));
-  a1.Hint = 0;
-  a1.uFrameX = 1;
-  a1.uFrameY = 1;
-  a1.uFrameWidth = 468;
-  v0 = pFontSmallnum->CalcTextHeight(pScrolls[pGUIWindow_ScrollWindow->par1C], &a1, 0, 0)
-     + 2 * LOBYTE(pFontCreate->uFontHeight) + 24;
-  a1.uFrameHeight = v0;
-  if ( (signed int)(v0 + a1.uFrameY) > 479 )
-  {
-    v0 = 479 - a1.uFrameY;
-    a1.uFrameHeight = 479 - a1.uFrameY;
-  }
-  a1.uFrameZ = a1.uFrameWidth + a1.uFrameX - 1;
-  a1.uFrameW = v0 + a1.uFrameY - 1;
-  a1.DrawMessageBox(0);
-  a1.uFrameX += 12;
-  a1.uFrameWidth -= 24;
-  a1.uFrameY += 12;
-  a1.uFrameHeight -= 12;
-  a1.uFrameZ = a1.uFrameWidth + a1.uFrameX - 1;
-  a1.uFrameW = a1.uFrameHeight + a1.uFrameY - 1;
-  v1 = pItemsTable->pItems[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C + 700].pName;
-  sprintf(pTmpBuf.data(), format_4E2D80, Color16(0xFFu, 0xFFu, 0x9Bu), v1);
-  a1.DrawTitleText(pFontCreate, 0, 0, 0, pTmpBuf.data(), 3);
-  a1.DrawText(pFontSmallnum, 1, LOBYTE(pFontCreate->uFontHeight) - 3, 0,
-              pScrolls[(unsigned int)pGUIWindow_ScrollWindow->ptr_1C], 0, 0, 0);
-}
-//----- (00467F48) --------------------------------------------------------
-void CreateMsgScrollWindow( signed int mscroll_id )
-{
-  if ( !pGUIWindow_ScrollWindow && mscroll_id >= 700 )
-  {
-    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);
-    }
-  }
-}
-//----- (00467F9F) --------------------------------------------------------
-void  free_book_subwindow()
-{
-  if ( pGUIWindow_ScrollWindow )
-  {
-    pGUIWindow_ScrollWindow->Release();
-    pGUIWindow_ScrollWindow = 0;
-  }
-}
-//----- (004226EF) --------------------------------------------------------
-void SetUserInterface(PartyAlignment align, bool bReplace)
-{
-  extern void set_default_ui_skin();
-  set_default_ui_skin();
-
-  if (align == PartyAlignment_Evil)
-  {
-    if ( bReplace )
-    {
-      pTexture_RightFrame->Reload("ib-r-C.pcx");
-      pTexture_BottomFrame->Reload("ib-b-C.pcx");
-      pTexture_TopFrame->Reload("ib-t-C.pcx");
-      pTexture_LeftFrame->Reload("ib-l-C.pcx");
-      pTexture_StatusBar->Reload("IB-Foot-c.pcx");
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-C", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-c", 2);
-
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-c", 2);
-
-      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeC");
-      pIconsFrameTable->InitializeAnimation(pUIAnim_WizardEye->uIconID);
-      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchC");
-      pIconsFrameTable->InitializeAnimation(pUIAnum_Torchlight->uIconID);
-
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt-c", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top-c", 2);
-      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap-c", 2);
-    }
-    else
-    {
-      pTexture_RightFrame->Load("ib-r-C.pcx", 0);
-      pTexture_BottomFrame->Load("ib-b-c.pcx", 0);
-      pTexture_TopFrame->Load("ib-t-C.pcx", 0);
-      pTexture_LeftFrame->Load("ib-l-C.pcx", 0);
-      pTexture_StatusBar->Load("IB-Foot-c.pcx", 0);
-      uTextureID_right_panel = pIcons_LOD->LoadTexture("ib-mb-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_Minimap_Loop = pIcons_LOD->LoadTexture("ib-autmask-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_Compas = pIcons_LOD->LoadTexture("IB-COMP-C", TEXTURE_16BIT_PALETTE);
-      dword_5079D0 = pIcons_LOD->LoadTexture("IB-InitG-c", TEXTURE_16BIT_PALETTE);
-      dword_5079C8 = pIcons_LOD->LoadTexture("IB-InitY-c", TEXTURE_16BIT_PALETTE);
-      dword_5079CC = pIcons_LOD->LoadTexture("IB-InitR-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_NPCLeft = pIcons_LOD->LoadTexture("IB-NPCLD-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_NPCRight = pIcons_LOD->LoadTexture("IB-NPCRD-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_ZoomIn = pIcons_LOD->LoadTexture("ib-autout-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_ZoomOut = pIcons_LOD->LoadTexture("ib-autin-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_GameUI_CharSelectionFrame = pIcons_LOD->LoadTexture("IB-selec-C", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_CastSpell = pIcons_LOD->LoadTexture("ib-m1d-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_Rest = pIcons_LOD->LoadTexture("ib-m2d-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_QuickReference = pIcons_LOD->LoadTexture("ib-m3d-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_GameSettings = pIcons_LOD->LoadTexture("ib-m4d-c", TEXTURE_16BIT_PALETTE);
-      uExitCancelTextureId = pIcons_LOD->LoadTexture("ib-bcu-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Bless = pIcons_LOD->LoadTexture("isg-01-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Preservation = pIcons_LOD->LoadTexture("isg-02-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Hammerhands = pIcons_LOD->LoadTexture("isg-03-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_PainReflection = pIcons_LOD->LoadTexture("isg-04-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_50795C = pIcons_LOD->LoadTexture("evtnpc-c", TEXTURE_16BIT_PALETTE);
-      uTextureID_CharacterUI_InventoryBackground = pIcons_LOD->LoadTexture("fr_inven", TEXTURE_16BIT_PALETTE);
-      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeC");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
-      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchC");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
-    }
-    uGameUIFontMain = Color16(0xC8u, 0, 0);
-    uGameUIFontShadow = Color16(10, 0, 0);
-  }
-  else if (align == PartyAlignment_Neutral)
-  {
-    if ( bReplace )
-    {
-      pTexture_RightFrame->Reload("ib-r-a.pcx");
-      pTexture_BottomFrame->Reload("ib-b-a.pcx");
-      pTexture_TopFrame->Reload("ib-t-a.pcx");
-      pTexture_LeftFrame->Reload("ib-l-a.pcx");
-      pTexture_StatusBar->Reload("IB-Foot-a.pcx");
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-a", 2);
-      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeA");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
-      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchA");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-a", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top", 2);
-      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap", 2);
-    }
-    else
-    {
-      pTexture_RightFrame->Load("ib-r-A.pcx", 0);
-      pTexture_BottomFrame->Load("ib-b-A.pcx", 0);
-      pTexture_TopFrame->Load("ib-t-A.pcx", 0);
-      pTexture_LeftFrame->Load("ib-l-A.pcx", 0);
-      pTexture_StatusBar->Load("IB-Foot-a.pcx", 0);
-      uTextureID_right_panel = pIcons_LOD->LoadTexture("ib-mb-A", TEXTURE_16BIT_PALETTE);
-      uTextureID_Minimap_Loop = pIcons_LOD->LoadTexture("ib-autmask-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Compas = pIcons_LOD->LoadTexture("IB-COMP-A", TEXTURE_16BIT_PALETTE);
-      dword_5079D0 = pIcons_LOD->LoadTexture("IB-InitG-a", TEXTURE_16BIT_PALETTE);
-      dword_5079C8 = pIcons_LOD->LoadTexture("IB-InitY-a", TEXTURE_16BIT_PALETTE);
-      dword_5079CC = pIcons_LOD->LoadTexture("IB-InitR-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_NPCLeft = pIcons_LOD->LoadTexture("IB-NPCLD-A", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_NPCRight = pIcons_LOD->LoadTexture("IB-NPCRD-A", TEXTURE_16BIT_PALETTE);
-      uTextureID_GameUI_CharSelectionFrame = pIcons_LOD->LoadTexture("IB-selec-A", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_CastSpell = pIcons_LOD->LoadTexture("ib-m1d-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_Rest = pIcons_LOD->LoadTexture("ib-m2d-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_QuickReference = pIcons_LOD->LoadTexture("ib-m3d-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_GameSettings = pIcons_LOD->LoadTexture("ib-m4d-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_ZoomIn = pIcons_LOD->LoadTexture("ib-autout-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_Btn_ZoomOut = pIcons_LOD->LoadTexture("ib-autin-a", TEXTURE_16BIT_PALETTE);
-      uExitCancelTextureId = pIcons_LOD->LoadTexture("ib-bcu-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Bless = pIcons_LOD->LoadTexture("isg-01-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Preservation = pIcons_LOD->LoadTexture("isg-02-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_Hammerhands = pIcons_LOD->LoadTexture("isg-03-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_PlayerBuff_PainReflection = pIcons_LOD->LoadTexture("isg-04-a", TEXTURE_16BIT_PALETTE);
-      uTextureID_50795C = pIcons_LOD->LoadTexture("evtnpc", TEXTURE_16BIT_PALETTE);
-      uTextureID_CharacterUI_InventoryBackground = pIcons_LOD->LoadTexture("fr_inven", TEXTURE_16BIT_PALETTE);
-      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeA");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
-      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchA");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
-      uTextureID_Parchment = pIcons_LOD->LoadTexture("parchment", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076B4 = pIcons_LOD->LoadTexture("cornr_ll", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076B0 = pIcons_LOD->LoadTexture("cornr_lr", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076AC = pIcons_LOD->LoadTexture("cornr_ul", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076A8 = pIcons_LOD->LoadTexture("cornr_ur", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076A4 = pIcons_LOD->LoadTexture("edge_btm", TEXTURE_16BIT_PALETTE);
-      uTextureID_5076A0 = pIcons_LOD->LoadTexture("edge_lf", TEXTURE_16BIT_PALETTE);
-      uTextureID_50769C = pIcons_LOD->LoadTexture("edge_rt", TEXTURE_16BIT_PALETTE);
-      uTextureID_507698 = pIcons_LOD->LoadTexture("edge_top", TEXTURE_16BIT_PALETTE);
-      pTexture_591428 = pIcons_LOD->LoadTexturePtr("endcap", TEXTURE_16BIT_PALETTE);
-    }
-    uGameUIFontMain = Color16(0xAu, 0, 0);
-    uGameUIFontShadow = Color16(230, 214, 193);
-  }
-  else if (align == PartyAlignment_Good)
-  {
-    if ( bReplace )
-    {
-      pTexture_RightFrame->Reload("ib-r-B.pcx");
-      pTexture_BottomFrame->Reload("ib-b-B.pcx");
-      pTexture_TopFrame->Reload("ib-t-B.pcx");
-      pTexture_LeftFrame->Reload("ib-l-B.pcx");
-      pTexture_StatusBar->Reload("IB-Foot-b.pcx");
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_right_panel], "ib-mb-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Minimap_Loop], "ib-autmask-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Compas], "IB-COMP-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079D0], "IB-InitG-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079C8], "IB-InitY-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[dword_5079CC], "IB-InitR-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCLeft], "IB-NPCLD-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_NPCRight], "IB-NPCRD-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomIn], "ib-autout-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_ZoomOut], "ib-autin-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_GameUI_CharSelectionFrame], "IB-selec-B", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_CastSpell], "ib-m1d-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_Rest], "ib-m2d-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_QuickReference], "ib-m3d-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Btn_GameSettings], "ib-m4d-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Bless], "isg-01-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Preservation], "isg-02-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_Hammerhands], "isg-03-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_PlayerBuff_PainReflection], "isg-04-b", 2);
-      pUIAnim_WizardEye->uIconID = pIconsFrameTable->FindIcon("wizeyeB");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnim_WizardEye->uIconID);
-      pUIAnum_Torchlight->uIconID = pIconsFrameTable->FindIcon("torchB");
-      pIconsFrameTable->InitializeAnimation((signed __int16)pUIAnum_Torchlight->uIconID);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uExitCancelTextureId], "ib-bcu-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50795C], "evtnpc-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_CharacterUI_InventoryBackground], "fr_inven-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_Parchment], "parchment", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B4], "cornr_ll-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076B0], "cornr_lr-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076AC], "cornr_ul-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A8], "cornr_ur-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A4], "edge_btm-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_5076A0], "edge_lf-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_50769C], "edge_rt-b", 2);
-      pIcons_LOD->ReloadTexture(&pIcons_LOD->pTextures[uTextureID_507698], "edge_top-b", 2);
-      pIcons_LOD->ReloadTexture(pTexture_591428, "endcap-b", 2);
-    }
-    uGameUIFontMain = Color16(0, 0, 0xC8u);
-    uGameUIFontShadow = Color16(255, 255, 255);
-  }
-  else Error("Invalid alignment type: %u", align);
-}
-//----- (0041D20D) --------------------------------------------------------
-void DrawBuff_remaining_time_string( int uY, struct GUIWindow *window, __int64 remaining_time, struct GUIFont *Font )
-{
-  unsigned int full_time; // esi@1
-  signed __int64 hours; // kr00_8@1
-  const char *text; // eax@2
-  signed __int64 minutes; // [sp+10h] [bp-10h]@1
-  signed __int64 seconds; // [sp+18h] [bp-8h]@1
-  unsigned int day; // [sp+24h] [bp+4h]@1
-
-  full_time = (signed __int64)((double)remaining_time * 0.234375);
-  day = (unsigned int)((full_time / 60) / 60) / 24;
-  hours = ((full_time / 60) / 60) % 24;
-  minutes = (signed __int64)(full_time / 60) % 60;
-  seconds = (signed __int64)full_time % 60;
-  strcpy(pTmpBuf.data(), "\r020");
-  if ( day )
-  {
-    text = pGlobalTXT_LocalizationStrings[57];   // Days
-    if ( day <= 1 )
-      text = pGlobalTXT_LocalizationStrings[56]; // Day
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)day, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( hours )
-  {
-    if ( hours <= 1 )
-      text = pGlobalTXT_LocalizationStrings[109];// Hour
-    else
-      text = pGlobalTXT_LocalizationStrings[110];// Hours
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)hours, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( minutes && !day )
-  {
-    if ( minutes <= 1 )
-      text = pGlobalTXT_LocalizationStrings[437];// Minute
-    else
-      text = pGlobalTXT_LocalizationStrings[436];// Minutes
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)minutes, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  if ( seconds && !hours )
-  {
-    if ( seconds <= 1 )
-      text = pGlobalTXT_LocalizationStrings[439];// Second
-    else
-      text = pGlobalTXT_LocalizationStrings[438];// Seconds
-    sprintfex(pTmpBuf2.data(), "%d %s ", (int)seconds, text);
-    strcat(pTmpBuf.data(), pTmpBuf2.data());
-  }
-  window->DrawText(Font, 32, uY, 0, pTmpBuf.data(), 0, 0, 0);
-}
-
-
-//----- (0042EB8D) --------------------------------------------------------
-void GUIMessageQueue::AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file, int line)
-{
-  //Log::Warning(L"%s @ (%S %u)", UIMessage2String(msg), file, line);
-  if (uNumMessages < 40)
-  {
-    files[uNumMessages] = file;
-    lines[uNumMessages] = line;
-
-    pMessages[uNumMessages].eType = msg;
-    pMessages[uNumMessages].param = param;
-    pMessages[uNumMessages++].field_8 = a4;
-  }
-}
-
-//----- (004637E0) --------------------------------------------------------
-char  sub_4637E0_is_there_popup_onscreen()
-{
-  return dword_507BF0_is_there_popup_onscreen == 1;
-}
-// 507BF0: using guessed type int dword_507BF0_is_there_popup_onscreen;
-
-//----- (00417AD4) --------------------------------------------------------
-unsigned int GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level)
-{
-	switch (uPlayerClass % 4)
-	{
-	case 0:
-	{
-			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] >= skill_level)
-				  return ui_character_skillinfo_can_learn;
-			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 1][uPlayerSkillType] < skill_level &&
-				  byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 2][uPlayerSkillType] < skill_level)
-			  {
-				  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 3][uPlayerSkillType] < skill_level)
-					  return ui_character_skillinfo_cant_learn;
-			  }
-			  return ui_character_skillinfo_can_learn_gm;
-	}
-		break;
-
-	case 1:
-	{
-			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] >= skill_level)
-				  return ui_character_skillinfo_can_learn;
-			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 1][uPlayerSkillType] < skill_level)
-			  {
-				  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass + 2][uPlayerSkillType] < skill_level)
-					  return ui_character_skillinfo_cant_learn;
-			  }
-			  return ui_character_skillinfo_can_learn_gm;
-	}
-		break;
-
-	case 2:
-	case 3:
-	{
-			  if (byte_4ED970_skill_learn_ability_by_class_table[uPlayerClass][uPlayerSkillType] < skill_level)
-				  return ui_character_skillinfo_cant_learn;
-			  return ui_character_skillinfo_can_learn;
-	}
-		break;
-	}
-	Error("Invalid player class: %u", uPlayerClass);
-}
-
-//----- (0040F92A) --------------------------------------------------------
-void __fastcall ZBuffer_DoFill2(int *pZBuffer, Texture *a2, int a3)
-{//ñðàáàòûâàåò â ïîêóïêå â ìàãàçèíå
-	void *v4; // eax@3
-	//int *v5; // edi@5
-	//  int v6; // ecx@6
-	//  int v9; // [sp+18h] [bp-4h]@1
-
-	if (pIcons_LOD->dword_011BA4 && a2->uDecompressedSize)
-		v4 = a2->UnzipPalette();
-	else
-		v4 = a2->pLevelOfDetail0_prolly_alpha_mask;
-	//v5 = pZBuffer;
-	for (uint i = 0; i < a2->uTextureHeight; i++)
-	{
-		for (uint j = 0; j < a2->uTextureWidth; j++)
-		{
-			*pZBuffer = a3;
-			++pZBuffer;
-		}
-		pZBuffer += window->GetWidth() - a2->uTextureWidth;
-	}
-	if (pIcons_LOD->dword_011BA4)
-	{
-		if (a2->uDecompressedSize)
-			free(v4);
-	}
-}
-
-
-// 4E28F8: using guessed type int pCurrentScreen;
-
-//----- (0040F82D) --------------------------------------------------------
-void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue)
-{
-	assert(uTextureId != -1);
-	ZBuffer_DoFill(pZBuffer, pIcons_LOD->GetTexture(uTextureId), iZValue);
-}
-
-//----- (0040F89C) --------------------------------------------------------
-void __fastcall ZBuffer_DoFill(int *pZBuffer, Texture *pTex, int uZValue)
-{//ñðàáàòûâàåò ïðè ïðîäàæå â ìàãàçèíå
-	void *v3; // eax@3
-	//void *v4; // esi@5
-	//int *v5; // edi@5
-	//int v6; // eax@5
-	//  int v7; // ecx@6
-	//  int v11; // [sp+18h] [bp-8h]@1
-	//void *v12; // [sp+1Ch] [bp-4h]@5
-
-	if (pIcons_LOD->dword_011BA4 && pTex->uDecompressedSize)
-		v3 = pTex->UnzipPalette();
-	else
-		v3 = pTex->pLevelOfDetail0_prolly_alpha_mask;
-	//v12 = v3;
-	//v4 = v3;
-	//v5 = pZBuffer;
-	//v6 = 0;
-	for (uint i = 0; i < pTex->uTextureHeight; i++)
-	{
-		for (uint j = 0; j < pTex->uTextureWidth; j++)
-		{
-			//LOBYTE(v6) = *(char *)v4;
-			//v4 = (char *)v4 + 1;
-			//if ( v6 )
-			*pZBuffer = uZValue;
-			++pZBuffer;
-		}
-		pZBuffer += window->GetWidth() - pTex->uTextureWidth;
-	}
-	if (pIcons_LOD->dword_011BA4)
-	{
-		if (pTex->uDecompressedSize)
-			free(v3);
-	}
-}
-
-//----- (004BC49B) --------------------------------------------------------
-void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType)
-{
-	NPCData *speakingNPC; // ebp@1
-	int npc_event_id; // ecx@10
-	char *v13; // [sp-8h] [bp-18h]@60
-
-	speakingNPC = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-	uDialogueType = newDialogueType;
-	if (!speakingNPC->uFlags)
-		speakingNPC->uFlags = 1;
-	if (newDialogueType == DIALOGUE_PROFESSION_DETAILS)
-		dialogue_show_profession_details = ~dialogue_show_profession_details;
-	else if (newDialogueType == DIALOGUE_76)
-	{
-		if (speakingNPC->Hired())
-		{
-			if ((signed int)pNPCStats->uNumNewNPCs > 0)
-			{
-				for (uint i = 0; i < (unsigned int)pNPCStats->uNumNewNPCs; ++i)
-				{
-					if (pNPCStats->pNewNPCData[i].uFlags & 0x80 && !strcmp(speakingNPC->pName, pNPCStats->pNewNPCData[i].pName))
-						pNPCStats->pNewNPCData[i].uFlags &= 0x7Fu;
-				}
-			}
-			if (pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName))
-				memset(&pParty->pHirelings[0], 0, sizeof(NPCData));
-			else if (pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName))
-				memset(&pParty->pHirelings[1], 0, sizeof(NPCData));
-			pParty->hirelingScrollPosition = 0;
-			pParty->CountHirelings();
-			dword_591084 = 0;
-			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-			dword_7241C8 = 0;
-			return;
-		}
-		if (pParty->pHirelings[0].pName && pParty->pHirelings[1].pName)
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
-		else
-		{
-			if (speakingNPC->uProfession != 51) //burglars have no hiring price
-			{
-				if (pParty->uNumGold < pNPCStats->pProfessions[speakingNPC->uProfession].uHirePrice)
-				{
-					ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);// "You don't have enough gold"
-					dialogue_show_profession_details = false;
-					uDialogueType = 13;
-					if (uActiveCharacter)
-						pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
-					if (!dword_7241C8)
-						pGame->Draw();
-					dword_7241C8 = 0;
-					return;
-				}
-				Party::TakeGold(pNPCStats->pProfessions[speakingNPC->uProfession].uHirePrice);
-			}
-			LOBYTE(speakingNPC->uFlags) |= 0x80u;
-			if (pParty->pHirelings[0].pName)
-			{
-				memcpy(&pParty->pHirelings[1], speakingNPC, sizeof(pParty->pHirelings[1]));
-				v13 = pParty->pHireling2Name;
-			}
-			else
-			{
-				memcpy(&pParty->pHirelings[0], speakingNPC, sizeof(pParty->pHirelings[0]));
-				v13 = pParty->pHireling1Name;
-			}
-			strcpy(v13, speakingNPC->pName);
-			pParty->hirelingScrollPosition = 0;
-			pParty->CountHirelings();
-			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-			if (sDialogue_SpeakingActorNPC_ID >= 0)
-				pDialogue_SpeakingActor->uAIState = Removed;
-			if (uActiveCharacter)
-				pPlayers[uActiveCharacter]->PlaySound(SPEECH_61, 0);
-		}
-	}
-	else if ((signed int)newDialogueType > DIALOGUE_84 && (signed int)newDialogueType <= DIALOGUE_ARENA_SELECT_CHAMPION) //âûáîð óðîâíÿ ñëîæíîñòè áîÿ
-	{
-		ArenaFight();
-		return;
-	}
-	else if (newDialogueType == DIALOGUE_USE_NPC_ABILITY)
-	{
-		if (UseNPCSkill((NPCProf)speakingNPC->uProfession) == 0)
-		{
-			if (speakingNPC->uProfession != GateMaster)
-				speakingNPC->bHasUsedTheAbility = 1;
-			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-		}
-		else
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[140], 2); //"Your packs are already full!"
-	}
-	else if (newDialogueType == DIALOGUE_13)
-	{
-		if (!speakingNPC->Hired())
-		{
-			sub_4B3E1E();
-			dialogue_show_profession_details = false;
-		}
-		else
-		{
-			for (uint i = 0; i < (signed int)pNPCStats->uNumNewNPCs; ++i)
-			{
-				if (pNPCStats->pNewNPCData[i].uFlags & 0x80 && !strcmp(speakingNPC->pName, pNPCStats->pNewNPCData[i].pName))
-					pNPCStats->pNewNPCData[i].uFlags &= 0x7Fu;
-			}
-			if (pParty->pHirelings[0].pName && !_stricmp(pParty->pHirelings[0].pName, speakingNPC->pName))
-				memset(&pParty->pHirelings[0], 0, sizeof(NPCData));
-			else if (pParty->pHirelings[1].pName && !_stricmp(pParty->pHirelings[1].pName, speakingNPC->pName))
-				memset(&pParty->pHirelings[1], 0, sizeof(NPCData));
-			pParty->hirelingScrollPosition = 0;
-			pParty->CountHirelings();
-			dword_591084 = 0;
-			pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-			dword_7241C8 = 0;
-			return;
-		}
-	}
-	else if (newDialogueType >= DIALOGUE_EVT_A && newDialogueType <= DIALOGUE_EVT_F)
-	{
-		switch (newDialogueType)
-		{
-		case DIALOGUE_EVT_A:  npc_event_id = speakingNPC->evt_A; break;
-		case DIALOGUE_EVT_B:  npc_event_id = speakingNPC->evt_B; break;
-		case DIALOGUE_EVT_C:  npc_event_id = speakingNPC->evt_C; break;
-		case DIALOGUE_EVT_D:  npc_event_id = speakingNPC->evt_D; break;
-		case DIALOGUE_EVT_E:  npc_event_id = speakingNPC->evt_E; break;
-		case DIALOGUE_EVT_F:  npc_event_id = speakingNPC->evt_F; break;
-		}
-		if ((npc_event_id >= 200) && (npc_event_id <= 310))
-			_4B3FE5_training_dialogue(npc_event_id); //200-310
-		else if ((npc_event_id >= 400) && (npc_event_id <= 410))
-		{ //400-410
-			dword_F8B1D8 = newDialogueType;
-			DrawJoinGuildWindow(npc_event_id - 400);
-		}
-		else
-		{
-			switch (npc_event_id)
-			{
-			case 139:
-				OracleDialogue();
-				break;
-			case 311:
-				CheckBountyRespawnAndAward();
-				break;
-			case 399:
-				Arena_SelectionFightLevel();
-				break;
-			default:
-				activeLevelDecoration = (LevelDecoration*)1;
-				current_npc_text = 0;
-				EventProcessor(npc_event_id, 0, 1);
-				activeLevelDecoration = nullptr;
-				break;
-			}
-		}
-	}
-	if (!dword_7241C8)
-		pGame->Draw();
-	dword_7241C8 = 0;
-}
-
-//----- (004B3E1E) --------------------------------------------------------
-void  sub_4B3E1E()
-{
-	NPCData *v0; // ST40_4@1
-	signed int v1; // edi@1
-	//GUIWindow *v2; // ecx@1
-
-	__debugbreak();
-	v0 = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-	v1 = 0;
-	pDialogueWindow->eWindowType = WINDOW_MainMenu;
-	pDialogueWindow->Release();
-	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), window->GetHeight(), WINDOW_Dialogue, 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);//Ïîäðîáíåå
-		v1 = 1;
-	}
-	pDialogueWindow->CreateButton(480, 30 * v1 + 160, 140, 30, 1, 0, UIMSG_SelectNPCDialogueOption, 76, 0, pGlobalTXT_LocalizationStrings[406], 0);//Íàíÿòü
-	pDialogueWindow->_41D08F_set_keyboard_control_group(v1 + 1, 1, 0, 1);
-}
-
-//----- (004B2001) --------------------------------------------------------
-void __fastcall ClickNPCTopic(signed int uMessageParam)
-{
-	//signed int v1; // eax@1
-	NPCData *pCurrentNPCInfo; // ebp@1
-	int pEventNumber; // ecx@8
-	Player *v4; // esi@20
-	//int v5; // eax@28
-	//int v6; // eax@31
-	//int v7; // eax@34
-	//int v8; // eax@37
-	//int v9; // eax@40
-	//unsigned int v10; // eax@43
-	char *v12; // eax@53
-	char *v13; // eax@56
-	char *v14; // eax@57
-	char *v15; // eax@58
-	//unsigned int v16; // ebp@62
-	char *v17; // ecx@63
-	char *v18; // eax@65
-	//  const char *v19; // ecx@68
-	//unsigned int v20; // eax@69
-	signed int pPrice; // ecx@70
-	char *v22; // [sp-Ch] [bp-18h]@73
-	//int v23; // [sp-8h] [bp-14h]@49
-	char *v24; // [sp-8h] [bp-14h]@73
-	//int v25; // [sp-4h] [bp-10h]@49
-
-	uDialogueType = uMessageParam + 1;
-	pCurrentNPCInfo = HouseNPCData[pDialogueNPCCount - ((dword_591080 != 0) ? 1 : 0)];//- 1
-	if (uMessageParam <= 24)
-	{
-		switch (uMessageParam)
-		{
-		case 13:
-			current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;//(char *)*(&pNPCStats->field_13A64 + 5 * v2->uProfession);
-			current_npc_text = BuildDialogueString(current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
-			NPCHireableDialogPrepare();
-			dialogue_show_profession_details = false;
-			BackToHouseMenu();
-			return;		
-		case 19:
-			pEventNumber = pCurrentNPCInfo->evt_A;
-			break;
-		case 20:
-			pEventNumber = pCurrentNPCInfo->evt_B;
-			break;
-		case 21:
-			pEventNumber = pCurrentNPCInfo->evt_C;
-			break;
-		case 22:
-			pEventNumber = pCurrentNPCInfo->evt_D;
-			break;
-		case 23:
-			pEventNumber = pCurrentNPCInfo->evt_E;
-			break;
-		case 24:
-			pEventNumber = pCurrentNPCInfo->evt_F;
-			break;
-		default:
-			BackToHouseMenu();
-			return;
-		}
-		/*switch ( pEventNumber )
-		{
-		case 139:
-		OracleDialogue();
-		goto _return;
-		case 311:
-		CheckBountyRespawnAndAward();
-		goto _return;
-		}*/
-		if (pEventNumber < 200 || pEventNumber > 310)
-		{
-			if (pEventNumber < 400 || pEventNumber > 410)
-			{
-				if (pEventNumber == 139)
-				{
-					OracleDialogue();
-				}
-				else
-				{
-					if (pEventNumber == 311)
-					{
-						CheckBountyRespawnAndAward();
-					}
-					else
-					{
-						current_npc_text = 0;
-						activeLevelDecoration = (LevelDecoration*)1;
-						EventProcessor(pEventNumber, 0, 1);
-						activeLevelDecoration = nullptr;
-					}
-				}
-			}
-			else
-			{
-				dword_F8B1D8 = uMessageParam;
-				DrawJoinGuildWindow(pEventNumber - 400);
-			}
-		}
-		else
-		{
-			_4B3FE5_training_dialogue(pEventNumber);
-		}
-		BackToHouseMenu();
-		return;
-	}
-	if (uMessageParam != 76)
-	{
-		if (uMessageParam == 77)
-		{
-			//v16 = pCurrentNPCInfo->uProfession;
-			__debugbreak();  // probably hirelings found in buildings, not present in MM7, changed "pCurrentNPCInfo->uProfession - 1" to "pCurrentNPCInfo->uProfession", have to check in other versions whether it's ok
-			if (dialogue_show_profession_details)
-				v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;
-			else
-				v17 = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pBenefits;
-			current_npc_text = v17;
-			v18 = BuildDialogueString(v17, uActiveCharacter - 1, 0, 0, 0, 0);
-			dialogue_show_profession_details = ~dialogue_show_profession_details;
-			current_npc_text = v18;
-		}
-		else
-		{
-			if (uMessageParam == 79)
-			{
-				if (contract_approved)
-				{
-					Party::TakeGold(gold_transaction_amount);
-					if (uActiveCharacter)
-					{
-						v12 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-						*(short *)v12 &= 0x3Fu;
-						switch (dword_F8B1B0_MasteryBeingTaught)
-						{
-						case 2:
-							v15 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-							*v15 |= 0x40u;
-							break;
-						case 3:
-							v14 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-							*v14 |= 0x80u;
-							break;
-						case 4:
-							v13 = (char *)&pPlayers[uActiveCharacter]->pActiveSkills[dword_F8B1AC_award_bit_number];
-							v13[1] |= 1u;
-							break;
-						}
-						pPlayers[uActiveCharacter]->PlaySound(SPEECH_85, 0);
-					}
-					pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-					/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-					{
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
-					*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-					++pMessageQueue_50CBD0->uNumMessages;
-					}*/
-				}
-			}
-			else
-			{
-				if (uMessageParam == 82 && contract_approved) //join guild
-				{
-					Party::TakeGold(gold_transaction_amount);
-					v4 = pParty->pPlayers.data();
-					do
-					{
-						v4->SetVariable(VAR_Award, dword_F8B1AC_award_bit_number);
-						++v4;
-					} while ((signed int)v4 < (signed int)pParty->pHirelings.data());
-					switch (dword_F8B1D8)
-					{
-					case 19:
-						pEventNumber = pCurrentNPCInfo->evt_A;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_A = 0;
-						break;
-					case 20:
-						pEventNumber = pCurrentNPCInfo->evt_B;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_B = 0;
-						break;
-					case 21:
-						pEventNumber = pCurrentNPCInfo->evt_C;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_C = 0;
-						break;
-					case 22:
-						pEventNumber = pCurrentNPCInfo->evt_D;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_D = 0;
-						break;
-					case 23:
-						pEventNumber = pCurrentNPCInfo->evt_E;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_E = 0;
-						break;
-					case 24:
-						pEventNumber = pCurrentNPCInfo->evt_F;
-						if (pEventNumber >= 400 && pEventNumber <= 416)
-							pCurrentNPCInfo->evt_F = 0;
-						break;
-					}
-					pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-					/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-					{
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-					pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
-					*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-					++pMessageQueue_50CBD0->uNumMessages;
-					}*/
-					//v11 = uActiveCharacter;
-					if (uActiveCharacter)
-					{
-						pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)SPEECH_86, 0);
-						BackToHouseMenu();
-						return;
-					}
-				}
-			}
-		}
-		BackToHouseMenu();
-		return;
-	}
-	if (pParty->pHirelings[0].pName && pParty->pHirelings[1].pName)
-	{
-		ShowStatusBarString(pGlobalTXT_LocalizationStrings[533], 2);// ""I cannot join you, you're party is full""
-		BackToHouseMenu();
-		return;
-	}
-	
-	
-	if (pCurrentNPCInfo->uProfession != 51) //burglars have no hiring price
-	{
-		__debugbreak();  // probably hirelings found in buildings, not present in MM7, changed "pCurrentNPCInfo->uProfession - 1" to "pCurrentNPCInfo->uProfession", have to check in other versions whether it's ok
-		pPrice = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].uHirePrice;
-		if (pParty->uNumGold < (unsigned int)pPrice)
-		{
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
-			dialogue_show_profession_details = false;
-			uDialogueType = 13;
-			current_npc_text = pNPCStats->pProfessions[pCurrentNPCInfo->uProfession].pJoinText;
-			current_npc_text = BuildDialogueString(current_npc_text, uActiveCharacter - 1, 0, 0, 0, 0);
-			if (uActiveCharacter)
-				pPlayers[uActiveCharacter]->PlaySound(SPEECH_NotEnoughGold, 0);
-			ShowStatusBarString(pGlobalTXT_LocalizationStrings[155], 2);
-			BackToHouseMenu();
-			return;
-		}
-		else
-			Party::TakeGold(pPrice);
-	}
-	//LOBYTE(v2->uFlags) |= 0x80u;
-	pCurrentNPCInfo->uFlags |= 128;
-	pParty->hirelingScrollPosition = 0;
-	pParty->CountHirelings();
-	if (pParty->pHirelings[0].pName)
-	{
-		memcpy(&pParty->pHirelings[1], pCurrentNPCInfo, sizeof(pParty->pHirelings[1]));
-		v24 = pCurrentNPCInfo->pName;
-		v22 = pParty->pHireling2Name;
-	}
-	else
-	{
-		memcpy(pParty->pHirelings.data(), pCurrentNPCInfo, 0x4Cu);
-		v24 = pCurrentNPCInfo->pName;
-		v22 = pParty->pHireling1Name;
-	}
-	strcpy(v22, v24);
-	pParty->hirelingScrollPosition = 0;
-	pParty->CountHirelings();
-	PrepareHouse((HOUSE_ID)(int)window_SpeakInHouse->ptr_1C);
-	dialog_menu_id = HOUSE_DIALOGUE_MAIN;
-
-	pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 1, 0);
-	/*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-	{
-	pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-	pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 1;
-	*(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-	++pMessageQueue_50CBD0->uNumMessages;
-	}*/
-	if (uActiveCharacter)
-		pPlayers[uActiveCharacter]->PlaySound((PlayerSpeech)61, 0);
-
-_return:
-	BackToHouseMenu();
-}
-
-//----- (004B3FE5) --------------------------------------------------------
-//Originally called _4B254D_SkillMasteryTeacher to have contract_approved assigned, to be able to set some button name. 
-//But it the name gets immediately overwritten
-void _4B3FE5_training_dialogue(int a4)
-{
-	const char *v2; // edi@1
-
-	//__debugbreak();
-	uDialogueType = DIALOGUE_SKILL_TRAINER;
-	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);
-	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);
-	v2 = "";
-	if (contract_approved)
-		v2 = pGlobalTXT_LocalizationStrings[535];
-	pDialogueWindow->CreateButton(480, 160, 0x8Cu, 0x1Eu, 1, 0, UIMSG_ClickNPCTopic, 0x4Fu, 0, v2, 0);
-	pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
-	dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-}
-// F8B19C: using guessed type int dword_F8B19C;
-// F8B1A8: using guessed type int dword_F8B1A8;
-//----- (004B1ECE) --------------------------------------------------------
-void OracleDialogue()
-{
-	__int16 *v0; // edi@1
-	signed int v4; // eax@9
-	int v5; // ebx@11
-	signed int v8; // edi@14
-	ItemGen *v9; // [sp+Ch] [bp-Ch]@11
-	signed int v10; // [sp+10h] [bp-8h]@13
-	int v11; // [sp+14h] [bp-4h]@1
-
-	contract_approved = 0;
-	v11 = 0;
-	uDialogueType = 84;
-	current_npc_text = (char *)pNPCTopics[667].pText;
-	v0 = _4F0882_evt_VAR_PlayerItemInHands_vals.data();
-	//while ( 1 )
-	for (uint i = 0; i <= 53; i++)
-	{
-		if ((unsigned __int16)_449B57_test_bit(pParty->_quest_bits, *v0))
-		{
-			//v1 = 0;
-			//v2 = pParty->pPlayers.data();
-			for (uint pl = 0; pl < 4; pl++)
-			{
-				//LOBYTE(v3) = pParty->pPlayers[pl].CompareVariable(VAR_PlayerItemInHands, *(v0+1));
-				if (pParty->pPlayers[pl].CompareVariable(VAR_PlayerItemInHands, *(v0 + 1)))
-					break;
-				//++v2;
-				//++v1;
-			}
-			//while ( (signed int)v2 < (signed int)pParty->pHirelings.data() );
-			//if ( v1 == 4 )
-			//break;
-		}
-		++v11;
-		//v0 += 2;
-		//if ( v0 > &_4F0882_evt_VAR_PlayerItemInHands_vals[53] )
-		//break;
-	}
-	if (v0 <= &_4F0882_evt_VAR_PlayerItemInHands_vals[53])
-	{
-		current_npc_text = (char *)pNPCTopics[666].pText; // Here's %s that you lost. Be careful
-		v4 = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
-		contract_approved = _4F0882_evt_VAR_PlayerItemInHands_vals[2 * v11];
-		pParty->pPlayers[0].AddVariable(VAR_PlayerItemInHands, v4);
-	}
-	if (contract_approved == 601)
-	{
-		v5 = 0;
-		//v12 = pParty->pPlayers.data();//[0].uClass;
-		v9 = 0;
-		//while ( 1 )
-		for (uint i = 0; i < 4; i++)
-		{
-			if (pParty->pPlayers[i].classType == PLAYER_CLASS_LICH)
-			{
-				v10 = 0;
-				//v6 = pParty->pPlayers.data();//[0].pInventoryItems[0].field_1A;
-				for (uint pl = 0; pl < 4; pl++)
-				{
-					for (v8 = 0; v8 < 126; v8++)//138
-					{
-						if (pParty->pPlayers[pl].pInventoryItemList[v8].uItemID == ITEM_LICH_JAR_FULL)
-						{
-							if (!pParty->pPlayers[pl].pInventoryItemList[v8].uHolderPlayer)
-								v9 = &pParty->pPlayers[pl].pInventoryItemList[v8];
-							if (pParty->pPlayers[pl].pInventoryItemList[v8].uHolderPlayer == v5)
-								v10 = 1;
-						}
-					}
-				}
-				if (!v10)
-					break;
-			}
-			//      ++v12;
-			++v5;
-			//  if ( v12 > &pParty->pPlayers[3] )
-			//  return;
-		}
-		if (v9)
-			v9->uHolderPlayer = v5;
-	}
-}
-
-//----- (004B46A5) --------------------------------------------------------
-void __fastcall DrawTextAtStatusBar(const char *Str, int a5)
-{
-	pRenderer->DrawTextureRGB(0, 352, pTexture_StatusBar);
-	pPrimaryWindow->DrawText(pFontLucida, pFontLucida->AlignText_Center(450, Str) + 11, 357, a5, Str, 0, 0, 0);
-}
-
-//----- (004BBA85) --------------------------------------------------------
-void CheckBountyRespawnAndAward()
-{
-	int i; // eax@2
-	int rand_monster_id; // edx@3
-
-	uDialogueType = 83;
-	pDialogueWindow->Release();
-	pDialogueWindow = GUIWindow::Create(0, 0, window->GetWidth(), 350, WINDOW_MainMenu, 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);
-	pDialogueWindow->CreateButton(480, 160, 140, 30, 1, 0, UIMSG_0, 83, 0, "", 0);
-	pDialogueWindow->_41D08F_set_keyboard_control_group(1, 1, 0, 2);
-	dialog_menu_id = HOUSE_DIALOGUE_OTHER;
-	//get new monster for hunting
-	if (pParty->PartyTimes.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] < (signed __int64)pParty->uTimePlayed)
-	{
-		pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
-		pParty->PartyTimes.bountyHunting_next_generation_time[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = (signed __int64)((double)(0x12750000 * (pParty->uCurrentMonth + 12i64 * pParty->uCurrentYear - 14015)) * 0.033333335);
-		for (i = rand();; i = rand())
-		{
-			rand_monster_id = i % 258 + 1;
-			pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = rand_monster_id;
-			if ((unsigned __int16)rand_monster_id < 0x73u || (unsigned __int16)rand_monster_id > 0x84u)
-			{
-				if (((unsigned __int16)rand_monster_id < 0xEBu || (unsigned __int16)rand_monster_id > 0xFCu)
-					&& ((unsigned __int16)rand_monster_id < 0x85u || (unsigned __int16)rand_monster_id > 0x96u)
-					&& ((unsigned __int16)rand_monster_id < 0x97u || (unsigned __int16)rand_monster_id > 0xBAu)
-					&& ((unsigned __int16)rand_monster_id < 0xC4u || (unsigned __int16)rand_monster_id > 0xC6u))
-					break;
-			}
-		}
-	}
-	bountyHunting_monster_id_for_hunting = pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)];
-	if (!pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
-	{
-		bountyHunting_text = pNPCTopics[351].pText;
-		if (!pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
-			bountyHunting_text = pNPCTopics[353].pText;
-	}
-	else//get prize
-	{
-		if (pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)])
-		{
-			pParty->PartyFindsGold(100 * pMonsterStats->pInfos[(unsigned __int16)pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel, 0);
-			for (uint i = 0; i < 4; ++i)
-				pParty->pPlayers[i].SetVariable(VAR_Award, 86);
-			pParty->uNumBountiesCollected += 100 * pMonsterStats->pInfos[pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)]].uLevel;
-			pParty->monster_id_for_hunting[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = 0;
-			pParty->monster_for_hunting_killed[(int)((char *)window_SpeakInHouse->ptr_1C - 102)] = false;
-		}
-		bountyHunting_text = pNPCTopics[352].pText;
-	}
-}
-
-//----- (004B254D) --------------------------------------------------------
-const char * _4B254D_SkillMasteryTeacher(int trainerInfo)
-{
-	int teacherLevel; // edx@1
-	int skillBeingTaught; // ecx@1
-	int pClassType; // eax@7
-	int currClassMaxMastery; // eax@7
-	int pointsInSkillWOutMastery; // ebx@7
-	int classBaseId; // eax@8
-	unsigned int skillMastery; // eax@29
-	unsigned __int16 pointsInSkill; // [sp+1Ch] [bp-10h]@7
-	int masteryLevelBeingTaught; // [sp+24h] [bp-8h]@7
-
-	contract_approved = 0;
-	teacherLevel = (trainerInfo - 200) % 3;
-	skillBeingTaught = (trainerInfo - 200) / 3;
-	Player* activePlayer = pPlayers[uActiveCharacter];
-	pClassType = activePlayer->classType;
-	currClassMaxMastery = byte_4ED970_skill_learn_ability_by_class_table[pClassType][skillBeingTaught];
-	masteryLevelBeingTaught = teacherLevel + 2;
-	dword_F8B1B0_MasteryBeingTaught = masteryLevelBeingTaught;
-	if (currClassMaxMastery < masteryLevelBeingTaught)
-	{
-		classBaseId = pClassType - pClassType % 4;
-		if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 1][skillBeingTaught] >= masteryLevelBeingTaught)
-			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 1]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
-		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught
-			&& byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught)
-			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[634], pClassNames[classBaseId + 2], pClassNames[classBaseId + 3]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s èëè %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s or %s to learn this skill level.
-		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 2][skillBeingTaught] >= masteryLevelBeingTaught)
-			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 2]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
-		else if (byte_4ED970_skill_learn_ability_by_class_table[classBaseId + 3][skillBeingTaught] >= masteryLevelBeingTaught)
-			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[633], pClassNames[classBaseId + 3]);//Âû äîëæíû äîñòè÷ü çâàíèÿ %s äëÿ îáó÷åíèÿ ýòîìó óðîâíþ íàâûêà. You have to be promoted to %s to learn this skill level.
-		else
-			sprintf(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[632], pClassNames[pClassType]);//Ýòîò óðîâåíü íàâûêà íå ìîæåò áûòü ïîñòèãíóò êëàññîì %s. This skill level can not be learned by the %s class.
-		return pTmpBuf.data();
-	}
-	if (!activePlayer->CanAct())
-		return pNPCTopics[122].pText; //Not in your condition!
-	pointsInSkill = activePlayer->pActiveSkills[skillBeingTaught];
-	pointsInSkillWOutMastery = pointsInSkill & 0x3F;
-	if (!pointsInSkillWOutMastery)
-		return pNPCTopics[131].pText; //You must know the skill before you can become an expert in it!
-	skillMastery = SkillToMastery(pointsInSkill);
-	if ((signed int)skillMastery > teacherLevel + 1)
-		return pNPCTopics[teacherLevel + 128].pText;    // You are already an SKILLLEVEL in this skill.	
-	dword_F8B1AC_award_bit_number = skillBeingTaught;
-	if (masteryLevelBeingTaught == 2 && pointsInSkillWOutMastery < 4
-		|| masteryLevelBeingTaught == 3 && pointsInSkillWOutMastery < 7
-		|| masteryLevelBeingTaught == 4 && pointsInSkillWOutMastery < 10
-		)
-		return pNPCTopics[127].pText;  //"You don't meet the requirements, and cannot be taught until you do."
-	switch (dword_F8B1AC_award_bit_number)
-	{
-	case PLAYER_SKILL_STAFF:
-	case PLAYER_SKILL_SWORD:
-	case PLAYER_SKILL_DAGGER:
-	case PLAYER_SKILL_AXE:
-	case PLAYER_SKILL_SPEAR:
-	case PLAYER_SKILL_BOW:
-	case PLAYER_SKILL_MACE:
-	case PLAYER_SKILL_ARMSMASTER:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_BLASTER:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 0;
-			break;
-		case 3:
-			gold_transaction_amount = 0;
-			break;
-		case 4:
-			gold_transaction_amount = 0;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_SHIELD:
-	case PLAYER_SKILL_LEATHER:
-	case PLAYER_SKILL_CHAIN:
-	case PLAYER_SKILL_PLATE:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 1000;
-			break;
-		case 3:
-			gold_transaction_amount = 3000;
-			break;
-		case 4:
-			gold_transaction_amount = 7000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_FIRE:
-	case PLAYER_SKILL_AIR:
-	case PLAYER_SKILL_WATER:
-	case PLAYER_SKILL_EARTH:
-	case PLAYER_SKILL_SPIRIT:
-	case PLAYER_SKILL_MIND:
-	case PLAYER_SKILL_BODY:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 1000;
-			break;
-		case 3:
-			gold_transaction_amount = 4000;
-			break;
-		case 4:
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_LIGHT:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 114))
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x22u, 1) ||
-				!activePlayer->ProfessionOrGuildFlagsCorrect(0x1Au, 1))
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_DARK:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			if (!(unsigned __int16)_449B57_test_bit(pParty->_quest_bits, 110))
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			if (!activePlayer->ProfessionOrGuildFlagsCorrect(0x23u, 1)
-				|| !activePlayer->ProfessionOrGuildFlagsCorrect(0x1Bu, 1))
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_ITEM_ID:
-	case PLAYER_SKILL_REPAIR:
-	case PLAYER_SKILL_MEDITATION:
-	case PLAYER_SKILL_PERCEPTION:
-	case PLAYER_SKILL_TRAP_DISARM:
-	case PLAYER_SKILL_MONSTER_ID:
-	case PLAYER_SKILL_STEALING:
-	case PLAYER_SKILL_ALCHEMY:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 500;
-			break;
-		case 3:
-			gold_transaction_amount = 2500;
-			break;
-		case 4:
-			gold_transaction_amount = 6000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_MERCHANT:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			if (activePlayer->GetBaseWillpower() < 50)
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_BODYBUILDING:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 500;
-			break;
-		case 3:
-			if (activePlayer->GetBaseEndurance() < 50)
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 2500;
-			break;
-		case 4:
-			gold_transaction_amount = 6000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_DIPLOMACY:
-		Error("Diplomacy not used");
-		break;
-	case PLAYER_SKILL_TIEVERY:
-		Error("Thievery not used");
-		break;
-	case PLAYER_SKILL_DODGE:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			if ((activePlayer->pActiveSkills[PLAYER_SKILL_UNARMED] & 63) < 0xA)
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_UNARMED:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			if ((activePlayer->pActiveSkills[PLAYER_SKILL_DODGE] & 63) < 0xA)
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	case PLAYER_SKILL_LEARNING:
-		switch (masteryLevelBeingTaught)
-		{
-		case 2:
-			gold_transaction_amount = 2000;
-			break;
-		case 3:
-			if (activePlayer->GetBaseIntelligence() < 50)
-				return pNPCTopics[127].pText;
-			gold_transaction_amount = 5000;
-			break;
-		case 4:
-			gold_transaction_amount = 8000;
-			break;
-		}
-		break;
-	default:
-		Error("Unknown skill");
-	}
-	if (gold_transaction_amount > pParty->uNumGold)
-		return pNPCTopics[124].pText;  //You don't have enough gold!
-	contract_approved = 1;
-	if (masteryLevelBeingTaught == 2)
-	{
-		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],//Ïîëó÷èòü ñòåïåíü ^Pr[%s] â íàâûêå ^Pr[%s] çà ^I[%lu] çîëîò^L[îé;ûõ;ûõ]
-			pGlobalTXT_LocalizationStrings[433], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Ýêñïåðò
-	}
-	else if (masteryLevelBeingTaught == 3)
-	{
-		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],
-			pGlobalTXT_LocalizationStrings[432], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Ìàñòåð
-	}
-	else if (masteryLevelBeingTaught == 4)
-		sprintfex(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[534],
-		pGlobalTXT_LocalizationStrings[225], pSkillNames[dword_F8B1AC_award_bit_number], gold_transaction_amount);//Âåëèêèé Ìàãèñòð
-	return pTmpBuf2.data();
-}
-
-//----- (00495461) --------------------------------------------------------
-char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, ItemGen *a3, char *a4, int a5, __int64 *a6)
-{
-	Player *pPlayer; // ebx@3
-	const char *pText; // esi@7
-	int v17; // eax@10
-	signed __int64 v18; // qax@18
-	unsigned __int8 *v20; // ebx@32
-	int v21; // ecx@34
-	int pReputation; // eax@45
-	int v29; // eax@68
-	__int16 v55[56]; // [sp+10h] [bp-128h]@34
-	stru351_summoned_item v56; // [sp+80h] [bp-B8h]@107
-	char a1[100]; // [sp+B8h] [bp-80h]@3
-	int v63; // [sp+12Ch] [bp-Ch]@32
-
-	if (IsBadStringPtrA(lpsz, 1))
-		return "Invalid String Passed";
-
-	a1[0] = 0;
-	pPlayer = &pParty->pPlayers[uPlayerID];
-	memset(pTmpBuf2.data(), 0, sizeof(pTmpBuf2));
-
-	NPCData *npc = nullptr;
-	if (dword_5C35D4)
-		npc = HouseNPCData[(unsigned int)((char *)pDialogueNPCCount + -(dword_591080 != 0))]; //- 1
-	else
-		npc = GetNPCData(sDialogue_SpeakingActorNPC_ID);
-
-	//pText = a4;
-	uint len = strlen(lpsz);
-	for (int i = 0, dst = 0; i < len; ++i)
-	{
-		char c = lpsz[i];
-		if (c != '%')
-			pTmpBuf2[dst++] = c;
-		else
-		{
-			v17 = 10 * (int)(lpsz[i + 1] - '0') + lpsz[i + 2] - '0';
-
-			switch (v17)
-			{
-			case 1://Ïîäðîáíåå
-				strcat(pTmpBuf2.data(), npc->pName);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 2:
-				strcat(pTmpBuf2.data(), pPlayer->pName);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 3:
-			case 4:
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 5:
-				v18 = (signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 60 / 60 % 24;
-				pText = pGlobalTXT_LocalizationStrings[397];// "evening"
-				if (SHIDWORD(v18) <= 0 && SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 5 && SHIDWORD(v18) <= 0)
-				{
-					if (SHIDWORD(v18) >= 0 && (unsigned int)v18 >= 11)
-					{
-						if (v18 < 20)
-							pText = pGlobalTXT_LocalizationStrings[396];// "day"
-					}
-					else
-					{
-						pText = pGlobalTXT_LocalizationStrings[395];// "morning"
-					}
-				}
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 6:
-				if (pPlayer->uSex)
-					pText = pGlobalTXT_LocalizationStrings[387];// "lady"
-				else
-					pText = pGlobalTXT_LocalizationStrings[385];// "sir"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 7:
-				if (pPlayer->uSex)
-					pText = pGlobalTXT_LocalizationStrings[389];// "Lady"
-				else
-					pText = pGlobalTXT_LocalizationStrings[386];// "Sir"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 8:
-				v63 = 0;
-				v20 = (unsigned __int8 *)pPlayer->_achieved_awards_bits;
-				for (uint _i = 0; _i < 28; ++_i)
-				{
-					if ((unsigned __int16)_449B57_test_bit(v20, word_4EE150[i]))
-					{
-						v21 = v63;
-						++v63;
-						v55[v63] = word_4EE150[i];
-					}
-				}
-				if (v63)
-				{
-					if (dword_A74CDC == -1)
-						dword_A74CDC = rand() % v63;
-					pText = (char *)pAwards[v55[dword_A74CDC]].pText;//(char *)dword_723E80_award_related[2 * v55[v24]];
-				}
-				else
-					pText = (char *)pNPCTopics[55].pText;
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 9:
-				if (npc->uSex)
-					pText = pGlobalTXT_LocalizationStrings[384];// "her"
-				else
-					pText = pGlobalTXT_LocalizationStrings[383];// "his"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 10:
-				if (pPlayer->uSex)
-					pText = pGlobalTXT_LocalizationStrings[389];// "Lady"
-				else
-					pText = pGlobalTXT_LocalizationStrings[388];// "Lord"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 11:
-				pReputation = pParty->GetPartyReputation();
-				if (pReputation >= 25)
-					pText = pGlobalTXT_LocalizationStrings[379];
-				else//v25 < 25
-				{
-					if (pReputation < 6)
-					{
-						if (pReputation >= -5)//6 >= v25 >= -5
-							pText = pGlobalTXT_LocalizationStrings[399];
-						else// v25 < -5
-						{
-							if (pReputation < -24)//-24 > v25
-								pText = pGlobalTXT_LocalizationStrings[434];
-							else// -5 > v25 > -24
-								pText = pGlobalTXT_LocalizationStrings[402];
-						}
-					}
-					else//25 > v25 > 6
-						pText = pGlobalTXT_LocalizationStrings[392];
-				}
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 12:
-				pReputation = npc->rep;
-				if (pReputation >= 25)
-					pText = pGlobalTXT_LocalizationStrings[379];//Íåíàâèñòíûé
-				else
-				{
-					if (pReputation < 6)
-					{
-						if (pReputation >= -5)
-							pText = pGlobalTXT_LocalizationStrings[399];//Íåéòðàëüíàÿ
-						else
-						{
-							if (pReputation < -24)
-								pText = pGlobalTXT_LocalizationStrings[434];//Ïî÷òåííàÿ
-							else
-								pText = pGlobalTXT_LocalizationStrings[402];//Äðóæåëþáíûé
-						}
-					}
-					else
-						pText = pGlobalTXT_LocalizationStrings[392];//Íåäðóæåëþáíûé
-				}
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 13:
-				strcat(pTmpBuf2.data(), pNPCStats->sub_495366_MispronounceName(pPlayer->pName[0], pPlayer->uSex));
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 14:
-				if (npc->uSex)
-					pText = pGlobalTXT_LocalizationStrings[391];// "sister"
-				else
-					pText = pGlobalTXT_LocalizationStrings[390];// "brother"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 15:
-				strcat(pTmpBuf2.data(), pGlobalTXT_LocalizationStrings[393]);// "daughter"
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 16:
-				if (npc->uSex)
-					pText = pGlobalTXT_LocalizationStrings[391];// "sister"
-				else
-					pText = pGlobalTXT_LocalizationStrings[390];// "brother"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 17://òåêñò íà¸ìíîãî ÍÏÑ
-			{
-						uint pay_percentage = pNPCStats->pProfessions[npc->uProfession].uHirePrice / 100;
-						if (!pay_percentage)
-							pay_percentage = 1;
-						sprintf(a1, "%lu", pay_percentage);
-						strcat(pTmpBuf2.data(), a1);
-						dst = strlen(pTmpBuf2.data());
-						i += 2;
-						break;
-			}
-			case 18:
-			case 19:
-			case 20:
-			case 21:
-			case 22:
-			case 26:
-				strncpy(a1, lpsz + i + 1, 2);
-				sprintf(a1, "%lu", atoi(a1));
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 23:
-				if (pMapStats->GetMapInfo(pCurrentMapName))
-					pText = pMapStats->pInfos[pMapStats->GetMapInfo(pCurrentMapName)].pName;
-				else
-					pText = pGlobalTXT_LocalizationStrings[394];// "Unknown"
-				strcat(pTmpBuf2.data(), pText);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 24://íàçâàíèå òîâàðà â ïðîäàæå
-				sprintfex(a1, format_4E2D80, Color16(255, 255, 155), a3->GetDisplayName());
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 25:
-				v29 = pPlayer->GetBaseBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-				switch (a5)
-				{
-				case 3:
-					v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-					break;
-				case 4:
-					v29 = pPlayer->GetBaseIdentifyPrice(p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-					break;
-				case 5:
-					v29 = pPlayer->GetBaseRepairPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-					break;
-				case 6:
-					v29 = pPlayer->GetBaseSellingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2;
-					break;
-				}
-				sprintfex(a1, "%lu", v29);
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 27://òåêñò ïðîäàæè
-				v29 = pPlayer->GetBuyingPrice(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-				if (a5 == 3)
-				{
-					v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-					if (a3->IsBroken())
-						v29 = 1;
-					sprintfex(a1, "%lu", v29);
-					strcat(pTmpBuf2.data(), a1);
-					dst = strlen(pTmpBuf2.data());
-					i += 2;
-					break;
-				}
-				if (a5 != 4)
-				{
-					if (a5 == 5)
-						v29 = pPlayer->GetPriceRepair(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier);
-					else
-					{
-						if (a5 == 6)
-						{
-							v29 = pPlayer->GetPriceSell(a3->GetValue(), p2DEvents[(signed int)a4 - 1].fPriceMultiplier) / 2;
-							if (a3->IsBroken())
-								v29 = 1;
-							if (!v29)
-								v29 = 1;
-							sprintfex(a1, "%lu", v29);
-							strcat(pTmpBuf2.data(), a1);
-							dst = strlen(pTmpBuf2.data());
-							i += 2;
-							break;
-						}
-					}
-					sprintfex(a1, "%lu", v29);
-					strcat(pTmpBuf2.data(), a1);
-					dst = strlen(pTmpBuf2.data());
-					i += 2;
-					break;
-				}
-				sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier));
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 28://ïðîôåññèÿ
-				strcat(pTmpBuf2.data(), (char *)p2DEvents[(signed int)a4 - 1].pProprieterTitle);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 29:
-				sprintfex(a1, "%lu", pPlayer->GetPriceIdentification(p2DEvents[(signed int)a4 - 1].fPriceMultiplier));
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 30:
-				if (!a6)
-				{
-					strcat(pTmpBuf2.data(), a4);
-					dst = strlen(pTmpBuf2.data());
-					i += 2;
-					break;
-				}
-				init_summoned_item(&v56, *a6);
-				sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year);
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			case 31:
-			case 32:
-			case 33:
-			case 34:
-				strcat(pTmpBuf2.data(), pParty->pPlayers[v17 - 31].pName);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			default:
-				if (v17 <= 50 || v17 > 70)
-				{
-					strncpy(a1, lpsz + i + 1, 2);
-					sprintf(a1, "%lu", atoi(a1));
-					strcat(pTmpBuf2.data(), a1);
-					dst = strlen(pTmpBuf2.data());
-					i += 2;
-					break;
-				}
-				if (v17 - 51 >= 20)
-				{
-					strcat(pTmpBuf2.data(), a4);
-					dst = strlen(pTmpBuf2.data());
-					i += 2;
-					break;
-				}
-				init_summoned_item(&v56, pParty->PartyTimes._s_times[v17 - 51]);
-				sprintfex(a1, pGlobalTXT_LocalizationStrings[378], aMonthNames[v56.field_14_exprie_month], v56.field_C_expire_day + 1, v56.field_18_expire_year);
-				strcat(pTmpBuf2.data(), a1);
-				dst = strlen(pTmpBuf2.data());
-				i += 2;
-				break;
-			}
-		}
-	}
-	return pTmpBuf2.data();
-}
-
-//----- (0044C175) --------------------------------------------------------
-void ShowStatusBarString(const char *pString, unsigned int uNumSeconds)
-{
-	strcpy(GameUI_Footer_TimedString.data(), pString);
-	GameUI_Footer_TimeLeft = 1000 * uNumSeconds + GetTickCount();
-
-	for (int i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()); i > 450;
-		i = pFontLucida->GetLineWidth(GameUI_Footer_TimedString.data()))
-		GameUI_Footer_TimedString[strlen(GameUI_Footer_TimedString.data()) - 1] = 0;
-}
-
-//----- (0044C1D0) --------------------------------------------------------
-void ShowNothingHereStatus()
-{
-	if (!GameUI_Footer_TimeLeft)
-		ShowStatusBarString(pGlobalTXT_LocalizationStrings[521], 2);// Nothing here
-}
-
-//----- (0044C28B) --------------------------------------------------------
-int const_2()
-{
-	return 2;
-}
--- a/GUIWindow.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,841 +0,0 @@
-#pragma once
-
-#include <cstdint>
-#include <array>
-
-#include "Engine/Objects/Player.h"
-
-enum UIMessageType: unsigned __int32
-{
-  UIMSG_0 = 0,
-
-  UIMSG_ChangeGameState = 5,
-
-  UIMSG_MouseLeftClickInGame = 10,
-
-  UIMSG_CHEST_ClickItem = 12,
-
-  UIMSG_MouseLeftClickInScreen = 14,
-  UIMSG_F = 15,
-
-  UIMSG_ChangeCursor = 17,
-
-  UIMSG_Attack = 23,
-
-  UIMSG_CastQuickSpell = 25,
-
-  UIMSG_STEALFROMACTOR = 27,
-  UIMSG_1C = 28,
-  UIMSG_PlayArcomage = 29,
-
-  UIMSG_31 = 49,
-  UIMSG_32 = 50,
-  UIMSG_SpellBook_PressTab = 51,
-  UIMSG_34 = 52,
-  UIMSG_35 = 53,
-  UIMSG_MainMenu_ShowPartyCreationWnd = 54,
-  UIMSG_MainMenu_ShowLoadWindow = 55,
-  UIMSG_ShowCredits = 56,
-  UIMSG_ExitToWindows = 57,
-  UIMSG_3A = 58,
-
-  UIMSG_PlayerCreationChangeName = 60,
-
-  UIMSG_PlayerCreationClickPlus = 62,
-  UIMSG_PlayerCreationClickMinus = 63,
-  UIMSG_PlayerCreationSelectActiveSkill = 64,
-  UIMSG_PlayerCreationSelectClass = 65,
-  UIMSG_PlayerCreationClickOK = 66,
-  UIMSG_PlayerCreationClickReset = 67,
-  UIMSG_44 = 68,
-  UIMSG_CastSpell_Character_Big_Improvement = 69,
-  UIMSG_CastSpell_Shoot_Monster = 70,
-  UIMSG_ClickBooksBtn = 71,
-  UIMSG_48 = 72,
-  UIMSG_49 = 73,
-  UIMSG_PlayerCreationRemoveUpSkill = 74,
-  UIMSG_PlayerCreationRemoveDownSkill = 75,
-
-  UIMSG_HintSelectRemoveQuickSpellBtn = 78,
-  UIMSG_SPellbook_ShowHightlightedSpellInfo = 79,
-
-  UIMSG_BuyInShop_Identify_Repair = 81,
-  UIMSG_LoadGame = 82,
-  UIMSG_SaveGame = 83,
-  UIMSG_54 = 84,
-  UIMSG_ChangeDetaliz = 85,
-  UIMSG_SelectSpell = 86,
-  UIMSG_OpenSpellbookPage = 87,
-  UIMSG_ClickInstallRemoveQuickSpellBtn = 88,
-
-  UIMSG_OnTravelByFoot = 90,
-  UIMSG_CHANGE_LOCATION_ClickCencelBtn = 91,
-  UIMSG_ShowStatus_DateTime = 92,
-  UIMSG_ShowStatus_ManaHP = 93,
-  UIMSG_ShowStatus_Player = 94,
-  UIMSG_Wait5Minutes  = 95,
-  UIMSG_Wait1Hour = 96,
-  UIMSG_Rest8Hour = 97,
-
-  UIMSG_ShowStatus_Food = 100,
-  UIMSG_ShowStatus_Funds = 101,
-
-  UIMSG_RestWindow = 104,
-  UIMSG_SpellBookWindow = 105,
-  UIMSG_QuickReference = 106,
-  UIMSG_GameMenuButton = 107,
-
-  UIMSG_AlreadyResting = 109,
-  UIMSG_SelectCharacter = 110,
-  UIMSG_ChangeSoundVolume = 111,
-  UIMSG_ChangeMusicVolume = 112,
-  UIMSG_Escape = 113,
-  UIMSG_ClickSkillsBtn = 114,
-  UIMSG_ClickStatsBtn = 115,
-  UIMSG_ClickInventoryBtn = 116,
-  UIMSG_ClickAwardsBtn = 117,
-  UIMSG_PlayerCreation_SelectAttribute = 118,
-
-  UIMSG_InventoryLeftClick = 120,
-  UIMSG_SkillUp = 121,
-  UIMSG_7A = 122,
-  UIMSG_GameMenu_ReturnToGame = 123,
-  UIMSG_StartNewGame = 124,
-  UIMSG_Game_OpenLoadGameDialog = 125,
-  UIMSG_Game_OpenSaveGameDialog = 126,
-  UIMSG_Game_OpenOptionsDialog = 127,
-  UIMSG_80 = 128,
-
-  UIMSG_SetGraphicsMode = 131,
-  UIMSG_Quit = 132,
-  UIMSG_ClickPaperdoll = 133,
-  UIMSG_StartHireling1Dialogue = 134,
-  UIMSG_StartHireling2Dialogue = 135,
-  UIMSG_SelectNPCDialogueOption = 136,
-
-  UIMSG_CastSpell_Monster_Improvement = 140,
-  UIMSG_CastSpell_Character_Small_Improvement = 141,
-  UIMSG_CastSpellFromBook = 142,
-  UIMSG_HiredNPC_CastSpell = 143,
-  UIMSG_PlayerCreation_VoicePrev = 144,
-  UIMSG_PlayerCreation_VoiceNext = 145,
-  UIMSG_SpellScrollUse = 146,
-
-  UIMSG_StartNPCDialogue = 161,
-  UIMSG_ArrowUp = 162,
-  UIMSG_DownArrow = 163,
-  UIMSG_SaveLoadBtn = 164,
-  UIMSG_SelectLoadSlot = 165,
-  UIMSG_Cancel = 166,
-  UIMSG_ExitRest = 167,
-  UIMSG_ClickExitCharacterWindowBtn = 168,
-  UIMSG_ClickAwardsUpBtn = 169,
-  UIMSG_ClickAwardsDownBtn = 170,
-  UIMSG_PlayerCreation_FacePrev = 171,
-  UIMSG_PlayerCreation_FaceNext = 172,
-  UIMSG_AD = 173,
-  UIMSG_AE = 174,
-  UIMSG_ClickNPCTopic = 175,
-  UIMSG_CycleCharacters = 176,
-  UIMSG_OnCastLloydsBeacon = 177,
-  UIMSG_LloydsBeacon_FlippingBtn = 178,
-  UIMSG_InstallBeacon = 179,
-  UIMSG_HintBeaconSlot = 180,
-  UIMSG_CloseAfterInstallBeacon = 181,
-  UIMSG_HintTownPortal = 182,
-  UIMSG_ClickTownInTP = 183,
-  UIMSG_SetTurnSpeed = 184,
-  UIMSG_ToggleWalkSound = 185,
-  UIMSG_ChangeVoiceVolume = 186,
-  UIMSG_ToggleShowDamage = 187,
-  UIMSG_ScrollNPCPanel = 188,
-  UIMSG_BD = 189,
-  UIMSG_CastSpell_Telekinesis = 190,
-  UIMSG_BF = 191,
-  UIMSG_ClickAwardScrollBar = 192,
-  UIMSG_C1 = 192,
-  UIMSG_C2 = 192,
-
-  UIMSG_OnCastTownPortal = 195,
-  UIMSG_OnFinalWindowClose = 196,
-  UIMSG_ShowFinalWindow = 197,
-  UIMSG_C6 = 198,
-  UIMSG_C7 = 199,
-  UIMSG_OpenQuestBook = 200,
-  UIMSG_OpenAutonotes = 201,
-  UIMSG_OpenMapBook = 202,
-  UIMSG_OpenCalendar = 203,
-  UIMSG_CC = 204,
-  UIMSG_CD = 205,
-  UIMSG_CE = 206,
-  UIMSG_CF = 207,
-  UIMSG_D0 = 208,
-  UIMSG_D1 = 209,
-  UIMSG_D2 = 210,
-  UIMSG_D3 = 211,
-  UIMSG_D4 = 212,
-  UIMSG_D5 = 213,
-  UIMSG_D6 = 214,
-
-  UIMSG_DD = 221,
-
-  UIMSG_OpenHistoryBook = 224,
-  UIMSG_ToggleAlwaysRun = 225,
-  UIMSG_ToggleFlipOnExit = 226,
-
-  UIMSG_ClickZoomOutBtn = 367,
-  UIMSG_ClickZoomInBtn = 368,
-
-  UIMSG_Game_Action = 404,
-  UIMSG_SelectShopDialogueOption = 405,
-
-  UIMSG_RentRoom = 409,
-  UIMSG_ClickHouseNPCPortrait = 410,
-  UIMSG_TransitionUI_Confirm = 411,
-  UIMSG_TransitionWindowCloseBtn = 412,
-
-  UIMSG_OpenKeyMappingOptions = 415,
-  UIMSG_SelectKeyPage1 = 416,
-  UIMSG_SelectKeyPage2 = 417,
-  UIMSG_ResetKeyMapping = 418,
-  UIMSG_ChangeKeyButton = 419,
-
-  UIMSG_OpenVideoOptions = 421,
-  UIMSG_ToggleBloodsplats = 422,
-  UIMSG_ToggleColoredLights = 423,
-  UIMSG_ToggleTint = 424,
-  UIMSG_1A9 = 425,
-
-  UIMSG_MMT_MainMenu_MM6 = 426,
-  UIMSG_MMT_MainMenu_MM7 = 427,
-  UIMSG_MMT_MainMenu_MM8 = 428,
-  UIMSG_MMT_MainMenu_Continue = 429,
-
-};
-
-
-/*  251 */
-enum MENU_STATE : __int32
-{
-  MENU_MAIN = 0,
-  MENU_NEWGAME = 1,
-  MENU_CREDITS = 2,
-  MENU_SAVELOAD = 3,
-  MENU_EXIT_GAME = 4,
-  MENU_5 = 5,
-  MENU_CREATEPARTY = 6,
-  MENU_NAMEPANELESC = 7,
-  MENU_CREDITSPROC = 8,
-  MENU_LoadingProcInMainMenu = 9,
-  MENU_DebugBLVLevel = 10,
-  MENU_CREDITSCLOSE = 11,
-  MENU_MMT_MAIN_MENU = 12,
-};
-
-
-enum DIALOGUE_TYPE
-{
-  DIALOGUE_USE_NPC_ABILITY = 9,
-  DIALOGUE_13 = 0xD,
-  DIALOGUE_18 = 18,
-  DIALOGUE_EVT_A = 19,
-  DIALOGUE_EVT_B = 20,
-  DIALOGUE_EVT_C = 21,
-  DIALOGUE_EVT_D = 22,
-  DIALOGUE_EVT_E = 23,
-  DIALOGUE_EVT_F = 0x18,
-  DIALOGUE_76 = 76,
-  DIALOGUE_PROFESSION_DETAILS = 77,
-  DIALOGUE_SKILL_TRAINER = 78,
-  DIALOGUE_84 = 84,
-  DIALOGUE_ARENA_SELECT_PAGE = 85,
-  DIALOGUE_ARENA_SELECT_SQUIRE = 86,
-  DIALOGUE_ARENA_SELECT_KNIGHT = 87,
-  DIALOGUE_ARENA_SELECT_CHAMPION = 88,
-  DIALOGUE_ARENA_WELCOME = 89,
-  DIALOGUE_ARENA_FIGHT_NOT_OVER_YET = 90,
-  DIALOGUE_ARENA_REWARD = 91,
-  DIALOGUE_ARENA_ALREADY_WON = 92,
-};
-
-
-
-
-
-/*  298 */
-enum WindowType: unsigned __int32
-{
-  WINDOW_null            = 0,
-  WINDOW_MainMenu        = 1,
-  WINDOW_OptionsButtons  = 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_SaveLoadButtons = 23,
-  WINDOW_MainMenu_Load = 0x18,
-  WINDOW_HouseInterior = 0x19,
-  WINDOW_Transition = 26,
-  WINDOW_CastSpell = 27,
-  WINDOW_Scroll = 0x1E,
-  WINDOW_CastSpell_InInventory = 31,
-  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_CharacterWindow_Inventory = 0x67,
-  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,
-};
-
-struct GUIButton;
-struct Texture;
-
-
-#define WINDOW_INPUT_NONE        0
-#define WINDOW_INPUT_IN_PROGRESS 1
-#define WINDOW_INPUT_CONFIRMED   2
-#define WINDOW_INPUT_CANCELLED   3
-
-/*  155 */
-#pragma pack(push, 1)
-struct GUIWindow
-{
-  inline GUIWindow()
-  {
-    pControlsHead = pControlsTail = nullptr;
-    eWindowType = WINDOW_null;
-  }
-
-  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, ...);
-  void DrawFlashingInputCursor(signed int uX, int uY, struct GUIFont *a2);
-  int DrawTextInRect(GUIFont *pFont, unsigned int uX, unsigned int uY, unsigned int uColor, const char *text, int rect_width, int reverse_text);
-  void DrawText(GUIFont *a2, signed int uX, int uY, unsigned int uFontColor, const char *Str, int a7, int a8, signed int uFontShadowColor);
-  void DrawTitleText(GUIFont *a2, signed int uHorizontalMargin, unsigned int uVerticalMargin, unsigned __int16 uDefaultColor, const char *pInString, unsigned int uLineSpacing);
-  void DrawShops_next_generation_time_string(__int64 next_generation_time);
-  void HouseDialogManager();
-  void OpenSpellBook();
-  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);
-
-  unsigned int uFrameX;
-  unsigned int uFrameY;
-  unsigned int uFrameWidth;
-  unsigned int uFrameHeight;
-  unsigned int uFrameZ;
-  unsigned int uFrameW;
-  WindowType   eWindowType;
-  union{
-  void *ptr_1C;// sometimes BuildID_2Events
-  unsigned int par1C;
-	};
-  unsigned int uNumControls;
-  int field_24;
-  int pNumPresenceButton; 
-  int pCurrentPosActiveItem;
-  int field_30;
-  int field_34;
-  int pStartingPosActiveItem;
-  int numVisibleWindows;
-  int receives_keyboard_input_2; //  0  no input   1 currently typing   2 enter pressed   3 escape pressed
-  int receives_keyboard_input;
-  const char *Hint;
-  GUIButton *pControlsHead;
-  GUIButton *pControlsTail;
-};
-#pragma pack(pop)
-
-
-
-
-
-
-
-
-enum CURRENT_SCREEN
-{
-  SCREEN_GAME = 0x0,
-  SCREEN_MENU = 0x1,
-  SCREEN_OPTIONS = 0x2,
-  SCREEN_BOOKS = 0x3,
-  SCREEN_NPC_DIALOGUE = 0x4,
-  SCREEN_REST = 0x5,
-  SCREEN_CHARACTERS = 0x7,
-  SCREEN_SPELL_BOOK = 0x8,
-  SCREEN_CREATORS = 0x9,
-  SCREEN_CHEST = 0xA,
-  SCREEN_SAVEGAME = 0xB,
-  SCREEN_LOADGAME = 0xC,
-  SCREEN_HOUSE = 0xD,
-  SCREEN_E = 0xE,
-  SCREEN_CHEST_INVENTORY = 0xF,
-  SCREEN_VIDEO = 0x10,
-  SCREEN_CHANGE_LOCATION = 0x11,
-  SCREEN_INPUT_BLV = 0x12,
-  SCREEN_BRANCHLESS_NPC_DIALOG = 0x13,
-  SCREEN_PARTY_CREATION = 0x15,
-  SCREEN_MODAL_WINDOW = 0x16,
-  SCREEN_CASTING = 0x17,
-  SCREEN_19 = 0x19,
-  SCREEN_KEYBOARD_OPTIONS = 0x1A,
-  SCREEN_1B = 0x1B,
-  SCREEN_VIDEO_OPTIONS = 0x1C,
-  SCREEN_63 = 0x63,
-  SCREEN_64 = 0x64,
-  SCREEN_67 = 0x67,
-  SCREEN_QUICK_REFERENCE = 0x68,
-};
-
-
-
-
-/*  249 */
-#pragma pack(push, 1)
-struct GUIMessage
-{
-  enum UIMessageType eType;
-  int param;
-  int field_8;
-};
-#pragma pack(pop)
-
-
-
-
-#define AddGUIMessage(msg, param, a4) AddMessageImpl((msg), (param), (a4), __FILE__, __LINE__)
-/*  250 */
-#pragma pack(push, 1)
-struct GUIMessageQueue
-{
-  inline GUIMessageQueue():
-    uNumMessages(0)
-  {}
-
-  void Flush();
-  void PopMessage(UIMessageType *pMsg, int *pParam, int *a4);
-  void AddMessageImpl(UIMessageType msg, int param, unsigned int a4, const char *file = nullptr, int line = 0);
-
-  unsigned int uNumMessages;
-  GUIMessage pMessages[40];
-
-  const char *files[40];
-  int          lines[40];
-};
-#pragma pack(pop)
-
-extern struct GUIMessageQueue *pMessageQueue_50CBD0; // idb
-
-extern struct GUIMessageQueue *pMessageQueue_50C9E8; // idb
-
-
-
-void OnSelectNPCDialogueOption(DIALOGUE_TYPE newDialogueType);
-
-
-
-extern int pWindowList_at_506F50_minus1_indexing_buttons____and_an_int_[]; // idb
-extern struct GUIWindow *pWindow_MMT_MainMenu;
-extern struct GUIWindow *pWindow_MainMenu;
-extern std::array<struct GUIWindow, 20> pWindowList;
-
-
-
-
-void ModalWindow(const char *pStrHint, UIMessageType OnRelease_message);
-void ModalWindow_ShowHint();
-void ModalWindow_Release();
-
-
-
-void draw_leather();
-
-
-// main menu ui
-void MainMenuUI_LoadFontsAndSomeStuff();
-void MainMenuUI_Create();
-MENU_STATE MainMenuUI_Credits_Loop();
-
-// save & load ui
-void SaveUI_Load();
-void SaveUI_Draw();
-
-void LoadUI_Draw();
-void LoadUI_Load(unsigned int uDialogueType); // idb
-
-// game ui
-void GameUI_DrawRightPanel();
-void GameUI_DrawRightPanelFrames();
-void GameUI_DrawRightPanelItems();
-void GameUI_QuickRef_Draw();
-void GameUI_DrawFoodAndGold();
-void GameUI_DrawLifeManaBars();
-void GameUI_DrawHiredNPCs();
-void GameUI_DrawPortraits(unsigned int _this);
-void GameUI_Footer();
-void GameUI_Footer_2();
-void GameUI_SetFooterString(const char *pStr);
-void GameUI_DrawMinimap(unsigned int uX, unsigned int uY, unsigned int uZ, unsigned int uW, unsigned int uZoom, unsigned int bRedrawOdmMinimap);
-auto GameUI_GetMinimapHintText() -> const char *;
-void GameUI_DrawPartySpells();
-void GameUI_DrawTorchlightAndWizardEye();
-void GameUI_DrawCharacterSelectionFrame();
-void GameUI_CharacterQuickRecord_Draw(GUIWindow *window, Player *player);
-void GameUI_DrawNPCPopup(void *_this);
-
-void GameUI_InitializeDialogue(struct Actor *actor, int bPlayerSaysHello);
-void GameUI_DrawBranchlessDialogue();
-void GameUI_DrawDialogue();
-
-
-// game menu ui
-void GameMenuUI_DrawKeyBindings();
-void GameMenuUI_DrawVideoOptions();
-void GameMenuUI_Options_Draw();
-
-
-
-
-// character ui
-struct GUIWindow *CharacterUI_Initialize(unsigned int _this);
-const char *CharacterUI_GetSkillDescText(unsigned int uPlayerID, PLAYER_SKILL_TYPE uPlayerSkillType);
-void CharacterUI_SkillsTab_ShowHint();
-void CharacterUI_StatsTab_ShowHint();
-void CharacterUI_StatsTab_Draw(Player *player);
-void CharacterUI_SkillsTab_CreateButtons();
-void CharacterUI_SkillsTab_Draw(Player *player);
-void CharacterUI_AwardsTab_Draw(Player *player);
-void CharacterUI_InventoryTab_Draw(Player *player, bool a2);
-void CharacterUI_CharacterScreen_Draw(Player *player);
-void CharacterUI_DrawPaperdoll(Player *player);
-void CharacterUI_DrawPaperdollWithRingOverlay(Player *player);
-void CharacterUI_ReleaseButtons();
-
-unsigned int GetSkillColor(unsigned int uPlayerClass, PLAYER_SKILL_TYPE uPlayerSkillType, signed int skill_level);
-
-
-
-
-
-// book ui
-void BookUI_Draw(WindowType book);
-void BookUI_Questbook_Draw();
-void BookUI_Autonotes_Draw();
-void BookUI_Map_Draw();
-void BookUI_Calendar_Draw();
-void BookUI_Journal_Draw();
-
-void OnCloseBook();
-void InitializeBookTextures();
-void InitializeBookFonts();
-void DrawSpellBookContent(Player *player);
-unsigned int  DrawLloydBeaconsScreen();
-void BookUI_DrawTownPortalMap();
-void LoadSpellbook(unsigned int uID); // idb
-void DrawSpellDescriptionPopup(int spell_index);
-void OnCloseSpellBookPage();
-void OnCloseSpellBook();
-
-
-
-// rest ui
-void RestUI_Load();
-void RestUI_Draw();
-
-
-// transition & travel ui
-void TransitionUI_Load(uint32_t anim_id, uint32_t exit_pic_id, int x, int y, int z, int directiony, int directionx, int a8, const char *pLocationName);
-void TransitionUI_Draw();
-
-void TravelUI_Load();
-void TravelUI_Draw();
-
-
-
-
-
-void UI_OnMouseRightClick(Vec2_int_ *_this);
-
-void __fastcall DrawPopupWindow(unsigned int uX, unsigned int uY, unsigned int uWidth, unsigned int uHeight); // idb
-void DrawMM7CopyrightWindow();
-//void LoadFonts_and_DrawCopyrightWindow();
-void GUI_UpdateWindows();
-int GetConditionDrawColor(unsigned int uConditionIdx); // idb
-void FillAwardsData();
-void CreateAwardsScrollBar();
-void ReleaseAwardsScrollBar();
-void Inventory_ItemPopupAndAlchemy();
-void __fastcall LoadThumbnailLloydTexture(unsigned int uSlot, unsigned int uPlayer);
-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 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);
-void SetUserInterface(enum PartyAlignment alignment, bool bReplace);
-void CreateMsgScrollWindow(signed int mscroll_id);
-void free_book_subwindow();
-void CreateScrollWindow();
-void OnPaperdollLeftClick();
-void DrawJoinGuildWindow(int pEventCode);
-void  DialogueEnding();
-char sub_4637E0_is_there_popup_onscreen();
-void sub_4B3E1E();
-void __fastcall ClickNPCTopic(signed int uMessageParam);
-void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
-void _4B3FE5_training_dialogue(int a4);
-void OracleDialogue();
-void CheckBountyRespawnAndAward();
-const char * _4B254D_SkillMasteryTeacher(int trainerInfo);
-char *BuildDialogueString(const char *lpsz, unsigned __int8 uPlayerID, struct ItemGen *a3, char *a4, int a5, __int64 *a6);
-void __fastcall DrawTextAtStatusBar(const char *Str, int a5);
-void ShowStatusBarString(const char *pString, unsigned int uNumSeconds);
-void ShowNothingHereStatus();
-int const_2();
-
-
-void __fastcall ZBuffer_Fill(int *pZBuffer, int uTextureId, int iZValue);
-void __fastcall ZBuffer_DoFill(int *pZBuffer, struct Texture *pTex, int uZValue);
-void __fastcall ZBuffer_DoFill2(int *pZBuffer, struct Texture *a2, int a3); // idb
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#pragma pack(push, 1)
-struct GUIButton
-{
-void DrawLabel(const char *label_text, struct GUIFont *pFont, int a5, int uFontShadowColor);
-
-  void Release();
-
-
-  unsigned int uX;
-  unsigned int uY;
-  unsigned int uWidth;
-  unsigned int uHeight;
-  unsigned int uZ;
-  unsigned int uW;
-  int uButtonType;
-  int field_1C;//may be pMessageType
-  UIMessageType msg;
-  unsigned int  msg_param;
-  int field_28;
-  int field_2C_is_pushed;
-  GUIButton *pPrev;
-  GUIButton *pNext;
-  struct GUIWindow *pParent;
-  struct Texture *pTextures[5];
-  unsigned int uNumTextures;
-  unsigned __int8 uHotkey;
-  char pButtonName[32];
-  char field_75[71];
-};
-#pragma pack(pop)
-
-
-
-
-extern struct GUIButton *pBtn_CloseBook;
-extern struct GUIButton *pBtn_InstallRemoveSpell;
-extern struct GUIButton *pBtn_Autonotes_Instructors;
-extern struct GUIButton *pBtn_Autonotes_Misc;
-extern struct GUIButton *pBtn_Book_6;
-extern struct GUIButton *pBtn_Book_5;
-extern struct GUIButton *pBtn_Book_4;
-extern struct GUIButton *pBtn_Book_3;
-extern struct GUIButton *pBtn_Book_2;
-extern struct GUIButton *pBtn_Book_1;
-
-
-extern struct GUIButton *pPlayerCreationUI_BtnReset;
-extern struct GUIButton *pPlayerCreationUI_BtnOK;
-extern struct GUIButton *pBtn_ExitCancel;
-extern struct GUIButton *pBtn_YES;
-extern struct GUIButton *pPlayerCreationUI_BtnPlus;
-extern struct GUIButton *pPlayerCreationUI_BtnMinus;
-
-
-extern struct GUIButton *pButton_RestUI_Main;
-extern struct GUIButton *pButton_RestUI_Exit;
-extern struct GUIButton *pButton_RestUI_Wait5Minutes;
-extern struct GUIButton *pButton_RestUI_WaitUntilDawn;
-extern struct GUIButton *pButton_RestUI_Wait1Hour;
-
-
-extern struct GUIButton *pCharacterScreen_ExitBtn;
-extern struct GUIButton *pCharacterScreen_AwardsBtn;
-extern struct GUIButton *pCharacterScreen_InventoryBtn;
-extern struct GUIButton *pCharacterScreen_SkillsBtn;
-extern struct GUIButton *pCharacterScreen_StatsBtn;
-extern struct GUIButton *pCharacterScreen_DollBtn;
-extern struct GUIButton *pCharacterScreen_DetalizBtn;
-
-
-extern struct GUIButton *pBtn_NPCRight;
-extern struct GUIButton *pBtn_NPCLeft;
-extern struct GUIButton *pBtn_GameSettings;
-extern struct GUIButton *pBtn_QuickReference;
-extern struct GUIButton *pBtn_CastSpell;
-extern struct GUIButton *pBtn_Rest;
-extern struct GUIButton *pBtn_History;
-extern struct GUIButton *pBtn_Calendar;
-extern struct GUIButton *pBtn_Maps;
-extern struct GUIButton *pBtn_Autonotes;
-extern struct GUIButton *pBtn_Quests;
-
-
-extern struct GUIButton *pMMT_MainMenu_BtnMM6;
-extern struct GUIButton *pMMT_MainMenu_BtnMM7;
-extern struct GUIButton *pMMT_MainMenu_BtnMM8;
-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;
-extern struct GUIButton *ptr_507BA4;
-
-
-extern struct GUIWindow *pPrimaryWindow;
-extern struct GUIWindow *pChestWindow;
-extern struct GUIWindow *pDialogueWindow;
-extern struct GUIWindow *window_SpeakInHouse;
-extern struct GUIWindow *pGUIWindow_ScrollWindow;
-extern struct GUIWindow *ptr_507BC8;
-extern struct GUIWindow *pGUIWindow_CurrentMenu;
-extern struct GUIWindow *ptr_507BD0;
-extern struct GUIWindow *pGUIWindow_Settings;
-extern struct GUIWindow *pModalWindow;
-extern struct GUIWindow *pGUIWindow_EscMessageWindow;
-extern struct GUIWindow *pBooksWindow;
-extern struct GUIWindow *pGUIWindow2;
-
-
-extern struct GUIButton *pBtn_Resume;
-extern struct GUIButton *pBtn_QuitGame;
-extern struct GUIButton *pBtn_GameControls;
-extern struct GUIButton *pBtn_LoadGame;
-extern struct GUIButton *pBtn_SaveGame;
-extern struct GUIButton *pBtn_NewGame;
-
-extern struct GUIButton *pBtn_SliderRight;
-extern struct GUIButton *pBtn_SliderLeft;
-
-
-extern struct GUIButton *pBtnDownArrow;
-extern struct GUIButton *pBtnArrowUp;
-extern struct GUIButton *pBtnCancel;
-extern struct GUIButton *pBtnLoadSlot;
-
-
-extern std::array<GUIButton*, 4> pCreationUI_BtnPressRight2;
-extern std::array<GUIButton*, 4> pCreationUI_BtnPressLeft2;
-extern std::array<GUIButton*, 4> pCreationUI_BtnPressLeft;
-extern std::array<GUIButton*, 4> pCreationUI_BtnPressRight;
-
-extern int uTextureID_GameUI_CharSelectionFrame; // 50C98C
-
-extern unsigned int ui_mainmenu_copyright_color;
-extern unsigned int ui_character_tooltip_header_default_color;
-extern unsigned int ui_character_default_text_color;
-extern unsigned int ui_character_skill_highlight_color;
-extern unsigned int ui_character_header_text_color;
-extern unsigned int ui_character_bonus_text_color;
-extern unsigned int ui_character_bonus_text_color_neg;
-extern unsigned int ui_character_skill_upgradeable_color;
-extern unsigned int ui_character_skill_default_color;
-extern unsigned int ui_character_stat_default_color;
-extern unsigned int ui_character_stat_buffed_color;
-extern unsigned int ui_character_stat_debuffed_color;
-extern unsigned int ui_character_skillinfo_can_learn;
-extern unsigned int ui_character_skillinfo_can_learn_gm;
-extern unsigned int ui_character_skillinfo_cant_learn;
-extern unsigned int ui_character_condition_normal_color;
-extern unsigned int ui_character_condition_light_color;
-extern unsigned int ui_character_condition_moderate_color;
-extern unsigned int ui_character_condition_severe_color;
-extern std::array<unsigned int, 6> ui_character_award_color;
-extern unsigned int ui_game_minimap_outline_color;
-extern unsigned int ui_game_minimap_actor_friendly_color;
-extern unsigned int ui_game_minimap_actor_hostile_color;
-extern unsigned int ui_game_minimap_actor_corpse_color;
-extern unsigned int ui_game_minimap_decoration_color_1;
-extern unsigned int ui_game_minimap_projectile_color;
-extern unsigned int ui_game_minimap_treasure_color;
-extern std::array<unsigned int, 24> ui_game_character_record_playerbuff_colors;
-extern unsigned int ui_gamemenu_video_gamma_title_color;
-extern unsigned int ui_gamemenu_keys_action_name_color;
-extern unsigned int ui_gamemenu_keys_key_selection_blink_color_1;
-extern unsigned int ui_gamemenu_keys_key_selection_blink_color_2;
-extern unsigned int ui_gamemenu_keys_key_default_color;
-extern unsigned int ui_book_quests_title_color;
-extern unsigned int ui_book_quests_text_color;
-extern unsigned int ui_book_autonotes_title_color;
-extern unsigned int ui_book_autonotes_text_color;
-extern unsigned int ui_book_map_title_color;
-extern unsigned int ui_book_map_coordinates_color;
-extern unsigned int ui_book_calendar_title_color;
-extern unsigned int ui_book_calendar_time_color;
-extern unsigned int ui_book_calendar_day_color;
-extern unsigned int ui_book_calendar_month_color;
-extern unsigned int ui_book_calendar_year_color;
-extern unsigned int ui_book_calendar_moon_color;
-extern unsigned int ui_book_calendar_location_color;
-extern unsigned int ui_book_journal_title_color;
-extern unsigned int ui_book_journal_text_color;
-extern unsigned int ui_book_journal_text_shadow;
-extern unsigned int ui_game_dialogue_npc_name_color;
-extern unsigned int ui_game_dialogue_option_highlight_color;
-extern unsigned int ui_game_dialogue_option_normal_color;
-extern unsigned int ui_house_player_cant_interact_color;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/Keyboard.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,840 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "Keyboard.h"
+#include "GUI/GUIWindow.h"
+#include "Engine/Game.h"
+
+#include "Engine/Graphics/Vis.h"
+#include "Engine/MM7.h"
+#include "Engine/Objects/Actor.h"
+#include "Engine/Party.h"
+#include "Engine/Timer.h"
+#include "Engine/TurnEngine/TurnEngine.h"
+#include "Engine/Graphics/Weather.h"
+#include "Engine/Spells/CastSpellInfo.h"
+#include "Engine/Graphics/Indoor.h"
+#include "Engine/Registry.h"
+
+#include <tuple>
+#include <vector>
+#include <string>
+
+struct KeyboardActionMapping *pKeyActionMap;
+
+
+class CKeyListElement
+{
+public:
+  std::string m_keyName;
+  unsigned char m_keyDefaultCode;
+  unsigned short m_cmdId;
+  KeyToggleType m_toggType;
+  CKeyListElement(std::string keyName, unsigned char keyDefaultCode, unsigned short cmdId, KeyToggleType toggType):
+    m_keyName(keyName),
+    m_keyDefaultCode(keyDefaultCode),
+    m_cmdId(cmdId),
+    m_toggType(toggType)
+  {
+
+  }
+};
+
+std::array<CKeyListElement, 30>keyMappingParams = {
+  CKeyListElement("KEY_FORWARD", VK_UP, INPUT_MoveForward, TOGGLE_Continuously),
+  CKeyListElement("KEY_BACKWARD", VK_DOWN, INPUT_MoveBackwards, TOGGLE_Continuously),
+  CKeyListElement("KEY_LEFT", VK_LEFT, INPUT_TurnLeft, TOGGLE_Continuously),
+  CKeyListElement("KEY_RIGHT", VK_RIGHT, INPUT_TurnRight, TOGGLE_Continuously),
+  CKeyListElement("KEY_ATTACK", 'A', INPUT_Attack, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_CASTREADY", 'S', INPUT_CastReady, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_YELL", 'Y', INPUT_Yell, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_JUMP", 'X', INPUT_Jump, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_COMBAT", VK_RETURN, INPUT_Combat, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_EVENTTRIGGER", VK_SPACE, INPUT_EventTrigger, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_CAST", 'C', INPUT_Cast, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_PASS", 'B', INPUT_Pass, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_CHARCYCLE", VK_TAB, INPUT_CharCycle, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_QUEST", 'Q', INPUT_Quest, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_QUICKREF", 'Z', INPUT_QuickRef, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_REST", 'R', INPUT_Rest, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_TIMECAL", 'T', INPUT_TimeCal, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_AUTONOTES", 'N', INPUT_Autonotes, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_MAPBOOK", 'M', INPUT_Mapbook, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_LOOKUP", VK_NEXT, INPUT_LookUp, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_LOOKDOWN", VK_DELETE, INPUT_LookDown, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_CENTERVIEWPT", VK_END, INPUT_CenterView, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_ZOOMIN", VK_ADD, INPUT_ZoomIn, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_ZOOMOUT", VK_SUBTRACT, INPUT_ZoomOut, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_FLYUP", VK_PRIOR, INPUT_FlyUp, TOGGLE_Continuously),
+  CKeyListElement("KEY_FLYDOWN", VK_INSERT, INPUT_FlyDown, TOGGLE_Continuously),
+  CKeyListElement("KEY_LAND", VK_HOME, INPUT_Land, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_ALWAYSRUN", 'U', INPUT_AlwaysRun, TOGGLE_OneTimePress),
+  CKeyListElement("KEY_STEPLEFT", VK_OEM_4, INPUT_StrafeLeft, TOGGLE_Continuously),
+  CKeyListElement("KEY_STEPRIGHT", VK_OEM_6, INPUT_StrafeRight, TOGGLE_Continuously)
+}; 
+
+std::array<std::tuple<const char*, const unsigned __int8>, 26> keyNameToCodeTranslationMap =
+{
+  std::tuple<const char*, const unsigned __int8>("UP", VK_UP),
+  std::tuple<const char*, const unsigned __int8>("DOWN", VK_DOWN),
+  std::tuple<const char*, const unsigned __int8>("LEFT", VK_LEFT),
+  std::tuple<const char*, const unsigned __int8>("ÂËÅÂÎ", VK_LEFT),
+  std::tuple<const char*, const unsigned __int8>("RIGHT", VK_RIGHT),
+  std::tuple<const char*, const unsigned __int8>("ÂÏÐÀÂÎ", VK_RIGHT),
+  std::tuple<const char*, const unsigned __int8>("RETURN", VK_RETURN),
+  std::tuple<const char*, const unsigned __int8>("SPACE", VK_SPACE),
+  std::tuple<const char*, const unsigned __int8>("PAGE_DOWN", VK_NEXT),
+  std::tuple<const char*, const unsigned __int8>("PAGE_UP", VK_PRIOR),
+  std::tuple<const char*, const unsigned __int8>("TAB", VK_TAB),
+  std::tuple<const char*, const unsigned __int8>("SUBTRACT", VK_SUBTRACT),
+  std::tuple<const char*, const unsigned __int8>("ADD", VK_ADD),
+  std::tuple<const char*, const unsigned __int8>("END", VK_END),
+  std::tuple<const char*, const unsigned __int8>("DELETE", VK_DELETE),
+  std::tuple<const char*, const unsigned __int8>("HOME", VK_HOME),
+  std::tuple<const char*, const unsigned __int8>("INSERT", VK_INSERT),
+  std::tuple<const char*, const unsigned __int8>("COMMA", VK_OEM_COMMA),
+  std::tuple<const char*, const unsigned __int8>("DECIMAL", VK_DECIMAL),
+  std::tuple<const char*, const unsigned __int8>("SEMICOLON", VK_OEM_1),
+  std::tuple<const char*, const unsigned __int8>("PERIOD", VK_OEM_PERIOD),
+  std::tuple<const char*, const unsigned __int8>("SLASH", VK_OEM_2),
+  std::tuple<const char*, const unsigned __int8>("SQUOTE", VK_OEM_7),
+  std::tuple<const char*, const unsigned __int8>("BACKSLASH", VK_OEM_5),
+  std::tuple<const char*, const unsigned __int8>("BACKSPACE", VK_BACK),
+  std::tuple<const char*, const unsigned __int8>("CONTROL", VK_CONTROL),
+};
+
+//----- (00459C68) --------------------------------------------------------
+void KeyboardActionMapping::SetKeyMapping(int uAction, int vKey, KeyToggleType type)
+{
+  pVirtualKeyCodesMapping[uAction] = vKey;
+  pToggleTypes[uAction] = type;
+}
+
+//----- (00459C82) --------------------------------------------------------
+unsigned int KeyboardActionMapping::GetActionVKey(enum InputAction eAction)
+{
+  return this->pVirtualKeyCodesMapping[eAction];
+}
+
+//----- (00459C8D) --------------------------------------------------------
+KeyboardActionMapping::KeyboardActionMapping()
+{
+  uLastKeyPressed = 0;
+  field_204 = 0;
+  pWindow = nullptr;
+
+  SetDefaultMapping();
+  ReadMappings();
+
+  ResetKeys();
+
+  uNumKeysPressed = 0;
+
+  uGameMenuUI_CurentlySelectedKeyIdx = -1;
+}
+// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
+
+//----- (00459CC4) --------------------------------------------------------
+void KeyboardActionMapping::SetDefaultMapping()
+{
+  for ( size_t i = 0; i < keyMappingParams.size(); i++)
+  {
+    SetKeyMapping(keyMappingParams[i].m_cmdId, keyMappingParams[i].m_keyDefaultCode, keyMappingParams[i].m_toggType);
+  }
+}
+
+//----- (00459E3F) --------------------------------------------------------
+void KeyboardActionMapping::ResetKeys()
+{
+  for (uint i = 0; i < 30; ++i)
+    GetAsyncKeyState(pVirtualKeyCodesMapping[i]);
+}
+
+//----- (00459E5A) --------------------------------------------------------
+void KeyboardActionMapping::EnterText(int a2, int max_string_len, GUIWindow *pWindow)
+{
+  memset(this->pPressedKeysBuffer, 0, 0x101u);
+  this->uNumKeysPressed = 0;
+  if ( a2 )
+    this->field_204 = 2;
+  else
+    this->field_204 = 1;
+  this->max_input_string_len = max_string_len;
+  this->pWindow = pWindow;
+  pWindow->receives_keyboard_input_2 = WINDOW_INPUT_IN_PROGRESS;
+}
+
+//----- (00459ED1) --------------------------------------------------------
+void KeyboardActionMapping::SetWindowInputStatus(int a2)
+{
+  field_204 = 0;
+  if ( pWindow )
+    pWindow->receives_keyboard_input_2 = a2;
+}
+
+//----- (00459F10) --------------------------------------------------------
+bool KeyboardActionMapping::ProcessTextInput(unsigned int a2)
+{
+  pKeyActionMap->uLastKeyPressed = a2;
+  if ( uGameMenuUI_CurentlySelectedKeyIdx == -1 )
+  {
+    if ( pKeyActionMap->field_204 != 1 && pKeyActionMap->field_204 != 2 )
+      return 0;
+    if ( a2 == VK_BACK)
+    {
+      if (pKeyActionMap->uNumKeysPressed > 0)
+      {
+        --pKeyActionMap->uNumKeysPressed;
+        pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
+      }
+    }
+    else if ( a2 == VK_RETURN )
+      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
+    else if ( a2 == VK_ESCAPE )
+      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CANCELLED);
+    else if (this->uNumKeysPressed < this->max_input_string_len)
+    {
+      if ( pKeyActionMap->field_204 == 1 )
+      {
+        if ( a2 != VK_TAB )
+        {
+          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
+          ++pKeyActionMap->uNumKeysPressed;
+          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
+        }
+      }
+      else if (pKeyActionMap->field_204 == 2)
+      {
+        if ( isdigit(a2))
+        {
+          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
+          ++pKeyActionMap->uNumKeysPressed;
+        }
+      }
+    }
+  }
+  else
+  {
+    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
+    ++pKeyActionMap->uNumKeysPressed;
+    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
+    pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
+  }
+  return 1;
+}
+// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
+
+//----- (00459FFC) --------------------------------------------------------
+void KeyboardActionMapping::ReadMappings()
+{
+  char str[32];
+
+  for (size_t i = 0; i < keyMappingParams.size(); i++)
+  {
+    const char* keyName = keyMappingParams[i].m_keyName.c_str();
+    short commandDefaultKeyCode = keyMappingParams[i].m_keyDefaultCode;
+    short commandId = keyMappingParams[i].m_cmdId;
+    KeyToggleType toggType = keyMappingParams[i].m_toggType;
+
+    ReadWindowsRegistryString(keyName, str, 32, "DEFAULT");
+    if ( strcmp(str, "DEFAULT") && ( TranslateKeyNameToKeyCode(str) != -1) )
+      pVirtualKeyCodesMapping[commandId] = TranslateKeyNameToKeyCode(str);
+    else
+      pVirtualKeyCodesMapping[commandId] = commandDefaultKeyCode;
+    pToggleTypes[commandId] = toggType;
+  }
+
+  bAlwaysRun = ReadWindowsRegistryInt("valAlwaysRun", 0) != 0;
+  bFlipOnExit = ReadWindowsRegistryInt("FlipOnExit", 0) != 0;
+}
+
+//----- (0045A960) --------------------------------------------------------
+void KeyboardActionMapping::StoreMappings()
+{
+
+  const char *v2; // eax@1
+
+  for ( size_t i = 0; i < keyMappingParams.size(); i++)
+  {
+    v2 = GetVKeyDisplayName(pVirtualKeyCodesMapping[keyMappingParams[i].m_cmdId]);
+    WriteWindowsRegistryString(keyMappingParams[i].m_keyName.c_str(), v2);
+  }
+}
+
+//----- (0045ABCA) --------------------------------------------------------
+const unsigned __int8 KeyboardActionMapping::TranslateKeyNameToKeyCode(const char *Str)
+{
+  if (strlen(Str) == 1)
+  {
+    if( Str[0] >= 65 && Str[0] <= 90 )
+      return *Str;
+    else
+      return 0xFF;
+  }
+
+  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
+  {
+    if (!strcmp(Str, std::get<0>(keyNameToCodeTranslationMap[i])))
+      return std::get<1>(keyNameToCodeTranslationMap[i]);
+  }
+  return 0xFF;
+}
+
+//----- (0045AE2C) --------------------------------------------------------
+const char * KeyboardActionMapping::GetVKeyDisplayName(unsigned char a1)
+{
+  static char static_sub_45AE2C_string_69ADE0_keyName[32];
+
+  if ( a1 >= 65 && a1 <= 90 )
+  {
+    static_sub_45AE2C_string_69ADE0_keyName[0] = a1;
+    static_sub_45AE2C_string_69ADE0_keyName[1] = '\0';
+    return static_sub_45AE2C_string_69ADE0_keyName;
+  }
+
+  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
+  {
+    if ( a1 == std::get<1>(keyNameToCodeTranslationMap[i]))
+    {
+      const char* keyName =  std::get<0>(keyNameToCodeTranslationMap[i]);
+      strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, keyName);
+      return static_sub_45AE2C_string_69ADE0_keyName;
+    }
+  }
+
+  strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, "-ÍÅÒ -");
+  return static_sub_45AE2C_string_69ADE0_keyName;
+}
+
+
+//----- (0045B019) --------------------------------------------------------
+void Keyboard::EnterCriticalSection()
+{
+}
+
+//----- (0045B06E) --------------------------------------------------------
+bool Keyboard::IsShiftHeld()
+{
+  return (GetAsyncKeyState(VK_SHIFT) & 0x8001) != 0;
+}
+
+//----- (0045B0A9) --------------------------------------------------------
+bool Keyboard::IsKeyBeingHeld(int vKey)
+{
+  return (GetAsyncKeyState(vKey) & 0x8001) != 0;
+}
+
+//----- (0045B0CE) --------------------------------------------------------
+bool Keyboard::WasKeyPressed(int vKey)
+{
+  return (GetAsyncKeyState(vKey) & 1) != 0;
+}
+//----- (0046A14B) --------------------------------------------------------
+void OnPressSpace()
+{
+
+  //if ( pRenderer->pRenderD3D )
+  {
+    pGame->PickKeyboard(Keyboard::IsKeyBeingHeld(VK_CONTROL), &vis_sprite_filter_3, &vis_door_filter);
+    int pid = pGame->pVisInstance->get_picked_object_zbuf_val();
+    if ( pid != -1 )
+      DoInteractionWithTopmostZObject(pid & 0xFFFF, PID_ID(pid));
+    return;
+  }
+
+  
+  // software render stuff following
+  /*
+  static int dword_720660[100]; // 720660
+  static int dword_7207F0[100]; // 7207F0
+
+  v22 = 0;
+  v1 = (int *)((signed int)(viewparams->uScreen_BttmR_X + viewparams->uScreen_topL_X) >> 1);//wrong pointer
+  if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
+  {
+	  v2 = (char *)v1 - 50;
+	  v1 = (int *)((char *)v1 + 50);
+	  v3 = 640 * viewparams->uScreen_topL_Y;
+	  v17 = v2;
+	  v20 = v1;
+	  v18 = ((viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y - 1) >> 1) + 1;
+	  do
+	  {
+		if ( (signed int)v2 < (signed int)v20 )
+		{
+			v1 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
+			v21 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
+			v4 = v22;
+			v5 = (((char *)v20 - v2 - 1) >> 1) + 1;
+			do
+			{
+			  v6 = 0;
+			  v7 = *v1 & 0xFFFF;
+			  v19 = 0;
+			  if ( v4 > 0 )
+			  {
+				do
+				{
+				  if ( dword_7207F0[v6] == v7 )
+					break;
+				  ++v6;
+				  v19 = v6;
+				}
+				while ( v6 < v22 );
+			  }
+			  if ( PID_TYPE(v7) == OBJECT_Decoration)
+			  {
+				v16 = (unsigned int)PID_ID(v7);
+				if ( (signed int)(((unsigned int)*v21 >> 16)
+								- pDecorationList->pDecorations[pLevelDecorations[(unsigned int)PID_ID(v7)].uDecorationDescID].uRadius) <= 512 )
+				  if ( v19 == v22 && v4 < 100 )
+				  {
+					++v22;
+					++v4;
+					v8 = *v21;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
+				  }
+			  }
+			  else if ( (unsigned int)*v21 <= 0x2000000 )
+			  {
+				  if ( v19 == v22 && v4 < 100 )
+				  {
+					++v22;
+					++v4;
+					v8 = *v21;
+					dword_7207F0[v4 - 1] = v7;
+					dword_720660[v4 - 1] = v8;
+				  }
+			  }
+			  v1 = v21 + 2;
+			  --v5;
+			  v21 += 2;
+			}
+			while ( v5 );
+			v2 = v17;
+		}
+		v3 += 1280;
+		--v18;
+	  }
+	  while ( v18 );
+  }
+  if ( v22 > 0 )
+  {
+    v9 = dword_720660;
+    v10 = 1;
+    do
+    {
+      for ( i = v10; i < v22; ++i )
+      {
+        v12 = *v9;
+        v13 = dword_720660[i];
+        if ( v13 < *v9 )
+        {
+          *v9 = v13;
+          dword_720660[i] = v12;
+        }
+      }
+      ++v10;
+      ++v9;
+      LOBYTE(v1) = v10 - 1;
+    }
+    while ( v10 - 1 < v22 );
+  }
+  for ( j = 0; j < v22; ++j )
+  {
+    LOBYTE(v1) = DoInteractionWithTopmostZObject(dword_720660[j] & 0xFFFF, v16);
+    if ( !(char)v1 )
+      break;
+  }*/
+}
+
+
+//----- (0042FC4E) --------------------------------------------------------
+void Keyboard::ProcessInputActions()
+{
+  char v4; // al@9
+  unsigned __int16 v9; // ax@102
+  int spell_price; // eax@103
+  PartyAction partyAction; // [sp-14h] [bp-1Ch]@20
+  InputAction inputAction; // [sp+0h] [bp-8h]@7
+
+  pGame->pKeyboardInstance->EnterCriticalSection();
+  Keyboard* pKeyboard = pGame->pKeyboardInstance;
+  if (!bAlwaysRun)
+  {
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+   }
+  else
+  {
+    if (pKeyboard->IsShiftHeld())
+      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
+    else
+      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+  }
+
+  //pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
+
+
+    //  WUT? double event trigger
+  /*for ( uint i = 0; i < 30; ++i )
+  {
+    if ( pKeyActionMap->pToggleTypes[i] )
+      v14 = pGame->pKeyboardInstance->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[i]);
+    else
+      v14 = pGame->pKeyboardInstance->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[i]);
+    if ( v14 )
+    {
+      if (pCurrentScreen == SCREEN_GAME)
+      {
+        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Game_Action, 0, 0);
+        continue;
+      }
+      if ( pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
+      {
+        v15 = pMessageQueue_50CBD0->uNumMessages;
+        if ( pMessageQueue_50CBD0->uNumMessages )
+        {
+          v15 = 0;
+          if ( pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 )
+          {
+            v15 = 1;
+            pMessageQueue_50CBD0->uNumMessages = 0;
+            pMessageQueue_50CBD0->pMessages[v15].eType = UIMSG_Escape;
+            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+            *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+            ++pMessageQueue_50CBD0->uNumMessages;
+            continue;
+          }
+          pMessageQueue_50CBD0->uNumMessages = 0;
+        }
+        //pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+      }
+    }
+  }*/
+  if ( !pEventTimer->bPaused )
+  {
+    for ( uint i = 0; i < 30; ++i )
+    {
+      inputAction = (InputAction)i;
+      if ( pKeyActionMap->pToggleTypes[inputAction] )
+        v4 = pKeyboard->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
+      else
+        v4 = pKeyboard->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
+      if ( v4 )
+      {
+        switch ( inputAction )
+        {
+          case INPUT_MoveForward:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
+                partyAction = PARTY_RunForward;
+              else
+                partyAction = PARTY_WalkForward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if (pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
+            {
+              pTurnEngine->uActionPointsLeft -= 26;
+              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
+                partyAction = PARTY_RunForward;
+              else
+                partyAction = PARTY_WalkForward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            break;
+          case INPUT_MoveBackwards:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_RunBackward;
+              else
+                partyAction = PARTY_WalkBackward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
+            {
+              pTurnEngine->uActionPointsLeft -= 26;
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_RunBackward;
+              else
+                partyAction = PARTY_WalkBackward;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            break;
+          case INPUT_StrafeLeft:
+            if (pCurrentScreen  != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              partyAction = PARTY_StrafeLeft;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+              break;
+            pTurnEngine->uActionPointsLeft -= 26;
+            partyAction = PARTY_StrafeLeft;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_StrafeRight:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if (!pParty->bTurnBasedModeOn)
+            {
+              partyAction = PARTY_StrafeRight;
+              pPartyActionQueue->Add(partyAction);
+              break;
+            }
+            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+              break;
+            pTurnEngine->uActionPointsLeft -= 26;
+            partyAction = PARTY_StrafeRight;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_TurnLeft:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if ( GetAsyncKeyState(VK_CONTROL) ) // strafing
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+                  break;
+                pTurnEngine->uActionPointsLeft -= 26;
+              }
+              partyAction = PARTY_StrafeLeft;
+            }
+            else
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_FastTurnLeft;
+              else
+                partyAction = PARTY_TurnLeft;
+            }
+            pPartyActionQueue->Add(partyAction);
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
+              pWeather->OnPlayerTurn(10);
+            break;
+          case INPUT_TurnRight:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if ( GetAsyncKeyState(VK_CONTROL) )         // strafing
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
+                  break;
+                pTurnEngine->uActionPointsLeft -= 26;
+              }
+              partyAction = PARTY_StrafeRight;
+            }
+            else
+            {
+              if ( pParty->uFlags2 & 2 )
+                partyAction = PARTY_FastTurnRight;
+              else
+                partyAction = PARTY_TurnRight;
+            }
+            pPartyActionQueue->Add(partyAction);
+            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
+              pWeather->OnPlayerTurn(-10);
+            break;
+          case INPUT_Jump:
+            if (pCurrentScreen != SCREEN_GAME || pParty->bTurnBasedModeOn)
+              break;
+            partyAction = (PartyAction)12;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_Yell:
+            if (!pCurrentScreen && uActiveCharacter)
+            {
+              pParty->Yell();
+              pPlayers[uActiveCharacter]->PlaySound(SPEECH_Yell, 0);
+            }
+          break;
+          case INPUT_Pass:
+            if ( pCurrentScreen )
+              break;
+            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
+            {
+              pTurnEngine->field_18 |= TE_FLAG_8;
+              break;
+            }
+            if ( uActiveCharacter )
+            {
+              if ( !pPlayers[uActiveCharacter]->uTimeToRecovery )
+              {
+                if ( !pParty->bTurnBasedModeOn )
+                  pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)pPlayers[uActiveCharacter]->GetAttackRecoveryTime(false) * 2.133333333333333));
+                CastSpellInfoHelpers::_427D48();
+                pTurnEngine->ApplyPlayerAction();
+              }
+            }
+            break;
+          case INPUT_Combat://if press ENTER
+            if (pCurrentScreen == SCREEN_GAME)
+            {
+              if (pParty->bTurnBasedModeOn)
+              {
+                if (pTurnEngine->turn_stage == TE_MOVEMENT || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
+                {
+                  pParty->bTurnBasedModeOn = 0;
+                  pTurnEngine->End(true);
+                }
+              }
+              else
+              {
+                pTurnEngine->Start();
+                pParty->bTurnBasedModeOn = true;
+              }
+            }
+            break;
+          case INPUT_CastReady:
+            {
+              if (pCurrentScreen != SCREEN_GAME)
+                break;
+              if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
+              {
+                pTurnEngine->field_18 |= TE_FLAG_8;
+                break;
+              }
+              if ( !uActiveCharacter )
+                break;
+              uchar quickSpellNumber = pPlayers[uActiveCharacter]->uQuickSpell;
+              v9 = pPlayers[uActiveCharacter]->pActiveSkills[quickSpellNumber / 11 + 12];
+              bool enoughMana = false;
+              if ((v9 & 0x100) != 0)
+              {
+                enoughMana = pSpellDatas[quickSpellNumber].uMagisterLevelMana < pPlayers[uActiveCharacter]->sMana;
+              }
+              else if ((v9 & 0x80) != 0)
+              {
+                enoughMana = pSpellDatas[quickSpellNumber].uMasterLevelMana < pPlayers[uActiveCharacter]->sMana;
+              }
+              else if ((v9 & 0x40) != 0)
+              {
+                enoughMana = pSpellDatas[quickSpellNumber].uExpertLevelMana < pPlayers[uActiveCharacter]->sMana;
+              }
+              else
+              {
+                enoughMana = pSpellDatas[quickSpellNumber].uNormalLevelMana < pPlayers[uActiveCharacter]->sMana;
+              }
+              if ( !pPlayers[uActiveCharacter]->uQuickSpell || bUnderwater || !enoughMana)
+              {
+                pPartyActionQueue = pPartyActionQueue;
+                pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
+                break;
+              }
+              else
+                pMessageQueue_50C9E8->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0);
+            }
+            break;
+          case INPUT_Attack:
+            if (pCurrentScreen != SCREEN_GAME)
+              break;
+            if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT)
+            {
+              pTurnEngine->field_18 |= TE_FLAG_8;
+              break;
+            }
+            pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
+            break;
+          case INPUT_EventTrigger:
+            if (pCurrentScreen == SCREEN_GAME)
+            {
+              pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Game_Action, 0, 0);
+              break;
+            }
+            if ( pCurrentScreen == SCREEN_NPC_DIALOGUE )
+            {
+              if ( pMessageQueue_50CBD0->uNumMessages )
+              {
+                pMessageQueue_50CBD0->uNumMessages = 0;
+                if ( pMessageQueue_50CBD0->pMessages[0].field_8 )
+                {
+                  pMessageQueue_50CBD0->uNumMessages = 1;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
+                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 = 0;
+                  ++pMessageQueue_50CBD0->uNumMessages;
+                  break;
+                }
+                break;
+              }
+              pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
+            }
+            break;
+          case INPUT_CharCycle:
+            if ( pCurrentScreen == SCREEN_SPELL_BOOK  )
+              break;
+
+            pMessageQueue_50C9E8->AddGUIMessage(UIMSG_CycleCharacters, 0, 0);
+            break;
+          case INPUT_LookUp:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)7;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_CenterView:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)9;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_LookDown:
+            if ( pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)8;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_FlyUp:
+            if ( pCurrentScreen || pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)13;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_Land:
+            if ( pCurrentScreen || pEventTimer->bPaused )
+              break;
+            partyAction = (PartyAction)15;
+            pPartyActionQueue->Add(partyAction);
+            break;
+          case INPUT_FlyDown:
+            if ( !pCurrentScreen && !pEventTimer->bPaused )
+            {
+              partyAction = (PartyAction)14;
+              pPartyActionQueue->Add(partyAction);
+            }
+            break;
+          case INPUT_ZoomIn:
+              pMessageQueue_50C9E8->AddGUIMessage(UIMSG_ClickZoomOutBtn, 0, 0);
+            break;
+          case INPUT_ZoomOut:
+              pMessageQueue_50C9E8->AddGUIMessage(UIMSG_ClickZoomInBtn, 0, 0);
+            break;
+          case INPUT_AlwaysRun:
+            bAlwaysRun = bAlwaysRun == 0;
+            break;
+          default:
+            break;
+        }
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/Keyboard.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,101 @@
+#pragma once
+
+
+/*  284 */
+enum InputAction : __int32
+{
+  INPUT_MoveForward = 0x0,
+  INPUT_MoveBackwards = 0x1,
+  INPUT_TurnLeft = 0x2,
+  INPUT_TurnRight = 0x3,
+  INPUT_Yell = 0x4,
+  INPUT_Jump = 0x5,
+  INPUT_Combat = 0x6,
+  INPUT_CastReady = 0x7,
+  INPUT_Attack = 0x8,
+  INPUT_EventTrigger = 0x9,
+  INPUT_Cast = 0xA,
+  INPUT_Pass = 0xB,
+  INPUT_CharCycle = 0xC,
+  INPUT_Quest = 0xD,
+  INPUT_QuickRef = 0xE,
+  INPUT_Rest = 0xF,
+  INPUT_TimeCal = 0x10,
+  INPUT_Autonotes = 0x11,
+  INPUT_Mapbook = 0x12,
+  INPUT_AlwaysRun = 0x13,
+  INPUT_LookUp = 0x14,
+  INPUT_LookDown = 0x15,
+  INPUT_CenterView = 0x16,
+  INPUT_ZoomIn = 0x17,
+  INPUT_ZoomOut = 0x18,
+  INPUT_FlyUp = 0x19,
+  INPUT_FlyDown = 0x1A,
+  INPUT_Land = 0x1B,
+  INPUT_StrafeLeft = 0x1C,
+  INPUT_StrafeRight = 0x1D,
+};
+
+
+
+enum KeyToggleType : __int32
+{
+  TOGGLE_Continuously = 0x0,
+  TOGGLE_OneTimePress = 0x1,
+};
+
+#pragma pack(push, 1)
+struct KeyboardActionMapping
+{
+  KeyboardActionMapping();
+
+  void SetKeyMapping(int uAction, int vKey, KeyToggleType type);
+  unsigned int GetActionVKey(enum InputAction eAction);
+  const char *GetVKeyDisplayName(unsigned char a1);
+  const unsigned __int8 TranslateKeyNameToKeyCode(const char *Str);
+  void ReadMappings();
+  void StoreMappings();
+  bool ProcessTextInput(unsigned int a2);
+  void SetWindowInputStatus(int a2);
+  void EnterText(int a2, int max_string_len, struct GUIWindow *pWindow);
+  void ResetKeys();
+  void SetDefaultMapping();
+
+  unsigned int uLastKeyPressed;
+  int field_4;
+  int field_8;
+  unsigned int pVirtualKeyCodesMapping[30];
+  KeyToggleType pToggleTypes[30];
+  int max_input_string_len;
+  __int8 pPressedKeysBuffer[257];
+  unsigned __int8 uNumKeysPressed;
+  char field_202;
+  char field_203;
+  int field_204;
+  struct GUIWindow *pWindow;
+};
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+class Keyboard
+{
+public:
+  inline Keyboard():
+    bUsingAsynKeyboard(false)
+  {}
+  bool WasKeyPressed(int vKey);
+  static bool IsKeyBeingHeld(int vKey);
+  static void ProcessInputActions();
+  bool IsShiftHeld();
+  void EnterCriticalSection();
+
+  void ( ***vdestructor_ptr)(Keyboard *, bool);
+  unsigned int bUsingAsynKeyboard;
+};
+#pragma pack(pop)
+
+
+
+void OnPressSpace();
+
+extern struct KeyboardActionMapping *pKeyActionMap;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/Mouse.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,795 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "Engine/mm7_data.h"
+#include "Mouse.h"
+#include "Engine/Party.h"
+#include "Engine/LOD.h"
+#include "Engine/Game.h"
+
+#include "Engine/TurnEngine/TurnEngine.h"
+#include "Engine/Graphics/Viewport.h"
+#include "GUI/GUIWindow.h"
+#include "Engine/Graphics/Vis.h"
+#include "Engine/Objects/Actor.h"
+#include "Engine/MM7.h"
+#include "Media/Audio/AudioPlayer.h"
+
+
+Mouse *pMouse;
+
+
+
+
+
+//----- (00469860) --------------------------------------------------------
+void Mouse::GetClickPos(unsigned int *pX, unsigned int *pY)
+{
+  *pX = uMouseClickX;
+  *pY = uMouseClickY;
+}
+
+//----- (004698A6) --------------------------------------------------------
+void Mouse::RemoveHoldingItem()
+{
+  pParty->pPickedItem.Reset();
+  if (_stricmp(pCurrentCursorName, "MICON2"))
+    SetCursorBitmap("MICON1");
+}
+
+//----- (004698D8) --------------------------------------------------------
+void Mouse::SetCursorBitmapFromItemID(unsigned int uItemID)
+{
+  pMouse->SetCursorBitmap(pItemsTable->pItems[uItemID].pIconName);
+}
+
+//----- (004698F6) --------------------------------------------------------
+void Mouse::SetCurrentCursorBitmap()
+{
+  SetCursorBitmap(pCurrentCursorName);
+}
+
+//----- (00469903) --------------------------------------------------------
+void Mouse::SetCursorBitmap(const char *pName)
+{
+//  DDSURFACEDESC2 Dst;
+
+  if ( !this->bInitialized || !pName )
+    return;
+  if ( _stricmp("MICON2", pName) )//åñëè êóñîð íå ìèøåíü
+    pGame->uFlags2 &= 0xFFFFFFEF;
+  else
+    pGame->uFlags2 |= 0x10;
+  if ( _stricmp(this->pCurrentCursorName, pName) )
+    strcpy(this->pCurrentCursorName, pName);
+  ClearCursor();
+  if ( _strnicmp(pName, "MICON1", 5) )//for click to item / åñëè êóðñîð ñ âåùüþ
+  {
+    this->uCursorTextureID = pIcons_LOD->LoadTexture(pName, TEXTURE_16BIT_PALETTE);
+    this->uCursorTextureID_2 = pIcons_LOD->LoadTexture(pName, TEXTURE_16BIT_PALETTE);
+    this->AllocCursorSystemMem();
+    this->field_C = 0;
+    this->bRedraw = true;
+    this->bActive = true;
+    if ( !areWeLoadingTexture )
+    {
+      if (uCursorTextureID != -1)
+        pIcons_LOD->pTextures[uCursorTextureID].Release();
+      pIcons_LOD->SyncLoadedFilesCount();
+    }
+    return;
+  }
+  this->bActive = false;
+  this->field_C = 1;
+  window->SetCursor(pName);
+}
+// 506128: using guessed type int areWeLoadingTexture;
+
+//----- (00469AE4) --------------------------------------------------------
+LONG Mouse::_469AE4()
+{
+  LONG v2; // ecx@2
+  LONG result; // eax@2
+  struct tagPOINT Point; // [sp+Ch] [bp-8h]@2
+
+  this->field_8 = 1;
+  /*if (pAsyncMouse)
+  {
+    v2 = *((int *)pAsyncMouse + 6);
+    Point.x = *((int *)pAsyncMouse + 6);
+    result = *((int *)pAsyncMouse + 7);
+  }
+  else
+  {*/
+    GetCursorPos(&Point);
+    //if ( pRenderer->bWindowMode )
+      ScreenToClient(window->GetApiHandle(), &Point);
+    result = Point.y;
+    v2 = Point.x;
+  //}
+  this->uMouseClickX = v2;
+  this->uMouseClickY = result;
+
+  /*
+  //This block has been commented out, because of the changed condition above "if(true)"
+  //Also the next condition and the first line has been commented out as well
+
+  // if (pRenderer->bWindowMode)
+  if ( true )
+    goto LABEL_16;
+  //if (pAsyncMouse)
+  //  goto LABEL_24;
+  
+
+  if ( v2 < 0 )
+    v2 = 0;
+  if ( result < 0 )
+    result = 0;
+  if ( v2 > window->GetWidth() - 1 )
+    v2 = window->GetWidth() - 1;
+  */
+  
+//  if ( result > window->GetHeight() - 1 )
+//  {
+//    result = window->GetHeight() - 1;
+//LABEL_16:
+    //if (pAsyncMouse)
+    //  goto LABEL_24;
+	if (true/*pRenderer->bWindowMode*/ && (v2 < 0 || result < 0 || v2 > window->GetWidth() - 1 || result > window->GetHeight() - 1))
+	{
+		this->bActive = false;
+		//LABEL_24:
+		this->field_8 = 0;
+		return result;
+	}
+  //}
+  
+  if ( this->field_C )
+//LABEL_23:
+    this->bActive = false;
+//LABEL_24:
+  this->field_8 = 0;
+  return result;
+}
+
+//----- (00469BA3) --------------------------------------------------------
+void Mouse::ClearCursor()
+{
+  this->bActive = false;
+  free(this->pCursorBitmap_sysmem);
+  this->pCursorBitmap_sysmem = nullptr;
+  free(this->pCursorBitmap2_sysmem);
+  this->pCursorBitmap2_sysmem = nullptr;
+  free(this->ptr_90);
+  this->ptr_90 = nullptr;
+}
+
+//----- (00469BE6) --------------------------------------------------------
+void Mouse::AllocCursorSystemMem()
+{
+  bActive = false;
+  if (!pCursorBitmap_sysmem)
+    pCursorBitmap_sysmem = (unsigned __int16 *)DoAllocCursorMem();
+  if (!pCursorBitmap2_sysmem)
+    pCursorBitmap2_sysmem = (unsigned __int8 *)DoAllocCursorMem();
+}
+
+//----- (00469C0D) --------------------------------------------------------
+void *Mouse::DoAllocCursorMem()
+{
+  Texture* tex = pIcons_LOD->GetTexture(uCursorTextureID);
+  return malloc(4 * tex->uTextureWidth * tex->uTextureHeight);
+}
+
+//----- (00469C39) --------------------------------------------------------
+POINT *Mouse::GetCursorPos(POINT *a2)
+{
+  a2->x = this->uMouseClickX;
+  a2->y = this->uMouseClickY;
+  return a2;
+}
+
+//----- (00469C65) --------------------------------------------------------
+void Mouse::Initialize(OSWindow *window)
+{
+  this->window = window;
+  this->bActive = false;
+  this->bInitialized = true;
+
+  //this->field_8 = 0;//Ritor1: result incorrect uMouseClickX, this->uMouseClickY in _469AE4()
+  this->uCursorBitmapPitch = 0;//Ritor1: it's include
+  for ( uint i = 0; i < 13; i++ )
+    this->field_5C[i] = 0;
+
+  this->pCursorBitmapPos.x = 0;
+  this->pCursorBitmapPos.y = 0;
+  this->uMouseClickX = 0;
+  this->uMouseClickY = 0;
+  this->pCursorBitmap_sysmem = nullptr;
+  this->field_34 = 0;
+  this->pCursorBitmap2_sysmem = nullptr;
+
+  SetCursorBitmap("MICON3");
+  SetCursorBitmap("MICON2");
+  SetCursorBitmap("MICON1");
+}
+
+// inlined
+//----- (0045FE00) mm6 chinese --------------------------------------------
+void Mouse::SetActive(bool active)
+{
+  bActive = active;
+}
+
+//----- (00469CC2) --------------------------------------------------------
+void Mouse::Deactivate()
+{
+  if (bInitialized)
+    SetActive(false);
+}
+
+//----- (00469CCD) --------------------------------------------------------
+void Mouse::DrawCursor()
+{
+  unsigned int v9; // eax@31
+
+  if ( this->bInitialized )
+  {
+    if ( !this->field_8 && this->bActive && !this->field_C ) //Uninitialized memory access(this->field_8)
+      pMouse->_469AE4();//Ritor1: ñòðàííàÿ, íåïîíÿòíàÿ ôóíêöèÿ
+    this->field_F4 = 1;
+    if ( this->field_C )
+    {
+      this->field_F4 = 0;
+      return;
+    }
+
+    //if ( pRenderer->bWindowMode )
+    {
+      if ( this->uMouseClickX < 0 || this->uMouseClickY < 0 || this->uMouseClickX > window->GetWidth() - 1 || this->uMouseClickY > window->GetHeight() - 1 )
+      {
+        this->field_F4 = 0;
+        return;
+      }
+    }
+    /*else
+    {
+      if ( this->uMouseClickX < 0 )
+        this->uMouseClickX = 0;
+      if ( this->uMouseClickY < 0 )
+        this->uMouseClickY = 0;
+      if ( this->uMouseClickX > 639 )
+        this->uMouseClickX = 639;
+      if ( this->uMouseClickY > 479 )
+        this->uMouseClickY = 479;
+    }*/
+    this->pCursorBitmapRect.x = this->uMouseClickX;
+    this->pCursorBitmapRect.w = this->uMouseClickY + this->field_5C[0]; //Ritor1: Maybe this->field_5C[0] - cursor width
+    this->pCursorBitmapRect.y = this->uMouseClickY;
+    this->pCursorBitmapRect.z = this->uMouseClickX + this->uCursorBitmapPitch; //Ritor1: Maybe this->uCursorBitmapPitch - cursor height
+    if ( this->uMouseClickX < 0 )
+      this->pCursorBitmapRect.x = 0;
+    if ( this->uMouseClickY < 0 )
+      this->pCursorBitmapRect.y = 0;
+    if ( this->pCursorBitmapRect.z > window->GetWidth() )
+      this->pCursorBitmapRect.z = window->GetWidth();
+    if ( this->pCursorBitmapRect.w > window->GetHeight() )
+      this->pCursorBitmapRect.w = window->GetHeight();
+    this->bActive = false;
+    this->uCursorBitmapWidth = this->pCursorBitmapRect.z - this->pCursorBitmapRect.x;
+    this->uCursorBitmapHeight = this->pCursorBitmapRect.w - this->pCursorBitmapRect.y;
+    if ( this->bRedraw )
+    {
+      if ( pMouse->ptr_90 )
+        v9 = 2 * pMouse->uCursorBitmapPitch;
+      else
+        v9 = 0;
+      pRenderer->_4A6DF5( this->pCursorBitmap_sysmem, v9, &this->pCursorBitmapPos, pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch,
+        &this->pCursorBitmapRect);//ñðàáàòûâàåò êîãäà áåð¸ì êóðñîðîì âåùü â èíâåíòîðå
+      this->bRedraw = false;
+    }
+  }
+}
+
+//----- (00469E1C) --------------------------------------------------------
+void Mouse::Activate()
+{
+  bActive = true;
+}
+
+//----- (00469E24) --------------------------------------------------------
+void Mouse::_469E24()
+{
+  free(pCursorBitmap3_sysmembits_16bit);
+  pCursorBitmap3_sysmembits_16bit = nullptr;
+}
+
+//----- (00469E3B) --------------------------------------------------------
+void Mouse::DrawCursorToTarget()//??? DrawCursorWithItem
+{
+  if (!pCursorBitmap3_sysmembits_16bit)
+    return;
+  //ïèøåì íà ýêðàí êóðñîð ñ âåùüþ
+  ushort* pSrc = pCursorBitmap3_sysmembits_16bit;
+  for (int y = uCursorWithItemY; y < uCursorWithItemZ; ++y)
+    for (int x = uCursorWithItemX; x < uCursorWithItemW; ++x)
+      //pRenderer->pTargetSurface[y * pRenderer->uTargetSurfacePitch + x] = *pSrc++;
+        pRenderer->WritePixel16(x, y, *pSrc++);
+}
+
+//----- (00469EA4) --------------------------------------------------------
+void Mouse::ReadCursorWithItem()
+{
+  unsigned int pTextureID; // eax@2
+  Texture *pTexture; // edi@2
+//  int v8; // ecx@25
+//  int v9; // ebx@26
+//  unsigned int v10; // eax@26
+//  int v11; // edx@27
+  int pTextureHeight; // [sp+20h] [bp-8h]@15
+//  unsigned __int16 *v20; // [sp+20h] [bp-8h]@28
+  int pTextureWidth; // [sp+24h] [bp-4h]@12
+  unsigned __int16 *v22; // [sp+24h] [bp-4h]@25
+
+  if ( pParty->pPickedItem.uItemID )
+  {
+    pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
+    pTexture = (Texture *)(pTextureID != -1 ? (int)&pIcons_LOD->pTextures[pTextureID] : 0);
+
+    if ( (signed int)pMouse->uMouseClickX <= window->GetWidth() - 1 && (signed int)pMouse->uMouseClickY <= window->GetHeight() - 1 )
+    {
+      /*if ( (v4 & 0x80000000u) != 0 )
+        a2 = 0;
+      if ( (v5 & 0x80000000u) != 0 )
+      {
+        //v6 = 0;
+        v15 = 0;
+      }	*/
+      if ( (signed int)(pTexture->uTextureWidth + pMouse->uMouseClickX) <= window->GetWidth() )
+        pTextureWidth = pTexture->uTextureWidth;
+      else
+        pTextureWidth = window->GetWidth() - pMouse->uMouseClickX;
+      if ( (signed int)(pTexture->uTextureHeight + pMouse->uMouseClickY) <= window->GetHeight() )
+        pTextureHeight = pTexture->uTextureHeight;
+      else
+        pTextureHeight = window->GetHeight() - pMouse->uMouseClickY;
+      if ( !this->pCursorBitmap3_sysmembits_16bit
+        || pMouse->uMouseClickX != this->uCursorWithItemX
+        || pMouse->uMouseClickY != this->uCursorWithItemY
+        || pMouse->uMouseClickX + pTextureWidth != this->uCursorWithItemW
+        || pMouse->uMouseClickY + pTextureHeight != this->uCursorWithItemZ )
+      {
+        free(this->pCursorBitmap3_sysmembits_16bit);
+        this->pCursorBitmap3_sysmembits_16bit = (unsigned __int16 *)malloc(2 * pTexture->uTextureHeight * pTexture->uTextureWidth);
+        this->uCursorWithItemX = pMouse->uMouseClickX;
+        this->uCursorWithItemW = pMouse->uMouseClickX + pTextureWidth;
+        this->uCursorWithItemY = pMouse->uMouseClickY;
+        this->uCursorWithItemZ = pMouse->uMouseClickY + pTextureHeight;
+      }
+      v22 = this->pCursorBitmap3_sysmembits_16bit;
+
+      for (int y = this->uCursorWithItemY; y < this->uCursorWithItemZ; ++y)
+      {
+        for (int x = this->uCursorWithItemX; x < this->uCursorWithItemW; ++x)
+        {
+          *v22++ = pRenderer->ReadPixel16(x, y);
+        }
+      }
+      /*if ( v8 < this->field_4C )
+      {
+        v9 = this->field_48;
+        v10 = pRenderer->uTargetSurfacePitch * v8;
+        do
+        {
+          v11 = this->field_40;
+          v18 = this->field_40;
+          if ( v11 < v9 )
+          {
+            v20 = &v17[v10 + v11];
+            do
+            {
+              //v12 = v20;
+              ++v18;
+              //++v20;
+              *v22++ = *v20++;
+            }
+            while ( v18 < v9 );
+          }
+          v10 += v16;
+          ++v8;
+        }
+        while ( v8 < this->field_4C );
+        v6 = v15;
+      }*/
+
+      if (pParty->pPickedItem.IsBroken())
+        pRenderer->DrawTransparentRedShade(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
+      else if (!pParty->pPickedItem.IsIdentified())
+        pRenderer->DrawTransparentGreenShade(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
+      else
+        pRenderer->DrawTextureTransparent(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
+    }
+  }
+  else
+  {
+    free(this->pCursorBitmap3_sysmembits_16bit);
+    this->pCursorBitmap3_sysmembits_16bit = nullptr;
+  }
+}
+
+//----- (0046A080) --------------------------------------------------------
+void Mouse::ChangeActivation(int a1)
+{
+  this->bActive = a1;
+}
+
+//----- (0046A08A) --------------------------------------------------------
+void Mouse::SetMouseClick(int x, int y)
+{
+  uMouseClickX = x;
+  uMouseClickY = y;
+}
+//----- (004175C0) --------------------------------------------------------
+void Mouse::UI_OnMouseLeftClick(int *pXY)
+{
+  signed int y; // eax@7
+  signed int x; // ecx@7
+  signed int v5; // eax@17
+  GUIButton *control; // esi@37
+  signed int v10; // eax@50
+//  int v11; // ecx@52
+  unsigned int pX; // [sp+14h] [bp-8h]@7
+  unsigned int pY; // [sp+18h] [bp-4h]@7
+
+  if ( pCurrentScreen == SCREEN_VIDEO || sub_4637E0_is_there_popup_onscreen() )
+    return;
+  if ( pGUIWindow2 && pGUIWindow2->ptr_1C == (void *)33 )
+  {
+    sub_4452BB();
+    return;
+  }
+  if ( pXY )
+  {
+    x = *pXY;
+    y = pXY[1];
+    pX = *pXY;
+    pY = y;
+  }
+  else
+  {
+    pMouse->GetClickPos(&pX, &pY);
+    y = pY;
+    x = pX;
+  }
+
+  extern bool _507B98_ctrl_pressed;
+  x = pX;
+  if ( GetCurrentMenuID() != -1 || pCurrentScreen != SCREEN_GAME || !_507B98_ctrl_pressed // stealing cursor
+      || (signed int)pX < (signed int)pViewport->uViewportTL_X || (signed int)pX > (signed int)pViewport->uViewportBR_X
+      || (signed int)pY < (signed int)pViewport->uViewportTL_Y || (signed int)pY > (signed int)pViewport->uViewportBR_Y)
+  {
+    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 )
+      {
+        for ( control = pWindowList[pVisibleWindowsIdxs[i] - 1].pControlsHead; control; control = control->pNext )
+        {
+          if ( control->uButtonType == 1 )
+          {
+            if ( x >= (signed int)control->uX && x <= (signed int)control->uZ && y >= (signed int)control->uY && y <= (signed int)control->uW )
+            {
+              control->field_2C_is_pushed = 1;
+              v10 = pMessageQueue_50CBD0->uNumMessages;
+              if ( pMessageQueue_50CBD0->uNumMessages )
+              {
+                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+              }
+              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
+              return;
+            }
+            continue;
+          }
+          if ( control->uButtonType == 2 )//êîãäà íàæèìàåøü íà ïàðòðåòû ïåðñîâ
+          {
+            if ( (signed int)(signed __int64)sqrt((double)((x - control->uX) * (x - control->uX) + (y - control->uY) * (y - control->uY))) < (signed int)control->uWidth )
+            {
+              control->field_2C_is_pushed = 1;
+              v10 = pMessageQueue_50CBD0->uNumMessages;
+              if ( pMessageQueue_50CBD0->uNumMessages )
+              {
+                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+              }
+              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
+              return;
+            }
+            continue;
+          }
+          if ( control->uButtonType == 3 )//êîãäà íàæèìàåøü íà ñêèëëû
+          {
+            if ( x >= (signed int)control->uX && x <= (signed int)control->uZ && y >= (signed int)control->uY && y <= (signed int)control->uW )
+            {
+              control->field_2C_is_pushed = 1;
+              v10 = pMessageQueue_50CBD0->uNumMessages;
+              if ( pMessageQueue_50CBD0->uNumMessages )
+              {
+                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
+              }
+              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
+              return;
+            }
+            continue;
+          }
+          y = pY;
+          x = pX;
+        }
+      }
+    }
+    return;
+  }
+  y = pY;
+  //if ( pRenderer->pRenderD3D )
+    v5 = pGame->pVisInstance->get_picked_object_zbuf_val();
+  /*else
+    v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];*/
+
+  uint type = PID_TYPE((unsigned __int16)v5);
+  if (type == OBJECT_Actor && uActiveCharacter && v5 < 0x2000000
+    && pPlayers[uActiveCharacter]->CanAct() && pPlayers[uActiveCharacter]->CanSteal() )
+  {
+    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
+    {
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_1B;
+      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v6 >> 3;
+      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
+      ++pMessageQueue_50CBD0->uNumMessages;
+    }*/
+    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_STEALFROMACTOR, PID_ID((unsigned __int16)v5), 0);
+
+    if ( pParty->bTurnBasedModeOn == 1 )
+    {
+      if ( pTurnEngine->turn_stage == TE_MOVEMENT )
+        pTurnEngine->field_18 |= TE_FLAG_8;
+    }
+  }
+}
+
+
+//----- (0041CD4F) --------------------------------------------------------
+bool Mouse::UI_OnKeyDown(unsigned int vkKey)
+{
+  //unsigned int v1; // edi@1
+  //unsigned int v2; // eax@2
+  int v3; // esi@3
+  int v4; // ecx@10
+  GUIButton *pButton; // eax@11
+  int v6; // edx@12
+  int v7; // ecx@20
+  char v8; // zf@21
+  //GUIButton *v9; // ecx@24
+  int v10; // esi@24
+  //int v11; // edx@26
+  int v12; // edx@28
+  int v13; // esi@32
+  //GUIButton *v14; // eax@37
+  int v15; // edx@38
+  int v17; // ecx@50
+  int v18; // edx@50
+  //GUIButton *v19; // ecx@54
+  int v20; // esi@54
+  //int v21; // edx@56
+  int v22; // ecx@59
+  int v23; // edx@59
+  int v24; // ecx@60
+  int v25; // esi@63
+  //unsigned int v26; // [sp+Ch] [bp-14h]@1
+  //int v27; // [sp+10h] [bp-10h]@1
+  int v28; // [sp+14h] [bp-Ch]@10
+  int v29; // [sp+14h] [bp-Ch]@36
+  unsigned int uClickX; // [sp+18h] [bp-8h]@10
+  unsigned int uClickY; // [sp+1Ch] [bp-4h]@10
+
+  //v1 = 0;
+  //v27 = uNumVisibleWindows;
+  if ( uNumVisibleWindows < 0 )
+    return false;
+  //v2 = pMessageQueue_50CBD0->uNumMessages;
+  for (int i = uNumVisibleWindows; i >= 0; --i)
+  //while ( 1 )
+  {
+    v3 = pVisibleWindowsIdxs[i] - 1;
+    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 )
+        {
+          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
+          pWindowList[v3].pCurrentPosActiveItem -= v12;
+          if ( v8 )
+          {
+            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
+            //v2 = pMessageQueue_50CBD0->uNumMessages;
+          }
+        }
+        if ( pWindowList[v3].field_30 != 0 )
+        {
+          break;
+        }
+        pButton = pWindowList[v3].pControlsHead;
+        v13 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v13 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v13;
+          }
+          while ( v13 );
+        }
+        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
+        break;
+      }
+      case VK_RIGHT:
+      {
+        v7 = pWindowList[v3].pCurrentPosActiveItem + pWindowList[v3].field_34;
+        if ( v7 < pWindowList[v3].pNumPresenceButton + pWindowList[v3].pStartingPosActiveItem )
+        {
+          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
+          pWindowList[v3].pCurrentPosActiveItem = v7;
+          if ( v8 )
+          {
+            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
+            //v2 = pMessageQueue_50CBD0->uNumMessages;
+          }
+        }
+        if ( pWindowList[v3].field_30 != 0 )
+        {
+          break;
+        }
+        pButton = pWindowList[v3].pControlsHead;
+        v10 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v10 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v10;
+          }
+          while ( v10 );
+        }
+        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
+        break;
+      }
+      case VK_DOWN:
+      {
+        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 )
+          return true;
+        pButton = pWindowList[v3].pControlsHead;
+        v20 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v20 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v20;
+          }
+          while ( v20 );
+        }
+        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
+        return true;
+      }
+      case VK_SELECT:
+      {
+        pMouse->GetClickPos(&uClickX, &uClickY);
+        v4 = pWindowList[v3].pStartingPosActiveItem;
+        v28 = v4 + pWindowList[v3].pNumPresenceButton;
+        if ( v4 < v4 + pWindowList[v3].pNumPresenceButton )
+        {
+          while ( 1 )
+          {
+            pButton = pWindowList[v3].pControlsHead;
+            if ( v4 > 0 )
+            {
+              v6 = v4;
+              do
+              {
+                pButton = pButton->pNext;
+                --v6;
+              }
+              while ( v6 );
+            }
+            if ( (signed int)uClickX >= (signed int)pButton->uX//test for StatsTab in PlayerCreation Window
+               && (signed int)uClickX <= (signed int)pButton->uZ
+               && (signed int)uClickY >= (signed int)pButton->uY
+               && (signed int)uClickY <= (signed int)pButton->uW )
+              break;
+            ++v4;
+            if ( v4 >= v28 )
+            {
+              //v1 = 0;
+              //v2 = pMessageQueue_50CBD0->uNumMessages;
+              //--i;
+              //if ( i < 0 )
+                return false;
+              //continue;
+            }
+          }
+          pWindowList[v3].pCurrentPosActiveItem = v4;
+          return true;
+        }
+        //v2 = pMessageQueue_50CBD0->uNumMessages;
+        break;
+      }
+      case VK_UP:
+      {
+        v22 = pWindowList[v3].pCurrentPosActiveItem;
+        v23 = pWindowList[v3].pStartingPosActiveItem;
+        if ( v22 <= v23 )
+          v24 = pWindowList[v3].pNumPresenceButton + v23 - 1;
+        else
+          v24 = v22 - 1;
+        v8 = pWindowList[v3].field_30 == 0;
+        pWindowList[v3].pCurrentPosActiveItem = v24;
+        if ( !v8 )
+          return true;
+        pButton = pWindowList[v3].pControlsHead;
+        v25 = pWindowList[v3].pCurrentPosActiveItem;
+        if ( v25 > 0)
+        {
+          do
+          {
+            pButton = pButton->pNext;
+            --v25;
+          }
+          while ( v25 );
+        }
+        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
+        return true;
+      }
+      case VK_NEXT:
+      {  
+        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 )
+          {
+            pButton = pWindowList[v3].pControlsHead;
+            if ( v4 > 0 )
+            {
+              for ( v15 = v4; v15; --v15 )
+                pButton = pButton->pNext;
+            }
+            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;
+              return true;
+            }
+          }
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IO/Mouse.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,150 @@
+#pragma once
+#include "OSWindow.h"
+
+#include "Engine/VectorTypes.h"
+
+
+
+/*  107 */
+#pragma pack(push, 1)
+class ThreadWard
+{
+public:
+  //----- (00438B0B) --------------------------------------------------------
+  inline ThreadWard()
+  {
+    InitializeCriticalSection(&csAsyncMouse);
+    InitializeCriticalSection(&cs2);
+    InitializeCriticalSection(&cs3);
+    InitializeCriticalSection(&csAsyncKeyboard);
+  }
+
+  //----- (00438B54) --------------------------------------------------------
+  virtual ~ThreadWard()
+  {
+  ThreadWard *v1; // esi@1
+
+  v1 = this;
+  //this->vdestructor_ptr = &ThreadWard_destructors;
+  DeleteCriticalSection(&this->csAsyncKeyboard);
+  DeleteCriticalSection(&v1->cs3);
+  DeleteCriticalSection(&v1->cs2);
+  DeleteCriticalSection(&v1->csAsyncMouse);
+  }
+
+  void ( ***vdestructor_ptr)(ThreadWard *, bool);
+  _RTL_CRITICAL_SECTION csAsyncMouse;
+  _RTL_CRITICAL_SECTION cs2;
+  _RTL_CRITICAL_SECTION cs3;
+  _RTL_CRITICAL_SECTION csAsyncKeyboard;
+};
+#pragma pack(pop)
+
+/*  106 */
+#pragma pack(push, 1)
+class Mouse
+{
+public:
+  //----- (00467E4E) --------------------------------------------------------
+  inline Mouse():
+    window(nullptr)
+  {
+    uCursorTextureID = 0;
+    uCursorTextureID_2 = 0;
+    pCursorBitmap_sysmem = nullptr;
+    field_34 = 0;
+    pCursorBitmap2_sysmem = nullptr;
+    pCursorBitmap3_sysmembits_16bit = nullptr;
+    ptr_90 = nullptr;
+    pWard = nullptr;
+    *pCurrentCursorName = NULL;
+    uMouseClickX = 0;
+    uMouseClickY = 0;
+  }
+
+  void GetClickPos(unsigned int *pX, unsigned int *pY);
+  void RemoveHoldingItem();
+  void SetCursorBitmapFromItemID(unsigned int uItemID);
+  void SetCurrentCursorBitmap();
+  void SetCursorBitmap(const char *pName);
+  LONG _469AE4();
+  void ClearCursor();
+  void AllocCursorSystemMem();
+  void *DoAllocCursorMem();
+  POINT *GetCursorPos(POINT *p);
+  void Initialize(OSWindow *window);
+  void SetActive(bool active);
+  void Deactivate();
+  void DrawCursor();
+  void Activate();
+  void _469E24();
+  void DrawCursorToTarget();
+  void ReadCursorWithItem();
+  void ChangeActivation(int a1);
+  void SetMouseClick(int x, int y);
+
+  static void UI_OnMouseLeftClick(int *pXY); // idb
+  static bool UI_OnKeyDown(unsigned int vkKey);
+
+
+  unsigned int uPointingObjectID;
+  unsigned int bActive;
+  int field_8;
+  int field_C;
+  unsigned int bInitialized;
+  unsigned int bRedraw;
+  int field_18;
+  int field_1C;
+  int field_20;
+  unsigned int uCursorTextureID;
+  unsigned int uCursorTextureID_2;
+  //HWND hWnd;
+  OSWindow *window;
+  unsigned __int16 *pCursorBitmap_sysmem;
+  int field_34;
+  unsigned __int8 *pCursorBitmap2_sysmem;
+  unsigned __int16 *pCursorBitmap3_sysmembits_16bit;
+  int uCursorWithItemX;
+  int uCursorWithItemY;
+  int uCursorWithItemW;
+  int uCursorWithItemZ;
+  int field_50;
+  int field_54;
+  int uCursorBitmapPitch;
+  int field_5C[13];
+  void *ptr_90;
+  int field_94;
+  int field_98;
+  int field_9C;
+  int field_A0;
+  int field_A4;
+  int field_A8;
+  int field_AC;
+  int field_B0;
+  int field_B4;
+  int field_B8;
+  int field_BC;
+  int field_C0;
+  Vec2_int_ pCursorBitmapPos;
+  int uCursorBitmapWidth;
+  int uCursorBitmapHeight;
+  int field_D4;
+  int field_D8;
+  int field_DC;
+  int field_E0;
+  Vec4_int_ pCursorBitmapRect;
+  char field_F4;
+  char pCurrentCursorName[11];
+  int field_100;
+  int field_104;
+  unsigned int uMouseClickX;
+  unsigned int uMouseClickY;
+  void/*ThreadWard*/ *pWard;
+};
+#pragma pack(pop)
+
+
+
+
+
+extern Mouse *pMouse;
\ No newline at end of file
--- a/Keyboard.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,840 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-#include "Keyboard.h"
-#include "GUIWindow.h"
-#include "Engine/Game.h"
-
-#include "Engine/Graphics/Vis.h"
-#include "Engine/MM7.h"
-#include "Engine/Objects/Actor.h"
-#include "Engine/Party.h"
-#include "Engine/Timer.h"
-#include "Engine/TurnEngine/TurnEngine.h"
-#include "Engine/Graphics/Weather.h"
-#include "Engine/Spells/CastSpellInfo.h"
-#include "Engine/Graphics/Indoor.h"
-#include "Engine/Registry.h"
-
-#include <tuple>
-#include <vector>
-#include <string>
-
-struct KeyboardActionMapping *pKeyActionMap;
-
-
-class CKeyListElement
-{
-public:
-  std::string m_keyName;
-  unsigned char m_keyDefaultCode;
-  unsigned short m_cmdId;
-  KeyToggleType m_toggType;
-  CKeyListElement(std::string keyName, unsigned char keyDefaultCode, unsigned short cmdId, KeyToggleType toggType):
-    m_keyName(keyName),
-    m_keyDefaultCode(keyDefaultCode),
-    m_cmdId(cmdId),
-    m_toggType(toggType)
-  {
-
-  }
-};
-
-std::array<CKeyListElement, 30>keyMappingParams = {
-  CKeyListElement("KEY_FORWARD", VK_UP, INPUT_MoveForward, TOGGLE_Continuously),
-  CKeyListElement("KEY_BACKWARD", VK_DOWN, INPUT_MoveBackwards, TOGGLE_Continuously),
-  CKeyListElement("KEY_LEFT", VK_LEFT, INPUT_TurnLeft, TOGGLE_Continuously),
-  CKeyListElement("KEY_RIGHT", VK_RIGHT, INPUT_TurnRight, TOGGLE_Continuously),
-  CKeyListElement("KEY_ATTACK", 'A', INPUT_Attack, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_CASTREADY", 'S', INPUT_CastReady, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_YELL", 'Y', INPUT_Yell, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_JUMP", 'X', INPUT_Jump, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_COMBAT", VK_RETURN, INPUT_Combat, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_EVENTTRIGGER", VK_SPACE, INPUT_EventTrigger, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_CAST", 'C', INPUT_Cast, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_PASS", 'B', INPUT_Pass, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_CHARCYCLE", VK_TAB, INPUT_CharCycle, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_QUEST", 'Q', INPUT_Quest, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_QUICKREF", 'Z', INPUT_QuickRef, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_REST", 'R', INPUT_Rest, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_TIMECAL", 'T', INPUT_TimeCal, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_AUTONOTES", 'N', INPUT_Autonotes, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_MAPBOOK", 'M', INPUT_Mapbook, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_LOOKUP", VK_NEXT, INPUT_LookUp, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_LOOKDOWN", VK_DELETE, INPUT_LookDown, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_CENTERVIEWPT", VK_END, INPUT_CenterView, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_ZOOMIN", VK_ADD, INPUT_ZoomIn, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_ZOOMOUT", VK_SUBTRACT, INPUT_ZoomOut, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_FLYUP", VK_PRIOR, INPUT_FlyUp, TOGGLE_Continuously),
-  CKeyListElement("KEY_FLYDOWN", VK_INSERT, INPUT_FlyDown, TOGGLE_Continuously),
-  CKeyListElement("KEY_LAND", VK_HOME, INPUT_Land, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_ALWAYSRUN", 'U', INPUT_AlwaysRun, TOGGLE_OneTimePress),
-  CKeyListElement("KEY_STEPLEFT", VK_OEM_4, INPUT_StrafeLeft, TOGGLE_Continuously),
-  CKeyListElement("KEY_STEPRIGHT", VK_OEM_6, INPUT_StrafeRight, TOGGLE_Continuously)
-}; 
-
-std::array<std::tuple<const char*, const unsigned __int8>, 26> keyNameToCodeTranslationMap =
-{
-  std::tuple<const char*, const unsigned __int8>("UP", VK_UP),
-  std::tuple<const char*, const unsigned __int8>("DOWN", VK_DOWN),
-  std::tuple<const char*, const unsigned __int8>("LEFT", VK_LEFT),
-  std::tuple<const char*, const unsigned __int8>("ÂËÅÂÎ", VK_LEFT),
-  std::tuple<const char*, const unsigned __int8>("RIGHT", VK_RIGHT),
-  std::tuple<const char*, const unsigned __int8>("ÂÏÐÀÂÎ", VK_RIGHT),
-  std::tuple<const char*, const unsigned __int8>("RETURN", VK_RETURN),
-  std::tuple<const char*, const unsigned __int8>("SPACE", VK_SPACE),
-  std::tuple<const char*, const unsigned __int8>("PAGE_DOWN", VK_NEXT),
-  std::tuple<const char*, const unsigned __int8>("PAGE_UP", VK_PRIOR),
-  std::tuple<const char*, const unsigned __int8>("TAB", VK_TAB),
-  std::tuple<const char*, const unsigned __int8>("SUBTRACT", VK_SUBTRACT),
-  std::tuple<const char*, const unsigned __int8>("ADD", VK_ADD),
-  std::tuple<const char*, const unsigned __int8>("END", VK_END),
-  std::tuple<const char*, const unsigned __int8>("DELETE", VK_DELETE),
-  std::tuple<const char*, const unsigned __int8>("HOME", VK_HOME),
-  std::tuple<const char*, const unsigned __int8>("INSERT", VK_INSERT),
-  std::tuple<const char*, const unsigned __int8>("COMMA", VK_OEM_COMMA),
-  std::tuple<const char*, const unsigned __int8>("DECIMAL", VK_DECIMAL),
-  std::tuple<const char*, const unsigned __int8>("SEMICOLON", VK_OEM_1),
-  std::tuple<const char*, const unsigned __int8>("PERIOD", VK_OEM_PERIOD),
-  std::tuple<const char*, const unsigned __int8>("SLASH", VK_OEM_2),
-  std::tuple<const char*, const unsigned __int8>("SQUOTE", VK_OEM_7),
-  std::tuple<const char*, const unsigned __int8>("BACKSLASH", VK_OEM_5),
-  std::tuple<const char*, const unsigned __int8>("BACKSPACE", VK_BACK),
-  std::tuple<const char*, const unsigned __int8>("CONTROL", VK_CONTROL),
-};
-
-//----- (00459C68) --------------------------------------------------------
-void KeyboardActionMapping::SetKeyMapping(int uAction, int vKey, KeyToggleType type)
-{
-  pVirtualKeyCodesMapping[uAction] = vKey;
-  pToggleTypes[uAction] = type;
-}
-
-//----- (00459C82) --------------------------------------------------------
-unsigned int KeyboardActionMapping::GetActionVKey(enum InputAction eAction)
-{
-  return this->pVirtualKeyCodesMapping[eAction];
-}
-
-//----- (00459C8D) --------------------------------------------------------
-KeyboardActionMapping::KeyboardActionMapping()
-{
-  uLastKeyPressed = 0;
-  field_204 = 0;
-  pWindow = nullptr;
-
-  SetDefaultMapping();
-  ReadMappings();
-
-  ResetKeys();
-
-  uNumKeysPressed = 0;
-
-  uGameMenuUI_CurentlySelectedKeyIdx = -1;
-}
-// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
-
-//----- (00459CC4) --------------------------------------------------------
-void KeyboardActionMapping::SetDefaultMapping()
-{
-  for ( size_t i = 0; i < keyMappingParams.size(); i++)
-  {
-    SetKeyMapping(keyMappingParams[i].m_cmdId, keyMappingParams[i].m_keyDefaultCode, keyMappingParams[i].m_toggType);
-  }
-}
-
-//----- (00459E3F) --------------------------------------------------------
-void KeyboardActionMapping::ResetKeys()
-{
-  for (uint i = 0; i < 30; ++i)
-    GetAsyncKeyState(pVirtualKeyCodesMapping[i]);
-}
-
-//----- (00459E5A) --------------------------------------------------------
-void KeyboardActionMapping::EnterText(int a2, int max_string_len, GUIWindow *pWindow)
-{
-  memset(this->pPressedKeysBuffer, 0, 0x101u);
-  this->uNumKeysPressed = 0;
-  if ( a2 )
-    this->field_204 = 2;
-  else
-    this->field_204 = 1;
-  this->max_input_string_len = max_string_len;
-  this->pWindow = pWindow;
-  pWindow->receives_keyboard_input_2 = WINDOW_INPUT_IN_PROGRESS;
-}
-
-//----- (00459ED1) --------------------------------------------------------
-void KeyboardActionMapping::SetWindowInputStatus(int a2)
-{
-  field_204 = 0;
-  if ( pWindow )
-    pWindow->receives_keyboard_input_2 = a2;
-}
-
-//----- (00459F10) --------------------------------------------------------
-bool KeyboardActionMapping::ProcessTextInput(unsigned int a2)
-{
-  pKeyActionMap->uLastKeyPressed = a2;
-  if ( uGameMenuUI_CurentlySelectedKeyIdx == -1 )
-  {
-    if ( pKeyActionMap->field_204 != 1 && pKeyActionMap->field_204 != 2 )
-      return 0;
-    if ( a2 == VK_BACK)
-    {
-      if (pKeyActionMap->uNumKeysPressed > 0)
-      {
-        --pKeyActionMap->uNumKeysPressed;
-        pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
-      }
-    }
-    else if ( a2 == VK_RETURN )
-      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
-    else if ( a2 == VK_ESCAPE )
-      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CANCELLED);
-    else if (this->uNumKeysPressed < this->max_input_string_len)
-    {
-      if ( pKeyActionMap->field_204 == 1 )
-      {
-        if ( a2 != VK_TAB )
-        {
-          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
-          ++pKeyActionMap->uNumKeysPressed;
-          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
-        }
-      }
-      else if (pKeyActionMap->field_204 == 2)
-      {
-        if ( isdigit(a2))
-        {
-          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
-          ++pKeyActionMap->uNumKeysPressed;
-        }
-      }
-    }
-  }
-  else
-  {
-    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
-    ++pKeyActionMap->uNumKeysPressed;
-    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
-    pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
-  }
-  return 1;
-}
-// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;
-
-//----- (00459FFC) --------------------------------------------------------
-void KeyboardActionMapping::ReadMappings()
-{
-  char str[32];
-
-  for (size_t i = 0; i < keyMappingParams.size(); i++)
-  {
-    const char* keyName = keyMappingParams[i].m_keyName.c_str();
-    short commandDefaultKeyCode = keyMappingParams[i].m_keyDefaultCode;
-    short commandId = keyMappingParams[i].m_cmdId;
-    KeyToggleType toggType = keyMappingParams[i].m_toggType;
-
-    ReadWindowsRegistryString(keyName, str, 32, "DEFAULT");
-    if ( strcmp(str, "DEFAULT") && ( TranslateKeyNameToKeyCode(str) != -1) )
-      pVirtualKeyCodesMapping[commandId] = TranslateKeyNameToKeyCode(str);
-    else
-      pVirtualKeyCodesMapping[commandId] = commandDefaultKeyCode;
-    pToggleTypes[commandId] = toggType;
-  }
-
-  bAlwaysRun = ReadWindowsRegistryInt("valAlwaysRun", 0) != 0;
-  bFlipOnExit = ReadWindowsRegistryInt("FlipOnExit", 0) != 0;
-}
-
-//----- (0045A960) --------------------------------------------------------
-void KeyboardActionMapping::StoreMappings()
-{
-
-  const char *v2; // eax@1
-
-  for ( size_t i = 0; i < keyMappingParams.size(); i++)
-  {
-    v2 = GetVKeyDisplayName(pVirtualKeyCodesMapping[keyMappingParams[i].m_cmdId]);
-    WriteWindowsRegistryString(keyMappingParams[i].m_keyName.c_str(), v2);
-  }
-}
-
-//----- (0045ABCA) --------------------------------------------------------
-const unsigned __int8 KeyboardActionMapping::TranslateKeyNameToKeyCode(const char *Str)
-{
-  if (strlen(Str) == 1)
-  {
-    if( Str[0] >= 65 && Str[0] <= 90 )
-      return *Str;
-    else
-      return 0xFF;
-  }
-
-  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
-  {
-    if (!strcmp(Str, std::get<0>(keyNameToCodeTranslationMap[i])))
-      return std::get<1>(keyNameToCodeTranslationMap[i]);
-  }
-  return 0xFF;
-}
-
-//----- (0045AE2C) --------------------------------------------------------
-const char * KeyboardActionMapping::GetVKeyDisplayName(unsigned char a1)
-{
-  static char static_sub_45AE2C_string_69ADE0_keyName[32];
-
-  if ( a1 >= 65 && a1 <= 90 )
-  {
-    static_sub_45AE2C_string_69ADE0_keyName[0] = a1;
-    static_sub_45AE2C_string_69ADE0_keyName[1] = '\0';
-    return static_sub_45AE2C_string_69ADE0_keyName;
-  }
-
-  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
-  {
-    if ( a1 == std::get<1>(keyNameToCodeTranslationMap[i]))
-    {
-      const char* keyName =  std::get<0>(keyNameToCodeTranslationMap[i]);
-      strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, keyName);
-      return static_sub_45AE2C_string_69ADE0_keyName;
-    }
-  }
-
-  strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, "-ÍÅÒ -");
-  return static_sub_45AE2C_string_69ADE0_keyName;
-}
-
-
-//----- (0045B019) --------------------------------------------------------
-void Keyboard::EnterCriticalSection()
-{
-}
-
-//----- (0045B06E) --------------------------------------------------------
-bool Keyboard::IsShiftHeld()
-{
-  return (GetAsyncKeyState(VK_SHIFT) & 0x8001) != 0;
-}
-
-//----- (0045B0A9) --------------------------------------------------------
-bool Keyboard::IsKeyBeingHeld(int vKey)
-{
-  return (GetAsyncKeyState(vKey) & 0x8001) != 0;
-}
-
-//----- (0045B0CE) --------------------------------------------------------
-bool Keyboard::WasKeyPressed(int vKey)
-{
-  return (GetAsyncKeyState(vKey) & 1) != 0;
-}
-//----- (0046A14B) --------------------------------------------------------
-void OnPressSpace()
-{
-
-  //if ( pRenderer->pRenderD3D )
-  {
-    pGame->PickKeyboard(Keyboard::IsKeyBeingHeld(VK_CONTROL), &vis_sprite_filter_3, &vis_door_filter);
-    int pid = pGame->pVisInstance->get_picked_object_zbuf_val();
-    if ( pid != -1 )
-      DoInteractionWithTopmostZObject(pid & 0xFFFF, PID_ID(pid));
-    return;
-  }
-
-  
-  // software render stuff following
-  /*
-  static int dword_720660[100]; // 720660
-  static int dword_7207F0[100]; // 7207F0
-
-  v22 = 0;
-  v1 = (int *)((signed int)(viewparams->uScreen_BttmR_X + viewparams->uScreen_topL_X) >> 1);//wrong pointer
-  if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
-  {
-	  v2 = (char *)v1 - 50;
-	  v1 = (int *)((char *)v1 + 50);
-	  v3 = 640 * viewparams->uScreen_topL_Y;
-	  v17 = v2;
-	  v20 = v1;
-	  v18 = ((viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y - 1) >> 1) + 1;
-	  do
-	  {
-		if ( (signed int)v2 < (signed int)v20 )
-		{
-			v1 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
-			v21 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
-			v4 = v22;
-			v5 = (((char *)v20 - v2 - 1) >> 1) + 1;
-			do
-			{
-			  v6 = 0;
-			  v7 = *v1 & 0xFFFF;
-			  v19 = 0;
-			  if ( v4 > 0 )
-			  {
-				do
-				{
-				  if ( dword_7207F0[v6] == v7 )
-					break;
-				  ++v6;
-				  v19 = v6;
-				}
-				while ( v6 < v22 );
-			  }
-			  if ( PID_TYPE(v7) == OBJECT_Decoration)
-			  {
-				v16 = (unsigned int)PID_ID(v7);
-				if ( (signed int)(((unsigned int)*v21 >> 16)
-								- pDecorationList->pDecorations[pLevelDecorations[(unsigned int)PID_ID(v7)].uDecorationDescID].uRadius) <= 512 )
-				  if ( v19 == v22 && v4 < 100 )
-				  {
-					++v22;
-					++v4;
-					v8 = *v21;
-					dword_7207F0[v4 - 1] = v7;
-					dword_720660[v4 - 1] = v8;
-				  }
-			  }
-			  else if ( (unsigned int)*v21 <= 0x2000000 )
-			  {
-				  if ( v19 == v22 && v4 < 100 )
-				  {
-					++v22;
-					++v4;
-					v8 = *v21;
-					dword_7207F0[v4 - 1] = v7;
-					dword_720660[v4 - 1] = v8;
-				  }
-			  }
-			  v1 = v21 + 2;
-			  --v5;
-			  v21 += 2;
-			}
-			while ( v5 );
-			v2 = v17;
-		}
-		v3 += 1280;
-		--v18;
-	  }
-	  while ( v18 );
-  }
-  if ( v22 > 0 )
-  {
-    v9 = dword_720660;
-    v10 = 1;
-    do
-    {
-      for ( i = v10; i < v22; ++i )
-      {
-        v12 = *v9;
-        v13 = dword_720660[i];
-        if ( v13 < *v9 )
-        {
-          *v9 = v13;
-          dword_720660[i] = v12;
-        }
-      }
-      ++v10;
-      ++v9;
-      LOBYTE(v1) = v10 - 1;
-    }
-    while ( v10 - 1 < v22 );
-  }
-  for ( j = 0; j < v22; ++j )
-  {
-    LOBYTE(v1) = DoInteractionWithTopmostZObject(dword_720660[j] & 0xFFFF, v16);
-    if ( !(char)v1 )
-      break;
-  }*/
-}
-
-
-//----- (0042FC4E) --------------------------------------------------------
-void Keyboard::ProcessInputActions()
-{
-  char v4; // al@9
-  unsigned __int16 v9; // ax@102
-  int spell_price; // eax@103
-  PartyAction partyAction; // [sp-14h] [bp-1Ch]@20
-  InputAction inputAction; // [sp+0h] [bp-8h]@7
-
-  pGame->pKeyboardInstance->EnterCriticalSection();
-  Keyboard* pKeyboard = pGame->pKeyboardInstance;
-  if (!bAlwaysRun)
-  {
-    if (pKeyboard->IsShiftHeld())
-      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-    else
-      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
-   }
-  else
-  {
-    if (pKeyboard->IsShiftHeld())
-      pParty->uFlags2 &= ~PARTY_FLAGS_2_RUNNING;
-    else
-      pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-  }
-
-  //pParty->uFlags2 |= PARTY_FLAGS_2_RUNNING;
-
-
-    //  WUT? double event trigger
-  /*for ( uint i = 0; i < 30; ++i )
-  {
-    if ( pKeyActionMap->pToggleTypes[i] )
-      v14 = pGame->pKeyboardInstance->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[i]);
-    else
-      v14 = pGame->pKeyboardInstance->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[i]);
-    if ( v14 )
-    {
-      if (pCurrentScreen == SCREEN_GAME)
-      {
-        pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Game_Action, 0, 0);
-        continue;
-      }
-      if ( pCurrentScreen == SCREEN_NPC_DIALOGUE || pCurrentScreen == SCREEN_BRANCHLESS_NPC_DIALOG )
-      {
-        v15 = pMessageQueue_50CBD0->uNumMessages;
-        if ( pMessageQueue_50CBD0->uNumMessages )
-        {
-          v15 = 0;
-          if ( pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 )
-          {
-            v15 = 1;
-            pMessageQueue_50CBD0->uNumMessages = 0;
-            pMessageQueue_50CBD0->pMessages[v15].eType = UIMSG_Escape;
-            pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-            *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-            ++pMessageQueue_50CBD0->uNumMessages;
-            continue;
-          }
-          pMessageQueue_50CBD0->uNumMessages = 0;
-        }
-        //pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-      }
-    }
-  }*/
-  if ( !pEventTimer->bPaused )
-  {
-    for ( uint i = 0; i < 30; ++i )
-    {
-      inputAction = (InputAction)i;
-      if ( pKeyActionMap->pToggleTypes[inputAction] )
-        v4 = pKeyboard->WasKeyPressed(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
-      else
-        v4 = pKeyboard->IsKeyBeingHeld(pKeyActionMap->pVirtualKeyCodesMapping[inputAction]);
-      if ( v4 )
-      {
-        switch ( inputAction )
-        {
-          case INPUT_MoveForward:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
-                partyAction = PARTY_RunForward;
-              else
-                partyAction = PARTY_WalkForward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if (pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
-            {
-              pTurnEngine->uActionPointsLeft -= 26;
-              if ( pParty->uFlags2 & PARTY_FLAGS_2_RUNNING)
-                partyAction = PARTY_RunForward;
-              else
-                partyAction = PARTY_WalkForward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            break;
-          case INPUT_MoveBackwards:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_RunBackward;
-              else
-                partyAction = PARTY_WalkBackward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage != TE_WAIT && pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->uActionPointsLeft > 0 )
-            {
-              pTurnEngine->uActionPointsLeft -= 26;
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_RunBackward;
-              else
-                partyAction = PARTY_WalkBackward;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            break;
-          case INPUT_StrafeLeft:
-            if (pCurrentScreen  != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              partyAction = PARTY_StrafeLeft;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-              break;
-            pTurnEngine->uActionPointsLeft -= 26;
-            partyAction = PARTY_StrafeLeft;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_StrafeRight:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if (!pParty->bTurnBasedModeOn)
-            {
-              partyAction = PARTY_StrafeRight;
-              pPartyActionQueue->Add(partyAction);
-              break;
-            }
-            if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-              break;
-            pTurnEngine->uActionPointsLeft -= 26;
-            partyAction = PARTY_StrafeRight;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_TurnLeft:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if ( GetAsyncKeyState(VK_CONTROL) ) // strafing
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-                  break;
-                pTurnEngine->uActionPointsLeft -= 26;
-              }
-              partyAction = PARTY_StrafeLeft;
-            }
-            else
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_FastTurnLeft;
-              else
-                partyAction = PARTY_TurnLeft;
-            }
-            pPartyActionQueue->Add(partyAction);
-            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
-              pWeather->OnPlayerTurn(10);
-            break;
-          case INPUT_TurnRight:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if ( GetAsyncKeyState(VK_CONTROL) )         // strafing
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if ( pTurnEngine->turn_stage == TE_WAIT || pTurnEngine->turn_stage == TE_ATTACK || pTurnEngine->uActionPointsLeft <= 0 )
-                  break;
-                pTurnEngine->uActionPointsLeft -= 26;
-              }
-              partyAction = PARTY_StrafeRight;
-            }
-            else
-            {
-              if ( pParty->uFlags2 & 2 )
-                partyAction = PARTY_FastTurnRight;
-              else
-                partyAction = PARTY_TurnRight;
-            }
-            pPartyActionQueue->Add(partyAction);
-            if (uCurrentlyLoadedLevelType == LEVEL_Outdoor && pWeather->bRenderSnow)
-              pWeather->OnPlayerTurn(-10);
-            break;
-          case INPUT_Jump:
-            if (pCurrentScreen != SCREEN_GAME || pParty->bTurnBasedModeOn)
-              break;
-            partyAction = (PartyAction)12;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_Yell:
-            if (!pCurrentScreen && uActiveCharacter)
-            {
-              pParty->Yell();
-              pPlayers[uActiveCharacter]->PlaySound(SPEECH_Yell, 0);
-            }
-          break;
-          case INPUT_Pass:
-            if ( pCurrentScreen )
-              break;
-            if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
-            {
-              pTurnEngine->field_18 |= TE_FLAG_8;
-              break;
-            }
-            if ( uActiveCharacter )
-            {
-              if ( !pPlayers[uActiveCharacter]->uTimeToRecovery )
-              {
-                if ( !pParty->bTurnBasedModeOn )
-                  pPlayers[uActiveCharacter]->SetRecoveryTime((signed __int64)(flt_6BE3A4_debug_recmod1 * (double)pPlayers[uActiveCharacter]->GetAttackRecoveryTime(false) * 2.133333333333333));
-                CastSpellInfoHelpers::_427D48();
-                pTurnEngine->ApplyPlayerAction();
-              }
-            }
-            break;
-          case INPUT_Combat://if press ENTER
-            if (pCurrentScreen == SCREEN_GAME)
-            {
-              if (pParty->bTurnBasedModeOn)
-              {
-                if (pTurnEngine->turn_stage == TE_MOVEMENT || PID_TYPE(pTurnEngine->pQueue[0].uPackedID) == OBJECT_Player)
-                {
-                  pParty->bTurnBasedModeOn = 0;
-                  pTurnEngine->End(true);
-                }
-              }
-              else
-              {
-                pTurnEngine->Start();
-                pParty->bTurnBasedModeOn = true;
-              }
-            }
-            break;
-          case INPUT_CastReady:
-            {
-              if (pCurrentScreen != SCREEN_GAME)
-                break;
-              if (pParty->bTurnBasedModeOn && pTurnEngine->turn_stage == TE_MOVEMENT)
-              {
-                pTurnEngine->field_18 |= TE_FLAG_8;
-                break;
-              }
-              if ( !uActiveCharacter )
-                break;
-              uchar quickSpellNumber = pPlayers[uActiveCharacter]->uQuickSpell;
-              v9 = pPlayers[uActiveCharacter]->pActiveSkills[quickSpellNumber / 11 + 12];
-              bool enoughMana = false;
-              if ((v9 & 0x100) != 0)
-              {
-                enoughMana = pSpellDatas[quickSpellNumber].uMagisterLevelMana < pPlayers[uActiveCharacter]->sMana;
-              }
-              else if ((v9 & 0x80) != 0)
-              {
-                enoughMana = pSpellDatas[quickSpellNumber].uMasterLevelMana < pPlayers[uActiveCharacter]->sMana;
-              }
-              else if ((v9 & 0x40) != 0)
-              {
-                enoughMana = pSpellDatas[quickSpellNumber].uExpertLevelMana < pPlayers[uActiveCharacter]->sMana;
-              }
-              else
-              {
-                enoughMana = pSpellDatas[quickSpellNumber].uNormalLevelMana < pPlayers[uActiveCharacter]->sMana;
-              }
-              if ( !pPlayers[uActiveCharacter]->uQuickSpell || bUnderwater || !enoughMana)
-              {
-                pPartyActionQueue = pPartyActionQueue;
-                pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
-                break;
-              }
-              else
-                pMessageQueue_50C9E8->AddGUIMessage(UIMSG_CastQuickSpell, 0, 0);
-            }
-            break;
-          case INPUT_Attack:
-            if (pCurrentScreen != SCREEN_GAME)
-              break;
-            if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT)
-            {
-              pTurnEngine->field_18 |= TE_FLAG_8;
-              break;
-            }
-            pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Attack, 0, 0);
-            break;
-          case INPUT_EventTrigger:
-            if (pCurrentScreen == SCREEN_GAME)
-            {
-              pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Game_Action, 0, 0);
-              break;
-            }
-            if ( pCurrentScreen == SCREEN_NPC_DIALOGUE )
-            {
-              if ( pMessageQueue_50CBD0->uNumMessages )
-              {
-                pMessageQueue_50CBD0->uNumMessages = 0;
-                if ( pMessageQueue_50CBD0->pMessages[0].field_8 )
-                {
-                  pMessageQueue_50CBD0->uNumMessages = 1;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_Escape;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = 0;
-                  pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].field_8 = 0;
-                  ++pMessageQueue_50CBD0->uNumMessages;
-                  break;
-                }
-                break;
-              }
-              pMessageQueue_50CBD0->AddGUIMessage(UIMSG_Escape, 0, 0);
-            }
-            break;
-          case INPUT_CharCycle:
-            if ( pCurrentScreen == SCREEN_SPELL_BOOK  )
-              break;
-
-            pMessageQueue_50C9E8->AddGUIMessage(UIMSG_CycleCharacters, 0, 0);
-            break;
-          case INPUT_LookUp:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)7;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_CenterView:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)9;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_LookDown:
-            if ( pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)8;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_FlyUp:
-            if ( pCurrentScreen || pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)13;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_Land:
-            if ( pCurrentScreen || pEventTimer->bPaused )
-              break;
-            partyAction = (PartyAction)15;
-            pPartyActionQueue->Add(partyAction);
-            break;
-          case INPUT_FlyDown:
-            if ( !pCurrentScreen && !pEventTimer->bPaused )
-            {
-              partyAction = (PartyAction)14;
-              pPartyActionQueue->Add(partyAction);
-            }
-            break;
-          case INPUT_ZoomIn:
-              pMessageQueue_50C9E8->AddGUIMessage(UIMSG_ClickZoomOutBtn, 0, 0);
-            break;
-          case INPUT_ZoomOut:
-              pMessageQueue_50C9E8->AddGUIMessage(UIMSG_ClickZoomInBtn, 0, 0);
-            break;
-          case INPUT_AlwaysRun:
-            bAlwaysRun = bAlwaysRun == 0;
-            break;
-          default:
-            break;
-        }
-      }
-    }
-  }
-}
--- a/Keyboard.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-#pragma once
-
-
-/*  284 */
-enum InputAction : __int32
-{
-  INPUT_MoveForward = 0x0,
-  INPUT_MoveBackwards = 0x1,
-  INPUT_TurnLeft = 0x2,
-  INPUT_TurnRight = 0x3,
-  INPUT_Yell = 0x4,
-  INPUT_Jump = 0x5,
-  INPUT_Combat = 0x6,
-  INPUT_CastReady = 0x7,
-  INPUT_Attack = 0x8,
-  INPUT_EventTrigger = 0x9,
-  INPUT_Cast = 0xA,
-  INPUT_Pass = 0xB,
-  INPUT_CharCycle = 0xC,
-  INPUT_Quest = 0xD,
-  INPUT_QuickRef = 0xE,
-  INPUT_Rest = 0xF,
-  INPUT_TimeCal = 0x10,
-  INPUT_Autonotes = 0x11,
-  INPUT_Mapbook = 0x12,
-  INPUT_AlwaysRun = 0x13,
-  INPUT_LookUp = 0x14,
-  INPUT_LookDown = 0x15,
-  INPUT_CenterView = 0x16,
-  INPUT_ZoomIn = 0x17,
-  INPUT_ZoomOut = 0x18,
-  INPUT_FlyUp = 0x19,
-  INPUT_FlyDown = 0x1A,
-  INPUT_Land = 0x1B,
-  INPUT_StrafeLeft = 0x1C,
-  INPUT_StrafeRight = 0x1D,
-};
-
-
-
-enum KeyToggleType : __int32
-{
-  TOGGLE_Continuously = 0x0,
-  TOGGLE_OneTimePress = 0x1,
-};
-
-#pragma pack(push, 1)
-struct KeyboardActionMapping
-{
-  KeyboardActionMapping();
-
-  void SetKeyMapping(int uAction, int vKey, KeyToggleType type);
-  unsigned int GetActionVKey(enum InputAction eAction);
-  const char *GetVKeyDisplayName(unsigned char a1);
-  const unsigned __int8 TranslateKeyNameToKeyCode(const char *Str);
-  void ReadMappings();
-  void StoreMappings();
-  bool ProcessTextInput(unsigned int a2);
-  void SetWindowInputStatus(int a2);
-  void EnterText(int a2, int max_string_len, struct GUIWindow *pWindow);
-  void ResetKeys();
-  void SetDefaultMapping();
-
-  unsigned int uLastKeyPressed;
-  int field_4;
-  int field_8;
-  unsigned int pVirtualKeyCodesMapping[30];
-  KeyToggleType pToggleTypes[30];
-  int max_input_string_len;
-  __int8 pPressedKeysBuffer[257];
-  unsigned __int8 uNumKeysPressed;
-  char field_202;
-  char field_203;
-  int field_204;
-  struct GUIWindow *pWindow;
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
-class Keyboard
-{
-public:
-  inline Keyboard():
-    bUsingAsynKeyboard(false)
-  {}
-  bool WasKeyPressed(int vKey);
-  static bool IsKeyBeingHeld(int vKey);
-  static void ProcessInputActions();
-  bool IsShiftHeld();
-  void EnterCriticalSection();
-
-  void ( ***vdestructor_ptr)(Keyboard *, bool);
-  unsigned int bUsingAsynKeyboard;
-};
-#pragma pack(pop)
-
-
-
-void OnPressSpace();
-
-extern struct KeyboardActionMapping *pKeyActionMap;
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Audio/AIL.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,402 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "AIL.h"
+
+
+
+
+int (__stdcall *mss32_AIL_startup)() = 0;
+HREDBOOK (__stdcall *mss32_AIL_redbook_open_drive)(long) = 0;
+int (__stdcall *mss32_AIL_set_preference)(unsigned int, int) = 0;
+int (__stdcall *mss32_AIL_waveOutOpen)(HDIGDRIVER *, HWAVEOUT *, int, WAVEFORMAT *) = 0;
+int (__stdcall *mss32_AIL_get_preference)(unsigned int) = 0;
+int (__stdcall *mss32_AIL_digital_configuration)(HDIGDRIVER, int *, int *, char *) = 0;
+HSAMPLE (__stdcall *mss32_AIL_allocate_sample_handle)(HDIGDRIVER) = 0;
+void (__stdcall *mss32_AIL_3D_provider_attribute)(HPROVIDER, char *, void *) = 0;
+unsigned int (__stdcall *mss32_AIL_redbook_tracks)(HREDBOOK) = 0;
+int (__stdcall *mss32_AIL_redbook_volume)(HREDBOOK) = 0;
+unsigned int (__stdcall *mss32_AIL_redbook_stop)(HREDBOOK) = 0;
+void (__stdcall *mss32_AIL_set_digital_master_volume)(HDIGDRIVER, float) = 0;
+int (__stdcall *mss32_AIL_redbook_set_volume)(HREDBOOK, int) = 0;
+void (__stdcall *mss32_AIL_waveOutClose)(HDIGDRIVER) = 0;
+unsigned int (__stdcall *mss32_AIL_redbook_pause)(HREDBOOK) = 0;
+void (__stdcall *mss32_AIL_redbook_track_info)(HREDBOOK, unsigned int, unsigned int *, unsigned int *) = 0;
+unsigned int (__stdcall *mss32_AIL_redbook_play)(HREDBOOK, unsigned int, unsigned int) = 0;
+unsigned int (__stdcall *mss32_AIL_redbook_resume)(HREDBOOK) = 0;
+AIL::Sample::Status (__stdcall *mss32_AIL_sample_status)(HSAMPLE) = 0;
+int (__stdcall *mss32_AIL_sample_volume)(HSAMPLE) = 0;
+int (__stdcall *mss32_AIL_enumerate_3D_providers)(int *, HPROVIDER *, char **) = 0;
+DWORD (__stdcall *mss32_AIL_open_3D_provider)(HPROVIDER) = 0;
+int (__stdcall *mss32_AIL_end_sample)(HSAMPLE) = 0;
+int (__stdcall *mss32_AIL_set_sample_volume)(HSAMPLE, long) = 0;
+int (__stdcall *mss32_AIL_set_sample_pan)(HSAMPLE, long) = 0;
+void (__stdcall *mss32_AIL_end_sequence)(HSEQUENCE) = 0;
+void (__stdcall *mss32_AIL_pause_stream)(HSTREAM, int) = 0;
+void (__stdcall *mss32_AIL_init_sample)(HSAMPLE) = 0;
+int (__stdcall *mss32_AIL_set_sample_file)(HSAMPLE, const void *, int) = 0;
+void (__stdcall *mss32_AIL_set_sample_loop_count)(HSAMPLE, int) = 0;
+void (__stdcall *mss32_AIL_set_sample_playback_rate)(HSAMPLE, int) = 0;
+void (__stdcall *mss32_AIL_sample_ms_position)(HSAMPLE, int *, int *) = 0;
+int (__stdcall *mss32_AIL_start_sample)(HSAMPLE) = 0;
+AILFILETYPE (__stdcall *mss32_AIL_file_type)(void *, int) = 0;
+int (__stdcall *mss32_AIL_WAV_info)(void *, AILSOUNDINFO *) = 0;
+int (__stdcall *mss32_AIL_decompress_ADPCM)(AILSOUNDINFO *, void *, void *) = 0;
+HREDBOOK (__stdcall *mss32_AIL_redbook_open)(int) = 0;
+void (__stdcall *mss32_AIL_release_sample_handle)(HSAMPLE) = 0;
+void MSS32_DLL_Initialize()
+{
+ HMODULE pDll = LoadLibraryW(L"mss32.dll");
+
+ mss32_AIL_startup = (int (__stdcall *)())GetProcAddress(pDll, "_AIL_startup@0");
+ mss32_AIL_redbook_open_drive = (HREDBOOK (__stdcall *)(long))GetProcAddress(pDll, "_AIL_redbook_open_drive@4");
+ mss32_AIL_set_preference = (int (__stdcall *)(unsigned int, int))GetProcAddress(pDll, "_AIL_set_preference@8");
+ mss32_AIL_waveOutOpen = (int (__stdcall *)(HDIGDRIVER *, HWAVEOUT *, int, WAVEFORMAT *))GetProcAddress(pDll, "_AIL_waveOutOpen@16");
+ mss32_AIL_get_preference = (int (__stdcall *)(unsigned int))GetProcAddress(pDll, "_AIL_get_preference@4");
+ mss32_AIL_digital_configuration = (int (__stdcall *)(HDIGDRIVER, int *, int *, char *))GetProcAddress(pDll, "_AIL_digital_configuration@16");
+ mss32_AIL_allocate_sample_handle = (HSAMPLE (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_AIL_allocate_sample_handle@4");
+ mss32_AIL_3D_provider_attribute = (void (__stdcall *)(HPROVIDER,char *, void *))GetProcAddress(pDll, "_AIL_3D_provider_attribute@12");
+ mss32_AIL_redbook_tracks = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_tracks@4");
+ mss32_AIL_redbook_volume = (int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_volume@4");
+ mss32_AIL_redbook_stop = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_stop@4");
+ mss32_AIL_set_digital_master_volume = (void (__stdcall *)(HDIGDRIVER, float))GetProcAddress(pDll, "_AIL_set_digital_master_volume@8");
+ mss32_AIL_redbook_set_volume = (int (__stdcall *)(HREDBOOK, int))GetProcAddress(pDll, "_AIL_redbook_set_volume@8");
+ mss32_AIL_waveOutClose = (void (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_AIL_waveOutClose@4");
+ mss32_AIL_redbook_pause = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_pause@4");
+ mss32_AIL_redbook_track_info = (void (__stdcall *)(HREDBOOK, unsigned int, unsigned int *, unsigned int *))GetProcAddress(pDll, "_AIL_redbook_track_info@16");
+ mss32_AIL_redbook_play = (unsigned int (__stdcall *)(HREDBOOK, unsigned int, unsigned int))GetProcAddress(pDll, "_AIL_redbook_play@12");
+ mss32_AIL_redbook_resume = (unsigned int (__stdcall *)(HREDBOOK))GetProcAddress(pDll, "_AIL_redbook_resume@4");
+ mss32_AIL_sample_status = (AIL::Sample::Status (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_sample_status@4");
+ mss32_AIL_sample_volume = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_sample_volume@4");
+ mss32_AIL_enumerate_3D_providers = (int (__stdcall *)(int *, HPROVIDER *, char **))GetProcAddress(pDll, "_AIL_enumerate_3D_providers@12");
+ mss32_AIL_open_3D_provider = (DWORD (__stdcall *)(HPROVIDER))GetProcAddress(pDll, "_AIL_open_3D_provider@4");
+ mss32_AIL_end_sample = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_end_sample@4");
+ mss32_AIL_set_sample_volume = (int (__stdcall *)(HSAMPLE, long))GetProcAddress(pDll, "_AIL_set_sample_volume@8");
+ mss32_AIL_set_sample_pan = (int (__stdcall *)(HSAMPLE, long))GetProcAddress(pDll, "_AIL_set_sample_pan@8");
+ mss32_AIL_end_sequence = (void (__stdcall *)(HSEQUENCE))GetProcAddress(pDll, "_AIL_end_sequence@4");
+ mss32_AIL_pause_stream = (void (__stdcall *)(HSTREAM, int))GetProcAddress(pDll, "_AIL_pause_stream@8");
+ mss32_AIL_init_sample = (void (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_init_sample@4");
+ mss32_AIL_set_sample_file = (int (__stdcall *)(HSAMPLE, const void *, int))GetProcAddress(pDll, "_AIL_set_sample_file@12");
+ mss32_AIL_set_sample_loop_count = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_loop_count@8");
+ mss32_AIL_set_sample_playback_rate = (void (__stdcall *)(HSAMPLE, int))GetProcAddress(pDll, "_AIL_set_sample_playback_rate@8");
+ mss32_AIL_sample_ms_position = (void (__stdcall *)(HSAMPLE, int *, int *))GetProcAddress(pDll, "_AIL_sample_ms_position@12");
+ mss32_AIL_start_sample = (int (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_start_sample@4");
+ mss32_AIL_file_type = (AILFILETYPE (__stdcall *)(void *, int))GetProcAddress(pDll, "_AIL_file_type@8");
+ mss32_AIL_WAV_info = (int (__stdcall *)(void *, AILSOUNDINFO *))GetProcAddress(pDll, "_AIL_WAV_info@8");
+ mss32_AIL_decompress_ADPCM = (int (__stdcall *)(AILSOUNDINFO *, void *, void *))GetProcAddress(pDll, "_AIL_decompress_ADPCM@12");
+ mss32_AIL_redbook_open = (HREDBOOK (__stdcall *)(int))GetProcAddress(pDll, "_AIL_redbook_open@4");
+ mss32_AIL_release_sample_handle = (void (__stdcall *)(HSAMPLE))GetProcAddress(pDll, "_AIL_release_sample_handle@4");
+}
+
+
+
+unsigned int __stdcall AIL_redbook_play(HREDBOOK hRedbook, unsigned int uStartMS, unsigned int uEndMS)
+{
+ return (mss32_AIL_redbook_play)(hRedbook, uStartMS, uEndMS);
+}
+
+void __stdcall AIL_redbook_track_info(HREDBOOK hRedbook, unsigned int uTrackNum, unsigned int *pStartMS, unsigned int *pEndMS)
+{
+ (mss32_AIL_redbook_track_info)(hRedbook, uTrackNum, pStartMS, pEndMS);
+}
+
+unsigned int __stdcall AIL_redbook_resume(HREDBOOK hRedbook)
+{
+ return (mss32_AIL_redbook_resume)(hRedbook);
+}
+
+int __stdcall AIL_enumerate_3D_providers(int *a1, HPROVIDER *pOutProv, char **pOutName)
+{
+ return (mss32_AIL_enumerate_3D_providers)(a1, pOutProv, pOutName);
+}
+HREDBOOK __stdcall AIL_redbook_open(int w)
+{
+ return (mss32_AIL_redbook_open)(w);
+}
+
+
+int __stdcall AIL_sample_volume(HSAMPLE s)
+{
+ return (mss32_AIL_sample_volume)(s);
+}
+
+AIL::Sample::Status __stdcall AIL_sample_status(HSAMPLE a1)
+{
+ return (mss32_AIL_sample_status)(a1);
+}
+
+// sub_4D8304: using guessed type int __stdcall AIL_set_digital_master_volume(_DWORD, _DWORD);
+void __stdcall AIL_set_digital_master_volume(HDIGDRIVER hDrv, float master_volume)
+{
+ (mss32_AIL_set_digital_master_volume)(hDrv, master_volume);
+}
+
+// sub_4D8370: using guessed type int __stdcall AIL_allocate_sample_handle(_DWORD);
+HSAMPLE __stdcall AIL_allocate_sample_handle(HDIGDRIVER hDrv)
+{
+ return (mss32_AIL_allocate_sample_handle)(hDrv);
+}
+
+// sub_4D8308: using guessed type int __fastcall AIL_redbook_set_volume(_DWORD, _DWORD, _DWORD, _DWORD);
+int __stdcall AIL_redbook_set_volume(HREDBOOK hRedbook, int volume)
+{
+ return (mss32_AIL_redbook_set_volume)(hRedbook, volume);
+}
+
+// sub_4D8324: using guessed type int __stdcall AIL_redbook_stop(_DWORD);
+unsigned int __stdcall AIL_redbook_stop(HREDBOOK hRedbook)
+{
+ return (mss32_AIL_redbook_stop)(hRedbook);
+}
+
+// sub_4D835C: using guessed type int __stdcall AIL_startup();
+int __stdcall AIL_startup()
+{
+ return (mss32_AIL_startup)();
+}
+
+// sub_4D8360: using guessed type int __stdcall AIL_redbook_open_drive(_DWORD);
+HREDBOOK __stdcall AIL_redbook_open_drive(long drive)
+{
+ return (mss32_AIL_redbook_open_drive)(drive);
+}
+
+// sub_4D834C: using guessed type int __stdcall AIL_waveOutOpen(_DWORD, _DWORD, _DWORD, _DWORD);
+int __stdcall AIL_waveOutOpen(_DIG_DRIVER **drv, HWAVEOUT *phWaveOut, int wDeviceID, WAVEFORMAT *pFormat)
+{
+ return (mss32_AIL_waveOutOpen)(drv, phWaveOut, wDeviceID, pFormat);
+}
+
+
+DWORD __stdcall AIL_open_3D_provider(HPROVIDER a2)
+{
+ return (mss32_AIL_open_3D_provider)(a2);
+}
+
+void __stdcall AIL_3D_provider_attribute(HPROVIDER lib, char *name, void *val)
+{ 
+ (mss32_AIL_3D_provider_attribute)(lib,name,val);
+}
+
+// sub_4D8374: using guessed type int __stdcall AIL_redbook_tracks(_DWORD);
+unsigned int __stdcall AIL_redbook_tracks(HREDBOOK hRedbook)
+{
+ return (mss32_AIL_redbook_tracks)(hRedbook);
+}
+
+// sub_4D83B0: using guessed type int __stdcall AIL_redbook_volume(_DWORD);
+int __stdcall AIL_redbook_volume(HREDBOOK hRedbook)
+{
+ return (mss32_AIL_redbook_volume)(hRedbook);
+}
+
+// sub_4D8348: using guessed type int __stdcall AIL_set_preference(_DWORD, _DWORD);
+int __stdcall AIL_set_preference(unsigned int number, int value)
+{
+ return (mss32_AIL_set_preference)(number, value);
+}
+
+// sub_4D8350: using guessed type int __stdcall AIL_digital_configuration(_DWORD, _DWORD, _DWORD, _DWORD);
+int __stdcall AIL_digital_configuration(HDIGDRIVER drv, int *rate, int *format, char *string)
+{
+ return (mss32_AIL_digital_configuration)(drv, rate, format, string);
+}
+
+// sub_4D8354: using guessed type int __stdcall AIL_get_preference(_DWORD);
+int __stdcall AIL_get_preference(unsigned int number)
+{
+ return (mss32_AIL_get_preference)(number);
+}
+
+void __stdcall AIL_waveOutClose(HDIGDRIVER drvr)
+{
+ (mss32_AIL_waveOutClose)(drvr);
+}
+
+// sub_4D8320: using guessed type int __stdcall AIL_redbook_pause(_DWORD);
+unsigned int __stdcall AIL_redbook_pause(HREDBOOK hRedbook)
+{
+ return (mss32_AIL_redbook_pause)(hRedbook);
+}
+
+int __stdcall AIL_set_3D_provider_preference(HPROVIDER a1, const char *a2, int *a3)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_allocate_3D_sample_handle(HPROVIDER)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_sample_float_distances(void *a1, long a2, long a3, long a4, long a5)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_sample_volume(void *a1, long a2)
+{
+ __asm int 3
+ return 0;
+}
+
+void __stdcall AIL_release_sample_handle(HSAMPLE s)
+{
+ (mss32_AIL_release_sample_handle)(s);
+}
+
+int __stdcall AIL_release_3D_sample_handle(void *a1)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_close_3D_provider(HPROVIDER)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_redbook_close(HREDBOOK a1)
+{
+ __asm int 3
+ return 0;
+}
+
+// sub_4D8344: using guessed type int __stdcall AIL_shutdown();
+int __stdcall AIL_shutdown()
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_end_sample(HSAMPLE a1)
+{
+ return (mss32_AIL_end_sample)(a1);
+}
+
+int __stdcall AIL_end_3D_sample(void *a1)
+{
+ __debugbreak();
+ return 0;
+}
+
+
+void __stdcall AIL_end_sequence(HSEQUENCE a1)
+{
+ (mss32_AIL_end_sequence)(a1);
+}
+
+void __stdcall AIL_pause_stream(HSTREAM a1, int onoff)
+{
+ (mss32_AIL_pause_stream)(a1, onoff);
+}
+
+int __stdcall AIL_set_sample_file(HSAMPLE s, const void *file_image, int block)
+{
+ return (mss32_AIL_set_sample_file)(s, file_image, block);
+}
+
+int __stdcall AIL_start_sample(HSAMPLE s)
+{
+ return (mss32_AIL_start_sample)(s);
+}
+
+void __stdcall AIL_set_sample_playback_rate(HSAMPLE s, int rate)
+{
+ (mss32_AIL_set_sample_playback_rate)(s, rate);
+}
+
+void __stdcall AIL_sample_ms_position(HSAMPLE s, int *pTotalMS, int *pCurrentMS)
+{
+ (mss32_AIL_sample_ms_position)(s, pTotalMS, pCurrentMS);
+}
+
+int __stdcall AIL_3D_sample_status(void *a1)
+{
+ __asm int 3
+ return 0;
+}
+
+void __stdcall AIL_set_sample_loop_count(HSAMPLE s, int num)
+{
+ (mss32_AIL_set_sample_loop_count)(s, num);
+}
+
+int __stdcall AIL_set_sample_volume(HSAMPLE a1, long a2)
+{
+ return (mss32_AIL_set_sample_volume)(a1, a2);
+}
+
+int __stdcall AIL_3D_position(void *a1, int *a2, float *a3, long *a4)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_sample_file(long a1, void *a2)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_sample_loop_count(long a1, long a2)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_start_3D_sample(long a1)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_position(void *hSample, long a2, long a3, long a4)
+{
+ __asm int 3
+ return 0;
+}
+
+int __stdcall AIL_set_3D_orientation(void *hSample, long a2, long a3, long a4, long a5, long a6, long a7)
+{
+ __asm int 3
+ return 0;
+}
+
+void __stdcall AIL_init_sample(HSAMPLE a1)
+{
+ (mss32_AIL_init_sample)(a1);
+}
+
+int __stdcall AIL_set_sample_pan(HSAMPLE a1, long a2)
+{
+ return (mss32_AIL_set_sample_pan)(a1, a2);
+}
+
+
+AILFILETYPE __stdcall AIL_file_type(void *pSoundBytes, int numBytes)
+{
+  return (mss32_AIL_file_type)(pSoundBytes, numBytes);
+}
+
+int __stdcall AIL_WAV_info(void *pSoundBytes, AILSOUNDINFO *pInfo)
+{
+  return (mss32_AIL_WAV_info)(pSoundBytes, pInfo);
+}
+
+int __stdcall AIL_decompress_ADPCM(AILSOUNDINFO *pInfo, void *a2, void *a3)
+{
+  return (mss32_AIL_decompress_ADPCM)(pInfo, a2, a3);
+}
+
+int __stdcall AIL_mem_free_lock(void *a1)
+{
+ __asm int 3
+ return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Audio/AIL.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,318 @@
+#pragma once
+#include "OSAPI.h"
+
+
+
+/*  252 */
+enum AILFILETYPE : __int32
+{
+  AILFILETYPE_UNKNOWN = 0x0,
+  AILFILETYPE_PCM_WAV = 0x1,
+  AILFILETYPE_ADPCM_WAV = 0x2,
+  AILFILETYPE_OTHER_WAV = 0x3,
+  AILFILETYPE_VOC = 0x4,
+  AILFILETYPE_MIDI = 0x5,
+  AILFILETYPE_XMIDI = 0x6,
+  AILFILETYPE_7 = 0x7,
+  AILFILETYPE_XMIDI_MLS = 0x8,
+  AILFILETYPE_DLS = 0x9,
+  AILFILETYPE_MLS = 0xA,
+  AILFILETYPE_MPEG_L1_AUDIO = 0xB,
+  AILFILETYPE_MPEG_L2_AUDIO = 0xC,
+  AILFILETYPE_MPEG_L3_AUDIO = 0xD,
+  AILFILETYPE_OTHER_ASI_WAV = 0xE,
+  AILFILETYPE_OTHER_ASI_F = 0xF,
+};
+
+
+
+/*  253 */
+#pragma pack(push, 1)
+struct AILSOUNDINFO
+{
+  int uFormat;
+  void *pData;
+  unsigned int uDataSize;
+  unsigned int uRate;
+  int uBits;
+  int uChannels;
+  unsigned int uSamples;
+  unsigned int uBlockSize;
+  void *pInitial;
+};
+#pragma pack(pop)
+
+
+
+
+//Bink
+typedef struct _BINK    *HBINK;
+typedef struct _BINKBUF *HBINKBUF;
+//Smacker & AIL types
+typedef struct _DIG_DRIVER *HDIGDRIVER;
+typedef struct _SMACK      *HSMACK;
+typedef struct _SMACKBLIT  *HSMACKBLIT;
+typedef struct _SMACKBUF   *HSMACKBUF;
+//AIL
+typedef struct _REDBOOK    *HREDBOOK;
+typedef struct _SAMPLE     *HSAMPLE;
+typedef struct _PROVIDER   *HPROVIDER;
+typedef struct _SEQUENCE   *HSEQUENCE;
+typedef struct _STREAM     *HSTREAM;
+typedef __int32             HATTRIB;
+typedef __int32             HASISTREAM; // Handle to stream being managed by ASI codec
+
+
+
+void MSS32_DLL_Initialize();
+
+#define AILCALL __stdcall
+#define AILCALLBACK __stdcall
+
+
+typedef __int32 (AILCALLBACK FAR * AILASIFETCHCB) (unsigned __int32		user,			// User value passed to ASI_open_stream()
+												void FAR *dest,			// Location to which stream data should be copied by app
+												__int32		bytes_requested, // # of bytes requested by ASI codec
+												__int32		offset);		 // If not -1, application should seek to this point in stream
+
+typedef HASISTREAM (AILCALL FAR *ASI_STREAM_OPEN) (unsigned __int32			user,				// User value passed to fetch callback
+													AILASIFETCHCB fetch_CB,			// Source data fetch handler
+													unsigned __int32			total_size);		// Total size for %-done calculations (0=unknown)
+typedef __int32	(AILCALL FAR *ASI_STREAM_PROCESS) (HASISTREAM	stream,				// Handle of stream
+												void FAR	*buffer,				// Destination for processed data
+												__int32		 buffer_size);		// # of bytes to return in buffer
+typedef __int32 (AILCALL FAR *ASI_STREAM_SEEK)	(HASISTREAM stream,
+													 __int32		stream_offset);
+typedef __int32 (AILCALL FAR *ASI_STREAM_CLOSE) (HASISTREAM stream);
+typedef __int32 (AILCALL FAR *ASI_STREAM_ATTRIBUTE) (HASISTREAM stream,
+												 HATTRIB	attrib);
+typedef __int32 (AILCALL FAR *ASI_STREAM_SET_PREFERENCE) (HASISTREAM stream,
+														HATTRIB	preference,
+														void const FAR	*	value);
+
+typedef struct
+	{
+	ASI_STREAM_OPEN			ASI_stream_open;
+	ASI_STREAM_PROCESS		ASI_stream_process;
+	ASI_STREAM_SEEK			ASI_stream_seek;
+	ASI_STREAM_CLOSE			ASI_stream_close;
+	ASI_STREAM_ATTRIBUTE		ASI_stream_attribute;
+	ASI_STREAM_SET_PREFERENCE ASI_stream_set_preference;
+
+	HATTRIB INPUT_BIT_RATE;
+	HATTRIB INPUT_SAMPLE_RATE;
+	HATTRIB INPUT_BITS;
+	HATTRIB INPUT_CHANNELS;
+	HATTRIB OUTPUT_BIT_RATE;
+	HATTRIB OUTPUT_SAMPLE_RATE;
+	HATTRIB OUTPUT_BITS;
+	HATTRIB OUTPUT_CHANNELS;
+	HATTRIB POSITION;
+	HATTRIB PERCENT_DONE;
+	HATTRIB MIN_INPUT_BLOCK_SIZE;
+	HATTRIB RAW_RATE;
+	HATTRIB RAW_BITS;
+	HATTRIB RAW_CHANNELS;
+	HATTRIB REQUESTED_RATE;
+	HATTRIB REQUESTED_BITS;
+	HATTRIB REQUESTED_CHANS;
+
+	HASISTREAM stream;
+	}
+ASISTAGE;
+
+
+
+
+typedef void (AILCALLBACK FAR* AILSTREAMCB)(HSTREAM stream);
+typedef struct _STREAM {
+
+	__int32 block_oriented; // 1 if this is an ADPCM or ASI-compressed stream
+	__int32 using_ASI;		// 1 if using ASI decoder to uncompress stream data
+	ASISTAGE FAR *ASI;	// handy pointer to our ASI coded
+
+	HSAMPLE samp;		// the sample handle
+
+	unsigned __int32 fileh;			// the open file handle
+
+	unsigned __int8 FAR* bufs[3];	// the data buffers
+	unsigned __int32 bufsizes[3];	// the size of each buffer
+	__int32 reset_ASI[3];	// should we reset the ASI at the end of the buffer?
+	__int32 bufstart[3];	// offset of where this buffer started
+	void FAR* asyncs[3];// async read structures
+
+	__int32 loadedbufstart[2]; // offset of where the loaded buffer started
+	__int32 loadedorder[2]; // order of the buffers as they were loaded
+	__int32 loadorder;		// incremented as each buffer is loaded
+
+	__int32 bufsize;		// size of each buffer
+	__int32 readsize;		// size of each read block
+
+	unsigned __int32 buf1;			// 0,1,2 (current buffer that we are reading into)
+	__int32 size1;			// holds the current amount of data read
+
+	unsigned __int32 buf2;			// 0,1,2 (the next buffer that we are reading into)
+	__int32 size2;			// next buffer loaded up to
+
+	unsigned __int32 buf3;			// 0,1,2 (the next buffer that we are reading into)
+	__int32 size3;			// next buffer loaded up to
+
+	unsigned __int32 datarate;		// datarate in bytes per second
+	__int32 filerate;		// original datarate of the file
+	__int32 filetype;		// file format type
+	unsigned __int32 fileflags;		// file format flags (signed or unsigned)
+	__int32 totallen;		// total length of the sound data
+
+	__int32 substart;		// subblock loop start
+	__int32 sublen;		 // subblock loop len
+	__int32 subpadding;	 // amount to pad the final block
+
+	unsigned __int32 blocksize;		// ADPCM block size
+	__int32 padding;		// padding to be done
+	__int32 padded;		 // padding done
+
+	__int32 loadedsome;	 // have we done any loads?
+
+	unsigned __int32 startpos;		// point that the sound data begins
+	unsigned __int32 totalread;		// total bytes read from the disk
+
+	unsigned __int32 loopsleft;		// how many loops are left
+
+	unsigned __int32 error;			// read error has occurred
+
+	__int32 preload;		// preload the file into the first buffer
+	unsigned __int32 preloadpos;	 // position to use in preload
+	__int32 noback;		 // no background processing
+	__int32 alldone;		// alldone
+	__int32 primeamount;	// amount to load after a seek
+	__int32 readatleast;	// forced amount to read on next service
+
+	__int32 playcontrol;	// control: 0=stopped, 1=started, |8=paused, |16=sample paused
+
+	AILSTREAMCB callback;	// end of stream callback
+
+	__int32 user_data[8];	// Miscellaneous user data
+	void FAR* next;	 // pointer to next stream
+
+#if defined(IS_WINDOWS) || defined(IS_MAC)
+	__int32 autostreaming;	// are we autostreaming this stream
+#endif
+
+#ifdef IS_WINDOWS
+	__int32 cb_IsWin32s;	// Is the callback win32s?
+#endif
+	__int32 docallback;	 // set when it time to poll for a callback
+#ifdef IS_MAC
+	IOParam	stream_param;
+	__int32		donext;
+	__int32		donext1;
+	unsigned __int32		fillup;
+	unsigned __int32		session;
+	unsigned __int32		tamt;
+	unsigned __int32		buf;
+	__int32*	 size;
+	__int32*	 done;
+	__int32		done1;
+	__int32		done2;
+	__int32		done3;
+	Boolean	force_quit;
+#endif
+
+} MSTREAM_TYPE;
+
+
+
+
+
+
+
+
+int __stdcall AIL_startup();
+HREDBOOK __stdcall AIL_redbook_open_drive(long drive);
+HREDBOOK __stdcall AIL_redbook_open(int);
+int __stdcall AIL_set_preference(unsigned int number, int value);
+int __stdcall AIL_waveOutOpen(HDIGDRIVER *drv, HWAVEOUT *phWaveOut, int wDeviceID, WAVEFORMAT *pFormat);
+int __stdcall AIL_get_preference(unsigned int number);
+int __stdcall AIL_digital_configuration(HDIGDRIVER drv, int *rate, int *format, char *string);
+HSAMPLE __stdcall AIL_allocate_sample_handle(HDIGDRIVER hDrv);
+unsigned int __stdcall AIL_redbook_tracks(HREDBOOK hRedbook);
+int __stdcall AIL_redbook_volume(HREDBOOK hRedbook);
+unsigned int __stdcall AIL_redbook_stop(HREDBOOK hRedbook);
+void __stdcall AIL_set_digital_master_volume(HDIGDRIVER hDrv, float master_volume);
+int __stdcall AIL_redbook_set_volume(HREDBOOK hRedbook, int volume);
+unsigned int __stdcall AIL_redbook_pause(HREDBOOK hRedbook);
+void __stdcall AIL_redbook_track_info(HREDBOOK hRedbook, unsigned int uTrackNum, unsigned int *pStartMS, unsigned int *pEndMS);
+unsigned int __stdcall AIL_redbook_play(HREDBOOK hRedbook, unsigned int uStartMS, unsigned int uEndMS);  	
+unsigned int __stdcall AIL_redbook_resume(HREDBOOK);
+int __stdcall AIL_enumerate_3D_providers(int *a1, HPROVIDER *pOutProv, char **pOutName);
+DWORD __stdcall AIL_open_3D_provider(HPROVIDER a2);
+void __stdcall AIL_3D_provider_attribute(HPROVIDER lib, char *name, void *val);
+int __stdcall AIL_set_3D_provider_preference(HPROVIDER a1, const char *a2, int *a3);
+void __stdcall AIL_waveOutClose(HDIGDRIVER drvr);
+int __stdcall AIL_allocate_3D_sample_handle(HPROVIDER);
+int __stdcall AIL_set_3D_sample_float_distances(void *a1, long a2, long a3, long a4, long a5);
+int __stdcall AIL_set_3D_sample_volume(void *a1, long a2);
+void __stdcall AIL_release_sample_handle(HSAMPLE s);
+int __stdcall AIL_3D_position(void *a1, int *a2, float *a3, long *a4);
+int __stdcall AIL_set_3D_sample_file(long a1, void *a2);
+int __stdcall AIL_set_3D_sample_loop_count(long a1, long a2);
+int __stdcall AIL_start_3D_sample(long a1);
+int __stdcall AIL_set_3D_position(void *hSample, long a2, long a3, long a4);
+int __stdcall AIL_set_3D_orientation(void *hSample, long a2, long a3, long a4, long a5, long a6, long a7);
+int __stdcall AIL_release_3D_sample_handle(void *hHandle);
+
+int __stdcall AIL_close_3D_provider(HPROVIDER);
+int __stdcall AIL_redbook_close(HREDBOOK);
+
+// sub_4D8344: using guessed type int __stdcall AIL_shutdown();
+int __stdcall AIL_shutdown();
+
+int __stdcall AIL_end_sample(HSAMPLE a1);
+int __stdcall AIL_end_3D_sample(void *a1);
+void __stdcall AIL_end_sequence(HSEQUENCE a1);
+void __stdcall AIL_pause_stream(HSTREAM a1, int onoff);
+int __stdcall AIL_set_sample_file(HSAMPLE, const void *file_image, int block);
+int __stdcall AIL_start_sample(HSAMPLE);
+void __stdcall AIL_set_sample_playback_rate(HSAMPLE, int rate);
+void __stdcall AIL_sample_ms_position(HSAMPLE, int *pTotalMS, int *pCurrentMS);
+int __stdcall AIL_3D_sample_status(void *a1);
+
+
+namespace AIL
+{
+ namespace Sample
+ {
+  enum Status
+  {
+   Free = 1,               // Sample is available for allocation
+   Done = 2,               // Sample has finished playing, or has never been started
+   Playing = 4,            // Sample is playing
+   Stopped = 8,            // Sample has been stopped
+   PlayingButReleased = 16 // Sample is playing, but digital handle has been temporarily released
+  };
+ };
+};
+AIL::Sample::Status __stdcall AIL_sample_status(HSAMPLE a1);
+
+
+void __stdcall AIL_set_sample_loop_count(HSAMPLE, int);
+int __stdcall AIL_set_sample_volume(HSAMPLE a1, long a2);
+
+
+int __stdcall AIL_sample_volume(HSAMPLE);
+void __stdcall AIL_init_sample(HSAMPLE);
+int __stdcall AIL_set_sample_pan(HSAMPLE, long a2);
+AILFILETYPE __stdcall AIL_file_type(void *pSoundBytes, int numBytes);
+int __stdcall AIL_WAV_info(void *pSoundBytes, AILSOUNDINFO *pInfo);
+int __stdcall AIL_decompress_ADPCM(AILSOUNDINFO *pInfo, void *a2, void *a3);
+int __stdcall AIL_mem_free_lock(void *a1);
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Audio/AudioPlayer.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,2740 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <string>
+#include "Engine/ZlibWrapper.h"
+
+#include "Engine/mm7_data.h"
+#include "../MediaPlayer.h"
+#include "AudioPlayer.h"
+#include "Engine/Tables/FrameTableInc.h"
+#include "Engine/Graphics/Indoor.h"
+#include "Engine/Objects/SpriteObject.h"
+#include "Engine/Party.h"
+#include "Engine/Objects/Actor.h"
+#include "Engine/Game.h"
+#include "Engine/Graphics/DecorationList.h"
+#include "Engine/Timer.h"
+#include "Engine/OurMath.h"
+#include "Engine/MapInfo.h"
+#include "GUI/GUIWindow.h"
+#include "Engine/Log.h"
+#include "Engine/ErrorHandling.h"
+#include "Engine/Graphics/Level/Decoration.h"
+#include "Engine/Registry.h"
+
+#include "Media/Video/Bink_Smacker.h"
+
+#include "Engine/MM7.h"
+
+
+PCMWAVEFORMAT pcmWaveFormat;
+
+int uFindSound_BinSearch_ResultID; // weak
+int uLastLoadedSoundID; // weak
+int sLastTrackLengthMS;
+std::array<Sound, 3000> pSounds;
+AudioPlayer *pAudioPlayer;
+SoundList *pSoundList;
+
+
+std::array<stru339_spell_sound, 4> stru_A750F8;
+std::array<stru339_spell_sound, 4> AA1058_PartyQuickSpellSound;
+
+
+
+unsigned __int8 uSoundVolumeMultiplier;// = 4;
+unsigned __int8 uVoicesVolumeMultiplier;// = 4;
+unsigned __int8 uMusicVolimeMultiplier;// = 4;
+int bWalkSound; // idb
+
+std::array<float, 10> pSoundVolumeLevels = 
+{
+  0.0000000f, 0.1099999f, 0.2199999f, 0.3300000f, 0.4399999f,
+ 0.5500000f, 0.6600000f, 0.7699999f, 0.8799999f, 0.9700000f  
+//  0.0000000f, 0.4900000f, 0.5500000f, 0.6100000f, 0.6700000f,  //for 128.0f
+// 0.7000000f, 0.7600000f, 0.8200000f, 0.8800000f, 0.9700000f     //changed 0.9900000f to 0.9700000f. for some reason it only works for values below this
+};
+
+
+
+
+void ReleaseSoundData(void *_this);
+_DIG_DRIVER *Audio_GetFirstHardwareDigitalDriver();
+
+
+
+
+//----- (004A9953) --------------------------------------------------------
+void SoundList::Initialize()
+{
+  SoundDesc *pSoundDesc; // eax@5
+  void *pSoundData; // ebx@7
+  unsigned int uSoundSize; // eax@7
+  char *pSoundBytes; // ebx@7
+  AILFILETYPE pType; // eax@7
+  int v8; // eax@8
+  char pSoundName[120]; // [sp+4h] [bp-A4h]@4
+  AILSOUNDINFO pInfo; // [sp+7Ch] [bp-2Ch]@10
+  int v12; // [sp+A0h] [bp-8h]@12
+
+  if ( sNumSounds > 1 )
+  {
+    for ( uint i = 1; i < pSoundList->sNumSounds; ++i )
+    {
+      sprintf(pSoundName, "%s", pSL_Sounds[i].pSoundName);
+      pSoundDesc = &pSoundList->pSL_Sounds[i];
+      if ( pSoundList->pSL_Sounds[i].eType != SOUND_DESC_SYSTEM )
+        continue;
+      pSoundList->pSL_Sounds[i].pSoundData[0] = ::LoadSound(pSoundName, (SoundData *)-1, pSL_Sounds[i].uSoundID); // Ritor result crash exe file
+      if ( !pAudioPlayer->b3DSoundInitialized )
+        continue;
+      pSoundDesc = &pSoundList->pSL_Sounds[i];
+      if ( !(pSoundDesc->uFlags & SOUND_DESC_SWAP) || !pSoundDesc->pSoundData[0] )
+        continue;
+      pSoundData = pSoundDesc->pSoundData[0];
+      uSoundSize = *(int *)pSoundData;
+      pSoundBytes = (char *)pSoundData + 4;
+      pType = AIL_file_type(pSoundBytes, uSoundSize);
+      if ( !pType )
+      {
+        pSoundList->pSL_Sounds[i].bDecompressed = false;
+        pSoundList->UnloadSound(i, 1);
+        continue;
+      }
+      v8 = pType - 1;
+      if ( v8 )
+      {
+        if ( v8 == 1 )
+        {
+          if ( AIL_WAV_info(pSoundBytes, &pInfo) && pInfo.uChannels != 2 )
+          {
+            if ( !AIL_decompress_ADPCM(&pInfo, &pSoundList->pSL_Sounds[i].p3DSound, &v12) )
+            {
+              pSoundList->pSL_Sounds[i].p3DSound = 0;
+              pSoundList->pSL_Sounds[i].bDecompressed = true;
+            }
+          }
+          pSoundList->UnloadSound(i, 1);
+          continue;
+        }
+        pSoundList->pSL_Sounds[i].bDecompressed = false;
+        pSoundList->UnloadSound(i, 1);
+        continue;
+      }
+      pSoundList->pSL_Sounds[i].p3DSound = pSoundList->pSL_Sounds[i].pSoundData[0];
+      pSoundList->UnloadSound(i, 1);
+    }
+  }
+  //_CrtDumpMemoryLeaks();
+}
+
+//----- (004A9A67) --------------------------------------------------------
+__int16 SoundList::LoadSound(int a1, unsigned int a3)
+{
+  AILSOUNDINFO v24; // [sp+84h] [bp-28h]@23
+
+  if (bNoSound || !sNumSounds)
+    return 0;
+
+  uint       uSoundIdx = 0;
+  SoundDesc *pSound = nullptr;
+  for (uint i = 1; i < sNumSounds; ++i)
+    if (pSL_Sounds[i].uSoundID == a1)
+    {
+      uSoundIdx = i;
+      pSound = &pSL_Sounds[i];
+      break;
+    }
+  if (!pSound)
+    return 0;
+
+  if (pSound->uFlags & SOUND_DESC_SWAP && pSound->p3DSound ||
+      ~pSound->uFlags & SOUND_DESC_SWAP && pSound->pSoundData[0])
+    return uSoundIdx;
+
+  if (!pSound->pSoundData[0])
+    pSound->pSoundData[0] = ::LoadSound(pSound->pSoundName, (SoundData *)-1, pSound->uSoundID);
+
+  if (!pSound->pSoundData[0])
+    return 0;
+
+  if (a3)
+    pSound->uFlags |= SOUND_DESC_SYSTEM;
+
+  if (!pAudioPlayer->b3DSoundInitialized)
+    return uSoundIdx;
+
+  if (~pSound->uFlags & SOUND_DESC_SWAP || !pSound->pSoundData[0])
+    return uSoundIdx;
+
+
+  SoundData* pSoundData = pSound->pSoundData[0];
+  switch (AIL_file_type((void *)pSoundData->pData, pSoundData->uDataSize))
+  {
+    default:
+    case AILFILETYPE_UNKNOWN:
+      pSound->bDecompressed = false;
+      return 0;
+
+    case AILFILETYPE_PCM_WAV:
+      pSound->p3DSound = pSound->pSoundData[0];
+      return uSoundIdx;
+
+    case AILFILETYPE_ADPCM_WAV:
+      if (AIL_WAV_info((void *)pSoundData->pData, &v24) && v24.uChannels != 2)
+      {
+        if (!AIL_decompress_ADPCM(&v24, &pSound->p3DSound, &a1) )
+        {
+          pSound->p3DSound = nullptr;
+          pSound->bDecompressed = true;
+          UnloadSound(uSoundIdx, 0);
+        }
+      }
+      return uSoundIdx;
+  };
+}
+
+//----- (004A9BBD) --------------------------------------------------------
+int SoundList::LoadSound(unsigned int a2, LPVOID lpBuffer, int uBufferSizeLeft, int *pOutSoundSize, int a6)
+{
+  void *v18; // ebx@19
+  DWORD NumberOfBytesRead;
+
+  if (!sNumSounds)
+    return 0;
+
+  for ( uint i = 0; i < sNumSounds; ++i )
+  {
+    if ( a2 == pSL_Sounds[i].uSoundID )
+    {
+      if ( !a6 && pSL_Sounds[i].pSoundData )
+        return i;
+      for ( uint j = 0; j < (signed int)pAudioPlayer->uNumSoundHeaders; ++j )
+      {
+        if ( !_stricmp(pAudioPlayer->pSoundHeaders[j].pSoundName, pSL_Sounds[i].pSoundName) )
+        {
+          if ( (signed int)pAudioPlayer->pSoundHeaders[j].uDecompressedSize > uBufferSizeLeft )
+            Error("Sound %s is size %i bytes, sound buffer size is %i bytes", pSL_Sounds[i].pSoundName, pAudioPlayer->pSoundHeaders[j].uDecompressedSize, uBufferSizeLeft);
+          SetFilePointer(pAudioPlayer->hAudioSnd, pAudioPlayer->pSoundHeaders[j].uFileOffset, 0, 0);
+          if ( (signed int)pAudioPlayer->pSoundHeaders[j].uCompressedSize >= (signed int)pAudioPlayer->pSoundHeaders[j].uDecompressedSize )
+          {
+            if ( pAudioPlayer->pSoundHeaders[j].uCompressedSize == pAudioPlayer->pSoundHeaders[j].uDecompressedSize )
+              ReadFile(pAudioPlayer->hAudioSnd, lpBuffer, pAudioPlayer->pSoundHeaders[j].uDecompressedSize, &NumberOfBytesRead, 0);
+            else
+              MessageBoxW(nullptr, L"Can't load sound file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Sound.cpp:666", 0);
+          }
+          else
+          {
+            v18 = malloc(pAudioPlayer->pSoundHeaders[j].uCompressedSize);
+            ReadFile(pAudioPlayer->hAudioSnd, v18, pAudioPlayer->pSoundHeaders[j].uCompressedSize, &NumberOfBytesRead, 0);
+            zlib::MemUnzip(lpBuffer, &pAudioPlayer->pSoundHeaders[j].uDecompressedSize, v18, pAudioPlayer->pSoundHeaders[j].uCompressedSize);
+            free(v18);
+          }
+          pSL_Sounds[i].pSoundData[a6] = (SoundData *)lpBuffer;
+          *pOutSoundSize = a2;
+          return i;
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+//----- (004A9D3E) --------------------------------------------------------
+SoundDesc *SoundList::Release()
+{
+  SoundDesc *result; // eax@3
+  //void *v5; // ecx@3
+
+  if ( (signed int)this->sNumSounds > 0 )
+  {
+    for ( uint i = 0; i < (signed int)this->sNumSounds; ++i )
+    {
+      result = this->pSL_Sounds;
+      //v5 = this->pSL_Sounds[i].pSoundData[0];
+      if ( this->pSL_Sounds[i].pSoundData[0] )
+      {
+        ReleaseSoundData(this->pSL_Sounds[i].pSoundData[0]);
+        this->pSL_Sounds[i].pSoundData[0] = nullptr;
+        this->pSL_Sounds[i].uFlags &= 0xFFFFFFFE;
+      }
+    }
+  }
+  return result;
+}
+
+//----- (004A9D79) --------------------------------------------------------
+void SoundList::_4A9D79(int a2)
+{
+  for ( int i = 0; i < (signed int)this->sNumSounds; ++i )
+  {
+    if ( this->pSL_Sounds[i].eType != SOUND_DESC_SYSTEM && (a2 || this->pSL_Sounds[i].eType != SOUND_DESC_LOCK) )
+    {
+      if ( this->pSL_Sounds[i].pSoundData[0] )
+      {
+        ReleaseSoundData(this->pSL_Sounds[i].pSoundData[0]);
+        this->pSL_Sounds[i].pSoundData[0] = nullptr;
+      }
+      this->pSL_Sounds[i].uFlags &= ~SOUND_DESC_SYSTEM;
+    }
+  }
+}
+
+//----- (004A9DCD) --------------------------------------------------------
+void SoundList::UnloadSound(unsigned int uSoundID, char a3)
+{
+  if ( pSL_Sounds[uSoundID].eType != SOUND_DESC_SYSTEM )
+  {
+    if ( (pSL_Sounds[uSoundID].uFlags & SOUND_DESC_SWAP) && pSL_Sounds[uSoundID].p3DSound && a3 )
+    {
+      if ( pSL_Sounds[uSoundID].bDecompressed)
+        AIL_mem_free_lock(pSL_Sounds[uSoundID].p3DSound);
+      pSL_Sounds[uSoundID].p3DSound = 0;
+      pSL_Sounds[uSoundID].uFlags &= ~SOUND_DESC_SYSTEM;
+    }
+    if ( pSL_Sounds[uSoundID].pSoundData[0] )
+    {
+      ReleaseSoundData(pSL_Sounds[uSoundID].pSoundData[0]);
+      pSL_Sounds[uSoundID].pSoundData[0] = nullptr;
+      pSL_Sounds[uSoundID].uFlags &= ~SOUND_DESC_SYSTEM;
+    }
+  }
+}
+
+
+//----- (004A9E3D) --------------------------------------------------------
+void SoundList::ToFile()
+{
+  FILE *v2; // eax@1
+
+  v2 = fopen("data\\dsounds.bin", "wb");
+  if ( !v2 )
+    Error("Unable to save dsounds.bin!");
+
+  fwrite(this, 4, 1, v2);
+  fwrite(this->pSL_Sounds, 0x78u, this->sNumSounds, v2);
+  fclose(v2);
+}
+
+//----- (004A9E89) --------------------------------------------------------
+void SoundList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8)
+{
+  uint num_mm6_sounds = data_mm6 ? *(int *)data_mm6 : 0,
+       num_mm7_sounds = data_mm7 ? *(int *)data_mm7 : 0,
+       num_mm8_sounds = data_mm8 ? *(int *)data_mm8 : 0;
+
+  sNumSounds = num_mm6_sounds + num_mm7_sounds + num_mm8_sounds;
+  assert(sNumSounds);
+  assert(!num_mm8_sounds);
+
+  pSL_Sounds = (SoundDesc *)malloc(sNumSounds * sizeof(SoundDesc));
+  memcpy(pSL_Sounds, (char *)data_mm7 + 4, num_mm7_sounds * sizeof(SoundDesc));
+  for (uint i = 0; i < num_mm6_sounds; ++i)
+  {
+    auto src = (SoundDesc_mm6 *)((char *)data_mm6 + 4) + i;
+    SoundDesc* dst = &pSL_Sounds[num_mm7_sounds + i];
+
+    memcpy(dst, src, sizeof(SoundDesc_mm6));
+    dst->p3DSound = nullptr;
+    dst->bDecompressed = false;
+  }
+}
+
+//----- (004A9ED0) --------------------------------------------------------
+int SoundList::FromFileTxt(const char *Args)
+{
+  __int32 v3; // edi@1
+  FILE *v4; // eax@1
+  unsigned int v5; // esi@3
+  void *v6; // eax@9
+  FILE *v7; // ST0C_4@11
+  char *i; // eax@11
+  char Buf; // [sp+Ch] [bp-2F0h]@3
+  FrameTableTxtLine v18; // [sp+200h] [bp-FCh]@4
+  FrameTableTxtLine v19; // [sp+27Ch] [bp-80h]@4
+  FILE *File; // [sp+2F8h] [bp-4h]@1
+  unsigned int Argsa; // [sp+304h] [bp+8h]@3
+
+  free(this->pSL_Sounds);
+  v3 = 0;
+  this->pSL_Sounds = 0;
+  this->sNumSounds = 0;
+  v4 = fopen(Args, "r");
+  File = v4;
+  if ( !v4 )
+    Error("SoundListClass::load - Unable to open file: %s.");
+
+  v5 = 0;
+  Argsa = 0;
+  if ( fgets(&Buf, 490, v4) )
+  {
+    do
+    {
+      *strchr(&Buf, 10) = 0;
+      memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19));
+      if ( v19.uPropCount && *v19.pProperties[0] != 47 )
+        ++Argsa;
+    }
+    while ( fgets(&Buf, 490, File) );
+    v5 = Argsa;
+    v3 = 0;
+  }
+  this->sNumSounds = v5;
+  v6 = malloc(120 * v5);
+  this->pSL_Sounds = (SoundDesc *)v6;
+  if ( v6 == (void *)v3 )
+    Error("SoundListClass::load - Out of Memory!");
+
+  memset(v6, v3, 120 * this->sNumSounds);
+  v7 = File;
+  this->sNumSounds = v3;
+  fseek(v7, v3, v3);
+  for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) )
+  {
+    *strchr(&Buf, 10) = 0;
+    memcpy(&v19, txt_file_frametable_parser(&Buf, &v18), sizeof(v19));
+    if ( v19.uPropCount && *v19.pProperties[0] != 47 )
+    {
+      sprintf(this->pSL_Sounds[this->sNumSounds].pSoundName, "%s", v19.pProperties[0]);
+      this->pSL_Sounds[this->sNumSounds].uSoundID = atoi(v19.pProperties[1]);
+      if ( _stricmp(v19.pProperties[2], "system") )
+      {
+        if ( _stricmp(v19.pProperties[2], "swap") )
+        {
+          if ( !_stricmp(v19.pProperties[2], "lock") )
+            this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_LOCK;
+          else
+            this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_LEVEL;
+        }
+        else
+          this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_SWAP;
+      }
+      else
+        this->pSL_Sounds[this->sNumSounds].eType = SOUND_DESC_SYSTEM;
+      if ( v19.uPropCount >= 4 && !_stricmp(v19.pProperties[3], "3D") )
+        this->pSL_Sounds[this->sNumSounds].uFlags |= SOUND_DESC_SWAP;
+      ++this->sNumSounds;
+    }
+  }
+  fclose(File);
+  return 1;
+}
+
+//----- (004AA13F) --------------------------------------------------------
+void AudioPlayer::PlayMusicTrack(MusicID eTrack)
+{
+  if (!bNoSound && bPlayerReady && hAILRedbook && uMusicVolimeMultiplier)
+  {
+    AIL_redbook_stop(hAILRedbook);
+    AIL_redbook_set_volume(hAILRedbook, (signed)pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f);
+    AIL_redbook_track_info(hAILRedbook, eTrack, &uCurrentMusicTrackStartMS, &uCurrentMusicTrackEndMS);
+    AIL_redbook_play(hAILRedbook, uCurrentMusicTrackStartMS + 1, uCurrentMusicTrackEndMS);
+    uCurrentMusicTrackLength = ((uCurrentMusicTrackEndMS - uCurrentMusicTrackStartMS) * 128) / 1000;
+  }
+}
+
+
+//----- (004AA1F3) --------------------------------------------------------
+void AudioPlayer::SetMusicVolume(int vol)
+{
+  if (bPlayerReady)
+  {
+    if (hAILRedbook)
+      AIL_redbook_set_volume(hAILRedbook, vol);
+  }
+}
+
+//----- (004AA214) --------------------------------------------------------
+void AudioPlayer::SetMasterVolume(float fVolume)
+{
+  if ( bPlayerReady )
+  {
+    uMasterVolume = fVolume;
+    if ( hDigDriver )
+      AIL_set_digital_master_volume(hDigDriver, fVolume);
+    if ( b3DSoundInitialized )
+      s3DSoundVolume = fVolume * 0.5f;
+  }
+}
+// 4D8304: using guessed type int __stdcall AIL_set_digital_master_volume(int, int);
+
+//----- (004AA258) --------------------------------------------------------
+void AudioPlayer::_4AA258(int a2)
+{
+  if (!bPlayerReady)
+    return;
+
+  if ( this->b3DSoundInitialized && a2 )
+  {
+    for ( uint i = 0; i < this->uNum3DSamples; ++i )
+    {
+      if ( this->p3DSamples[i].field_4 == a2 && AIL_3D_sample_status(this->p3DSamples[i].hSample) == AIL::Sample::Playing )
+        AIL_end_3D_sample(this->p3DSamples[i].hSample);
+    }
+  }
+  if ( this->hDigDriver && a2 )
+  {
+    for ( uint i = 0; i < this->uMixerChannels; ++i )
+    {
+      if ( this->pMixerChannels[i].source_pid == a2 && AIL_sample_status(this->pMixerChannels[i].hSample) == AIL::Sample::Playing)
+      {
+        AIL_end_sample(this->pMixerChannels[i].hSample);
+        FreeChannel(&this->pMixerChannels[i]);
+      }
+    }
+  }
+}
+
+//----- (004AA306) --------------------------------------------------------
+void AudioPlayer::PlaySound(SoundID eSoundID, signed int pid, unsigned int uNumRepeats, signed int source_x, signed int source_y, int sound_data_id, float uVolume, int sPlaybackRate)
+{
+  int v12; // edi@13
+  signed int v13; // ecx@17
+  signed int v14; // eax@20
+  int v15; // eax@24
+  signed int v16; // eax@25
+  SpriteObject *pLayingItem; // eax@28
+  signed int v18; // eax@29
+  Actor *pActor1; // eax@32
+  signed int v20; // ecx@32
+  double v21; // st7@32
+  signed int v22; // ecx@33
+  AudioPlayer_3DSample *pAudioPlayer_3DSample; // esi@53
+  AudioPlayer_3DSample *pAudioPlayer_3DSample1; // esi@61
+  int v25; // esi@67
+  double v26; // st7@68
+  int v27; // ST18_4@68
+  int v28; // ebx@68
+  int v29; // eax@68
+  AudioPlayer_3DSample *pAudioPlayer_3DSample2; // esi@69
+  int v31; // ST18_4@70
+  int v32; // ebx@70
+  int v33; // eax@70
+  int v34; // eax@70
+  char v35; // zf@70
+  signed int v36; // ebx@74
+  AudioPlayer_3DSample *pAudioPlayer_3DSample3; // esi@79
+  int v40; // eax@81
+  char *v41; // edi@82
+  int v42; // esi@82
+  double v43; // st7@91
+  SpriteObject *pLayingItem2; // eax@92
+  Actor *pActor; // eax@93
+  signed int v46; // ecx@93
+  double v47; // st7@93
+  BLVDoor *pBLVDoor; // eax@97
+  double v49; // st7@104
+  int v50; // ST18_4@104
+  int v51; // ebx@104
+  int v52; // eax@104
+  float v53; // ST0C_4@106
+  float v54; // ST04_4@106
+//  SoundDesc *pSoundDesc; // edx@107
+//  SpriteObject *pLayingItem3; // eax@114
+  signed int v62; // esi@133
+//  int v68; // eax@143
+  unsigned int v86; // [sp+14h] [bp-60h]@84
+  RenderVertexSoft pRenderVertexSoft; // [sp+24h] [bp-50h]@1
+  int v90; // [sp+58h] [bp-1Ch]@68
+  float v91; // [sp+5Ch] [bp-18h]@68
+  float v93; // [sp+64h] [bp-10h]@1
+  signed int varC; // [sp+68h] [bp-Ch]@68
+  int v96; // [sp+70h] [bp-4h]@19
+  signed int uNumRepeatsb; // [sp+84h] [bp+10h]@93
+  float uNumRepeatsa; // [sp+84h] [bp+10h]@104
+  float v99; // [sp+8Ch] [bp+18h]@104
+  signed int v100; // [sp+90h] [bp+1Ch]@32
+  int v101; // [sp+90h] [bp+1Ch]@52
+  int v102; // [sp+90h] [bp+1Ch]@60
+  int v103; // [sp+90h] [bp+1Ch]@68
+
+  if ( !bPlayerReady || !uSoundVolumeMultiplier || !hDigDriver || eSoundID == SOUND_Invalid )
+    return;
+
+  int sample_volume = 10000;
+
+  int sound_id = 0;
+  for (uint i = 0; i < pSoundList->sNumSounds; ++i)
+    if (pSoundList->pSL_Sounds[i].uSoundID == eSoundID)
+    {
+      sound_id = i;
+      break;
+    }
+
+  if (!sound_id)
+  {
+    Log::Warning(L"SoundID = %u not found", eSoundID);
+    return;
+  }
+  assert(sound_id < pSoundList->sNumSounds);
+  if ( !sound_data_id )
+  {
+    if ( !pSoundList->pSL_Sounds[sound_id].pSoundData[0] )
+    {
+      if ( pSoundList->pSL_Sounds[sound_id].eType == SOUND_DESC_SWAP )
+        pSoundList->LoadSound(eSoundID, 0);
+    }
+  }
+  if ( !pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] )
+    return;
+
+  int start_channel = 0,
+      end_channel = 0;
+  v62 = start_channel;
+
+  if (!b3DSoundInitialized || pSoundList->pSL_Sounds[sound_id].Is3D())
+  {
+    if (pid == 0)  // generic sound like from UI
+    {
+      start_channel = 10;
+      end_channel = 12;
+      for (uint i = start_channel; i <= end_channel; ++i)
+      {
+        if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+        {
+          if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+            return;                          // already playing the same sound from the same source - return
+          AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      for ( uint j = start_channel; j <= end_channel; j++ )
+      {
+        if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+        {
+          AIL_init_sample(pMixerChannels[j].hSample);
+          char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
+          //if (sound_data_id == 0)  p = p + 4;//for RIFF
+		  //if ( eSoundID == 75 )// Ritor1: include +7 for pSounds[20]
+			  //p = p + 7;
+          AIL_set_sample_file(pMixerChannels[j].hSample, p, -1);
+          if ( sample_volume == 10000 )
+            sample_volume = uMasterVolume;
+          if (uVolume)
+            sample_volume = uVolume;
+          int object_type = PID_TYPE(pid),
+              object_id = PID_ID(pid);
+          if (source_x != -1)//ñðàáàòûâàåò íàïðèìåð ó ôîðòà â Õåðìîíäåéëå çâóê âûñòðåëîâ ïóøåê
+          {
+            //if (!source_x)
+              //source_x = pParty->vPosition.x;
+            //if (!source_y)
+              //source_y = pParty->vPosition.y;
+           if ( source_x )//Ritor1: for pedestals
+           {
+              AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(source_x, source_y));
+              int vol = GetSoundStrengthByDistanceFromParty(source_x, source_y, pParty->vPosition.z);
+              AIL_set_sample_volume(pMixerChannels[j].hSample, vol);
+           }
+          }
+          if (uNumRepeats)
+            AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+          pMixerChannels[j].uSourceTrackIdx = sound_id;
+          pMixerChannels[j].source_pid = pid;
+          pMixerChannels[j].uSourceTrackID = eSoundID;
+          int rval = AIL_start_sample(pMixerChannels[j].hSample);
+          if ( sPlaybackRate )
+            AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+          if (object_type == OBJECT_Player)
+            AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+          return;
+        }
+      }
+      return;
+    }
+    else if (pid == -1)  // exclusive sounds - can override
+    {
+      /*if ( AIL_sample_status(pMixerChannels[13].hSample) == AIL::Sample::Done )
+      {
+          AIL_end_sample(pMixerChannels[13].hSample);
+          if ( pMixerChannels[13].uSourceTrackIdx )
+            FreeChannel(&pMixerChannels[13]);
+      }*/
+      AIL_init_sample(pMixerChannels[13].hSample);
+      char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
+      if (sound_data_id == 0)
+        p = p + 4;//for RIFF
+	  if ( eSoundID == 75 )//  Ritor1: include +7 for pSounds[20]
+		  p = p + 7;
+       AIL_set_sample_file(pMixerChannels[13].hSample, p, -1);
+       if ( sample_volume == 10000 )
+         sample_volume = uMasterVolume;
+       if (uVolume)
+         sample_volume = uVolume;
+       AIL_set_sample_volume(pMixerChannels[13].hSample, sample_volume);
+       int object_type = PID_TYPE(pid),
+           object_id = PID_ID(pid);
+       if (uNumRepeats)
+         AIL_set_sample_loop_count(pMixerChannels[13].hSample, uNumRepeats - 1);
+       pMixerChannels[13].uSourceTrackIdx = sound_id;
+       pMixerChannels[13].source_pid = pid;
+       pMixerChannels[13].uSourceTrackID = eSoundID;
+       int rval = AIL_start_sample(pMixerChannels[13].hSample);//no sound chest close 
+       if ( sPlaybackRate )
+         AIL_set_sample_playback_rate(pMixerChannels[13].hSample, sPlaybackRate);
+       if (object_type == OBJECT_Player)
+         AIL_sample_ms_position(pMixerChannels[13].hSample, &sLastTrackLengthMS, 0);
+       return;
+    }
+    else if (pid < 0)    // exclusive sounds - no override (close chest)
+    {
+      start_channel = 14;
+      end_channel = 14;
+      for (uint i = start_channel; i <= end_channel; ++i)
+      {
+        if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+        {
+          if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+            return;                          // already playing the same sound from the same source - return
+          AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      for ( uint j = start_channel; j <= end_channel; j++ )
+      {
+        if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+        {
+          AIL_init_sample(pMixerChannels[j].hSample);
+          char *p = (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id];
+          if (sound_data_id == 0)  p = p + 4;//for RIFF
+		  if ( eSoundID == 75 )//  Ritor1: include +7 for pSounds[20]
+			  p = p + 7;
+          AIL_set_sample_file(pMixerChannels[j].hSample, p, -1);
+          if ( sample_volume == 10000 )
+            sample_volume = uMasterVolume;
+          if (uVolume)
+            sample_volume = uVolume;
+          int object_type = PID_TYPE(pid),
+              object_id = PID_ID(pid);
+          if (uNumRepeats)
+            AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+          pMixerChannels[j].uSourceTrackIdx = sound_id;
+          pMixerChannels[j].source_pid = pid;
+          pMixerChannels[j].uSourceTrackID = eSoundID;
+          int rval = AIL_start_sample(pMixerChannels[j].hSample);//no sound chest close 
+          if ( sPlaybackRate )
+            AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+          if (object_type == OBJECT_Player)
+            AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+          return;
+        }
+      }
+      return;
+    }
+    else
+    {
+        int object_type = PID_TYPE(pid),
+            object_id = PID_ID(pid);
+        switch (object_type)
+        {
+          case OBJECT_BLVDoor:
+          {
+            assert(uCurrentlyLoadedLevelType == LEVEL_Indoor);
+            assert(object_id < pIndoor->uNumDoors);
+            if ( !pIndoor->pDoors[object_id].uDoorID )
+              return;
+
+            start_channel = 10;
+            end_channel = 12;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+              {
+                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                /*if (!GetSoundStrengthByDistanceFromParty(pIndoor->pDoors[object_id].pXOffsets[0], pIndoor->pDoors[object_id].pYOffsets[0], pIndoor->pDoors[object_id].pZOffsets[0]))
+                {
+                  AIL_end_sample(pMixerChannels[j].hSample);
+                  FreeChannel(&pMixerChannels[j]);
+                  return;
+                } */
+                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pIndoor->pDoors[object_id].pXOffsets[0], pIndoor->pDoors[object_id].pYOffsets[0]));
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          case OBJECT_Player:
+          {
+            start_channel = 10;
+            end_channel = 12;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+              {
+                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          case OBJECT_Actor:
+          {
+            start_channel = 0;
+            end_channel = 3;
+            assert(object_id < uNumActors);
+            sample_volume = GetSoundStrengthByDistanceFromParty(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y, pActors[object_id].vPosition.z);
+            if (!sample_volume)
+              return;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+              {
+                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample( pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                if (!GetSoundStrengthByDistanceFromParty(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y, pActors[object_id].vPosition.z))
+                  return;
+                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pActors[object_id].vPosition.x, pActors[object_id].vPosition.y));
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          case OBJECT_Decoration:
+          {
+            start_channel = 4;
+            end_channel = 4;
+            assert(object_id < uNumLevelDecorations);
+            sample_volume = GetSoundStrengthByDistanceFromParty(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y, pLevelDecorations[object_id].vPosition.z);
+            if (!sample_volume)
+              return;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )//çâóê ôîíòàíà è øàãîâ íå ïðîõîäÿò ïðîâåðêó íà ïîâòîð
+              {
+                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                if (!GetSoundStrengthByDistanceFromParty(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y, pLevelDecorations[object_id].vPosition.z))
+                  return;
+                AIL_set_sample_pan(pMixerChannels[j].hSample, sub_4AB66C(pLevelDecorations[object_id].vPosition.x, pLevelDecorations[object_id].vPosition.y));
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          case OBJECT_Item:
+          {
+            start_channel = 5;
+            end_channel = 7;
+            assert(object_id < uNumSpriteObjects);
+            sample_volume = GetSoundStrengthByDistanceFromParty(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y, pSpriteObjects[object_id].vPosition.z);
+            if (!sample_volume)
+              return;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+              {
+                if (pMixerChannels[i].uSourceTrackIdx == sound_id)
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                if (!GetSoundStrengthByDistanceFromParty(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y, pSpriteObjects[object_id].vPosition.z) )
+                  return;
+                AIL_set_sample_pan(pMixerChannels[v62].hSample, sub_4AB66C(pSpriteObjects[object_id].vPosition.x, pSpriteObjects[object_id].vPosition.y));
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          case OBJECT_BModel:
+          {
+            start_channel = 8;
+            end_channel = 9;
+            for (uint i = start_channel; i <= end_channel; ++i)
+            {
+              if ( pMixerChannels[i].source_pid == pid && AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Playing )
+              {
+                if ( pMixerChannels[i].uSourceTrackIdx == sound_id )
+                  return;                          // already playing the same sound from the same source - return
+                AIL_end_sample(pMixerChannels[i].hSample);  // requested new sound from the same source - end & switch
+                FreeChannel(&pMixerChannels[i]);
+              }
+            }
+            for ( uint j = start_channel; j <= end_channel; j++ )
+            {
+              if ( AIL_sample_status(pMixerChannels[j].hSample) == AIL::Sample::Done )
+              {
+                AIL_init_sample(pMixerChannels[j].hSample);
+                AIL_set_sample_file(pMixerChannels[j].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+                if (uVolume)
+                  sample_volume = uVolume;
+                AIL_set_sample_volume(pMixerChannels[j].hSample, sample_volume);
+                if (uNumRepeats)
+                  AIL_set_sample_loop_count(pMixerChannels[j].hSample, uNumRepeats - 1);
+                pMixerChannels[j].uSourceTrackIdx = sound_id;
+                pMixerChannels[j].source_pid = pid;
+                pMixerChannels[j].uSourceTrackID = eSoundID;
+                int rval = AIL_start_sample(pMixerChannels[j].hSample);
+                if ( sPlaybackRate )
+                  AIL_set_sample_playback_rate(pMixerChannels[j].hSample, sPlaybackRate);
+                if (object_type == OBJECT_Player)
+                  AIL_sample_ms_position(pMixerChannels[j].hSample, &sLastTrackLengthMS, 0);
+                return;
+              }
+            }
+          }
+          return;
+
+          default:
+            assert(false);
+        }
+      }
+
+	  __debugbreak();//Ritor1
+      if (start_channel > end_channel)  // no free channel - occupy the quitest one
+      {
+        start_channel = -1;
+        int min_volume = sample_volume;
+        for (uint i = start_channel; i <= end_channel; ++i)
+        {
+          int volume = AIL_sample_volume(pMixerChannels[i].hSample);
+          if (volume < min_volume)
+          {
+            min_volume = volume;
+            start_channel = i;
+          }
+        }
+        if (v62 == -1)   // no free channels at all - only channel 13 allows override (a3 == -1)
+        {
+          if (start_channel != 13)
+            return;
+          v62 = 13;
+        }
+        AIL_end_sample(pMixerChannels[v62].hSample);
+        FreeChannel(&pMixerChannels[v62]);
+      }
+
+      if (v62 > end_channel)//10!=13
+        return;
+
+      if ( sample_volume == 10000 )
+        sample_volume = uMasterVolume;
+
+      AIL_init_sample(pMixerChannels[v62].hSample);
+      AIL_set_sample_file(pMixerChannels[v62].hSample, (char *)pSoundList->pSL_Sounds[sound_id].pSoundData[sound_data_id] + 4 * (sound_data_id == 0), -1);
+      if (uVolume)
+        sample_volume = uVolume;
+      AIL_set_sample_volume(pMixerChannels[v62].hSample, sample_volume);
+
+      int object_type = PID_TYPE(pid),
+          object_id = PID_ID(pid);
+      if (source_x != -1)
+      {
+        if (!source_x)
+          source_x = pParty->vPosition.x;
+        if (!source_y)
+          source_y = pParty->vPosition.y;
+        AIL_set_sample_pan(pMixerChannels[v62].hSample, sub_4AB66C(source_x, source_y));
+        AIL_set_sample_volume(pMixerChannels[v62].hSample, GetSoundStrengthByDistanceFromParty(source_x, source_y, pParty->vPosition.z));
+      }
+
+      if (uNumRepeats)
+        AIL_set_sample_loop_count(pMixerChannels[v62].hSample, uNumRepeats - 1);
+      pMixerChannels[v62].uSourceTrackIdx = sound_id;
+      pMixerChannels[v62].source_pid = pid;
+      pMixerChannels[v62].uSourceTrackID = eSoundID;
+      int rval = AIL_start_sample(pMixerChannels[v62].hSample);
+      if ( sPlaybackRate )
+        AIL_set_sample_playback_rate(pMixerChannels[v62].hSample, sPlaybackRate);
+      if (object_type == OBJECT_Player)
+        AIL_sample_ms_position(pMixerChannels[v62].hSample, &sLastTrackLengthMS, 0);
+      return; 
+  }
+  else
+  {
+  __debugbreak(); // 3d sound stuff, refactor
+  v12 = 13;
+  if ( pid < 0 )
+  {
+    v15 = pAudioPlayer->uNum3DSamples;
+    if ( pid == -1 )
+    {
+      if ( v15 < 16 )
+        v12 = v15 - 1;
+      v96 = v12;
+      //goto LABEL_46;
+	  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+      pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
+      v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+      goto LABEL_47;
+    }
+    if ( v15 >= 16 )
+      v15 = 14;
+    v12 = v15;
+    //goto LABEL_45;
+	v96 = v15;
+    pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+    pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
+    v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+    goto LABEL_47;
+  }
+  if ( PID_TYPE(pid) == 2 )
+  {
+    v22 = pAudioPlayer->uNum3DSamples;
+    if ( v22 < 16 )
+    {
+      v12 = 5 * v22 / 16;
+      v96 = 7 * v22 / 16;
+    }
+    else
+    {
+      v96 = 7;
+      v12 = 5;
+    }
+    pLayingItem = &pSpriteObjects[PID_ID(pid)];
+  }
+  else
+  {
+    if ( PID_TYPE(pid) == 3 )
+    {
+      v18 = pAudioPlayer->uNum3DSamples;
+      v12 = 0;
+      if ( v18 < 16 )
+        v96 = 3 * v18 / 16;
+      else
+        v96 = 3;
+      pActor1 = &pActors[PID_ID(pid)];
+      v20 = pActor1->vPosition.y;
+      pRenderVertexSoft.vWorldPosition.x = (double)pActor1->vPosition.x;
+      v100 = pActor1->vPosition.z;
+      pRenderVertexSoft.vWorldPosition.y = (double)v20;
+      v21 = (double)v100;
+      goto LABEL_47;
+    }
+    if ( PID_TYPE(pid) != 5 )
+    {
+      v13 = pAudioPlayer->uNum3DSamples;
+      if ( PID_TYPE(pid) == 6 )
+      {
+        if ( v13 >= 16 )
+        {
+          v96 = 9;
+          v12 = 8;
+          //goto LABEL_46;
+		  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+          pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
+		  v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+		  goto LABEL_47;
+        }
+        v12 = 8 * v13 / 16;
+        v14 = 9 * v13;
+      }
+      else
+      {
+        if ( v13 >= 16 )
+        {
+          v96 = 12;
+          v12 = 10;
+//LABEL_46:
+          pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+          pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
+          v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+          goto LABEL_47;
+        }
+        v12 = 10 * v13 / 16;
+        v14 = 12 * v13;
+      }
+      v15 = v14 / 16;
+//LABEL_45:
+      v96 = v15;
+      //goto LABEL_46;
+	  pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+      pRenderVertexSoft.vWorldPosition.y = (double)pParty->vPosition.y;
+      v21 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+      goto LABEL_47;
+    }
+    v16 = pAudioPlayer->uNum3DSamples;
+    if ( v16 < 16 )
+    {
+      v12 = v16 / 4;
+      v96 = v16 / 4;
+    }
+    else
+    {
+      v12 = 4;
+      v96 = 4;
+    }
+    pLayingItem = (SpriteObject *)&pLevelDecorations[PID_ID(pid)];
+  }
+  pRenderVertexSoft.vWorldPosition.x = (double)pLayingItem->vPosition.x;
+  pRenderVertexSoft.vWorldPosition.y = (double)pLayingItem->vPosition.y;
+  v21 = (double)pLayingItem->vPosition.z;
+LABEL_47:
+  pRenderVertexSoft.vWorldPosition.z = v21;
+  if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+    sub_4AAEA6_transform(&pRenderVertexSoft);
+  else
+    pGame->pIndoorCameraD3D->ViewTransform(&pRenderVertexSoft, 1);
+  if ( pid )
+  {
+    if ( pid != -1 )
+    {
+      v101 = 0;
+      if ( pAudioPlayer->uNum3DSamples > 0 )
+      {
+        pAudioPlayer_3DSample = pAudioPlayer->p3DSamples;
+        do
+        {
+          if ( AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 
+			  && pAudioPlayer_3DSample->field_4 == pid && AIL_3D_sample_status(pAudioPlayer_3DSample->hSample) == 4 )
+          {
+            if ( pAudioPlayer_3DSample->field_8 == sound_id )
+              return;
+            AIL_end_3D_sample(pAudioPlayer_3DSample->hSample);
+            pAudioPlayer->_4ABF23(pAudioPlayer_3DSample);
+          }
+          ++v101;
+          ++pAudioPlayer_3DSample;
+        }
+        while ( v101 < pAudioPlayer->uNum3DSamples );
+      }
+    }
+  }
+  v102 = v12;
+  if ( v12 <= v96 )
+  {
+    pAudioPlayer_3DSample1 = &pAudioPlayer->p3DSamples[v12];
+    while ( AIL_3D_sample_status(pAudioPlayer_3DSample1->hSample) != 2 )
+    {
+      ++v102;
+      ++pAudioPlayer_3DSample1;
+      if ( v102 > v96 )
+        goto LABEL_67;
+    }
+    AIL_end_3D_sample(pAudioPlayer_3DSample1->hSample);
+    if ( pAudioPlayer_3DSample1->field_8 )
+      pAudioPlayer->_4ABF23(pAudioPlayer_3DSample1);
+  }
+LABEL_67:
+  v25 = v96;
+  if ( v102 == v96 + 1 )
+  {
+    LODWORD(v91) = -1;
+    v103 = 0;
+    *(float *)&varC = pRenderVertexSoft.vWorldViewPosition.y * -0.012207031;
+    v93 = 0.0;
+    v26 = pRenderVertexSoft.vWorldViewPosition.x * 0.012207031;
+    *(float *)&uVolume = v26;
+    v27 = abs((signed __int64)v26);
+    v28 = abs((signed __int64)v93);
+    v29 = abs((signed __int64)*(float *)&varC);
+    v90 = int_get_vector_length(v29, v28, v27);
+    sPlaybackRate = v12;
+    if ( v12 > v25 )
+      goto LABEL_192;
+    pAudioPlayer_3DSample2 = &pAudioPlayer->p3DSamples[v12];
+    do
+    {
+      AIL_3D_position(pAudioPlayer_3DSample2->hSample, &varC, &v93, (long *)&uVolume);
+      v31 = abs((signed __int64)*(float *)&uVolume);
+      v32 = abs((signed __int64)v93);
+      v33 = abs((signed __int64)*(float *)&varC);
+      v34 = int_get_vector_length(v33, v32, v31);
+      v35 = v103 == v34;
+      if ( v103 < v34 )
+      {
+        v103 = v34;
+        v35 = 1;
+      }
+      if ( v35 && v90 < v103 )
+      {
+        v36 = sPlaybackRate;
+        LODWORD(v91) = sPlaybackRate;
+      }
+      else
+      {
+        v36 = LODWORD(v91);
+      }
+      ++sPlaybackRate;
+      ++pAudioPlayer_3DSample2;
+    }
+    while ( sPlaybackRate <= v96 );
+    if ( v36 == -1 )
+    {
+LABEL_192:
+      v36 = 13;
+      if ( v12 != 13 )
+        return;
+    }
+    //pAudioPlayer2 = pAudioPlayer;
+    pAudioPlayer_3DSample3 = &pAudioPlayer->p3DSamples[v36];
+    AIL_end_3D_sample(pAudioPlayer_3DSample3->hSample);
+    pAudioPlayer->_4ABF23(pAudioPlayer_3DSample3);
+    v102 = v36;
+  }
+  //v39 = v89;
+  if ( pSoundList->pSL_Sounds[sound_id].p3DSound || (LOWORD(v40) = pSoundList->LoadSound(eSoundID, 0), v40) )
+  {
+    v41 = (char *)pAudioPlayer + 16 * v102;
+    v42 = (int)(v41 + 20);
+    if ( AIL_set_3D_sample_file(*((int *)v41 + 5), *(void **)((char *)&pSoundList->pSL_Sounds->p3DSound + sound_id * sizeof(SoundDesc))) )
+    {
+      if ( uNumRepeats )
+        v86 = uNumRepeats - 1;
+      else
+        v86 = 1;
+      AIL_set_3D_sample_loop_count(*(int *)v42, v86);
+      if ( source_x == -1 )
+      {
+        if ( PID_TYPE(pid) == 1 )
+        {
+          if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+          {
+			//goto LABEL_103;
+            pBLVDoor = &pIndoor->pDoors[PID_ID(pid)];
+            if ( !pBLVDoor->uDoorID )
+             return;
+            pRenderVertexSoft.vWorldPosition.x = (double)*pBLVDoor->pXOffsets;
+            pRenderVertexSoft.vWorldPosition.y = (double)*pBLVDoor->pYOffsets;
+            v47 = (double)*pBLVDoor->pZOffsets;
+LABEL_101:
+            pRenderVertexSoft.vWorldPosition.z = v47;
+          //if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+          //{
+            sub_4AAEA6_transform(&pRenderVertexSoft);
+            //goto LABEL_104;
+          //}
+		  }
+//LABEL_103:
+		  if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )
+            pGame->pIndoorCameraD3D->ViewTransform(&pRenderVertexSoft, 1);
+//LABEL_104:
+          AIL_start_3D_sample(*(int *)v42);
+          AIL_set_3D_sample_float_distances(*(int **)v42, 100.0, 20.0, 100.0, 20.0);
+          AIL_set_3D_sample_volume(*(int **)v42, pAudioPlayer->s3DSoundVolume);
+          v99 = pRenderVertexSoft.vWorldViewPosition.y * -0.012207031;
+          v49 = pRenderVertexSoft.vWorldViewPosition.x * 0.012207031;
+          uNumRepeatsa = v49;
+          v50 = abs((signed __int64)v49);
+          v51 = abs(0);
+          v52 = abs((signed __int64)v99);
+          if ( int_get_vector_length(v52, v51, v50) <= 100 )
+          {
+            AIL_set_3D_position((void *)*(int *)v42, LODWORD(v99), 0.0, LODWORD(uNumRepeatsa));
+            v53 = -uNumRepeatsa;
+            v54 = -v99;
+            AIL_set_3D_orientation((void *)*(int *)v42, LODWORD(v54), 0.0, LODWORD(v53), 0.0, 1.0, 0.0);
+            //pAudioPlayer3 = pAudioPlayer;
+            *((int *)v41 + 6) = pid;
+            *((int *)v41 + 7) = sound_id;
+            *(&pAudioPlayer->bEAXSupported + 4 * (v102 + 2)) = eSoundID;
+          }
+          else
+          {
+            AIL_end_3D_sample(*(int **)v42);
+            pAudioPlayer->_4ABF23((AudioPlayer_3DSample *)(v41 + 20));
+          }
+          return;
+        }
+        if ( PID_TYPE(pid) == 2 )
+        {
+          pLayingItem2 = &pSpriteObjects[PID_ID(pid)];
+        }
+        else
+        {
+          if ( PID_TYPE(pid) == 3 )
+          {
+            pActor = &pActors[PID_ID(pid)];
+            v46 = pActor->vPosition.y;
+            pRenderVertexSoft.vWorldPosition.x = (double)pActor->vPosition.x;
+            uNumRepeatsb = pActor->vPosition.z;
+            pRenderVertexSoft.vWorldPosition.y = (double)v46;
+            v47 = (double)uNumRepeatsb;
+            goto LABEL_101;
+          }
+          if ( PID_TYPE(pid) != 5 )
+          {
+            pRenderVertexSoft.vWorldPosition.x = (double)pParty->vPosition.x;
+            v43 = (double)pParty->vPosition.y;
+            pRenderVertexSoft.vWorldPosition.y = v43;
+            v47 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+            goto LABEL_101;
+          }
+          pLayingItem2 = (SpriteObject *)&pLevelDecorations[PID_ID(pid)];
+        }
+        pRenderVertexSoft.vWorldPosition.x = (double)pLayingItem2->vPosition.x;
+        pRenderVertexSoft.vWorldPosition.y = (double)pLayingItem2->vPosition.y;
+        v47 = (double)pLayingItem2->vPosition.z;
+        goto LABEL_101;
+      }
+      pRenderVertexSoft.vWorldPosition.x = (double)source_x;
+      v43 = (double)source_y;
+      pRenderVertexSoft.vWorldPosition.y = v43;
+      v47 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+      goto LABEL_101;
+    }
+  }
+  }
+}
+
+//----- (0040DEA5) --------------------------------------------------------
+void  AudioPlayer::MessWithChannels()
+{
+  pAudioPlayer->StopChannels(-1, -1);
+}
+
+
+//----- (004AAFCF) --------------------------------------------------------
+void AudioPlayer::UpdateSounds()
+{
+  int v2; // ebx@1
+  int v7; // ebx@6
+  int v8; // ebx@9
+  int v9; // ebx@10
+  int v10; // ebx@11
+  double v11; // st7@13
+  SpriteObject *v12; // eax@14
+  Actor *v13; // eax@15
+//  signed int v14; // edx@15
+  BLVDoor *pDoor; // eax@19
+  double v16; // st7@22
+  double v17; // st6@22
+  double v18; // st5@23
+  double v19; // st4@24
+  double v20; // st3@24
+  double v21; // st6@28
+  double v22; // st7@32
+  int v23; // ST1C_4@32
+  int v24; // ebx@32
+  int v25; // eax@32
+  float v26; // ST10_4@34
+  float v27; // ST08_4@34
+//  int v38; // eax@53
+//  __int16 v51; // ax@71
+  signed int v53; // eax@88
+  RenderVertexSoft a1; // [sp+24h] [bp-48h]@1
+  float v55; // [sp+54h] [bp-18h]@22
+  float v56; // [sp+58h] [bp-14h]@22
+  int uNumRepeats; // [sp+5Ch] [bp-10h]@15
+  float v58; // [sp+60h] [bp-Ch]@23
+  int v59; // [sp+64h] [bp-8h]@4
+
+  //pAudioPlayer = this;
+  v2 = 0;
+  //thisa = this;
+  //v3 = this->bPlayerReady == 0;
+  //a1.flt_2C = 0.0;
+  if (!bPlayerReady)
+    return;
+  
+  //if (field_2D0_time_left <= pEventTimer->uTimeElapsed)
+    //field_2D0_time_left = 32;
+  //else
+  //{
+    //field_2D0_time_left -= pEventTimer->uTimeElapsed;
+    //return;
+  //}
+  field_2D0_time_left -= pEventTimer->uTimeElapsed;
+  if ( field_2D0_time_left <= 0 )
+  {
+  field_2D0_time_left = 32;
+  if ( b3DSoundInitialized )//for 3D sound
+  {
+    __debugbreak(); // refactor refactor
+    v2 = 0;
+    for ( v59 = 0; v59 < pAudioPlayer->uNum3DSamples; ++v59 )
+    {
+      v7 = PID_TYPE(this->p3DSamples[v59].field_4);
+      if ( AIL_3D_sample_status(this->p3DSamples[v59].hSample) == AIL::Sample::Done )
+      {
+        AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+        pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+      }
+      if ( AIL_3D_sample_status(this->p3DSamples[v59].hSample) != AIL::Sample::Playing )
+        continue;
+      v8 = v7 - 1;//
+      if ( v8 )//> 1
+      {
+        v9 = v8 - 1;//
+        if ( v9 )//> 2
+        {
+          v10 = v9 - 1;//
+          if ( !v10 )//3
+          {
+            v13 = &pActors[PID_ID(this->p3DSamples[v59].field_4)];
+            //uNumRepeats = v13->vPosition.x;
+            //v14 = v13->vPosition.y;
+            a1.vWorldPosition.x = (double)v13->vPosition.x;
+            //uNumRepeats = v13->vPosition.z;
+            a1.vWorldPosition.y = (double)v13->vPosition.y;
+            //v11 = (double)uNumRepeats;
+            a1.vWorldPosition.z = v13->vPosition.z;
+            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+            {
+              v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
+              v17 = pGame->pIndoorCameraD3D->fRotationXSine;
+              v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
+              v56 = pGame->pIndoorCameraD3D->fRotationYSine;
+              if (pGame->pIndoorCameraD3D->sRotationX)
+              {
+                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+                v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+                //if ( pRenderer->pRenderD3D )
+                {
+                  v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
+                  v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
+                }
+                /*else
+                {
+                  v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
+                  v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
+                }*/
+                a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
+                a1.vWorldViewPosition.y = v20;
+                a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
+              }
+              else
+              {
+                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+                //if ( pRenderer->pRenderD3D )
+                {
+                  a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
+                  v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
+                }
+                /*else
+                {
+                  a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
+                  v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
+                }*/
+                a1.vWorldViewPosition.y = v21;
+                a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+              }
+            }
+            else
+              pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
+            v58 = a1.vWorldViewPosition.y * -0.012207031;
+            v22 = a1.vWorldViewPosition.x * 0.012207031;
+            *(float *)&uNumRepeats = v22;
+            v23 = abs((signed __int64)v22);
+            v24 = abs(0);
+            v25 = abs((signed __int64)v58);
+            if ( int_get_vector_length(v25, v24, v23) <= 100 )
+            {
+              AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
+              v26 = -*(float *)&uNumRepeats;
+              v27 = -v58;
+              AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
+            }
+            else
+            {
+              AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+              pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+            }
+            continue;
+          }
+          if ( v10 != 2 )//4
+          {
+            a1.vWorldPosition.x = (double)pParty->vPosition.x;
+            a1.vWorldPosition.y = (double)pParty->vPosition.y;
+            v11 = (double)pParty->sEyelevel + (double)pParty->vPosition.z;
+            a1.vWorldPosition.z = v11;
+            if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+            {
+              v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
+              v17 = pGame->pIndoorCameraD3D->fRotationXSine;
+              v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
+              v56 = pGame->pIndoorCameraD3D->fRotationYSine;
+              if (pGame->pIndoorCameraD3D->sRotationX)
+              {
+                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+                v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+                //if ( pRenderer->pRenderD3D )
+                {
+                  v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
+                  v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
+                }
+                /*else
+                {
+                  v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
+                  v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
+                }*/
+                a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
+                a1.vWorldViewPosition.y = v20;
+                a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
+              }
+              else
+              {
+                v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+                *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+                //if ( pRenderer->pRenderD3D )
+                {
+                  a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
+                  v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
+                }
+                /*else
+                {
+                  a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
+                  v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
+                }*/
+                a1.vWorldViewPosition.y = v21;
+                a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+              }
+            }
+            else
+              pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
+            v58 = a1.vWorldViewPosition.y * -0.012207031;
+            v22 = a1.vWorldViewPosition.x * 0.012207031;
+            *(float *)&uNumRepeats = v22;
+            v23 = abs((signed __int64)v22);
+            v24 = abs(0);
+            v25 = abs((signed __int64)v58);
+            if ( int_get_vector_length(v25, v24, v23) <= 100 )
+            {
+              AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
+              v26 = -*(float *)&uNumRepeats;
+              v27 = -v58;
+              AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
+            }
+            else
+            {
+              AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+              pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+            }
+            continue;
+          }//5
+          v12 = (SpriteObject *)&pLevelDecorations[PID_ID(this->p3DSamples[v59].field_4)];
+        }
+        else//2
+          v12 = &pSpriteObjects[PID_ID(this->p3DSamples[v59].field_4)];
+        a1.vWorldPosition.x = (double)v12->vPosition.x;
+        a1.vWorldPosition.y = (double)v12->vPosition.y;
+        v11 = (double)v12->vPosition.z;
+//LABEL_21:
+        a1.vWorldPosition.z = v11;
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+        {
+          v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
+          v17 = pGame->pIndoorCameraD3D->fRotationXSine;
+          v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
+          v56 = pGame->pIndoorCameraD3D->fRotationYSine;
+          if (pGame->pIndoorCameraD3D->sRotationX)
+          {
+            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+            v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+            //if ( pRenderer->pRenderD3D )
+            {
+              v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
+              v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
+            }
+            /*else
+            {
+              v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
+              v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
+            }*/
+            a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
+            a1.vWorldViewPosition.y = v20;
+            a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
+          }
+          else
+          {
+            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+            //if ( pRenderer->pRenderD3D )
+            {
+              a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
+              v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
+            }
+            /*else
+            {
+              a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
+              v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
+            }*/
+            a1.vWorldViewPosition.y = v21;
+            a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+          }
+        }
+        else
+          pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
+        v58 = a1.vWorldViewPosition.y * -0.012207031;
+        v22 = a1.vWorldViewPosition.x * 0.012207031;
+        *(float *)&uNumRepeats = v22;
+        v23 = abs((signed __int64)v22);
+        v24 = abs(0);
+        v25 = abs((signed __int64)v58);
+        if ( int_get_vector_length(v25, v24, v23) <= 100 )
+        {
+          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
+          v26 = -*(float *)&uNumRepeats;
+          v27 = -v58;
+          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
+        }
+        else
+        {
+          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+        }
+        continue;
+      }
+      if ( uCurrentlyLoadedLevelType != LEVEL_Indoor )//==1
+      {
+        pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
+        v58 = a1.vWorldViewPosition.y * -0.012207031;
+        v22 = a1.vWorldViewPosition.x * 0.012207031;
+        *(float *)&uNumRepeats = v22;
+        v23 = abs((signed __int64)v22);
+        v24 = abs(0);
+        v25 = abs((signed __int64)v58);
+        if ( int_get_vector_length(v25, v24, v23) <= 100 )
+        {
+          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
+          v26 = -*(float *)&uNumRepeats;
+          v27 = -v58;
+          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
+        }
+        else
+        {
+          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+        }
+        continue;
+      }
+      pDoor = &pIndoor->pDoors[PID_ID(this->p3DSamples[v59].field_4)];
+      if ( pDoor->uDoorID )
+      {
+        uNumRepeats = *pDoor->pXOffsets;
+        a1.vWorldPosition.x = (double)uNumRepeats;
+        uNumRepeats = *pDoor->pYOffsets;
+        a1.vWorldPosition.y = (double)uNumRepeats;
+        uNumRepeats = *pDoor->pZOffsets;
+        v11 = (double)uNumRepeats;
+        a1.vWorldPosition.z = v11;
+        if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
+        {
+          v16 = pGame->pIndoorCameraD3D->fRotationXCosine;
+          v17 = pGame->pIndoorCameraD3D->fRotationXSine;
+          v55 = pGame->pIndoorCameraD3D->fRotationYCosine;
+          v56 = pGame->pIndoorCameraD3D->fRotationYSine;
+          if (pGame->pIndoorCameraD3D->sRotationX)
+          {
+            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+            v18 = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+            //if ( pRenderer->pRenderD3D )
+            {
+              v19 = *(float *)&uNumRepeats * v56 + v58 * v55;
+              v20 = v58 * v56 - *(float *)&uNumRepeats * v55;
+            }
+            /*else
+            {
+              v19 = v58 * v55 - *(float *)&uNumRepeats * v56;
+              v20 = v58 * v56 + *(float *)&uNumRepeats * v55;
+            }*/
+            a1.vWorldViewPosition.x = v19 * v16 - v18 * v17;
+            a1.vWorldViewPosition.y = v20;
+            a1.vWorldViewPosition.z = v19 * v17 + v18 * v16;
+          }
+          else
+          {
+            v58 = a1.vWorldPosition.x - (double)pParty->vPosition.x;
+            *(float *)&uNumRepeats = a1.vWorldPosition.y - (double)pParty->vPosition.y;
+            //if ( pRenderer->pRenderD3D )
+            {
+              a1.vWorldViewPosition.x = *(float *)&uNumRepeats * v56 + v58 * v55;
+              v21 = v58 * v56 - *(float *)&uNumRepeats * v55;
+            }
+            /*else
+            {
+              a1.vWorldViewPosition.x = v58 * v55 - *(float *)&uNumRepeats * v56;
+              v21 = v58 * v56 + *(float *)&uNumRepeats * v55;
+            }*/
+            a1.vWorldViewPosition.y = v21;
+            a1.vWorldViewPosition.z = a1.vWorldPosition.z - (double)pParty->vPosition.z;
+          }
+        }
+        else
+          pGame->pIndoorCameraD3D->ViewTransform(&a1, 1);
+        v58 = a1.vWorldViewPosition.y * -0.012207031;
+        v22 = a1.vWorldViewPosition.x * 0.012207031;
+        *(float *)&uNumRepeats = v22;
+        v23 = abs((signed __int64)v22);
+        v24 = abs(0);
+        v25 = abs((signed __int64)v58);
+        if ( int_get_vector_length(v25, v24, v23) <= 100 )
+        {
+          AIL_set_3D_position(this->p3DSamples[v59].hSample, LODWORD(v58), 0.0, uNumRepeats);
+          v26 = -*(float *)&uNumRepeats;
+          v27 = -v58;
+          AIL_set_3D_orientation(this->p3DSamples[v59].hSample, LODWORD(v27), 0.0, LODWORD(v26), 0.0, 1.0, 0.0);
+        }
+        else
+        {
+          AIL_end_3D_sample(this->p3DSamples[v59].hSample);
+          pAudioPlayer->_4ABF23(&this->p3DSamples[v59]);
+        }
+      }
+    }
+    //}
+  }
+
+//LABEL_37:
+  for (int i = 0; i < uMixerChannels; ++i)
+  {
+    if (AIL_sample_status(pMixerChannels[i].hSample) == AIL::Sample::Done)
+    {
+      AIL_end_sample(pMixerChannels[i].hSample);
+      FreeChannel(&pMixerChannels[i]);
+    }
+  }
+
+  for (int i = 0; i < uMixerChannels; ++i)
+  {
+    if (pMixerChannels[i].source_pid <= 0)
+      continue;
+
+    int source_type = PID_TYPE(pMixerChannels[i].source_pid),
+        source_id = PID_ID(pMixerChannels[i].source_pid);
+//    int source_x,
+//       int source_y,
+//        source_z;
+
+    switch (source_type)
+    {
+      case 0:
+      case OBJECT_Player:
+      case OBJECT_BModel:
+        continue;
+
+      case OBJECT_BLVDoor:
+      {
+        assert(uCurrentlyLoadedLevelType == LEVEL_Indoor);
+
+        assert(source_id < pIndoor->uNumDoors);
+        if (!pIndoor->pDoors[source_id].uDoorID)
+          continue;
+
+        //source_x = pIndoor->pDoors[source_id].pXOffsets[0];
+        //source_y = pIndoor->pDoors[source_id].pYOffsets[0];
+        //source_z = pIndoor->pDoors[source_id].pZOffsets[0];
+        int sound_strength = GetSoundStrengthByDistanceFromParty(pIndoor->pDoors[source_id].pXOffsets[0],
+                                                                 pIndoor->pDoors[source_id].pYOffsets[0],
+                                                                 pIndoor->pDoors[source_id].pZOffsets[0]);
+        if ( sound_strength )
+        {
+          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
+          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pIndoor->pDoors[source_id].pXOffsets[0],
+                                                                 pIndoor->pDoors[source_id].pYOffsets[0]));
+        }
+        else
+        {
+          AIL_end_sample(pMixerChannels[i].hSample);
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      continue;
+
+      case OBJECT_Item:
+      {
+        //assert(source_id < uNumSpriteObjects); // Ritor1:â èäà äî è ïîñëå ïåðåõîäà îäèíàêîâî
+
+        //source_x = pSpriteObjects[source_id].vPosition.x;
+        //source_y = pSpriteObjects[source_id].vPosition.y;
+        //source_z = pSpriteObjects[source_id].vPosition.z;
+        int sound_strength = GetSoundStrengthByDistanceFromParty(pSpriteObjects[source_id].vPosition.x,
+                                                                 pSpriteObjects[source_id].vPosition.y,
+                                                                 pSpriteObjects[source_id].vPosition.z);
+        if ( sound_strength )
+        {
+          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
+          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pSpriteObjects[source_id].vPosition.x,
+                                                                   pSpriteObjects[source_id].vPosition.y));
+        }
+        else
+        {
+          AIL_end_sample(pMixerChannels[i].hSample);
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      continue;
+
+      case OBJECT_Decoration:
+      {
+        assert(source_id < uNumLevelDecorations);
+
+        //source_x = pLevelDecorations[source_id].vPosition.x;
+        //source_y = pLevelDecorations[source_id].vPosition.y;
+        //source_z = pLevelDecorations[source_id].vPosition.z;
+        int sound_strength = GetSoundStrengthByDistanceFromParty(pLevelDecorations[source_id].vPosition.x,
+                                                                 pLevelDecorations[source_id].vPosition.y,
+                                                                 pLevelDecorations[source_id].vPosition.z);
+        if ( sound_strength )
+        {
+          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
+          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pLevelDecorations[source_id].vPosition.x,
+                                                                   pLevelDecorations[source_id].vPosition.y));
+        }
+        else
+        {
+          AIL_end_sample(pMixerChannels[i].hSample);
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      continue;
+
+      case OBJECT_Actor:
+      {
+        assert(source_id < uNumActors);
+
+        //source_x = pActors[source_id].vPosition.x;
+        //source_y = pActors[source_id].vPosition.y;
+        //source_z = pActors[source_id].vPosition.z;
+        int sound_strength = GetSoundStrengthByDistanceFromParty(pActors[source_id].vPosition.x,
+                                                                 pActors[source_id].vPosition.y,
+                                                                 pActors[source_id].vPosition.z);
+        if ( sound_strength )
+        {
+          AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
+          AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(pActors[source_id].vPosition.x,
+                                                                   pActors[source_id].vPosition.y));
+        }
+        else
+        {
+          AIL_end_sample(pMixerChannels[i].hSample);
+          FreeChannel(&pMixerChannels[i]);
+        }
+      }
+      continue;
+
+      default:
+        assert(false);
+        continue;
+    }
+
+    /*if (int sound_strength = GetSoundStrengthByDistanceFromParty(source_x, source_y, source_z))
+    {
+      AIL_set_sample_volume(pMixerChannels[i].hSample, sound_strength);
+      AIL_set_sample_pan(pMixerChannels[i].hSample, sub_4AB66C(source_x, source_y));
+    }
+    else
+    {
+      AIL_end_sample(pMixerChannels[i].hSample);
+      FreeChannel(&pMixerChannels[i]);
+    } */
+  }
+
+  if (pCurrentScreen != SCREEN_GAME) //îòêëþ÷åíèå çâóêà äåêîðàöèé ïðè ïåðåêëþ÷åíèè îêíà èãðû
+  {
+    if (AIL_sample_status(pMixerChannels[4].hSample) == AIL::Sample::Playing)
+      AIL_end_sample(pMixerChannels[4].hSample);
+    return;
+  }
+  if (!_6807E0_num_decorations_with_sounds_6807B8)
+    return;
+
+  v55 = 0;
+      //v59 = 0;
+  for (uint i = 0; i < _6807E0_num_decorations_with_sounds_6807B8; ++i)
+  {
+    LODWORD(v56) = 1;
+        //v43 = _6807B8_level_decorations_ids[v59];
+        //v44 = &pLevelDecorations[_6807B8_level_decorations_ids[v59]];
+        //v45 = abs(v44->vPosition.z - pParty->vPosition.z);
+        //v46 = abs(v44->vPosition.y - pParty->vPosition.y);
+        //v47 = abs(v44->vPosition.x - pParty->vPosition.x);
+    LevelDecoration* decor = &pLevelDecorations[_6807B8_level_decorations_ids[i]];
+    if (int_get_vector_length(abs(decor->vPosition.x - pParty->vPosition.x),
+                              abs(decor->vPosition.y - pParty->vPosition.y),
+                              abs(decor->vPosition.z - pParty->vPosition.z)) > 0x2000)
+      continue;
+
+    DecorationDesc* decor_desc = &pDecorationList->pDecorations[decor->uDecorationDescID];
+      //v48 = &pDecorationList->pDecorations[decor->uDecorationDescID];
+      //v49 = v48->uFlags;
+      uNumRepeats = (~(unsigned __int8)decor_desc->uFlags & DECORATION_DESC_SLOW_LOOP) >> 6;
+ 
+    if (decor_desc->SoundOnDawn() || decor_desc->SoundOnDusk())
+    {
+        //v50 = decor->field_1A;
+        v55 = 0.0;
+        uNumRepeats = 2;
+        if (decor->field_1A)
+        {
+          //v51 = decor->field_1A - 32;
+          decor->field_1A = decor->field_1A - 32;
+          if ( decor->field_1A < 0 )
+            decor->field_1A = 0;
+        }
+    }
+
+      //v52 = v48->uFlags;
+    if (!decor_desc->SoundOnDawn())
+    {
+      if (!decor_desc->SoundOnDusk())
+      {
+        if ( v55 == 0.0 )
+        {
+          if ( v56 != 0.0 )
+          {
+            v53 = 8 * _6807B8_level_decorations_ids[i];
+            LOBYTE(v53) = v53 | OBJECT_Decoration;
+            PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);//sound of Boat and water(çâóêè êîðàáëÿ, ïëåñêàíèÿ âîäû)
+          }
+          continue;
+        }
+        if ( !decor->field_1A )
+          decor->field_1A = (rand() % 15 + 1) << 7;
+        if ( v56 != 0.0 )
+        {
+          v53 = 8 * _6807B8_level_decorations_ids[i];
+          LOBYTE(v53) = v53 | OBJECT_Decoration;
+          PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
+        }
+        continue;
+      }
+      if ( v55 != 0.0 )
+      {
+        if ( !decor->field_1A )
+          decor->field_1A = (rand() % 15 + 1) << 7;
+        if ( v56 != 0.0 )
+        {
+          v53 = 8 * _6807B8_level_decorations_ids[i];
+          LOBYTE(v53) = v53 | OBJECT_Decoration;
+          PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
+        }
+        continue;
+      }
+    }
+    v56 = 0.0;
+
+    if (pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 6 ||
+        pParty->uCurrentHour >= 20 && pParty->uCurrentHour < 21)
+    {
+        if ( !decor->field_1A && rand() % 100 < 100 )
+          LODWORD(v56) = 1;
+        LODWORD(v55) = 1;
+    }
+    if ( v55 == 0.0 )
+    {
+      if ( v56 != 0.0 )
+      {
+        v53 = 8 * _6807B8_level_decorations_ids[i];
+        LOBYTE(v53) = v53 | OBJECT_Decoration;
+        PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
+      }
+      continue;
+    }
+    if ( !decor->field_1A )
+      decor->field_1A = (rand() % 15 + 1) << 7;
+    if ( v56 != 0.0 )
+    {
+      v53 = 8 * _6807B8_level_decorations_ids[i];
+      LOBYTE(v53) = v53 | OBJECT_Decoration;
+      PlaySound((SoundID)decor_desc->uSoundID, v53, uNumRepeats, -1, 0, 0, 0, 0);
+    }
+    continue;
+  }
+  }
+}
+
+//----- (004AB66C) --------------------------------------------------------
+int __fastcall sub_4AB66C(int a1, int a2)
+{
+  signed int v2; // eax@1
+
+  v2 = stru_5C6E00->uDoublePiMask & (stru_5C6E00->Atan2(a1 - pParty->vPosition.x, a2 - pParty->vPosition.y)
+                                  - stru_5C6E00->uIntegerHalfPi - pParty->sRotationY);
+  if ( v2 > (signed int)stru_5C6E00->uIntegerPi )
+    v2 = 2 * stru_5C6E00->uIntegerPi - v2;
+  return (v2 >> 3) - (v2 >> 10);
+}
+// 4AB66C: using guessed type int __fastcall sub_4AB66C(int, int);
+
+//----- (004AB6B1) --------------------------------------------------------
+int GetSoundStrengthByDistanceFromParty(int x, int y, int z)
+{
+  int dir_x; // ST08_4@1
+  int dir_y; // esi@1
+  int dir_z; // eax@1
+  int length; // [sp+10h] [bp+8h]@1
+
+  dir_z = abs(z - pParty->vPosition.z);
+  dir_y = abs(y - pParty->vPosition.y);
+  dir_x = abs(x - pParty->vPosition.x);
+  length = int_get_vector_length(dir_x, dir_y, dir_z);
+  if ( length <= 0x2000 )
+    return 114 - (unsigned __int64)(signed __int64)((double)length * 0.0001220703125 * 100.0);
+  else
+    return 0;
+}
+
+//----- (004AB71F) --------------------------------------------------------
+void AudioPlayer::StopChannels(int uStartChannel, int uEndChannel)
+{
+  if ( bPlayerReady )
+  {
+    if ( b3DSoundInitialized )
+    {
+      for ( uint i = 0; i < uNum3DSamples; ++i )
+      {
+        if ( (uStartChannel == -1 || i < uStartChannel || i > uEndChannel)
+            && p3DSamples[i].field_8 && pSoundList->pSL_Sounds[p3DSamples[i].field_8].eType != SOUND_DESC_SYSTEM)
+        {
+          AIL_end_3D_sample(p3DSamples[i].hSample);
+          _4ABF23(&p3DSamples[i]);
+          p3DSamples[i].field_4 = 0;
+        }
+      }
+    }
+    if ( hDigDriver )
+    {
+      for ( int i = 0; i < uMixerChannels; ++i )
+      {
+        if ( (uStartChannel == -1 || i < uStartChannel || i > uEndChannel)
+          && pSoundList->pSL_Sounds[pMixerChannels[i].uSourceTrackIdx].eType != SOUND_DESC_SYSTEM)//âñå, êðîìå ñèñòåìíûõ çâóêîâ, îòêëþ÷àþòñÿ
+        {
+          AIL_end_sample(pMixerChannels[i].hSample);
+          FreeChannel(&pMixerChannels[i]);
+          pMixerChannels[i].source_pid = 0;
+        }
+      }
+    }
+    if (hSequence)
+      AIL_end_sequence(hSequence);
+    if (hStream)
+      AIL_pause_stream(hStream, 1);
+  }
+}
+
+//----- (004AB818) --------------------------------------------------------
+void AudioPlayer::LoadAudioSnd()
+{
+  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3
+
+  hAudioSnd = CreateFileA("Sounds\\Audio.snd", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, 0);
+  if (hAudioSnd == INVALID_HANDLE_VALUE)
+  {
+    Log::Warning(L"Can't open file: %s", L"Sounds\\Audio.snd");
+    return;
+  }
+
+  ReadFile(hAudioSnd, &uNumSoundHeaders, 4, &NumberOfBytesRead, 0);
+  pSoundHeaders = nullptr;
+  pSoundHeaders = (SoundHeader *)malloc(52 * uNumSoundHeaders + 2);
+  ReadFile(hAudioSnd, pSoundHeaders, 52 * uNumSoundHeaders, &NumberOfBytesRead, 0);
+}
+
+//----- (004AB8CE) --------------------------------------------------------
+void AudioPlayer::Initialize()
+{
+  int v3; // ebx@1
+  _PROVIDER *v6; // eax@9
+  int v12; // [sp+Ch] [bp-Ch]@9
+  char *Str1; // [sp+10h] [bp-8h]@6
+  int v14; // [sp+14h] [bp-4h]@5
+
+  //WriteWindowsRegistryString( "3DSoundProvider", "Aureal A3D Interactive(TM)");//çàïèñü â ðååñòð äëÿ 3D çâóêà(Microsoft DirectSound3D with Creative Labs EAX(TM))
+
+  v3 = 0;
+  //this->hWindow = hWnd;
+  this->hAILRedbook = 0;
+  this->hDigDriver = 0;
+  this->dword_0002AC = 0;
+  this->hSequence = 0;
+  this->uMasterVolume = 127;
+  this->dword_0002C8 = 64;
+  this->dword_0002CC = 2;
+
+  MSS32_DLL_Initialize();
+  BINKW32_DLL_Initialize();
+  SMACKW32_DLL_Initialize();
+  
+  AIL_startup();
+  if (bCanLoadFromCD)
+    hAILRedbook = AIL_redbook_open_drive(cMM7GameCDDriveLetter/*cGameCDDriveLetter*/);
+  //else
+  //  hAILRedbook = AIL_redbook_open(0);
+  //v4 = Audio_GetFirstHardwareDigitalDriver();
+
+  hDigDriver = Audio_GetFirstHardwareDigitalDriver();
+  if ( hDigDriver )
+    SmackSoundUseMSS(hDigDriver);
+  if ( ReadWindowsRegistryInt("Disable3DSound", 0) != 1 && true)//pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT )
+  {
+    v14 = 0;
+    bEAXSupported = 0;
+    b3DSoundInitialized = 0;
+    ReadWindowsRegistryString("3DSoundProvider", p3DSoundProvider, 128, "NONE");
+    CheckA3DSupport(true);
+    HPROVIDER prov;
+    while ( AIL_enumerate_3D_providers(&v14, &prov, &Str1) )
+    {
+      if ( !strcmp(Str1, p3DSoundProvider) )
+      {
+        if ( AIL_open_3D_provider(prov) )
+        {
+          bEAXSupported = 0;
+          b3DSoundInitialized = 0;
+          h3DSoundProvider = 0;
+        }
+        else
+        {
+          v6 = prov;
+          //v7 = prov;
+          b3DSoundInitialized = 1;
+          h3DSoundProvider = v6;
+          uNum3DSamples = 4;
+          AIL_3D_provider_attribute(prov, "EAX environment selection", &v12);
+          if ( v12 != -1 )
+            bEAXSupported = 1;
+        }
+        pAudioPlayer->_4AC0A2();
+        break;
+      }
+    }
+  }
+  for ( v3; v3 < uMixerChannels; ++v3 )
+  {
+    pMixerChannels[v3].hSample = AIL_allocate_sample_handle(hDigDriver);
+    if ( !pMixerChannels[v3].hSample )
+      break;
+  }
+  uMixerChannels = v3;
+  if ( bPlayerReady )
+    StopChannels(-1, -1);
+  //v10 = hAILRedbook;
+  bPlayerReady = true;
+  if ( hAILRedbook )
+  {
+    AIL_redbook_stop(hAILRedbook);
+    uNumRedbookTracks = AIL_redbook_tracks(hAILRedbook);
+  }
+  pAudioPlayer->sRedbookVolume = AIL_redbook_volume(hAILRedbook);
+  pAudioPlayer->SetMasterVolume(pSoundVolumeLevels[uSoundVolumeMultiplier] * 128.0f);
+  //unsigned __int64 t = (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 128.0f);
+  if ( bPlayerReady && hAILRedbook )
+    //AIL_redbook_set_volume(hAILRedbook, (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 128.0f));
+	AIL_redbook_set_volume(hAILRedbook, (unsigned __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0f) >> 32);
+  //int v = AIL_redbook_volume(pAudioPlayer->hAILRedbook);
+  //if (v)
+    //__debugbreak();
+  LoadAudioSnd();
+}
+
+//----- (004ABAF7) --------------------------------------------------------
+_DIG_DRIVER *Audio_GetFirstHardwareDigitalDriver(void)
+{
+  int v0; // ecx@1
+  size_t v2; // eax@4
+  signed int v3; // kr14_4@9
+  int v5; // [sp+10h] [bp-Ch]@2
+  unsigned int pNum_devices; // [sp+14h] [bp-8h]@1
+  _DIG_DRIVER *hDrv; // [sp+18h] [bp-4h]@3
+  
+  static int sample_Rate = 22050;
+  static int bitsPerSample = 16;
+  static int channels = 2;
+
+  AIL_set_preference(15, 0);
+  AIL_set_preference(33, 1);
+  v0 = sample_Rate;
+  pAudioPlayer->pDeviceNames[0][0] = 0;
+  pAudioPlayer->uNumDevices = 0;
+  pNum_devices = 0;
+
+  if ( sample_Rate < 11025 )
+    return 0;
+  v5 = 0;
+  while ( 1 )
+  {
+    while ( 1 )
+    {
+      pcmWaveFormat.wf.wFormatTag = WAVE_FORMAT_PCM;
+      pcmWaveFormat.wf.nChannels = channels;                                   // Channels: 1 = mono, 2 = stereo
+      pcmWaveFormat.wf.nSamplesPerSec = v0;                                    //÷àñòîòà îöèôðîâêè
+      pcmWaveFormat.wf.nBlockAlign = channels * bitsPerSample / 8;             //êîëè÷åñòâî äàííûõ â áëîêå
+      pcmWaveFormat.wBitsPerSample = bitsPerSample;
+      pcmWaveFormat.wf.nAvgBytesPerSec = pcmWaveFormat.wf.nSamplesPerSec * pcmWaveFormat.wf.nBlockAlign;
+      if ( !AIL_waveOutOpen(&hDrv, 0, -1, &pcmWaveFormat.wf) )
+      {
+        strcpy(pAudioPlayer->pDeviceNames[v5], "Device: ");
+        v2 = strlen(pAudioPlayer->pDeviceNames[v5]);
+        AIL_digital_configuration(hDrv, (int *)pAudioPlayer->array_000BF0 + v5, (int *)pAudioPlayer->array_000C30 + v5, (char *)pAudioPlayer->pDeviceNames + v2 + v5 * 32);
+        ++pNum_devices;
+        v5++;
+        pAudioPlayer->uNumDevices = pNum_devices;
+        if ( AIL_get_preference(15) )
+          return hDrv;
+        if ( !strstr(pAudioPlayer->pDeviceNames[v5 - 1], "Emulated") )
+          return hDrv;
+        AIL_waveOutClose(hDrv);
+        AIL_set_preference(15, 1);
+        break;
+	  }
+      if ( !AIL_get_preference(15) )
+      {
+        AIL_set_preference(15, 1);
+        if ( sample_Rate < 11025 )
+          return 0;
+	    break;
+      }
+      //v3 = sample_Rate;
+      v0 = sample_Rate / 2;
+      sample_Rate /= 2;
+      if ( sample_Rate / 2 < 11025 )
+      {
+        if ( bitsPerSample == 8 )
+       {
+          v0 = 22050;
+          bitsPerSample = 8;
+          sample_Rate = 22050;
+        }
+        if ( v0 < 11025 )
+          return 0;
+		break;
+      }
+    }
+  }
+}
+
+//----- (004ABC9B) --------------------------------------------------------
+void AudioPlayer::CheckA3DSupport(bool query)
+{
+  DWORD cbData; // [sp+8h] [bp-Ch]@1
+  HKEY hKey; // [sp+10h] [bp-4h]@1
+  hKey = 0;
+  cbData = 4;
+  if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Aureal\\A3D", 0, KEY_READ|KEY_WOW64_32KEY, &hKey))
+  {
+    int Aureal3D_SplashAudio = 0;
+    if (query)
+      RegQueryValueExA(hKey, "SplashAudio", 0, 0, (LPBYTE)&Aureal3D_SplashAudio, &cbData);
+    RegSetValueExA(hKey, "SplashAudio", 0, 4, (const BYTE *)&Aureal3D_SplashAudio, 4);
+
+    int Aureal3D_SplashScreen = 0;
+    if (query)
+      RegQueryValueExA(hKey, "SplashScreen", 0, 0, (LPBYTE)&Aureal3D_SplashScreen, &cbData);
+    RegSetValueExA(hKey, "SplashScreen", 0, 4, (const BYTE *)&Aureal3D_SplashScreen, 4);
+    RegCloseKey(hKey);
+  }
+}
+
+
+//----- (004ABD5B) --------------------------------------------------------
+void AudioPlayer::Release() //Îñâîáîäèòü
+{
+  MixerChannel *pMixerChannel; // ebx@3
+//  char v4; // dl@5
+  AudioPlayer_3DSample *p3DSample; // edi@7
+  void *v9; // ecx@15
+
+  if ( this->bPlayerReady )
+  {
+	free(pSoundHeaders);
+    CloseHandle(pMediaPlayer->hMagicVid);
+    CloseHandle(pMediaPlayer->hMightVid);
+    pAudioPlayer->StopChannels(-1, -1);
+    if ( pAudioPlayer->uMixerChannels > 0 )
+    {
+      pMixerChannel = pAudioPlayer->pMixerChannels;
+      for ( uint i = 0; i < pAudioPlayer->uMixerChannels; ++i )
+      {
+        AIL_release_sample_handle(pMixerChannel->hSample);
+        ++pMixerChannel;
+      }
+    }
+    if ( ReadWindowsRegistryInt("Disable3DSound", 0) != 1 )
+    {
+      CheckA3DSupport(false);
+      if ( pAudioPlayer->uNum3DSamples > 0 )
+      {
+        p3DSample = pAudioPlayer->p3DSamples;
+        for ( uint i = 0; i < pAudioPlayer->uNum3DSamples; ++i )
+        {
+          if ( p3DSample->hSample )
+          {
+            AIL_release_3D_sample_handle(p3DSample->hSample);
+            p3DSample->hSample = 0;
+          }
+          ++p3DSample;
+        }
+      }
+      if ( pAudioPlayer->h3DSoundProvider )
+      {
+        AIL_close_3D_provider(pAudioPlayer->h3DSoundProvider);
+        pAudioPlayer->h3DSoundProvider = 0;
+      }
+    }
+    if ( pAudioPlayer->hAILRedbook )
+    {
+      AIL_redbook_stop(pAudioPlayer->hAILRedbook);
+      AIL_redbook_set_volume((HREDBOOK)&pAudioPlayer->hAILRedbook, pAudioPlayer->sRedbookVolume);
+      AIL_redbook_close(pAudioPlayer->hAILRedbook);
+    }
+    AIL_shutdown();
+    pSoundList->Release();
+    v9 = *(void **)&pAudioPlayer->field_C78[0];
+    if ( v9 )
+      ReleaseSoundData(v9);
+    CloseHandle(pAudioPlayer->hAudioSnd);
+  }
+}
+
+//----- (004ABE55) --------------------------------------------------------
+void AudioPlayer::FreeChannel(MixerChannel *pChannel)
+{
+  int num_same_sound_on_channels; // eax@8
+  int v10; // ecx@12
+  int v12; // eax@13
+  int v14[16]; // [sp+Ch] [bp-48h]@8
+  int num_playing_channels; // [sp+4Ch] [bp-8h]@5
+
+  if (!pSoundList->pSL_Sounds)
+    return;
+
+  //v4 = &pSoundList->pSounds[pChannel->uSourceTrackIdx];
+  if ( pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].eType == SOUND_DESC_SWAP)
+  {
+    if ( pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].pSoundData[0] && 
+       !(pSoundList->pSL_Sounds[pChannel->uSourceTrackIdx].uFlags & SOUND_DESC_SYSTEM) )
+    {
+      num_playing_channels = 0;
+      num_same_sound_on_channels = 0;
+      if ( this->uMixerChannels <= 0 )
+        goto LABEL_16;
+      for ( uint i = 0; i < uMixerChannels; i++ )
+      {
+        if ( pChannel->uSourceTrackID == pMixerChannels[i].uSourceTrackID )
+        {
+          v14[num_same_sound_on_channels++] = i;
+          if ( AIL_sample_status((HSAMPLE)pMixerChannels[i].hSample) == AIL::Sample::Playing)
+            ++num_playing_channels;
+        }
+      }
+      if ( !num_playing_channels )
+      {
+LABEL_16:
+        pSoundList->UnloadSound(pChannel->uSourceTrackIdx, 1);
+        for ( v10 = 0; v10 < num_same_sound_on_channels; v10++ )
+        {
+          v12 = 16 * (v14[v10] + 47);
+          pMixerChannels[v14[v10]].uSourceTrackID = 0;
+          *(unsigned int *)((char *)&bEAXSupported + v12) = 0;
+        }
+      }
+    }
+  }
+}
+
+//----- (004ABF23) --------------------------------------------------------
+void AudioPlayer::_4ABF23(AudioPlayer_3DSample *a2)
+{
+  int v2; // ebx@1
+  unsigned __int8 v5; // zf@5
+  unsigned __int8 v6; // sf@5
+  char *v7; // edi@6
+  int v8; // eax@8
+  int v10; // ecx@12
+  int v11; // eax@13
+  int v13[16]; // [sp+Ch] [bp-48h]@8
+  int v14; // [sp+4Ch] [bp-8h]@5
+  int v15; // [sp+50h] [bp-4h]@5
+
+  if ( pSoundList->pSL_Sounds )
+  {
+    //v4 = &pSoundList->pSounds[a2->field_8];
+    if ( pSoundList->pSL_Sounds[a2->field_8].eType == SOUND_DESC_SWAP)
+    {
+      if ( pSoundList->pSL_Sounds[a2->field_8].p3DSound && !(pSoundList->pSL_Sounds[a2->field_8].uFlags & SOUND_DESC_SYSTEM) )
+      {
+        v5 = this->uNum3DSamples == 0;
+        v6 = this->uNum3DSamples < 0;
+        v14 = 0;
+        v15 = 0;
+        if ( v6 | v5 )
+          goto LABEL_16;
+        v7 = (char *)this->p3DSamples;
+        __debugbreak();//Ritor1
+        for ( v2 = 0; v2 < uNum3DSamples; ++v2 )
+        {
+          if ( a2->field_C == *((int *)v7 + 3) )
+          {
+            v8 = v15;
+            //v9 = this->p3DSamples[v2];
+            ++v15;
+            v13[v8] = v2;
+            if ( AIL_3D_sample_status(&this->p3DSamples[v2]) == 4 )
+              ++v14;
+          }
+          v7 += 16;
+        }
+        if ( !v14 )
+        {
+LABEL_16:
+          pSoundList->UnloadSound(a2->field_8, 1);
+          for ( v10 = 0; v10 < v15; v10++ )
+          {
+            v11 = v13[v10];
+            *(&bEAXSupported + 4 * (v11 + 2)) = 0;
+            p3DSamples[v11].field_8 = 0;
+          }
+        }
+      }
+    }
+  }
+}
+
+//----- (004ABFDB) --------------------------------------------------------
+void PlayLevelMusic()
+{
+  unsigned int v0; // eax@1
+
+  v0 = pMapStats->GetMapInfo(pCurrentMapName);
+  if ( v0 )
+    pAudioPlayer->PlayMusicTrack((MusicID)pMapStats->pInfos[v0].uRedbookTrackID);
+}
+
+//----- (004AC004) --------------------------------------------------------
+void AudioPlayer::SetEAXPreferences()
+{
+  float v4; // [sp+4h] [bp-4h]@2
+
+  if ( this->bEAXSupported )
+  {
+    v4 = 0.0;
+    AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX effect volume", (int *)&v4);
+    v4 = 1.0;
+    AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX damping", (int *)&v4);
+  }
+}
+// 4D82DC: using guessed type int __stdcall AIL_set_3D_provider_preference(int, int, int);
+
+//----- (004AC041) --------------------------------------------------------
+void AudioPlayer::SetMapEAX()
+{
+  unsigned int pMapID; // eax@1
+  int v3; // [sp+4h] [bp-4h]@3
+
+  pMapID = pMapStats->GetMapInfo(pCurrentMapName);
+  if ( this->b3DSoundInitialized && this->bEAXSupported )
+  {
+    v3 = pMapStats->pInfos[pMapID].uEAXEnv;
+    if ( (unsigned int)v3 >= 0x1A )
+    {
+      SetEAXPreferences();
+      this->field_214 = -1;
+    }
+    else
+    {
+      AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX environment selection", &v3);
+      this->field_214 = v3;
+    }
+  }
+}
+// 4D82DC: using guessed type int __stdcall AIL_set_3D_provider_preference(int, int, int);
+
+//----- (004AC0A2) --------------------------------------------------------
+int AudioPlayer::_4AC0A2()
+{
+  unsigned int map_id; // eax@1
+  void *v9; // eax@8
+  int v12; // [sp+1Ch] [bp-8h]@1
+
+  if ( this->b3DSoundInitialized )
+  {
+    //v5 = &this->uNum3DSamples;
+    AIL_3D_provider_attribute(this->h3DSoundProvider, "Maximum supported samples", &this->uNum3DSamples);
+    if ( this->uNum3DSamples > 32 )
+      this->uNum3DSamples = 32;
+    //v6 = this->uNum3DSamples;
+    if ( !this->uNum3DSamples )
+    {
+      this->b3DSoundInitialized = 0;
+      return -1;
+    }
+    //v13 = 0;
+    //if ( this->uNum3DSamples > 0 )
+    //{
+      //v8 = this->p3DSamples;
+      //while ( 1 )
+      for ( int i = 0; i < this->uNum3DSamples; ++i )
+      {
+        v9 = (void *)AIL_allocate_3D_sample_handle(this->h3DSoundProvider);
+        this->p3DSamples[i].hSample = v9;
+        if ( !v9 )
+          this->uNum3DSamples = i;
+        AIL_set_3D_sample_float_distances(v9, 4096.0, 256.0, 4096.0, 256.0);
+        AIL_set_3D_sample_volume(this->p3DSamples[i].hSample, this->s3DSoundVolume);
+        //++v8;
+      }
+    //}
+    if ( this->bEAXSupported )
+    {
+      //v10 = v4;
+      //v11 = pMapStats->pInfos[map_id].uEAXEnv;
+      map_id = pMapStats->GetMapInfo(pCurrentMapName);
+      v12 = pMapStats->pInfos[map_id].uEAXEnv;
+      if ( pMapStats->pInfos[map_id].uEAXEnv >= 0x1A )
+      {
+        pAudioPlayer->SetEAXPreferences();
+        this->field_214 = -1;
+      }
+      else
+      {
+        AIL_set_3D_provider_preference(this->h3DSoundProvider, "EAX environment selection", &v12);
+        this->field_214 = v12;
+      }
+    }
+  }
+  return 1;
+}
+
+//----- (004A96BE) --------------------------------------------------------
+void ReleaseSoundData(void *_this)
+{
+  //for ( uint i = 0; (void *)&pSounds[i].pSoundData < (void *)&pSounds[2999].pSoundData; i++ )
+  for ( uint i = 0; i < 2999; i++ )
+  {
+    if ( pSounds[i].pSoundData == _this )
+    {
+      free(_this);
+      memset(&pSounds[i], 0, sizeof(pSounds[i]));
+    }
+  }
+
+}
+
+//----- (004A96FF) --------------------------------------------------------
+struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName)
+{
+/*  SoundHeader *result; // eax@2
+  SoundHeader *pSound;
+  signed int v6; // ebx@11
+
+  while ( 1 )
+  {
+    v6 = uEnd - uStart;
+    pSound = &pAudioPlayer->pSoundHeaders[v6 / 2 + uStart];
+    if ( !pSound )
+      return false;
+    result = (SoundHeader *)_stricmp(pName, pSound->pSoundName);
+    if ( !_stricmp(pName, pSound->pSoundName) )
+      uFindSound_BinSearch_ResultID = v6 / 2 + uStart;
+    if ( uStart == uEnd )
+    {
+      uFindSound_BinSearch_ResultID = -1;
+      return result;
+    }
+    if ( (signed int)result < 0 )
+      break;
+
+    if ( v6 <= 4 )
+    {
+      if ( (signed int)uStart < (signed int)uEnd )
+      {
+        for ( uint i = uStart; i < (signed int)uEnd; ++i )
+        {
+          if ( !_stricmp(pName, pAudioPlayer->pSoundHeaders[i].pSoundName) )
+          {
+            uFindSound_BinSearch_ResultID = i;
+            return &pAudioPlayer->pSoundHeaders[i];
+          }
+        }
+      }
+      uFindSound_BinSearch_ResultID = -1;
+      return false;
+    }
+
+    uStart += v6 / 2;
+LABEL_10:
+	;
+  }
+  if ( v6 > 4 )
+  {
+    uEnd = v6 / 2 + uStart;
+    goto LABEL_10;
+  }
+  if ( (signed int)uStart >= (signed int)uEnd )
+  {
+    uFindSound_BinSearch_ResultID = -1;
+    return false;
+  }*/
+  for ( uint i = uStart; i < (signed int)uEnd; ++i )
+  {
+    if ( !_stricmp(pName, pAudioPlayer->pSoundHeaders[i].pSoundName) )
+    {
+      uFindSound_BinSearch_ResultID = i;
+      return &pAudioPlayer->pSoundHeaders[i];
+    }
+  }
+  uFindSound_BinSearch_ResultID = -1;
+  return false;
+}
+// F1B4C8: using guessed type int uFindSound_BinSearch_ResultID;
+
+//----- (004A97C6) --------------------------------------------------------
+SoundData *LoadSound(const char *pSoundName, SoundData *pOutBuff, unsigned int uID)
+{
+  DWORD NumberOfBytesRead; // [sp+14h] [bp-8h]@8
+
+  for (uint i = 0; i < 3000; ++i)
+  {
+    if (pSounds[i].uID == uID)
+      return pSounds[i].pSoundData;
+  }
+  FindSound_BinSearch(0, pAudioPlayer->uNumSoundHeaders, pSoundName);
+  if ( uFindSound_BinSearch_ResultID == -1 )
+    return 0;
+  if ( pOutBuff == (SoundData *)-1 )
+    pOutBuff = (SoundData *)malloc(pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize + 4);
+  SetFilePointer(pAudioPlayer->hAudioSnd, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uFileOffset, 0, 0);
+  if ( (signed int)pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize >= (signed int)pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize )
+  {
+    pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize = pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
+    if ( pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize )
+    {
+      ReadFile(pAudioPlayer->hAudioSnd, pOutBuff->pData, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize, &NumberOfBytesRead, 0);// Ritor1: pSounds[20]
+    }
+    else
+    {
+      MessageBoxW(nullptr, L"Can't load sound file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Sound.cpp:448", 0);
+    }
+  }
+  else
+  {
+    uID = (unsigned int)malloc(pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize);
+    ReadFile(pAudioPlayer->hAudioSnd, (LPVOID)uID, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize, &NumberOfBytesRead, 0);
+    zlib::MemUnzip(pOutBuff->pData, &pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize, (const void *)uID, pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uCompressedSize);
+    free((void *)uID);
+  }
+  if ( pOutBuff )
+  {
+    pOutBuff->uDataSize = pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
+    uLastLoadedSoundID = 0;
+    if ( pSounds[0].pSoundData )
+    {
+      for ( uint i = 0; pSounds[i].pSoundData; i++ )
+        ++uLastLoadedSoundID;
+    }
+    strcpy((char *)pSounds[uLastLoadedSoundID].SoundName, pSoundName);
+    pSoundList->uTotalLoadedSoundSize += pAudioPlayer->pSoundHeaders[uFindSound_BinSearch_ResultID].uDecompressedSize;
+    pSounds[uLastLoadedSoundID].pSoundData = pOutBuff;
+    return pOutBuff;
+  }
+  else
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Audio/AudioPlayer.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,363 @@
+#pragma once
+#include "OSAPI.h"
+#include "Media/MediaPlayer.h"
+
+
+
+
+
+
+#pragma pack(push, 1)
+struct _PROVIDER {char unk_0;};
+struct _SAMPLE   {char unk_0;};
+//struct _STREAM   {char unk_0;};
+struct _REDBOOK  {char unk_0;};
+struct _DIG_DRIVER {char unk_0;};
+struct _SEQUENCE {char unk_0;};
+#pragma pack(pop)
+
+
+
+/*   22 */
+#pragma pack(push, 1)
+struct AudioPlayer_3DSample
+{
+  inline AudioPlayer_3DSample()
+  {
+    hSample = 0;
+    field_4 = 0;
+    field_8 = 0;
+    field_C = 0;
+  }
+
+  void *hSample;
+  int field_4;
+  int field_8;
+  int field_C;
+};
+#pragma pack(pop)
+
+
+
+
+/*   26 */
+/*#pragma pack(push, 1)
+struct SoundHeader
+{
+  char pSoundName[40];
+  unsigned int uFileOffset;
+  unsigned int uCompressedSize;
+  unsigned int uDecompressedSize;
+};
+#pragma pack(pop)*/
+
+/*   27 */
+#pragma pack(push, 1)
+struct MixerChannel
+{
+  inline MixerChannel():
+    hSample(nullptr), source_pid(0), uSourceTrackIdx(0), uSourceTrackID(0)
+  {}
+
+  _SAMPLE *hSample;
+  int source_pid;
+  unsigned int uSourceTrackIdx;
+  unsigned int uSourceTrackID;
+};
+#pragma pack(pop)
+
+
+
+
+
+/*  308 */
+enum SoundID
+{
+  SOUND_Invalid = 0,
+  SOUND_EnteringAHouse = 6,
+  SOUND_7 = 7,
+  SOUND_8 = 0x8,
+  SOUND_24 = 24,
+  SOUND_error = 27,
+  SOUND_RunAlongWater = 63,
+  SOUND_RunAlong3DModel = 64,
+  SOUND_Button = 66,
+  SOUND_67 = 67,
+  SOUND_71 = 71,
+  SOUND_Button2 = 75,
+  SOUND_78 = 78,
+  SOUND_80 = 80,
+  SOUND_81 = 81,
+  SOUND_83 = 83,
+  SOUND_84 = 84,
+  SOUND_85 = 85,
+  SOUND_WalkAlongWater = 102,
+  SOUND_WalkAlong3DModel = 103,
+  SOUND_Arcomage_LoseResources = 0x78,
+  SOUND_Arcomage_AddResources = 0x79,
+  SOUND_Arcomage_TowerWallDamage = 0x7A,
+  SOUND_Arcomage_DrawCard = 0x7B,
+  SOUND_Arcomage_124 = 0x7C,
+  SOUND_Arcomage_ProductionDamage = 0x7D,
+  SOUND_Arcomage_ProductionUpgrade = 0x7E,
+  SOUND_Arcomage_127 = 0x7F,
+  SOUND_Arcomage_128 = 0x80,
+  SOUND_Arcomage_TowerUpgrade = 0x81,
+  SOUND_Arcomage_130 = 0x82,
+  SOUND_Arcomage_131 = 0x83,
+  SOUND_Arcomage_WallUpgrade = 0x84,
+  SOUND_PlayLute = 133, // 85
+  SOUND_PlayFaeriePipes = 134, // 86
+  SOUND_PlayGryphonheartsTrumpet = 135, // 87
+  SOUND_GoldReceived = 0xC8,
+  SOUND_203 = 203,
+  SOUND_206 = 206,
+  SOUND_207 = 207,
+  SOUND_OpenChest = 208,
+  SOUND_PlayerCantCastSpell = 0xD1,
+  SOUND_EatApple = 211, // D3
+  SOUND_Bell = 0xD9,
+  SOUND_OpenBook = 230,
+  SOUND_CloseBook = 231,
+  SOUND_11090 = 11090,
+  SOUND_12040 = 12040,
+  SOUND_Arena_Welcome = 14060,
+  SOUND_20001 = 0x4E21,
+};
+
+
+enum MusicID: unsigned __int32
+{
+  MUSIC_Credits = 15
+};
+
+/*   20 */
+#pragma pack(push, 1)
+struct AudioPlayer
+{
+  //----- (004A9669) --------------------------------------------------------
+  AudioPlayer():
+    bPlayerReady(false), b3DSoundInitialized(false),
+    hAILRedbook(nullptr), hStream(nullptr)
+  {
+	/*AudioPlayer_3DSample *v0; //ecx@1
+	signed int v1; //edi@1
+
+	v0 = p3DSamples;
+	v1 = 32;
+	do
+	{
+		v0->field_4 = 0;
+		v0->field_8 = 0;
+		v0->field_C = 0;
+		v0->hSample = 0;
+		++v0;
+		--v1;
+	}
+	while (v1);*/
+    uMixerChannels = 16;
+    field_2D0_time_left = 256;
+    uNumRedbookTracks = 0;
+    uCurrentMusicTrackLength = 0;
+    field_2D4 = 0;
+    s3DSoundVolume = 127;
+  }
+  inline ~AudioPlayer(){ Release(); };
+  void SetMusicVolume(int vol);
+  void SetMasterVolume(float fVolume);
+  void _4AA258(int a2);
+  void PlaySound(SoundID eSoundID, signed int a3, unsigned int uNumRepeats, signed int a5, signed int a6, int a7, float uVolume, int sPlaybackRate);
+  void UpdateSounds();
+  void StopChannels(int uStartChannel, int uEndChannel);
+  void LoadAudioSnd();//
+  void Initialize();//
+  void CheckA3DSupport(bool query);
+  void Release();
+  void FreeChannel(MixerChannel *pChannel);
+  void _4ABF23(AudioPlayer_3DSample *a2);
+  void SetEAXPreferences();
+  void SetMapEAX();
+  int _4AC0A2();
+  void PlayMusicTrack(enum MusicID eTrack);
+  void  MessWithChannels();
+
+
+  unsigned int bEAXSupported;
+  unsigned int b3DSoundInitialized;
+  int s3DSoundVolume;
+  struct _PROVIDER *h3DSoundProvider;
+  int uNum3DSamples;
+  struct AudioPlayer_3DSample p3DSamples[32];
+  int field_214;
+  int sRedbookVolume;
+  char p3DSoundProvider[128];
+  unsigned int bPlayerReady;
+  //HWND hWindow;
+  class OSWindow *window;
+  struct _REDBOOK *hAILRedbook;
+  struct _DIG_DRIVER *hDigDriver;
+  int dword_0002AC;
+  struct _SEQUENCE *hSequence;
+  int dword_0002B4;
+  struct SoundHeader *pSoundHeaders;
+  HANDLE hAudioSnd;
+  unsigned int uNumSoundHeaders;
+  unsigned int uMasterVolume;
+  int dword_0002C8;
+  int dword_0002CC;
+  int field_2D0_time_left;
+  int field_2D4;
+  unsigned int uCurrentMusicTrackLength;
+  unsigned int uNumRedbookTracks;
+  unsigned int uCurrentMusicTrackStartMS;
+  unsigned int uCurrentMusicTrackEndMS;
+  struct MixerChannel pMixerChannels[16];
+  int uMixerChannels;
+  int field_3EC;
+  char pDeviceNames[16][128];
+  int array_000BF0[16];
+  int array_000C30[16];
+  unsigned int uNumDevices;
+  struct _STREAM *hStream;
+  char field_C78[8];
+  int cGameCDDriveLetter;
+};
+#pragma pack(pop)
+
+
+
+
+
+
+
+
+/*  325 */
+enum SOUND_DESC_TYPE : __int32
+{
+  SOUND_DESC_LEVEL = 0x0,
+  SOUND_DESC_SYSTEM = 0x1,
+  SOUND_DESC_SWAP = 0x2,
+  SOUND_DESC_3 = 0x3,
+  SOUND_DESC_LOCK = 0x4,
+};
+
+/*  326 */
+enum SOUND_DESC_FLAGS
+{
+  SOUND_DESC_LOCKED = 0x1,
+  SOUND_DESC_3D = 0x2,
+};
+
+
+#pragma pack(push, 1)
+struct SoundData
+{
+  unsigned int uDataSize;
+  char         pData[1];
+};
+
+struct SoundDesc_mm6
+{
+  inline bool Is3D()  {return (uFlags & SOUND_DESC_3D) != 0;}
+
+  char pSoundName[32];
+  unsigned int uSoundID;
+  SOUND_DESC_TYPE eType;
+  int uFlags;
+  SoundData *pSoundData[17];
+};
+
+struct SoundDesc: public SoundDesc_mm6
+{
+  void *p3DSound;
+  int bDecompressed;
+};
+#pragma pack(pop)
+
+
+
+#pragma pack(push, 1)
+struct SoundList
+{
+  inline SoundList():
+    sNumSounds(0), pSL_Sounds(nullptr), uTotalLoadedSoundSize(0)
+  {}
+
+  void Initialize();
+  __int16 LoadSound(int a1, unsigned int a3);
+  int LoadSound(unsigned int a2, LPVOID lpBuffer, int uBufferSizeLeft, int *pOutSoundSize, int a6);
+  SoundDesc *Release();
+  void _4A9D79(int a2);
+  void UnloadSound(unsigned int uSoundID, char a3);
+  void ToFile();
+  void FromFile(void *data_mm6, void *data_mm7, void *data_mm8);
+  int FromFileTxt(const char *Args);
+
+  signed int sNumSounds;
+  SoundDesc *pSL_Sounds;
+  unsigned int uTotalLoadedSoundSize;
+};
+#pragma pack(pop)
+
+
+
+
+
+/*  241 */
+#pragma pack(push, 1)
+struct Sound
+{
+  unsigned int uID;
+  char SoundName[120];
+  SoundData *pSoundData;
+};
+#pragma pack(pop)
+
+
+
+
+extern int Aureal3D_SplashScreen;
+extern int Aureal3D_SplashAudio;
+extern int uFindSound_BinSearch_ResultID; // weak
+extern int uLastLoadedSoundID; // weak
+extern int sLastTrackLengthMS;
+extern std::array<Sound, 3000> pSounds;
+extern AudioPlayer *pAudioPlayer;
+extern SoundList *pSoundList;
+
+extern unsigned __int8 uSoundVolumeMultiplier;
+extern unsigned __int8 uVoicesVolumeMultiplier;
+extern unsigned __int8 uMusicVolimeMultiplier;
+extern int bWalkSound; // idb
+
+extern std::array<float, 10> pSoundVolumeLevels; // idb
+
+
+
+
+
+
+
+
+/*  379 */
+#pragma pack(push, 1)
+struct stru339_spell_sound
+{
+  int AddPartySpellSound(int uSoundID, int a6);
+
+  char pSounds[44744];
+  int field_AEC8[45];
+  int field_AF7C[18];
+  int field_AFC4;
+  int pSoundsSizes[2];
+  int pSoundsOffsets[2];
+};
+#pragma pack(pop)
+extern std::array<stru339_spell_sound, 4> stru_A750F8;
+extern std::array<stru339_spell_sound, 4> AA1058_PartyQuickSpellSound;
+
+struct SoundHeader *FindSound_BinSearch(unsigned int uStart, unsigned int uEnd, const char *pName);
+struct SoundData *LoadSound(const char *pSoundName, struct SoundData *pOutBuff, unsigned int uID);
+int __fastcall sub_4AB66C(int, int); // weak
+int GetSoundStrengthByDistanceFromParty(int x, int y, int z);
+void PlayLevelMusic();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Audio/OpenALSoundProvider.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,388 @@
+#pragma once
+#include "lib/OpenAL/al.h"
+#include "lib/OpenAL/alc.h"
+#pragma comment(lib, "OpenAL32.lib")
+
+#include "Engine/stuff.h"
+#include "Engine/Log.h"
+
+class OpenALSoundProvider
+{
+  public:
+    struct TrackBuffer
+    {
+      unsigned int source_id;
+      unsigned int buffer_id;
+    };
+
+    struct StreamingTrackBuffer
+    {
+      unsigned int source_id;
+      ALenum       sample_format;
+      int          sample_rate;
+    };
+
+    inline OpenALSoundProvider()
+    {
+      this->device = nullptr;
+      this->context = nullptr;
+    }
+
+    inline ~OpenALSoundProvider()
+    {
+      Release();
+    }
+
+    inline bool Initialize()
+    {
+
+      auto device_names = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
+      if (!device_names)
+      {
+        device_names = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
+      }
+      if (device_names)
+      {
+        for (auto device_name = device_names; device_name[0]; device_name += strlen(device_name))
+        {
+          continue;
+        }
+      }
+
+      device = alcOpenDevice(nullptr);
+      if (!device || CheckError())
+	  {
+        Log::Warning(L"Default sound device not present");
+        return false;
+	  }
+
+      context = alcCreateContext(device, nullptr);
+      if (!context || CheckError())
+        return Release(), false;
+
+      alcMakeContextCurrent(context);
+
+      bool eax2 = alIsExtensionPresent("EAX2.0");
+      bool eax3 = alIsExtensionPresent("EAX3.0");
+      bool eax4 = alIsExtensionPresent("EAX4.0");
+      bool eax5 = alIsExtensionPresent("EAX5.0");
+      
+      auto vendor = alGetString(AL_VENDOR);
+      auto version = alGetString(AL_VERSION);
+      auto extensions = alcGetString(device, ALC_EXTENSIONS);
+
+      return true;
+    }
+
+    void Release()
+    {
+      alcMakeContextCurrent(nullptr);
+      if (context)
+      {
+        alcDestroyContext(context);
+      }
+      if (device)
+      {
+        alcCloseDevice(device);
+      }
+    }
+
+    void DeleteStreamingTrack(StreamingTrackBuffer **buffer)
+    {
+      if (!buffer && !*buffer)
+        return;
+      auto track = *buffer;
+
+      int status;
+      alGetSourcei(track->source_id, AL_SOURCE_STATE, &status);
+      if (status == AL_PLAYING)
+      {
+        alSourceStop(track->source_id);
+        if (CheckError()) __debugbreak();
+      }
+
+      int num_processed_buffers = 0;
+      int num_queued_buffers = 0;
+      alGetSourcei(track->source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers);
+      alGetSourcei(track->source_id, AL_BUFFERS_QUEUED, &num_queued_buffers);
+      int num_track_buffers = num_queued_buffers + num_processed_buffers;
+      for (int i = 0; i < num_processed_buffers; ++i)
+      {
+        unsigned int buffer_id;
+        alSourceUnqueueBuffers(track->source_id, 1, &buffer_id);
+        if (!CheckError())
+          alDeleteBuffers(1, &buffer_id);
+        else __debugbreak();
+      }
+
+      alDeleteSources(1, &track->source_id);
+      CheckError();
+
+      delete *buffer;
+      *buffer = nullptr;
+    }
+
+    void DeleteBuffer16(TrackBuffer **buffer)
+    {
+      alDeleteBuffers(1, &(*buffer)->buffer_id);
+      CheckError();
+
+      delete *buffer;
+      *buffer = nullptr;
+    }
+
+    float alBufferLength(unsigned int buffer)
+    {
+      int size, bits, channels, freq;
+
+      alGetBufferi(buffer, AL_SIZE, &size);
+      alGetBufferi(buffer, AL_BITS, &bits);
+      alGetBufferi(buffer, AL_CHANNELS, &channels);
+      alGetBufferi(buffer, AL_FREQUENCY, &freq);
+      if (CheckError())
+        return 0.0f;
+
+      return (ALfloat)((ALuint)size / channels / (bits / 8)) / (ALfloat)freq;
+    }
+
+    StreamingTrackBuffer *CreateStreamingTrack16(int num_channels, int sample_rate, int bytes_per_sample)
+    {
+      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
+
+      ALenum sound_format;
+      switch (num_channels)
+      {
+        case 1: sound_format = AL_FORMAT_MONO16;    break;
+        case 2: sound_format = AL_FORMAT_STEREO16;  break;
+        default:
+          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
+          {
+            switch (num_channels)
+            {
+              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
+              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
+              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
+              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
+            }
+          }
+          Error("Unsupported number of audio channels: %u", num_channels);
+      }
+
+      unsigned int al_source = -1;
+      alGetError();
+      alGenSources(1, &al_source);
+      if (CheckError())
+        return nullptr;
+
+      float sound_pos[] = {0.0f, 0.0f, 0.0f},
+            sound_vel[] = {0.0f, 0.0f, 0.0f};
+
+      alSourcei(al_source, AL_LOOPING, AL_FALSE);
+      alSourcef(al_source, AL_PITCH, 1.0f);
+      alSourcef(al_source, AL_GAIN, 1.0f);
+      alSourcefv(al_source, AL_POSITION, sound_pos);
+      alSourcefv(al_source, AL_VELOCITY, sound_vel);
+
+      auto ret = new StreamingTrackBuffer;
+      ret->source_id = al_source;
+      ret->sample_format = sound_format;
+      ret->sample_rate = sample_rate;
+      return ret;
+    }
+
+    void Stream16(StreamingTrackBuffer *buffer, int num_samples, const void *samples, bool wait = false)
+    {
+      int bytes_per_sample = 2;
+
+      unsigned int al_buffer;
+      alGenBuffers(1, &al_buffer);
+      alBufferData(al_buffer, buffer->sample_format, samples, num_samples * bytes_per_sample, buffer->sample_rate);
+      if (CheckError())
+      {
+        alDeleteBuffers(1, &al_buffer);
+        return;
+      }
+
+      int num_processed_buffers = 0;
+      alGetSourcei(buffer->source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers);
+      for (int i = 0; i < num_processed_buffers; ++i)
+      {
+        unsigned int processed_buffer_id;
+        alSourceUnqueueBuffers(buffer->source_id, 1, &processed_buffer_id);
+        if (!CheckError())
+          alDeleteBuffers(1, &processed_buffer_id);
+      }
+
+      alSourceQueueBuffers(buffer->source_id, 1, &al_buffer);
+      if (CheckError())
+      {
+        alDeleteBuffers(1, &al_buffer);
+        return;
+      }
+
+      volatile int status;
+      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+      if (status != AL_PLAYING)
+      {
+        float listener_pos[] = {0.0f, 0.0f, 0.0f};
+        float listener_vel[] = {0.0f, 0.0f, 0.0f};
+        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
+                                        0.0f, 1.0f, 0.0f}; // up vector
+        alListenerfv(AL_POSITION, listener_pos);
+        alListenerfv(AL_VELOCITY, listener_vel);
+        alListenerfv(AL_ORIENTATION, listener_orientation);
+
+        alSourcePlay(buffer->source_id);
+        if (CheckError())
+          __debugbreak();
+
+        if (wait)
+        {
+          do
+          {
+            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+          }
+          while (status == AL_PLAYING);
+        }
+      }
+    }
+
+
+
+
+    TrackBuffer *CreateTrack16(int num_channels, int sample_rate, int bytes_per_sample, int num_samples, const void *samples)
+    {
+      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
+
+      ALenum sound_format;
+      switch (num_channels)
+      {
+        case 1: sound_format = AL_FORMAT_MONO16;    break;
+        case 2: sound_format = AL_FORMAT_STEREO16;  break;
+        default:
+          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
+          {
+            switch (num_channels)
+            {
+              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
+              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
+              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
+              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
+            }
+          }
+          Error("Unsupported number of audio channels: %u", num_channels);
+      }
+
+      unsigned int al_source = -1;
+      alGenSources(1, &al_source);
+      if (CheckError())
+        return nullptr;
+
+      float sound_pos[] = {0.0f, 0.0f, 0.0f},
+            sound_vel[] = {0.0f, 0.0f, 0.0f};
+
+      alSourcei(al_source, AL_LOOPING, AL_FALSE);
+      alSourcef(al_source, AL_PITCH, 1.0f);
+      alSourcef(al_source, AL_GAIN, 1.0f);
+      alSourcefv(al_source, AL_POSITION, sound_pos);
+      alSourcefv(al_source, AL_VELOCITY, sound_vel);
+
+      unsigned int al_buffer = -1;
+      alGenBuffers(1, &al_buffer);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        return nullptr;
+      }
+
+      alBufferData(al_buffer, sound_format, samples, num_samples * bytes_per_sample, sample_rate);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        alDeleteBuffers(1, &al_buffer);
+        return nullptr;
+      }
+
+      alSourcei(al_source, AL_BUFFER, al_buffer);
+      if (CheckError())
+      {
+        alDeleteSources(1, &al_source);
+        alDeleteBuffers(1, &al_buffer);
+        return nullptr;
+      }
+
+      auto ret = new TrackBuffer;
+      ret->source_id = al_source;
+      ret->buffer_id = al_buffer;
+      return ret;
+    }
+
+
+    void PlayTrack16(TrackBuffer *buffer, bool loop = false, bool wait = false)
+    {
+      volatile int status;
+      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+      if (status == AL_PLAYING)
+        Error("Already playing");
+      else
+      {
+        float listener_pos[] = {0.0f, 0.0f, 0.0f};
+        float listener_vel[] = {0.0f, 0.0f, 0.0f};
+        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
+                                        0.0f, 1.0f, 0.0f}; // up vector
+        alListenerfv(AL_POSITION, listener_pos);
+        alListenerfv(AL_VELOCITY, listener_vel);
+        alListenerfv(AL_ORIENTATION, listener_orientation);
+
+        alSourcei(buffer->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
+        alSourcePlay(buffer->source_id);
+        if (CheckError())
+          __debugbreak();
+
+        if (wait && !loop)
+        {
+          float track_length = alBufferLength(buffer->buffer_id);
+          do
+          {
+            float track_offset = 0;
+            alGetSourcef(buffer->source_id, AL_SEC_OFFSET, &track_offset);
+            log("playing: %.4f/%.4f\n", track_offset, track_length);
+
+            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
+          }
+          while (status == AL_PLAYING);
+        }
+      }
+    }
+
+
+
+  protected:
+    ALCdevice    *device;
+    ALCcontext   *context;
+
+
+    bool CheckError()
+    {
+      ALenum code1 = alGetError();
+      if (code1 != AL_NO_ERROR)
+      {
+        DWORD w;
+        const char *message = alGetString(code1);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
+        return true;
+      }
+
+      ALenum code2 = alcGetError(device);
+      if (code2 != ALC_NO_ERROR)
+      {
+        DWORD w;
+        const char *message = alcGetString(device, code2);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
+        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
+        return true;
+      }
+      return false;
+    }
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/MediaPlayer.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,1511 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#include <vector>
+#include <deque>
+
+#define _CRT_SECURE_NO_WARNINGS
+
+
+#include "IO/Mouse.h"
+#include "GUI/GUIWindow.h"
+#include "Engine/mm7_data.h"
+#include "Media/Audio/OpenALSoundProvider.h"
+#include "Engine/Log.h"
+#include "MediaPlayer.h"
+#include "Media/Video/Bink_Smacker.h"
+#include "Media/Audio/AudioPlayer.h"
+#include "Engine/Timer.h"
+#include "Engine/Graphics/Render.h"
+#include "Engine/Game.h"
+
+
+#pragma comment(lib, "Version.lib")
+
+using namespace Media;
+
+Media::MPlayer *pMediaPlayer = nullptr;
+Media::IMovie *pMovie_Track;
+Media::ITrack *pAudio_Track;
+Movie *movie;
+
+int mSourceID;
+
+void PlayMovie(const wchar_t * pFilename);
+void PlayAudio(const wchar_t * pFilename);
+void LoadMovie(const char *);
+ 
+class MemoryStream 
+{
+  public:
+    inline MemoryStream(void *data, size_t data_size)
+    {
+      this->data_size = data_size;
+      this->data = data;
+      this->current_pos = 0;
+    }
+    inline MemoryStream()
+    {
+      this->data_size = 0;
+      this->data = nullptr;
+      this->current_pos = 0;
+    }
+
+    inline ~MemoryStream()
+    {
+      //Log::Warning(L"Destructor: data delete %u", data);
+      if (data)
+        delete [] data;
+    }
+
+    inline size_t Write(void *buffer, size_t num_bytes)
+    {
+      if (!data)
+      {
+        data_size = 32 + num_bytes;
+        data = new char[data_size];
+        //Log::Warning(L"new data %u", data);
+        current_pos = 0;
+      }
+      else if (current_pos + num_bytes >= data_size)
+      {
+        int  new_data_size = data_size + num_bytes + data_size / 8 + 4;
+        auto new_data = new char[new_data_size];
+        //Log::Warning(L"new new_data %u", new_data);
+
+        memcpy(new_data, data, data_size);
+        //Log::Warning(L"data delete %u", data);
+        delete [] data;
+
+        data_size = new_data_size;
+        data = new_data;
+      }
+      memcpy((char *)data + current_pos, buffer, num_bytes);
+      current_pos += num_bytes;
+      return num_bytes;
+    }
+
+    inline size_t Read(void *buffer, size_t num_bytes)
+    {
+      size_t read_size = min(num_bytes, data_size - current_pos);
+      if (read_size)
+      {
+        memcpy(buffer, (char *)data + current_pos, read_size);
+        current_pos += read_size;
+      }
+      return read_size;
+    }
+
+    inline void Reset()
+    {
+      current_pos = 0;
+    }
+    inline void SeekToEnd()
+    {
+      current_pos = data_size;
+    }
+
+    inline size_t Unwind(size_t bytes)
+    {
+      if (bytes > current_pos)
+        current_pos = 0;
+      else
+        current_pos -= bytes;
+      return current_pos;
+    }
+    
+    inline size_t Rewind(size_t bytes)
+    {
+      if (current_pos + bytes >= data_size)
+        current_pos = data_size;
+      else
+        current_pos += bytes;
+      return current_pos;
+    }
+
+    inline size_t  Size() const    {return data_size;}
+    inline size_t  Current() const {return current_pos;}
+    inline void   *Ptr() const     {return data;}
+
+  private:
+    void   *data;
+    size_t  data_size;
+    size_t  current_pos;
+};
+
+OpenALSoundProvider *provider = nullptr;
+
+static int av_num_bytes_per_sample(AVSampleFormat sample_fmt)
+{
+  switch (sample_fmt)
+  {
+    case AV_SAMPLE_FMT_U8:
+    case AV_SAMPLE_FMT_U8P:
+      return 1;
+          
+    case AV_SAMPLE_FMT_S16:
+    case AV_SAMPLE_FMT_S16P:
+      return 2;
+
+    case AV_SAMPLE_FMT_S32:
+    case AV_SAMPLE_FMT_S32P:
+    case AV_SAMPLE_FMT_FLT:
+    case AV_SAMPLE_FMT_FLTP:
+      return 4;
+
+    case AV_SAMPLE_FMT_DBL:
+    case AV_SAMPLE_FMT_DBLP:
+      return 8;
+
+    default:
+    case AV_SAMPLE_FMT_NONE:
+      Error("Invalid av sample format: %u", sample_fmt);
+  }
+  return 0;
+}
+
+struct AVStreamWrapper
+{
+  inline AVStreamWrapper()
+  {
+    this->type = AVMEDIA_TYPE_UNKNOWN;
+    this->stream_idx = -1;
+    this->stream = nullptr;
+    this->dec = nullptr;
+    this->dec_ctx = nullptr;
+  }
+
+  inline void Release()
+  {
+    type = AVMEDIA_TYPE_UNKNOWN;
+    stream_idx = -1;
+    stream = nullptr;
+    dec = nullptr;
+    if (dec_ctx)
+    {
+	  // Close the codec
+      avcodec_close(dec_ctx);
+	  Log::Warning(L"close decoder context file\n");
+      dec_ctx = nullptr;
+    }
+  }
+
+  AVMediaType      type;
+  int              stream_idx;
+  AVStream        *stream;
+  AVCodec         *dec;
+  AVCodecContext  *dec_ctx;
+};
+
+struct AVAudioStream: public AVStreamWrapper
+{
+  inline AVAudioStream():AVStreamWrapper()
+  {
+    this->bytes_per_sample = 0;
+    this->bytes_per_second = 0;
+  }
+
+  int bytes_per_sample;
+  int bytes_per_second;
+};
+
+struct AVVideoStream: public AVStreamWrapper
+{
+  inline AVVideoStream(): AVStreamWrapper()
+  {
+    this->frames_per_second = 0.0;
+  }
+
+  double frames_per_second;
+};
+
+static bool av_open_stream(AVFormatContext *format_ctx, AVMediaType type, AVStreamWrapper *out_stream)
+{
+  int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0);
+  if (stream_idx >= 0)
+  {
+    auto stream = format_ctx->streams[stream_idx];
+    auto dec_ctx = stream->codec;
+
+	// Find the decoder for the video stream
+    auto dec = avcodec_find_decoder(dec_ctx->codec_id);
+    if (dec)
+    {
+	  // Open codec
+      if (avcodec_open2(dec_ctx, dec, nullptr) >= 0)
+      {
+        out_stream->type = type;
+        out_stream->stream_idx = stream_idx;
+        out_stream->stream = stream;
+        out_stream->dec = dec;
+        out_stream->dec_ctx = dec_ctx;
+        return true;
+      }
+      fprintf(stderr, "ffmpeg: Could not open codec\n");
+	  return false;
+    }
+    fprintf(stderr, "ffmpeg: Unable to open codec\n");
+	return false;
+  }
+  fprintf(stderr, "ffmpeg: Didn't find a stream\n");
+  return false;	
+}
+
+static bool av_open_audio_stream(AVFormatContext *format_ctx, AVAudioStream *out_stream)
+{
+  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_AUDIO, out_stream))
+    return Error("Audio stream not found"), false;
+  
+  // we support only 2-channel audio for now
+  //if (out_stream->dec_ctx->channels != 2)
+  //{
+   // out_stream->Release();
+   // return Error("Unsupported number of channels: %u", out_stream->dec_ctx->channels), false;
+  //}
+  
+  out_stream->bytes_per_sample = av_num_bytes_per_sample(out_stream->dec_ctx->sample_fmt);
+  out_stream->bytes_per_second = out_stream->dec_ctx->channels * out_stream->dec_ctx->sample_rate * out_stream->bytes_per_sample;
+
+  return true;
+}
+
+static bool av_open_video_stream(AVFormatContext *format_ctx, AVVideoStream *out_stream)
+{
+  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_VIDEO, out_stream))
+    return Error("Video stream not found"), false;
+
+  out_stream->frames_per_second = (double)out_stream->dec_ctx->time_base.den / (double)out_stream->dec_ctx->time_base.num;
+  return true;
+}
+
+void InterleaveAudioData(MemoryStream *stream, AVSampleFormat src_format, int num_channels, int num_samples, uint8_t **channels)
+{
+  unsigned int bytes_per_sample;
+  switch (src_format)
+  {
+    case AV_SAMPLE_FMT_U8:
+    case AV_SAMPLE_FMT_U8P:
+      __debugbreak();
+
+    case AV_SAMPLE_FMT_S16:
+      bytes_per_sample = sizeof(__int16);
+      stream->Write(channels[0], num_channels * num_samples * bytes_per_sample);
+    break;
+
+    case AV_SAMPLE_FMT_S16P:
+    {
+      bytes_per_sample = sizeof(__int16);
+      for (int i = 0; i < num_samples; ++i)
+        for (int j = 0; j < num_channels; ++j)
+          stream->Write(channels[j] + i * bytes_per_sample, bytes_per_sample);
+    }
+    break;
+
+    case AV_SAMPLE_FMT_FLT:
+    {
+      SwrContext *converter = swr_alloc();
+      av_opt_set_int(converter, "in_channel_layout",    av_get_default_channel_layout(2), 0);
+      //av_opt_set_int(converter, "in_sample_rate",       sample_ra, 0);
+      av_opt_set_sample_fmt(converter, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
+
+      av_opt_set_int(converter, "out_channel_layout",    av_get_default_channel_layout(2), 0);
+      //av_opt_set_int(converter, "out_sample_rate",       dst_sample_rate, 0);
+      av_opt_set_sample_fmt(converter, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+
+      if (swr_init(converter) < 0)
+      {
+        __debugbreak();
+        swr_free(&converter);
+        return;
+      }
+
+      uint8_t **dst_channels;
+      int       dst_linesize[8];
+      //int dst_nb_channels = av_get_channel_layout_nb_channels(dst_channel_layout);
+      if (av_samples_alloc_array_and_samples(&dst_channels, dst_linesize, 2, num_channels * num_samples, AV_SAMPLE_FMT_S16, 0) < 0)
+      {
+        __debugbreak();
+        swr_free(&converter);
+        return;
+      }
+
+      if (swr_convert(converter, dst_channels, num_channels * num_samples, (const uint8_t **)channels, num_channels * num_samples) >= 0) //Invalid partial memory access, Uninitialized memory access
+
+        stream->Write(dst_channels[0], num_channels * num_samples * sizeof(__int16));
+      else
+        __debugbreak();
+
+      av_free(dst_channels[0]);
+      swr_free(&converter);
+    }
+    break;
+
+    default:
+      __debugbreak();
+      //if (Resample(next_frame->avframe, next_frame->avframe->channel_layout, next_frame->avframe->sample_rate,
+      //                                            av_get_default_channel_layout(2),    next_frame->avframe->sample_rate, AV_SAMPLE_FMT_S16P, resampled_data))
+  }
+}
+
+const uint16_t ff_wma_critical_freqs[25] = {
+    100,   200,  300, 400,   510,  630,  770,    920,
+    1080, 1270, 1480, 1720, 2000, 2320, 2700,   3150,
+    3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
+    24500,
+};
+extern const uint16_t ff_wma_critical_freqs[25];
+static float quant_table[96];
+
+bool DecodeAudioFrame(AVCodecContext *dec_ctx, AVPacket *avpacket, AVFrame *avframe, MemoryStream *out_audio_data, int *out_num_audio_samples)
+{
+  volatile int decoded = false;
+  do
+  {
+    if (avcodec_decode_audio4(dec_ctx, avframe, (int *)&decoded, avpacket) < 0)	//Uninitialized portail memory access
+    {
+      log("Cannot decode audio frame\n");
+      return false;
+    }
+
+    if (!decoded)
+      log("Cannot decode audio frame in one piece\n");
+  } while (!decoded);
+
+  switch (dec_ctx->codec_id)
+  {
+    case  AV_CODEC_ID_BINKAUDIO_DCT:
+    {
+      __debugbreak();	
+    }
+    case AV_CODEC_ID_BINKAUDIO_RDFT:
+    {//pts	samples		dpts
+     //    0	960
+     //17280	960		17280    18x960
+     //18240	960		960       1x960
+     //20160	960		1920      2x960
+     //21120	960		960       1x960
+     //23040	960		1920      2x960
+      /*static int bink_next_pts = 0;
+
+        // there's a gap in the sound - fill empty samples in
+      if (bink_next_pts < avpacket->pts)
+      {
+        short silence[1024];
+        memset(silence, 0, sizeof(silence));
+
+        int samples_to_fill = /*dec_ctx->channels *  (avpacket->pts - bink_next_pts);
+        while (samples_to_fill > 0)
+        {
+          int samples_to_fill_this_step = samples_to_fill >= 1024 ? 1024 : samples_to_fill;
+          out_audio_data->Write(silence, samples_to_fill_this_step  * sizeof(short));
+
+          samples_to_fill -= samples_to_fill_this_step;
+        }
+      }
+
+      bink_next_pts = avpacket->pts + /*dec_ctx->channels *  avframe->nb_samples; */
+
+  AVFrame frame;
+  int first;
+  int version_b;
+  int frame_len;
+  int overlap_len;        
+  int block_size;
+  int num_bands;
+  unsigned int *bands;
+  float root;
+  int sample_rate = dec_ctx->sample_rate;
+  int sample_rate_half;
+  int i;
+  int frame_len_bits;
+  int channels;
+
+  //compresses audio in chunks of varying sizes depending on sample rate:
+   // if sample rate < 22050, frame size is 2048 samples
+   // if sample rate < 44100, frame size is 4096 samples
+   // else, frame size is 8192 samples
+
+
+  /* determine frame length */
+  if (dec_ctx->sample_rate < 22050)
+    frame_len_bits = 9;
+  else if (dec_ctx->sample_rate < 44100)
+    frame_len_bits = 10;
+  else
+    frame_len_bits = 11;
+
+  if (dec_ctx->channels < 1 || dec_ctx->channels > 2) 
+  {
+        av_log(dec_ctx, AV_LOG_ERROR, "invalid number of channels: %d\n", dec_ctx->channels);
+        return AVERROR_INVALIDDATA;
+  }
+
+	  version_b = dec_ctx->extradata_size >= 4 && dec_ctx->extradata[3] == 'b';
+      if (version_b)
+	    __debugbreak();
+
+      if (dec_ctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
+      {
+        // audio is already interleaved for the RDFT format variant
+        dec_ctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        sample_rate  *= dec_ctx->channels;
+        channels = 1;
+        if (!version_b)
+          frame_len_bits += av_log2(dec_ctx->channels);
+      }
+      else
+      {
+        channels = dec_ctx->channels;
+        dec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+      }
+
+	  frame_len     = 1 << frame_len_bits;                          //2048
+
+	  //a frame is windowed with the previous frame; the size of the window is frame size / 16 
+      overlap_len   = frame_len / 16;                               //128
+      block_size    = (frame_len - overlap_len) * channels;         //1920
+
+	  //compute half the sample rate as (sample rate + 1) / 2;
+	  //initialize an array of band frequencies corresponding to an array of 25 critical frequencies (same as WMA, apparently),
+	  // any for which the critical frequencies are less than half the sample rate 
+
+      sample_rate_half = (sample_rate + 1) / 2;	                    //22050
+      if (dec_ctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
+         root = 2.0 / (sqrt(float(frame_len)) * 32768.0);
+      else
+         root = frame_len / (sqrt(float(frame_len)) * 32768.0);
+      for (i = 0; i < 96; i++) 
+	  {
+         /* constant is result of 0.066399999/log10(M_E) */
+        quant_table[i] = expf(i * 0.15289164787221953823f) * root;
+      }
+ 
+       /* calculate number of bands */
+	  //bands calculation:
+	  //bands[0] = 1;
+	  //foreach (i in 1..# of bands-1):
+	  //bands[i] = crit_freq[i-1] * (frame length / 2) / (sample rate / 2); 
+	  //bands[# of bands] = frame length / 2 
+       for (num_bands = 1; num_bands < 25; num_bands++)
+         if (sample_rate_half <= ff_wma_critical_freqs[num_bands - 1])
+            break;
+
+       bands = (unsigned int *)(av_malloc((num_bands + 1) * sizeof(*bands)));
+       if (!bands)
+         return AVERROR(ENOMEM);
+
+	   /* populate bands data */
+       bands[0] = 2;
+       for (i = 1; i < num_bands; i++)
+         bands[i] = (ff_wma_critical_freqs[i - 1] * frame_len / sample_rate_half) & ~1;
+       bands[num_bands] = frame_len;
+
+       first = 1;
+
+       //ff_rdft_init(&trans.rdft, frame_len_bits, DFT_C2R);
+
+       avcodec_get_frame_defaults(&frame);
+       dec_ctx->coded_frame = &frame;
+    }
+    break;
+                /*
+      case AV_CODEC_ID_SMACKAUDIO:
+      {
+        static int smack_debug_next_audio_time = 0;
+        if (smack_debug_next_audio_time != packet->pts)
+        {
+          Error("There's a gap in the sound before frame %u\n", num_audio_frames);
+          __debugbreak(); // there's a gap in the sound
+        }
+
+        int num_actual_data_channels = 0;
+        switch (dec_ctx->sample_fmt)
+        {
+          case AV_SAMPLE_FMT_U8:
+          case AV_SAMPLE_FMT_S16:
+          case AV_SAMPLE_FMT_S32:
+          case AV_SAMPLE_FMT_FLT:
+          case AV_SAMPLE_FMT_DBL:
+            num_actual_data_channels = 1;
+          break;
+
+          case AV_SAMPLE_FMT_U8P:
+          case AV_SAMPLE_FMT_S16P:
+          case AV_SAMPLE_FMT_S32P:
+          case AV_SAMPLE_FMT_FLTP:
+          case AV_SAMPLE_FMT_DBLP:
+            num_actual_data_channels = dec_ctx->channels;
+          break;
+
+          default:
+          case AV_SAMPLE_FMT_NONE:
+          case AV_SAMPLE_FMT_NB:
+            __debugbreak();
+        }
+
+        smack_debug_next_audio_time += dec_ctx->channels * frame->nb_samples * bytes_per_sample;
+        Assert(frame->avframe->linesize[0] == audio.dec_ctx->channels * frame->avframe->nb_samples * audio.bytes_per_sample / num_actual_data_channels,
+               "Smack audio size mismatch in frame %u in %s\n", audio_num_read_frames, movie_filename);
+
+        frame->play_time = (double)frame->avpacket->pts / (double)audio.bytes_per_second;
+      }
+      break;
+
+                case AV_CODEC_ID_MP3:
+                {
+                  static int mp3_samples_decoded_so_far = 0;
+                  static int mp3_prev_samples_count = frame->avframe->nb_samples; // mp3 seems to always feed same amount of samples
+                  frame->play_time = (double)mp3_samples_decoded_so_far / (double)audio.dec_ctx->sample_rate;
+
+                  mp3_samples_decoded_so_far += frame->avframe->nb_samples;
+                  Assert(mp3_prev_samples_count == frame->avframe->nb_samples,
+                          "MP3 audio have variable sample count in frame %u in %s\n", audio_num_read_frames, movie_filename);
+                }
+                break;
+
+                default:
+                {
+                  __debugbreak();
+                  double samples_per_second = (double)audio.dec_ctx->time_base.den / (double)audio.dec_ctx->time_base.num;
+                  double play_length = frame->avframe->nb_samples / samples_per_second;
+                  frame->play_time = (double)frame->avpacket->pts / samples_per_second;
+                }
+                break;*/
+  }
+
+  if (!avframe->channel_layout)
+  {
+    log("Audio channel layout not specified, rolling back to default\n");
+    avframe->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
+  }
+
+  *out_num_audio_samples = dec_ctx->channels * avframe->nb_samples;
+  InterleaveAudioData(out_audio_data, dec_ctx->sample_fmt,
+                      dec_ctx->channels, avframe->nb_samples, avframe->data);
+  return true;
+}
+
+bool LoadAudioTrack(AVFormatContext *format_ctx, AVCodecContext *dec_ctx, int audio_stream_idx, MemoryStream *out_audio_stream, int *out_num_audio_frames, int *out_num_audio_samples)
+{
+  out_audio_stream->Reset();
+
+  AVFrame  *frame = avcodec_alloc_frame();
+
+  AVPacket *packet = new AVPacket;
+  av_init_packet(packet);
+
+  int num_audio_frames = 0;
+  int num_audio_samples = 0;
+
+  while (av_read_frame(format_ctx, packet) >= 0)
+  {
+	// Is this a packet from the audio stream?
+    if (packet->stream_index != audio_stream_idx)
+    {
+      //log("Suspicious stream id %u in %s", packet->stream_index, filenamea);
+      continue;
+    }
+
+	// Decode audio frame
+    int num_samples_decoded;
+    DecodeAudioFrame(dec_ctx, packet, frame, out_audio_stream, &num_samples_decoded);
+
+    num_audio_samples += num_samples_decoded;
+    num_audio_frames++;
+  }
+  *out_num_audio_frames = num_audio_frames;
+  *out_num_audio_samples = num_audio_samples;
+
+  avcodec_free_frame(&frame);
+  delete frame;
+  av_free_packet(packet);
+  delete packet;
+
+  return true;
+}
+
+class Track: public Media::ITrack
+{
+  public:
+    inline Track()
+    {
+      this->format_ctx = nullptr;
+      this->audio_num_samples = 0;
+    }
+
+    void Release()
+    {
+      ReleaseAvcodec();
+    }
+
+    void ReleaseAvcodec()
+    {
+      audio.Release();
+      if (format_ctx)
+      {
+        av_close_input_file(format_ctx);
+		Log::Warning(L"close audio format context file\n");
+        format_ctx = nullptr;
+      }
+    }
+
+    bool LoadAudio(const wchar_t *filename)
+    {
+      char filenamea[1024];
+      sprintf(filenamea, "%S", filename);
+      // Open audio file
+      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
+      {
+        // Retrieve stream information
+        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
+        {
+          // Dump information about file onto standard error
+          av_dump_format(format_ctx, 0, filenamea, 0);
+
+          if (!av_open_audio_stream(format_ctx, &audio))
+          {
+            Error("Cannot open strack: %s", filenamea);
+            return Release(), false;
+          }
+          
+          MemoryStream audio_plain_data;
+          int          num_audio_frames;
+          int          num_audio_samples;
+
+          if (LoadAudioTrack(format_ctx, audio.dec_ctx, audio.stream_idx, &audio_plain_data, &num_audio_frames, &num_audio_samples))
+          {
+            /*#ifdef _DEBUG
+              char debug_filename[1024];
+              sprintf(debug_filename, "%s.wav", filenamea);
+              FILE *wav = fopen(debug_filename, "w+b");
+
+              extern void write_wav_header(FILE *wav, int channel_count = 2, int sample_rate = 22050, int bytes_per_sample = 2);
+              write_wav_header(wav, audio.dec_ctx->channels, audio.dec_ctx->sample_rate, audio.bytes_per_sample);
+
+              fwrite(audio_plain_data.Ptr(), audio_plain_data.Current(), 1, wav);
+            
+              extern void fix_wav_header(FILE *wav, int wav_bytes_in_stream);
+              fix_wav_header(wav, audio_plain_data.Current());
+            #endif*/
+
+            device_buffer = provider->CreateTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2, num_audio_samples, audio_plain_data.Ptr());
+
+            Release();
+            return true;
+          }
+        }
+        Release();
+        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
+        return false;
+      }
+      fprintf(stderr, "ffmpeg: Unable to open input file\n");
+      return false;
+    }
+
+    virtual void Play(bool loop)
+    {
+      provider->PlayTrack16(device_buffer, loop);
+      mSourceID = device_buffer->source_id;
+    }
+  
+  protected:
+    AVFormatContext *format_ctx;
+    AVAudioStream    audio;
+    int              audio_num_samples;
+
+    bool             stopped;
+
+    OpenALSoundProvider::TrackBuffer *device_buffer;
+};
+
+class Movie: public Media::IMovie
+{
+  public:
+    inline Movie()
+    {
+      this->movie_filename[0] = 0;
+      this->width = 0;
+      this->height = 0;
+      this->format_ctx = nullptr;
+      this->end_of_file = false;
+      this->playback_time = 0.0;
+
+      this->num_audio_frames = 0;
+      this->num_audio_samples = 0;
+
+      this->last_resampled_frame_num = -1;
+      memset(last_resampled_frame_data, 0, sizeof(last_resampled_frame_data));
+      memset(last_resampled_frame_linesize, 0, sizeof(last_resampled_frame_linesize));
+
+      audio_data_in_device = nullptr;
+      decoding_packet = nullptr;
+	  ioBuffer = nullptr;
+	  format_ctx = nullptr;
+	  avioContext = nullptr;
+    }
+
+    virtual ~Movie() {}
+ 
+    virtual void Release()
+    {
+      ReleaseAVCodec();
+
+      if (audio_data_in_device)
+        provider->DeleteStreamingTrack(&audio_data_in_device);
+    }
+
+    inline void ReleaseAVCodec()
+    {
+      audio.Release();
+      video.Release();
+
+      if (format_ctx)
+      {
+		// Close the video file
+        av_close_input_file(format_ctx);
+		Log::Warning(L"close video format context file\n");
+        format_ctx = nullptr;
+	  }
+	  if(avioContext)
+	  {
+		av_free(avioContext);
+		avioContext = nullptr;
+	  }
+	  if (ioBuffer)
+	  {
+		//av_free(ioBuffer);
+		ioBuffer = nullptr;
+      }
+	  av_free_packet(decoding_packet);
+	  delete decoding_packet;
+      avcodec_free_frame(&decoding_frame);
+	  delete decoding_frame;
+      if (last_resampled_frame_data[0])
+        av_freep(&last_resampled_frame_data[0]);
+
+    }
+
+    bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms)	//Çàãðóçêà
+    {
+      char filenamea[1024];
+      sprintf(filenamea, "%S", filename);
+      sprintf(movie_filename, "%S", filename);
+
+      width = dst_width;
+      height = dst_height;
+      // Open video file
+      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
+      {
+        // Retrieve stream information
+        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
+        {
+          // Dump information about file onto standard error
+          av_dump_format(format_ctx, 0, filenamea, 0);
+
+          if (!av_open_audio_stream(format_ctx, &audio))
+          {
+            Error("Cannot open audio stream: %s", filenamea);
+            return Release(), false;
+          }
+          
+          if (!av_open_video_stream(format_ctx, &video))
+          {
+            Error("Cannot open video stream: %s", filenamea);
+            return Release(), false;
+          }
+
+          //Ritor1: include 
+		  if (_stricmp("binkvideo", video.dec->name) ) 
+		  {
+			pMediaPlayer->current_movie_width = video.dec_ctx->width;
+			pMediaPlayer->current_movie_height = video.dec_ctx->height;
+		  }
+		  else
+		  {
+			pMediaPlayer->current_movie_width = width;
+			pMediaPlayer->current_movie_height = height;
+	      }
+		  //
+          decoding_packet = new AVPacket;
+          av_init_packet(decoding_packet);
+      
+		  // Allocate video frame
+          decoding_frame = avcodec_alloc_frame();
+
+          audio_data_in_device = provider->CreateStreamingTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2);
+          return true;
+        }
+        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
+        return Release(), false; 
+      }
+      fprintf(stderr, "ffmpeg: Unable to open input file\n");
+      return Release(), false;
+    }
+
+	bool LoadFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
+	{
+		if (!ioBuffer)
+			ioBuffer = (unsigned char *)av_malloc(0x4000 + FF_INPUT_BUFFER_PADDING_SIZE); // can get av_free()ed by libav
+		if (!avioContext)
+			avioContext = avio_alloc_context(ioBuffer, 0x4000, 0, h, readFunction, NULL, seekFunction);
+		if (!format_ctx)
+			format_ctx = avformat_alloc_context();
+		format_ctx->pb = avioContext;
+		return Load(L"dummyFilename", width, height, 0);
+	}
+
+    virtual void GetNextFrame(double dt, void *dst_surface)
+    {
+      playback_time += dt;
+
+      AVPacket *avpacket = decoding_packet;
+      AVFrame *avframe = decoding_frame;
+
+      avcodec_get_frame_defaults(avframe);
+
+      int desired_frame_number = floor(playback_time * video.dec_ctx->time_base.den / video.dec_ctx->time_base.num + 0.5);
+      if (last_resampled_frame_num == desired_frame_number)
+      {
+        memcpy(dst_surface, last_resampled_frame_data[0], pMediaPlayer->current_movie_height * last_resampled_frame_linesize[0]);
+        return;
+      }
+
+      volatile int frameFinished = false;
+
+      // keep reading packets until we hit the end or find a video packet
+      do
+      {
+        if (pMediaPlayer->loop_current_file)
+        {
+          //Now seek back to the beginning of the stream
+          if (video.dec_ctx->frame_number >= video.stream->duration - 1 )
+            pMediaPlayer->bPlaying_Movie = false;
+        }
+        if (av_read_frame(format_ctx, avpacket) < 0)
+        {
+          // probably movie is finished
+          pMediaPlayer->bPlaying_Movie = false;
+          av_free_packet(avpacket);
+		  return;
+        }
+		// Is this a packet from the video stream?
+        // audio packet - queue into playing
+        if (avpacket->stream_index == audio.stream_idx)
+        {
+          MemoryStream audio_data;
+          if (DecodeAudioFrame(audio.dec_ctx, avpacket, avframe, &audio_data, &num_audio_samples))
+            provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr());
+          //continue;
+        }
+
+		// Decode video frame
+        // video packet - decode & maybe show
+        else if (avpacket->stream_index == video.stream_idx)
+        {
+          do
+          {
+            if (avcodec_decode_video2(video.dec_ctx, avframe, (int *)&frameFinished, avpacket) < 0)
+              __debugbreak();
+          } while (!frameFinished);
+        }
+        else __debugbreak(); // unknown stream
+      }
+      while (avpacket->stream_index != video.stream_idx ||
+               avpacket->pts != desired_frame_number);
+
+      if (frameFinished)
+      {
+        if (last_resampled_frame_data[0])
+          av_freep(&last_resampled_frame_data[0]);
+
+        AVPixelFormat  rescaled_format = AV_PIX_FMT_RGB32;
+        uint8_t       *rescaled_data[4] = {nullptr, nullptr, nullptr, nullptr};
+        int            rescaled_linesize[4] = {0, 0, 0, 0};
+
+        if (av_image_alloc(rescaled_data, rescaled_linesize, pMediaPlayer->current_movie_width, pMediaPlayer->current_movie_height, rescaled_format, 1) >= 0)
+        {
+          SwsContext *converter = sws_getContext(avframe->width, avframe->height, (AVPixelFormat)avframe->format,
+                                               pMediaPlayer->current_movie_width, pMediaPlayer->current_movie_height, rescaled_format,
+                                               SWS_BICUBIC, nullptr, nullptr, nullptr);
+          sws_scale(converter, avframe->data, avframe->linesize, 0, avframe->height, rescaled_data, rescaled_linesize);
+          sws_freeContext(converter);
+
+          memcpy(dst_surface, rescaled_data[0], pMediaPlayer->current_movie_height * rescaled_linesize[0]);
+
+          last_resampled_frame_num = desired_frame_number;
+          memcpy(last_resampled_frame_data, rescaled_data, sizeof(rescaled_data));
+          memcpy(last_resampled_frame_linesize, rescaled_linesize, sizeof(rescaled_linesize));
+        }
+      }
+      else
+        memset(dst_surface, 0, width * pMediaPlayer->current_movie_height * 4);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(avpacket);
+    }
+
+    virtual void Play()
+    {
+    }
+
+  protected:
+    char             movie_filename[256];
+    int              width;
+    int              height;
+    bool             stopped;
+    AVFormatContext *format_ctx;
+    double           playback_time;
+    bool             end_of_file;
+
+    AVPacket        *decoding_packet;
+    AVFrame         *decoding_frame;
+
+    AVAudioStream   audio;
+    int             num_audio_frames;
+    int             num_audio_samples;
+	unsigned char  *ioBuffer;
+	AVIOContext    *avioContext;
+    OpenALSoundProvider::StreamingTrackBuffer *audio_data_in_device;
+
+    AVVideoStream   video;
+    int             last_resampled_frame_num;
+    uint8_t        *last_resampled_frame_data[4];
+    int             last_resampled_frame_linesize[4];
+};	
+
+ITrack *MPlayer::LoadTrack(const wchar_t *filename)
+{
+  auto audio_track = new Track;
+  Log::Warning(L"allocation dynamic memory for audio_track\n");
+  if (!audio_track->LoadAudio(filename))
+  {
+    delete audio_track;
+	Log::Warning(L"delete dynamic memory for audio_track\n");
+    audio_track = nullptr;
+  }
+  return audio_track;
+}
+
+IMovie *MPlayer::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms)	//Çàãðóçèòü âèäåî
+{
+  movie = new Movie;
+  Log::Warning(L"allocation dynamic memory for movie\n");
+  if (!movie->Load(filename, width, height, cache_ms))
+  {
+    delete movie;
+	Log::Warning(L"delete dynamic memory for movie\n");
+    movie = nullptr;
+  }
+  return movie;
+}
+
+
+//for video/////////////////////////////////////////////////////////////////
+
+//----- (004BE9D8) --------------------------------------------------------
+void MPlayer::Initialize(OSWindow *target_window)
+{
+  DWORD NumberOfBytesRead; // [sp+10h] [bp-4h]@9
+    
+  window = target_window;
+
+  unsigned int uBinkVersionMajor = -1,
+               uBinkVersionMinor = -1;
+  //GetDllVersion(L"BINKW32.DLL", &uBinkVersionMajor, &uBinkVersionMinor);
+  //uBinkVersion = (unsigned __int64)uBinkVersionMajor << 32 | uBinkVersionMinor;
+
+  strcpy(pTmpBuf.data(), "anims\\might7.vid");
+  hMightVid = CreateFileW(L"anims\\might7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
+  if ( hMightVid == INVALID_HANDLE_VALUE )
+  {
+    sprintf(pTmpBuf2.data(), "Can't open file - anims\\%s.smk", pTmpBuf.data());
+    MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
+    return;
+  }
+  strcpy(pTmpBuf.data(), "anims\\magic7.vid");
+  hMagicVid = CreateFileW(L"anims\\magic7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
+  if ( hMagicVid == INVALID_HANDLE_VALUE )
+  {
+    if ( !bCanLoadFromCD )
+    {
+       sprintf(pTmpBuf2.data(), "Can't open file - anims\\%s.smk", pTmpBuf.data());
+       MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
+       return;
+    }
+    sprintf(pTmpBuf2.data(), "%c:\\%s", (unsigned __int8)cMM7GameCDDriveLetter, pTmpBuf.data());
+    hMagicVid = CreateFileA(pTmpBuf2.data(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
+    if ( hMagicVid == (HANDLE)INVALID_HANDLE_VALUE )
+    {
+      sprintf(pTmpBuf2.data(), "Can't open file - %s", pTmpBuf.data());
+      MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
+      return;
+    }
+  }
+  ReadFile(hMightVid, &uNumMightVideoHeaders, 4, &NumberOfBytesRead, 0);
+  ReadFile(hMagicVid, &uNumMagicVideoHeaders, 4, &NumberOfBytesRead, 0);
+  pMightVideoHeaders = (MovieHeader *)malloc(sizeof(MovieHeader) * uNumMightVideoHeaders + 2);
+  pMagicVideoHeaders = (MovieHeader *)malloc(sizeof(MovieHeader) * uNumMagicVideoHeaders + 2);
+  ReadFile(hMightVid, pMightVideoHeaders, 44 * uNumMightVideoHeaders, &NumberOfBytesRead, 0);
+  ReadFile(hMagicVid, pMagicVideoHeaders, 44 * uNumMagicVideoHeaders, &NumberOfBytesRead, 0);
+}
+
+//----- (004BF411) --------------------------------------------------------
+void MPlayer::OpenFullscreenMovie(const char *pFilename, unsigned int bLoop/*, int ScreenSizeFlag*/)
+{
+  if (!this->bPlaying_Movie)
+  {
+    pEventTimer->Pause();
+	if (pAudioPlayer->hAILRedbook)
+		AIL_redbook_pause(pAudioPlayer->hAILRedbook);
+
+	bStopBeforeSchedule = false;
+	bFirstFrame = false;
+	this->bLoopPlaying = bLoop;
+	LoadMovie(pFilename);
+	return;
+  }
+}
+
+//----- (004BF28F) --------------------------------------------------------
+void MPlayer::OpenHouseMovie(const char *pMovieName, unsigned int a3_1)
+{
+  if (!this->bPlaying_Movie)
+  {
+    //Prepare();
+    pEventTimer->Pause();
+    if (pAudioPlayer->hAILRedbook)
+      AIL_redbook_pause(pAudioPlayer->hAILRedbook);
+
+    bStopBeforeSchedule = false;
+    bFirstFrame = false;
+
+    this->bLoopPlaying = a3_1;
+    /*if ( LOBYTE(this->field_104) == 1 )
+    {
+      MessageBoxA(nullptr, "Unsupported Bink playback!", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:925", 0);
+      return;
+    }*/
+
+    LoadMovie(pMovieName);
+	time_video_begin = GetTickCount();
+  }
+}
+
+//----- (004BE70E) --------------------------------------------------------
+void MPlayer::FullscreenMovieLoop(const char *pMovieName, int a2/*, int ScreenSizeFlag, int a4*/)
+{
+  int v4; // ebp@1
+  MSG Msg; // [sp+Ch] [bp-1Ch]@12
+
+  v4 = a2;
+  if ( dword_6BE364_game_settings_1 & (GAME_SETTINGS_NO_HOUSE_ANIM | GAME_SETTINGS_NO_INTRO) ||
+	   bNoVideo)
+    return;
+
+    if ( a2 == 2 )
+      v4 = 0;
+    ShowCursor(0);
+    OpenFullscreenMovie(pMovieName, 0);
+    bPlaying_Movie = 1;
+    field_44 = v4;
+    pRenderer->ClearTarget(0);
+    pCurrentScreen = SCREEN_VIDEO;
+
+    auto hwnd = pMediaPlayer->window->GetApiHandle();
+
+    RECT rc_client;
+    GetClientRect(hwnd, &rc_client);
+    int client_width = rc_client.right - rc_client.left,
+        client_height = rc_client.bottom - rc_client.top;
+
+    HDC     dc = GetDC(hwnd);
+    HDC     back_dc = CreateCompatibleDC(dc);
+	HBITMAP back_bmp = CreateCompatibleBitmap(dc, client_width, client_height);
+	auto    frame_buffer = new char[client_width * client_height * 4];
+    SelectObject(back_dc, back_bmp);
+
+	DWORD t = GetTickCount();
+
+	bPlaying_Movie = true;
+
+    while (true)
+    {
+      if (pMediaPlayer->bStopBeforeSchedule)
+        break;
+      while (PeekMessageA(&Msg, hwnd, 0, 0, PM_REMOVE))
+      {
+        if (Msg.message == WM_QUIT)
+          Game_DeinitializeAndTerminate(0);
+        if (Msg.message == WM_PAINT)
+          break;
+        TranslateMessage(&Msg);
+        DispatchMessageA(&Msg);
+      }
+
+      double dt = (GetTickCount() - t) / 1000.0; 
+      t = GetTickCount();
+
+      pMovie_Track->GetNextFrame(dt, frame_buffer);	
+
+      if (!bPlaying_Movie)
+        break;
+
+      if (frame_buffer)
+      {
+        // draw to hwnd
+        BITMAPINFO bmi;
+        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+        bmi.bmiHeader.biWidth = client_width;
+        bmi.bmiHeader.biHeight = -client_height;
+        bmi.bmiHeader.biPlanes = 1;
+        bmi.bmiHeader.biBitCount = 32;
+        bmi.bmiHeader.biCompression = BI_RGB;
+        bmi.bmiHeader.biSizeImage = 0;
+        bmi.bmiHeader.biXPelsPerMeter = 0;
+        bmi.bmiHeader.biYPelsPerMeter = 0;
+        bmi.bmiHeader.biClrUsed = 0;
+        bmi.bmiHeader.biClrImportant = 0;
+        GetDIBits(back_dc, back_bmp, 0, client_height, 0, &bmi, DIB_RGB_COLORS);
+        SetDIBits(back_dc, back_bmp, 0, client_height, frame_buffer, &bmi, DIB_RGB_COLORS);
+        BitBlt(dc, 0, 0, client_width, client_height, back_dc, 0, 0, SRCCOPY);
+      }
+
+      GUI_MainMenuMessageProc();  
+
+      if (pMediaPlayer->bStopBeforeSchedule == 1)
+        Sleep(1000); 
+    }
+	delete [] frame_buffer;
+	DeleteObject(back_bmp);
+	DeleteObject(back_dc);
+	ReleaseDC(hwnd, dc);
+
+    pMediaPlayer->Unload();
+
+    //if (a4 == 1)
+      pCurrentScreen = SCREEN_GAME;
+
+    pMediaPlayer->bPlaying_Movie = false;
+
+    ShowCursor(1);
+
+    /*if ( pCurrentScreen == SCREEN_VIDEO )
+      pCurrentScreen = SCREEN_GAME;*/
+}
+
+void MPlayer::HouseMovieLoop()
+{
+	if (pMovie_Track && !bNoVideo)
+	{
+		pRenderer->BeginScene();
+		pMouse->DrawCursorToTarget();
+
+        Log::Warning(L"smacker");
+        loop_current_file = true;
+        pRenderer->BeginScene();
+        if (!bPlaying_Movie)//reload
+        {
+          unsigned int width = game_viewport_width;
+          unsigned int height = game_viewport_height;
+	      MovieRelease();
+
+          SetFilePointer(hVidFile, uOffset, nullptr, FILE_BEGIN);
+          pMovie_Track = nullptr;
+	      Log::Warning(L"reload pMovie_Track");
+          pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, width, height);
+          bPlaying_Movie = true;
+        }
+        //else 
+        //{
+          double dt = (GetTickCount() - time_video_begin) / 1000.0;
+          //dt = 1.0/15.0;
+          time_video_begin = GetTickCount();
+
+          //log("dt=%.5f\n", dt);
+
+          auto image = new char[current_movie_width * current_movie_height * 4];
+
+          pMovie_Track->GetNextFrame(dt, image);
+
+          int image_array[460 * 344];//game_viewport_width * game_viewport_height
+          if (image)
+          {
+            memcpy(image_array, image, sizeof (image_array));
+            for (unsigned int y = 8; y < 8 + game_viewport_height; ++y)//êîîðäèíàòû ìåñòîïîëîæåíèÿ âèäåîðîëèêà
+            {
+              for (unsigned int x = 8; x < 8 + game_viewport_width; ++x)
+              {
+                auto p = (unsigned __int32 *)pRenderer->pTargetSurface + x + y * pRenderer->uTargetSurfacePitch;
+                *p = image_array[((x - 8) + ((y - 8)*game_viewport_width))];
+              }
+            }
+            delete[] image;
+          }
+       //}
+        pRenderer->EndScene();
+		pMouse->ReadCursorWithItem();
+		pRenderer->EndScene();
+	}
+}
+ 
+//----- (004BF73A) --------------------------------------------------------
+void MPlayer::SelectMovieType()
+{
+  char Source[32]; // [sp+Ch] [bp-40h]@1
+
+  strcpy(Source, this->pCurrentMovieName);
+  pMediaPlayer->Unload();
+  if ( this->uMovieType == 1 )
+    OpenHouseMovie(Source, LOBYTE(this->bLoopPlaying));
+  else if ( this->uMovieType == 2 )
+    OpenFullscreenMovie(Source, LOBYTE(this->bLoopPlaying));
+  else
+    __debugbreak();
+}
+
+void MPlayer::LoadMovie(const char *pFilename)
+{
+  char pVideoNameBik[120]; // [sp+Ch] [bp-28h]@2
+  char pVideoNameSmk[120]; // [sp+Ch] [bp-28h]@2
+
+  sprintf(pVideoNameBik, "%s.bik", pFilename);
+  sprintf(pVideoNameSmk, "%s.smk", pFilename);
+  for (uint i = 0; i < uNumMightVideoHeaders; ++i)
+  {
+    if (!_stricmp(pVideoNameSmk, pMightVideoHeaders[i].pVideoName))
+    {
+      hVidFile = hMightVid;
+      uOffset = pMightVideoHeaders[i].uFileOffset;
+      uSize = pMightVideoHeaders[i + 1].uFileOffset - uOffset;
+      this->uMovieType = 2;
+    }
+  }
+  for (uint i = 0; i < uNumMagicVideoHeaders; ++i)
+  {
+    if (!_stricmp(pVideoNameBik, pMagicVideoHeaders[i].pVideoName))
+    {
+      hVidFile = hMagicVid;
+      uOffset = pMagicVideoHeaders[i].uFileOffset;
+      uSize = pMagicVideoHeaders[i + 1].uFileOffset - uOffset;
+      this->uMovieType = 1;
+    }
+    if (!_stricmp(pVideoNameSmk, pMagicVideoHeaders[i].pVideoName))
+    {
+      hVidFile = hMagicVid;
+      uOffset = pMagicVideoHeaders[i].uFileOffset;
+      uSize = pMagicVideoHeaders[i + 1].uFileOffset - uOffset;
+      this->uMovieType = 2;
+    }
+  }
+  if (!hVidFile)
+  {
+    pMediaPlayer->Unload();
+    MessageBoxA(0, "MediaPlayer error", "MediaPlayer Error", 0);
+    return;
+  }
+
+  SetFilePointer(hVidFile, uOffset, 0, FILE_BEGIN);
+  strcpy(this->pCurrentMovieName, pFilename);
+
+  auto hwnd = pMediaPlayer->window->GetApiHandle();
+  RECT rc_client;
+  GetClientRect(hwnd, &rc_client);
+  int client_width = rc_client.right - rc_client.left,
+      client_height = rc_client.bottom - rc_client.top;
+
+  pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, client_width, client_height);
+}
+
+//----- (004BF794) --------------------------------------------------------
+void MPlayer::ShowMM7IntroVideo_and_LoadingScreen()
+{
+  RGBTexture tex; // [sp+Ch] [bp-30h]@1
+  unsigned int uTrackStartMS; // [sp+34h] [bp-8h]@8
+  unsigned int uTrackEndMS; // [sp+38h] [bp-4h]@8
+
+  pMediaPlayer->bStopBeforeSchedule = false;
+//  pMediaPlayer->pResetflag = 0;
+  bGameoverLoop = true;
+  if (!bNoVideo)
+  {
+    pRenderer->PresentBlackScreen();
+    if ( !pMediaPlayer->bStopBeforeSchedule )
+      PlayFullscreenMovie(MOVIE_Intro, true);
+  }
+
+  tex.Load("mm6title.pcx", 2);
+  pRenderer->BeginScene();
+  pRenderer->DrawTextureRGB(0, 0, &tex);
+  free(tex.pPixels);
+  tex.pPixels = 0;
+
+  //LoadFonts_and_DrawCopyrightWindow();
+  DrawMM7CopyrightWindow();
+
+  pRenderer->EndScene();
+  pRenderer->Present();
+
+  #ifndef _DEBUG
+    Sleep(1500);   // let the copyright window stay for a while
+  #endif
+
+  if (!bNoSound && pAudioPlayer->hAILRedbook )
+  {
+    pAudioPlayer->SetMusicVolume((signed __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0));
+    AIL_redbook_stop(pAudioPlayer->hAILRedbook);
+    AIL_redbook_track_info(pAudioPlayer->hAILRedbook, 14, &uTrackStartMS, &uTrackEndMS);
+    AIL_redbook_play(pAudioPlayer->hAILRedbook, uTrackStartMS + 1, uTrackEndMS);
+  }
+  bGameoverLoop = false;
+}
+
+//----- (004BEBD7) --------------------------------------------------------
+void MPlayer::Unload()
+{
+  bPlaying_Movie = false;
+  uMovieType = 0;
+  memset(pCurrentMovieName, 0, 0x40);
+  if ( pAudioPlayer->hAILRedbook && !bGameoverLoop )
+    AIL_redbook_resume(pAudioPlayer->hAILRedbook);
+  pEventTimer->Resume();
+
+  pMovie_Track->Release();
+  delete pMovie_Track;
+  pMovie_Track = nullptr;
+}
+
+int MPlayer::readFunction(void* opaque, uint8_t* buf, int buf_size)
+{
+  HANDLE stream = (HANDLE)opaque;
+  //int numBytes = stream->read((char*)buf, buf_size);
+  int numBytes;
+  ReadFile(stream, (char *)buf, buf_size, (LPDWORD)&numBytes, NULL);
+  return numBytes;
+}
+
+int64_t MPlayer::seekFunction(void* opaque, int64_t offset, int whence)
+{
+  if (whence == AVSEEK_SIZE)
+    return pMediaPlayer->uSize;
+  HANDLE h = (HANDLE)opaque;
+  LARGE_INTEGER li;
+  li.QuadPart = offset;
+
+  if (!SetFilePointerEx(h, li, (PLARGE_INTEGER)&li, FILE_BEGIN))
+    return -1;
+  return li.QuadPart;
+}
+
+//for video//////////////////////////////////////////////////////////////////
+
+
+
+IMovie *MPlayer::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
+{
+	movie = new Movie;
+	Log::Warning(L"allocation dynamic memory for movie\n");
+	if (movie)
+	{
+		if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height))
+		  return movie;
+		delete movie;
+		Log::Warning(L"delete dynamic memory for movie\n");
+	}
+	return nullptr;
+}
+
+void MovieRelease()
+{
+  movie->Release();
+  delete movie;
+  Log::Warning(L"delete dynamic memory for movie\n");
+  movie = nullptr;
+}
+
+
+//for audio///////////////////////////////////////////////////////
+//----- (004AB818) --------------------------------------------------------
+void MPlayer::LoadAudioSnd()
+{
+  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3
+
+  hAudioSnd = CreateFileA("Sounds\\Audio.snd", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0);
+  if (hAudioSnd == INVALID_HANDLE_VALUE)
+  {
+    Log::Warning(L"Can't open file: %s", L"Sounds\\Audio.snd");
+    return;
+  }
+
+  ReadFile(hAudioSnd, &uNumSoundHeaders, 4, &NumberOfBytesRead, 0);
+  pSoundHeaders = nullptr;
+  pSoundHeaders = (SoundHeader *)malloc(52 * uNumSoundHeaders + 2);
+  ReadFile(hAudioSnd, pSoundHeaders, 52 * uNumSoundHeaders, &NumberOfBytesRead, 0);
+}
+//for audio///////////////////////////////////////////////////////
+
+void av_logger(void *, int, const char *format, va_list args)
+{
+  va_list va;
+  va_start(va, format);
+  char msg[256];
+  vsprintf(msg, format, va);
+  va_end(va);
+
+  log("av: %s", msg);
+}
+
+MPlayer::MPlayer()
+{
+  bPlaying_Movie = false;
+
+  static int libavcodec_initialized = false;
+
+  if (!libavcodec_initialized)
+  {
+    av_log_set_callback(av_logger);
+    avcodec_register_all();
+
+    // Register all available file formats and codecs
+    av_register_all();
+
+    libavcodec_initialized = true;
+  }
+
+  bStopBeforeSchedule = false;
+  pMovie_Track = nullptr;
+
+  if (!provider)
+  {
+    provider = new OpenALSoundProvider;
+	Log::Warning(L"allocation dynamic memory for provider\n");
+    provider->Initialize();
+  }
+  LoadAudioSnd();
+}
+
+MPlayer::~MPlayer()
+{
+	delete provider;
+	Log::Warning(L"delete dynamic memory for provider\n");
+
+    bStopBeforeSchedule = false;
+//    pResetflag = 0;
+    pVideoFrame.Release();
+}
+
+void PlayAudio(const wchar_t * pFilename)
+{
+  pAudio_Track = pMediaPlayer->LoadTrack(pFilename);
+  pAudio_Track->Play();
+  delete pAudio_Track;
+  Log::Warning(L"delete dynamic memory for pAudio_Track\n");
+  pAudio_Track = nullptr;
+}
+
+void PlayMovie(const wchar_t * pFilename)
+{
+  Media::IMovie *Movie_track = pMediaPlayer->LoadMovie(pFilename, 640, 480, 0);
+  Movie_track->Play();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/MediaPlayer.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,179 @@
+#pragma once
+#include "OSWindow.h"
+#include "Engine/Graphics/Texture.h"
+#include "Engine/ErrorHandling.h"
+
+#pragma pack(push, 1)
+
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+#pragma pack(pop)
+
+
+
+extern "C"
+{
+#include "lib/libavcodec/avcodec.h"
+#include "lib/libavformat/avformat.h"
+#include "lib/libavutil/avutil.h"
+#include "lib/libavutil/imgutils.h"
+#include "lib/libswscale/swscale.h"
+#include "lib/libswresample/swresample.h"
+#include "lib/libavutil/opt.h"
+}
+#pragma comment(lib, "avcodec.lib")
+#pragma comment(lib, "avformat.lib")
+#pragma comment(lib, "avutil.lib")
+#pragma comment(lib, "swscale.lib")
+#pragma comment(lib, "swresample.lib")
+
+#include "lib/OpenAL/al.h"
+#include "lib/OpenAL/alc.h"
+#pragma comment(lib, "OpenAL32.lib")
+
+#pragma pack(push, 1)
+
+struct MovieHeader
+{
+  char pVideoName[40];
+  unsigned int uFileOffset;
+};
+struct SoundHeader
+{
+  char pSoundName[40];
+  unsigned int uFileOffset;
+  unsigned int uCompressedSize;
+  unsigned int uDecompressedSize;
+};
+
+enum MovieType
+{
+  MOVIE_Invalid = 0x0,
+  MOVIE_3DOLogo = 0x1,
+  MOVIE_NWCLogo = 0x2,
+  MOVIE_JVC = 0x3,
+  MOVIE_Emerald = 0x4,
+  MOVIE_Intro = 0x5,
+  MOVIE_Death = 0x6,
+  MOVIE_Outro = 0x7,
+};
+
+namespace Media
+{
+  class ITrack
+  {
+    public:
+      virtual ~ITrack() {}
+
+	  virtual void Play(bool loop = false) = 0;
+      virtual void Release() = 0;
+  };
+
+  class IMovie
+  {
+    public: 
+      virtual ~IMovie() {}
+
+	  virtual void Play() = 0;
+      virtual void GetNextFrame(double dt, void *target_surface) = 0;
+      virtual void Release() = 0;
+
+  };
+
+  class MPlayer
+  {
+    public:
+               MPlayer();
+      virtual ~MPlayer();
+
+	  //for video/////////////////////////////////////////////////
+      RGBTexture pVideoFrame;
+      int field_44;//final video
+      unsigned int bFirstFrame;
+      unsigned int bLoopPlaying;
+      unsigned int bStopBeforeSchedule;
+      OSWindow *window;
+      int uMovieType;//0 - null, 1 - bik, 2 - smk
+      char pCurrentMovieName[64];
+      char pVideoFrameTextureFilename[32];
+	  MovieHeader *pMightVideoHeaders;
+      MovieHeader *pMagicVideoHeaders;
+      HANDLE hMightVid;
+      HANDLE hMagicVid;
+      unsigned int uNumMightVideoHeaders;
+      unsigned int uNumMagicVideoHeaders;
+	  bool bPlaying_Movie;
+      bool loop_current_file;
+      DWORD time_video_begin;
+      int current_movie_width;
+      int current_movie_height;
+	  HANDLE hVidFile;
+      int uSize;
+      int uOffset;
+
+      void Initialize(OSWindow *window);
+
+      void OpenFullscreenMovie(const char *pFilename, unsigned int bLoop);
+      void OpenHouseMovie(const char *pMovieName, unsigned int a3_1);
+
+      void LoadMovie(const char *);
+      void SelectMovieType();
+
+      inline void PlayFullscreenMovie(MovieType movie_type, bool bShowMouseAfterPlayback)
+      {
+        extern unsigned int bNoVideo;
+        if (bNoVideo) return;
+
+        switch (movie_type)
+        {
+          case MOVIE_3DOLogo: FullscreenMovieLoop("3dologo", 0);        break;
+          case MOVIE_NWCLogo: FullscreenMovieLoop("new world logo", 0); break;
+          case MOVIE_JVC:     FullscreenMovieLoop("jvc", 0);            break;
+          case MOVIE_Intro:   FullscreenMovieLoop("Intro", 0);          break;
+          case MOVIE_Emerald: FullscreenMovieLoop("Intro Post", 0);     break;
+          case MOVIE_Death:   FullscreenMovieLoop("losegame", 2);       break;
+          case MOVIE_Outro:   FullscreenMovieLoop("end_seq1", 20);      break;
+
+          default:
+            Error("Invalid movie requested: %u", movie_type);
+          break;
+        }
+      }
+	  void FullscreenMovieLoop(const char *pMovieName, int a2);
+      void HouseMovieLoop();
+
+      void ShowMM7IntroVideo_and_LoadingScreen();
+      void Unload();
+	  ///////////////////////////////////////////////
+
+      IMovie *LoadMovie(const wchar_t *name, int width, int height, int cache_ms);
+      IMovie *LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height);
+
+	  //for audio////////////////////////////////////
+	  HANDLE hAudioSnd;
+	  unsigned int uNumSoundHeaders;
+	  struct SoundHeader *pSoundHeaders;
+
+	  void LoadAudioSnd();
+	  ///////////////////////////////////////////////
+
+
+      ITrack *LoadTrack(const wchar_t *name);
+
+  protected:
+    static int readFunction(void *, uint8_t *, int);
+    static int64_t seekFunction(void *, int64_t, int);
+  };
+};
+#pragma pack(pop)
+extern Media::MPlayer *pMediaPlayer;
+extern Media::IMovie *pMovie_Track;
+extern Media::ITrack *pAudio_Track;
+extern class Movie *movie;
+
+extern int mSourceID;
+
+extern void PlayMovie(const wchar_t * pFilename);
+extern void PlayAudio(const wchar_t * pFilename);
+extern void MovieRelease();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Video/Bink_Smacker.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,336 @@
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+
+#define _CRT_SECURE_NO_WARNINGS
+#include "Bink_Smacker.h"
+
+
+
+
+
+
+
+int (__stdcall *smackw32_SmackSoundUseMSS)(HDIGDRIVER) = 0;
+unsigned int (__stdcall *smackw32_SmackUseMMX)(unsigned int) = 0;
+HSMACK (__stdcall *smackw32_SmackOpen)(HANDLE, unsigned int, unsigned int) = 0;
+HSMACKBLIT (__stdcall *smackw32_SmackBlitOpen)(unsigned int) = 0;
+void (__stdcall *smackw32_SmackToBuffer)(HSMACK, unsigned int, unsigned int, unsigned int, unsigned int, void *, unsigned int) = 0;
+void (__stdcall *smackw32_SmackBlitSetPalette)(HSMACKBLIT, void *, unsigned int) = 0;
+unsigned int (__stdcall *smackw32_SmackDoFrame)(HSMACK) = 0;
+unsigned int (__stdcall *smackw32_SmackToBufferRect)(HSMACK, unsigned int) = 0;
+void (__stdcall *smackw32_SmackBlit)(HSMACKBLIT, void *, unsigned int, unsigned int, unsigned int, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) = 0;
+void (__stdcall *smackw32_SmackNextFrame)(HSMACK) = 0;
+unsigned int (__stdcall *smackw32_SmackWait)(HSMACK) = 0;
+unsigned int (__stdcall *smackw32_SmackSoundOnOff)(HSMACK, unsigned int) = 0;
+void (__stdcall *smackw32_SmackClose)(HSMACK) = 0;
+void (__stdcall *smackw32_SmackBufferClose)(HSMACKBUF) = 0;
+void (__stdcall *smackw32_SmackBlitClose)(HSMACKBLIT) = 0;
+int  (__stdcall *smackw32_SmackBlitClear)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int) = 0;
+int  (__stdcall *smackw32_SmackGoto)(_SMACK *, long) = 0;
+int  (__stdcall *smackw32_SmackBufferOpen)(HWND a1, long a2, long a3, long a4, long a5, long a6) = nullptr;
+void(__stdcall *smackw32_SmackBufferNewPalette)(HSMACKBUF, void *, unsigned int) = nullptr;
+void(__stdcall *smackw32_SmackColorRemapWithTrans)(_SMACK *, void *, unsigned int, unsigned int, unsigned int) = nullptr;
+void SMACKW32_DLL_Initialize()
+{
+  HMODULE pDll = LoadLibraryW(L"SmackW32.dll");
+  
+  #define LOAD(x) smackw32_##x = (decltype(smackw32_##x))GetProcAddress(pDll, #x)
+  {
+    smackw32_SmackSoundUseMSS = (int (__stdcall *)(HDIGDRIVER))GetProcAddress(pDll, "_SmackSoundUseMSS@4");
+    smackw32_SmackUseMMX = (unsigned int (__stdcall *)(unsigned int))GetProcAddress(pDll, "_SmackUseMMX@4");
+    smackw32_SmackOpen = (HSMACK (__stdcall *)(HANDLE, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackOpen@12");
+    smackw32_SmackBlitOpen = (HSMACKBLIT (__stdcall *)(unsigned int))GetProcAddress(pDll, "_SmackBlitOpen@4");
+    smackw32_SmackToBuffer = (void (__stdcall *)(HSMACK, unsigned int, unsigned int, unsigned int, unsigned int, void *, unsigned int))GetProcAddress(pDll, "_SmackToBuffer@28");
+    smackw32_SmackBlitSetPalette = (void (__stdcall *)(HSMACKBLIT, void *, unsigned int))GetProcAddress(pDll, "_SmackBlitSetPalette@12");
+    smackw32_SmackDoFrame = (unsigned int (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackDoFrame@4");
+    smackw32_SmackToBufferRect = (unsigned int (__stdcall *)(HSMACK, unsigned int))GetProcAddress(pDll, "_SmackToBufferRect@8");
+    smackw32_SmackBlit = (void (__stdcall *)(HSMACKBLIT, void *, unsigned int, unsigned int, unsigned int, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackBlit@44");
+    smackw32_SmackNextFrame = (void (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackNextFrame@4");
+    smackw32_SmackWait = (unsigned int (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackWait@4");
+    smackw32_SmackSoundOnOff = (unsigned int (__stdcall *)(HSMACK, unsigned int))GetProcAddress(pDll, "_SmackSoundOnOff@8");
+    smackw32_SmackClose = (void (__stdcall *)(HSMACK))GetProcAddress(pDll, "_SmackClose@4");
+    smackw32_SmackBufferClose = (void (__stdcall *)(HSMACKBUF))GetProcAddress(pDll, "_SmackBufferClose@4");
+    smackw32_SmackBlitClose = (void (__stdcall *)(HSMACKBLIT))GetProcAddress(pDll, "_SmackBlitClose@4");
+    smackw32_SmackBlitClear = (int (__stdcall *)(HSMACKBLIT, unsigned short *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int))GetProcAddress(pDll, "_SmackBlitClear@32");
+    smackw32_SmackGoto = (int  (__stdcall *)(_SMACK *, long))GetProcAddress(pDll, "_SmackGoto@8");
+    smackw32_SmackBufferOpen = (int  (__stdcall *)(HWND, long, long, long, long, long))GetProcAddress(pDll, "_SmackBufferOpen@24");
+	smackw32_SmackBufferNewPalette = (void(__stdcall *)(HSMACKBUF, void *, unsigned int))GetProcAddress(pDll, "_SmackBufferNewPalette@12");
+	smackw32_SmackColorRemapWithTrans = (void(__stdcall *)(_SMACK *, void *, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_SmackColorRemapWithTrans@20");
+    //LOAD(SmackBufferNewPalette);
+    //LOAD(SmackColorRemapWithTrans);
+  }
+}
+
+
+
+
+void __stdcall SmackColorRemapWithTrans(_SMACK *a1, void *a2, unsigned int a3, unsigned int a4, unsigned int a5)
+{
+  return (smackw32_SmackColorRemapWithTrans)(a1, a2, a3, a4, a5);
+}
+
+void __stdcall SmackBlitClose(HSMACKBLIT hBlit)
+{
+ (smackw32_SmackBlitClose)(hBlit);
+}
+
+void __stdcall SmackBufferClose(HSMACKBUF hBuf)
+{
+ (smackw32_SmackBufferClose)(hBuf);
+}
+
+void __stdcall SmackClose(HSMACK hSmack)
+{
+ (smackw32_SmackClose)(hSmack);
+}
+
+unsigned int __stdcall SmackSoundOnOff(HSMACK hSmack, unsigned int bOn)
+{
+ return (smackw32_SmackSoundOnOff)(hSmack, bOn);
+}
+
+unsigned int __stdcall SmackWait(HSMACK hSmack)
+{
+ return (smackw32_SmackWait)(hSmack);
+}
+
+void __stdcall SmackNextFrame(HSMACK hSmack)
+{
+ (smackw32_SmackNextFrame)(hSmack);
+}
+
+void __stdcall SmackBlit(HSMACKBLIT hBlit, void *pDest, unsigned int uDestPitch, unsigned int uDestX, unsigned int uDestY, void *pSrc, unsigned int uSrcPitch, unsigned int uSrcX, unsigned int uSrcY, unsigned int uSrcZ, unsigned int uSrcW)
+{
+ (smackw32_SmackBlit)(hBlit, pDest, uDestPitch, uDestX, uDestY, pSrc, uSrcPitch, uSrcX, uSrcY, uSrcZ, uSrcW);
+}
+
+unsigned int __stdcall SmackToBufferRect(HSMACK hSmack, unsigned int uSmackSurface)
+{
+ return (smackw32_SmackToBufferRect)(hSmack, uSmackSurface);
+}
+
+unsigned int __stdcall SmackDoFrame(HSMACK hSmack)
+{
+ return (smackw32_SmackDoFrame)(hSmack);
+}
+
+void __stdcall SmackBlitSetPalette(HSMACKBLIT hBlit, void *pPalette, unsigned int uPalType)
+{
+ (smackw32_SmackBlitSetPalette)(hBlit, pPalette, uPalType);
+}
+
+int __stdcall SmackSoundUseMSS(HDIGDRIVER hDrv)
+{
+ return (smackw32_SmackSoundUseMSS)(hDrv);
+}
+
+unsigned int __stdcall SmackUseMMX(unsigned int flag)
+{
+ return (smackw32_SmackUseMMX)(flag);
+}
+
+HSMACK __stdcall SmackOpen(HANDLE hSourceFile, unsigned int uFlags, unsigned int uExtraBuffers)
+{
+ return (smackw32_SmackOpen)(hSourceFile, uFlags, uExtraBuffers);
+}
+
+HSMACKBLIT __stdcall SmackBlitOpen(unsigned int uSurfaceFormat)
+{
+ return (smackw32_SmackBlitOpen)(uSurfaceFormat);
+}
+
+void __stdcall SmackToBuffer(HSMACK hSmack, unsigned int uX, unsigned int uY, unsigned int uPitch, unsigned int uHeight, void *pBuffer, unsigned int uFlags)
+{
+ (smackw32_SmackToBuffer)(hSmack, uX, uY, uPitch, uHeight, pBuffer, uFlags);
+}
+
+int __stdcall SmackBlitClear(HSMACKBLIT a1, unsigned short *pFrameData, unsigned int uTargetSurfacePitch, unsigned int uOutX, unsigned int uOutY, unsigned int uOutZ, unsigned int uOutW, int a8)
+{
+ return (smackw32_SmackBlitClear)(a1, pFrameData, uTargetSurfacePitch, uOutX, uOutY, uOutZ, uOutW, a8);
+}
+
+int __stdcall SmackGoto(_SMACK *a1, long a2)
+{
+ return (smackw32_SmackGoto)(a1, a2);
+}
+
+
+int __stdcall SmackBufferOpen(HWND a1, long a2, long a3, long a4, long a5, long a6)
+{
+  return (smackw32_SmackBufferOpen)(a1, a2, a3, a4, a5, a6);
+}
+
+int __fastcall SmackVolumePan(_SMACK *a3, long a4, long a5, long a6)
+{
+ //__asm int 3
+ return 0;
+}
+
+
+// sub_4D83D0: using guessed type int __stdcall SmackBufferNewPalette(_DWORD, _DWORD, _DWORD);
+void __stdcall SmackBufferNewPalette(HSMACKBUF a1, void *a2, unsigned int a3)
+{
+ (smackw32_SmackBufferNewPalette)(a1, a2, a3);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int (__stdcall *binkw32_BinkDDSurfaceType)(struct IDirectDrawSurface *) = 0;
+int (__stdcall *binkw32_BinkSetSoundSystem)(void *, HDIGDRIVER) = 0;
+int (__stdcall *binkw32_BinkOpenMiles)(int) = 0;
+HBINK (__stdcall *binkw32_BinkOpen)(void *, unsigned int) = 0;
+int (__stdcall *binkw32_BinkWait)(HBINK) = 0;
+int (__stdcall *binkw32_BinkDoFrame)(HBINK) = 0;
+int (__stdcall *binkw32_BinkNextFrame)(HBINK) = 0;
+int (__stdcall *binkw32_BinkGetRects)(HBINK, unsigned int) = 0;
+int (__stdcall *binkw32_BinkCopyToBuffer)(HBINK, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) = 0;
+int (__stdcall *binkw32_BinkPause)(HBINK, int) = 0;
+int (__stdcall *binkw32_BinkClose)(HBINK) = 0;
+int (__stdcall *binkw32_BinkBufferSetOffset)(void *, int, int) = 0;
+int (__stdcall *binkw32_BinkBufferSetScale)(void *, unsigned int, unsigned int) = 0;
+void BINKW32_DLL_Initialize()
+{
+ HMODULE pDll = LoadLibraryW(L"BinkW32.dll");
+
+ binkw32_BinkDDSurfaceType = (int (__stdcall *)(struct IDirectDrawSurface *))GetProcAddress(pDll, "_BinkDDSurfaceType@4");
+ binkw32_BinkSetSoundSystem = (int (__stdcall *)(void *, HDIGDRIVER))GetProcAddress(pDll, "_BinkSetSoundSystem@8");
+ binkw32_BinkOpenMiles = (int (__stdcall *)(int))GetProcAddress(pDll, "_BinkOpenMiles@4");
+ binkw32_BinkOpen = (HBINK (__stdcall *)(void *, unsigned int))GetProcAddress(pDll, "_BinkOpen@8");
+ binkw32_BinkWait = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkWait@4");
+ binkw32_BinkBufferSetOffset = (int (__stdcall *)(void *, int, int))GetProcAddress(pDll, "_BinkBufferSetOffset@12");
+ binkw32_BinkBufferSetScale = (int (__stdcall *)(void *, unsigned int, unsigned int))GetProcAddress(pDll, "_BinkBufferSetScale@12");
+ binkw32_BinkDoFrame = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkDoFrame@4");
+ binkw32_BinkNextFrame = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkNextFrame@4");
+ binkw32_BinkGetRects = (int (__stdcall *)(HBINK, unsigned int))GetProcAddress(pDll, "_BinkGetRects@8");
+ binkw32_BinkCopyToBuffer = (int (__stdcall *)(HBINK, void *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int))GetProcAddress(pDll, "_BinkCopyToBuffer@28");
+ binkw32_BinkPause = (int (__stdcall *)(HBINK, int))GetProcAddress(pDll, "_BinkPause@8");
+ binkw32_BinkClose = (int (__stdcall *)(HBINK))GetProcAddress(pDll, "_BinkClose@4");
+}
+
+
+int __stdcall BinkPause(HBINK hBink, int bPause)
+{
+ return (binkw32_BinkPause)(hBink, bPause);
+}
+
+int __stdcall BinkClose(HBINK hBink)
+{
+ return (binkw32_BinkClose)(hBink);
+}
+
+int __stdcall BinkGetRects(HBINK hBink, unsigned int uFlags)
+{
+ return (binkw32_BinkGetRects)(hBink, uFlags);
+}
+
+int __stdcall BinkCopyToBuffer(HBINK hBink, void *pBuffer, unsigned int lPitch, unsigned int uNumScanlines, unsigned int uX, unsigned int uY, unsigned int uFlags)
+{
+ return (binkw32_BinkCopyToBuffer)(hBink, pBuffer, lPitch, uNumScanlines, uX, uY, uFlags);
+}
+
+int __stdcall BinkDoFrame(HBINK hBink)
+{
+ return (binkw32_BinkDoFrame)(hBink);
+}
+
+int __stdcall BinkNextFrame(HBINK hBink)
+{
+ return (binkw32_BinkNextFrame)(hBink);
+}
+
+HBINK __stdcall BinkOpen(void *hFileHandle, unsigned int uFlags)
+{
+ return (binkw32_BinkOpen)(hFileHandle, uFlags);
+}
+
+int __stdcall BinkOpenMiles(int unk)
+{
+ return (binkw32_BinkOpenMiles)(unk);
+}
+
+int __stdcall BinkWait(HBINK hBink)
+{
+ return (binkw32_BinkWait)(hBink);
+}
+
+
+
+int __stdcall BinkBufferSetOffset(void *pStruct, int b, int c)
+{
+ return (binkw32_BinkBufferSetOffset)(pStruct, b, c);
+}
+
+int __stdcall BinkBufferSetScale(void *pStruct, unsigned int uWidth, unsigned int uHeight)
+{
+ return (binkw32_BinkBufferSetScale)(pStruct, uWidth, uHeight);
+}
+
+int __stdcall BinkDDSurfaceType(struct IDirectDrawSurface *pDDS)
+{
+ return (binkw32_BinkDDSurfaceType)(pDDS);
+}
+
+int __stdcall BinkSetSoundSystem(void *pSoundSystem, HDIGDRIVER hDrv)
+{
+ return (binkw32_BinkSetSoundSystem)(pSoundSystem, hDrv);
+}
+
+
+
+
+
+
+int __stdcall BinkGoto(_BINK *a1, long a2, long a3)
+{
+ __asm int 3
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Media/Video/Bink_Smacker.h	Fri Sep 19 05:13:32 2014 +0600
@@ -0,0 +1,230 @@
+#pragma once
+#include "Media/Audio/AIL.h"
+
+
+
+
+void BINKW32_DLL_Initialize();
+
+
+int __stdcall BinkDDSurfaceType(struct IDirectDrawSurface *);
+int __stdcall BinkSetSoundSystem(void *pSoundSystem, HDIGDRIVER hDrv);
+int __stdcall BinkOpenMiles(int);
+HBINK __stdcall BinkOpen(void *hFileHandle, unsigned int uFlags);
+int __stdcall BinkWait(HBINK);
+int __stdcall BinkDoFrame(HBINK);
+int __stdcall BinkNextFrame(HBINK);
+int __stdcall BinkGetRects(HBINK hBink, unsigned int uFlags);
+int __stdcall BinkCopyToBuffer(HBINK hBink, void *pBuffer, unsigned int lPitch, unsigned int uNumLines, unsigned int uX, unsigned int uY, unsigned int uFlags);
+int __stdcall BinkPause(HBINK, int bPause);
+int __stdcall BinkClose(HBINK);
+int __stdcall BinkGoto(HBINK, long a2, long a3);
+
+int __stdcall BinkBufferSetOffset(void *, int, int);
+int __stdcall BinkBufferSetScale(void *, unsigned int uWidth, unsigned int uHeight);
+
+  void SMACKW32_DLL_Initialize();
+
+struct _SMACK
+{
+  unsigned int Version;           // SMK2 only right now
+  unsigned int Width;             // Width (1 based, 640 for example)
+  unsigned int Height;            // Height (1 based, 480 for example)
+  unsigned int Frames;            // Number of frames (1 based, 100 = 100 frames)
+  unsigned int MSPerFrame;        // Frame Rate
+  unsigned int SmackerType;       // bit 0 set=ring frame
+  unsigned int LargestInTrack[7]; // Largest single size for each track
+  unsigned int tablesize;         // Size of the init tables
+  unsigned int codesize;          // Compression info   
+  unsigned int absize;            // ditto
+  unsigned int detailsize;        // ditto
+  unsigned int typesize;          // ditto
+  unsigned int TrackType[7];      // high byte=0x80-Comp,0x40-PCM data,0x20-16 bit,0x10-stereo
+  unsigned int extra;             // extra value (should be zero)
+  unsigned int NewPalette;        // set to one if the palette changed
+  unsigned char Palette[772];      // palette data
+  unsigned int PalType;           // type of palette
+  unsigned int FrameNum;          // 0374 Frame Number to be displayed
+  unsigned int FrameSize;         // The current frame's size in bytes
+  unsigned int SndSize;           // The current frame sound tracks' size in bytes
+  int LastRectx;                  // 0380 Rect set in from SmackToBufferRect (X coord)
+  int LastRecty;                  // Rect set in from SmackToBufferRect (Y coord)
+  int LastRectw;                  // Rect set in from SmackToBufferRect (Width)
+  int LastRecth;                  // 038C Rect set in from SmackToBufferRect (Height)
+  unsigned int OpenFlags;         // flags used on open
+  unsigned int LeftOfs;           // Left Offset used in SmackTo
+  unsigned int TopOfs;            // Top Offset used in SmackTo
+  unsigned int LargestFrameSize;  // Largest frame size
+  unsigned int Highest1SecRate;   // Highest 1 sec data rate
+  unsigned int Highest1SecFrame;  // Highest 1 sec data rate starting frame
+  unsigned int ReadError;         // Set to non-zero if a read error has ocurred
+  unsigned int addr32;            // translated address for 16 bit interface
+};
+
+
+
+struct _SMACKBLIT
+{
+  unsigned int    Flags;
+  unsigned char  *Palette;
+  unsigned int    PalType;
+  unsigned short *SmoothTable;
+  unsigned short *Conv8to16Table;
+  unsigned int    whichmode;
+  unsigned int    palindex;
+  unsigned int    t16index;
+  unsigned int    smoothindex;
+  unsigned int    smoothtype;
+  unsigned int    firstpalette;
+};
+
+struct _SMACKBUF
+{
+        unsigned int Reversed;             // 1 if the buffer is upside down
+        unsigned int SurfaceType;          // SMACKSURFACExxxx defines
+        unsigned int BlitType;             // SMACKxxxxBLIT defines
+        unsigned int FullScreen;           // 1 if full-screen
+        unsigned int Width;
+        unsigned int Height;
+        unsigned int Pitch;
+        unsigned int Zoomed;
+        unsigned int ZWidth;
+        unsigned int ZHeight;
+        unsigned int DispColors;           // colors on the screen
+        unsigned int MaxPalColors;         // total possible colors in palette (usually 256)
+        unsigned int PalColorsInUse;       // Used colors in palette (usually 236)
+        unsigned int StartPalColor;        // first usable color index (usually 10)
+        unsigned int EndPalColor;          // last usable color index (usually 246)
+        RGBQUAD Palette[256];
+        unsigned int PalType;
+        unsigned int forceredraw;  // force a complete redraw on next blit (for >8bit)
+        unsigned int didapalette;  // force an invalidate on the next palette change
+
+        void * Buffer;
+        void * DIBRestore;
+        unsigned int OurBitmap;
+        unsigned int OrigBitmap;
+        unsigned int OurPalette;
+        unsigned int WinGDC;
+        unsigned int FullFocused;
+        unsigned int ParentHwnd;
+        unsigned int OldParWndProc;
+        unsigned int OldDispWndProc;
+        unsigned int DispHwnd;
+        unsigned int WinGBufHandle;
+        void * lpDD;
+        void * lpDDSP;
+        unsigned int DDSurfaceType;
+        struct _SMACKBLIT DDblit;
+        int ddSoftwarecur;
+        int didaddblit;
+        int lastwasdd;
+        RECT ddscreen;
+        int manyblits;
+        int * blitrects;
+        int * rectsptr;
+        int maxrects;
+        int numrects;
+        HDC lastdc;
+};
+#define BINKFRAMERATE            0x00001000L // Override fr (call BinkFrameRate first)
+#define BINKPRELOADALL            0x00002000L // Preload the entire animation
+#define BINKSNDTRACK            0x00004000L // Set the track number to play
+#define BINKOLDFRAMEFORMAT        0x00008000L // using the old Bink frame format (internal use only)
+#define BINKRBINVERT            0x00010000L // use reversed R and B planes (internal use only)
+#define BINKGRAYSCALE            0x00020000L // Force Bink to use grayscale
+#define BINKNOMMX                0x00040000L // Don't use MMX
+#define BINKNOSKIP                0x00080000L // Don't skip frames if falling behind
+#define BINKALPHA                0x00100000L // Decompress alpha plane (if present)
+#define BINKNOFILLIOBUF            0x00200000L // Fill the IO buffer in SmackOpen
+#define BINKSIMULATE            0x00400000L // Simulate the speed (call BinkSim first)
+#define BINKFILEHANDLE            0x00800000L // Use when passing in a file handle
+#define BINKIOSIZE                0x01000000L // Set an io size (call BinkIOSize first)
+#define BINKIOPROCESSOR            0x02000000L // Set an io processor (call BinkIO first)
+#define BINKFROMMEMORY            0x04000000L // Use when passing in a pointer to the file
+#define BINKNOTHREADEDIO        0x08000000L // Don't use a background thread for IO
+
+#define BINKSURFACEFAST            0x00000000L
+#define BINKSURFACESLOW            0x08000000L
+#define BINKSURFACEDIRECT        0x04000000L
+
+#define BINKCOPYALL                0x80000000L // copy all pixels (not just changed)
+#define BINKCOPY2XH                0x10000000L // Force doubling height scaling
+#define BINKCOPY2XHI            0x20000000L // Force interleaving height scaling
+#define BINKCOPY2XW                0x30000000L // copy the width zoomed by two
+#define BINKCOPY2XWH            0x40000000L // copy the width and height zoomed by two
+#define BINKCOPY2XWHI            0x50000000L // copy the width and height zoomed by two
+#define BINKCOPY1XI                0x60000000L // copy the width and height zoomed by two
+#define BINKCOPYNOSCALING        0x70000000L // Force scaling off
+
+#define SMACKNEEDPAN    0x00020L // Will be setting the pan
+#define SMACKNEEDVOLUME 0x00040L // Will be setting the volume
+#define SMACKFRAMERATE  0x00080L // Override fr (call SmackFrameRate first)
+#define SMACKLOADEXTRA  0x00100L // Load the extra buffer during SmackOpen
+#define SMACKPRELOADALL 0x00200L // Preload the entire animation
+#define SMACKNOSKIP     0x00400L // Don't skip frames if falling behind
+#define SMACKSIMULATE   0x00800L // Simulate the speed (call SmackSim first)
+#define SMACKFILEHANDLE 0x01000L // Use when passing in a file handle
+#define SMACKTRACK1     0x02000L // Play audio track 1
+#define SMACKTRACK2     0x04000L // Play audio track 2
+#define SMACKTRACK3     0x08000L // Play audio track 3
+#define SMACKTRACK4     0x10000L // Play audio track 4
+#define SMACKTRACK5     0x20000L // Play audio track 5
+#define SMACKTRACK6     0x40000L // Play audio track 6
+#define SMACKTRACK7     0x80000L // Play audio track 7
+
+
+#define SMACKBUFFER555      0x80000000
+#define SMACKBUFFER565      0xC0000000
+
+#define SMACKBLIT1X                1
+#define SMACKBLIT2X                2
+#define SMACKBLIT2XSMOOTHING       4
+#define SMACKBLIT2XINTERLACE       8
+
+
+int __stdcall SmackSoundUseMSS(HDIGDRIVER hDrv);
+unsigned int __stdcall SmackUseMMX(unsigned int flag);
+HSMACK __stdcall SmackOpen(HANDLE hSourceFile, unsigned int uFlags, unsigned int uExtraBuffers);
+HSMACKBLIT __stdcall SmackBlitOpen(unsigned int uSurfaceFormat);
+void __stdcall SmackToBuffer(HSMACK, unsigned int uX, unsigned int uY, unsigned int uPitch, unsigned int uHeight, void *pBuffer, unsigned int uFlags);
+void __stdcall SmackBlitSetPalette(HSMACKBLIT hBlit, void *pPalette, unsigned int uPalType);
+unsigned int __stdcall SmackDoFrame(HSMACK);
+unsigned int __stdcall SmackToBufferRect(HSMACK, unsigned int uSmackSurface);
+void __stdcall SmackBlit(HSMACKBLIT, void *pDest, unsigned int uDestPitch, unsigned int uDestX, unsigned int uDestY, void *pSrc, unsigned int uSrcPitch, unsigned int uSrcX, unsigned int uSrcY, unsigned int uSrcZ, unsigned int uSrcW);
+void __stdcall SmackNextFrame(HSMACK);
+unsigned int __stdcall SmackWait(HSMACK);
+unsigned int __stdcall SmackSoundOnOff(HSMACK, unsigned int bOn);
+void __stdcall SmackClose(HSMACK);
+void __stdcall SmackBufferClose(HSMACKBUF);
+void __stdcall SmackBlitClose(HSMACKBLIT);
+int __stdcall SmackBlitClear(HSMACKBLIT a1, unsigned short *pFrameData, unsigned int uTargetSurfacePitch, unsigned int uOutX, unsigned int uOutY, unsigned int uOutZ, unsigned int uOutW, int a8);
+
+
+
+
+
+int __stdcall SmackBufferOpen(HWND a1, long a2, long a3, long a4, long a5, long a6);
+int __fastcall SmackVolumePan(_SMACK *a3, long a4, long a5, long a6);
+
+int __stdcall SmackGoto(_SMACK *a1, long a2);
+
+// sub_4D83D0: using guessed type int __stdcall SmackBufferNewPalette(_DWORD, _DWORD, _DWORD);
+void __stdcall SmackBufferNewPalette(HSMACKBUF a1, void *a2, unsigned int a3);
+
+// sub_4D83D4: using guessed type int __stdcall SmackColorRemapWithTrans(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD);
+void __stdcall SmackColorRemapWithTrans(_SMACK *a1, void *a2, unsigned int a3, unsigned int a4, unsigned int a5);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- a/MediaPlayer.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1511 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#include <vector>
-#include <deque>
-
-#define _CRT_SECURE_NO_WARNINGS
-
-
-#include "Mouse.h"
-#include "GUIWindow.h"
-#include "Engine/mm7_data.h"
-#include "OpenALSoundProvider.h"
-#include "Engine/Log.h"
-#include "MediaPlayer.h"
-#include "Bink_Smacker.h"
-#include "AudioPlayer.h"
-#include "Engine/Timer.h"
-#include "Engine/Graphics/Render.h"
-#include "Engine/Game.h"
-
-
-#pragma comment(lib, "Version.lib")
-
-using namespace Media;
-
-Media::MPlayer *pMediaPlayer = nullptr;
-Media::IMovie *pMovie_Track;
-Media::ITrack *pAudio_Track;
-Movie *movie;
-
-int mSourceID;
-
-void PlayMovie(const wchar_t * pFilename);
-void PlayAudio(const wchar_t * pFilename);
-void LoadMovie(const char *);
- 
-class MemoryStream 
-{
-  public:
-    inline MemoryStream(void *data, size_t data_size)
-    {
-      this->data_size = data_size;
-      this->data = data;
-      this->current_pos = 0;
-    }
-    inline MemoryStream()
-    {
-      this->data_size = 0;
-      this->data = nullptr;
-      this->current_pos = 0;
-    }
-
-    inline ~MemoryStream()
-    {
-      //Log::Warning(L"Destructor: data delete %u", data);
-      if (data)
-        delete [] data;
-    }
-
-    inline size_t Write(void *buffer, size_t num_bytes)
-    {
-      if (!data)
-      {
-        data_size = 32 + num_bytes;
-        data = new char[data_size];
-        //Log::Warning(L"new data %u", data);
-        current_pos = 0;
-      }
-      else if (current_pos + num_bytes >= data_size)
-      {
-        int  new_data_size = data_size + num_bytes + data_size / 8 + 4;
-        auto new_data = new char[new_data_size];
-        //Log::Warning(L"new new_data %u", new_data);
-
-        memcpy(new_data, data, data_size);
-        //Log::Warning(L"data delete %u", data);
-        delete [] data;
-
-        data_size = new_data_size;
-        data = new_data;
-      }
-      memcpy((char *)data + current_pos, buffer, num_bytes);
-      current_pos += num_bytes;
-      return num_bytes;
-    }
-
-    inline size_t Read(void *buffer, size_t num_bytes)
-    {
-      size_t read_size = min(num_bytes, data_size - current_pos);
-      if (read_size)
-      {
-        memcpy(buffer, (char *)data + current_pos, read_size);
-        current_pos += read_size;
-      }
-      return read_size;
-    }
-
-    inline void Reset()
-    {
-      current_pos = 0;
-    }
-    inline void SeekToEnd()
-    {
-      current_pos = data_size;
-    }
-
-    inline size_t Unwind(size_t bytes)
-    {
-      if (bytes > current_pos)
-        current_pos = 0;
-      else
-        current_pos -= bytes;
-      return current_pos;
-    }
-    
-    inline size_t Rewind(size_t bytes)
-    {
-      if (current_pos + bytes >= data_size)
-        current_pos = data_size;
-      else
-        current_pos += bytes;
-      return current_pos;
-    }
-
-    inline size_t  Size() const    {return data_size;}
-    inline size_t  Current() const {return current_pos;}
-    inline void   *Ptr() const     {return data;}
-
-  private:
-    void   *data;
-    size_t  data_size;
-    size_t  current_pos;
-};
-
-OpenALSoundProvider *provider = nullptr;
-
-static int av_num_bytes_per_sample(AVSampleFormat sample_fmt)
-{
-  switch (sample_fmt)
-  {
-    case AV_SAMPLE_FMT_U8:
-    case AV_SAMPLE_FMT_U8P:
-      return 1;
-          
-    case AV_SAMPLE_FMT_S16:
-    case AV_SAMPLE_FMT_S16P:
-      return 2;
-
-    case AV_SAMPLE_FMT_S32:
-    case AV_SAMPLE_FMT_S32P:
-    case AV_SAMPLE_FMT_FLT:
-    case AV_SAMPLE_FMT_FLTP:
-      return 4;
-
-    case AV_SAMPLE_FMT_DBL:
-    case AV_SAMPLE_FMT_DBLP:
-      return 8;
-
-    default:
-    case AV_SAMPLE_FMT_NONE:
-      Error("Invalid av sample format: %u", sample_fmt);
-  }
-  return 0;
-}
-
-struct AVStreamWrapper
-{
-  inline AVStreamWrapper()
-  {
-    this->type = AVMEDIA_TYPE_UNKNOWN;
-    this->stream_idx = -1;
-    this->stream = nullptr;
-    this->dec = nullptr;
-    this->dec_ctx = nullptr;
-  }
-
-  inline void Release()
-  {
-    type = AVMEDIA_TYPE_UNKNOWN;
-    stream_idx = -1;
-    stream = nullptr;
-    dec = nullptr;
-    if (dec_ctx)
-    {
-	  // Close the codec
-      avcodec_close(dec_ctx);
-	  Log::Warning(L"close decoder context file\n");
-      dec_ctx = nullptr;
-    }
-  }
-
-  AVMediaType      type;
-  int              stream_idx;
-  AVStream        *stream;
-  AVCodec         *dec;
-  AVCodecContext  *dec_ctx;
-};
-
-struct AVAudioStream: public AVStreamWrapper
-{
-  inline AVAudioStream():AVStreamWrapper()
-  {
-    this->bytes_per_sample = 0;
-    this->bytes_per_second = 0;
-  }
-
-  int bytes_per_sample;
-  int bytes_per_second;
-};
-
-struct AVVideoStream: public AVStreamWrapper
-{
-  inline AVVideoStream(): AVStreamWrapper()
-  {
-    this->frames_per_second = 0.0;
-  }
-
-  double frames_per_second;
-};
-
-static bool av_open_stream(AVFormatContext *format_ctx, AVMediaType type, AVStreamWrapper *out_stream)
-{
-  int stream_idx = av_find_best_stream(format_ctx, type, -1, -1, nullptr, 0);
-  if (stream_idx >= 0)
-  {
-    auto stream = format_ctx->streams[stream_idx];
-    auto dec_ctx = stream->codec;
-
-	// Find the decoder for the video stream
-    auto dec = avcodec_find_decoder(dec_ctx->codec_id);
-    if (dec)
-    {
-	  // Open codec
-      if (avcodec_open2(dec_ctx, dec, nullptr) >= 0)
-      {
-        out_stream->type = type;
-        out_stream->stream_idx = stream_idx;
-        out_stream->stream = stream;
-        out_stream->dec = dec;
-        out_stream->dec_ctx = dec_ctx;
-        return true;
-      }
-      fprintf(stderr, "ffmpeg: Could not open codec\n");
-	  return false;
-    }
-    fprintf(stderr, "ffmpeg: Unable to open codec\n");
-	return false;
-  }
-  fprintf(stderr, "ffmpeg: Didn't find a stream\n");
-  return false;	
-}
-
-static bool av_open_audio_stream(AVFormatContext *format_ctx, AVAudioStream *out_stream)
-{
-  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_AUDIO, out_stream))
-    return Error("Audio stream not found"), false;
-  
-  // we support only 2-channel audio for now
-  //if (out_stream->dec_ctx->channels != 2)
-  //{
-   // out_stream->Release();
-   // return Error("Unsupported number of channels: %u", out_stream->dec_ctx->channels), false;
-  //}
-  
-  out_stream->bytes_per_sample = av_num_bytes_per_sample(out_stream->dec_ctx->sample_fmt);
-  out_stream->bytes_per_second = out_stream->dec_ctx->channels * out_stream->dec_ctx->sample_rate * out_stream->bytes_per_sample;
-
-  return true;
-}
-
-static bool av_open_video_stream(AVFormatContext *format_ctx, AVVideoStream *out_stream)
-{
-  if (!av_open_stream(format_ctx, AVMEDIA_TYPE_VIDEO, out_stream))
-    return Error("Video stream not found"), false;
-
-  out_stream->frames_per_second = (double)out_stream->dec_ctx->time_base.den / (double)out_stream->dec_ctx->time_base.num;
-  return true;
-}
-
-void InterleaveAudioData(MemoryStream *stream, AVSampleFormat src_format, int num_channels, int num_samples, uint8_t **channels)
-{
-  unsigned int bytes_per_sample;
-  switch (src_format)
-  {
-    case AV_SAMPLE_FMT_U8:
-    case AV_SAMPLE_FMT_U8P:
-      __debugbreak();
-
-    case AV_SAMPLE_FMT_S16:
-      bytes_per_sample = sizeof(__int16);
-      stream->Write(channels[0], num_channels * num_samples * bytes_per_sample);
-    break;
-
-    case AV_SAMPLE_FMT_S16P:
-    {
-      bytes_per_sample = sizeof(__int16);
-      for (int i = 0; i < num_samples; ++i)
-        for (int j = 0; j < num_channels; ++j)
-          stream->Write(channels[j] + i * bytes_per_sample, bytes_per_sample);
-    }
-    break;
-
-    case AV_SAMPLE_FMT_FLT:
-    {
-      SwrContext *converter = swr_alloc();
-      av_opt_set_int(converter, "in_channel_layout",    av_get_default_channel_layout(2), 0);
-      //av_opt_set_int(converter, "in_sample_rate",       sample_ra, 0);
-      av_opt_set_sample_fmt(converter, "in_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
-
-      av_opt_set_int(converter, "out_channel_layout",    av_get_default_channel_layout(2), 0);
-      //av_opt_set_int(converter, "out_sample_rate",       dst_sample_rate, 0);
-      av_opt_set_sample_fmt(converter, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
-
-      if (swr_init(converter) < 0)
-      {
-        __debugbreak();
-        swr_free(&converter);
-        return;
-      }
-
-      uint8_t **dst_channels;
-      int       dst_linesize[8];
-      //int dst_nb_channels = av_get_channel_layout_nb_channels(dst_channel_layout);
-      if (av_samples_alloc_array_and_samples(&dst_channels, dst_linesize, 2, num_channels * num_samples, AV_SAMPLE_FMT_S16, 0) < 0)
-      {
-        __debugbreak();
-        swr_free(&converter);
-        return;
-      }
-
-      if (swr_convert(converter, dst_channels, num_channels * num_samples, (const uint8_t **)channels, num_channels * num_samples) >= 0) //Invalid partial memory access, Uninitialized memory access
-
-        stream->Write(dst_channels[0], num_channels * num_samples * sizeof(__int16));
-      else
-        __debugbreak();
-
-      av_free(dst_channels[0]);
-      swr_free(&converter);
-    }
-    break;
-
-    default:
-      __debugbreak();
-      //if (Resample(next_frame->avframe, next_frame->avframe->channel_layout, next_frame->avframe->sample_rate,
-      //                                            av_get_default_channel_layout(2),    next_frame->avframe->sample_rate, AV_SAMPLE_FMT_S16P, resampled_data))
-  }
-}
-
-const uint16_t ff_wma_critical_freqs[25] = {
-    100,   200,  300, 400,   510,  630,  770,    920,
-    1080, 1270, 1480, 1720, 2000, 2320, 2700,   3150,
-    3700, 4400, 5300, 6400, 7700, 9500, 12000, 15500,
-    24500,
-};
-extern const uint16_t ff_wma_critical_freqs[25];
-static float quant_table[96];
-
-bool DecodeAudioFrame(AVCodecContext *dec_ctx, AVPacket *avpacket, AVFrame *avframe, MemoryStream *out_audio_data, int *out_num_audio_samples)
-{
-  volatile int decoded = false;
-  do
-  {
-    if (avcodec_decode_audio4(dec_ctx, avframe, (int *)&decoded, avpacket) < 0)	//Uninitialized portail memory access
-    {
-      log("Cannot decode audio frame\n");
-      return false;
-    }
-
-    if (!decoded)
-      log("Cannot decode audio frame in one piece\n");
-  } while (!decoded);
-
-  switch (dec_ctx->codec_id)
-  {
-    case  AV_CODEC_ID_BINKAUDIO_DCT:
-    {
-      __debugbreak();	
-    }
-    case AV_CODEC_ID_BINKAUDIO_RDFT:
-    {//pts	samples		dpts
-     //    0	960
-     //17280	960		17280    18x960
-     //18240	960		960       1x960
-     //20160	960		1920      2x960
-     //21120	960		960       1x960
-     //23040	960		1920      2x960
-      /*static int bink_next_pts = 0;
-
-        // there's a gap in the sound - fill empty samples in
-      if (bink_next_pts < avpacket->pts)
-      {
-        short silence[1024];
-        memset(silence, 0, sizeof(silence));
-
-        int samples_to_fill = /*dec_ctx->channels *  (avpacket->pts - bink_next_pts);
-        while (samples_to_fill > 0)
-        {
-          int samples_to_fill_this_step = samples_to_fill >= 1024 ? 1024 : samples_to_fill;
-          out_audio_data->Write(silence, samples_to_fill_this_step  * sizeof(short));
-
-          samples_to_fill -= samples_to_fill_this_step;
-        }
-      }
-
-      bink_next_pts = avpacket->pts + /*dec_ctx->channels *  avframe->nb_samples; */
-
-  AVFrame frame;
-  int first;
-  int version_b;
-  int frame_len;
-  int overlap_len;        
-  int block_size;
-  int num_bands;
-  unsigned int *bands;
-  float root;
-  int sample_rate = dec_ctx->sample_rate;
-  int sample_rate_half;
-  int i;
-  int frame_len_bits;
-  int channels;
-
-  //compresses audio in chunks of varying sizes depending on sample rate:
-   // if sample rate < 22050, frame size is 2048 samples
-   // if sample rate < 44100, frame size is 4096 samples
-   // else, frame size is 8192 samples
-
-
-  /* determine frame length */
-  if (dec_ctx->sample_rate < 22050)
-    frame_len_bits = 9;
-  else if (dec_ctx->sample_rate < 44100)
-    frame_len_bits = 10;
-  else
-    frame_len_bits = 11;
-
-  if (dec_ctx->channels < 1 || dec_ctx->channels > 2) 
-  {
-        av_log(dec_ctx, AV_LOG_ERROR, "invalid number of channels: %d\n", dec_ctx->channels);
-        return AVERROR_INVALIDDATA;
-  }
-
-	  version_b = dec_ctx->extradata_size >= 4 && dec_ctx->extradata[3] == 'b';
-      if (version_b)
-	    __debugbreak();
-
-      if (dec_ctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
-      {
-        // audio is already interleaved for the RDFT format variant
-        dec_ctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-        sample_rate  *= dec_ctx->channels;
-        channels = 1;
-        if (!version_b)
-          frame_len_bits += av_log2(dec_ctx->channels);
-      }
-      else
-      {
-        channels = dec_ctx->channels;
-        dec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
-      }
-
-	  frame_len     = 1 << frame_len_bits;                          //2048
-
-	  //a frame is windowed with the previous frame; the size of the window is frame size / 16 
-      overlap_len   = frame_len / 16;                               //128
-      block_size    = (frame_len - overlap_len) * channels;         //1920
-
-	  //compute half the sample rate as (sample rate + 1) / 2;
-	  //initialize an array of band frequencies corresponding to an array of 25 critical frequencies (same as WMA, apparently),
-	  // any for which the critical frequencies are less than half the sample rate 
-
-      sample_rate_half = (sample_rate + 1) / 2;	                    //22050
-      if (dec_ctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT)
-         root = 2.0 / (sqrt(float(frame_len)) * 32768.0);
-      else
-         root = frame_len / (sqrt(float(frame_len)) * 32768.0);
-      for (i = 0; i < 96; i++) 
-	  {
-         /* constant is result of 0.066399999/log10(M_E) */
-        quant_table[i] = expf(i * 0.15289164787221953823f) * root;
-      }
- 
-       /* calculate number of bands */
-	  //bands calculation:
-	  //bands[0] = 1;
-	  //foreach (i in 1..# of bands-1):
-	  //bands[i] = crit_freq[i-1] * (frame length / 2) / (sample rate / 2); 
-	  //bands[# of bands] = frame length / 2 
-       for (num_bands = 1; num_bands < 25; num_bands++)
-         if (sample_rate_half <= ff_wma_critical_freqs[num_bands - 1])
-            break;
-
-       bands = (unsigned int *)(av_malloc((num_bands + 1) * sizeof(*bands)));
-       if (!bands)
-         return AVERROR(ENOMEM);
-
-	   /* populate bands data */
-       bands[0] = 2;
-       for (i = 1; i < num_bands; i++)
-         bands[i] = (ff_wma_critical_freqs[i - 1] * frame_len / sample_rate_half) & ~1;
-       bands[num_bands] = frame_len;
-
-       first = 1;
-
-       //ff_rdft_init(&trans.rdft, frame_len_bits, DFT_C2R);
-
-       avcodec_get_frame_defaults(&frame);
-       dec_ctx->coded_frame = &frame;
-    }
-    break;
-                /*
-      case AV_CODEC_ID_SMACKAUDIO:
-      {
-        static int smack_debug_next_audio_time = 0;
-        if (smack_debug_next_audio_time != packet->pts)
-        {
-          Error("There's a gap in the sound before frame %u\n", num_audio_frames);
-          __debugbreak(); // there's a gap in the sound
-        }
-
-        int num_actual_data_channels = 0;
-        switch (dec_ctx->sample_fmt)
-        {
-          case AV_SAMPLE_FMT_U8:
-          case AV_SAMPLE_FMT_S16:
-          case AV_SAMPLE_FMT_S32:
-          case AV_SAMPLE_FMT_FLT:
-          case AV_SAMPLE_FMT_DBL:
-            num_actual_data_channels = 1;
-          break;
-
-          case AV_SAMPLE_FMT_U8P:
-          case AV_SAMPLE_FMT_S16P:
-          case AV_SAMPLE_FMT_S32P:
-          case AV_SAMPLE_FMT_FLTP:
-          case AV_SAMPLE_FMT_DBLP:
-            num_actual_data_channels = dec_ctx->channels;
-          break;
-
-          default:
-          case AV_SAMPLE_FMT_NONE:
-          case AV_SAMPLE_FMT_NB:
-            __debugbreak();
-        }
-
-        smack_debug_next_audio_time += dec_ctx->channels * frame->nb_samples * bytes_per_sample;
-        Assert(frame->avframe->linesize[0] == audio.dec_ctx->channels * frame->avframe->nb_samples * audio.bytes_per_sample / num_actual_data_channels,
-               "Smack audio size mismatch in frame %u in %s\n", audio_num_read_frames, movie_filename);
-
-        frame->play_time = (double)frame->avpacket->pts / (double)audio.bytes_per_second;
-      }
-      break;
-
-                case AV_CODEC_ID_MP3:
-                {
-                  static int mp3_samples_decoded_so_far = 0;
-                  static int mp3_prev_samples_count = frame->avframe->nb_samples; // mp3 seems to always feed same amount of samples
-                  frame->play_time = (double)mp3_samples_decoded_so_far / (double)audio.dec_ctx->sample_rate;
-
-                  mp3_samples_decoded_so_far += frame->avframe->nb_samples;
-                  Assert(mp3_prev_samples_count == frame->avframe->nb_samples,
-                          "MP3 audio have variable sample count in frame %u in %s\n", audio_num_read_frames, movie_filename);
-                }
-                break;
-
-                default:
-                {
-                  __debugbreak();
-                  double samples_per_second = (double)audio.dec_ctx->time_base.den / (double)audio.dec_ctx->time_base.num;
-                  double play_length = frame->avframe->nb_samples / samples_per_second;
-                  frame->play_time = (double)frame->avpacket->pts / samples_per_second;
-                }
-                break;*/
-  }
-
-  if (!avframe->channel_layout)
-  {
-    log("Audio channel layout not specified, rolling back to default\n");
-    avframe->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
-  }
-
-  *out_num_audio_samples = dec_ctx->channels * avframe->nb_samples;
-  InterleaveAudioData(out_audio_data, dec_ctx->sample_fmt,
-                      dec_ctx->channels, avframe->nb_samples, avframe->data);
-  return true;
-}
-
-bool LoadAudioTrack(AVFormatContext *format_ctx, AVCodecContext *dec_ctx, int audio_stream_idx, MemoryStream *out_audio_stream, int *out_num_audio_frames, int *out_num_audio_samples)
-{
-  out_audio_stream->Reset();
-
-  AVFrame  *frame = avcodec_alloc_frame();
-
-  AVPacket *packet = new AVPacket;
-  av_init_packet(packet);
-
-  int num_audio_frames = 0;
-  int num_audio_samples = 0;
-
-  while (av_read_frame(format_ctx, packet) >= 0)
-  {
-	// Is this a packet from the audio stream?
-    if (packet->stream_index != audio_stream_idx)
-    {
-      //log("Suspicious stream id %u in %s", packet->stream_index, filenamea);
-      continue;
-    }
-
-	// Decode audio frame
-    int num_samples_decoded;
-    DecodeAudioFrame(dec_ctx, packet, frame, out_audio_stream, &num_samples_decoded);
-
-    num_audio_samples += num_samples_decoded;
-    num_audio_frames++;
-  }
-  *out_num_audio_frames = num_audio_frames;
-  *out_num_audio_samples = num_audio_samples;
-
-  avcodec_free_frame(&frame);
-  delete frame;
-  av_free_packet(packet);
-  delete packet;
-
-  return true;
-}
-
-class Track: public Media::ITrack
-{
-  public:
-    inline Track()
-    {
-      this->format_ctx = nullptr;
-      this->audio_num_samples = 0;
-    }
-
-    void Release()
-    {
-      ReleaseAvcodec();
-    }
-
-    void ReleaseAvcodec()
-    {
-      audio.Release();
-      if (format_ctx)
-      {
-        av_close_input_file(format_ctx);
-		Log::Warning(L"close audio format context file\n");
-        format_ctx = nullptr;
-      }
-    }
-
-    bool LoadAudio(const wchar_t *filename)
-    {
-      char filenamea[1024];
-      sprintf(filenamea, "%S", filename);
-      // Open audio file
-      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
-      {
-        // Retrieve stream information
-        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
-        {
-          // Dump information about file onto standard error
-          av_dump_format(format_ctx, 0, filenamea, 0);
-
-          if (!av_open_audio_stream(format_ctx, &audio))
-          {
-            Error("Cannot open strack: %s", filenamea);
-            return Release(), false;
-          }
-          
-          MemoryStream audio_plain_data;
-          int          num_audio_frames;
-          int          num_audio_samples;
-
-          if (LoadAudioTrack(format_ctx, audio.dec_ctx, audio.stream_idx, &audio_plain_data, &num_audio_frames, &num_audio_samples))
-          {
-            /*#ifdef _DEBUG
-              char debug_filename[1024];
-              sprintf(debug_filename, "%s.wav", filenamea);
-              FILE *wav = fopen(debug_filename, "w+b");
-
-              extern void write_wav_header(FILE *wav, int channel_count = 2, int sample_rate = 22050, int bytes_per_sample = 2);
-              write_wav_header(wav, audio.dec_ctx->channels, audio.dec_ctx->sample_rate, audio.bytes_per_sample);
-
-              fwrite(audio_plain_data.Ptr(), audio_plain_data.Current(), 1, wav);
-            
-              extern void fix_wav_header(FILE *wav, int wav_bytes_in_stream);
-              fix_wav_header(wav, audio_plain_data.Current());
-            #endif*/
-
-            device_buffer = provider->CreateTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2, num_audio_samples, audio_plain_data.Ptr());
-
-            Release();
-            return true;
-          }
-        }
-        Release();
-        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
-        return false;
-      }
-      fprintf(stderr, "ffmpeg: Unable to open input file\n");
-      return false;
-    }
-
-    virtual void Play(bool loop)
-    {
-      provider->PlayTrack16(device_buffer, loop);
-      mSourceID = device_buffer->source_id;
-    }
-  
-  protected:
-    AVFormatContext *format_ctx;
-    AVAudioStream    audio;
-    int              audio_num_samples;
-
-    bool             stopped;
-
-    OpenALSoundProvider::TrackBuffer *device_buffer;
-};
-
-class Movie: public Media::IMovie
-{
-  public:
-    inline Movie()
-    {
-      this->movie_filename[0] = 0;
-      this->width = 0;
-      this->height = 0;
-      this->format_ctx = nullptr;
-      this->end_of_file = false;
-      this->playback_time = 0.0;
-
-      this->num_audio_frames = 0;
-      this->num_audio_samples = 0;
-
-      this->last_resampled_frame_num = -1;
-      memset(last_resampled_frame_data, 0, sizeof(last_resampled_frame_data));
-      memset(last_resampled_frame_linesize, 0, sizeof(last_resampled_frame_linesize));
-
-      audio_data_in_device = nullptr;
-      decoding_packet = nullptr;
-	  ioBuffer = nullptr;
-	  format_ctx = nullptr;
-	  avioContext = nullptr;
-    }
-
-    virtual ~Movie() {}
- 
-    virtual void Release()
-    {
-      ReleaseAVCodec();
-
-      if (audio_data_in_device)
-        provider->DeleteStreamingTrack(&audio_data_in_device);
-    }
-
-    inline void ReleaseAVCodec()
-    {
-      audio.Release();
-      video.Release();
-
-      if (format_ctx)
-      {
-		// Close the video file
-        av_close_input_file(format_ctx);
-		Log::Warning(L"close video format context file\n");
-        format_ctx = nullptr;
-	  }
-	  if(avioContext)
-	  {
-		av_free(avioContext);
-		avioContext = nullptr;
-	  }
-	  if (ioBuffer)
-	  {
-		//av_free(ioBuffer);
-		ioBuffer = nullptr;
-      }
-	  av_free_packet(decoding_packet);
-	  delete decoding_packet;
-      avcodec_free_frame(&decoding_frame);
-	  delete decoding_frame;
-      if (last_resampled_frame_data[0])
-        av_freep(&last_resampled_frame_data[0]);
-
-    }
-
-    bool Load(const wchar_t *filename, int dst_width, int dst_height, int cache_ms)	//Çàãðóçêà
-    {
-      char filenamea[1024];
-      sprintf(filenamea, "%S", filename);
-      sprintf(movie_filename, "%S", filename);
-
-      width = dst_width;
-      height = dst_height;
-      // Open video file
-      if (avformat_open_input(&format_ctx, filenamea, nullptr, nullptr) >= 0)
-      {
-        // Retrieve stream information
-        if (avformat_find_stream_info(format_ctx, nullptr) >= 0)
-        {
-          // Dump information about file onto standard error
-          av_dump_format(format_ctx, 0, filenamea, 0);
-
-          if (!av_open_audio_stream(format_ctx, &audio))
-          {
-            Error("Cannot open audio stream: %s", filenamea);
-            return Release(), false;
-          }
-          
-          if (!av_open_video_stream(format_ctx, &video))
-          {
-            Error("Cannot open video stream: %s", filenamea);
-            return Release(), false;
-          }
-
-          //Ritor1: include 
-		  if (_stricmp("binkvideo", video.dec->name) ) 
-		  {
-			pMediaPlayer->current_movie_width = video.dec_ctx->width;
-			pMediaPlayer->current_movie_height = video.dec_ctx->height;
-		  }
-		  else
-		  {
-			pMediaPlayer->current_movie_width = width;
-			pMediaPlayer->current_movie_height = height;
-	      }
-		  //
-          decoding_packet = new AVPacket;
-          av_init_packet(decoding_packet);
-      
-		  // Allocate video frame
-          decoding_frame = avcodec_alloc_frame();
-
-          audio_data_in_device = provider->CreateStreamingTrack16(audio.dec_ctx->channels, audio.dec_ctx->sample_rate, 2);
-          return true;
-        }
-        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
-        return Release(), false; 
-      }
-      fprintf(stderr, "ffmpeg: Unable to open input file\n");
-      return Release(), false;
-    }
-
-	bool LoadFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
-	{
-		if (!ioBuffer)
-			ioBuffer = (unsigned char *)av_malloc(0x4000 + FF_INPUT_BUFFER_PADDING_SIZE); // can get av_free()ed by libav
-		if (!avioContext)
-			avioContext = avio_alloc_context(ioBuffer, 0x4000, 0, h, readFunction, NULL, seekFunction);
-		if (!format_ctx)
-			format_ctx = avformat_alloc_context();
-		format_ctx->pb = avioContext;
-		return Load(L"dummyFilename", width, height, 0);
-	}
-
-    virtual void GetNextFrame(double dt, void *dst_surface)
-    {
-      playback_time += dt;
-
-      AVPacket *avpacket = decoding_packet;
-      AVFrame *avframe = decoding_frame;
-
-      avcodec_get_frame_defaults(avframe);
-
-      int desired_frame_number = floor(playback_time * video.dec_ctx->time_base.den / video.dec_ctx->time_base.num + 0.5);
-      if (last_resampled_frame_num == desired_frame_number)
-      {
-        memcpy(dst_surface, last_resampled_frame_data[0], pMediaPlayer->current_movie_height * last_resampled_frame_linesize[0]);
-        return;
-      }
-
-      volatile int frameFinished = false;
-
-      // keep reading packets until we hit the end or find a video packet
-      do
-      {
-        if (pMediaPlayer->loop_current_file)
-        {
-          //Now seek back to the beginning of the stream
-          if (video.dec_ctx->frame_number >= video.stream->duration - 1 )
-            pMediaPlayer->bPlaying_Movie = false;
-        }
-        if (av_read_frame(format_ctx, avpacket) < 0)
-        {
-          // probably movie is finished
-          pMediaPlayer->bPlaying_Movie = false;
-          av_free_packet(avpacket);
-		  return;
-        }
-		// Is this a packet from the video stream?
-        // audio packet - queue into playing
-        if (avpacket->stream_index == audio.stream_idx)
-        {
-          MemoryStream audio_data;
-          if (DecodeAudioFrame(audio.dec_ctx, avpacket, avframe, &audio_data, &num_audio_samples))
-            provider->Stream16(audio_data_in_device, num_audio_samples, audio_data.Ptr());
-          //continue;
-        }
-
-		// Decode video frame
-        // video packet - decode & maybe show
-        else if (avpacket->stream_index == video.stream_idx)
-        {
-          do
-          {
-            if (avcodec_decode_video2(video.dec_ctx, avframe, (int *)&frameFinished, avpacket) < 0)
-              __debugbreak();
-          } while (!frameFinished);
-        }
-        else __debugbreak(); // unknown stream
-      }
-      while (avpacket->stream_index != video.stream_idx ||
-               avpacket->pts != desired_frame_number);
-
-      if (frameFinished)
-      {
-        if (last_resampled_frame_data[0])
-          av_freep(&last_resampled_frame_data[0]);
-
-        AVPixelFormat  rescaled_format = AV_PIX_FMT_RGB32;
-        uint8_t       *rescaled_data[4] = {nullptr, nullptr, nullptr, nullptr};
-        int            rescaled_linesize[4] = {0, 0, 0, 0};
-
-        if (av_image_alloc(rescaled_data, rescaled_linesize, pMediaPlayer->current_movie_width, pMediaPlayer->current_movie_height, rescaled_format, 1) >= 0)
-        {
-          SwsContext *converter = sws_getContext(avframe->width, avframe->height, (AVPixelFormat)avframe->format,
-                                               pMediaPlayer->current_movie_width, pMediaPlayer->current_movie_height, rescaled_format,
-                                               SWS_BICUBIC, nullptr, nullptr, nullptr);
-          sws_scale(converter, avframe->data, avframe->linesize, 0, avframe->height, rescaled_data, rescaled_linesize);
-          sws_freeContext(converter);
-
-          memcpy(dst_surface, rescaled_data[0], pMediaPlayer->current_movie_height * rescaled_linesize[0]);
-
-          last_resampled_frame_num = desired_frame_number;
-          memcpy(last_resampled_frame_data, rescaled_data, sizeof(rescaled_data));
-          memcpy(last_resampled_frame_linesize, rescaled_linesize, sizeof(rescaled_linesize));
-        }
-      }
-      else
-        memset(dst_surface, 0, width * pMediaPlayer->current_movie_height * 4);
-
-      // Free the packet that was allocated by av_read_frame
-      av_free_packet(avpacket);
-    }
-
-    virtual void Play()
-    {
-    }
-
-  protected:
-    char             movie_filename[256];
-    int              width;
-    int              height;
-    bool             stopped;
-    AVFormatContext *format_ctx;
-    double           playback_time;
-    bool             end_of_file;
-
-    AVPacket        *decoding_packet;
-    AVFrame         *decoding_frame;
-
-    AVAudioStream   audio;
-    int             num_audio_frames;
-    int             num_audio_samples;
-	unsigned char  *ioBuffer;
-	AVIOContext    *avioContext;
-    OpenALSoundProvider::StreamingTrackBuffer *audio_data_in_device;
-
-    AVVideoStream   video;
-    int             last_resampled_frame_num;
-    uint8_t        *last_resampled_frame_data[4];
-    int             last_resampled_frame_linesize[4];
-};	
-
-ITrack *MPlayer::LoadTrack(const wchar_t *filename)
-{
-  auto audio_track = new Track;
-  Log::Warning(L"allocation dynamic memory for audio_track\n");
-  if (!audio_track->LoadAudio(filename))
-  {
-    delete audio_track;
-	Log::Warning(L"delete dynamic memory for audio_track\n");
-    audio_track = nullptr;
-  }
-  return audio_track;
-}
-
-IMovie *MPlayer::LoadMovie(const wchar_t *filename, int width, int height, int cache_ms)	//Çàãðóçèòü âèäåî
-{
-  movie = new Movie;
-  Log::Warning(L"allocation dynamic memory for movie\n");
-  if (!movie->Load(filename, width, height, cache_ms))
-  {
-    delete movie;
-	Log::Warning(L"delete dynamic memory for movie\n");
-    movie = nullptr;
-  }
-  return movie;
-}
-
-
-//for video/////////////////////////////////////////////////////////////////
-
-//----- (004BE9D8) --------------------------------------------------------
-void MPlayer::Initialize(OSWindow *target_window)
-{
-  DWORD NumberOfBytesRead; // [sp+10h] [bp-4h]@9
-    
-  window = target_window;
-
-  unsigned int uBinkVersionMajor = -1,
-               uBinkVersionMinor = -1;
-  //GetDllVersion(L"BINKW32.DLL", &uBinkVersionMajor, &uBinkVersionMinor);
-  //uBinkVersion = (unsigned __int64)uBinkVersionMajor << 32 | uBinkVersionMinor;
-
-  strcpy(pTmpBuf.data(), "anims\\might7.vid");
-  hMightVid = CreateFileW(L"anims\\might7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
-  if ( hMightVid == INVALID_HANDLE_VALUE )
-  {
-    sprintf(pTmpBuf2.data(), "Can't open file - anims\\%s.smk", pTmpBuf.data());
-    MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
-    return;
-  }
-  strcpy(pTmpBuf.data(), "anims\\magic7.vid");
-  hMagicVid = CreateFileW(L"anims\\magic7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
-  if ( hMagicVid == INVALID_HANDLE_VALUE )
-  {
-    if ( !bCanLoadFromCD )
-    {
-       sprintf(pTmpBuf2.data(), "Can't open file - anims\\%s.smk", pTmpBuf.data());
-       MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
-       return;
-    }
-    sprintf(pTmpBuf2.data(), "%c:\\%s", (unsigned __int8)cMM7GameCDDriveLetter, pTmpBuf.data());
-    hMagicVid = CreateFileA(pTmpBuf2.data(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080, 0);
-    if ( hMagicVid == (HANDLE)INVALID_HANDLE_VALUE )
-    {
-      sprintf(pTmpBuf2.data(), "Can't open file - %s", pTmpBuf.data());
-      MessageBoxA(0, pTmpBuf2.data(), "Video File Error", 0);
-      return;
-    }
-  }
-  ReadFile(hMightVid, &uNumMightVideoHeaders, 4, &NumberOfBytesRead, 0);
-  ReadFile(hMagicVid, &uNumMagicVideoHeaders, 4, &NumberOfBytesRead, 0);
-  pMightVideoHeaders = (MovieHeader *)malloc(sizeof(MovieHeader) * uNumMightVideoHeaders + 2);
-  pMagicVideoHeaders = (MovieHeader *)malloc(sizeof(MovieHeader) * uNumMagicVideoHeaders + 2);
-  ReadFile(hMightVid, pMightVideoHeaders, 44 * uNumMightVideoHeaders, &NumberOfBytesRead, 0);
-  ReadFile(hMagicVid, pMagicVideoHeaders, 44 * uNumMagicVideoHeaders, &NumberOfBytesRead, 0);
-}
-
-//----- (004BF411) --------------------------------------------------------
-void MPlayer::OpenFullscreenMovie(const char *pFilename, unsigned int bLoop/*, int ScreenSizeFlag*/)
-{
-  if (!this->bPlaying_Movie)
-  {
-    pEventTimer->Pause();
-	if (pAudioPlayer->hAILRedbook)
-		AIL_redbook_pause(pAudioPlayer->hAILRedbook);
-
-	bStopBeforeSchedule = false;
-	bFirstFrame = false;
-	this->bLoopPlaying = bLoop;
-	LoadMovie(pFilename);
-	return;
-  }
-}
-
-//----- (004BF28F) --------------------------------------------------------
-void MPlayer::OpenHouseMovie(const char *pMovieName, unsigned int a3_1)
-{
-  if (!this->bPlaying_Movie)
-  {
-    //Prepare();
-    pEventTimer->Pause();
-    if (pAudioPlayer->hAILRedbook)
-      AIL_redbook_pause(pAudioPlayer->hAILRedbook);
-
-    bStopBeforeSchedule = false;
-    bFirstFrame = false;
-
-    this->bLoopPlaying = a3_1;
-    /*if ( LOBYTE(this->field_104) == 1 )
-    {
-      MessageBoxA(nullptr, "Unsupported Bink playback!", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:925", 0);
-      return;
-    }*/
-
-    LoadMovie(pMovieName);
-	time_video_begin = GetTickCount();
-  }
-}
-
-//----- (004BE70E) --------------------------------------------------------
-void MPlayer::FullscreenMovieLoop(const char *pMovieName, int a2/*, int ScreenSizeFlag, int a4*/)
-{
-  int v4; // ebp@1
-  MSG Msg; // [sp+Ch] [bp-1Ch]@12
-
-  v4 = a2;
-  if ( dword_6BE364_game_settings_1 & (GAME_SETTINGS_NO_HOUSE_ANIM | GAME_SETTINGS_NO_INTRO) ||
-	   bNoVideo)
-    return;
-
-    if ( a2 == 2 )
-      v4 = 0;
-    ShowCursor(0);
-    OpenFullscreenMovie(pMovieName, 0);
-    bPlaying_Movie = 1;
-    field_44 = v4;
-    pRenderer->ClearTarget(0);
-    pCurrentScreen = SCREEN_VIDEO;
-
-    auto hwnd = pMediaPlayer->window->GetApiHandle();
-
-    RECT rc_client;
-    GetClientRect(hwnd, &rc_client);
-    int client_width = rc_client.right - rc_client.left,
-        client_height = rc_client.bottom - rc_client.top;
-
-    HDC     dc = GetDC(hwnd);
-    HDC     back_dc = CreateCompatibleDC(dc);
-	HBITMAP back_bmp = CreateCompatibleBitmap(dc, client_width, client_height);
-	auto    frame_buffer = new char[client_width * client_height * 4];
-    SelectObject(back_dc, back_bmp);
-
-	DWORD t = GetTickCount();
-
-	bPlaying_Movie = true;
-
-    while (true)
-    {
-      if (pMediaPlayer->bStopBeforeSchedule)
-        break;
-      while (PeekMessageA(&Msg, hwnd, 0, 0, PM_REMOVE))
-      {
-        if (Msg.message == WM_QUIT)
-          Game_DeinitializeAndTerminate(0);
-        if (Msg.message == WM_PAINT)
-          break;
-        TranslateMessage(&Msg);
-        DispatchMessageA(&Msg);
-      }
-
-      double dt = (GetTickCount() - t) / 1000.0; 
-      t = GetTickCount();
-
-      pMovie_Track->GetNextFrame(dt, frame_buffer);	
-
-      if (!bPlaying_Movie)
-        break;
-
-      if (frame_buffer)
-      {
-        // draw to hwnd
-        BITMAPINFO bmi;
-        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-        bmi.bmiHeader.biWidth = client_width;
-        bmi.bmiHeader.biHeight = -client_height;
-        bmi.bmiHeader.biPlanes = 1;
-        bmi.bmiHeader.biBitCount = 32;
-        bmi.bmiHeader.biCompression = BI_RGB;
-        bmi.bmiHeader.biSizeImage = 0;
-        bmi.bmiHeader.biXPelsPerMeter = 0;
-        bmi.bmiHeader.biYPelsPerMeter = 0;
-        bmi.bmiHeader.biClrUsed = 0;
-        bmi.bmiHeader.biClrImportant = 0;
-        GetDIBits(back_dc, back_bmp, 0, client_height, 0, &bmi, DIB_RGB_COLORS);
-        SetDIBits(back_dc, back_bmp, 0, client_height, frame_buffer, &bmi, DIB_RGB_COLORS);
-        BitBlt(dc, 0, 0, client_width, client_height, back_dc, 0, 0, SRCCOPY);
-      }
-
-      GUI_MainMenuMessageProc();  
-
-      if (pMediaPlayer->bStopBeforeSchedule == 1)
-        Sleep(1000); 
-    }
-	delete [] frame_buffer;
-	DeleteObject(back_bmp);
-	DeleteObject(back_dc);
-	ReleaseDC(hwnd, dc);
-
-    pMediaPlayer->Unload();
-
-    //if (a4 == 1)
-      pCurrentScreen = SCREEN_GAME;
-
-    pMediaPlayer->bPlaying_Movie = false;
-
-    ShowCursor(1);
-
-    /*if ( pCurrentScreen == SCREEN_VIDEO )
-      pCurrentScreen = SCREEN_GAME;*/
-}
-
-void MPlayer::HouseMovieLoop()
-{
-	if (pMovie_Track && !bNoVideo)
-	{
-		pRenderer->BeginScene();
-		pMouse->DrawCursorToTarget();
-
-        Log::Warning(L"smacker");
-        loop_current_file = true;
-        pRenderer->BeginScene();
-        if (!bPlaying_Movie)//reload
-        {
-          unsigned int width = game_viewport_width;
-          unsigned int height = game_viewport_height;
-	      MovieRelease();
-
-          SetFilePointer(hVidFile, uOffset, nullptr, FILE_BEGIN);
-          pMovie_Track = nullptr;
-	      Log::Warning(L"reload pMovie_Track");
-          pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, width, height);
-          bPlaying_Movie = true;
-        }
-        //else 
-        //{
-          double dt = (GetTickCount() - time_video_begin) / 1000.0;
-          //dt = 1.0/15.0;
-          time_video_begin = GetTickCount();
-
-          //log("dt=%.5f\n", dt);
-
-          auto image = new char[current_movie_width * current_movie_height * 4];
-
-          pMovie_Track->GetNextFrame(dt, image);
-
-          int image_array[460 * 344];//game_viewport_width * game_viewport_height
-          if (image)
-          {
-            memcpy(image_array, image, sizeof (image_array));
-            for (unsigned int y = 8; y < 8 + game_viewport_height; ++y)//êîîðäèíàòû ìåñòîïîëîæåíèÿ âèäåîðîëèêà
-            {
-              for (unsigned int x = 8; x < 8 + game_viewport_width; ++x)
-              {
-                auto p = (unsigned __int32 *)pRenderer->pTargetSurface + x + y * pRenderer->uTargetSurfacePitch;
-                *p = image_array[((x - 8) + ((y - 8)*game_viewport_width))];
-              }
-            }
-            delete[] image;
-          }
-       //}
-        pRenderer->EndScene();
-		pMouse->ReadCursorWithItem();
-		pRenderer->EndScene();
-	}
-}
- 
-//----- (004BF73A) --------------------------------------------------------
-void MPlayer::SelectMovieType()
-{
-  char Source[32]; // [sp+Ch] [bp-40h]@1
-
-  strcpy(Source, this->pCurrentMovieName);
-  pMediaPlayer->Unload();
-  if ( this->uMovieType == 1 )
-    OpenHouseMovie(Source, LOBYTE(this->bLoopPlaying));
-  else if ( this->uMovieType == 2 )
-    OpenFullscreenMovie(Source, LOBYTE(this->bLoopPlaying));
-  else
-    __debugbreak();
-}
-
-void MPlayer::LoadMovie(const char *pFilename)
-{
-  char pVideoNameBik[120]; // [sp+Ch] [bp-28h]@2
-  char pVideoNameSmk[120]; // [sp+Ch] [bp-28h]@2
-
-  sprintf(pVideoNameBik, "%s.bik", pFilename);
-  sprintf(pVideoNameSmk, "%s.smk", pFilename);
-  for (uint i = 0; i < uNumMightVideoHeaders; ++i)
-  {
-    if (!_stricmp(pVideoNameSmk, pMightVideoHeaders[i].pVideoName))
-    {
-      hVidFile = hMightVid;
-      uOffset = pMightVideoHeaders[i].uFileOffset;
-      uSize = pMightVideoHeaders[i + 1].uFileOffset - uOffset;
-      this->uMovieType = 2;
-    }
-  }
-  for (uint i = 0; i < uNumMagicVideoHeaders; ++i)
-  {
-    if (!_stricmp(pVideoNameBik, pMagicVideoHeaders[i].pVideoName))
-    {
-      hVidFile = hMagicVid;
-      uOffset = pMagicVideoHeaders[i].uFileOffset;
-      uSize = pMagicVideoHeaders[i + 1].uFileOffset - uOffset;
-      this->uMovieType = 1;
-    }
-    if (!_stricmp(pVideoNameSmk, pMagicVideoHeaders[i].pVideoName))
-    {
-      hVidFile = hMagicVid;
-      uOffset = pMagicVideoHeaders[i].uFileOffset;
-      uSize = pMagicVideoHeaders[i + 1].uFileOffset - uOffset;
-      this->uMovieType = 2;
-    }
-  }
-  if (!hVidFile)
-  {
-    pMediaPlayer->Unload();
-    MessageBoxA(0, "MediaPlayer error", "MediaPlayer Error", 0);
-    return;
-  }
-
-  SetFilePointer(hVidFile, uOffset, 0, FILE_BEGIN);
-  strcpy(this->pCurrentMovieName, pFilename);
-
-  auto hwnd = pMediaPlayer->window->GetApiHandle();
-  RECT rc_client;
-  GetClientRect(hwnd, &rc_client);
-  int client_width = rc_client.right - rc_client.left,
-      client_height = rc_client.bottom - rc_client.top;
-
-  pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, client_width, client_height);
-}
-
-//----- (004BF794) --------------------------------------------------------
-void MPlayer::ShowMM7IntroVideo_and_LoadingScreen()
-{
-  RGBTexture tex; // [sp+Ch] [bp-30h]@1
-  unsigned int uTrackStartMS; // [sp+34h] [bp-8h]@8
-  unsigned int uTrackEndMS; // [sp+38h] [bp-4h]@8
-
-  pMediaPlayer->bStopBeforeSchedule = false;
-//  pMediaPlayer->pResetflag = 0;
-  bGameoverLoop = true;
-  if (!bNoVideo)
-  {
-    pRenderer->PresentBlackScreen();
-    if ( !pMediaPlayer->bStopBeforeSchedule )
-      PlayFullscreenMovie(MOVIE_Intro, true);
-  }
-
-  tex.Load("mm6title.pcx", 2);
-  pRenderer->BeginScene();
-  pRenderer->DrawTextureRGB(0, 0, &tex);
-  free(tex.pPixels);
-  tex.pPixels = 0;
-
-  //LoadFonts_and_DrawCopyrightWindow();
-  DrawMM7CopyrightWindow();
-
-  pRenderer->EndScene();
-  pRenderer->Present();
-
-  #ifndef _DEBUG
-    Sleep(1500);   // let the copyright window stay for a while
-  #endif
-
-  if (!bNoSound && pAudioPlayer->hAILRedbook )
-  {
-    pAudioPlayer->SetMusicVolume((signed __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0));
-    AIL_redbook_stop(pAudioPlayer->hAILRedbook);
-    AIL_redbook_track_info(pAudioPlayer->hAILRedbook, 14, &uTrackStartMS, &uTrackEndMS);
-    AIL_redbook_play(pAudioPlayer->hAILRedbook, uTrackStartMS + 1, uTrackEndMS);
-  }
-  bGameoverLoop = false;
-}
-
-//----- (004BEBD7) --------------------------------------------------------
-void MPlayer::Unload()
-{
-  bPlaying_Movie = false;
-  uMovieType = 0;
-  memset(pCurrentMovieName, 0, 0x40);
-  if ( pAudioPlayer->hAILRedbook && !bGameoverLoop )
-    AIL_redbook_resume(pAudioPlayer->hAILRedbook);
-  pEventTimer->Resume();
-
-  pMovie_Track->Release();
-  delete pMovie_Track;
-  pMovie_Track = nullptr;
-}
-
-int MPlayer::readFunction(void* opaque, uint8_t* buf, int buf_size)
-{
-  HANDLE stream = (HANDLE)opaque;
-  //int numBytes = stream->read((char*)buf, buf_size);
-  int numBytes;
-  ReadFile(stream, (char *)buf, buf_size, (LPDWORD)&numBytes, NULL);
-  return numBytes;
-}
-
-int64_t MPlayer::seekFunction(void* opaque, int64_t offset, int whence)
-{
-  if (whence == AVSEEK_SIZE)
-    return pMediaPlayer->uSize;
-  HANDLE h = (HANDLE)opaque;
-  LARGE_INTEGER li;
-  li.QuadPart = offset;
-
-  if (!SetFilePointerEx(h, li, (PLARGE_INTEGER)&li, FILE_BEGIN))
-    return -1;
-  return li.QuadPart;
-}
-
-//for video//////////////////////////////////////////////////////////////////
-
-
-
-IMovie *MPlayer::LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height)
-{
-	movie = new Movie;
-	Log::Warning(L"allocation dynamic memory for movie\n");
-	if (movie)
-	{
-		if (movie->LoadFromLOD(h, readFunction, seekFunction, width, height))
-		  return movie;
-		delete movie;
-		Log::Warning(L"delete dynamic memory for movie\n");
-	}
-	return nullptr;
-}
-
-void MovieRelease()
-{
-  movie->Release();
-  delete movie;
-  Log::Warning(L"delete dynamic memory for movie\n");
-  movie = nullptr;
-}
-
-
-//for audio///////////////////////////////////////////////////////
-//----- (004AB818) --------------------------------------------------------
-void MPlayer::LoadAudioSnd()
-{
-  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3
-
-  hAudioSnd = CreateFileA("Sounds\\Audio.snd", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0);
-  if (hAudioSnd == INVALID_HANDLE_VALUE)
-  {
-    Log::Warning(L"Can't open file: %s", L"Sounds\\Audio.snd");
-    return;
-  }
-
-  ReadFile(hAudioSnd, &uNumSoundHeaders, 4, &NumberOfBytesRead, 0);
-  pSoundHeaders = nullptr;
-  pSoundHeaders = (SoundHeader *)malloc(52 * uNumSoundHeaders + 2);
-  ReadFile(hAudioSnd, pSoundHeaders, 52 * uNumSoundHeaders, &NumberOfBytesRead, 0);
-}
-//for audio///////////////////////////////////////////////////////
-
-void av_logger(void *, int, const char *format, va_list args)
-{
-  va_list va;
-  va_start(va, format);
-  char msg[256];
-  vsprintf(msg, format, va);
-  va_end(va);
-
-  log("av: %s", msg);
-}
-
-MPlayer::MPlayer()
-{
-  bPlaying_Movie = false;
-
-  static int libavcodec_initialized = false;
-
-  if (!libavcodec_initialized)
-  {
-    av_log_set_callback(av_logger);
-    avcodec_register_all();
-
-    // Register all available file formats and codecs
-    av_register_all();
-
-    libavcodec_initialized = true;
-  }
-
-  bStopBeforeSchedule = false;
-  pMovie_Track = nullptr;
-
-  if (!provider)
-  {
-    provider = new OpenALSoundProvider;
-	Log::Warning(L"allocation dynamic memory for provider\n");
-    provider->Initialize();
-  }
-  LoadAudioSnd();
-}
-
-MPlayer::~MPlayer()
-{
-	delete provider;
-	Log::Warning(L"delete dynamic memory for provider\n");
-
-    bStopBeforeSchedule = false;
-//    pResetflag = 0;
-    pVideoFrame.Release();
-}
-
-void PlayAudio(const wchar_t * pFilename)
-{
-  pAudio_Track = pMediaPlayer->LoadTrack(pFilename);
-  pAudio_Track->Play();
-  delete pAudio_Track;
-  Log::Warning(L"delete dynamic memory for pAudio_Track\n");
-  pAudio_Track = nullptr;
-}
-
-void PlayMovie(const wchar_t * pFilename)
-{
-  Media::IMovie *Movie_track = pMediaPlayer->LoadMovie(pFilename, 640, 480, 0);
-  Movie_track->Play();
-}
-
--- a/MediaPlayer.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-#pragma once
-#include "OSWindow.h"
-#include "Engine/Graphics/Texture.h"
-#include "Engine/ErrorHandling.h"
-
-#pragma pack(push, 1)
-
-#pragma pack(pop)
-
-#pragma pack(push, 1)
-#pragma pack(pop)
-
-
-
-extern "C"
-{
-#include "lib/libavcodec/avcodec.h"
-#include "lib/libavformat/avformat.h"
-#include "lib/libavutil/avutil.h"
-#include "lib/libavutil/imgutils.h"
-#include "lib/libswscale/swscale.h"
-#include "lib/libswresample/swresample.h"
-#include "lib/libavutil/opt.h"
-}
-#pragma comment(lib, "avcodec.lib")
-#pragma comment(lib, "avformat.lib")
-#pragma comment(lib, "avutil.lib")
-#pragma comment(lib, "swscale.lib")
-#pragma comment(lib, "swresample.lib")
-
-#include "lib/OpenAL/al.h"
-#include "lib/OpenAL/alc.h"
-#pragma comment(lib, "OpenAL32.lib")
-
-#pragma pack(push, 1)
-
-struct MovieHeader
-{
-  char pVideoName[40];
-  unsigned int uFileOffset;
-};
-struct SoundHeader
-{
-  char pSoundName[40];
-  unsigned int uFileOffset;
-  unsigned int uCompressedSize;
-  unsigned int uDecompressedSize;
-};
-
-enum MovieType
-{
-  MOVIE_Invalid = 0x0,
-  MOVIE_3DOLogo = 0x1,
-  MOVIE_NWCLogo = 0x2,
-  MOVIE_JVC = 0x3,
-  MOVIE_Emerald = 0x4,
-  MOVIE_Intro = 0x5,
-  MOVIE_Death = 0x6,
-  MOVIE_Outro = 0x7,
-};
-
-namespace Media
-{
-  class ITrack
-  {
-    public:
-      virtual ~ITrack() {}
-
-	  virtual void Play(bool loop = false) = 0;
-      virtual void Release() = 0;
-  };
-
-  class IMovie
-  {
-    public: 
-      virtual ~IMovie() {}
-
-	  virtual void Play() = 0;
-      virtual void GetNextFrame(double dt, void *target_surface) = 0;
-      virtual void Release() = 0;
-
-  };
-
-  class MPlayer
-  {
-    public:
-               MPlayer();
-      virtual ~MPlayer();
-
-	  //for video/////////////////////////////////////////////////
-      RGBTexture pVideoFrame;
-      int field_44;//final video
-      unsigned int bFirstFrame;
-      unsigned int bLoopPlaying;
-      unsigned int bStopBeforeSchedule;
-      OSWindow *window;
-      int uMovieType;//0 - null, 1 - bik, 2 - smk
-      char pCurrentMovieName[64];
-      char pVideoFrameTextureFilename[32];
-	  MovieHeader *pMightVideoHeaders;
-      MovieHeader *pMagicVideoHeaders;
-      HANDLE hMightVid;
-      HANDLE hMagicVid;
-      unsigned int uNumMightVideoHeaders;
-      unsigned int uNumMagicVideoHeaders;
-	  bool bPlaying_Movie;
-      bool loop_current_file;
-      DWORD time_video_begin;
-      int current_movie_width;
-      int current_movie_height;
-	  HANDLE hVidFile;
-      int uSize;
-      int uOffset;
-
-      void Initialize(OSWindow *window);
-
-      void OpenFullscreenMovie(const char *pFilename, unsigned int bLoop);
-      void OpenHouseMovie(const char *pMovieName, unsigned int a3_1);
-
-      void LoadMovie(const char *);
-      void SelectMovieType();
-
-      inline void PlayFullscreenMovie(MovieType movie_type, bool bShowMouseAfterPlayback)
-      {
-        extern unsigned int bNoVideo;
-        if (bNoVideo) return;
-
-        switch (movie_type)
-        {
-          case MOVIE_3DOLogo: FullscreenMovieLoop("3dologo", 0);        break;
-          case MOVIE_NWCLogo: FullscreenMovieLoop("new world logo", 0); break;
-          case MOVIE_JVC:     FullscreenMovieLoop("jvc", 0);            break;
-          case MOVIE_Intro:   FullscreenMovieLoop("Intro", 0);          break;
-          case MOVIE_Emerald: FullscreenMovieLoop("Intro Post", 0);     break;
-          case MOVIE_Death:   FullscreenMovieLoop("losegame", 2);       break;
-          case MOVIE_Outro:   FullscreenMovieLoop("end_seq1", 20);      break;
-
-          default:
-            Error("Invalid movie requested: %u", movie_type);
-          break;
-        }
-      }
-	  void FullscreenMovieLoop(const char *pMovieName, int a2);
-      void HouseMovieLoop();
-
-      void ShowMM7IntroVideo_and_LoadingScreen();
-      void Unload();
-	  ///////////////////////////////////////////////
-
-      IMovie *LoadMovie(const wchar_t *name, int width, int height, int cache_ms);
-      IMovie *LoadMovieFromLOD(HANDLE h, int readFunction(void*, uint8_t*, int), int64_t seekFunction(void*, int64_t, int), int width, int height);
-
-	  //for audio////////////////////////////////////
-	  HANDLE hAudioSnd;
-	  unsigned int uNumSoundHeaders;
-	  struct SoundHeader *pSoundHeaders;
-
-	  void LoadAudioSnd();
-	  ///////////////////////////////////////////////
-
-
-      ITrack *LoadTrack(const wchar_t *name);
-
-  protected:
-    static int readFunction(void *, uint8_t *, int);
-    static int64_t seekFunction(void *, int64_t, int);
-  };
-};
-#pragma pack(pop)
-extern Media::MPlayer *pMediaPlayer;
-extern Media::IMovie *pMovie_Track;
-extern Media::ITrack *pAudio_Track;
-extern class Movie *movie;
-
-extern int mSourceID;
-
-extern void PlayMovie(const wchar_t * pFilename);
-extern void PlayAudio(const wchar_t * pFilename);
-extern void MovieRelease();
--- a/Mouse.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,795 +0,0 @@
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>
-#include <crtdbg.h>
-
-#define _CRT_SECURE_NO_WARNINGS
-
-#include "Engine/mm7_data.h"
-#include "Mouse.h"
-#include "Engine/Party.h"
-#include "Engine/LOD.h"
-#include "Engine/Game.h"
-
-#include "Engine/TurnEngine/TurnEngine.h"
-#include "Engine/Graphics/Viewport.h"
-#include "GUIWindow.h"
-#include "Engine/Graphics/Vis.h"
-#include "Engine/Objects/Actor.h"
-#include "Engine/MM7.h"
-#include "AudioPlayer.h"
-
-
-Mouse *pMouse;
-
-
-
-
-
-//----- (00469860) --------------------------------------------------------
-void Mouse::GetClickPos(unsigned int *pX, unsigned int *pY)
-{
-  *pX = uMouseClickX;
-  *pY = uMouseClickY;
-}
-
-//----- (004698A6) --------------------------------------------------------
-void Mouse::RemoveHoldingItem()
-{
-  pParty->pPickedItem.Reset();
-  if (_stricmp(pCurrentCursorName, "MICON2"))
-    SetCursorBitmap("MICON1");
-}
-
-//----- (004698D8) --------------------------------------------------------
-void Mouse::SetCursorBitmapFromItemID(unsigned int uItemID)
-{
-  pMouse->SetCursorBitmap(pItemsTable->pItems[uItemID].pIconName);
-}
-
-//----- (004698F6) --------------------------------------------------------
-void Mouse::SetCurrentCursorBitmap()
-{
-  SetCursorBitmap(pCurrentCursorName);
-}
-
-//----- (00469903) --------------------------------------------------------
-void Mouse::SetCursorBitmap(const char *pName)
-{
-//  DDSURFACEDESC2 Dst;
-
-  if ( !this->bInitialized || !pName )
-    return;
-  if ( _stricmp("MICON2", pName) )//åñëè êóñîð íå ìèøåíü
-    pGame->uFlags2 &= 0xFFFFFFEF;
-  else
-    pGame->uFlags2 |= 0x10;
-  if ( _stricmp(this->pCurrentCursorName, pName) )
-    strcpy(this->pCurrentCursorName, pName);
-  ClearCursor();
-  if ( _strnicmp(pName, "MICON1", 5) )//for click to item / åñëè êóðñîð ñ âåùüþ
-  {
-    this->uCursorTextureID = pIcons_LOD->LoadTexture(pName, TEXTURE_16BIT_PALETTE);
-    this->uCursorTextureID_2 = pIcons_LOD->LoadTexture(pName, TEXTURE_16BIT_PALETTE);
-    this->AllocCursorSystemMem();
-    this->field_C = 0;
-    this->bRedraw = true;
-    this->bActive = true;
-    if ( !areWeLoadingTexture )
-    {
-      if (uCursorTextureID != -1)
-        pIcons_LOD->pTextures[uCursorTextureID].Release();
-      pIcons_LOD->SyncLoadedFilesCount();
-    }
-    return;
-  }
-  this->bActive = false;
-  this->field_C = 1;
-  window->SetCursor(pName);
-}
-// 506128: using guessed type int areWeLoadingTexture;
-
-//----- (00469AE4) --------------------------------------------------------
-LONG Mouse::_469AE4()
-{
-  LONG v2; // ecx@2
-  LONG result; // eax@2
-  struct tagPOINT Point; // [sp+Ch] [bp-8h]@2
-
-  this->field_8 = 1;
-  /*if (pAsyncMouse)
-  {
-    v2 = *((int *)pAsyncMouse + 6);
-    Point.x = *((int *)pAsyncMouse + 6);
-    result = *((int *)pAsyncMouse + 7);
-  }
-  else
-  {*/
-    GetCursorPos(&Point);
-    //if ( pRenderer->bWindowMode )
-      ScreenToClient(window->GetApiHandle(), &Point);
-    result = Point.y;
-    v2 = Point.x;
-  //}
-  this->uMouseClickX = v2;
-  this->uMouseClickY = result;
-
-  /*
-  //This block has been commented out, because of the changed condition above "if(true)"
-  //Also the next condition and the first line has been commented out as well
-
-  // if (pRenderer->bWindowMode)
-  if ( true )
-    goto LABEL_16;
-  //if (pAsyncMouse)
-  //  goto LABEL_24;
-  
-
-  if ( v2 < 0 )
-    v2 = 0;
-  if ( result < 0 )
-    result = 0;
-  if ( v2 > window->GetWidth() - 1 )
-    v2 = window->GetWidth() - 1;
-  */
-  
-//  if ( result > window->GetHeight() - 1 )
-//  {
-//    result = window->GetHeight() - 1;
-//LABEL_16:
-    //if (pAsyncMouse)
-    //  goto LABEL_24;
-	if (true/*pRenderer->bWindowMode*/ && (v2 < 0 || result < 0 || v2 > window->GetWidth() - 1 || result > window->GetHeight() - 1))
-	{
-		this->bActive = false;
-		//LABEL_24:
-		this->field_8 = 0;
-		return result;
-	}
-  //}
-  
-  if ( this->field_C )
-//LABEL_23:
-    this->bActive = false;
-//LABEL_24:
-  this->field_8 = 0;
-  return result;
-}
-
-//----- (00469BA3) --------------------------------------------------------
-void Mouse::ClearCursor()
-{
-  this->bActive = false;
-  free(this->pCursorBitmap_sysmem);
-  this->pCursorBitmap_sysmem = nullptr;
-  free(this->pCursorBitmap2_sysmem);
-  this->pCursorBitmap2_sysmem = nullptr;
-  free(this->ptr_90);
-  this->ptr_90 = nullptr;
-}
-
-//----- (00469BE6) --------------------------------------------------------
-void Mouse::AllocCursorSystemMem()
-{
-  bActive = false;
-  if (!pCursorBitmap_sysmem)
-    pCursorBitmap_sysmem = (unsigned __int16 *)DoAllocCursorMem();
-  if (!pCursorBitmap2_sysmem)
-    pCursorBitmap2_sysmem = (unsigned __int8 *)DoAllocCursorMem();
-}
-
-//----- (00469C0D) --------------------------------------------------------
-void *Mouse::DoAllocCursorMem()
-{
-  Texture* tex = pIcons_LOD->GetTexture(uCursorTextureID);
-  return malloc(4 * tex->uTextureWidth * tex->uTextureHeight);
-}
-
-//----- (00469C39) --------------------------------------------------------
-POINT *Mouse::GetCursorPos(POINT *a2)
-{
-  a2->x = this->uMouseClickX;
-  a2->y = this->uMouseClickY;
-  return a2;
-}
-
-//----- (00469C65) --------------------------------------------------------
-void Mouse::Initialize(OSWindow *window)
-{
-  this->window = window;
-  this->bActive = false;
-  this->bInitialized = true;
-
-  //this->field_8 = 0;//Ritor1: result incorrect uMouseClickX, this->uMouseClickY in _469AE4()
-  this->uCursorBitmapPitch = 0;//Ritor1: it's include
-  for ( uint i = 0; i < 13; i++ )
-    this->field_5C[i] = 0;
-
-  this->pCursorBitmapPos.x = 0;
-  this->pCursorBitmapPos.y = 0;
-  this->uMouseClickX = 0;
-  this->uMouseClickY = 0;
-  this->pCursorBitmap_sysmem = nullptr;
-  this->field_34 = 0;
-  this->pCursorBitmap2_sysmem = nullptr;
-
-  SetCursorBitmap("MICON3");
-  SetCursorBitmap("MICON2");
-  SetCursorBitmap("MICON1");
-}
-
-// inlined
-//----- (0045FE00) mm6 chinese --------------------------------------------
-void Mouse::SetActive(bool active)
-{
-  bActive = active;
-}
-
-//----- (00469CC2) --------------------------------------------------------
-void Mouse::Deactivate()
-{
-  if (bInitialized)
-    SetActive(false);
-}
-
-//----- (00469CCD) --------------------------------------------------------
-void Mouse::DrawCursor()
-{
-  unsigned int v9; // eax@31
-
-  if ( this->bInitialized )
-  {
-    if ( !this->field_8 && this->bActive && !this->field_C ) //Uninitialized memory access(this->field_8)
-      pMouse->_469AE4();//Ritor1: ñòðàííàÿ, íåïîíÿòíàÿ ôóíêöèÿ
-    this->field_F4 = 1;
-    if ( this->field_C )
-    {
-      this->field_F4 = 0;
-      return;
-    }
-
-    //if ( pRenderer->bWindowMode )
-    {
-      if ( this->uMouseClickX < 0 || this->uMouseClickY < 0 || this->uMouseClickX > window->GetWidth() - 1 || this->uMouseClickY > window->GetHeight() - 1 )
-      {
-        this->field_F4 = 0;
-        return;
-      }
-    }
-    /*else
-    {
-      if ( this->uMouseClickX < 0 )
-        this->uMouseClickX = 0;
-      if ( this->uMouseClickY < 0 )
-        this->uMouseClickY = 0;
-      if ( this->uMouseClickX > 639 )
-        this->uMouseClickX = 639;
-      if ( this->uMouseClickY > 479 )
-        this->uMouseClickY = 479;
-    }*/
-    this->pCursorBitmapRect.x = this->uMouseClickX;
-    this->pCursorBitmapRect.w = this->uMouseClickY + this->field_5C[0]; //Ritor1: Maybe this->field_5C[0] - cursor width
-    this->pCursorBitmapRect.y = this->uMouseClickY;
-    this->pCursorBitmapRect.z = this->uMouseClickX + this->uCursorBitmapPitch; //Ritor1: Maybe this->uCursorBitmapPitch - cursor height
-    if ( this->uMouseClickX < 0 )
-      this->pCursorBitmapRect.x = 0;
-    if ( this->uMouseClickY < 0 )
-      this->pCursorBitmapRect.y = 0;
-    if ( this->pCursorBitmapRect.z > window->GetWidth() )
-      this->pCursorBitmapRect.z = window->GetWidth();
-    if ( this->pCursorBitmapRect.w > window->GetHeight() )
-      this->pCursorBitmapRect.w = window->GetHeight();
-    this->bActive = false;
-    this->uCursorBitmapWidth = this->pCursorBitmapRect.z - this->pCursorBitmapRect.x;
-    this->uCursorBitmapHeight = this->pCursorBitmapRect.w - this->pCursorBitmapRect.y;
-    if ( this->bRedraw )
-    {
-      if ( pMouse->ptr_90 )
-        v9 = 2 * pMouse->uCursorBitmapPitch;
-      else
-        v9 = 0;
-      pRenderer->_4A6DF5( this->pCursorBitmap_sysmem, v9, &this->pCursorBitmapPos, pRenderer->pTargetSurface, pRenderer->uTargetSurfacePitch,
-        &this->pCursorBitmapRect);//ñðàáàòûâàåò êîãäà áåð¸ì êóðñîðîì âåùü â èíâåíòîðå
-      this->bRedraw = false;
-    }
-  }
-}
-
-//----- (00469E1C) --------------------------------------------------------
-void Mouse::Activate()
-{
-  bActive = true;
-}
-
-//----- (00469E24) --------------------------------------------------------
-void Mouse::_469E24()
-{
-  free(pCursorBitmap3_sysmembits_16bit);
-  pCursorBitmap3_sysmembits_16bit = nullptr;
-}
-
-//----- (00469E3B) --------------------------------------------------------
-void Mouse::DrawCursorToTarget()//??? DrawCursorWithItem
-{
-  if (!pCursorBitmap3_sysmembits_16bit)
-    return;
-  //ïèøåì íà ýêðàí êóðñîð ñ âåùüþ
-  ushort* pSrc = pCursorBitmap3_sysmembits_16bit;
-  for (int y = uCursorWithItemY; y < uCursorWithItemZ; ++y)
-    for (int x = uCursorWithItemX; x < uCursorWithItemW; ++x)
-      //pRenderer->pTargetSurface[y * pRenderer->uTargetSurfacePitch + x] = *pSrc++;
-        pRenderer->WritePixel16(x, y, *pSrc++);
-}
-
-//----- (00469EA4) --------------------------------------------------------
-void Mouse::ReadCursorWithItem()
-{
-  unsigned int pTextureID; // eax@2
-  Texture *pTexture; // edi@2
-//  int v8; // ecx@25
-//  int v9; // ebx@26
-//  unsigned int v10; // eax@26
-//  int v11; // edx@27
-  int pTextureHeight; // [sp+20h] [bp-8h]@15
-//  unsigned __int16 *v20; // [sp+20h] [bp-8h]@28
-  int pTextureWidth; // [sp+24h] [bp-4h]@12
-  unsigned __int16 *v22; // [sp+24h] [bp-4h]@25
-
-  if ( pParty->pPickedItem.uItemID )
-  {
-    pTextureID = pIcons_LOD->LoadTexture(pParty->pPickedItem.GetIconName(), TEXTURE_16BIT_PALETTE);
-    pTexture = (Texture *)(pTextureID != -1 ? (int)&pIcons_LOD->pTextures[pTextureID] : 0);
-
-    if ( (signed int)pMouse->uMouseClickX <= window->GetWidth() - 1 && (signed int)pMouse->uMouseClickY <= window->GetHeight() - 1 )
-    {
-      /*if ( (v4 & 0x80000000u) != 0 )
-        a2 = 0;
-      if ( (v5 & 0x80000000u) != 0 )
-      {
-        //v6 = 0;
-        v15 = 0;
-      }	*/
-      if ( (signed int)(pTexture->uTextureWidth + pMouse->uMouseClickX) <= window->GetWidth() )
-        pTextureWidth = pTexture->uTextureWidth;
-      else
-        pTextureWidth = window->GetWidth() - pMouse->uMouseClickX;
-      if ( (signed int)(pTexture->uTextureHeight + pMouse->uMouseClickY) <= window->GetHeight() )
-        pTextureHeight = pTexture->uTextureHeight;
-      else
-        pTextureHeight = window->GetHeight() - pMouse->uMouseClickY;
-      if ( !this->pCursorBitmap3_sysmembits_16bit
-        || pMouse->uMouseClickX != this->uCursorWithItemX
-        || pMouse->uMouseClickY != this->uCursorWithItemY
-        || pMouse->uMouseClickX + pTextureWidth != this->uCursorWithItemW
-        || pMouse->uMouseClickY + pTextureHeight != this->uCursorWithItemZ )
-      {
-        free(this->pCursorBitmap3_sysmembits_16bit);
-        this->pCursorBitmap3_sysmembits_16bit = (unsigned __int16 *)malloc(2 * pTexture->uTextureHeight * pTexture->uTextureWidth);
-        this->uCursorWithItemX = pMouse->uMouseClickX;
-        this->uCursorWithItemW = pMouse->uMouseClickX + pTextureWidth;
-        this->uCursorWithItemY = pMouse->uMouseClickY;
-        this->uCursorWithItemZ = pMouse->uMouseClickY + pTextureHeight;
-      }
-      v22 = this->pCursorBitmap3_sysmembits_16bit;
-
-      for (int y = this->uCursorWithItemY; y < this->uCursorWithItemZ; ++y)
-      {
-        for (int x = this->uCursorWithItemX; x < this->uCursorWithItemW; ++x)
-        {
-          *v22++ = pRenderer->ReadPixel16(x, y);
-        }
-      }
-      /*if ( v8 < this->field_4C )
-      {
-        v9 = this->field_48;
-        v10 = pRenderer->uTargetSurfacePitch * v8;
-        do
-        {
-          v11 = this->field_40;
-          v18 = this->field_40;
-          if ( v11 < v9 )
-          {
-            v20 = &v17[v10 + v11];
-            do
-            {
-              //v12 = v20;
-              ++v18;
-              //++v20;
-              *v22++ = *v20++;
-            }
-            while ( v18 < v9 );
-          }
-          v10 += v16;
-          ++v8;
-        }
-        while ( v8 < this->field_4C );
-        v6 = v15;
-      }*/
-
-      if (pParty->pPickedItem.IsBroken())
-        pRenderer->DrawTransparentRedShade(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
-      else if (!pParty->pPickedItem.IsIdentified())
-        pRenderer->DrawTransparentGreenShade(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
-      else
-        pRenderer->DrawTextureTransparent(pMouse->uMouseClickX, pMouse->uMouseClickY, pTexture);
-    }
-  }
-  else
-  {
-    free(this->pCursorBitmap3_sysmembits_16bit);
-    this->pCursorBitmap3_sysmembits_16bit = nullptr;
-  }
-}
-
-//----- (0046A080) --------------------------------------------------------
-void Mouse::ChangeActivation(int a1)
-{
-  this->bActive = a1;
-}
-
-//----- (0046A08A) --------------------------------------------------------
-void Mouse::SetMouseClick(int x, int y)
-{
-  uMouseClickX = x;
-  uMouseClickY = y;
-}
-//----- (004175C0) --------------------------------------------------------
-void Mouse::UI_OnMouseLeftClick(int *pXY)
-{
-  signed int y; // eax@7
-  signed int x; // ecx@7
-  signed int v5; // eax@17
-  GUIButton *control; // esi@37
-  signed int v10; // eax@50
-//  int v11; // ecx@52
-  unsigned int pX; // [sp+14h] [bp-8h]@7
-  unsigned int pY; // [sp+18h] [bp-4h]@7
-
-  if ( pCurrentScreen == SCREEN_VIDEO || sub_4637E0_is_there_popup_onscreen() )
-    return;
-  if ( pGUIWindow2 && pGUIWindow2->ptr_1C == (void *)33 )
-  {
-    sub_4452BB();
-    return;
-  }
-  if ( pXY )
-  {
-    x = *pXY;
-    y = pXY[1];
-    pX = *pXY;
-    pY = y;
-  }
-  else
-  {
-    pMouse->GetClickPos(&pX, &pY);
-    y = pY;
-    x = pX;
-  }
-
-  extern bool _507B98_ctrl_pressed;
-  x = pX;
-  if ( GetCurrentMenuID() != -1 || pCurrentScreen != SCREEN_GAME || !_507B98_ctrl_pressed // stealing cursor
-      || (signed int)pX < (signed int)pViewport->uViewportTL_X || (signed int)pX > (signed int)pViewport->uViewportBR_X
-      || (signed int)pY < (signed int)pViewport->uViewportTL_Y || (signed int)pY > (signed int)pViewport->uViewportBR_Y)
-  {
-    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 )
-      {
-        for ( control = pWindowList[pVisibleWindowsIdxs[i] - 1].pControlsHead; control; control = control->pNext )
-        {
-          if ( control->uButtonType == 1 )
-          {
-            if ( x >= (signed int)control->uX && x <= (signed int)control->uZ && y >= (signed int)control->uY && y <= (signed int)control->uW )
-            {
-              control->field_2C_is_pushed = 1;
-              v10 = pMessageQueue_50CBD0->uNumMessages;
-              if ( pMessageQueue_50CBD0->uNumMessages )
-              {
-                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-              }
-              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
-              return;
-            }
-            continue;
-          }
-          if ( control->uButtonType == 2 )//êîãäà íàæèìàåøü íà ïàðòðåòû ïåðñîâ
-          {
-            if ( (signed int)(signed __int64)sqrt((double)((x - control->uX) * (x - control->uX) + (y - control->uY) * (y - control->uY))) < (signed int)control->uWidth )
-            {
-              control->field_2C_is_pushed = 1;
-              v10 = pMessageQueue_50CBD0->uNumMessages;
-              if ( pMessageQueue_50CBD0->uNumMessages )
-              {
-                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-              }
-              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
-              return;
-            }
-            continue;
-          }
-          if ( control->uButtonType == 3 )//êîãäà íàæèìàåøü íà ñêèëëû
-          {
-            if ( x >= (signed int)control->uX && x <= (signed int)control->uZ && y >= (signed int)control->uY && y <= (signed int)control->uW )
-            {
-              control->field_2C_is_pushed = 1;
-              v10 = pMessageQueue_50CBD0->uNumMessages;
-              if ( pMessageQueue_50CBD0->uNumMessages )
-              {
-                v10 = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-                pMessageQueue_50CBD0->uNumMessages = pMessageQueue_50CBD0->pMessages[0].field_8 != 0;
-              }
-              pMessageQueue_50CBD0->AddGUIMessage(control->msg, control->msg_param, 0);
-              return;
-            }
-            continue;
-          }
-          y = pY;
-          x = pX;
-        }
-      }
-    }
-    return;
-  }
-  y = pY;
-  //if ( pRenderer->pRenderD3D )
-    v5 = pGame->pVisInstance->get_picked_object_zbuf_val();
-  /*else
-    v5 = pRenderer->pActiveZBuffer[pX + pSRZBufferLineOffsets[pY]];*/
-
-  uint type = PID_TYPE((unsigned __int16)v5);
-  if (type == OBJECT_Actor && uActiveCharacter && v5 < 0x2000000
-    && pPlayers[uActiveCharacter]->CanAct() && pPlayers[uActiveCharacter]->CanSteal() )
-  {
-    /*if ( (signed int)pMessageQueue_50CBD0->uNumMessages < 40 )
-    {
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].eType = UIMSG_1B;
-      pMessageQueue_50CBD0->pMessages[pMessageQueue_50CBD0->uNumMessages].param = v6 >> 3;
-      *(&pMessageQueue_50CBD0->uNumMessages + 3 * pMessageQueue_50CBD0->uNumMessages + 3) = 0;
-      ++pMessageQueue_50CBD0->uNumMessages;
-    }*/
-    pMessageQueue_50CBD0->AddGUIMessage(UIMSG_STEALFROMACTOR, PID_ID((unsigned __int16)v5), 0);
-
-    if ( pParty->bTurnBasedModeOn == 1 )
-    {
-      if ( pTurnEngine->turn_stage == TE_MOVEMENT )
-        pTurnEngine->field_18 |= TE_FLAG_8;
-    }
-  }
-}
-
-
-//----- (0041CD4F) --------------------------------------------------------
-bool Mouse::UI_OnKeyDown(unsigned int vkKey)
-{
-  //unsigned int v1; // edi@1
-  //unsigned int v2; // eax@2
-  int v3; // esi@3
-  int v4; // ecx@10
-  GUIButton *pButton; // eax@11
-  int v6; // edx@12
-  int v7; // ecx@20
-  char v8; // zf@21
-  //GUIButton *v9; // ecx@24
-  int v10; // esi@24
-  //int v11; // edx@26
-  int v12; // edx@28
-  int v13; // esi@32
-  //GUIButton *v14; // eax@37
-  int v15; // edx@38
-  int v17; // ecx@50
-  int v18; // edx@50
-  //GUIButton *v19; // ecx@54
-  int v20; // esi@54
-  //int v21; // edx@56
-  int v22; // ecx@59
-  int v23; // edx@59
-  int v24; // ecx@60
-  int v25; // esi@63
-  //unsigned int v26; // [sp+Ch] [bp-14h]@1
-  //int v27; // [sp+10h] [bp-10h]@1
-  int v28; // [sp+14h] [bp-Ch]@10
-  int v29; // [sp+14h] [bp-Ch]@36
-  unsigned int uClickX; // [sp+18h] [bp-8h]@10
-  unsigned int uClickY; // [sp+1Ch] [bp-4h]@10
-
-  //v1 = 0;
-  //v27 = uNumVisibleWindows;
-  if ( uNumVisibleWindows < 0 )
-    return false;
-  //v2 = pMessageQueue_50CBD0->uNumMessages;
-  for (int i = uNumVisibleWindows; i >= 0; --i)
-  //while ( 1 )
-  {
-    v3 = pVisibleWindowsIdxs[i] - 1;
-    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 )
-        {
-          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem -= v12;
-          if ( v8 )
-          {
-            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
-            //v2 = pMessageQueue_50CBD0->uNumMessages;
-          }
-        }
-        if ( pWindowList[v3].field_30 != 0 )
-        {
-          break;
-        }
-        pButton = pWindowList[v3].pControlsHead;
-        v13 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v13 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v13;
-          }
-          while ( v13 );
-        }
-        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
-        break;
-      }
-      case VK_RIGHT:
-      {
-        v7 = pWindowList[v3].pCurrentPosActiveItem + pWindowList[v3].field_34;
-        if ( v7 < pWindowList[v3].pNumPresenceButton + pWindowList[v3].pStartingPosActiveItem )
-        {
-          v8 = pCurrentScreen == SCREEN_PARTY_CREATION;
-          pWindowList[v3].pCurrentPosActiveItem = v7;
-          if ( v8 )
-          {
-            pAudioPlayer->PlaySound(SOUND_Button, 0, 0, -1, 0, 0, 0, 0);
-            //v2 = pMessageQueue_50CBD0->uNumMessages;
-          }
-        }
-        if ( pWindowList[v3].field_30 != 0 )
-        {
-          break;
-        }
-        pButton = pWindowList[v3].pControlsHead;
-        v10 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v10 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v10;
-          }
-          while ( v10 );
-        }
-        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
-        break;
-      }
-      case VK_DOWN:
-      {
-        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 )
-          return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v20 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v20 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v20;
-          }
-          while ( v20 );
-        }
-        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
-        return true;
-      }
-      case VK_SELECT:
-      {
-        pMouse->GetClickPos(&uClickX, &uClickY);
-        v4 = pWindowList[v3].pStartingPosActiveItem;
-        v28 = v4 + pWindowList[v3].pNumPresenceButton;
-        if ( v4 < v4 + pWindowList[v3].pNumPresenceButton )
-        {
-          while ( 1 )
-          {
-            pButton = pWindowList[v3].pControlsHead;
-            if ( v4 > 0 )
-            {
-              v6 = v4;
-              do
-              {
-                pButton = pButton->pNext;
-                --v6;
-              }
-              while ( v6 );
-            }
-            if ( (signed int)uClickX >= (signed int)pButton->uX//test for StatsTab in PlayerCreation Window
-               && (signed int)uClickX <= (signed int)pButton->uZ
-               && (signed int)uClickY >= (signed int)pButton->uY
-               && (signed int)uClickY <= (signed int)pButton->uW )
-              break;
-            ++v4;
-            if ( v4 >= v28 )
-            {
-              //v1 = 0;
-              //v2 = pMessageQueue_50CBD0->uNumMessages;
-              //--i;
-              //if ( i < 0 )
-                return false;
-              //continue;
-            }
-          }
-          pWindowList[v3].pCurrentPosActiveItem = v4;
-          return true;
-        }
-        //v2 = pMessageQueue_50CBD0->uNumMessages;
-        break;
-      }
-      case VK_UP:
-      {
-        v22 = pWindowList[v3].pCurrentPosActiveItem;
-        v23 = pWindowList[v3].pStartingPosActiveItem;
-        if ( v22 <= v23 )
-          v24 = pWindowList[v3].pNumPresenceButton + v23 - 1;
-        else
-          v24 = v22 - 1;
-        v8 = pWindowList[v3].field_30 == 0;
-        pWindowList[v3].pCurrentPosActiveItem = v24;
-        if ( !v8 )
-          return true;
-        pButton = pWindowList[v3].pControlsHead;
-        v25 = pWindowList[v3].pCurrentPosActiveItem;
-        if ( v25 > 0)
-        {
-          do
-          {
-            pButton = pButton->pNext;
-            --v25;
-          }
-          while ( v25 );
-        }
-        pMessageQueue_50CBD0->AddGUIMessage(pButton->msg, pButton->msg_param, 0);
-        return true;
-      }
-      case VK_NEXT:
-      {  
-        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 )
-          {
-            pButton = pWindowList[v3].pControlsHead;
-            if ( v4 > 0 )
-            {
-              for ( v15 = v4; v15; --v15 )
-                pButton = pButton->pNext;
-            }
-            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;
-              return true;
-            }
-          }
-        }
-        break;
-      }
-      default:
-        break;
-    }
-  }
-}
--- a/Mouse.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-#pragma once
-#include "OSWindow.h"
-
-#include "Engine/VectorTypes.h"
-
-
-
-/*  107 */
-#pragma pack(push, 1)
-class ThreadWard
-{
-public:
-  //----- (00438B0B) --------------------------------------------------------
-  inline ThreadWard()
-  {
-    InitializeCriticalSection(&csAsyncMouse);
-    InitializeCriticalSection(&cs2);
-    InitializeCriticalSection(&cs3);
-    InitializeCriticalSection(&csAsyncKeyboard);
-  }
-
-  //----- (00438B54) --------------------------------------------------------
-  virtual ~ThreadWard()
-  {
-  ThreadWard *v1; // esi@1
-
-  v1 = this;
-  //this->vdestructor_ptr = &ThreadWard_destructors;
-  DeleteCriticalSection(&this->csAsyncKeyboard);
-  DeleteCriticalSection(&v1->cs3);
-  DeleteCriticalSection(&v1->cs2);
-  DeleteCriticalSection(&v1->csAsyncMouse);
-  }
-
-  void ( ***vdestructor_ptr)(ThreadWard *, bool);
-  _RTL_CRITICAL_SECTION csAsyncMouse;
-  _RTL_CRITICAL_SECTION cs2;
-  _RTL_CRITICAL_SECTION cs3;
-  _RTL_CRITICAL_SECTION csAsyncKeyboard;
-};
-#pragma pack(pop)
-
-/*  106 */
-#pragma pack(push, 1)
-class Mouse
-{
-public:
-  //----- (00467E4E) --------------------------------------------------------
-  inline Mouse():
-    window(nullptr)
-  {
-    uCursorTextureID = 0;
-    uCursorTextureID_2 = 0;
-    pCursorBitmap_sysmem = nullptr;
-    field_34 = 0;
-    pCursorBitmap2_sysmem = nullptr;
-    pCursorBitmap3_sysmembits_16bit = nullptr;
-    ptr_90 = nullptr;
-    pWard = nullptr;
-    *pCurrentCursorName = NULL;
-    uMouseClickX = 0;
-    uMouseClickY = 0;
-  }
-
-  void GetClickPos(unsigned int *pX, unsigned int *pY);
-  void RemoveHoldingItem();
-  void SetCursorBitmapFromItemID(unsigned int uItemID);
-  void SetCurrentCursorBitmap();
-  void SetCursorBitmap(const char *pName);
-  LONG _469AE4();
-  void ClearCursor();
-  void AllocCursorSystemMem();
-  void *DoAllocCursorMem();
-  POINT *GetCursorPos(POINT *p);
-  void Initialize(OSWindow *window);
-  void SetActive(bool active);
-  void Deactivate();
-  void DrawCursor();
-  void Activate();
-  void _469E24();
-  void DrawCursorToTarget();
-  void ReadCursorWithItem();
-  void ChangeActivation(int a1);
-  void SetMouseClick(int x, int y);
-
-  static void UI_OnMouseLeftClick(int *pXY); // idb
-  static bool UI_OnKeyDown(unsigned int vkKey);
-
-
-  unsigned int uPointingObjectID;
-  unsigned int bActive;
-  int field_8;
-  int field_C;
-  unsigned int bInitialized;
-  unsigned int bRedraw;
-  int field_18;
-  int field_1C;
-  int field_20;
-  unsigned int uCursorTextureID;
-  unsigned int uCursorTextureID_2;
-  //HWND hWnd;
-  OSWindow *window;
-  unsigned __int16 *pCursorBitmap_sysmem;
-  int field_34;
-  unsigned __int8 *pCursorBitmap2_sysmem;
-  unsigned __int16 *pCursorBitmap3_sysmembits_16bit;
-  int uCursorWithItemX;
-  int uCursorWithItemY;
-  int uCursorWithItemW;
-  int uCursorWithItemZ;
-  int field_50;
-  int field_54;
-  int uCursorBitmapPitch;
-  int field_5C[13];
-  void *ptr_90;
-  int field_94;
-  int field_98;
-  int field_9C;
-  int field_A0;
-  int field_A4;
-  int field_A8;
-  int field_AC;
-  int field_B0;
-  int field_B4;
-  int field_B8;
-  int field_BC;
-  int field_C0;
-  Vec2_int_ pCursorBitmapPos;
-  int uCursorBitmapWidth;
-  int uCursorBitmapHeight;
-  int field_D4;
-  int field_D8;
-  int field_DC;
-  int field_E0;
-  Vec4_int_ pCursorBitmapRect;
-  char field_F4;
-  char pCurrentCursorName[11];
-  int field_100;
-  int field_104;
-  unsigned int uMouseClickX;
-  unsigned int uMouseClickY;
-  void/*ThreadWard*/ *pWard;
-};
-#pragma pack(pop)
-
-
-
-
-
-extern Mouse *pMouse;
\ No newline at end of file
--- a/OSWindow.cpp	Fri Sep 19 04:21:12 2014 +0600
+++ b/OSWindow.cpp	Fri Sep 19 05:13:32 2014 +0600
@@ -7,17 +7,17 @@
 #include "OSWindow.h"
 #include "Engine/mm7_data.h"
 #include "Arcomage\Arcomage.h"
-#include "AudioPlayer.h"
-#include "Mouse.h"
+#include "Media/Audio/AudioPlayer.h"
+#include "IO/Mouse.h"
 #include "Engine/Timer.h"
-#include "GUIWindow.h"
+#include "GUI/GUIWindow.h"
 #include "Engine/Party.h"
 #include "Engine/Game.h"
 #include "Engine/Graphics/IndoorCameraD3D.h"
-#include "Keyboard.h"
+#include "IO/Keyboard.h"
 #include "Engine/Graphics/Viewport.h"
 #include "Engine/Graphics/Vis.h"
-#include "AIL.h"
+#include "Media/Audio/AIL.h"
 #include "Engine/ErrorHandling.h"
 #include "Engine/Log.h"
 #include "Engine/Registry.h"
--- a/OpenALSoundProvider.h	Fri Sep 19 04:21:12 2014 +0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-#pragma once
-#include "lib/OpenAL/al.h"
-#include "lib/OpenAL/alc.h"
-#pragma comment(lib, "OpenAL32.lib")
-
-#include "Engine/stuff.h"
-#include "Engine/Log.h"
-
-class OpenALSoundProvider
-{
-  public:
-    struct TrackBuffer
-    {
-      unsigned int source_id;
-      unsigned int buffer_id;
-    };
-
-    struct StreamingTrackBuffer
-    {
-      unsigned int source_id;
-      ALenum       sample_format;
-      int          sample_rate;
-    };
-
-    inline OpenALSoundProvider()
-    {
-      this->device = nullptr;
-      this->context = nullptr;
-    }
-
-    inline ~OpenALSoundProvider()
-    {
-      Release();
-    }
-
-    inline bool Initialize()
-    {
-
-      auto device_names = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
-      if (!device_names)
-      {
-        device_names = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
-      }
-      if (device_names)
-      {
-        for (auto device_name = device_names; device_name[0]; device_name += strlen(device_name))
-        {
-          continue;
-        }
-      }
-
-      device = alcOpenDevice(nullptr);
-      if (!device || CheckError())
-	  {
-        Log::Warning(L"Default sound device not present");
-        return false;
-	  }
-
-      context = alcCreateContext(device, nullptr);
-      if (!context || CheckError())
-        return Release(), false;
-
-      alcMakeContextCurrent(context);
-
-      bool eax2 = alIsExtensionPresent("EAX2.0");
-      bool eax3 = alIsExtensionPresent("EAX3.0");
-      bool eax4 = alIsExtensionPresent("EAX4.0");
-      bool eax5 = alIsExtensionPresent("EAX5.0");
-      
-      auto vendor = alGetString(AL_VENDOR);
-      auto version = alGetString(AL_VERSION);
-      auto extensions = alcGetString(device, ALC_EXTENSIONS);
-
-      return true;
-    }
-
-    void Release()
-    {
-      alcMakeContextCurrent(nullptr);
-      if (context)
-      {
-        alcDestroyContext(context);
-      }
-      if (device)
-      {
-        alcCloseDevice(device);
-      }
-    }
-
-    void DeleteStreamingTrack(StreamingTrackBuffer **buffer)
-    {
-      if (!buffer && !*buffer)
-        return;
-      auto track = *buffer;
-
-      int status;
-      alGetSourcei(track->source_id, AL_SOURCE_STATE, &status);
-      if (status == AL_PLAYING)
-      {
-        alSourceStop(track->source_id);
-        if (CheckError()) __debugbreak();
-      }
-
-      int num_processed_buffers = 0;
-      int num_queued_buffers = 0;
-      alGetSourcei(track->source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers);
-      alGetSourcei(track->source_id, AL_BUFFERS_QUEUED, &num_queued_buffers);
-      int num_track_buffers = num_queued_buffers + num_processed_buffers;
-      for (int i = 0; i < num_processed_buffers; ++i)
-      {
-        unsigned int buffer_id;
-        alSourceUnqueueBuffers(track->source_id, 1, &buffer_id);
-        if (!CheckError())
-          alDeleteBuffers(1, &buffer_id);
-        else __debugbreak();
-      }
-
-      alDeleteSources(1, &track->source_id);
-      CheckError();
-
-      delete *buffer;
-      *buffer = nullptr;
-    }
-
-    void DeleteBuffer16(TrackBuffer **buffer)
-    {
-      alDeleteBuffers(1, &(*buffer)->buffer_id);
-      CheckError();
-
-      delete *buffer;
-      *buffer = nullptr;
-    }
-
-    float alBufferLength(unsigned int buffer)
-    {
-      int size, bits, channels, freq;
-
-      alGetBufferi(buffer, AL_SIZE, &size);
-      alGetBufferi(buffer, AL_BITS, &bits);
-      alGetBufferi(buffer, AL_CHANNELS, &channels);
-      alGetBufferi(buffer, AL_FREQUENCY, &freq);
-      if (CheckError())
-        return 0.0f;
-
-      return (ALfloat)((ALuint)size / channels / (bits / 8)) / (ALfloat)freq;
-    }
-
-    StreamingTrackBuffer *CreateStreamingTrack16(int num_channels, int sample_rate, int bytes_per_sample)
-    {
-      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
-
-      ALenum sound_format;
-      switch (num_channels)
-      {
-        case 1: sound_format = AL_FORMAT_MONO16;    break;
-        case 2: sound_format = AL_FORMAT_STEREO16;  break;
-        default:
-          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
-          {
-            switch (num_channels)
-            {
-              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
-              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
-              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
-              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
-            }
-          }
-          Error("Unsupported number of audio channels: %u", num_channels);
-      }
-
-      unsigned int al_source = -1;
-      alGetError();
-      alGenSources(1, &al_source);
-      if (CheckError())
-        return nullptr;
-
-      float sound_pos[] = {0.0f, 0.0f, 0.0f},
-            sound_vel[] = {0.0f, 0.0f, 0.0f};
-
-      alSourcei(al_source, AL_LOOPING, AL_FALSE);
-      alSourcef(al_source, AL_PITCH, 1.0f);
-      alSourcef(al_source, AL_GAIN, 1.0f);
-      alSourcefv(al_source, AL_POSITION, sound_pos);
-      alSourcefv(al_source, AL_VELOCITY, sound_vel);
-
-      auto ret = new StreamingTrackBuffer;
-      ret->source_id = al_source;
-      ret->sample_format = sound_format;
-      ret->sample_rate = sample_rate;
-      return ret;
-    }
-
-    void Stream16(StreamingTrackBuffer *buffer, int num_samples, const void *samples, bool wait = false)
-    {
-      int bytes_per_sample = 2;
-
-      unsigned int al_buffer;
-      alGenBuffers(1, &al_buffer);
-      alBufferData(al_buffer, buffer->sample_format, samples, num_samples * bytes_per_sample, buffer->sample_rate);
-      if (CheckError())
-      {
-        alDeleteBuffers(1, &al_buffer);
-        return;
-      }
-
-      int num_processed_buffers = 0;
-      alGetSourcei(buffer->source_id, AL_BUFFERS_PROCESSED, &num_processed_buffers);
-      for (int i = 0; i < num_processed_buffers; ++i)
-      {
-        unsigned int processed_buffer_id;
-        alSourceUnqueueBuffers(buffer->source_id, 1, &processed_buffer_id);
-        if (!CheckError())
-          alDeleteBuffers(1, &processed_buffer_id);
-      }
-
-      alSourceQueueBuffers(buffer->source_id, 1, &al_buffer);
-      if (CheckError())
-      {
-        alDeleteBuffers(1, &al_buffer);
-        return;
-      }
-
-      volatile int status;
-      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
-      if (status != AL_PLAYING)
-      {
-        float listener_pos[] = {0.0f, 0.0f, 0.0f};
-        float listener_vel[] = {0.0f, 0.0f, 0.0f};
-        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
-                                        0.0f, 1.0f, 0.0f}; // up vector
-        alListenerfv(AL_POSITION, listener_pos);
-        alListenerfv(AL_VELOCITY, listener_vel);
-        alListenerfv(AL_ORIENTATION, listener_orientation);
-
-        alSourcePlay(buffer->source_id);
-        if (CheckError())
-          __debugbreak();
-
-        if (wait)
-        {
-          do
-          {
-            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
-          }
-          while (status == AL_PLAYING);
-        }
-      }
-    }
-
-
-
-
-    TrackBuffer *CreateTrack16(int num_channels, int sample_rate, int bytes_per_sample, int num_samples, const void *samples)
-    {
-      Assert(bytes_per_sample == 2, "OpenALSoundProvider: unsupported sample size: %u", bytes_per_sample);
-
-      ALenum sound_format;
-      switch (num_channels)
-      {
-        case 1: sound_format = AL_FORMAT_MONO16;    break;
-        case 2: sound_format = AL_FORMAT_STEREO16;  break;
-        default:
-          if (bool multichannel = alIsExtensionPresent("AL_EXT_MCFORMATS"))
-          {
-            switch (num_channels)
-            {
-              case 4: sound_format = alGetEnumValue("AL_FORMAT_QUAD16");  break;
-              case 6: sound_format = alGetEnumValue("AL_FORMAT_51CHN16"); break;
-              case 7: sound_format = alGetEnumValue("AL_FORMAT_61CHN16"); break;
-              case 8: sound_format = alGetEnumValue("AL_FORMAT_71CHN16"); break;
-            }
-          }
-          Error("Unsupported number of audio channels: %u", num_channels);
-      }
-
-      unsigned int al_source = -1;
-      alGenSources(1, &al_source);
-      if (CheckError())
-        return nullptr;
-
-      float sound_pos[] = {0.0f, 0.0f, 0.0f},
-            sound_vel[] = {0.0f, 0.0f, 0.0f};
-
-      alSourcei(al_source, AL_LOOPING, AL_FALSE);
-      alSourcef(al_source, AL_PITCH, 1.0f);
-      alSourcef(al_source, AL_GAIN, 1.0f);
-      alSourcefv(al_source, AL_POSITION, sound_pos);
-      alSourcefv(al_source, AL_VELOCITY, sound_vel);
-
-      unsigned int al_buffer = -1;
-      alGenBuffers(1, &al_buffer);
-      if (CheckError())
-      {
-        alDeleteSources(1, &al_source);
-        return nullptr;
-      }
-
-      alBufferData(al_buffer, sound_format, samples, num_samples * bytes_per_sample, sample_rate);
-      if (CheckError())
-      {
-        alDeleteSources(1, &al_source);
-        alDeleteBuffers(1, &al_buffer);
-        return nullptr;
-      }
-
-      alSourcei(al_source, AL_BUFFER, al_buffer);
-      if (CheckError())
-      {
-        alDeleteSources(1, &al_source);
-        alDeleteBuffers(1, &al_buffer);
-        return nullptr;
-      }
-
-      auto ret = new TrackBuffer;
-      ret->source_id = al_source;
-      ret->buffer_id = al_buffer;
-      return ret;
-    }
-
-
-    void PlayTrack16(TrackBuffer *buffer, bool loop = false, bool wait = false)
-    {
-      volatile int status;
-      alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
-      if (status == AL_PLAYING)
-        Error("Already playing");
-      else
-      {
-        float listener_pos[] = {0.0f, 0.0f, 0.0f};
-        float listener_vel[] = {0.0f, 0.0f, 0.0f};
-        float listener_orientation[] = {0.0f, 0.0f, -1.0f, // direction
-                                        0.0f, 1.0f, 0.0f}; // up vector
-        alListenerfv(AL_POSITION, listener_pos);
-        alListenerfv(AL_VELOCITY, listener_vel);
-        alListenerfv(AL_ORIENTATION, listener_orientation);
-
-        alSourcei(buffer->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
-        alSourcePlay(buffer->source_id);
-        if (CheckError())
-          __debugbreak();
-
-        if (wait && !loop)
-        {
-          float track_length = alBufferLength(buffer->buffer_id);
-          do
-          {
-            float track_offset = 0;
-            alGetSourcef(buffer->source_id, AL_SEC_OFFSET, &track_offset);
-            log("playing: %.4f/%.4f\n", track_offset, track_length);
-
-            alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
-          }
-          while (status == AL_PLAYING);
-        }
-      }
-    }
-
-
-
-  protected:
-    ALCdevice    *device;
-    ALCcontext   *context;
-
-
-    bool CheckError()
-    {
-      ALenum code1 = alGetError();
-      if (code1 != AL_NO_ERROR)
-      {
-        DWORD w;
-        const char *message = alGetString(code1);
-        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
-        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
-        return true;
-      }
-
-      ALenum code2 = alcGetError(device);
-      if (code2 != ALC_NO_ERROR)
-      {
-        DWORD w;
-        const char *message = alcGetString(device, code2);
-        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), message, lstrlenA(message), &w, nullptr);
-        WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &w, nullptr);
-        return true;
-      }
-      return false;
-    }
-};
\ No newline at end of file