/* This file has been generated by the Hex-Rays decompiler.
   Copyright (c) 2007-2011 Hex-Rays <info@hex-rays.com>

   Detected compiler: Delphi
*/

#include <windows.h>
#include <defs.h>


//-------------------------------------------------------------------------
// Data declarations

// extern _UNKNOWN System::__linkproc___NewAnsiString; weak
// extern _UNKNOWN System::__linkproc___LStrSetLength; weak
extern _strings str____0[1]; // weak
extern _strings str_Ok[1]; // weak
extern _strings str_Internal_error[2]; // weak
extern _strings str_Not_implemented[3]; // weak
extern _strings str_Incompatible_ve[3]; // weak
extern _strings str_Out_of_memory[2]; // weak
extern _strings str_Invalid_paramet[3]; // weak
extern _strings str_Invalid_TtakStr[4]; // weak
extern _strings str_Invalid_mode[2]; // weak
extern _strings str_Buffer_too_smal[3]; // weak
extern _strings str_Not_enough_audi[3]; // weak
extern _strings str_Too_much_audio_[3]; // weak
extern _strings str_Unknown_error[2]; // weak
extern char *off_408460; // weak
extern char *off_4095DC; // weak
extern char *off_40989C; // weak
extern void *off_409B0C; // weak
extern _strings str_D__VocComp_Win_[6]; // weak
extern _strings str_Not_supported[2]; // weak
extern char *off_40B1C8; // weak
extern _strings str_D__VocComp_Win__0[5]; // weak
extern _strings str_Assertion_failu[3]; // weak
extern char *off_40B51C; // weak
extern _strings str_D__VocComp_Win__1[5]; // weak
extern _strings str_Assertion_failu_0[3]; // weak
extern char *off_40C420; // weak
extern int (__stdcall **off_40CFCC)(int); // weak
extern int (**off_40DAB0)(); // weak
extern int (**off_40DB2C)(); // weak
extern _strings str_Invalid_codec_v[3]; // weak
extern _strings str_0_Integer_24_bi[4]; // weak
extern _strings str_1_Experimental_[3]; // weak
extern _strings str_2_Integer_24_bi[4]; // weak
extern _strings str_3_LossyWav__TAK[4]; // weak
extern _strings str_4_Integer_24_bi[4]; // weak
extern _strings str__Unknown[2]; // weak
extern _strings str_D__VocComp_Win__2[6]; // weak
extern _strings str_TtbArrayBase_Te[4]; // weak
extern _strings str_D__VocComp_Win__3[6]; // weak
extern _strings str_TtbArrayBase_Se[4]; // weak
extern _strings str_D__VocComp_Win__4[6]; // weak
extern _strings str_TtbArrayBase_Se_0[3]; // weak
extern _strings str_D__VocComp_Win__5[6]; // weak
extern _strings str_TtbArrayBase_pu[4]; // weak
extern _strings str_D__VocComp_Win__6[6]; // weak
extern _strings str_TtbArrayBase_Cr[4]; // weak
extern _strings str_TtbArrayBase_Cr_0[4]; // weak
extern char *off_40F090; // weak
extern int (**off_40F0EC)(); // weak
extern char *off_40F158; // weak
extern char *off_40F1B4; // weak
extern _strings str_Item_not_availa[3]; // weak
extern _strings str_Invalid_item_ty[3]; // weak
extern _strings str_Buffer_too_smal_0[3]; // weak
extern _strings str_No_tag_found_[2]; // weak
extern _strings str_Incompatible_ta[3]; // weak
extern _strings str_Invalid_tag_[2]; // weak
extern _strings str_Error_reading_s[4]; // weak
extern char *off_4103DC; // weak
extern char *off_41043C; // weak
extern char *off_4104A0; // weak
extern char *off_410508; // weak
extern char *off_410568; // weak
extern _strings str_D__VocComp_Win__7[6]; // weak
extern _strings str_Assertion_failu_1[3]; // weak
extern _strings str_D__VocComp_Win__8[6]; // weak
extern _strings str_Assertion_failu_2[3]; // weak
extern _strings str_D__VocComp_Win__9[6]; // weak
extern _strings str_Assertion_failu_3[3]; // weak
extern char *off_412810; // weak
extern char *off_41286C; // weak
extern char *off_412E1C; // weak
extern _strings str_D__VocComp_Win__10[6]; // weak
extern _strings str_Assertion_failu_4[3]; // weak
extern _strings str_D__VocComp_Win__11[6]; // weak
extern _strings str_Assertion_failu_5[3]; // weak
extern char *off_4145AC; // weak
extern int (__stdcall **off_415080)(int); // weak
extern int (*off_4159B0)[2]; // weak
extern _strings str_Meta_data_missi[3]; // weak
extern _strings str_Meta_data_damag[3]; // weak
extern _strings str_Audio_data_dama[3]; // weak
extern _strings str_Error_reading_s_0[4]; // weak
extern _strings str_Incompatible_fi[4]; // weak
extern _strings str_Undecodable_[2]; // weak
extern int dword_418000; // weak
extern int dword_418004; // weak
extern char byte_418008; // weak
extern int dword_4180C8; // weak
extern int dword_4182A4[]; // weak
extern int dword_4186A8[]; // weak
extern _UNKNOWN unk_418780; // weak
extern char byte_418EAC[]; // weak
extern char aApetagex_[10]; // weak
extern _UNKNOWN unk_418EF4; // weak
extern int dword_418EF8[]; // weak
extern int dword_418EFC[]; // weak
extern _UNKNOWN unk_418F04; // weak
extern void *off_4193EC; // weak
extern void *off_4193F0; // weak
extern int *off_419424[7]; // weak
extern void *off_419440; // weak
extern void *off_41948C; // weak
extern void *off_419498; // weak
extern int *off_4194D0[6]; // weak
extern char *off_4194E8; // weak
extern int *off_4194F4[4]; // weak
extern void *off_419504; // weak
extern int *off_419510[13]; // weak
extern int *off_41953C[2]; // weak
extern int dword_41A000; // weak
extern int dword_41A014; // weak
extern int dword_41A018; // weak
extern int dword_41A030; // weak
extern int dword_41A038; // weak
extern int dword_41A03C; // weak
extern char byte_41A046; // weak
extern __int16 word_41A04C; // weak
extern __int16 word_41A218; // weak
extern __int16 word_41A3E4; // weak
extern int dword_41A5B4; // weak
extern HMODULE hModule; // idb
extern int dword_41A718; // weak
extern int dword_41A720; // weak
extern int dword_41A724; // weak
extern int dword_41A728; // weak
extern int dword_41A7F8; // weak
extern int dword_41A84C; // weak
extern int dword_41A850; // weak
extern int dword_41A854; // weak
extern int dword_41A858; // weak
extern int dword_41A85C; // weak
extern int dword_41A860; // weak
extern int dword_41A864; // weak
extern int dword_41A868; // weak
extern int dword_41A86C; // weak
extern int dword_41A870; // weak
extern int dword_41A874; // weak
extern int dword_41A878; // weak
extern int dword_41A87C; // weak
extern int dword_41A880; // weak
extern int dword_41A884; // weak
extern int dword_41A888; // weak
extern int dword_41A88C; // weak
extern int dword_41A890; // weak
extern int dword_41A894; // weak
extern int dword_41A898; // weak
extern int dword_41A89C; // weak
extern int dword_41A8A0; // weak
extern int dword_41A8A4; // weak
extern int dword_41A8A8; // weak
extern int dword_41A8AC; // weak
extern int dword_41A8B0; // weak
extern int dword_41A8B4; // weak
extern int dword_41A8B8; // weak
extern int dword_41A8BC; // weak
extern int dword_41A8C0; // weak
extern int dword_41A8C4; // weak
extern int dword_41A8C8; // weak
extern int dword_41A8CC; // weak
extern int dword_41A8D0; // weak
extern int dword_41A8D4; // weak
extern int dword_41A8D8; // weak
extern int dword_41A8DC; // weak
extern int dword_41A8E0; // weak
extern int dword_41A8E4; // weak
extern int dword_41A8E8; // weak
extern int dword_41A8EC; // weak
extern int dword_41A8F0; // weak
extern int dword_41A8F4; // weak
extern int dword_41A8F8; // weak
extern int dword_41A8FC; // weak

//-------------------------------------------------------------------------
// Function declarations

// void __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR *lpArguments);
// int RtlUnwind(); weak
// LPSTR GetCommandLineA(void);
// DWORD GetCurrentThreadId(void);
// int unknown_libname_2(void); weak
int __fastcall sub_4011F4(int result);
// int __fastcall System::__linkproc___GetMem(_DWORD); weak
// int __fastcall System::__linkproc___FreeMem(_DWORD); weak
// int __fastcall System::__linkproc___ReallocMem(_DWORD, _DWORD); weak
void __fastcall sub_402574(int a1, int a2);
// int __fastcall System::Error(_DWORD); weak
// int __fastcall System::__linkproc____IOTest(_DWORD); weak
// int __fastcall System::Move(_DWORD, _DWORD);
// int __fastcall System::UpCase(_DWORD); weak
// int __usercall System::__linkproc___ROUND<eax>(double<st0>); weak
// int __fastcall System::Flush(_DWORD); weak
// int __fastcall System::__linkproc___AStrCmp(_DWORD, _DWORD, _DWORD); weak
// int __fastcall System::__linkproc___FillChar(_DWORD, _DWORD, _DWORD); weak
// int unknown_libname_30(void); weak
// int unknown_libname_31(void); weak
// int __fastcall unknown_libname_32(_DWORD); weak
void __cdecl sub_402CA8();
int __fastcall sub_402CE0(int a1);
// int __fastcall unknown_libname_33(_DWORD, _DWORD); weak
// int __fastcall System::TObject::_TObject(_DWORD, _DWORD); weak
// int __fastcall System::TObject::Free(_DWORD); weak
// int System::TObject::CleanupInstance(void); weak
// _DWORD __cdecl System::__linkproc___ClassCreate();
// int __fastcall System::__linkproc___ClassDestroy(_DWORD); weak
// int __fastcall System::__linkproc___AfterConstruction(_DWORD); weak
// int System::__linkproc___BeforeDestruction(void); weak
// int __fastcall System::__linkproc___RaiseExcept(_DWORD); weak
// _DWORD __stdcall System::__linkproc___TryFinallyExit(_DWORD, _DWORD, _DWORD); weak
// int System::__linkproc___Halt0(void); weak
void __fastcall sub_403730(int a1);
// int __fastcall System::__linkproc___Assert(_DWORD, _DWORD);
// int __fastcall System::__linkproc___LStrClr(_DWORD); weak
// int __fastcall System::__linkproc___LStrArrayClr(_DWORD, _DWORD); weak
// int __fastcall System::__linkproc___LStrAsg(_DWORD, _DWORD); weak
// int __fastcall System::__linkproc___LStrFromPCharLen(_DWORD, _DWORD);
// int __fastcall unknown_libname_51(_DWORD, _DWORD); weak
// int __fastcall unknown_libname_53(_DWORD, _DWORD); weak
// int __fastcall unknown_libname_54(_DWORD, _DWORD, _DWORD); weak
int __fastcall sub_4039D8(int result);
// int __fastcall System::__linkproc___LStrCat3(_DWORD, _DWORD, _DWORD); weak
int __fastcall sub_403A98(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // weak
// int __fastcall System::__linkproc___LStrToPChar(_DWORD); weak
int __fastcall j_unknown_libname_55(_DWORD); // weak
int __fastcall sub_403D74(int a1, int a2);
int __fastcall sub_403D7C(int a1, int a2);
void __cdecl sub_403D84();
// int __fastcall System::_16829(_DWORD); weak
int sub_403DC4(void); // weak
int sub_403DCC(void); // weak
int __fastcall sub_403DD4(int a1);
void __cdecl sub_403DDC();
// _DWORD __stdcall unknown_libname_56(_DWORD, _DWORD); weak
// _DWORD __stdcall System::__linkproc____lldiv(_DWORD, _DWORD); weak
// _DWORD __stdcall System::__linkproc____llmod(_DWORD, _DWORD); weak
// int __fastcall System::FindResourceHInstance(_DWORD); weak
// _DWORD __stdcall System::Utf8ToUnicode(_DWORD); weak
// int __fastcall System::LoadResString(_DWORD, _DWORD); weak
void __cdecl sub_404768();
// HLOCAL __stdcall LocalAlloc_0(UINT uFlags, SIZE_T uBytes);
HLOCAL __fastcall sub_404820(SIZE_T uBytes);
signed int __cdecl sub_40482C();
int __cdecl sub_404984();
int __cdecl sub_4049BC();
void __cdecl sub_4049EC();
// BOOL __stdcall CloseHandle(HANDLE hObject);
// HANDLE __stdcall CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
// DWORD __stdcall GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);
// DWORD GetLastError(void);
// DWORD __stdcall GetModuleFileNameA_0(HMODULE hModule, LPSTR lpFilename, DWORD nSize);
// HANDLE __stdcall GetStdHandle_0(DWORD nStdHandle);
// BOOL __stdcall ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
// DWORD __stdcall SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
// DWORD __stdcall VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, DWORD dwLength);
// BOOL __stdcall WriteFile_0(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
// int __stdcall LoadStringA_0(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax);
// int __stdcall MessageBoxA_0(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
int __cdecl sub_404AB4();
void __cdecl sub_404AE4();
int __cdecl sub_404D64();
void __cdecl sub_404D94();
// int __usercall sub_405790<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __fastcall Sysutils::CompareMem(_DWORD, _DWORD);
// int __fastcall Sysutils::IntToStr(_DWORD, _DWORD); weak
// int __fastcall Sysutils::ExtractFileName(_DWORD, _DWORD); weak
// int __fastcall Sysutils::StrLen(_DWORD); weak
// int __fastcall Sysutils::StrLCopy(_DWORD, _DWORD);
int __fastcall sub_40598C(int a1, int a2);
int __cdecl sub_405A6C();
// unsigned int __usercall sub_405D0A<eax>(unsigned int result<eax>, int a2<ebp>);
// int __usercall sub_405E80<eax>(int a1<eax>, int a2<ebp>);
// char __usercall sub_4060EE<al>(char *a1<esi>);
// int sub_4060F7(void); weak
// char __usercall sub_406196<al>(int a1<ebp>, int a2<edi>, char *a3<esi>);
_DWORD loc_40619B(); // weak
// void __usercall sub_406200(int a1<ebp>, void *a2<edi>);
// void __usercall sub_406254(int a1<ebp>, void *a2<edi>);
// void __usercall sub_406263(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebp>);
// int __cdecl loc_4062C7(int, int, char); weak
// int __fastcall Sysutils::ExceptionErrorMessage(int, LPCVOID lpAddress, int, int); idb
BOOL __fastcall sub_406BF0(int a1, const void *a2);
// _DWORD __stdcall Sysutils::Exception::Exception(_DWORD, _DWORD); weak
// _DWORD __stdcall Sysutils::Exception::Exception(_DWORD, _DWORD); weak
int __cdecl sub_4070BC(int a1);
int __cdecl loc_407277(int); // weak
int __cdecl loc_40727E(int); // weak
// int __fastcall Sysutils::StrCharLength(LPCSTR lpsz); idb
int __fastcall sub_407580(int a1, int a2);
int __fastcall sub_408158(signed int a1, int a2);
// signed int __usercall sub_4083A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_4083DC<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
signed int __fastcall sub_408418(char a1);
int __cdecl sub_408428();
void __cdecl sub_408458();
int __fastcall sub_4084BC(int a1);
unsigned int __fastcall sub_408518(int a1, int a2);
int __fastcall sub_408568(int a1);
int __fastcall sub_408574(int a1);
int __fastcall sub_408580(int a1);
signed int __fastcall sub_40859C(int a1);
// int __usercall sub_4085B4<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_4085E4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
unsigned int __fastcall sub_408638(int a1);
unsigned int __fastcall sub_40864C(int a1, int a2);
unsigned int __fastcall sub_4086E0(int a1, int a2);
int __fastcall sub_408704(int a1);
int __fastcall sub_408758(int a1, int a2);
// char __usercall sub_408814<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_408834<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_408854(int a1, int a2);
int __cdecl sub_40886C();
void __cdecl sub_40889C();
void __cdecl sub_4088A4();
// int __userpurge sub_4088BD<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4);
int __stdcall loc_408926(int); // weak
// void __usercall sub_408950(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3);
// void __usercall sub_408955(unsigned int a1<ecx>, int a2<ebp>, int a3<edi>);
int loc_408968(); // weak
int __cdecl loc_4089D5(int, int, int, int, int, int); // weak
// int __usercall sub_4089F8<eax>(int a1<ecx>, int a2<ebx>, int a3<edi>, __m64 a4<mm0>, __m64 a5<mm1>, __m64 a6<mm2>, __m64 a7<mm3>, __m64 a8<mm4>);
void __fastcall sub_408B6B(int a1, int a2, int a3, int a4, unsigned int a5, int a6, int a7, int a8);
unsigned int __cdecl sub_408C41(int a1, int a2, int a3, int a4, int a5);
int __cdecl loc_408D94(int, int, int, int, int); // weak
int __cdecl loc_408DA1(int, int, int, int, int); // weak
int __cdecl loc_408E3E(int, int, int, int, int); // weak
int __cdecl loc_408E4C(int, int, int, int, int); // weak
// int __usercall sub_408E80<eax>(int a1<edi>, int a2<esi>, __m64 a3<mm4>);
void __cdecl sub_408ED4(int a1, int a2, int a3, int a4, unsigned int a5);
int __cdecl loc_408F01(int, int, int, int, int); // weak
int __cdecl sub_408F82(int a1, int a2, int a3, int a4, int a5);
signed int __cdecl sub_409173(int a1, int a2, int a3, int a4);
// int __usercall sub_4093C7<eax>(int result<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>);
// int __userpurge sub_409459<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4, unsigned __int16 a5);
int __cdecl sub_4094D0();
void __cdecl sub_409500();
// int __userpurge sub_409510<eax>(int result<eax>, int a2<edx>, unsigned int ecx0<ecx>, unsigned int a3, int a4);
// int __usercall sub_40957C<eax>(int result<eax>, int a2<edx>, char cl0<cl>);
int __cdecl sub_4095A4();
void __cdecl sub_4095D4();
int __fastcall sub_409634(int a1);
// int __fastcall unknown_libname_101(_DWORD); weak
// int __userpurge sub_409664<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, signed int a5);
int __cdecl sub_4096F8();
int __cdecl sub_40972C();
void __cdecl sub_40975C();
// signed int __usercall sub_409764<eax>(char _CF<cf>, char _ZF<zf>, char _SF<sf>, char _OF<of>, int a5<eax>, int a6<edx>);
int __cdecl sub_4097A4();
// signed int __usercall sub_4097EC<eax>(char a1<cf>, char a2<zf>, char a3<sf>, char a4<of>, int a5<eax>);
int __cdecl sub_409864();
void __cdecl sub_409894();
// signed int __usercall sub_4098FC<eax>(char a1<cf>, char a2<zf>, char a3<sf>, char a4<of>, int a5<eax>);
int __fastcall sub_409924(int result, int a2);
int __fastcall sub_409964(int a1, int a2);
int __fastcall sub_409980(int a1, char a2);
int __cdecl sub_4099CC();
void __cdecl sub_4099FC();
// int __usercall sub_409A04<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __fastcall sub_409AC8(int a1, signed int a2);
int __cdecl sub_409AD4();
void __cdecl sub_409B04();
int __fastcall sub_409B64(int a1, char a2);
int __fastcall sub_409BA0(int result);
// int __usercall sub_409BD0<eax>(int a1<eax>, int a2<edx>, unsigned int ecx0<ecx>);
int __fastcall sub_409C78(int a1);
char __fastcall sub_409CD8(int a1, int a2);
int __fastcall sub_409CFC(int a1, int a2);
int __cdecl sub_40A33C();
void __cdecl sub_40A36C();
unsigned int __fastcall sub_40A374(int a1, unsigned int a2);
// char __usercall sub_40A390<al>(int a1<eax>, unsigned int *a2<edx>, int ecx0<ecx>);
int __fastcall sub_40A3FC(int a1, signed int a2);
// unsigned int __usercall sub_40A40C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_40A4A0(int a1, int a2);
char __fastcall sub_40A4CC(int a1, int a2);
int __fastcall sub_40A524(int result);
int __fastcall sub_40A53C(int a1, int a2);
// int __usercall sub_40A5AC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40A610(int a1, int a2);
char __fastcall sub_40A714(int a1, int a2);
// char __usercall sub_40A760<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_40A824(int a1, int a2, int a3, unsigned __int64 a4);
// int __usercall sub_40A874<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_40A8CC(int a1, int a2);
// int __usercall sub_40A900<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40A97C(int a1, int a2);
int __fastcall sub_40A9B8(int a1, int a2);
int __cdecl sub_40AA1C();
void __cdecl sub_40AA4C();
// int __userpurge sub_40AA54<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// int __userpurge sub_40AA78<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// __int16 __userpurge sub_40AAB0<ax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4);
// int __userpurge sub_40AAF8<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4);
// char __userpurge sub_40AB58<al>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4);
// int __userpurge sub_40AC2C<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4);
// int __userpurge sub_40ACDC<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4);
int __fastcall sub_40AE7C(int a1, int a2, int a3);
int __cdecl sub_40AEA8();
void __cdecl sub_40AED8();
// int __userpurge sub_40AF4C<eax>(int a1<ebx>, int a2);
int __cdecl sub_40AFBC();
void __cdecl sub_40AFEC();
int __cdecl sub_40AFF4();
void __cdecl sub_40B024();
// int __usercall sub_40B02C<eax>(int result<eax>, int a2<edx>, unsigned int ecx0<ecx>);
int __fastcall sub_40B058(int result, signed int a2);
int __fastcall sub_40B06C(int result, signed int a2);
int __fastcall sub_40B0B4(int result, signed int a2);
// char __usercall sub_40B0F0<al>(char a1<al>, int a2<edx>, signed int ecx0<ecx>);
int __cdecl sub_40B11C();
void __cdecl sub_40B14C();
char __fastcall sub_40B154(int a1, int a2);
int __cdecl sub_40B190();
void __cdecl sub_40B1C0();
// int __userpurge sub_40B224<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, signed int a5);
int __fastcall sub_40B2E4(int result, signed int a2);
int __fastcall sub_40B394(int a1, int a2);
int __fastcall sub_40B3A4(int a1, int a2);
// char __usercall sub_40B3B4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_40B4B4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __cdecl sub_40B4E4();
void __cdecl sub_40B514();
int __fastcall sub_40B57C(void *a1, int a2);
char __fastcall sub_40B58C(signed int a1);
// char __userpurge sub_40B5B0<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// char __usercall sub_40B618<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_40B6FC<eax>(int a1<eax>, char a2<dl>, signed int ecx0<ecx>, signed int a3, int a4);
int __cdecl sub_40B760();
// char __userpurge sub_40B790<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4);
int __cdecl sub_40B91C();
void __cdecl sub_40B94C();
// int __userpurge sub_40B954<eax>(int result<eax>, int a2<edx>, char cl0<cl>, int a3, int a4);
// int __usercall sub_40B9D0<eax>(int result<eax>, signed int a2<edx>, char cl0<cl>);
// int __usercall sub_40BA90<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40BB1C(int a1);
int __fastcall sub_40BB50(int a1, int a2);
// int __fastcall unknown_libname_103(_DWORD); weak
// int __userpurge sub_40BB9C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, int a6);
char __fastcall sub_40BBF8(int a1, int a2);
// int __usercall sub_40BD2C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40BDC8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_40BE85<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
int __cdecl sub_40BEC0();
void __cdecl sub_40BEF0();
// int __userpurge sub_40BEF8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, char a4, int a5, int a6, int a7, int a8);
int __cdecl sub_40C04C();
void __cdecl sub_40C07C();
int __cdecl sub_40C084();
void __cdecl sub_40C0B4();
// int __userpurge sub_40C0BC<eax>(int a1<eax>, int a2<edx>, char cl0<cl>, char a3, int a4, int a5, int a6, int a7);
// int __usercall sub_40C210<eax>(int a1<eax>, int a2<ecx>);
int __fastcall sub_40C298(int a1, int a2);
// int __usercall sub_40C39C<eax>(int a1<eax>, int a2<edx>, int a3<ecx>);
int __cdecl sub_40C3B0();
void __cdecl sub_40C3E0();
int __cdecl sub_40C3E8();
void __cdecl sub_40C418();
// char __usercall sub_40C484<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40C698(unsigned int a1);
char __fastcall sub_40C6AC(int a1, int a2);
char __fastcall sub_40C6F4(int a1, int a2);
int __fastcall sub_40C740(int result);
int __fastcall sub_40C75C(int a1);
char __fastcall sub_40C768(int a1, int a2);
char __fastcall sub_40C7F8(int a1, int a2);
// int __usercall sub_40C828<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>);
// int __usercall sub_40C860<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>);
// int __usercall sub_40C8A0<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40C8F0<eax>(int a1<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>);
// int __userpurge sub_40C928<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// int __userpurge sub_40C9A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// void __userpurge sub_40CAE4(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<esi>, unsigned int a5, int a6);
// char __userpurge sub_40CCB8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// char __userpurge sub_40CD10<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4, int a5);
// int __userpurge sub_40CDF8<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4);
// int __userpurge sub_40CE50<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebx>, __m64 a5<mm5>, signed int a6, int a7);
int __cdecl sub_40CF2C();
void __cdecl sub_40CF5C();
// char __usercall sub_40CF64<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __cdecl sub_40CF94();
void __cdecl sub_40CFC4();
// int __usercall sub_40D034<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_40D078<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, const void *a5);
int __cdecl sub_40D15C();
char __fastcall sub_40D1AC(int a1);
// char __usercall sub_40D1F0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_40D234<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// char __userpurge sub_40D370<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// char __userpurge sub_40D3C4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// char __userpurge sub_40D500<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5);
// int __userpurge sub_40D608<eax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4);
// char __userpurge sub_40D63C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4);
// char __userpurge sub_40D6CC<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, signed int a5, int a6);
// char __userpurge sub_40D77C<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5);
int __cdecl sub_40D9FC();
void __cdecl sub_40DA2C();
int __fastcall sub_40DBAC(int result, unsigned __int8 a2);
char __cdecl sub_40DBF0();
char __fastcall sub_40DBF4(int a1);
char __fastcall sub_40DBFC(int a1);
int __cdecl sub_40DC08();
int __cdecl sub_40DC0C();
int __cdecl sub_40DC10();
char __fastcall sub_40DC14(int a1);
char __fastcall sub_40DC3C(int a1);
int __fastcall sub_40DC64(int a1, char a2);
int __cdecl sub_40DCBC();
int loc_40DCFF(); // weak
int loc_40DD06(); // weak
char __fastcall sub_40DD18(int a1);
char __fastcall sub_40DD34(int a1, int a2, int a3, __int64 a4);
char __fastcall sub_40DD98(int a1, int a2, int a3, int a4);
// int __usercall sub_40DDF0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_40DE2C(int a1);
int loc_40DE9E(); // weak
// int __usercall sub_40DEAC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
char __fastcall sub_40DF08(int a1, int a2, int a3, LONG lDistanceToMove, LONG a5);
// char __userpurge sub_40DF6C<al>(int a1<eax>, LPVOID lpBuffer<edx>, DWORD a3<ecx>, DWORD nNumberOfBytesToRead, int a4);
// char __userpurge sub_40DFB0<al>(int a1<eax>, LPCVOID lpBuffer<edx>, DWORD a3<ecx>, DWORD nNumberOfBytesToWrite, int a4);
bool __fastcall sub_40DFF4(int a1);
char __fastcall sub_40E008(int a1);
char __fastcall sub_40E01C(int a1);
char __cdecl sub_40E028();
// char __userpurge sub_40E02C<al>(int a1<eax>, int a2<edx>, unsigned __int8 cl0<cl>, unsigned __int8 a3, unsigned __int8 a4);
char __fastcall sub_40E0D4(int a1, int a2, unsigned __int8 a3);
char __fastcall sub_40E0E0(int a1, int a2);
char __fastcall sub_40E0FC(int a1, int a2, int a3, int a4, int a5);
// char __userpurge sub_40E130<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// char __userpurge sub_40E158<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
char __fastcall sub_40E188(int a1);
char __fastcall sub_40E18C(int a1);
char __fastcall sub_40E190(int a1);
// char __usercall sub_40E194<al>(int a1<eax>, const void *a2<edx>, int ecx0<ecx>);
int __cdecl sub_40E1F0();
void __cdecl sub_40E220();
int __cdecl sub_40E228();
void __cdecl sub_40E258();
char __fastcall sub_40E260(unsigned int a1, int a2);
// int __usercall sub_40E2B4<eax>(signed int a1<eax>, int a2<edx>, int a3<ebx>, int a4<edi>, int a5<esi>);
int loc_40E385(); // weak
int loc_40E38C(); // weak
char __fastcall sub_40E470(unsigned int a1, int a2);
int __cdecl sub_40E4A0();
void __cdecl sub_40E4D0();
int __fastcall sub_40E53C(int a1, int a2);
int __fastcall sub_40E548(int a1, int a2);
int __fastcall sub_40E550(int a1, int a2);
int __fastcall sub_40E55C(int a1, int a2);
int __fastcall sub_40E568(int a1, int a2);
// int __usercall sub_40E570<eax>(int a1<edx>, int a2<ecx>);
// int __usercall sub_40E57C<eax>(int a1<edx>, int a2<ecx>);
// int __usercall sub_40E584<eax>(int a1<edx>, int a2<ecx>);
// int unknown_libname_107(); weak
// void __usercall sub_40E598(int a1<edx>, int a2<ecx>);
// char __usercall sub_40E59C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// __int16 __usercall sub_40E5D0<ax>(int a1<edx>, int a2<ecx>);
// int __usercall sub_40E5DC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40E5E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40E600<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>);
int loc_40E655(); // weak
// int __usercall sub_40E6A8<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40E6F0(int a1, signed int a2);
int __fastcall sub_40E728(_DWORD, _DWORD); // weak
int __fastcall sub_40E7BC(int result, int a2);
int __fastcall sub_40E8A0(int result, int a2);
int __fastcall sub_40E960(int a1, int a2);
// int __usercall sub_40E98C<eax>(int a1<eax>, int a2<edx>, int a3<ecx>);
// unsigned int __usercall sub_40EA7C<eax>(int a1<eax>, unsigned int a2<edx>, signed int ecx0<ecx>);
// char __userpurge sub_40EBCC<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4, int a5, int (__fastcall *a6)(_DWORD, _DWORD));
int __fastcall sub_40EC6C(int a1, int a2);
// int __userpurge sub_40ECF0<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, char a5);
int __cdecl sub_40EEEC();
// int __fastcall Actnmenus::TCustomActionPopupMenu::CloseMenu(_DWORD); weak
int __cdecl sub_40EF3C();
void __cdecl sub_40EF6C();
void __cdecl sub_40F088();
int __fastcall sub_40F214(int result);
int __fastcall sub_40F25C(int a1, char a2);
int __cdecl sub_40F2A8();
int __fastcall sub_40F2E8(int result, int a2);
// int __usercall sub_40F2EC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40F348<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int unknown_libname_108(); weak
// char __userpurge sub_40F3C8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
int __fastcall sub_40F430(int a1, char a2);
int __fastcall sub_40F478(int a1, int a2);
int __fastcall sub_40F48C(int a1, int a2);
// signed int __usercall sub_40F494<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40F4F8(int result, signed int a2);
char __fastcall sub_40F510(int a1);
int __fastcall sub_40F518(int a1, char a2);
int __cdecl sub_40F564();
// int __usercall sub_40F594<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __fastcall sub_40F708(int a1);
signed int __fastcall sub_40F720(int a1);
char __fastcall sub_40F73C(int a1);
int __fastcall sub_40F740(int a1, void *a2);
// int __usercall sub_40F784<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_40F7F4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_40F860<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// int __userpurge sub_40F90C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// int __userpurge sub_40F9A0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, signed int a5, int a6, char a7);
int __stdcall loc_40FCC9(int, int, int, char); // weak
int __stdcall loc_40FCD0(int, int, int, char); // weak
int __stdcall loc_40FCF9(int, int, int, char); // weak
int __stdcall loc_40FD00(int, int, int, char); // weak
int __fastcall sub_40FD0C(int result, unsigned __int8 a2);
char __fastcall sub_40FD18(int a1);
// char __usercall sub_40FD20<al>(int a1<eax>, int a2<edx>, unsigned __int8 cl0<cl>);
char __fastcall sub_40FD70(int a1);
// char __userpurge sub_40FDA8<al>(int a1<eax>, unsigned __int8 a2<dl>, int ecx0<ecx>, int a3, __int64 a4);
char __fastcall sub_40FE30(int a1, int a2, int a3, __int64 a4);
int __stdcall loc_4100A1(__int64); // weak
int __stdcall loc_4100A8(__int64); // weak
int __stdcall loc_4100BE(__int64); // weak
int __stdcall loc_4100C5(__int64); // weak
char __fastcall sub_4100D8(int a1, int a2, int a3, __int64 a4, __int64 a5);
int __fastcall sub_410150(int result);
int __fastcall sub_4101AC(int a1, char a2);
// int __usercall sub_4101E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __cdecl sub_4103A4();
void __cdecl sub_4103D4();
int __fastcall sub_4105C0(int a1, int a2);
signed int __fastcall sub_410640(int a1);
int __fastcall sub_410718(int a1, int a2);
char __fastcall sub_410784(int a1, int a2);
char __fastcall sub_4107E0(int a1, int a2);
char __fastcall sub_410840(int a1);
// char __userpurge sub_410A44<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
int __fastcall sub_410AF8(int a1, int a2);
int __fastcall sub_410B8C(int a1, int a2);
char __fastcall sub_410CAC(int a1, int a2);
char __fastcall sub_410CD0(int a1, int a2);
int __fastcall sub_410CF4(int result, int a2);
int __fastcall sub_410D00(int a1);
unsigned int __fastcall sub_410D0C(int a1);
char __fastcall sub_410D48(int a1);
// int __fastcall unknown_libname_109(_DWORD, _DWORD);
int __cdecl sub_410DB8();
// signed int __userpurge sub_410DE8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, __int64 a6);
char __fastcall sub_410E3C(int a1, int a2);
int __fastcall sub_410F14(int a1, signed int a2);
int __fastcall sub_411078(int a1);
__int64 __fastcall sub_411090(int a1);
char __fastcall sub_4110C4(int a1);
// char __userpurge sub_411168<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
int __fastcall sub_411204(int result);
int __fastcall sub_411218(int result);
char __fastcall sub_411220(int a1);
int __fastcall sub_41123C(int result, int a2);
int __fastcall sub_411240(int result);
int loc_4112A6(); // weak
int loc_4112AD(); // weak
char __fastcall sub_4112B4(int a1, int a2);
// char __userpurge sub_411338<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, __int64 a5, int a6, int a7);
int __stdcall loc_4113F7(int, __int64, int, int); // weak
int __stdcall loc_4113FE(int, __int64, int, int); // weak
// char __userpurge sub_41140C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, __int64 a5);
char __fastcall sub_411484(int a1, void *a2, int a3, __int64 a4);
char __fastcall sub_411560(int a1);
__int64 __fastcall sub_411568(int a1);
int __fastcall sub_411590(int a1);
int __fastcall sub_4115A4(int a1, char a2);
int __cdecl sub_41162C();
signed int __fastcall sub_41167C(int a1, int a2);
int __fastcall sub_411A0C(int result);
char __fastcall sub_411A40(int a1, int a2);
char __fastcall sub_411A80(int a1, int a2);
char __fastcall sub_411AC0(int a1, signed int *a2);
// char __usercall sub_411AE4<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
char __fastcall sub_411B48(int a1, int a2);
char __fastcall sub_411B54(int a1, int a2);
int __fastcall sub_411B60(int a1, signed int a2);
int __fastcall sub_411B78(int a1, char a2);
// signed int __usercall sub_411BF8<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
signed int __fastcall sub_411C64(int a1, signed int *a2);
// char __usercall sub_411CAC<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
// char __usercall sub_411D28<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __fastcall sub_411DB4(int result, int a2);
char __fastcall sub_411DC0(int a1);
// char __userpurge sub_411DE4<al>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, int a3, signed int *a4, int a5, __int64 a6, signed __int64 a7);
char __fastcall sub_411F64(int a1, unsigned int a2);
// char __userpurge sub_412010<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4, __int64 a5);
// char __usercall sub_412058<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
char __fastcall sub_4123B8(int a1);
char __fastcall sub_4123C0(int a1);
int __fastcall sub_4123C8(int a1, char a2);
int __cdecl sub_412404();
// int __userpurge sub_412430<eax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10);
int __fastcall sub_412518(int a1);
char __fastcall sub_41253C(int a1, signed int *a2);
// int __usercall sub_41255C<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __cdecl sub_412630();
void __cdecl sub_412660();
int __cdecl sub_412668();
void __cdecl sub_412698();
// int __userpurge sub_4126A0<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, char a4);
// int __userpurge sub_4126D8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
// int __usercall sub_4126F8<eax>(int result<eax>, unsigned int a2<edx>, char cl0<cl>);
// int __userpurge sub_412725<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4);
int __cdecl sub_4127D8();
void __cdecl sub_412808();
int __fastcall sub_4128CC(int a1);
// int __usercall sub_4129A8<eax>(signed int a1<edx>, int a2<ecx>, int a3<ebx>);
// int __userpurge sub_4129EC<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5, int a6, int a7, int a8);
signed int __fastcall sub_412AC4(int a1, signed int a2);
// int __usercall sub_412B30<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>);
// int __userpurge sub_412B84<eax>(int a1<eax>, signed int a2<edx>, char cl0<cl>, int a3, int a4);
int __fastcall sub_412C24(int a1, int a2);
int __fastcall sub_412C48(int a1, int a2);
int __cdecl sub_412CAC();
void __cdecl sub_412CDC();
int *__fastcall sub_412CE4(int *a1, int a2);
int __fastcall sub_412D38(int result, signed int a2);
int __fastcall sub_412D84(int result);
int __cdecl sub_412DAC();
void __cdecl sub_412DDC();
int __cdecl sub_412DE4();
void __cdecl sub_412E14();
signed int __fastcall sub_412E7C(int a1);
bool __fastcall sub_412E8C(signed int a1);
int __fastcall sub_412EB0(int a1, unsigned __int8 a2);
// char __userpurge sub_412F5C<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
int __fastcall sub_413060(int a1, unsigned __int8 a2);
int __fastcall sub_4130B4(void *a1, int a2);
char __fastcall sub_4130C4(signed int a1, int a2);
int __fastcall sub_413120(int a1, unsigned __int8 a2);
// char __userpurge sub_413140<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// char __usercall sub_4131B8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_413244<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_413304<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __usercall sub_4133F0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
signed int __fastcall sub_413440(int a1);
// int __userpurge sub_413454<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5);
int __cdecl sub_4134E8();
// char __userpurge sub_413520<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4);
int __cdecl sub_413749(int a1, int a2, int a3, int a4, int a5);
int __cdecl sub_41395C();
void __cdecl sub_41398C();
char __fastcall sub_413994(int a1, int a2);
int __fastcall sub_413A04(int a1, int a2);
// int __fastcall unknown_libname_111(_DWORD); weak
// int __userpurge sub_413A40<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
char __fastcall sub_413AB8(int a1, int a2);
char __fastcall sub_413B48(int a1, int a2);
// int __usercall sub_413C18<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_413C98<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __cdecl sub_413D34();
void __cdecl sub_413D64();
// int __userpurge sub_413D6C<eax>(int a1<eax>, signed int a2<edx>, char cl0<cl>, char a3, int a4, int a5, unsigned int a6, int a7);
// int __usercall sub_413EB0<eax>(int a1<eax>, int a2<ecx>);
// int __usercall sub_413F38<eax>(int a1<eax>, int a2<ecx>);
// int __usercall sub_414004<eax>(int a1<eax>, int a2<edx>, int a3<ecx>);
// signed int __usercall sub_41401C<eax>(__int64 a1<edx:eax>, int a2<ebp>, int a3<esi>);
// int __usercall sub_414050<eax>(__int64 a1<edx:eax>, int a2<ebp>, int a3<esi>);
signed int __cdecl sub_414078(int a1, int a2, int a3, int a4, int a5);
void __cdecl sub_414234(int a1, unsigned int a2, int a3, int a4, int a5);
void __cdecl sub_4142F5();
void __fastcall sub_41434C(int a1, int a2);
int sub_4143AC(); // weak
int __cdecl sub_4144A8();
void __cdecl sub_4144D8();
char __fastcall sub_4144E0(int a1, int a2);
int __cdecl sub_414574();
void __cdecl sub_4145A4();
// int __userpurge sub_414610<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
int __fastcall sub_414628(int a1);
int __fastcall sub_414638(int a1);
char __fastcall sub_414644(int a1, int a2);
// int __usercall sub_4146A4<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>);
// int __usercall sub_4146D4<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>);
// int __usercall sub_41470C<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_41475C<eax>(int a1<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>);
// signed int __userpurge sub_414794<eax>(signed int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// int __userpurge sub_414858<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// void __userpurge sub_414978(int a1<eax>, int a2<edx>, int a3<ecx>, signed int a4<esi>, unsigned int a5, int a6);
// char __userpurge sub_414B30<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
// int __userpurge sub_414C28<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4);
// int __userpurge sub_414C80<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebx>, __m64 a5<mm5>, int a6, int a7, int a8);
// int __usercall sub_414D37<eax>(int result<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>);
void __cdecl sub_414DB8(int a1, int a2, unsigned int a3, int a4);
int __cdecl sub_414ED8();
void __cdecl sub_414F08();
int __fastcall sub_414F70(int a1);
// int __fastcall unknown_libname_112(_DWORD); weak
char __fastcall sub_414F8C(int a1, int a2);
// _DWORD __stdcall unknown_libname_113(_DWORD); weak
// int __userpurge sub_415018<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4);
int __cdecl sub_415048();
void __cdecl sub_415078();
// int __usercall sub_4150EC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __userpurge sub_41512C<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5, int a6);
int __cdecl sub_415250();
char __fastcall sub_4152D4(int a1);
char __fastcall sub_415318(int a1);
// char __usercall sub_415380<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_4153C0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_415418<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// int __usercall sub_4154D8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __userpurge sub_41552C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, int a6);
// char __userpurge sub_415654<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5, int a6);
// int *__userpurge sub_41578C<eax>(int a1<eax>, int *a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, char a6);
// char __userpurge sub_4157D4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4);
// char __userpurge sub_415888<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, signed int a5, int a6);
int __cdecl sub_415978();
void __cdecl sub_4159A8();
int __fastcall sub_415A28(int result);
int __fastcall sub_415A4C(int a1);
int __fastcall sub_415A6C(_DWORD, _DWORD); // weak
int __fastcall sub_415A84(int a1, int a2, int a3, int a4, int a5, int a6, int a7);
char __fastcall sub_415ACC(int a1);
int __fastcall sub_415C1C(int a1);
// char __usercall sub_415C68<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_415CDC(int a1);
int __fastcall sub_415DF0(int a1);
char __fastcall sub_415E14(int a1);
// char __usercall sub_415EB4<al>(int a1<eax>, signed int *a2<edx>, int ecx0<ecx>);
char __fastcall sub_415FFC(int a1);
char __fastcall sub_416054(int a1, int a2);
// int __usercall sub_4161A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
// char __userpurge sub_4161E0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5);
char __fastcall sub_416278(int a1);
char __fastcall sub_4162E4(int a1);
// int unknown_libname_114(void); weak
// int __userpurge sub_4162F8<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, int a5, int a6, int a7);
// int __userpurge sub_4163B0<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, int a5, int a6, int a7, int a8);
// int __usercall sub_4164C8<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>);
int __fastcall sub_416614(int a1, void *a2);
int __fastcall sub_416644(int a1, void *a2);
signed int __fastcall sub_416690(int a1);
signed __int64 __fastcall sub_4166B0(int a1);
signed int __fastcall sub_4166E8(int a1);
int __fastcall sub_416700(int a1, int a2, int a3, __int64 a4);
// int __userpurge sub_4168E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4);
int __fastcall sub_416B8C(int a1, int a2);
// int __usercall sub_416C2C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>);
int __fastcall sub_416CC0(int a1, int a2);
int __fastcall sub_416D30(int a1, int a2);
int __cdecl sub_416DD0();
void __cdecl sub_416E00();
signed int __cdecl tak_GetLibraryVersion(int a1, int a2);
// int __usercall tak_GetCodecName<eax>(int a1<ebx>, int a2<edi>, int a3<esi>, signed int a4, int a5, int a6);
int __cdecl loc_416E80(int, int, int); // weak
int __cdecl loc_416E87(int, int, int); // weak
bool __cdecl tak_GetWaveExtensibleSpeakerMask(int a1, int a2);
int __cdecl tak_SSD_Create_FromFile(int a1, int a2, int a3, int a4);
int __cdecl tak_SSD_Create_FromStream(int a1, int a2, int a3, int a4, int a5);
int __cdecl tak_SSD_Destroy(int a1);
bool __cdecl tak_SSD_Valid(int a1);
signed int __cdecl tak_SSD_State(int a1);
int __cdecl tak_SSD_GetStateInfo(int a1, void *a2);
// int __usercall tak_SSD_GetErrorString<eax>(int a1<ebx>, signed int a2, int a3, int a4);
int __cdecl loc_41700A(int, int, int); // weak
int __cdecl loc_417011(int, int, int); // weak
int __cdecl tak_SSD_GetStreamInfo(int a1, int a2);
int __cdecl tak_SSD_GetStreamInfo_V22(int a1, void *a2);
signed int __cdecl tak_SSD_GetFrameSize(int a1);
int __fastcall tak_SSD_Seek(int a1, int a2, int a3, int a4, __int64 a5);
int __cdecl tak_SSD_ReadAudio(int a1, int a2, unsigned int a3, int a4);
signed __int64 __cdecl tak_SSD_GetReadPos(int a1);
signed int __cdecl tak_SSD_GetCurFrameBitRate(int a1);
int __cdecl tak_SSD_GetSimpleWaveDataDesc(int a1, int a2);
int __cdecl tak_SSD_ReadSimpleWaveData(int a1, int a2, int a3);
int __cdecl tak_SSD_GetEncoderInfo(int a1, int a2);
int __cdecl tak_SSD_GetMD5(int a1, int a2);
int __cdecl tak_SSD_GetAPEv2Tag(int a1);
bool __cdecl tak_APE_Valid(int a1);
signed int __cdecl tak_APE_State(int a1);
// int __usercall tak_APE_GetErrorString<eax>(int a1<ebx>, signed int a2, int a3, int a4);
int __cdecl loc_41724E(int, int, int); // weak
int __cdecl loc_417255(int, int, int); // weak
bool __cdecl tak_APE_ReadOnly(int a1);
int __cdecl tak_APE_GetDesc(int a1, void *a2);
signed int __cdecl tak_APE_GetItemNum(int a1);
int __cdecl tak_APE_GetIndexOfKey(int a1, int a2, int a3);
int __cdecl tak_APE_GetItemDesc(int a1, int a2, int a3);
int __cdecl tak_APE_GetItemKey(int a1, int a2, int a3, int a4, int a5);
int __cdecl tak_APE_GetItemValue(int a1, int a2, int a3, int a4, int a5);
int __cdecl tak_APE_GetTextItemValueAsAnsi(int a1, int a2, int a3, char a4, signed int a5, int a6, int a7);


//----- (004011F4) --------------------------------------------------------
int __fastcall sub_4011F4(int result)
{
  *(_DWORD *)result = result;
  *(_DWORD *)(result + 4) = result;
  return result;
}

//----- (00402574) --------------------------------------------------------
void __fastcall sub_402574(int a1, int a2)
{
  dword_418004 = a2;
  sub_403730(a1);
}
// 418004: using guessed type int dword_418004;

//----- (00402CA8) --------------------------------------------------------
void __cdecl sub_402CA8()
{
  System::Error(4);
}
// 4025CC: using guessed type int __fastcall System__Error(_DWORD);

//----- (00402CE0) --------------------------------------------------------
int __fastcall sub_402CE0(int a1)
{
  int v1; // ebx@1

  v1 = a1;
  System::TObject::CleanupInstance();
  return System::__linkproc___FreeMem(v1);
}
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);
// 402D90: using guessed type int System__TObject__CleanupInstance(void);

//----- (00403730) --------------------------------------------------------
void __fastcall sub_403730(int a1)
{
  dword_418000 = a1;
  System::__linkproc___Halt0();
}
// 403658: using guessed type int System____linkproc__ Halt0(void);
// 418000: using guessed type int dword_418000;

//----- (0040373C) --------------------------------------------------------
#error "FFFFFFFF: positive sp value has been found (funcsize=0)"

//----- (004039D8) --------------------------------------------------------
int __fastcall sub_4039D8(int result)
{
  if ( result )
    result = *(_DWORD *)(result - 4);
  return result;
}

//----- (00403A98) --------------------------------------------------------
#error "403B13: positive sp value has been found (funcsize=59)"

//----- (00403D74) --------------------------------------------------------
int __fastcall sub_403D74(int a1, int a2)
{
  return sub_403D7C(a1, a2);
}

//----- (00403D7C) --------------------------------------------------------
int __fastcall sub_403D7C(int a1, int a2)
{
  return unknown_libname_53(a2, a1);
}
// 403970: using guessed type int __fastcall unknown_libname_53(_DWORD, _DWORD);

//----- (00403D84) --------------------------------------------------------
void __cdecl sub_403D84()
{
  System::Error(16);
}
// 4025CC: using guessed type int __fastcall System__Error(_DWORD);

//----- (00403DD4) --------------------------------------------------------
int __fastcall sub_403DD4(int a1)
{
  int v1; // ST00_4@1

  v1 = a1;
  sub_403DC4();
  return v1;
}
// 403DC4: using guessed type int sub_403DC4(void);

//----- (00403DDC) --------------------------------------------------------
void __cdecl sub_403DDC()
{
  System::Error(17);
}
// 4025CC: using guessed type int __fastcall System__Error(_DWORD);

//----- (00404768) --------------------------------------------------------
void __cdecl sub_404768()
{
  char v0; // cf@1
  int v1; // eax@2
  int v2; // eax@4

  v0 = (unsigned int)dword_41A5B4-- < 1;
  if ( v0 )
  {
    byte_418008 = 2;
    dword_41A014 = (int)RaiseException;
    dword_41A018 = (int)RtlUnwind;
    byte_41A046 = 2;
    dword_41A000 = (int)sub_403DDC;
    v1 = unknown_libname_30();
    if ( (_BYTE)v1 )
      v1 = unknown_libname_31();
    v2 = unknown_libname_32(v1);
    word_41A04C = -10320;
    word_41A218 = -10320;
    word_41A3E4 = -10320;
    System::_16829(v2);
    dword_41A03C = (int)GetCommandLineA();
    dword_41A038 = unknown_libname_2();
    dword_41A030 = GetCurrentThreadId();
  }
}
// 401070: using guessed type int RtlUnwind();
// 401140: using guessed type int unknown_libname_2(void);
// 402BA8: using guessed type int unknown_libname_30(void);
// 402BD8: using guessed type int unknown_libname_31(void);
// 402C9C: using guessed type int __fastcall unknown_libname_32(_DWORD);
// 403DA4: using guessed type int __fastcall System___16829(_DWORD);
// 418008: using guessed type char byte_418008;
// 41A000: using guessed type int dword_41A000;
// 41A014: using guessed type int dword_41A014;
// 41A018: using guessed type int dword_41A018;
// 41A030: using guessed type int dword_41A030;
// 41A038: using guessed type int dword_41A038;
// 41A03C: using guessed type int dword_41A03C;
// 41A046: using guessed type char byte_41A046;
// 41A04C: using guessed type __int16 word_41A04C;
// 41A218: using guessed type __int16 word_41A218;
// 41A3E4: using guessed type __int16 word_41A3E4;
// 41A5B4: using guessed type int dword_41A5B4;

//----- (00404820) --------------------------------------------------------
HLOCAL __fastcall sub_404820(SIZE_T uBytes)
{
  return LocalAlloc_0(0x40u, uBytes);
}

//----- (0040482C) --------------------------------------------------------
signed int __cdecl sub_40482C()
{
  return 8;
}

//----- (00404984) --------------------------------------------------------
int __cdecl sub_404984()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A718;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A718: using guessed type int dword_41A718;

//----- (004049BC) --------------------------------------------------------
int __cdecl sub_4049BC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A720;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A720: using guessed type int dword_41A720;

//----- (004049EC) --------------------------------------------------------
void __cdecl sub_4049EC()
{
  --dword_41A720;
}
// 41A720: using guessed type int dword_41A720;

//----- (00404AB4) --------------------------------------------------------
int __cdecl sub_404AB4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A724;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A724: using guessed type int dword_41A724;

//----- (00404AE4) --------------------------------------------------------
void __cdecl sub_404AE4()
{
  --dword_41A724;
}
// 41A724: using guessed type int dword_41A724;

//----- (00404D64) --------------------------------------------------------
int __cdecl sub_404D64()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A728;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A728: using guessed type int dword_41A728;

//----- (00404D94) --------------------------------------------------------
void __cdecl sub_404D94()
{
  --dword_41A728;
}
// 41A728: using guessed type int dword_41A728;

//----- (00405790) --------------------------------------------------------
int __usercall sub_405790<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // eax@1

  v3 = Sysutils::Exception::Exception(ecx0, a2);
  return System::__linkproc___RaiseExcept(v3);
}
// 403120: using guessed type int __fastcall System____linkproc__ RaiseExcept(_DWORD);
// 406DA0: using guessed type _DWORD __stdcall Sysutils__Exception__Exception(_DWORD, _DWORD);

//----- (0040598C) --------------------------------------------------------
int __fastcall sub_40598C(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // eax@1

  v2 = a2;
  v3 = a1;
  sub_4039D8(a2);
  v4 = System::__linkproc___LStrToPChar(v2);
  return Sysutils::StrLCopy(v3, v4);
}
// 403B1C: using guessed type int __fastcall System____linkproc__ LStrToPChar(_DWORD);

//----- (00405A6C) --------------------------------------------------------
int __cdecl sub_405A6C()
{
  return sub_403DCC();
}
// 403DCC: using guessed type int sub_403DCC(void);

//----- (00405D0A) --------------------------------------------------------
unsigned int __usercall sub_405D0A<eax>(unsigned int result<eax>, int a2<ebp>)
{
  int v2; // esi@1
  unsigned int v3; // ett@2
  unsigned __int8 v4; // dl@2
  int v5; // ecx@5
  unsigned int v6; // edx@5
  unsigned __int8 v7; // cf@6
  int v8; // edx@6

  v2 = a2 - 97;
  do
  {
    v3 = result;
    result /= 0xAu;
    v4 = v3 % 0xA + 48;
    if ( v4 >= 0x3Au )
      v4 += 7;
    --v2;
    *(_BYTE *)v2 = v4;
  }
  while ( result );
  v5 = a2 - 97 - v2;
  v6 = *(_DWORD *)(a2 - 36);
  if ( v6 <= 0x10 )
  {
    v7 = v6 < v5;
    v8 = v6 - v5;
    if ( !(v7 | v8 == 0) )
    {
      LOBYTE(result) = 48;
      do
      {
        --v2;
        *(_BYTE *)v2 = 48;
        --v8;
      }
      while ( v8 );
    }
  }
  return result;
}

//----- (00405E80) --------------------------------------------------------
int __usercall sub_405E80<eax>(int a1<eax>, int a2<ebp>)
{
  int v2; // ST00_4@1

  v2 = a1;
  System::__linkproc___LStrClr(a2 - 20);
  return v2;
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);

//----- (004060EE) --------------------------------------------------------
char __usercall sub_4060EE<al>(char *a1<esi>)
{
  char result; // al@1

  result = *a1;
  if ( !*a1 )
    result = 48;
  return result;
}

//----- (00406196) --------------------------------------------------------
char __usercall sub_406196<al>(int a1<ebp>, int a2<edi>, char *a3<esi>)
{
  signed int v3; // edx@1
  int v4; // ecx@3
  char result; // al@4
  int v6; // ebx@5
  int v7; // ecx@7
  char v8; // al@9
  char v9; // al@12
  int v10; // edx@18

  sub_4060F7();
  v3 = *(_DWORD *)(a1 + 8);
  if ( (unsigned int)v3 >= 0x12 )
    v3 = 18;
  v4 = *(_WORD *)(a1 - 44);
  if ( v4 > 0 )
  {
    v6 = 0;
    if ( *(_BYTE *)(a1 + 16) != 2 )
    {
      LOBYTE(v6) = (unsigned __int16)(v4 - 1) % 3u;
      ++v6;
    }
    while ( 1 )
    {
      result = sub_4060EE(a3);
      *(_BYTE *)a2++ = result;
      v4 = v7 - 1;
      if ( !v4 )
        break;
      --v6;
      if ( !v6 )
      {
        v8 = *(_BYTE *)(a1 - 6);
        if ( v8 )
        {
          *(_BYTE *)a2++ = v8;
          LOBYTE(v6) = 3;
        }
      }
    }
  }
  else
  {
    result = 48;
    *(_BYTE *)a2++ = 48;
  }
  if ( v3 )
  {
    v9 = *(_BYTE *)(a1 - 5);
    if ( v9 )
      *(_BYTE *)a2++ = v9;
    if ( v4 )
    {
      result = 48;
      while ( 1 )
      {
        *(_BYTE *)a2++ = 48;
        --v3;
        if ( !v3 )
          break;
        ++v4;
        if ( !v4 )
          goto LABEL_18;
      }
    }
    else
    {
      do
      {
LABEL_18:
        result = sub_4060EE(a3);
        *(_BYTE *)a2++ = result;
      }
      while ( v10 != 1 );
    }
  }
  return result;
}
// 4060F7: using guessed type int sub_4060F7(void);

//----- (00406200) --------------------------------------------------------
void __usercall sub_406200(int a1<ebp>, void *a2<edi>)
{
  int v2; // ebx@1
  signed __int16 v3; // cx@1
  char *v4; // ebx@5
  int v5; // ecx@5
  char v6; // al@6
  int v7; // [sp-4h] [bp-4h]@7

  v2 = *(_BYTE *)(a1 - 13);
  v3 = 3;
  if ( *(_BYTE *)(a1 - 42) )
  {
    LOBYTE(v2) = *(_BYTE *)(a1 - 14);
    v3 = 1039;
  }
  if ( (unsigned __int8)v2 > (unsigned __int8)v3 )
    LOBYTE(v2) = v3;
  LOBYTE(v2) = HIBYTE(v3) + v2;
  v4 = (char *)sub_406263 + 5 * v2 + *(_DWORD *)(a1 - 20);
  v5 = 5;
  do
  {
    v6 = *v4;
    if ( *v4 == 64 )
      break;
    v7 = v5;
    if ( v6 == 36 )
    {
      sub_406254(a1, a2);
    }
    else
    {
      if ( v6 == 42 )
      {
        loc_40619B();
      }
      else
      {
        *(_BYTE *)a2 = v6;
        a2 = (char *)a2 + 1;
      }
    }
    ++v4;
    v5 = v7 - 1;
  }
  while ( v7 != 1 );
}
// 40619B: using guessed type _DWORD loc_40619B();

//----- (00406254) --------------------------------------------------------
void __usercall sub_406254(int a1<ebp>, void *a2<edi>)
{
  const void *v2; // esi@1

  v2 = *(const void **)(a1 - 12);
  if ( v2 )
    memcpy(a2, v2, *((_DWORD *)v2 - 1));
}

//----- (00406263) --------------------------------------------------------
void __usercall sub_406263(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebp>)
{
  int v4; // eax@1

  LOBYTE(a1) = a1 & 0x2A;
  v4 = a1 + 3;
  BYTE1(v4) -= *(_BYTE *)(3 * v4);
  v4 += 2;
  LOBYTE(v4) = v4 & 0x20;
  LOBYTE(v4) = v4 - *(_BYTE *)(v4 + 64);
  BYTE1(v4) -= *(_BYTE *)v4;
  LOBYTE(v4) = v4 & 0x40;
  ++v4;
  *(_BYTE *)(a2 + a4) -= BYTE1(v4);
  *(_DWORD *)(v4 + 45) -= v4;
  LOBYTE(v4) = v4 & 0x2A;
  v4 += 2;
  LOBYTE(v4) = v4 & 0x2D;
  LOBYTE(v4) = (v4 - *(_BYTE *)(v4 + 64)) & 0x2A;
  v4 -= 707280960;
  LOBYTE(v4) = v4 & 0x29;
  v4 -= 1077945385;
  LOBYTE(v4) = v4 & 0x2D;
  v4 += 2142355380;
  BYTE1(v4) -= *(_BYTE *)v4;
  LOBYTE(v4) = v4 & 0x2D;
  ++v4;
  LOBYTE(v4) = v4 & 0x20;
  BYTE1(a3) = BYTE1(a3) - v2A404024 - v2D202440;
  LOBYTE(v4) = v4 - *(_BYTE *)(v4 + 42);
  BYTE1(a3) -= *(_BYTE *)a3;
  *(_BYTE *)a2 -= BYTE1(a3);
  *(_BYTE *)(a3 + a4) &= (unsigned __int16)(v4 - 9248) >> 8;
  JUMPOUT(*(int *)loc_4062C7);
}
// 4062C7: using guessed type int __cdecl loc_4062C7(int, int, char);

//----- (00406BF0) --------------------------------------------------------
BOOL __fastcall sub_406BF0(int a1, const void *a2)
{
  int v2; // eax@2
  DWORD v3; // ST08_4@2
  HANDLE v4; // eax@2
  HANDLE v5; // eax@2
  BOOL result; // eax@2
  UINT v7; // ST08_4@3
  HINSTANCE v8; // eax@3
  DWORD NumberOfBytesWritten; // [sp+0h] [bp-444h]@1
  const CHAR Caption; // [sp+4h] [bp-440h]@3
  char Buffer; // [sp+44h] [bp-400h]@2

  Sysutils::ExceptionErrorMessage(a1, a2, 1024, NumberOfBytesWritten);
  if ( *off_4194E8 )
  {
    v2 = System::Flush(off_419440);
    System::__linkproc____IOTest(v2);
    v3 = Sysutils::StrLen(&Buffer);
    v4 = GetStdHandle_0(0xFFFFFFF5u);
    WriteFile_0(v4, &Buffer, v3, &NumberOfBytesWritten, 0);
    v5 = GetStdHandle_0(0xFFFFFFF5u);
    result = WriteFile_0(v5, &str____0[1], 2u, &NumberOfBytesWritten, 0);
  }
  else
  {
    v7 = off_419424[0][1];
    v8 = (HINSTANCE)System::FindResourceHInstance(hModule);
    LoadStringA_0(v8, v7, (LPSTR)&Caption, 64);
    result = MessageBoxA_0(0, &Buffer, &Caption, 0x2010u);
  }
  return result;
}
// 4025D8: using guessed type int __fastcall System____linkproc__ _IOTest(_DWORD);
// 4026E4: using guessed type int __fastcall System__Flush(_DWORD);
// 404020: using guessed type int __fastcall System__FindResourceHInstance(_DWORD);
// 405930: using guessed type int __fastcall Sysutils__StrLen(_DWORD);
// 406C9C: using guessed type _strings str____0[1];
// 419424: using guessed type int *off_419424[7];
// 419440: using guessed type void *off_419440;
// 4194E8: using guessed type char *off_4194E8;

//----- (004070BC) --------------------------------------------------------
int __cdecl sub_4070BC(int a1)
{
  int v1; // ebx@1
  int v2; // esi@4
  unsigned int v4; // [sp-Ch] [bp-184h]@1
  int (__cdecl *v5)(int); // [sp-8h] [bp-180h]@1
  int (__cdecl *v6)(int); // [sp-4h] [bp-17Ch]@1
  int v7; // [sp+8h] [bp-170h]@1
  int v8; // [sp+Ch] [bp-16Ch]@7
  char v9; // [sp+10h] [bp-168h]@7
  int v10; // [sp+14h] [bp-164h]@7
  char v11; // [sp+18h] [bp-160h]@7
  int v12; // [sp+1Ch] [bp-15Ch]@7
  char v13; // [sp+20h] [bp-158h]@7
  int v14; // [sp+24h] [bp-154h]@1
  int v15; // [sp+28h] [bp-150h]@1
  int v16; // [sp+2Ch] [bp-14Ch]@1
  int v17; // [sp+30h] [bp-148h]@6
  char v18; // [sp+34h] [bp-144h]@6
  int v19; // [sp+38h] [bp-140h]@6
  char v20; // [sp+3Ch] [bp-13Ch]@6
  int v21; // [sp+40h] [bp-138h]@6
  char v22; // [sp+44h] [bp-134h]@6
  int v23; // [sp+48h] [bp-130h]@6
  char v24; // [sp+4Ch] [bp-12Ch]@6
  CHAR Filename; // [sp+53h] [bp-125h]@5
  struct _MEMORY_BASIC_INFORMATION Buffer; // [sp+158h] [bp-20h]@4
  int v27; // [sp+174h] [bp-4h]@1
  int v28; // [sp+178h] [bp+0h]@1

  v7 = 0;
  v16 = 0;
  v14 = 0;
  v15 = 0;
  v27 = 0;
  v6 = (int (__cdecl *)(int))&v28;
  v5 = loc_407277;
  v4 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v4);
  v1 = *(_DWORD *)(a1 - 4);
  if ( *(_DWORD *)(v1 + 20) )
    System::LoadResString(off_4194D0[0], &v27);
  else
    System::LoadResString(off_41953C[0], &v27);
  v2 = *(_DWORD *)(v1 + 24);
  VirtualQuery(*(LPCVOID *)(v1 + 12), &Buffer, 0x1Cu);
  if ( Buffer.State == 4096 && GetModuleFileNameA_0(Buffer.AllocationBase, &Filename, 0x105u) )
  {
    v17 = *(_DWORD *)(v1 + 12);
    v18 = 5;
    unknown_libname_54(&v15, &Filename, v4);
    Sysutils::ExtractFileName(v15, &v16);
    v19 = v16;
    v20 = 11;
    v21 = v27;
    v22 = 11;
    v23 = v2;
    v24 = 5;
    System::LoadResString(off_4194F4[0], &v14);
    Sysutils::Exception::Exception(3, &v17);
  }
  else
  {
    v8 = *(_DWORD *)(v1 + 12);
    v9 = 5;
    v10 = v27;
    v11 = 11;
    v12 = v2;
    v13 = 5;
    System::LoadResString(off_419510[0], &v7);
    Sysutils::Exception::Exception(2, &v8);
  }
  __writefsdword(0, v4);
  v6 = loc_40727E;
  System::__linkproc___LStrClr(&v7);
  System::__linkproc___LStrArrayClr(&v14, 3);
  return System::__linkproc___LStrClr(&v27);
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 40378C: using guessed type int __fastcall System____linkproc__ LStrArrayClr(_DWORD, _DWORD);
// 4039AC: using guessed type int __fastcall unknown_libname_54(_DWORD, _DWORD, _DWORD);
// 4046BC: using guessed type int __fastcall System__LoadResString(_DWORD, _DWORD);
// 405884: using guessed type int __fastcall Sysutils__ExtractFileName(_DWORD, _DWORD);
// 406CE4: using guessed type _DWORD __stdcall Sysutils__Exception__Exception(_DWORD, _DWORD);
// 407277: using guessed type int __cdecl loc_407277(int);
// 40727E: using guessed type int __cdecl loc_40727E(int);
// 4194D0: using guessed type int *off_4194D0[6];
// 4194F4: using guessed type int *off_4194F4[4];
// 419510: using guessed type int *off_419510[13];
// 41953C: using guessed type int *off_41953C[2];

//----- (00407580) --------------------------------------------------------
int __fastcall sub_407580(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int result; // eax@1
  int v5; // eax@3

  v2 = a2;
  v3 = a1;
  result = 1;
  if ( (_BYTE)dword_41A7F8 )
  {
    if ( _bittest((signed __int32 *)&dword_4180C8, *(_BYTE *)(v3 + a2 - 1)) )
    {
      v5 = System::__linkproc___LStrToPChar(v3);
      result = Sysutils::StrCharLength((LPCSTR)(v2 + v5 - 1));
    }
  }
  return result;
}
// 403B1C: using guessed type int __fastcall System____linkproc__ LStrToPChar(_DWORD);
// 4180C8: using guessed type int dword_4180C8;
// 41A7F8: using guessed type int dword_41A7F8;

//----- (00408158) --------------------------------------------------------
int __fastcall sub_408158(signed int a1, int a2)
{
  char v2; // cf@5
  int v3; // eax@5
  int v4; // eax@8
  int result; // eax@12

  if ( a1 > 2048 )
  {
    switch ( a1 )
    {
      case 2049:
        result = System::__linkproc___LStrAsg(a2, &str_Invalid_TtakStr[1]);
        break;
      case 2050:
        result = System::__linkproc___LStrAsg(a2, &str_Invalid_mode[1]);
        break;
      case 2051:
        result = System::__linkproc___LStrAsg(a2, &str_Buffer_too_smal[1]);
        break;
      case 2052:
        result = System::__linkproc___LStrAsg(a2, &str_Not_enough_audi[1]);
        break;
      case 2053:
        result = System::__linkproc___LStrAsg(a2, &str_Too_much_audio_[1]);
        break;
      default:
        goto LABEL_23;
    }
  }
  else
  {
    if ( a1 == 2048 )
    {
      result = System::__linkproc___LStrAsg(a2, &str_Invalid_paramet[1]);
    }
    else
    {
      if ( a1 > 1025 )
      {
        v4 = a1 - 1026;
        if ( !v4 )
          return System::__linkproc___LStrAsg(a2, &str_Incompatible_ve[1]);
        if ( v4 == 1 )
          return System::__linkproc___LStrAsg(a2, &str_Out_of_memory[1]);
      }
      else
      {
        if ( a1 == 1025 )
          return System::__linkproc___LStrAsg(a2, &str_Not_implemented[1]);
        v2 = (unsigned int)a1 < 1;
        v3 = a1 - 1;
        if ( v2 )
          return System::__linkproc___LStrAsg(a2, &str_Ok[1]);
        if ( v3 == 1023 )
          return System::__linkproc___LStrAsg(a2, &str_Internal_error[1]);
      }
LABEL_23:
      result = System::__linkproc___LStrAsg(a2, &str_Unknown_error[1]);
    }
  }
  return result;
}
// 4037BC: using guessed type int __fastcall System____linkproc__ LStrAsg(_DWORD, _DWORD);
// 408264: using guessed type _strings str_Ok[1];
// 408270: using guessed type _strings str_Internal_error[2];
// 408288: using guessed type _strings str_Not_implemented[3];
// 4082A0: using guessed type _strings str_Incompatible_ve[3];
// 4082C0: using guessed type _strings str_Out_of_memory[2];
// 4082D8: using guessed type _strings str_Invalid_paramet[3];
// 4082F4: using guessed type _strings str_Invalid_TtakStr[4];
// 40831C: using guessed type _strings str_Invalid_mode[2];
// 408334: using guessed type _strings str_Buffer_too_smal[3];
// 408350: using guessed type _strings str_Not_enough_audi[3];
// 408370: using guessed type _strings str_Too_much_audio_[3];
// 40838C: using guessed type _strings str_Unknown_error[2];

//----- (004083A4) --------------------------------------------------------
signed int __usercall sub_4083A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // esi@1
  signed int result; // eax@2

  v3 = a2;
  v4 = a1;
  if ( a2 )
  {
    if ( ecx0 > sub_4039D8(a1) )
    {
      sub_40598C(v3, v4);
      result = 0;
    }
    else
    {
      result = 2051;
    }
  }
  else
  {
    result = 2048;
  }
  return result;
}

//----- (004083DC) --------------------------------------------------------
char __usercall sub_4083DC<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // edi@1
  int v5; // ebx@1
  char result; // al@2
  int v7; // eax@3

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( a1 )
  {
    v7 = Sysutils::StrLen(a1);
    if ( v7 < 0 )
      sub_402CA8();
    if ( v3 >= v7 )
    {
      System::__linkproc___LStrFromPCharLen(v4, v5);
      result = 1;
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}
// 405930: using guessed type int __fastcall Sysutils__StrLen(_DWORD);

//----- (00408418) --------------------------------------------------------
signed int __fastcall sub_408418(char a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = 1;
  else
    result = 0;
  return result;
}

//----- (00408428) --------------------------------------------------------
int __cdecl sub_408428()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A84C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A84C: using guessed type int dword_41A84C;

//----- (00408458) --------------------------------------------------------
void __cdecl sub_408458()
{
  --dword_41A84C;
}
// 41A84C: using guessed type int dword_41A84C;

//----- (004084BC) --------------------------------------------------------
int __fastcall sub_4084BC(int a1)
{
  int v1; // ebx@1
  int v2; // eax@4
  int result; // eax@4
  int v4; // [sp+0h] [bp-Ch]@3
  int v5; // [sp+4h] [bp-8h]@4

  v1 = a1;
  if ( !*(_BYTE *)(a1 + 44)
    && *(_DWORD *)(a1 + 8)
    && (unsigned __int8)(*(int (__fastcall **)(_DWORD, int *))(a1 + 8))(*(_DWORD *)(a1 + 12), &v4) )
  {
    *(_DWORD *)(v1 + 16) = v4;
    *(_DWORD *)(v1 + 24) = v4;
    *(_DWORD *)(v1 + 20) = 0;
    v2 = 8 * v5;
    *(_DWORD *)(v1 + 36) = 8 * v5;
    *(_DWORD *)(v1 + 32) = v2;
    result = *(_DWORD *)(v1 + 36);
    *(_DWORD *)(v1 + 28) += result;
    *(_DWORD *)(v1 + 40) = 32;
    LOBYTE(result) = 1;
  }
  else
  {
    *(_BYTE *)(v1 + 44) = 1;
    result = 0;
  }
  return result;
}

//----- (00408518) --------------------------------------------------------
unsigned int __fastcall sub_408518(int a1, int a2)
{
  int v2; // ebp@1
  int v3; // ebx@1
  int v4; // eax@1
  char v5; // si@1
  unsigned int v6; // edi@2
  unsigned int v7; // edi@6

  v2 = a2;
  v3 = a1;
  v4 = *(_DWORD *)(a1 + 36);
  v5 = v4;
  if ( v4 )
  {
    v2 = a2 - v4;
    v6 = sub_40864C(v3, v4);
  }
  else
  {
    v6 = 0;
  }
  if ( (unsigned __int8)sub_4084BC(v3) && v2 <= *(_DWORD *)(v3 + 36) )
  {
    v7 = (sub_40864C(v3, v2) << v5) | v6;
  }
  else
  {
    *(_BYTE *)(v3 + 44) = 1;
    v7 = 0;
  }
  return v7;
}

//----- (00408568) --------------------------------------------------------
int __fastcall sub_408568(int a1)
{
  return *(_DWORD *)(a1 + 28) - *(_DWORD *)(a1 + 36);
}

//----- (00408574) --------------------------------------------------------
int __fastcall sub_408574(int a1)
{
  return *(_DWORD *)(a1 + 20) + *(_DWORD *)(a1 + 16);
}

//----- (00408580) --------------------------------------------------------
int __fastcall sub_408580(int a1)
{
  return (sub_408568(a1) + 7) / 8;
}

//----- (0040859C) --------------------------------------------------------
signed int __fastcall sub_40859C(int a1)
{
  signed int v1; // edx@1

  v1 = *(_DWORD *)(a1 + 32) - *(_DWORD *)(a1 + 36) + 7;
  if ( v1 < 0 )
    v1 = *(_DWORD *)(a1 + 32) - *(_DWORD *)(a1 + 36) + 14;
  return v1 >> 3;
}

//----- (004085B4) --------------------------------------------------------
int __usercall sub_4085B4<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ecx@1

  *(_DWORD *)(result + 16) = a2;
  *(_DWORD *)(result + 24) = a2;
  *(_DWORD *)(result + 28) = 8 * ecx0;
  v3 = 8 * ecx0;
  *(_DWORD *)(result + 36) = v3;
  *(_DWORD *)(result + 32) = v3;
  *(_DWORD *)(result + 40) = 32;
  *(_BYTE *)(result + 44) = 0;
  *(_DWORD *)(result + 8) = 0;
  *(_DWORD *)(result + 12) = 0;
  *(_DWORD *)(result + 20) = 0;
  return result;
}

//----- (004085E4) --------------------------------------------------------
int __userpurge sub_4085E4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  char v6; // si@1
  int v7; // ebx@1
  int result; // eax@1

  v6 = a2;
  v7 = a1;
  sub_4085B4(a1, a2, ecx0);
  *(_DWORD *)(v7 + 8) = a3;
  *(_DWORD *)(v7 + 12) = a4;
  result = v6 & 3;
  *(_DWORD *)(v7 + 20) = result;
  if ( result > 0 )
  {
    *(_DWORD *)(v7 + 16) -= result;
    *(_DWORD *)(v7 + 24) = *(_DWORD *)(v7 + 16);
    result = 8 * *(_DWORD *)(v7 + 20);
    *(_DWORD *)(v7 + 40) = 32 - result;
  }
  return result;
}

//----- (00408638) --------------------------------------------------------
unsigned int __fastcall sub_408638(int a1)
{
  int v1; // edx@1
  unsigned int result; // eax@2

  v1 = *(_DWORD *)(a1 + 40) & 7;
  if ( v1 )
    result = sub_40864C(a1, v1);
  else
    result = 0;
  return result;
}

//----- (0040864C) --------------------------------------------------------
unsigned int __fastcall sub_40864C(int a1, int a2)
{
  unsigned int v2; // ecx@2
  int v3; // ebx@3

  if ( a2 <= *(_DWORD *)(a1 + 36) )
  {
    v3 = *(_DWORD *)(a1 + 40);
    if ( a2 > v3 )
    {
      if ( v3 <= 0 )
      {
        *(_DWORD *)(a1 + 40) = 32 - a2;
        v2 = *(_DWORD *)(*(_DWORD *)(a1 + 24) + 4) & (0xFFFFFFFFu >> (32 - a2));
      }
      else
      {
        v2 = (*(_DWORD *)(*(_DWORD *)(a1 + 24) + 4) << (v3 + 32 - a2) >> (32 - a2)) | (**(_DWORD **)(a1 + 24) >> (32 - v3));
        *(_DWORD *)(a1 + 40) += 32 - a2;
      }
      *(_DWORD *)(a1 + 24) += 4;
    }
    else
    {
      *(_DWORD *)(a1 + 40) -= a2;
      v2 = **(_DWORD **)(a1 + 24) << *(_DWORD *)(a1 + 40) >> (32 - a2);
    }
    *(_DWORD *)(a1 + 36) -= a2;
  }
  else
  {
    v2 = sub_408518(a1, a2);
  }
  return v2;
}

//----- (004086E0) --------------------------------------------------------
unsigned int __fastcall sub_4086E0(int a1, int a2)
{
  int v2; // ebx@1
  unsigned int result; // eax@1
  signed int v4; // edx@3

  v2 = a2;
  result = sub_40864C(a1, a2);
  if ( v2 == 1 )
  {
    result = 0;
  }
  else
  {
    v4 = -1 << (v2 - 1);
    if ( result & v4 )
      result |= v4;
  }
  return result;
}

//----- (00408704) --------------------------------------------------------
int __fastcall sub_408704(int a1)
{
  int v1; // ebx@1
  int result; // eax@3
  int v3; // eax@4

  v1 = a1;
  if ( *(_DWORD *)(a1 + 36) || (unsigned __int8)sub_4084BC(a1) )
  {
    v3 = *(_DWORD *)(v1 + 40);
    if ( v3 <= 0 )
    {
      result = *(_DWORD *)(*(_DWORD *)(v1 + 24) + 4) & 1;
      *(_DWORD *)(v1 + 40) = 31;
      *(_DWORD *)(v1 + 24) += 4;
      --*(_DWORD *)(v1 + 36);
    }
    else
    {
      result = (**(_DWORD **)(v1 + 24) >> (32 - v3)) & 1;
      --*(_DWORD *)(v1 + 40);
      --*(_DWORD *)(v1 + 36);
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00408758) --------------------------------------------------------
int __fastcall sub_408758(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // eax@7
  int v5; // eax@9
  int i; // [sp+8h] [bp-8h]@2
  int v14; // [sp+Ch] [bp-4h]@8
  int v15; // [sp+Ch] [bp-4h]@12

  v2 = a2;
  v3 = a1;
  if ( a2 <= *(_DWORD *)(a1 + 36) )
  {
    v4 = *(_DWORD *)(a1 + 40);
    if ( v4 )
    {
      v14 = **(_DWORD **)(v3 + 24) >> (32 - v4);
      v5 = *(_DWORD *)(v3 + 40);
      if ( a2 > v5 )
        v14 |= *(_DWORD *)(*(_DWORD *)(v3 + 24) + 4) << v5;
    }
    else
    {
      v14 = *(_DWORD *)(*(_DWORD *)(v3 + 24) + 4);
    }
    _EAX = v14 | 0x80000000;
    __asm { bsf     ecx, eax }
    i = _ECX;
    if ( a2 > _ECX )
    {
      v15 = _ECX + 1;
    }
    else
    {
      i = a2;
      v15 = a2;
    }
    if ( *(_DWORD *)(v3 + 40) >= v15 )
    {
      *(_DWORD *)(v3 + 40) -= v15;
    }
    else
    {
      *(_DWORD *)(v3 + 24) += 4;
      *(_DWORD *)(v3 + 40) = *(_DWORD *)(v3 + 40) + 32 - v15;
    }
    *(_DWORD *)(v3 + 36) -= v15;
  }
  else
  {
    for ( i = 0; v2 > i && !sub_408704(v3); ++i )
      ;
  }
  return i;
}

//----- (00408814) --------------------------------------------------------
char __usercall sub_408814<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1

  v3 = a1;
  *(_DWORD *)ecx0 = sub_40864C(a1, a2);
  return *(_BYTE *)(v3 + 44) ^ 1;
}

//----- (00408834) --------------------------------------------------------
char __usercall sub_408834<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1

  v3 = a1;
  *(_DWORD *)ecx0 = sub_4086E0(a1, a2);
  return *(_BYTE *)(v3 + 44) ^ 1;
}

//----- (00408854) --------------------------------------------------------
char __fastcall sub_408854(int a1, int a2)
{
  int v2; // ebx@1

  v2 = a1;
  *(_DWORD *)a2 = sub_408704(a1);
  return *(_BYTE *)(v2 + 44) ^ 1;
}

//----- (0040886C) --------------------------------------------------------
int __cdecl sub_40886C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A850;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A850: using guessed type int dword_41A850;

//----- (0040889C) --------------------------------------------------------
void __cdecl sub_40889C()
{
  --dword_41A850;
}
// 41A850: using guessed type int dword_41A850;

//----- (004088A4) --------------------------------------------------------
void __cdecl sub_4088A4()
{
  ;
}

//----- (004088BD) --------------------------------------------------------
int __userpurge sub_4088BD<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4)
{
  int v5; // edi@1
  int v6; // ebx@2
  int v7; // ebx@3
  __m64 v8; // mm7@4

  v5 = ecx0;
  if ( ecx0 > 0 )
  {
    v6 = ecx0 & 0xFFFFFFFC;
    if ( !(ecx0 & 0xFFFFFFFC) )
      goto LABEL_12;
    result += 4 * v6;
    a2 += 2 * v6;
    v7 = -v6;
    if ( a3 )
    {
      v8 = _mm_cvtsi32_si64(a3);
      do
      {
        *(_QWORD *)(a2 + 2 * v7) = _m_packssdw(
                                     _m_psrad(*(__m64 *)(result + 4 * v7), v8),
                                     _m_psrad(*(__m64 *)(result + 4 * v7 + 8), v8));
        v7 += 4;
      }
      while ( v7 < 0 );
    }
    else
    {
      do
      {
        *(_QWORD *)(a2 + 2 * v7) = _m_packssdw(*(__m64 *)(result + 4 * v7), *(__m64 *)(result + 4 * v7 + 8));
        v7 += 4;
      }
      while ( v7 < 0 );
    }
    _m_femms();
    v5 = ecx0 & 3;
    if ( ecx0 & 3 )
    {
LABEL_12:
      do
      {
        *(_WORD *)a2 = *(_DWORD *)result >> a3;
        result += 4;
        a2 += 2;
        --v5;
      }
      while ( v5 );
    }
  }
  return result;
}

//----- (00408950) --------------------------------------------------------
void __usercall sub_408950(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3)
{
  JUMPOUT(ecx0, 4, loc_408968);
  JUMPOUT(*(int *)sub_408955);
}
// 408968: using guessed type int loc_408968();

//----- (00408955) --------------------------------------------------------
void __usercall sub_408955(unsigned int a1<ecx>, int a2<ebp>, int a3<edi>)
{
  int (__usercall *v3)<eax>(int<ecx>, int<ebx>, int<edi>, __m64<mm0>, __m64<mm1>, __m64<mm2>, __m64<mm3>, __m64<mm4>); // ebp@1

  *(_DWORD *)(a3 + 28) = a2;
  v3 = sub_4089F8;
  if ( a1 <= 0x18 )
    v3 = *(int (__usercall **)<eax>(int<ecx>, int<ebx>, int<edi>, __m64<mm0>, __m64<mm1>, __m64<mm2>, __m64<mm3>, __m64<mm4>))((char *)loc_408926 + a1 + 2);
  *(_DWORD *)(a3 + 24) = v3;
  *(_DWORD *)(a3 + 32) = 2 * a1;
}
// 408926: using guessed type int __stdcall loc_408926(int);

//----- (004089F8) --------------------------------------------------------
int __usercall sub_4089F8<eax>(int a1<ecx>, int a2<ebx>, int a3<edi>, __m64 a4<mm0>, __m64 a5<mm1>, __m64 a6<mm2>, __m64 a7<mm3>, __m64 a8<mm4>)
{
  int v8; // eax@1
  signed int v9; // ecx@1
  __m64 v10; // mm0@2
  __m64 v11; // mm1@2
  __m64 v12; // mm5@2
  __m64 v13; // mm2@2
  __m64 v14; // mm4@2
  __m64 v15; // mm0@2
  __m64 v16; // mm1@2
  __m64 v17; // mm2@2
  __m64 v18; // mm4@2
  __m64 v19; // mm0@2
  __m64 v20; // mm1@2
  __m64 v21; // mm2@2
  __m64 v22; // mm4@2

  v8 = a1 - 32;
  v9 = 32;
  do
  {
    v10 = _m_paddd(a4, _m_pmaddwd(a8, *(__m64 *)(a3 + 4 * v9 - 48)));
    v11 = _m_paddd(a5, _m_pmaddwd(a8, *(__m64 *)(a3 + 4 * v9 - 40)));
    v12 = a8;
    v13 = _m_paddd(a6, _m_pmaddwd(a8, *(__m64 *)(a3 + 4 * v9 - 32)));
    v14 = *(__m64 *)(a2 + v9 - 16);
    v15 = _m_paddd(v10, _m_pmaddwd(v14, *(__m64 *)(a3 + 4 * v9 - 16)));
    v16 = _m_paddd(v11, _m_pmaddwd(v14, *(__m64 *)(a3 + 4 * v9 - 8)));
    v17 = _m_paddd(v13, _m_pmaddwd(v14, *(__m64 *)(a3 + 4 * v9)));
    v18 = *(__m64 *)(a2 + v9 - 8);
    v19 = _m_paddd(v15, _m_pmaddwd(v18, *(__m64 *)(a3 + 4 * v9 + 16)));
    v20 = _m_paddd(v16, _m_pmaddwd(v18, *(__m64 *)(a3 + 4 * v9 + 24)));
    v21 = _m_paddd(v17, _m_pmaddwd(v18, *(__m64 *)(a3 + 4 * v9 + 32)));
    v22 = *(__m64 *)(a2 + v9);
    a4 = _m_paddd(v19, _m_pmaddwd(v22, *(__m64 *)(a3 + 4 * v9 + 48)));
    a5 = _m_paddd(v20, _m_pmaddwd(v22, *(__m64 *)(a3 + 4 * v9 + 56)));
    a6 = _m_paddd(v21, _m_pmaddwd(v22, *(__m64 *)(a3 + 4 * v9 + 64)));
    a8 = *(__m64 *)(a2 + v9 + 8);
    a7 = _m_paddd(
           _m_paddd(
             _m_paddd(
               _m_paddd(a7, _m_pmaddwd(v12, *(__m64 *)(a3 + 4 * v9 - 24))),
               _m_pmaddwd(*(__m64 *)(a2 + v9 - 16), *(__m64 *)(a3 + 4 * v9 + 8))),
             _m_pmaddwd(*(__m64 *)(a2 + v9 - 8), *(__m64 *)(a3 + 4 * v9 + 40))),
           _m_pmaddwd(*(__m64 *)(a2 + v9), *(__m64 *)(a3 + 4 * v9 + 72)));
    v9 += 32;
  }
  while ( v9 <= (unsigned int)v8 );
  return (*(int (**)(void))(a3 + 28))();
}

//----- (00408B6B) --------------------------------------------------------
void __fastcall sub_408B6B(int a1, int a2, int a3, int a4, unsigned int a5, int a6, int a7, int a8)
{
  int v8; // [sp+0h] [bp-10h]@0

  sub_408950(a1, (unsigned int)a4 >> 2, a8, v8);
  JUMPOUT(__CS__, *(_DWORD *)(a7 + 24));
}

//----- (00408C41) --------------------------------------------------------
unsigned int __cdecl sub_408C41(int a1, int a2, int a3, int a4, int a5)
{
  int v5; // esi@1
  int v6; // edx@1
  int v7; // ecx@1
  __m64 v8; // mm0@1
  int v9; // esi@3
  int v10; // edx@3
  __m64 v11; // mm1@3
  int v12; // ecx@4
  __m64 v13; // mm2@5
  __m64 v14; // mm0@5
  __m64 v15; // mm2@5
  int v16; // eax@5
  unsigned int result; // eax@7
  __m64 v18; // mm2@11
  __m64 v19; // mm0@11
  __m64 v20; // mm2@11
  int v21; // eax@11
  int v22; // ecx@11
  signed int v23; // eax@13
  __m64 v24; // mm1@17
  __m64 v25; // mm2@17
  __m64 v26; // mm3@17
  __m64 v27; // mm4@17
  __m64 v28; // mm5@17
  int (__cdecl *v29)(int, int, int, int, int); // ebx@17
  __m64 v30; // mm4@19
  __m64 v31; // mm7@19
  __m64 v32; // mm5@19
  __m64 v33; // mm1@19
  __m64 v34; // mm4@19
  int v35; // eax@19
  int v36; // ecx@19
  int v37; // eax@19
  int v38; // ecx@22
  signed int v39; // eax@22
  signed int v40; // eax@24
  __m64 v41; // mm1@26
  __m64 v42; // mm2@26
  int (__cdecl *v43)(int, int, int, int, int); // ebx@26
  __m64 v44; // mm7@28
  __m64 v45; // mm5@28
  __m64 v46; // mm2@28
  __m64 v47; // mm3@28
  int v48; // eax@28
  int v49; // ecx@31
  signed int v50; // eax@31
  signed int v51; // eax@33

  v5 = a1;
  v6 = a2;
  v7 = *(_DWORD *)(a4 + 8);
  v8 = *(__m64 *)a3;
  if ( a5 == 12 )
  {
    v41 = *(__m64 *)(a3 + 8);
    v42 = *(__m64 *)(a3 + 16);
    v43 = loc_408E3E;
    if ( !v7 )
      v43 = loc_408E4C;
    do
    {
      v44 = v42;
      v45 = _m_pmaddwd(*(__m64 *)(a4 + 112), v42);
      v46 = _m_psrlq(v42, 0x10u);
      v47 = _m_paddd(_m_paddd(_m_pmaddwd(*(__m64 *)(a4 + 48), v8), _m_pmaddwd(*(__m64 *)(a4 + 80), v41)), v45);
      v8 = _m_por(_m_psrlq(v8, 0x10u), _m_psllq(v41, 0x30u));
      v41 = _m_por(_m_psrlq(v41, 0x10u), _m_psllq(v44, 0x30u));
      v48 = (*(_DWORD *)a4 + _mm_cvtsi64_si32(_m_psrlq(v47, 0x20u)) + _mm_cvtsi64_si32(v47)) >> *(_DWORD *)(a4 + 16);
      if ( v48 < -8192 )
      {
        v51 = -8192;
      }
      else
      {
        if ( v48 <= 8191 )
          JUMPOUT(__CS__, v43);
        v51 = 8191;
      }
      v49 = *(_DWORD *)(a4 + 8);
      v50 = (v51 << v49) - *(_DWORD *)v5;
      *(_DWORD *)v5 = v50;
      result = v50 >> v49;
      v5 += 4;
      v42 = _m_por(v46, _m_psllq(_mm_cvtsi32_si64(result), 0x30u));
      --v6;
    }
    while ( v6 );
  }
  else
  {
    if ( a5 == 8 )
    {
      v24 = *(__m64 *)(a3 + 8);
      v25 = *(__m64 *)(a4 + 48);
      v26 = *(__m64 *)(a4 + 80);
      v27 = *(__m64 *)(a4 + 48);
      v28 = *(__m64 *)(a4 + 80);
      v29 = loc_408D94;
      if ( !v7 )
        v29 = loc_408DA1;
      do
      {
        v30 = _m_pmaddwd(v27, v8);
        v31 = v24;
        v32 = _m_pmaddwd(v28, v24);
        v33 = _m_psrlq(v24, 0x10u);
        v8 = _m_por(_m_psrlq(v8, 0x10u), _m_psllq(v31, 0x30u));
        v34 = _m_paddd(v30, v32);
        v28 = v26;
        v35 = _mm_cvtsi64_si32(v34);
        v36 = _mm_cvtsi64_si32(_m_psrlq(v34, 0x20u));
        v27 = v25;
        v37 = (*(_DWORD *)a4 + v36 + v35) >> *(_DWORD *)(a4 + 16);
        if ( v37 < -8192 )
        {
          v40 = -8192;
        }
        else
        {
          if ( v37 <= 8191 )
            JUMPOUT(__CS__, v29);
          v40 = 8191;
        }
        v38 = *(_DWORD *)(a4 + 8);
        v39 = (v40 << v38) - *(_DWORD *)v5;
        *(_DWORD *)v5 = v39;
        result = v39 >> v38;
        v5 += 4;
        v24 = _m_por(v33, _m_psllq(_mm_cvtsi32_si64(result), 0x30u));
        --v6;
      }
      while ( v6 );
    }
    else
    {
      v9 = a1 + 4 * a2;
      v10 = -a2;
      v11 = *(__m64 *)(a4 + 48);
      if ( v7 )
      {
        do
        {
          v18 = v8;
          v19 = _m_pmaddwd(v8, v11);
          v20 = _m_psrlq(v18, 0x10u);
          v21 = (*(_DWORD *)a4 + _mm_cvtsi64_si32(_m_psrlq(v19, 0x20u)) + _mm_cvtsi64_si32(v19)) >> *(_DWORD *)(a4 + 16);
          v22 = *(_DWORD *)(a4 + 8);
          if ( v21 < -8192 )
          {
            v21 = -8192;
          }
          else
          {
            if ( v21 > 8191 )
              v21 = 8191;
          }
          v23 = (v21 << v22) - *(_DWORD *)(v9 + 4 * v10);
          *(_DWORD *)(v9 + 4 * v10) = v23;
          result = v23 >> v22;
          v8 = _m_por(_m_psllq(_mm_cvtsi32_si64(result), 0x30u), v20);
          ++v10;
        }
        while ( v10 < 0 );
      }
      else
      {
        v12 = *(_DWORD *)(a4 + 16);
        do
        {
          v13 = v8;
          v14 = _m_pmaddwd(v8, v11);
          v15 = _m_psrlq(v13, 0x10u);
          v16 = (*(_DWORD *)a4 + _mm_cvtsi64_si32(_m_psrlq(v14, 0x20u)) + _mm_cvtsi64_si32(v14)) >> v12;
          if ( v16 < -8192 )
          {
            v16 = -8192;
          }
          else
          {
            if ( v16 > 8191 )
              v16 = 8191;
          }
          result = v16 - *(_DWORD *)(v9 + 4 * v10);
          *(_DWORD *)(v9 + 4 * v10) = result;
          v8 = _m_por(_m_psllq(_mm_cvtsi32_si64(result), 0x30u), v15);
          ++v10;
        }
        while ( v10 < 0 );
      }
    }
  }
  _m_femms();
  return result;
}
// 408D94: using guessed type int __cdecl loc_408D94(int, int, int, int, int);
// 408DA1: using guessed type int __cdecl loc_408DA1(int, int, int, int, int);
// 408E3E: using guessed type int __cdecl loc_408E3E(int, int, int, int, int);
// 408E4C: using guessed type int __cdecl loc_408E4C(int, int, int, int, int);

//----- (00408E80) --------------------------------------------------------
int __usercall sub_408E80<eax>(int a1<edi>, int a2<esi>, __m64 a3<mm4>)
{
  int v3; // eax@1
  int v4; // ecx@1
  int result; // eax@4
  signed int v6; // eax@5

  v3 = (*(_DWORD *)a1 + _mm_cvtsi64_si32(_m_psrlq(a3, 0x20u)) + _mm_cvtsi64_si32(a3)) >> *(_DWORD *)(a1 + 16);
  v4 = *(_DWORD *)(a1 + 8);
  if ( v3 < -8192 )
  {
    v3 = -8192;
  }
  else
  {
    if ( v3 > 8191 )
    {
      v3 = 8191;
    }
    else
    {
      if ( !v4 )
      {
        result = v3 - *(_DWORD *)a2;
        *(_DWORD *)a2 = result;
        return result;
      }
    }
  }
  v6 = (v3 << v4) - *(_DWORD *)a2;
  *(_DWORD *)a2 = v6;
  return v6 >> v4;
}

//----- (00408ED4) --------------------------------------------------------
void __cdecl sub_408ED4(int a1, int a2, int a3, int a4, unsigned int a5)
{
  sub_408955(a5, (int)loc_408F01, a4);
  JUMPOUT(loc_4089D5);
}
// 4089D5: using guessed type int __cdecl loc_4089D5(int, int, int, int, int, int);
// 408F01: using guessed type int __cdecl loc_408F01(int, int, int, int, int);

//----- (00408F82) --------------------------------------------------------
int __cdecl sub_408F82(int a1, int a2, int a3, int a4, int a5)
{
  int v5; // ebx@1
  int v6; // ebp@1
  __m64 v7; // mm5@1
  __m64 v8; // mm6@1
  __m64 v9; // mm7@1
  __m128i v10; // xmm1@2
  __m128i v11; // xmm0@2
  __m128i v12; // xmm2@2
  __m128i v13; // xmm1@2
  __m128i v14; // xmm3@2
  __m128i v15; // xmm4@2
  __m128i v16; // xmm2@2
  __m128i v17; // xmm3@2
  unsigned int v18; // ecx@2
  __m128i v19; // xmm0@3
  __m128i v20; // xmm1@3
  __m128i v21; // xmm5@3
  __m128i v22; // xmm2@3
  __m128i v23; // xmm4@3
  __m128i v24; // xmm3@3
  __m128i v25; // xmm5@3
  __m128i v26; // xmm0@4
  __m128i v27; // xmm1@4
  __m128i v28; // xmm2@4
  __m128i v29; // xmm3@4
  __m64 v30; // mm0@4
  __m64 v31; // mm0@4
  __m64 v32; // mm0@4
  int result; // eax@4
  int v34; // edx@4

  v5 = a3;
  v6 = 2 * a5;
  v7 = *(__m64 *)(a4 + 8 * a5 + 64);
  v8 = *(__m64 *)(a4 + 8 * a5 + 80);
  v9 = *(__m64 *)(a4 + 8 * a5 + 96);
  do
  {
    v10 = _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i *)v5), _mm_loadl_epi64((const __m128i *)(v5 + 8)));
    v11 = _mm_madd_epi16(v10, *(__m128i *)(a4 + 48));
    v12 = v10;
    v13 = _mm_madd_epi16(v10, *(__m128i *)(a4 + 64));
    v14 = v12;
    v15 = _mm_unpacklo_epi64(_mm_loadl_epi64((const __m128i *)(v5 + 16)), _mm_loadl_epi64((const __m128i *)(v5 + 24)));
    v16 = _mm_madd_epi16(v12, *(__m128i *)(a4 + 80));
    v17 = _mm_madd_epi16(v14, *(__m128i *)(a4 + 96));
    v18 = 32;
    do
    {
      v19 = _mm_add_epi32(v11, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18 - 16)));
      v20 = _mm_add_epi32(v13, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18)));
      v21 = v15;
      v22 = _mm_add_epi32(v16, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18 + 16)));
      v23 = _mm_unpacklo_epi64(
              _mm_loadl_epi64((const __m128i *)(v5 + v18)),
              _mm_loadl_epi64((const __m128i *)(v5 + v18 + 8)));
      v24 = _mm_add_epi32(v17, _mm_madd_epi16(v21, *(__m128i *)(a4 + 4 * v18 + 32)));
      v11 = _mm_add_epi32(v19, _mm_madd_epi16(v23, *(__m128i *)(a4 + 4 * v18 + 48)));
      v13 = _mm_add_epi32(v20, _mm_madd_epi16(v23, *(__m128i *)(a4 + 4 * v18 + 64)));
      v25 = v23;
      v16 = _mm_add_epi32(v22, _mm_madd_epi16(v23, *(__m128i *)(a4 + 4 * v18 + 80)));
      v15 = _mm_unpacklo_epi64(
              _mm_loadl_epi64((const __m128i *)(v5 + v18 + 16)),
              _mm_loadl_epi64((const __m128i *)(v5 + v18 + 24)));
      v17 = _mm_add_epi32(v24, _mm_madd_epi16(v25, *(__m128i *)(a4 + 4 * v18 + 96)));
      v18 += 32;
    }
    while ( v18 <= v6 - 32 );
    v26 = _mm_add_epi32(v11, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18 - 16)));
    v27 = _mm_add_epi32(v13, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18)));
    v28 = _mm_add_epi32(v16, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18 + 16)));
    v29 = _mm_add_epi32(v17, _mm_madd_epi16(v15, *(__m128i *)(a4 + 4 * v18 + 32)));
    v30 = _mm_cvtsi32_si64((unsigned __int16)sub_408E80(
                                               a4,
                                               a1,
                                               _mm_movepi64_pi64(_mm_add_epi32(_mm_srli_si128(v26, 8), v26))));
    v31 = _m_pinsrw(
            v30,
            sub_408E80(
              a4,
              a1,
              _m_paddd(_m_pmaddwd(v30, v7), _mm_movepi64_pi64(_mm_add_epi32(_mm_srli_si128(v27, 8), v27)))),
            1);
    v32 = _m_pinsrw(
            v31,
            sub_408E80(
              a4,
              a1,
              _m_paddd(_m_pmaddwd(v31, v8), _mm_movepi64_pi64(_mm_add_epi32(_mm_srli_si128(v28, 8), v28)))),
            2);
    result = sub_408E80(
               a4,
               a1,
               _m_paddd(_m_pmaddwd(v32, v9), _mm_movepi64_pi64(_mm_add_epi32(_mm_srli_si128(v29, 8), v29))));
    *(_QWORD *)(v5 + v6) = _m_pinsrw(v32, result, 3);
    v5 += 8;
  }
  while ( v34 != 1 );
  _m_femms();
  return result;
}

//----- (00409173) --------------------------------------------------------
signed int __cdecl sub_409173(int a1, int a2, int a3, int a4)
{
  int v4; // edi@1
  int v5; // eax@2
  int v6; // ecx@3
  int v7; // ecx@4
  unsigned int v8; // ebx@4
  int v9; // esi@5
  int v10; // edx@6
  int v11; // edx@7
  int v12; // edx@13
  int v13; // edx@14
  int v14; // esi@14
  int v15; // edx@15
  int v16; // ST00_4@16
  int v17; // ebx@17
  unsigned int v18; // ebx@18
  int v19; // esi@22
  int v20; // edx@22
  int v21; // edi@23
  int v28; // eax@32
  int v30; // [sp-4h] [bp-28h]@21
  int v31; // [sp+0h] [bp-24h]@1
  signed int v32; // [sp+4h] [bp-20h]@1
  int v33; // [sp+8h] [bp-1Ch]@1
  int v34; // [sp+Ch] [bp-18h]@1
  int v35; // [sp+10h] [bp-14h]@1
  int v36; // [sp+30h] [bp+Ch]@1

  v31 = *(_DWORD *)a1;
  v32 = *(_DWORD *)(a1 + 8);
  v33 = *(_DWORD *)(a1 + 24);
  v34 = *(_DWORD *)(a1 + 20);
  v35 = *(_DWORD *)(a1 + 32);
  v36 = a3 + 4 * a4;
  v4 = -a4;
  if ( a4 )
  {
    do
    {
      while ( 1 )
      {
        v5 = a2;
        if ( v31 > *(_DWORD *)(a2 + 36) )
        {
          v8 = sub_408518(a2, v31);
          v5 = a2;
        }
        else
        {
          v6 = *(_DWORD *)(a2 + 40);
          *(_DWORD *)(a2 + 36) -= v31;
          if ( v31 > v6 )
          {
            v9 = 32 - v31;
            if ( v6 )
            {
              *(_DWORD *)(a2 + 40) = v6 + v9;
              v10 = *(_DWORD *)(a2 + 24) + 4;
              *(_DWORD *)(a2 + 24) = v10;
              v8 = (*(_DWORD *)v10 << (v6 + v9) >> v9) | (*(_DWORD *)(v10 - 4) >> (32 - v6));
            }
            else
            {
              *(_DWORD *)(a2 + 40) = v9;
              v11 = *(_DWORD *)(a2 + 24) + 4;
              *(_DWORD *)(a2 + 24) = v11;
              v8 = (0xFFFFFFFFu >> v9) & *(_DWORD *)v11;
            }
          }
          else
          {
            v7 = v6 - v31;
            *(_DWORD *)(a2 + 40) = v7;
            v8 = **(_DWORD **)(a2 + 24) << v7 >> (32 - v31);
          }
        }
        if ( (signed int)v8 >= v32 )
          break;
        *(_DWORD *)(v36 + 4 * v4++) = (v8 >> 1) ^ -(v8 & 1);
        if ( v4 >= 0 )
          return 1;
      }
      if ( *(_DWORD *)(v5 + 36) )
      {
        v12 = *(_DWORD *)(v5 + 40);
        --*(_DWORD *)(v5 + 36);
        if ( v12 )
        {
          v13 = v12 - 1;
          *(_DWORD *)(v5 + 40) = v13;
          v14 = (**(_DWORD **)(v5 + 24) >> (31 - v13)) & 1;
        }
        else
        {
          *(_DWORD *)(v5 + 40) = 31;
          v15 = *(_DWORD *)(v5 + 24) + 4;
          *(_DWORD *)(v5 + 24) = v15;
          v14 = *(_DWORD *)v15 & 1;
        }
      }
      else
      {
        v16 = v5;
        v14 = sub_408704(v5);
        v5 = v16;
      }
      v17 = (v14 << v31) | v8;
      if ( v17 >= v33 )
      {
        v30 = v4;
        if ( *(_DWORD *)(v5 + 36) < 9 )
        {
          _EDX = sub_408758(v5, 9);
        }
        else
        {
          v19 = *(_DWORD *)(v5 + 40);
          v20 = *(_DWORD *)(v5 + 24);
          if ( v19 )
          {
            v21 = *(_DWORD *)v20 >> (32 - v19);
            if ( v19 < 9 )
              v21 |= *(_DWORD *)(v20 + 4) << v19;
          }
          else
          {
            v21 = *(_DWORD *)(v20 + 4);
          }
          _EDI = v21 | 0x200;
          __asm { bsf     edx, edi }
          if ( v19 < ((unsigned int)_EDX < 9) + _EDX )
          {
            *(_DWORD *)(v5 + 24) += 4;
            v19 += 32;
          }
          *(_DWORD *)(v5 + 40) = (__PAIR__(v19, _EDX) - __PAIR__(_EDX, 9)) >> 32;
          *(_DWORD *)(v5 + 36) = (__PAIR__(*(_DWORD *)(v5 + 36), _EDX) - __PAIR__(_EDX, 9)) >> 32;
        }
        v4 = v30;
        if ( (unsigned int)_EDX >= 9 )
        {
          v18 = v35 + v17;
          v28 = sub_40864C(a2, 3);
          if ( v28 == 7 )
          {
            v28 = sub_40864C(a2, 5) + 7;
            if ( (unsigned int)v28 > 0x1D )
              return 0;
LABEL_36:
            v18 += v34 * (sub_40864C(a2, v28) + 1);
            goto LABEL_19;
          }
          if ( v28 )
            goto LABEL_36;
        }
        else
        {
          v18 = v34 * _EDX + v17 - v32;
        }
      }
      else
      {
        v18 = v17 - (v32 & -v14);
      }
LABEL_19:
      *(_DWORD *)(v36 + 4 * v4++) = (v18 >> 1) ^ -(v18 & 1);
    }
    while ( v4 < 0 );
  }
  return 1;
}

//----- (004093C7) --------------------------------------------------------
int __usercall sub_4093C7<eax>(int result<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>)
{
  int v4; // ecx@2
  int v5; // edx@2
  int v6; // ecx@2
  __m64 v7; // mm4@2
  __m64 v8; // mm2@3
  __m64 v9; // mm3@3
  __m64 v10; // mm0@3
  __m64 v11; // mm1@3

  if ( a3 >= 4 )
  {
    v4 = a3 & 0xFFFFFFFC;
    result += 4 * v4;
    v5 = a2 + 4 * v4;
    v6 = -v4;
    v7 = _m_psubd(0i64, _m_pcmpeqd(a4, a4));
    do
    {
      v8 = *(__m64 *)(v5 + 4 * v6);
      v9 = *(__m64 *)(v5 + 4 * v6 + 8);
      v10 = _m_paddd(_m_pslld(*(__m64 *)(result + 4 * v6), 1u), _m_pand(*(__m64 *)(v5 + 4 * v6), v7));
      v11 = _m_paddd(_m_pslld(*(__m64 *)(result + 4 * v6 + 8), 1u), _m_pand(*(__m64 *)(v5 + 4 * v6 + 8), v7));
      *(_QWORD *)(result + 4 * v6) = _m_psrad(_m_psubd(v10, v8), 1u);
      *(_QWORD *)(result + 4 * v6 + 8) = _m_psrad(_m_psubd(v11, v9), 1u);
      *(_QWORD *)(v5 + 4 * v6) = _m_psrad(_m_paddd(v10, v8), 1u);
      *(_QWORD *)(v5 + 4 * v6 + 8) = _m_psrad(_m_paddd(v11, v9), 1u);
      v6 += 4;
    }
    while ( v6 < 0 );
    _m_femms();
  }
  return result;
}

//----- (00409459) --------------------------------------------------------
int __userpurge sub_409459<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4, unsigned __int16 a5)
{
  __m64 v6; // mm6@1
  __m64 v7; // mm6@1
  __m64 v8; // mm5@1
  __m64 v9; // mm5@1
  __m64 v10; // mm7@1
  int v11; // ecx@1
  int result; // eax@1
  int v13; // edx@1
  int v14; // ecx@1
  __m64 v15; // mm1@2

  v6 = _mm_cvtsi32_si64((unsigned __int16)a4);
  v7 = _m_punpckldq(v6, v6);
  v8 = _mm_cvtsi32_si64(0x80u);
  v9 = _m_punpckldq(v8, v8);
  v10 = _mm_cvtsi32_si64(a3);
  v11 = ecx0 & 0xFFFFFFFC;
  result = a1 + 4 * v11;
  v13 = a2 + 4 * v11;
  v14 = -v11;
  do
  {
    v15 = _m_psubd(
            _m_pslld(_m_psrad(_m_paddd(_m_pmaddwd(_m_psrad(*(__m64 *)(result + 4 * v14 + 8), v10), v7), v9), 8u), v10),
            *(__m64 *)(v13 + 4 * v14 + 8));
    *(_QWORD *)(v13 + 4 * v14) = _m_psubd(
                                   _m_pslld(
                                     _m_psrad(
                                       _m_paddd(_m_pmaddwd(_m_psrad(*(__m64 *)(result + 4 * v14), v10), v7), v9),
                                       8u),
                                     v10),
                                   *(__m64 *)(v13 + 4 * v14));
    *(_QWORD *)(v13 + 4 * v14 + 8) = v15;
    v14 += 4;
  }
  while ( v14 < 0 );
  _m_femms();
  return result;
}

//----- (004094D0) --------------------------------------------------------
int __cdecl sub_4094D0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A854;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A854: using guessed type int dword_41A854;

//----- (00409500) --------------------------------------------------------
void __cdecl sub_409500()
{
  char v0; // cf@1

  v0 = (unsigned int)dword_41A854-- < 1;
  if ( v0 )
    sub_4088A4();
}
// 41A854: using guessed type int dword_41A854;

//----- (00409510) --------------------------------------------------------
int __userpurge sub_409510<eax>(int result<eax>, int a2<edx>, unsigned int ecx0<ecx>, unsigned int a3, int a4)
{
  unsigned int v5; // esi@5

  if ( (signed int)ecx0 > 0 )
  {
    if ( a3 )
    {
      if ( (((ecx0 >> 1) - 1) & 0x80000000u) == 0 )
      {
        v5 = ecx0 >> 1;
        do
        {
          *(_DWORD *)a2 = (signed __int16)(*(_DWORD *)result >> a3);
          *(_DWORD *)(a2 + 4) = (signed __int16)(*(_DWORD *)(result + 4) >> a3);
          result += 8;
          a2 += 8;
          --v5;
        }
        while ( v5 );
      }
      if ( ecx0 & 1 )
      {
        result = (signed __int16)(*(_DWORD *)result >> a3);
        *(_DWORD *)a2 = (signed __int16)result;
      }
    }
    else
    {
      result = System::Move(result, a2);
    }
  }
  return result;
}

//----- (0040957C) --------------------------------------------------------
int __usercall sub_40957C<eax>(int result<eax>, int a2<edx>, char cl0<cl>)
{
  int v3; // edx@1
  int v4; // edx@2
  unsigned int v5; // ebx@2

  v3 = a2 - 1;
  if ( v3 >= 0 )
  {
    v4 = v3 + 1;
    v5 = 0;
    do
    {
      if ( v5 > 0x1FFFFFFE )
        sub_402CA8();
      *(_DWORD *)(result + 4 * v5++) <<= cl0;
      --v4;
    }
    while ( v4 );
  }
  return result;
}

//----- (004095A4) --------------------------------------------------------
int __cdecl sub_4095A4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A858;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A858: using guessed type int dword_41A858;

//----- (004095D4) --------------------------------------------------------
void __cdecl sub_4095D4()
{
  --dword_41A858;
}
// 41A858: using guessed type int dword_41A858;

//----- (00409634) --------------------------------------------------------
int __fastcall sub_409634(int a1)
{
  int v1; // ebx@1
  int result; // eax@1

  v1 = a1;
  result = *(_DWORD *)a1;
  if ( result )
  {
    System::__linkproc___FreeMem(result);
    result = 0;
    *(_DWORD *)v1 = 0;
  }
  return result;
}
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);

//----- (00409664) --------------------------------------------------------
int __userpurge sub_409664<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, signed int a5)
{
  int v6; // edi@3
  int v7; // ebx@3
  int v8; // eax@4
  int v9; // edx@5
  char v11; // [sp+Fh] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v6 = ecx0;
  v11 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 12) = v6;
  if ( a4 > 4 )
  {
    *(_DWORD *)(v7 + 4) = System::__linkproc___GetMem(v6 + a4 - 1);
    v9 = *(_DWORD *)(v7 + 4) % a4;
    if ( a4 == a4 - v9 )
      *(_DWORD *)(v7 + 8) = *(_DWORD *)(v7 + 4);
    else
      *(_DWORD *)(v7 + 8) = *(_DWORD *)(v7 + 4) + a4 - v9;
  }
  else
  {
    v8 = System::__linkproc___GetMem(v6);
    *(_DWORD *)(v7 + 4) = v8;
    *(_DWORD *)(v7 + 8) = v8;
  }
  *(_DWORD *)a3 = *(_DWORD *)(v7 + 8);
  if ( v11 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (004096F8) --------------------------------------------------------
int __cdecl sub_4096F8()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // eax@1
  int v5; // edx@3
  int result; // eax@3

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  v4 = *(_DWORD *)(v0 + 4);
  if ( v4 )
    System::__linkproc___FreeMem(v4);
  v5 = v2;
  LOBYTE(v5) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v5);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (0040972C) --------------------------------------------------------
int __cdecl sub_40972C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A85C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A85C: using guessed type int dword_41A85C;

//----- (0040975C) --------------------------------------------------------
void __cdecl sub_40975C()
{
  --dword_41A85C;
}
// 41A85C: using guessed type int dword_41A85C;

//----- (00409764) --------------------------------------------------------
signed int __usercall sub_409764<eax>(char _CF<cf>, char _ZF<zf>, char _SF<sf>, char _OF<of>, int a5<eax>, int a6<edx>)
{
  int v6; // esi@1
  int v7; // edi@1
  int v8; // eax@1
  signed int result; // eax@3
  int v20; // [sp-4h] [bp-10h]@0

  v6 = a5;
  v7 = a6;
  __asm { pushf }
  v8 = v20 ^ v20 ^ 0x200000;
  if ( !(v8 & 0x200000) )
    goto LABEL_7;
  _EAX = 0;
  __asm { cpuid }
  if ( _EAX )
  {
    _EAX = 1;
    __asm { cpuid }
    *(_DWORD *)v6 = _EDX;
    *(_DWORD *)v7 = _ECX;
    result = 1;
  }
  else
  {
LABEL_7:
    result = 0;
  }
  return result;
}

//----- (004097A4) --------------------------------------------------------
int __cdecl sub_4097A4()
{
  __asm
  {
    fxsave  [esp+204h+var_204]
    fxrstor [esp+204h+var_204]
    fxsave  [esp+204h+var_204]
    fxrstor [esp+204h+var_204]
  }
  return 0;
}

//----- (004097EC) --------------------------------------------------------
signed int __usercall sub_4097EC<eax>(char a1<cf>, char a2<zf>, char a3<sf>, char a4<of>, int a5<eax>)
{
  int v5; // ebx@1
  signed int result; // eax@1
  int v7; // [sp+0h] [bp-Ch]@1
  char v8; // [sp+4h] [bp-8h]@1
  char v9; // [sp+5h] [bp-7h]@7

  v5 = a5;
  *(_BYTE *)a5 = 0;
  *(_BYTE *)(a5 + 1) = 0;
  *(_BYTE *)(a5 + 2) = 0;
  *(_BYTE *)(a5 + 3) = 0;
  *(_BYTE *)(a5 + 4) = 0;
  *(_BYTE *)(a5 + 5) = 0;
  result = sub_409764(a1, a2, a3, a4, (int)&v7, (int)&v8);
  if ( (_BYTE)result )
  {
    *(_BYTE *)v5 = 1;
    if ( BYTE2(v7) & 0x80 )
    {
      *(_BYTE *)(v5 + 1) = 1;
      if ( BYTE3(v7) & 2 )
      {
        result = sub_4097A4();
        if ( (_BYTE)result )
        {
          *(_BYTE *)(v5 + 2) = 1;
          if ( BYTE3(v7) & 4 )
          {
            *(_BYTE *)(v5 + 3) = 1;
            if ( v8 & 1 )
            {
              *(_BYTE *)(v5 + 4) = 1;
              *(_BYTE *)(v5 + 5) = (v9 & 2) != 0;
            }
          }
        }
      }
    }
  }
  LOBYTE(result) = *(_BYTE *)v5;
  return result;
}

//----- (00409864) --------------------------------------------------------
int __cdecl sub_409864()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A860;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A860: using guessed type int dword_41A860;

//----- (00409894) --------------------------------------------------------
void __cdecl sub_409894()
{
  --dword_41A860;
}
// 41A860: using guessed type int dword_41A860;

//----- (004098FC) --------------------------------------------------------
signed int __usercall sub_4098FC<eax>(char a1<cf>, char a2<zf>, char a3<sf>, char a4<of>, int a5<eax>)
{
  int v5; // ebx@1
  signed int result; // eax@1
  int v7; // [sp+0h] [bp-Ch]@1
  char v8; // [sp+5h] [bp-7h]@1

  v5 = a5;
  result = sub_4097EC(a1, a2, a3, a4, (int)&v7);
  *(_BYTE *)(v5 + 16) = BYTE1(v7);
  *(_BYTE *)(v5 + 17) = BYTE3(v7);
  LOBYTE(result) = v8;
  *(_BYTE *)(v5 + 18) = v8;
  return result;
}

//----- (00409924) --------------------------------------------------------
int __fastcall sub_409924(int result, int a2)
{
  *(_DWORD *)(result + 4) = a2;
  if ( !*(_BYTE *)(result + 16) )
    *(_DWORD *)(result + 4) &= 0xFFFFFFFDu;
  if ( !*(_BYTE *)(result + 17) )
    *(_DWORD *)(result + 4) &= 0xFFFFFFF7u;
  if ( !*(_BYTE *)(result + 18) )
    *(_DWORD *)(result + 4) &= 0xFFFFFFDFu;
  *(_BYTE *)(result + 19) = (*(_BYTE *)(result + 4) & 2) != 0;
  *(_BYTE *)(result + 20) = (*(_BYTE *)(result + 4) & 8) != 0;
  *(_BYTE *)(result + 21) = (*(_BYTE *)(result + 4) & 0x20) != 0;
  return result;
}

//----- (00409964) --------------------------------------------------------
int __fastcall sub_409964(int a1, int a2)
{
  *(_DWORD *)(a1 + 4) = *(_DWORD *)a2;
  *(_DWORD *)(a1 + 8) = *(_DWORD *)(a2 + 4);
  *(_DWORD *)(a1 + 12) = *(_DWORD *)(a2 + 8);
  return sub_409924(a1, *(_DWORD *)a2);
}

//----- (00409980) --------------------------------------------------------
int __fastcall sub_409980(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3
  char v4; // cf@3
  char v5; // zf@3
  char v6; // sf@3
  char v7; // of@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  sub_4098FC(v4, v5, v6, v7, v3);
  sub_409964(v3, (int)off_419498);
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 419498: using guessed type void *off_419498;

//----- (004099CC) --------------------------------------------------------
int __cdecl sub_4099CC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A864;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A864: using guessed type int dword_41A864;

//----- (004099FC) --------------------------------------------------------
void __cdecl sub_4099FC()
{
  --dword_41A864;
}
// 41A864: using guessed type int dword_41A864;

//----- (00409A04) --------------------------------------------------------
int __usercall sub_409A04<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@5
  int v4; // edx@5
  __int16 v5; // bx@6
  int v6; // ecx@6
  signed int v8; // [sp+0h] [bp-10h]@1

  v8 = a2;
  if ( a2 > 0 )
  {
    if ( a1 & 1 )
    {
      ecx0 = (ecx0 << 8) ^ dword_4182A4[(unsigned __int8)(*(_BYTE *)a1++ ^ ((unsigned int)ecx0 >> 16))];
      v8 = a2 - 1;
    }
    if ( v8 / 2 - 1 >= 0 )
    {
      v3 = v8 / 2;
      v4 = 0;
      do
      {
        v5 = *(_WORD *)(a1 + 2 * v4);
        v6 = (ecx0 << 8) ^ dword_4182A4[(unsigned __int8)(v5 ^ ((unsigned int)ecx0 >> 16))];
        ecx0 = (v6 << 8) ^ dword_4182A4[(unsigned __int8)(HIBYTE(v5) ^ ((unsigned int)v6 >> 16))];
        ++v4;
        --v3;
      }
      while ( v3 );
    }
    if ( v8 & 1 )
      ecx0 = (ecx0 << 8) ^ dword_4182A4[(unsigned __int8)(((unsigned int)ecx0 >> 16) ^ *(_BYTE *)(a1 + (v8 & 0xFFFFFFFE)))];
    ecx0 &= 0xFFFFFFu;
  }
  return ecx0;
}
// 4182A4: using guessed type int dword_4182A4[];

//----- (00409AC8) --------------------------------------------------------
int __fastcall sub_409AC8(int a1, signed int a2)
{
  return sub_409A04(a1, a2, 11994318);
}

//----- (00409AD4) --------------------------------------------------------
int __cdecl sub_409AD4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A868;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A868: using guessed type int dword_41A868;

//----- (00409B04) --------------------------------------------------------
void __cdecl sub_409B04()
{
  --dword_41A868;
}
// 41A868: using guessed type int dword_41A868;

//----- (00409B64) --------------------------------------------------------
int __fastcall sub_409B64(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  sub_409BA0(v3);
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (00409BA0) --------------------------------------------------------
int __fastcall sub_409BA0(int result)
{
  *(_DWORD *)(result + 4) = 1732584193;
  *(_DWORD *)(result + 8) = -271733879;
  *(_DWORD *)(result + 12) = -1732584194;
  *(_DWORD *)(result + 16) = 271733878;
  *(_DWORD *)(result + 24) = 0;
  *(_DWORD *)(result + 28) = 0;
  *(_DWORD *)(result + 96) = 0;
  return result;
}

//----- (00409BD0) --------------------------------------------------------
int __usercall sub_409BD0<eax>(int a1<eax>, int a2<edx>, unsigned int ecx0<ecx>)
{
  unsigned int v3; // ebp@1
  int v4; // edi@1
  int v5; // esi@1
  int result; // eax@1
  unsigned __int8 v7; // cf@1
  int v8; // ecx@1
  int v9; // ebx@2
  unsigned int v10; // ebx@11
  int v11; // ebx@13
  __int64 v12; // [sp+0h] [bp-18h]@2

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  result = ecx0;
  v7 = __CFADD__(ecx0, *(_DWORD *)(v5 + 24));
  *(_DWORD *)(v5 + 24) += ecx0;
  *(_DWORD *)(v5 + 28) += v7;
  v8 = *(_DWORD *)(v5 + 96);
  if ( v8 <= 0 )
    goto LABEL_10;
  v9 = 64 - v8;
  v12 = 64 - v8;
  if ( HIDWORD(v12) )
  {
    result = (unsigned __int64)(64 - v8) >> 32;
    if ( SHIDWORD(v12) > 0 )
    {
LABEL_6:
      v9 = v3;
      goto LABEL_7;
    }
  }
  else
  {
    result = 0;
    if ( v3 < (unsigned int)v12 )
      goto LABEL_6;
  }
LABEL_7:
  if ( v9 > 0 )
  {
    result = System::Move(a2, v5 + v8 + 32);
    *(_DWORD *)(v5 + 96) += v9;
    v4 += v9;
    v3 -= v9;
    if ( *(_DWORD *)(v5 + 96) == 64 )
    {
      sub_409CFC(v5 + 4, v5 + 32);
      result = 0;
      *(_DWORD *)(v5 + 96) = 0;
    }
  }
LABEL_10:
  if ( (((v3 >> 6) - 1) & 0x80000000u) == 0 )
  {
    v10 = v3 >> 6;
    do
    {
      result = sub_409CFC(v5 + 4, v4);
      v4 += 64;
      --v10;
    }
    while ( v10 );
  }
  v11 = v3 & 0x3F;
  if ( v11 > 0 )
  {
    result = System::Move(v4, v5 + 32);
    *(_DWORD *)(v5 + 96) = v11;
  }
  return result;
}

//----- (00409C78) --------------------------------------------------------
int __fastcall sub_409C78(int a1)
{
  int v1; // ebx@1
  unsigned int v2; // esi@1
  __int64 v4; // [sp+0h] [bp-50h]@1
  char v5; // [sp+8h] [bp-48h]@1

  v1 = a1;
  v4 = 8i64 * *(_QWORD *)(a1 + 24);
  v2 = ((119 - (*(_DWORD *)(a1 + 24) & 0x3F)) & 0x3F) + 1;
  System::__linkproc___FillChar(&v5, ((119 - (*(_DWORD *)(a1 + 24) & 0x3F)) & 0x3F) + 1, v4);
  v5 = -128;
  sub_409BD0(v1, (int)&v5, v2);
  return sub_409BD0(v1, (int)&v4, 8u);
}
// 4027B8: using guessed type int __fastcall System____linkproc__ FillChar(_DWORD, _DWORD, _DWORD);

//----- (00409CD8) --------------------------------------------------------
char __fastcall sub_409CD8(int a1, int a2)
{
  return *(_DWORD *)a1 == *(_DWORD *)a2
      && *(_DWORD *)(a1 + 4) == *(_DWORD *)(a2 + 4)
      && *(_DWORD *)(a1 + 8) == *(_DWORD *)(a2 + 8)
      && *(_DWORD *)(a1 + 12) == *(_DWORD *)(a2 + 12);
}

//----- (00409CFC) --------------------------------------------------------
int __fastcall sub_409CFC(int a1, int a2)
{
  int v2; // ecx@1
  int v3; // ebx@1
  int v4; // esi@1
  int v5; // edi@1
  int v6; // ebp@1
  int v7; // eax@1
  int v8; // edx@1
  int v9; // eax@1
  int v10; // ebp@1
  int v11; // eax@1
  int v12; // edi@1
  int v13; // eax@1
  int v14; // esi@1
  int v15; // eax@1
  int v16; // edx@1
  int v17; // eax@1
  int v18; // ebp@1
  int v19; // eax@1
  int v20; // edi@1
  int v21; // eax@1
  int v22; // esi@1
  int v23; // eax@1
  int v24; // edx@1
  int v25; // eax@1
  int v26; // ebp@1
  int v27; // eax@1
  int v28; // edi@1
  int v29; // eax@1
  int v30; // esi@1
  int v31; // eax@1
  int v32; // edx@1
  int v33; // eax@1
  int v34; // ebp@1
  int v35; // eax@1
  int v36; // edi@1
  int v37; // eax@1
  int v38; // esi@1
  int v39; // eax@1
  int v40; // edx@1
  int v41; // eax@1
  int v42; // ebp@1
  int v43; // eax@1
  int v44; // edi@1
  int v45; // eax@1
  int v46; // esi@1
  int v47; // eax@1
  int v48; // edx@1
  int v49; // eax@1
  int v50; // ebp@1
  int v51; // eax@1
  int v52; // edi@1
  int v53; // eax@1
  int v54; // esi@1
  int v55; // eax@1
  int v56; // edx@1
  int v57; // eax@1
  int v58; // ebp@1
  int v59; // eax@1
  int v60; // edi@1
  int v61; // eax@1
  int v62; // esi@1
  int v63; // eax@1
  int v64; // edx@1
  int v65; // eax@1
  int v66; // ebp@1
  int v67; // eax@1
  int v68; // edi@1
  int v69; // eax@1
  int v70; // esi@1
  int v71; // eax@1
  int v72; // edx@1
  int v73; // eax@1
  int v74; // ebp@1
  int v75; // eax@1
  int v76; // edi@1
  int v77; // eax@1
  int v78; // esi@1
  int v79; // eax@1
  int v80; // edx@1
  int v81; // eax@1
  int v82; // ebp@1
  int v83; // eax@1
  int v84; // edi@1
  int v85; // eax@1
  int v86; // esi@1
  int v87; // eax@1
  int v88; // edx@1
  int v89; // eax@1
  int v90; // ebp@1
  int v91; // eax@1
  int v92; // edi@1
  int v93; // eax@1
  int v94; // esi@1
  int v95; // eax@1
  int v96; // edx@1
  int v97; // eax@1
  int v98; // ebp@1
  int v99; // eax@1
  int v100; // edi@1
  int v101; // eax@1
  int v102; // esi@1
  int v103; // eax@1
  int v104; // edx@1
  int v105; // eax@1
  int v106; // ebp@1
  int v107; // eax@1
  int v108; // edi@1
  int v109; // eax@1
  int v110; // esi@1
  int v111; // eax@1
  int v112; // edx@1
  int v113; // eax@1
  int v114; // ebp@1
  int v115; // eax@1
  int v116; // edi@1
  int v117; // eax@1
  int v118; // esi@1
  int v119; // eax@1
  int v120; // edx@1
  int v121; // eax@1
  int v122; // ebp@1
  int v123; // eax@1
  int v124; // edi@1
  int v125; // eax@1
  int v126; // esi@1
  int v127; // eax@1
  int v128; // edx@1
  int v129; // eax@1
  int v130; // ebp@1
  int v131; // eax@1
  int v132; // edi@1
  int v133; // eax@1
  int result; // eax@1

  v2 = a1;
  v3 = a2;
  v4 = *(_DWORD *)(a1 + 4);
  v5 = *(_DWORD *)(a1 + 8);
  v6 = *(_DWORD *)(a1 + 12);
  v7 = __ROL__(*(_DWORD *)a2 + *(_DWORD *)a1 + (v6 ^ v4 & (v5 ^ *(_DWORD *)(a1 + 12))) - 680876936, 7);
  v8 = v4 + v7;
  v9 = __ROL__(*(_DWORD *)(v3 + 4) + v6 + (v5 ^ (v4 + v7) & (v4 ^ v5)) - 389564586, 12);
  v10 = v8 + v9;
  v11 = __ROL__(*(_DWORD *)(v3 + 8) + v5 + (v4 ^ (v8 + v9) & (v8 ^ v4)) + 606105819, 17);
  v12 = v10 + v11;
  v13 = __ROL__(*(_DWORD *)(v3 + 12) + v4 + (v8 ^ (v10 + v11) & (v10 ^ v8)) - 1044525330, 22);
  v14 = v12 + v13;
  v15 = __ROL__(*(_DWORD *)(v3 + 16) + v8 + (v10 ^ (v12 + v13) & (v12 ^ v10)) - 176418897, 7);
  v16 = v14 + v15;
  v17 = __ROL__(*(_DWORD *)(v3 + 20) + v10 + (v12 ^ (v14 + v15) & (v14 ^ v12)) + 1200080426, 12);
  v18 = v16 + v17;
  v19 = __ROL__(*(_DWORD *)(v3 + 24) + v12 + (v14 ^ (v16 + v17) & (v16 ^ v14)) - 1473231341, 17);
  v20 = v18 + v19;
  v21 = __ROL__(*(_DWORD *)(v3 + 28) + v14 + (v16 ^ (v18 + v19) & (v18 ^ v16)) - 45705983, 22);
  v22 = v20 + v21;
  v23 = __ROL__(*(_DWORD *)(v3 + 32) + v16 + (v18 ^ (v20 + v21) & (v20 ^ v18)) + 1770035416, 7);
  v24 = v22 + v23;
  v25 = __ROL__(*(_DWORD *)(v3 + 36) + v18 + (v20 ^ (v22 + v23) & (v22 ^ v20)) - 1958414417, 12);
  v26 = v24 + v25;
  v27 = __ROL__(*(_DWORD *)(v3 + 40) + v20 + (v22 ^ (v24 + v25) & (v24 ^ v22)) - 42063, 17);
  v28 = v26 + v27;
  v29 = __ROL__(*(_DWORD *)(v3 + 44) + v22 + (v24 ^ (v26 + v27) & (v26 ^ v24)) - 1990404162, 22);
  v30 = v28 + v29;
  v31 = __ROL__(*(_DWORD *)(v3 + 48) + v24 + (v26 ^ (v28 + v29) & (v28 ^ v26)) + 1804603682, 7);
  v32 = v30 + v31;
  v33 = __ROL__(*(_DWORD *)(v3 + 52) + v26 + (v28 ^ (v30 + v31) & (v30 ^ v28)) - 40341101, 12);
  v34 = v32 + v33;
  v35 = __ROL__(*(_DWORD *)(v3 + 56) + v28 + (v30 ^ (v32 + v33) & (v32 ^ v30)) - 1502002290, 17);
  v36 = v34 + v35;
  v37 = __ROL__(*(_DWORD *)(v3 + 60) + v30 + (v32 ^ (v34 + v35) & (v34 ^ v32)) + 1236535329, 22);
  v38 = v36 + v37;
  v39 = __ROL__(*(_DWORD *)(v3 + 4) + v32 + (v36 ^ v34 & ((v36 + v37) ^ v36)) - 165796510, 5);
  v40 = v38 + v39;
  v41 = __ROL__(*(_DWORD *)(v3 + 24) + v34 + (v38 ^ v36 & ((v38 + v39) ^ v38)) - 1069501632, 9);
  v42 = v40 + v41;
  v43 = __ROL__(*(_DWORD *)(v3 + 44) + v36 + (v40 ^ v38 & ((v40 + v41) ^ v40)) + 643717713, 14);
  v44 = v42 + v43;
  v45 = __ROL__(*(_DWORD *)v3 + v38 + (v42 ^ v40 & ((v42 + v43) ^ v42)) - 373897302, 20);
  v46 = v44 + v45;
  v47 = __ROL__(*(_DWORD *)(v3 + 20) + v40 + (v44 ^ v42 & ((v44 + v45) ^ v44)) - 701558691, 5);
  v48 = v46 + v47;
  v49 = __ROL__(*(_DWORD *)(v3 + 40) + v42 + (v46 ^ v44 & ((v46 + v47) ^ v46)) + 38016083, 9);
  v50 = v48 + v49;
  v51 = __ROL__(*(_DWORD *)(v3 + 60) + v44 + (v48 ^ v46 & ((v48 + v49) ^ v48)) - 660478335, 14);
  v52 = v50 + v51;
  v53 = __ROL__(*(_DWORD *)(v3 + 16) + v46 + (v50 ^ v48 & ((v50 + v51) ^ v50)) - 405537848, 20);
  v54 = v52 + v53;
  v55 = __ROL__(*(_DWORD *)(v3 + 36) + v48 + (v52 ^ v50 & ((v52 + v53) ^ v52)) + 568446438, 5);
  v56 = v54 + v55;
  v57 = __ROL__(*(_DWORD *)(v3 + 56) + v50 + (v54 ^ v52 & ((v54 + v55) ^ v54)) - 1019803690, 9);
  v58 = v56 + v57;
  v59 = __ROL__(*(_DWORD *)(v3 + 12) + v52 + (v56 ^ v54 & ((v56 + v57) ^ v56)) - 187363961, 14);
  v60 = v58 + v59;
  v61 = __ROL__(*(_DWORD *)(v3 + 32) + v54 + (v58 ^ v56 & ((v58 + v59) ^ v58)) + 1163531501, 20);
  v62 = v60 + v61;
  v63 = __ROL__(*(_DWORD *)(v3 + 52) + v56 + (v60 ^ v58 & ((v60 + v61) ^ v60)) - 1444681467, 5);
  v64 = v62 + v63;
  v65 = __ROL__(*(_DWORD *)(v3 + 8) + v58 + (v62 ^ v60 & ((v62 + v63) ^ v62)) - 51403784, 9);
  v66 = v64 + v65;
  v67 = __ROL__(*(_DWORD *)(v3 + 28) + v60 + (v64 ^ v62 & ((v64 + v65) ^ v64)) + 1735328473, 14);
  v68 = v66 + v67;
  v69 = __ROL__(*(_DWORD *)(v3 + 48) + v62 + (v66 ^ v64 & ((v66 + v67) ^ v66)) - 1926607734, 20);
  v70 = v68 + v69;
  v71 = __ROL__(*(_DWORD *)(v3 + 20) + v64 + ((v68 + v69) ^ v68 ^ v66) - 378558, 4);
  v72 = v70 + v71;
  v73 = __ROL__(*(_DWORD *)(v3 + 32) + v66 + ((v70 + v71) ^ v70 ^ v68) - 2022574463, 11);
  v74 = v72 + v73;
  v75 = __ROL__(*(_DWORD *)(v3 + 44) + v68 + ((v72 + v73) ^ v72 ^ v70) + 1839030562, 16);
  v76 = v74 + v75;
  v77 = __ROL__(*(_DWORD *)(v3 + 56) + v70 + ((v74 + v75) ^ v74 ^ v72) - 35309556, 23);
  v78 = v76 + v77;
  v79 = __ROL__(*(_DWORD *)(v3 + 4) + v72 + ((v76 + v77) ^ v76 ^ v74) - 1530992060, 4);
  v80 = v78 + v79;
  v81 = __ROL__(*(_DWORD *)(v3 + 16) + v74 + ((v78 + v79) ^ v78 ^ v76) + 1272893353, 11);
  v82 = v80 + v81;
  v83 = __ROL__(*(_DWORD *)(v3 + 28) + v76 + ((v80 + v81) ^ v80 ^ v78) - 155497632, 16);
  v84 = v82 + v83;
  v85 = __ROL__(*(_DWORD *)(v3 + 40) + v78 + ((v82 + v83) ^ v82 ^ v80) - 1094730640, 23);
  v86 = v84 + v85;
  v87 = __ROL__(*(_DWORD *)(v3 + 52) + v80 + ((v84 + v85) ^ v84 ^ v82) + 681279174, 4);
  v88 = v86 + v87;
  v89 = __ROL__(*(_DWORD *)v3 + v82 + ((v86 + v87) ^ v86 ^ v84) - 358537222, 11);
  v90 = v88 + v89;
  v91 = __ROL__(*(_DWORD *)(v3 + 12) + v84 + ((v88 + v89) ^ v88 ^ v86) - 722521979, 16);
  v92 = v90 + v91;
  v93 = __ROL__(*(_DWORD *)(v3 + 24) + v86 + ((v90 + v91) ^ v90 ^ v88) + 76029189, 23);
  v94 = v92 + v93;
  v95 = __ROL__(*(_DWORD *)(v3 + 36) + v88 + ((v92 + v93) ^ v92 ^ v90) - 640364487, 4);
  v96 = v94 + v95;
  v97 = __ROL__(*(_DWORD *)(v3 + 48) + v90 + ((v94 + v95) ^ v94 ^ v92) - 421815835, 11);
  v98 = v96 + v97;
  v99 = __ROL__(*(_DWORD *)(v3 + 60) + v92 + ((v96 + v97) ^ v96 ^ v94) + 530742520, 16);
  v100 = v98 + v99;
  v101 = __ROL__(*(_DWORD *)(v3 + 8) + v94 + ((v98 + v99) ^ v98 ^ v96) - 995338651, 23);
  v102 = v100 + v101;
  v103 = __ROL__(*(_DWORD *)v3 + v96 + (v100 ^ ((v100 + v101) | ~v98)) - 198630844, 6);
  v104 = v102 + v103;
  v105 = __ROL__(*(_DWORD *)(v3 + 28) + v98 + (v102 ^ ((v102 + v103) | ~v100)) + 1126891415, 10);
  v106 = v104 + v105;
  v107 = __ROL__(*(_DWORD *)(v3 + 56) + v100 + (v104 ^ ((v104 + v105) | ~v102)) - 1416354905, 15);
  v108 = v106 + v107;
  v109 = __ROL__(*(_DWORD *)(v3 + 20) + v102 + (v106 ^ ((v106 + v107) | ~v104)) - 57434055, 21);
  v110 = v108 + v109;
  v111 = __ROL__(*(_DWORD *)(v3 + 48) + v104 + (v108 ^ ((v108 + v109) | ~v106)) + 1700485571, 6);
  v112 = v110 + v111;
  v113 = __ROL__(*(_DWORD *)(v3 + 12) + v106 + (v110 ^ ((v110 + v111) | ~v108)) - 1894986606, 10);
  v114 = v112 + v113;
  v115 = __ROL__(*(_DWORD *)(v3 + 40) + v108 + (v112 ^ ((v112 + v113) | ~v110)) - 1051523, 15);
  v116 = v114 + v115;
  v117 = __ROL__(*(_DWORD *)(v3 + 4) + v110 + (v114 ^ ((v114 + v115) | ~v112)) - 2054922799, 21);
  v118 = v116 + v117;
  v119 = __ROL__(*(_DWORD *)(v3 + 32) + v112 + (v116 ^ ((v116 + v117) | ~v114)) + 1873313359, 6);
  v120 = v118 + v119;
  v121 = __ROL__(*(_DWORD *)(v3 + 60) + v114 + (v118 ^ ((v118 + v119) | ~v116)) - 30611744, 10);
  v122 = v120 + v121;
  v123 = __ROL__(*(_DWORD *)(v3 + 24) + v116 + (v120 ^ ((v120 + v121) | ~v118)) - 1560198380, 15);
  v124 = v122 + v123;
  v125 = __ROL__(*(_DWORD *)(v3 + 52) + v118 + (v122 ^ ((v122 + v123) | ~v120)) + 1309151649, 21);
  v126 = v124 + v125;
  v127 = __ROL__(*(_DWORD *)(v3 + 16) + v120 + (v124 ^ ((v124 + v125) | ~v122)) - 145523070, 6);
  v128 = v126 + v127;
  v129 = __ROL__(*(_DWORD *)(v3 + 44) + v122 + (v126 ^ ((v126 + v127) | ~v124)) - 1120210379, 10);
  v130 = v128 + v129;
  v131 = __ROL__(*(_DWORD *)(v3 + 8) + v124 + (v128 ^ ((v128 + v129) | ~v126)) + 718787259, 15);
  v132 = v130 + v131;
  v133 = __ROL__(*(_DWORD *)(v3 + 36) + v126 + (v130 ^ ((v130 + v131) | ~v128)) - 343485551, 21);
  result = v132 + v133;
  *(_DWORD *)v2 += v128;
  *(_DWORD *)(v2 + 4) += result;
  *(_DWORD *)(v2 + 8) += v132;
  *(_DWORD *)(v2 + 12) += v130;
  return result;
}

//----- (0040A33C) --------------------------------------------------------
int __cdecl sub_40A33C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A86C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A86C: using guessed type int dword_41A86C;

//----- (0040A36C) --------------------------------------------------------
void __cdecl sub_40A36C()
{
  --dword_41A86C;
}
// 41A86C: using guessed type int dword_41A86C;

//----- (0040A374) --------------------------------------------------------
unsigned int __fastcall sub_40A374(int a1, unsigned int a2)
{
  if ( a2 > 9 )
    sub_402CA8();
  return (unsigned int)(a1 * dword_4186A8[a2]) >> 5;
}
// 4186A8: using guessed type int dword_4186A8[];

//----- (0040A390) --------------------------------------------------------
char __usercall sub_40A390<al>(int a1<eax>, unsigned int *a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  unsigned int *v4; // esi@1
  char result; // al@3
  unsigned int v6; // eax@7

  v3 = ecx0;
  v4 = a2;
  if ( (signed int)*a2 > 3 )
  {
    if ( *a2 > 9 )
      sub_402CA8();
    *(_DWORD *)ecx0 = dword_4186A8[*a2];
    v6 = sub_40A374(a1, 3u);
    if ( (signed int)v6 >= *(_DWORD *)v3 )
    {
      result = 1;
    }
    else
    {
      *(_DWORD *)v3 = v6;
      *v4 = 3;
      result = 0;
    }
  }
  else
  {
    *(_DWORD *)ecx0 = sub_40A374(a1, *a2);
    if ( *(_DWORD *)v3 <= 16384 )
    {
      result = 1;
    }
    else
    {
      *(_DWORD *)v3 = 16384;
      *v4 = 6;
      result = 0;
    }
  }
  return result;
}
// 4186A8: using guessed type int dword_4186A8[];

//----- (0040A3FC) --------------------------------------------------------
int __fastcall sub_40A3FC(int a1, signed int a2)
{
  return (a2 + a1 - 1) / a2;
}

//----- (0040A40C) --------------------------------------------------------
unsigned int __usercall sub_40A40C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  unsigned int result; // eax@3
  int v6; // [sp+0h] [bp-Ch]@1

  v6 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408814(a1, 16, (int)&v6) && v6 == 41215 )
  {
    *(_BYTE *)v3 = sub_408704(v4) != 0;
    *(_BYTE *)(v3 + 1) = sub_408704(v4) != 0;
    *(_BYTE *)(v3 + 2) = sub_408704(v4) != 0;
    *(_DWORD *)(v3 + 4) = sub_40864C(v4, 21);
    if ( *(_BYTE *)v3 )
    {
      *(_DWORD *)(v3 + 8) = sub_40864C(v4, 14) + 1;
      result = sub_40864C(v4, 2);
    }
    else
    {
      result = 0;
      *(_DWORD *)(v3 + 8) = 0;
    }
    LOBYTE(result) = *(_BYTE *)(v4 + 44) ^ 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040A4A0) --------------------------------------------------------
char __fastcall sub_40A4A0(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)a2 = sub_40864C(a1, 6);
  *(_DWORD *)(v2 + 4) = sub_40864C(v3, 4);
  return *(_BYTE *)(v3 + 44) ^ 1;
}

//----- (0040A4CC) --------------------------------------------------------
char __fastcall sub_40A4CC(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  unsigned int v4; // eax@1
  char result; // al@2
  __int64 v6; // qax@3

  v2 = a2;
  v3 = a1;
  v4 = sub_40864C(a1, 4);
  if ( (signed int)v4 <= 9 )
  {
    *(_DWORD *)v2 = v4;
    *(_QWORD *)(v2 + 8) = (signed int)sub_40864C(v3, 24);
    v6 = (signed int)(sub_40864C(v3, 11) << 24);
    HIDWORD(v6) |= *(_DWORD *)(v2 + 12);
    *(_DWORD *)(v2 + 8) |= v6;
    *(_DWORD *)(v2 + 12) = HIDWORD(v6);
    result = *(_BYTE *)(v3 + 44) ^ 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040A524) --------------------------------------------------------
int __fastcall sub_40A524(int result)
{
  signed int v1; // edx@1

  v1 = *(_DWORD *)(result + 8) + 7;
  if ( v1 < 0 )
    v1 = *(_DWORD *)(result + 8) + 14;
  *(_DWORD *)(result + 16) = *(_DWORD *)(result + 12) * (v1 >> 3);
  return result;
}

//----- (0040A53C) --------------------------------------------------------
int __fastcall sub_40A53C(int a1, int a2)
{
  signed int v2; // edx@1
  int v3; // esi@2
  unsigned int v4; // edi@2
  signed int v5; // ebx@5
  signed int v6; // ebx@8
  int result; // eax@10
  int v8; // [sp+0h] [bp-14h]@1
  int v9; // [sp+4h] [bp-10h]@1

  v8 = a2;
  v9 = 0;
  v2 = 0;
  if ( *(_DWORD *)(a1 + 12) - 1 >= 0 )
  {
    v3 = *(_DWORD *)(a1 + 12);
    v4 = 0;
    do
    {
      if ( v4 > 0xF )
        sub_402CA8();
      v5 = *(_BYTE *)(a1 + v4 + 32);
      if ( *(_BYTE *)(a1 + v4 + 32) )
      {
        if ( v5 > 18 || v2 >= v5 )
          return 0;
        v2 = *(_BYTE *)(a1 + v4 + 32);
        v6 = 1 << (v5 - 1);
        if ( v6 & v9 )
          return 0;
        v9 |= v6;
      }
      ++v4;
      --v3;
    }
    while ( v3 );
  }
  result = v8;
  *(_DWORD *)v8 = v9;
  LOBYTE(result) = 1;
  return result;
}

//----- (0040A5AC) --------------------------------------------------------
int __usercall sub_40A5AC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ecx@12
  int v5; // [sp-4h] [bp-4h]@1

  v5 = ecx0;
  if ( *(_DWORD *)a1
    || *(_DWORD *)(a1 + 4) < 6000
    || *(_DWORD *)(a1 + 4) > 262144
    || *(_DWORD *)(a1 + 8) < 8
    || *(_DWORD *)(a1 + 8) > 24
    || *(_DWORD *)(a1 + 12) < 1
    || *(_DWORD *)(a1 + 12) > 16 )
    a2 = 0;
  else
    LOBYTE(a2) = 1;
  if ( (_BYTE)a2 && *(_DWORD *)(a1 + 20) == 1 )
  {
    v3 = *(_DWORD *)(a1 + 24);
    if ( v3 <= 0 || v3 > *(_DWORD *)(a1 + 8) )
    {
      a2 = 0;
    }
    else
    {
      if ( *(_DWORD *)(a1 + 28) == 1 )
        a2 = sub_40A53C(a1, (int)&v5);
    }
  }
  return a2;
}

//----- (0040A610) --------------------------------------------------------
int __fastcall sub_40A610(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // eax@1
  int v5; // edx@1
  int v6; // ecx@1
  int v7; // edi@6
  unsigned int v8; // ebp@6
  unsigned int v9; // eax@7
  int result; // eax@15
  char v11; // [sp+0h] [bp-14h]@18

  v2 = a2;
  v3 = a1;
  *(_DWORD *)a2 = sub_40864C(a1, 3);
  *(_DWORD *)(v2 + 4) = sub_40864C(v3, 18) + 6000;
  *(_DWORD *)(v2 + 8) = sub_40864C(v3, 5) + 8;
  *(_DWORD *)(v2 + 12) = sub_40864C(v3, 4) + 1;
  v4 = sub_408704(v3);
  *(_DWORD *)(v2 + 20) = sub_408418(v4 != 0);
  if ( *(_DWORD *)(v2 + 20) == 1 && !*(_BYTE *)(v3 + 44) && *(_DWORD *)(v2 + 12) <= 16 )
  {
    *(_DWORD *)(v2 + 24) = sub_40864C(v3, 5) + 1;
    if ( sub_408704(v3) )
    {
      *(_DWORD *)(v2 + 28) = 1;
      if ( *(_DWORD *)(v2 + 12) - 1 >= 0 )
      {
        v7 = *(_DWORD *)(v2 + 12);
        v8 = 0;
        do
        {
          v9 = sub_40864C(v3, 6);
          if ( v9 > 0xFF )
            sub_402CA8();
          if ( v8 > 0xF )
            sub_402CA8();
          *(_BYTE *)(v2 + v8++ + 32) = v9;
          --v7;
        }
        while ( v7 );
      }
    }
    else
    {
      *(_DWORD *)(v2 + 28) = 0;
    }
  }
  if ( !*(_BYTE *)(v3 + 44) && (result = sub_40A5AC(v2, v5, v6), (_BYTE)result) )
    LOBYTE(result) = 1;
  else
    result = 0;
  v11 = result;
  if ( (_BYTE)result )
    result = sub_40A524(v2);
  LOBYTE(result) = v11;
  return result;
}

//----- (0040A714) --------------------------------------------------------
char __fastcall sub_40A714(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1

  v2 = a2;
  v3 = a1;
  return sub_40A4A0(a1, a2)
      && sub_40A4CC(v3, v2 + 8)
      && (unsigned __int8)sub_40A610(v3, v2 + 24)
      && sub_40A390(*(_DWORD *)(v2 + 28), (unsigned int *)(v2 + 8), v2 + 12);
}

//----- (0040A760) --------------------------------------------------------
char __usercall sub_40A760<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  unsigned int v6; // edi@7
  unsigned int v7; // edi@9
  unsigned int v8; // esi@11
  signed int v9; // ST00_4@15
  int v10; // eax@15

  v3 = a2;
  v4 = a1;
  if ( !(unsigned __int8)sub_40A40C(a1, a2, ecx0) || *(_BYTE *)(v3 + 2) )
    return 0;
  if ( *(_BYTE *)(v3 + 1) )
  {
    if ( !sub_40A714(v4, v3 + 12) )
      return 0;
    *(_BYTE *)(v3 + 84) = sub_408704(v4) != 0;
    v6 = sub_40864C(v4, 5);
    if ( *(_BYTE *)(v3 + 84) )
      *(_DWORD *)(v3 + 88) = sub_40864C(v4, 25);
    v7 = sub_408638(v4) | v6;
  }
  else
  {
    v7 = 0;
  }
  v8 = sub_40864C(v4, 24);
  if ( (v8 & 0x80000000u) != 0 )
    sub_402CA8();
  return !*(_BYTE *)(v4 + 44) && !v7 && (v9 = sub_408580(v4) - 3, v10 = sub_408574(v4), v8 == sub_409AC8(v10, v9));
}

//----- (0040A824) --------------------------------------------------------
char __fastcall sub_40A824(int a1, int a2, int a3, unsigned __int64 a4)
{
  int v4; // ecx@1
  int v5; // eax@3
  int v7; // [sp-4h] [bp-4h]@1

  v4 = a1;
  v7 = a3 & 0x7F;
  if ( v7 >> 31 )
    sub_402CA8();
  *(_DWORD *)a1 = v7;
  v5 = __PAIR__(a4, a3) >> 8;
  if ( (v5 & 0xFFFFFF) >> 31 )
    sub_402CA8();
  *(_DWORD *)(v4 + 4) = v5 & 0xFFFFFF;
  return 1;
}

//----- (0040A874) --------------------------------------------------------
int __usercall sub_40A874<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  signed int v4; // ST00_4@3
  int v5; // eax@3
  int result; // eax@3
  int v7; // [sp+0h] [bp-Ch]@1

  v7 = ecx0;
  v3 = a1;
  if ( sub_40A714(a1, a2) )
  {
    sub_408638(v3);
    if ( sub_408814(v3, 24, (int)&v7)
      && (v4 = sub_408580(v3) - 3, v5 = sub_408574(v3), result = sub_409AC8(v5, v4), result == v7) )
      LOBYTE(result) = 1;
    else
      result = 0;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040A8CC) --------------------------------------------------------
char __fastcall sub_40A8CC(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)a2 = 0;
  System::Move(a1, a2);
  *(_DWORD *)(v2 + 4) = 0;
  System::Move(v3 + 3, v2 + 4);
  return 1;
}

//----- (0040A900) --------------------------------------------------------
int __usercall sub_40A900<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  signed int v5; // ST00_4@3
  int v6; // eax@3
  int result; // eax@3
  int v8; // [sp+0h] [bp-Ch]@1

  v8 = ecx0;
  v3 = a2;
  v4 = a1;
  *(_DWORD *)a2 = sub_40864C(a1, 24);
  *(_DWORD *)(v3 + 4) = sub_40864C(v4, 4);
  *(_DWORD *)(v3 + 8) = sub_40864C(v4, 2);
  sub_408638(v4);
  if ( !*(_BYTE *)(v4 + 44)
    && sub_408814(v4, 24, (int)&v8)
    && (v5 = sub_408580(v4) - 3, v6 = sub_408574(v4), result = sub_409AC8(v6, v5), result == v8) )
    LOBYTE(result) = 1;
  else
    result = 0;
  return result;
}

//----- (0040A97C) --------------------------------------------------------
int __fastcall sub_40A97C(int a1, int a2)
{
  int v2; // ebx@1
  int result; // eax@1
  int v4; // [sp+0h] [bp-8h]@1

  v2 = a1;
  System::Move(a1, a2);
  v4 = 0;
  System::Move(v2 + 16, &v4);
  result = sub_409AC8(v2, 16);
  LOBYTE(result) = result == v4;
  return result;
}

//----- (0040A9B8) --------------------------------------------------------
int __fastcall sub_40A9B8(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int result; // eax@1
  int v5; // [sp+0h] [bp-Ch]@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)a2 = 0;
  *(_DWORD *)(a2 + 4) = 0;
  System::Move(a1, a2);
  *(_DWORD *)(v2 + 8) = 0;
  System::Move(v3 + 5, v2 + 8);
  v5 = 0;
  System::Move(v3 + 8, &v5);
  result = sub_409AC8(v3, 8);
  LOBYTE(result) = result == v5;
  return result;
}

//----- (0040AA1C) --------------------------------------------------------
int __cdecl sub_40AA1C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A870;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A870: using guessed type int dword_41A870;

//----- (0040AA4C) --------------------------------------------------------
void __cdecl sub_40AA4C()
{
  --dword_41A870;
}
// 41A870: using guessed type int dword_41A870;

//----- (0040AA54) --------------------------------------------------------
int __userpurge sub_40AA54<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int result; // eax@1
  int v6; // ecx@1

  result = a1 + 4 * ecx0;
  v6 = -ecx0;
  do
  {
    *(_BYTE *)a2 = *(_BYTE *)(result + 4 * v6) + -128;
    a2 += a3;
    ++v6;
  }
  while ( v6 );
  return result;
}

//----- (0040AA78) --------------------------------------------------------
int __userpurge sub_40AA78<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int result; // eax@1
  int v6; // edx@1
  int v7; // ecx@1
  int v8; // ebx@1

  result = a1 + 4 * a3;
  v6 = a2 + 4 * a3;
  v7 = ecx0 + 2 * a3;
  v8 = -a3;
  do
  {
    *(_WORD *)(v7 + 2 * v8) = ((*(_WORD *)(v6 + 4 * v8) + 128) << 8) | (*(_WORD *)(result + 4 * v8) + 128);
    ++v8;
  }
  while ( v8 );
  return result;
}

//----- (0040AAB0) --------------------------------------------------------
__int16 __userpurge sub_40AAB0<ax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4)
{
  int v5; // ebx@1
  int v6; // edx@2
  int v7; // ebx@3

  v5 = a2;
  if ( ecx0 >= 2 )
  {
    a1 += 4 * (ecx0 & 0xFFFFFFFE);
    v6 = -(ecx0 & 0xFFFFFFFE);
    do
    {
      *(_WORD *)v5 = *(_WORD *)(a1 + 4 * v6);
      v7 = a3 + v5;
      *(_WORD *)v7 = *(_WORD *)(a1 + 4 * v6 + 4);
      v5 = a3 + v7;
      v6 += 2;
    }
    while ( v6 );
  }
  if ( ecx0 & 1 )
  {
    LOWORD(a1) = *(_WORD *)a1;
    *(_WORD *)v5 = a1;
  }
  return a1;
}

//----- (0040AAF8) --------------------------------------------------------
int __userpurge sub_40AAF8<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4)
{
  int v5; // ebx@2

  if ( a3 >= 2 )
  {
    result += 4 * (a3 & 0xFFFFFFFE);
    a2 += 4 * (a3 & 0xFFFFFFFE);
    ecx0 += 4 * (a3 & 0xFFFFFFFE);
    v5 = -(a3 & 0xFFFFFFFE);
    do
    {
      *(_DWORD *)(ecx0 + 4 * v5) = (*(_DWORD *)(a2 + 4 * v5) << 16) | *(_WORD *)(result + 4 * v5);
      *(_DWORD *)(ecx0 + 4 * v5 + 4) = (*(_DWORD *)(a2 + 4 * v5 + 4) << 16) | *(_WORD *)(result + 4 * v5 + 4);
      v5 += 2;
    }
    while ( v5 );
  }
  if ( a3 & 1 )
  {
    result = (*(_DWORD *)a2 << 16) | *(_WORD *)result;
    *(_DWORD *)ecx0 = result;
  }
  return result;
}

//----- (0040AB58) --------------------------------------------------------
char __userpurge sub_40AB58<al>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4)
{
  unsigned int v5; // esi@5
  int v6; // edx@6
  signed int v7; // esi@9
  signed int v8; // esi@12
  unsigned int v10; // [sp+Ch] [bp-4h]@1

  v10 = ecx0;
  if ( ecx0 >= 2 )
  {
    if ( a3 & 1 )
    {
      if ( a2 & 1 )
      {
        *(_BYTE *)a2 = *(_BYTE *)a1;
        *(_WORD *)(a2 + 1) = *(_DWORD *)a1 >> 8;
        v10 = ecx0 - 1;
        a1 += 4;
        a2 += a3;
      }
      v5 = v10 >> 1;
      if ( (signed int)(v10 >> 1) > 0 )
      {
        do
        {
          *(_WORD *)a2 = *(_WORD *)a1;
          *(_BYTE *)(a2 + 2) = *(_BYTE *)(a1 + 2);
          v6 = a3 + a2;
          *(_BYTE *)v6 = *(_BYTE *)(a1 + 4);
          *(_WORD *)(v6 + 1) = *(_DWORD *)(a1 + 4) >> 8;
          a1 += 8;
          a2 = a3 + v6;
          --v5;
        }
        while ( v5 );
      }
    }
    else
    {
      if ( a2 & 1 )
      {
        v7 = ecx0;
        if ( ecx0 > 0 )
        {
          do
          {
            *(_BYTE *)a2 = *(_BYTE *)a1;
            *(_WORD *)(a2 + 1) = *(_DWORD *)a1 >> 8;
            a1 += 4;
            a2 += a3;
            --v7;
          }
          while ( v7 );
        }
      }
      else
      {
        v8 = ecx0;
        if ( ecx0 > 0 )
        {
          do
          {
            *(_WORD *)a2 = *(_WORD *)a1;
            *(_BYTE *)(a2 + 2) = *(_DWORD *)a1 >> 16;
            a1 += 4;
            a2 += a3;
            --v8;
          }
          while ( v8 );
        }
      }
      LOBYTE(v10) = 0;
    }
  }
  if ( v10 & 1 )
  {
    *(_BYTE *)a2 = *(_BYTE *)a1;
    *(_BYTE *)(a2 + 1) = *(_BYTE *)(a1 + 1);
    LOBYTE(a1) = *(_BYTE *)(a1 + 2);
    *(_BYTE *)(a2 + 2) = a1;
  }
  return a1;
}

//----- (0040AC2C) --------------------------------------------------------
int __userpurge sub_40AC2C<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4)
{
  int v5; // ebx@5
  unsigned int v6; // ebx@5
  unsigned int v7; // [sp+Ch] [bp-4h]@4

  if ( ecx0 & 2 )
  {
    *(_WORD *)ecx0 = *(_WORD *)result;
    *(_DWORD *)(ecx0 + 2) = (*(_DWORD *)a2 << 8) | *(_BYTE *)(result + 2);
    result += 4;
    a2 += 4;
    ecx0 += 6;
    --a3;
  }
  if ( ((((unsigned int)a3 >> 1) - 1) & 0x80000000u) == 0 )
  {
    v7 = (unsigned int)a3 >> 1;
    do
    {
      v5 = *(_DWORD *)result;
      *(_DWORD *)ecx0 = (*(_DWORD *)a2 << 24) | v5 & 0xFFFFFF;
      v6 = *(_DWORD *)(result + 4);
      *(_DWORD *)(ecx0 + 4) = (*(_DWORD *)(result + 4) << 16) | (*(_DWORD *)a2 >> 8) & 0xFFFF;
      *(_DWORD *)(ecx0 + 8) = (*(_DWORD *)(a2 + 4) << 8) | (v6 >> 16) & 0xFF;
      result += 8;
      a2 += 8;
      ecx0 += 12;
      --v7;
    }
    while ( v7 );
  }
  if ( a3 & 1 )
  {
    *(_WORD *)ecx0 = *(_WORD *)result;
    result = (*(_DWORD *)a2 << 8) | *(_BYTE *)(result + 2);
    *(_DWORD *)(ecx0 + 2) = result;
  }
  return result;
}

//----- (0040ACDC) --------------------------------------------------------
int __userpurge sub_40ACDC<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4)
{
  int v5; // edx@2
  int v6; // eax@3
  int v7; // eax@4
  unsigned int v8; // esi@22
  int v9; // ebx@23
  unsigned int v10; // [sp+0h] [bp-30h]@0
  unsigned int v11; // [sp+8h] [bp-28h]@23
  int v12; // [sp+Ch] [bp-24h]@20
  int v13; // [sp+10h] [bp-20h]@19
  int v14; // [sp+18h] [bp-18h]@19
  int v15; // [sp+1Ch] [bp-14h]@17
  int v16; // [sp+20h] [bp-10h]@17
  void *v17; // [sp+24h] [bp-Ch]@14
  int v18; // [sp+28h] [bp-8h]@1
  int v19; // [sp+2Ch] [bp-4h]@1

  v18 = ecx0;
  v19 = a2;
  if ( ecx0 > 0 )
  {
    v5 = *(_DWORD *)(result + 12);
    if ( v5 == 2 )
    {
      v6 = *(_DWORD *)(result + 8) - 8;
      if ( v6 )
      {
        v7 = v6 - 8;
        if ( v7 )
        {
          result = v7 - 8;
          if ( !result )
            result = sub_40AC2C(*(_DWORD *)v19, *(_DWORD *)(v19 + 4), a3, ecx0, v10);
        }
        else
        {
          result = sub_40AAF8(*(_DWORD *)v19, *(_DWORD *)(v19 + 4), a3, ecx0, v10);
        }
      }
      else
      {
        result = sub_40AA78(*(_DWORD *)v19, *(_DWORD *)(v19 + 4), a3, ecx0, v10);
      }
    }
    else
    {
      if ( *(_DWORD *)(result + 8) == 8 )
      {
        v17 = sub_40AA54;
      }
      else
      {
        if ( *(_DWORD *)(result + 8) == 16 )
        {
          v17 = sub_40AAB0;
        }
        else
        {
          if ( *(_DWORD *)(result + 8) != 24 )
            return result;
          v17 = sub_40AB58;
        }
      }
      v16 = *(_DWORD *)(result + 12);
      v15 = *(_DWORD *)(result + 8) >> 3;
      if ( v5 == 1 )
      {
        result = ((int (__fastcall *)(_DWORD, unsigned int, int))v17)(*(_DWORD *)v19, a3, v15);
      }
      else
      {
        v14 = *(_DWORD *)(result + 16);
        v13 = 0;
        do
        {
          v12 = v18 - v13;
          if ( v18 - v13 > (24576 / (v14 + 8) & 0xFFFFFFFC) )
            v12 = 24576 / (v14 + 8) & 0xFFFFFFFC;
          v8 = 0;
          if ( v16 - 1 >= 0 )
          {
            v9 = v16;
            v11 = 0;
            do
            {
              if ( v11 > 5 )
                sub_402CA8();
              if ( (unsigned int)v13 > 0x1FFFFFFE )
                sub_402CA8();
              if ( v8 > 0x7FFFFFFE )
                sub_402CA8();
              ((void (__fastcall *)(int, unsigned int, int))v17)(*(_DWORD *)(v19 + 4 * v11) + 4 * v13, v8 + a3, v14);
              v8 += v15;
              ++v11;
              --v9;
            }
            while ( v9 );
          }
          a3 += v14 * v12;
          v13 += v12;
          result = v13;
        }
        while ( v13 != v18 );
      }
    }
  }
  return result;
}

//----- (0040AE7C) --------------------------------------------------------
#error "40AE9F: call analysis failed (funcsize=16)"

//----- (0040AEA8) --------------------------------------------------------
int __cdecl sub_40AEA8()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A874;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A874: using guessed type int dword_41A874;

//----- (0040AED8) --------------------------------------------------------
void __cdecl sub_40AED8()
{
  --dword_41A874;
}
// 41A874: using guessed type int dword_41A874;

//----- (0040AF4C) --------------------------------------------------------
int __userpurge sub_40AF4C<eax>(int a1<ebx>, int a2)
{
  System::__linkproc___Assert(&str_Not_supported[1], &str_D__VocComp_Win_[1]);
  return a1;
}
// 40AF6C: using guessed type _strings str_D__VocComp_Win_[6];
// 40AFA4: using guessed type _strings str_Not_supported[2];

//----- (0040AFBC) --------------------------------------------------------
int __cdecl sub_40AFBC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A878;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A878: using guessed type int dword_41A878;

//----- (0040AFEC) --------------------------------------------------------
void __cdecl sub_40AFEC()
{
  --dword_41A878;
}
// 41A878: using guessed type int dword_41A878;

//----- (0040AFF4) --------------------------------------------------------
int __cdecl sub_40AFF4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A87C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A87C: using guessed type int dword_41A87C;

//----- (0040B024) --------------------------------------------------------
void __cdecl sub_40B024()
{
  --dword_41A87C;
}
// 41A87C: using guessed type int dword_41A87C;

//----- (0040B02C) --------------------------------------------------------
int __usercall sub_40B02C<eax>(int result<eax>, int a2<edx>, unsigned int ecx0<ecx>)
{
  unsigned int v3; // ebx@3
  int v4; // eax@4

  if ( (signed int)ecx0 >= 1 )
  {
    if ( (((ecx0 >> 1) - 1) & 0x80000000u) == 0 )
    {
      v3 = ecx0 >> 1;
      do
      {
        v4 = *(_DWORD *)a2 + result;
        *(_DWORD *)a2 = v4;
        result = *(_DWORD *)(a2 + 4) + v4;
        *(_DWORD *)(a2 + 4) = result;
        a2 += 8;
        --v3;
      }
      while ( v3 );
    }
    if ( ecx0 & 1 )
      *(_DWORD *)a2 += result;
  }
  return result;
}

//----- (0040B058) --------------------------------------------------------
int __fastcall sub_40B058(int result, signed int a2)
{
  if ( a2 >= 2 )
    result = sub_40B02C(*(_DWORD *)result, result + 4, a2 - 1);
  return result;
}

//----- (0040B06C) --------------------------------------------------------
int __fastcall sub_40B06C(int result, signed int a2)
{
  int v2; // ebx@2
  int v3; // ecx@2
  unsigned int v4; // esi@4
  int v5; // ebx@5
  int v6; // ecx@5

  if ( a2 >= 2 )
  {
    v2 = *(_DWORD *)(result + 4);
    v3 = v2 + *(_DWORD *)result;
    *(_DWORD *)(result + 4) = v3;
    if ( a2 >= 3 )
    {
      result += 8;
      if ( ((((unsigned int)(a2 - 2) >> 1) - 1) & 0x80000000u) == 0 )
      {
        v4 = (unsigned int)(a2 - 2) >> 1;
        do
        {
          v5 = *(_DWORD *)result + v2;
          v6 = v5 + v3;
          *(_DWORD *)result = v6;
          v2 = *(_DWORD *)(result + 4) + v5;
          v3 = v2 + v6;
          *(_DWORD *)(result + 4) = v3;
          result += 8;
          --v4;
        }
        while ( v4 );
      }
      if ( a2 & 1 )
        *(_DWORD *)result += v3 + v2;
    }
  }
  return result;
}

//----- (0040B0B4) --------------------------------------------------------
int __fastcall sub_40B0B4(int result, signed int a2)
{
  int v2; // ebx@2
  int v3; // ecx@2
  int v4; // esi@3
  int v5; // ebx@3
  int v6; // ecx@3
  int v7; // edx@3
  int v8; // edx@4

  if ( a2 >= 2 )
  {
    v2 = *(_DWORD *)(result + 4);
    v3 = v2 + *(_DWORD *)result;
    *(_DWORD *)(result + 4) = v3;
    if ( a2 >= 3 )
    {
      v4 = *(_DWORD *)(result + 8);
      v5 = v4 + v2;
      v6 = v5 + v3;
      *(_DWORD *)(result + 8) = v6;
      result += 12;
      v7 = a2 - 4;
      if ( v7 >= 0 )
      {
        v8 = v7 + 1;
        do
        {
          v4 += *(_DWORD *)result;
          v5 += v4;
          v6 += v5;
          *(_DWORD *)result = v6;
          result += 4;
          --v8;
        }
        while ( v8 );
      }
    }
  }
  return result;
}

//----- (0040B0F0) --------------------------------------------------------
char __usercall sub_40B0F0<al>(char a1<al>, int a2<edx>, signed int ecx0<ecx>)
{
  char v3; // al@1
  char v4; // al@2
  char result; // al@3

  v3 = a1 - 1;
  if ( v3 )
  {
    v4 = v3 - 1;
    if ( v4 )
    {
      result = v4 - 1;
      if ( !result )
        result = sub_40B0B4(a2, ecx0);
    }
    else
    {
      result = sub_40B06C(a2, ecx0);
    }
  }
  else
  {
    result = sub_40B058(a2, ecx0);
  }
  return result;
}

//----- (0040B11C) --------------------------------------------------------
int __cdecl sub_40B11C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A880;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A880: using guessed type int dword_41A880;

//----- (0040B14C) --------------------------------------------------------
void __cdecl sub_40B14C()
{
  --dword_41A880;
}
// 41A880: using guessed type int dword_41A880;

//----- (0040B154) --------------------------------------------------------
char __fastcall sub_40B154(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  if ( sub_408704(a1) )
    *(_DWORD *)v2 = sub_40864C(v3, 4) + 1;
  else
    *(_DWORD *)v2 = 0;
  return !*(_BYTE *)(v3 + 44) && *(_DWORD *)v2 <= 16;
}

//----- (0040B190) --------------------------------------------------------
int __cdecl sub_40B190()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A884;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A884: using guessed type int dword_41A884;

//----- (0040B1C0) --------------------------------------------------------
void __cdecl sub_40B1C0()
{
  --dword_41A884;
}
// 41A884: using guessed type int dword_41A884;

//----- (0040B224) --------------------------------------------------------
int __userpurge sub_40B224<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, signed int a5)
{
  int v6; // esi@3
  signed int v7; // eax@9
  int v9; // [sp+8h] [bp-8h]@3
  char v10; // [sp+Fh] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v9 = ecx0;
  v10 = a2;
  v6 = a1;
  unknown_libname_33(a1, 0);
  *(_BYTE *)(v6 + 8) = a3;
  switch ( (_BYTE)a3 )
  {
    case 4:
      *(_DWORD *)(v6 + 16) = 1024;
      break;
    case 5:
      *(_DWORD *)(v6 + 16) = 512;
      break;
    case 6:
      *(_DWORD *)(v6 + 16) = 256;
      break;
    default:
      v7 = v9 + 511;
      if ( v9 + 511 < 0 )
        v7 = v9 + 1022;
      *(_DWORD *)(v6 + 16) = (((v7 >> 9) + 3) & 0xFFFFFFFC) << (3 - (a3 & 0x7F));
      break;
  }
  *(_DWORD *)(v6 + 12) = *(_DWORD *)(v6 + 16) / 2;
  *(_DWORD *)(v6 + 4) = -1;
  sub_40B2E4(v6, a4);
  if ( v10 )
    System::__linkproc___AfterConstruction(v6);
  return v6;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (0040B2E4) --------------------------------------------------------
int __fastcall sub_40B2E4(int result, signed int a2)
{
  int v2; // ecx@1
  int v3; // eax@2

  v2 = result;
  if ( a2 != *(_DWORD *)(result + 4) )
  {
    *(_DWORD *)(result + 4) = a2;
    v3 = a2 / *(_DWORD *)(result + 16);
    *(_DWORD *)(v2 + 20) = v3;
    result = *(_DWORD *)(v2 + 4) - *(_DWORD *)(v2 + 16) * v3;
    *(_DWORD *)(v2 + 24) = result;
    if ( *(_DWORD *)(v2 + 20) )
    {
      if ( result < *(_DWORD *)(v2 + 12) )
      {
        result = *(_DWORD *)(v2 + 16);
        *(_DWORD *)(v2 + 24) += result;
      }
      else
      {
        ++*(_DWORD *)(v2 + 20);
      }
    }
    else
    {
      *(_DWORD *)(v2 + 20) = 1;
    }
    if ( *(_DWORD *)(v2 + 20) > 128 )
      result = System::__linkproc___Assert(&str_Assertion_failu[1], &str_D__VocComp_Win__0[1]);
  }
  return result;
}
// 40B348: using guessed type _strings str_D__VocComp_Win__0[5];
// 40B378: using guessed type _strings str_Assertion_failu[3];

//----- (0040B394) --------------------------------------------------------
int __fastcall sub_40B394(int a1, int a2)
{
  int result; // eax@2

  if ( a2 >= *(_DWORD *)(a1 + 20) )
    result = *(_DWORD *)(a1 + 4);
  else
    result = *(_DWORD *)(a1 + 16) * a2;
  return result;
}

//----- (0040B3A4) --------------------------------------------------------
int __fastcall sub_40B3A4(int a1, int a2)
{
  int result; // eax@2

  if ( a2 >= *(_DWORD *)(a1 + 20) - 1 )
    result = *(_DWORD *)(a1 + 24);
  else
    result = *(_DWORD *)(a1 + 16);
  return result;
}

//----- (0040B3B4) --------------------------------------------------------
char __usercall sub_40B3B4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  signed int v5; // esi@2
  char result; // al@11
  int v7; // eax@13
  int v8; // edi@17
  signed int v9; // esi@18
  int v10; // eax@21
  int v11; // [sp+0h] [bp-18h]@1
  int v12; // [sp+4h] [bp-14h]@1

  v3 = ecx0;
  v12 = a2;
  v11 = a1;
  *(_DWORD *)(ecx0 + 4) = 0;
  v4 = *(_DWORD *)ecx0 - 1;
  if ( *(_DWORD *)ecx0 - 1 <= 0 )
  {
LABEL_13:
    v7 = *(_DWORD *)v3 - 1;
    if ( (unsigned int)v7 > 8 )
      sub_402CA8();
    if ( *(_DWORD *)(v3 + 8 * v7 + 4) < *(_DWORD *)(v12 + 20) )
    {
      *(_DWORD *)(v3 + 8) = 0;
      v8 = *(_DWORD *)v3 - 1;
      if ( *(_DWORD *)v3 - 1 > 0 )
      {
        v9 = 1;
        do
        {
          if ( (unsigned int)v9 > 8 )
            sub_402CA8();
          v10 = sub_40B394(v12, *(_DWORD *)(v3 + 8 * v9 + 4));
          if ( (unsigned int)v9 > 8 )
            sub_402CA8();
          *(_DWORD *)(v3 + 8 * v9++ + 8) = v10;
          --v8;
        }
        while ( v8 );
      }
      if ( *(_DWORD *)v3 > 8u )
        sub_402CA8();
      *(_DWORD *)(v3 + 8 * *(_DWORD *)v3 + 4) = *(_DWORD *)(v12 + 20);
      if ( *(_DWORD *)v3 > 8u )
        sub_402CA8();
      *(_DWORD *)(v3 + 8 * *(_DWORD *)v3 + 8) = *(_DWORD *)(v12 + 4);
      result = 1;
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    v5 = 1;
    while ( 1 )
    {
      if ( (unsigned int)v5 > 8 )
        sub_402CA8();
      if ( !sub_408814(v11, 6, v3 + 8 * v5 + 4) )
        break;
      if ( (unsigned int)v5 > 8 )
        sub_402CA8();
      if ( (unsigned int)(v5 - 1) > 8 )
        sub_402CA8();
      if ( *(_DWORD *)(v3 + 8 * v5 + 4) <= *(_DWORD *)(v3 + 8 * (v5 - 1) + 4) )
        break;
      ++v5;
      --v4;
      if ( !v4 )
        goto LABEL_13;
    }
    result = 0;
  }
  return result;
}

//----- (0040B4B4) --------------------------------------------------------
char __usercall sub_40B4B4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  int v5; // esi@1
  char result; // al@2

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_408814(a1, 3, ecx0) )
  {
    ++*(_DWORD *)v3;
    result = sub_40B3B4(v5, v4, v3);
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040B4E4) --------------------------------------------------------
int __cdecl sub_40B4E4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A888;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A888: using guessed type int dword_41A888;

//----- (0040B514) --------------------------------------------------------
void __cdecl sub_40B514()
{
  --dword_41A888;
}
// 41A888: using guessed type int dword_41A888;

//----- (0040B57C) --------------------------------------------------------
int __fastcall sub_40B57C(void *a1, int a2)
{
  void *v2; // edi@1
  int result; // eax@1

  v2 = a1;
  result = 0;
  memset(v2, 0, 4 * a2);
  return result;
}

//----- (0040B58C) --------------------------------------------------------
char __fastcall sub_40B58C(signed int a1)
{
  char result; // al@2

  if ( a1 < 44100 )
  {
    if ( a1 < 22050 )
      result = a1 >= 11025;
    else
      result = 2;
  }
  else
  {
    result = 3;
  }
  return result;
}

//----- (0040B5B0) --------------------------------------------------------
char __userpurge sub_40B5B0<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@1
  unsigned __int8 v6; // bl@1
  char v7; // cf@1
  unsigned __int8 v8; // al@1
  char result; // al@7

  v5 = a2;
  v6 = a1;
  v7 = a1 < 1u;
  v8 = a1 - 1;
  if ( v7 )
  {
    sub_40B57C((void *)ecx0, a3);
    result = 1;
  }
  else
  {
    if ( v8 >= 0x32u )
    {
      result = 1;
    }
    else
    {
      if ( (unsigned int)v6 - 1 > 0x31 )
        sub_402CA8();
      result = (unsigned __int8)sub_409173((int)((char *)&unk_418780 + 36 * v6), a2, ecx0, a3) && !*(_BYTE *)(v5 + 44);
    }
  }
  return result;
}

//----- (0040B618) --------------------------------------------------------
char __usercall sub_40B618<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  char result; // al@4
  int v6; // esi@5
  signed int v7; // ebp@6
  int v8; // eax@7
  int v9; // ebx@7
  int v10; // eax@10
  int v11; // [sp+0h] [bp-18h]@1
  unsigned int v12; // [sp+4h] [bp-14h]@1

  v11 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408814(a1, 6, (int)&v12) && (v12 & 0x80000000u) == 0 && (signed int)v12 <= 50 )
  {
    *(_BYTE *)v11 = v12;
    v6 = v3 - 1;
    if ( v3 - 1 <= 0 )
    {
LABEL_17:
      result = *(_BYTE *)(v4 + 44) ^ 1;
    }
    else
    {
      v7 = 1;
      while ( 1 )
      {
        v8 = sub_408758(v4, 6);
        v9 = v8;
        if ( v8 > 2 )
        {
          if ( v8 >= 6 )
          {
            v12 = sub_40864C(v4, 6);
          }
          else
          {
            v10 = sub_408704(v4);
            v12 += (-v10 ^ (v9 - 1)) + v10;
          }
        }
        else
        {
          v12 += (-(v8 & 1) ^ (((v8 & 1u) + v8) >> 1)) + (v8 & 1);
        }
        if ( (signed int)(v12 & 0xFFFFFFF) > 50 )
          break;
        if ( (unsigned int)v7 > 0x7F )
          sub_402CA8();
        *(_BYTE *)(v11 + v7++) = v12;
        --v6;
        if ( !v6 )
          goto LABEL_17;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040B6FC) --------------------------------------------------------
int __userpurge sub_40B6FC<eax>(int a1<eax>, char a2<dl>, signed int ecx0<ecx>, signed int a3, int a4)
{
  signed int v5; // esi@3
  char v6; // ST27_1@3
  int v7; // ebx@3
  int v8; // eax@3
  signed int v10; // [sp-10h] [bp-20h]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v5 = ecx0;
  v6 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 4) = a3;
  LOBYTE(v8) = sub_40B58C(v5);
  *(_DWORD *)(v7 + 8) = sub_40B224((int)off_40B1C8, 1, v5, v8, a3, v10);
  if ( v6 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40B1C8: using guessed type char *off_40B1C8;

//----- (0040B760) --------------------------------------------------------
int __cdecl sub_40B760()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 8));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (0040B790) --------------------------------------------------------
char __userpurge sub_40B790<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4)
{
  int v5; // esi@1
  unsigned int v6; // edi@11
  unsigned __int8 v7; // bl@14
  int v8; // esi@14
  int v10; // [sp+0h] [bp-A4h]@0
  char v11[128]; // [sp+Ch] [bp-98h]@10
  int v12; // [sp+8Ch] [bp-18h]@11
  int v13; // [sp+90h] [bp-14h]@3
  int v14; // [sp+94h] [bp-10h]@5
  char v15; // [sp+9Bh] [bp-9h]@3
  int v16; // [sp+9Ch] [bp-8h]@1
  int v17; // [sp+A0h] [bp-4h]@1

  v5 = ecx0;
  v16 = a2;
  v17 = a1;
  if ( a3 > *(_DWORD *)(a1 + 4) )
    System::__linkproc___Assert(&str_Assertion_failu_0[1], &str_D__VocComp_Win__1[1]);
  v15 = 0;
  if ( sub_408814(v16, 1, (int)&v13) )
  {
    if ( v13 )
    {
      sub_40B2E4(*(_DWORD *)(v17 + 8), a3);
      v13 = *(_DWORD *)(*(_DWORD *)(v17 + 8) + 20);
      if ( v13 > 1 && sub_40B618(v16, v13, (int)v11) )
      {
        v12 = v5;
        v6 = 0;
        if ( v13 <= 0 )
        {
LABEL_21:
          v15 = 1;
        }
        else
        {
          while ( 1 )
          {
            if ( v6 > 0x7F )
              sub_402CA8();
            v7 = v11[v6];
            v8 = 0;
            do
            {
              v8 += sub_40B3A4(*(_DWORD *)(v17 + 8), v6++);
              if ( v6 == v13 )
                break;
              if ( v6 > 0x7F )
                sub_402CA8();
            }
            while ( v7 == v11[v6] );
            if ( !sub_40B5B0(v7, v16, v12, v8, v10) )
              break;
            v12 += 4 * v8;
            if ( (signed int)v6 >= v13 )
              goto LABEL_21;
          }
        }
      }
    }
    else
    {
      if ( sub_408814(v16, 6, (int)&v14) && v14 >= 0 && v14 <= 50 )
        v15 = sub_40B5B0(v14, v16, v5, a3, v10);
    }
  }
  return v15;
}
// 40B8D0: using guessed type _strings str_D__VocComp_Win__1[5];
// 40B900: using guessed type _strings str_Assertion_failu_0[3];
// 40B790: using guessed type char var_98[128];

//----- (0040B91C) --------------------------------------------------------
int __cdecl sub_40B91C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A88C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A88C: using guessed type int dword_41A88C;

//----- (0040B94C) --------------------------------------------------------
void __cdecl sub_40B94C()
{
  --dword_41A88C;
}
// 41A88C: using guessed type int dword_41A88C;

//----- (0040B954) --------------------------------------------------------
int __userpurge sub_40B954<eax>(int result<eax>, int a2<edx>, char cl0<cl>, int a3, int a4)
{
  signed int v5; // esi@1
  int v6; // ecx@1
  int v7; // edx@1
  int v8; // edx@4
  signed int v9; // esi@4
  char v10; // [sp+10h] [bp-8h]@1
  int v11; // [sp+14h] [bp-4h]@1

  v10 = cl0;
  v11 = a2;
  v5 = 2;
  v6 = result;
  v7 = a3;
  do
  {
    *(_DWORD *)v7 = *(_DWORD *)v6;
    v7 += 4;
    v6 += 4;
    --v5;
  }
  while ( v5 );
  if ( v11 - 1 >= 2 )
  {
    v8 = v11 - 3 + 1;
    v9 = 2;
    do
    {
      if ( (unsigned int)v9 > 0xFF )
        sub_402CA8();
      if ( (unsigned int)v9 > 0xFF )
        sub_402CA8();
      *(_DWORD *)(a3 + 4 * v9) = *(_DWORD *)(result + 4 * v9) << (9 - v10);
      ++v9;
      --v8;
    }
    while ( v8 );
  }
  return result;
}

//----- (0040B9D0) --------------------------------------------------------
int __usercall sub_40B9D0<eax>(int result<eax>, signed int a2<edx>, char cl0<cl>)
{
  int v3; // ebx@1
  int v4; // edx@1
  unsigned int v5; // edx@2
  unsigned int v6; // edi@7
  signed int v7; // [sp+4h] [bp-1Ch]@1
  signed int v8; // [sp+8h] [bp-18h]@1
  int v9; // [sp+Ch] [bp-14h]@2

  v7 = -1 << (32 - cl0);
  v8 = 1 << (cl0 - 1);
  v3 = a2 - 1;
  v4 = a2 / 2 - 1;
  if ( v4 >= 0 )
  {
    v9 = v4 + 1;
    v5 = 0;
    do
    {
      if ( v5 > 0xFF )
        sub_402CA8();
      if ( (unsigned int)v3 > 0xFF )
        sub_402CA8();
      v6 = v8 + *(_DWORD *)(result + 4 * v3);
      if ( (unsigned int)v3 > 0xFF )
        sub_402CA8();
      *(_DWORD *)(result + 4 * v3) = -(v7 & -((unsigned int)(v8 + *(_DWORD *)(result + 4 * v5)) >> 31) | ((unsigned int)(v8 + *(_DWORD *)(result + 4 * v5)) >> cl0));
      if ( v5 > 0xFF )
        sub_402CA8();
      *(_DWORD *)(result + 4 * v5) = -(v7 & -(v6 >> 31) | (v6 >> cl0));
      --v3;
      ++v5;
      --v9;
    }
    while ( v9 );
  }
  return result;
}

//----- (0040BA90) --------------------------------------------------------
int __usercall sub_40BA90<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int result; // eax@1
  int v5; // ebp@1
  signed int v6; // ebx@2
  int v7; // [sp+0h] [bp-14h]@1

  v3 = ecx0;
  v7 = a1;
  result = *(_DWORD *)a1 << 6;
  *(_DWORD *)ecx0 = result;
  v5 = a2 - 1;
  if ( a2 - 1 > 0 )
  {
    v6 = 1;
    do
    {
      if ( (unsigned int)v6 > 0xFF )
        sub_402CA8();
      if ( (unsigned int)(v6 - 1) > 0xFF )
        sub_402CA8();
      sub_40BE85(v3, v3 + 4 * (v6 - 1), (v6 + 1) / 2, *(_DWORD *)(v7 + 4 * v6), v7);
      if ( (unsigned int)v6 > 0xFF )
        sub_402CA8();
      result = *(_DWORD *)(v7 + 4 * v6) << 6;
      if ( (unsigned int)v6 > 0xFF )
        sub_402CA8();
      *(_DWORD *)(v3 + 4 * v6++) = result;
      --v5;
    }
    while ( v5 );
  }
  return result;
}

//----- (0040BB1C) --------------------------------------------------------
int __fastcall sub_40BB1C(int a1)
{
  int v1; // ebx@1
  int v3; // [sp+0h] [bp-4h]@0

  v1 = a1;
  sub_40B954(*(_DWORD *)(a1 + 24), *(_DWORD *)(a1 + 8), *(_DWORD *)(a1 + 12), *(_DWORD *)(a1 + 24), v3);
  sub_40BA90(*(_DWORD *)(v1 + 24), *(_DWORD *)(v1 + 8), *(_DWORD *)(v1 + 20));
  return sub_40B9D0(*(_DWORD *)(v1 + 20), *(_DWORD *)(v1 + 8), *(_DWORD *)(v1 + 16) + 5);
}

//----- (0040BB50) --------------------------------------------------------
int __fastcall sub_40BB50(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int result; // eax@1
  signed int v5; // [sp+0h] [bp-8h]@0

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a1 + 4) = 0;
  *(_DWORD *)a1 = a2;
  *(_DWORD *)(a1 + 8) = 0;
  *(_DWORD *)(a1 + 4) = sub_409664((int)off_4095DC, 1, 8 * a2, a1 + 20, 64, v5);
  result = 4 * v2 + *(_DWORD *)(v3 + 20);
  *(_DWORD *)(v3 + 24) = result;
  return result;
}
// 4095DC: using guessed type char *off_4095DC;

//----- (0040BB9C) --------------------------------------------------------
int __userpurge sub_40BB9C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, int a6)
{
  int v7; // esi@1
  int result; // eax@4

  v7 = ecx0;
  if ( (_BYTE)a4 )
    sub_40BDC8(a1, a3 + 48, a2);
  else
    sub_40BD2C(a1, a3 + 48, a2);
  *(_DWORD *)a3 = 0x200u >> v7;
  *(_DWORD *)(a3 + 4) = 0x200u >> v7;
  *(_DWORD *)(a3 + 8) = a5;
  *(_DWORD *)(a3 + 12) = 0;
  *(_DWORD *)(a3 + 16) = 10 - v7;
  result = 0;
  *(_DWORD *)(a3 + 20) = 0;
  return result;
}

//----- (0040BBF8) --------------------------------------------------------
char __fastcall sub_40BBF8(int a1, int a2)
{
  int v2; // esi@1
  int v3; // edi@1
  unsigned int v4; // eax@3
  unsigned int v6; // ebp@8
  signed int v7; // ebx@9
  unsigned int v8; // eax@10
  unsigned int v9; // [sp+0h] [bp-20h]@6
  signed int v10; // [sp+4h] [bp-1Ch]@6
  int v11; // [sp+8h] [bp-18h]@8
  int v12; // [sp+Ch] [bp-14h]@7

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a2 + 12) = sub_40864C(a1, 1) + 5;
  if ( sub_408704(v3) )
  {
    v4 = sub_40864C(v3, 3);
    *(_DWORD *)(v2 + 16) = v4 + 1;
    if ( (signed int)(v4 + 1) > 7 )
      return 0;
  }
  else
  {
    *(_DWORD *)(v2 + 16) = 0;
  }
  **(_DWORD **)(v2 + 24) = sub_4086E0(v3, 10);
  *(_DWORD *)(*(_DWORD *)(v2 + 24) + 4) = sub_4086E0(v3, 10);
  *(_DWORD *)(*(_DWORD *)(v2 + 24) + 8) = sub_4086E0(v3, *(_DWORD *)(v2 + 12) + 1);
  *(_DWORD *)(*(_DWORD *)(v2 + 24) + 12) = sub_4086E0(v3, *(_DWORD *)(v2 + 12) + 1);
  if ( *(_DWORD *)(v2 + 8) > 4 )
  {
    v9 = *(_DWORD *)(v2 + 12) + 1 - sub_40864C(v3, 1);
    v10 = 4;
    if ( (*(_DWORD *)(v2 + 8) - 4) / 4 - 1 >= 0 )
    {
      v12 = (*(_DWORD *)(v2 + 8) - 4) / 4;
      do
      {
        v11 = v9 - sub_40864C(v3, 2);
        v6 = v10;
        if ( !__OFSUB__(v10 + 3, v10) )
        {
          v7 = 4;
          do
          {
            v8 = sub_4086E0(v3, v11);
            if ( v6 > 0xFF )
              sub_402CA8();
            *(_DWORD *)(*(_DWORD *)(v2 + 24) + 4 * v6++) = v8;
            --v7;
          }
          while ( v7 );
        }
        v10 += 4;
        --v12;
      }
      while ( v12 );
    }
  }
  return *(_BYTE *)(v3 + 44) ^ 1;
}

//----- (0040BD2C) --------------------------------------------------------
int __usercall sub_40BD2C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  __m64 v3; // mm0@1
  __m64 v4; // mm1@1
  __m64 v5; // mm1@1
  int result; // eax@1
  int v7; // edx@1
  int i; // ecx@1
  __m64 v9; // mm1@2
  __m64 v10; // mm3@2
  __m64 v11; // mm3@2
  __m64 v12; // mm0@3
  __m64 v13; // mm0@3

  v3 = _m_packssdw(*(__m64 *)a1, *(__m64 *)(a1 + 8));
  *(_QWORD *)a2 = v3;
  v4 = _m_psllq(v3, 0x10u);
  *(_QWORD *)(a2 + 8) = v4;
  v5 = _m_psllq(v4, 0x10u);
  *(_QWORD *)(a2 + 16) = v5;
  *(_QWORD *)(a2 + 24) = _m_psllq(v5, 0x10u);
  result = a1 + 16;
  v7 = a2 + 32;
  for ( i = ecx0 - 4; i; i -= 4 )
  {
    v9 = _m_packssdw(*(__m64 *)result, *(__m64 *)(result + 8));
    *(_QWORD *)v7 = v9;
    v10 = _m_psllq(v9, 0x10u);
    *(_QWORD *)(v7 + 8) = _m_por(_m_psrlq(v3, 0x30u), v10);
    v11 = _m_psllq(v10, 0x10u);
    *(_QWORD *)(v7 + 16) = _m_por(_m_psrlq(v3, 0x20u), v11);
    *(_QWORD *)(v7 + 24) = _m_por(_m_psrlq(v3, 0x10u), _m_psllq(v11, 0x10u));
    v3 = v9;
    result += 16;
    v7 += 32;
  }
  v12 = _m_psrlq(v3, 0x10u);
  *(_QWORD *)(v7 + 24) = v12;
  v13 = _m_psrlq(v12, 0x10u);
  *(_QWORD *)(v7 + 16) = v13;
  *(_QWORD *)(v7 + 8) = _m_psrlq(v13, 0x10u);
  _m_femms();
  return result;
}

//----- (0040BDC8) --------------------------------------------------------
int __usercall sub_40BDC8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  __m128i v3; // xmm0@1
  __m128i v4; // xmm1@1
  __m128i v5; // xmm1@1
  int result; // eax@1
  int v7; // edx@1
  int i; // ecx@1
  __m128i v9; // xmm1@2
  __m128i v10; // xmm3@2
  __m128i v11; // xmm3@2
  __m128i v12; // xmm0@3
  __m128i v13; // xmm0@3

  v3 = _mm_packs_epi32(_mm_load_si128((const __m128i *)a1), *(__m128i *)(a1 + 16));
  _mm_store_si128((__m128i *)a2, v3);
  v4 = _mm_slli_si128(v3, 2);
  _mm_store_si128((__m128i *)(a2 + 16), v4);
  v5 = _mm_slli_si128(v4, 2);
  _mm_store_si128((__m128i *)(a2 + 32), v5);
  _mm_store_si128((__m128i *)(a2 + 48), _mm_slli_si128(v5, 2));
  result = a1 + 32;
  v7 = a2 + 64;
  for ( i = ecx0 - 8; i; i -= 8 )
  {
    v9 = _mm_packs_epi32(_mm_load_si128((const __m128i *)result), *(__m128i *)(result + 16));
    _mm_store_si128((__m128i *)v7, v9);
    v10 = _mm_slli_si128(v9, 2);
    _mm_store_si128((__m128i *)(v7 + 16), _mm_or_si128(_mm_srli_si128(v3, 14), v10));
    v11 = _mm_slli_si128(v10, 2);
    _mm_store_si128((__m128i *)(v7 + 32), _mm_or_si128(_mm_srli_si128(v3, 12), v11));
    _mm_store_si128((__m128i *)(v7 + 48), _mm_or_si128(_mm_srli_si128(v3, 10), _mm_slli_si128(v11, 2)));
    v3 = v9;
    result += 32;
    v7 += 64;
  }
  v12 = _mm_srli_si128(v3, 10);
  _mm_store_si128((__m128i *)(v7 + 48), v12);
  v13 = _mm_srli_si128(v12, 2);
  _mm_store_si128((__m128i *)(v7 + 32), v13);
  _mm_store_si128((__m128i *)(v7 + 16), _mm_srli_si128(v13, 2));
  return result;
}

//----- (0040BE85) --------------------------------------------------------
int __userpurge sub_40BE85<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@1

  do
  {
    v5 = *(_DWORD *)result + ((a3 * *(_DWORD *)a2 + 256) >> 9);
    *(_DWORD *)a2 += (a3 * *(_DWORD *)result + 256) >> 9;
    *(_DWORD *)result = v5;
    result += 4;
    a2 -= 4;
    --ecx0;
  }
  while ( ecx0 );
  return result;
}

//----- (0040BEC0) --------------------------------------------------------
int __cdecl sub_40BEC0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A890;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A890: using guessed type int dword_41A890;

//----- (0040BEF0) --------------------------------------------------------
void __cdecl sub_40BEF0()
{
  --dword_41A890;
}
// 41A890: using guessed type int dword_41A890;

//----- (0040BEF8) --------------------------------------------------------
int __userpurge sub_40BEF8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, char a4, int a5, int a6, int a7, int a8)
{
  int result; // eax@1
  int v10; // esi@1
  int v11; // ebx@1
  int v12; // edx@3
  unsigned int v13; // eax@3
  int v14; // eax@7
  int v15; // [sp+Ch] [bp-1Ch]@2
  int v16; // [sp+24h] [bp-4h]@1

  v16 = a1;
  result = a5;
  v10 = a6 + 4 * a5;
  v11 = ecx0 + 4 * a5;
  if ( a2 > 0 )
  {
    v15 = a2;
    do
    {
      v12 = -a5;
      v13 = 1 << (10 - a4 - 1);
      if ( a5 & 4 )
      {
        do
        {
          v13 += *(_DWORD *)(v11 + 4 * v12 + 12) * *(_DWORD *)(v10 + 4 * v12 + 12)
               + *(_DWORD *)(v11 + 4 * v12 + 8) * *(_DWORD *)(v10 + 4 * v12 + 8)
               + *(_DWORD *)(v11 + 4 * v12 + 4) * *(_DWORD *)(v10 + 4 * v12 + 4)
               + *(_DWORD *)(v11 + 4 * v12) * *(_DWORD *)(v10 + 4 * v12);
          v12 += 4;
        }
        while ( v12 );
      }
      else
      {
        do
        {
          v13 += *(_DWORD *)(v11 + 4 * v12 + 28) * *(_DWORD *)(v10 + 4 * v12 + 28)
               + *(_DWORD *)(v11 + 4 * v12 + 24) * *(_DWORD *)(v10 + 4 * v12 + 24)
               + *(_DWORD *)(v11 + 4 * v12 + 20) * *(_DWORD *)(v10 + 4 * v12 + 20)
               + *(_DWORD *)(v11 + 4 * v12 + 16) * *(_DWORD *)(v10 + 4 * v12 + 16)
               + *(_DWORD *)(v11 + 4 * v12 + 12) * *(_DWORD *)(v10 + 4 * v12 + 12)
               + *(_DWORD *)(v11 + 4 * v12 + 8) * *(_DWORD *)(v10 + 4 * v12 + 8)
               + *(_DWORD *)(v11 + 4 * v12 + 4) * *(_DWORD *)(v10 + 4 * v12 + 4)
               + *(_DWORD *)(v11 + 4 * v12) * *(_DWORD *)(v10 + 4 * v12);
          v12 += 8;
        }
        while ( v12 );
      }
      v14 = (-1 << (32 - (10 - a4))) & -(v13 >> 31) | (v13 >> (10 - a4));
      if ( v14 > 8191 )
        v14 = 8191;
      if ( v14 < -8192 )
        v14 = -8192;
      result = (v14 << a3) - *(_DWORD *)v16;
      *(_DWORD *)a7 = result;
      a7 += 4;
      v16 += 4;
      v11 += 4;
      --v15;
    }
    while ( v15 );
  }
  return result;
}

//----- (0040C04C) --------------------------------------------------------
int __cdecl sub_40C04C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A894;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A894: using guessed type int dword_41A894;

//----- (0040C07C) --------------------------------------------------------
void __cdecl sub_40C07C()
{
  --dword_41A894;
}
// 41A894: using guessed type int dword_41A894;

//----- (0040C084) --------------------------------------------------------
int __cdecl sub_40C084()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A898;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A898: using guessed type int dword_41A898;

//----- (0040C0B4) --------------------------------------------------------
void __cdecl sub_40C0B4()
{
  --dword_41A898;
}
// 41A898: using guessed type int dword_41A898;

//----- (0040C0BC) --------------------------------------------------------
int __userpurge sub_40C0BC<eax>(int a1<eax>, int a2<edx>, char cl0<cl>, char a3, int a4, int a5, int a6, int a7)
{
  int result; // eax@1
  int v9; // esi@1
  int v10; // edx@3
  unsigned int v11; // ebx@3
  int v12; // ebx@7
  unsigned int v13; // edx@11
  int v14; // [sp+8h] [bp-18h]@2
  char v15; // [sp+Fh] [bp-11h]@1
  int v16; // [sp+1Ch] [bp-4h]@1

  result = a1 + 4 * a2;
  v9 = a4 + 4 * a2;
  v16 = -a2;
  v15 = (a2 & 4) != 0;
  if ( a5 > 0 )
  {
    v14 = a5;
    do
    {
      v10 = v16;
      v11 = 1 << (10 - cl0 - 1);
      if ( v15 )
      {
        do
        {
          v11 += *(_DWORD *)(v9 + 4 * v10 + 12) * *(_DWORD *)(result + 4 * v10 + 12)
               + *(_DWORD *)(v9 + 4 * v10 + 8) * *(_DWORD *)(result + 4 * v10 + 8)
               + *(_DWORD *)(v9 + 4 * v10 + 4) * *(_DWORD *)(result + 4 * v10 + 4)
               + *(_DWORD *)(v9 + 4 * v10) * *(_DWORD *)(result + 4 * v10);
          v10 += 4;
        }
        while ( v10 );
      }
      else
      {
        do
        {
          v11 += *(_DWORD *)(v9 + 4 * v10 + 28) * *(_DWORD *)(result + 4 * v10 + 28)
               + *(_DWORD *)(v9 + 4 * v10 + 24) * *(_DWORD *)(result + 4 * v10 + 24)
               + *(_DWORD *)(v9 + 4 * v10 + 20) * *(_DWORD *)(result + 4 * v10 + 20)
               + *(_DWORD *)(v9 + 4 * v10 + 16) * *(_DWORD *)(result + 4 * v10 + 16)
               + *(_DWORD *)(v9 + 4 * v10 + 12) * *(_DWORD *)(result + 4 * v10 + 12)
               + *(_DWORD *)(v9 + 4 * v10 + 8) * *(_DWORD *)(result + 4 * v10 + 8)
               + *(_DWORD *)(v9 + 4 * v10 + 4) * *(_DWORD *)(result + 4 * v10 + 4)
               + *(_DWORD *)(v9 + 4 * v10) * *(_DWORD *)(result + 4 * v10);
          v10 += 8;
        }
        while ( v10 );
      }
      v12 = (-1 << (32 - (10 - cl0))) & -(v11 >> 31) | (v11 >> (10 - cl0));
      if ( v12 > 8191 )
        v12 = 8191;
      if ( v12 < -8192 )
        v12 = -8192;
      v13 = (v12 << a3) - *(_DWORD *)a6;
      *(_DWORD *)a6 = v13;
      *(_DWORD *)v9 = (signed __int16)(v13 >> a3);
      a6 += 4;
      v9 += 4;
      --v14;
    }
    while ( v14 );
  }
  return result;
}

//----- (0040C210) --------------------------------------------------------
int __usercall sub_40C210<eax>(int a1<eax>, int a2<ecx>)
{
  int v2; // ebx@1
  int result; // eax@1
  int v4; // ebp@1
  int v5; // esi@1
  int v6; // edi@3
  int v7; // [sp+0h] [bp-14h]@1

  v2 = a1;
  sub_409510(*(_DWORD *)(a1 + 8), *(_DWORD *)(a1 + 20), *(_DWORD *)(a1 + 16), *(_DWORD *)(a1 + 4), a2);
  result = *(_DWORD *)(v2 + 16);
  v7 = *(_DWORD *)(v2 + 8) + 4 * result;
  v4 = 544 - result;
  v5 = *(_DWORD *)(v2 + 12) - result;
  while ( v5 > 0 )
  {
    if ( v4 >= v5 )
      v6 = v5;
    else
      v6 = v4;
    result = sub_40C0BC(
               *(_DWORD *)(*(_DWORD *)v2 + 20),
               *(_DWORD *)(v2 + 16),
               *(_DWORD *)(*(_DWORD *)v2 + 16),
               *(_DWORD *)(v2 + 4),
               *(_DWORD *)(v2 + 20),
               v6,
               v7,
               v7);
    v5 -= v6;
    if ( v5 > 0 )
    {
      System::Move(*(_DWORD *)(v2 + 20) + 4 * v4, *(_DWORD *)(v2 + 20));
      result = 4 * v6;
      v7 += 4 * v6;
    }
  }
  return result;
}

//----- (0040C298) --------------------------------------------------------
int __fastcall sub_40C298(int a1, int a2)
{
  int v2; // ebx@1
  char v3; // al@3
  int v4; // edx@5
  signed int v5; // eax@5
  int v6; // ebp@5
  int v7; // esi@5
  int result; // eax@6
  int v9; // esi@10
  int v10; // edi@12
  int v11; // [sp+0h] [bp-1Ch]@0
  unsigned int v12; // [sp+0h] [bp-1Ch]@5
  void *v13; // [sp+4h] [bp-18h]@8
  int v14; // [sp+8h] [bp-14h]@10

  v2 = a1;
  v3 = *(_BYTE *)a2 & 8 && *(_DWORD *)(a1 + 16) >= 32;
  LOBYTE(v11) = v3;
  v4 = *(_DWORD *)(v2 + 4);
  LOBYTE(v4) = v3;
  sub_40BB9C(
    *(_DWORD *)(*(_DWORD *)v2 + 20),
    *(_DWORD *)(v2 + 16),
    *(_DWORD *)(*(_DWORD *)v2 + 16),
    *(_DWORD *)(v2 + 20) + 2176,
    v4,
    *(_DWORD *)(v2 + 4),
    v11);
  sub_4088BD(*(_DWORD *)(v2 + 8), *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 16), *(_DWORD *)(v2 + 4), v12);
  v5 = *(_DWORD *)(v2 + 16);
  v6 = *(_DWORD *)(v2 + 8) + 4 * v5;
  v7 = *(_DWORD *)(v2 + 12) - v5;
  if ( v5 > 12 )
  {
    if ( (_BYTE)v12 )
      v13 = sub_408F82;
    else
      v13 = sub_408ED4;
    v9 = (v7 + 3) & 0xFFFFFFFC;
    result = (544 - *(_DWORD *)(v2 + 16)) & 0xFFFFFFFC;
    v14 = (544 - *(_DWORD *)(v2 + 16)) & 0xFFFFFFFC;
    while ( v9 > 0 )
    {
      if ( v9 <= v14 )
        v10 = v9;
      else
        v10 = v14;
      result = ((int (__cdecl *)(int, int, _DWORD, int, _DWORD))v13)(
                 v6,
                 v10,
                 *(_DWORD *)(v2 + 20),
                 *(_DWORD *)(v2 + 20) + 2176,
                 *(_DWORD *)(v2 + 16));
      v9 -= v10;
      if ( v9 > 0 )
      {
        System::Move(*(_DWORD *)(v2 + 20) + 2 * v10, *(_DWORD *)(v2 + 20));
        result = 4 * v10;
        v6 += 4 * v10;
      }
    }
  }
  else
  {
    result = sub_408C41(v6, v7, *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 20) + 2176, *(_DWORD *)(v2 + 16));
  }
  return result;
}

//----- (0040C39C) --------------------------------------------------------
int __usercall sub_40C39C<eax>(int a1<eax>, int a2<edx>, int a3<ecx>)
{
  int result; // eax@2

  if ( *(_BYTE *)a1 & 2 )
    result = sub_40C298(a2, a1);
  else
    result = sub_40C210(a2, a3);
  return result;
}

//----- (0040C3B0) --------------------------------------------------------
int __cdecl sub_40C3B0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A89C;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A89C: using guessed type int dword_41A89C;

//----- (0040C3E0) --------------------------------------------------------
void __cdecl sub_40C3E0()
{
  --dword_41A89C;
}
// 41A89C: using guessed type int dword_41A89C;

//----- (0040C3E8) --------------------------------------------------------
int __cdecl sub_40C3E8()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8A0;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8A0: using guessed type int dword_41A8A0;

//----- (0040C418) --------------------------------------------------------
void __cdecl sub_40C418()
{
  --dword_41A8A0;
}
// 41A8A0: using guessed type int dword_41A8A0;

//----- (0040C484) --------------------------------------------------------
char __usercall sub_40C484<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  unsigned int v4; // eax@2
  unsigned int v5; // edi@6
  unsigned int v6; // ebx@6
  unsigned int v7; // ebp@7
  unsigned int v8; // eax@12
  unsigned int v9; // eax@14
  signed int v10; // edi@36
  unsigned int v11; // ebx@36
  int v14; // [sp+0h] [bp-24h]@1
  signed int v15; // [sp+4h] [bp-20h]@1
  char v16; // [sp+8h] [bp-1Ch]@1
  char v17; // [sp+8h] [bp-1Ch]@34
  int v18; // [sp+Ch] [bp-18h]@5
  signed int v19; // [sp+10h] [bp-14h]@7

  v3 = ecx0;
  v15 = a2;
  v14 = a1;
  v16 = 0;
  if ( sub_408704(a1) )
  {
    v4 = sub_40864C(v14, 4) + 1;
    if ( (signed int)v4 > v15 )
      return v16;
  }
  else
  {
    v4 = 0;
  }
  if ( !v4 )
  {
    *(_DWORD *)v3 = v15;
    if ( v15 - 1 >= 0 )
    {
      v10 = v15;
      v11 = 0;
      do
      {
        if ( v11 > 0xF )
          sub_402CA8();
        if ( v11 > 0xFF )
          sub_402CA8();
        *(_BYTE *)(v3 + 12 * v11 + 4) = v11;
        if ( v11 > 0xF )
          sub_402CA8();
        *(_BYTE *)(v3 + 12 * v11++ + 5) = 0;
        --v10;
      }
      while ( v10 );
    }
    v17 = 1;
    return v17 && !*(_BYTE *)(v14 + 44);
  }
  *(_DWORD *)v3 = v4;
  v18 = 0;
  if ( ((v4 - 1) & 0x80000000u) != 0 )
  {
LABEL_34:
    v17 = (1 << v15) - 1 == v18;
    return v17 && !*(_BYTE *)(v14 + 44);
  }
  v5 = v4;
  v6 = 0;
  while ( 1 )
  {
    v7 = sub_40864C(v14, 4);
    v19 = 1 << v7;
    if ( (signed int)v7 >= v15 )
      return v16;
    if ( v19 & v18 )
      return v16;
    if ( sub_408704(v14) )
    {
      if ( v6 > 0xF )
        sub_402CA8();
      *(_BYTE *)(v3 + 12 * v6 + 5) = 1;
      v8 = sub_40864C(v14, 2) + 1;
      if ( v6 > 0xF )
        sub_402CA8();
      *(_DWORD *)(v3 + 12 * v6 + 8) = v8;
      v9 = sub_40864C(v14, 4);
      if ( v6 > 0xF )
        sub_402CA8();
      if ( *(_DWORD *)(v3 + 12 * v6 + 8) == 2 )
      {
        if ( v18 & (1 << v9) || v7 == v9 )
          return v16;
        v18 |= 1 << v9;
      }
      else
      {
        if ( !(v18 & (1 << v9)) )
          return v16;
      }
      if ( v6 > 0xF )
        sub_402CA8();
      if ( v9 > 0xFF )
        sub_402CA8();
      *(_BYTE *)(v3 + 12 * v6 + 12) = v9;
    }
    else
    {
      if ( v6 > 0xF )
        sub_402CA8();
      *(_BYTE *)(v3 + 12 * v6 + 5) = 0;
    }
    v18 |= v19;
    if ( v6 > 0xF )
      sub_402CA8();
    if ( v7 > 0xFF )
      sub_402CA8();
    *(_BYTE *)(v3 + 12 * v6++ + 4) = v7;
    --v5;
    if ( !v5 )
      goto LABEL_34;
  }
}

//----- (0040C698) --------------------------------------------------------
int __fastcall sub_40C698(unsigned int a1)
{
  if ( a1 > 5 )
    sub_402CA8();
  return (unsigned __int8)byte_418EAC[a1];
}

//----- (0040C6AC) --------------------------------------------------------
char __fastcall sub_40C6AC(int a1, int a2)
{
  int v2; // ebp@1
  int v3; // esi@1
  int v4; // edi@1
  unsigned int v5; // ebx@1
  unsigned int v6; // eax@2

  v2 = a2;
  v3 = a1;
  v4 = 14 - sub_40864C(a1, 3);
  v5 = 0;
  do
  {
    v6 = sub_4086E0(v3, v4);
    if ( v5 > 0xFF )
      sub_402CA8();
    *(_DWORD *)(v2 + 4 * v5++) = v6;
  }
  while ( v5 != 4 );
  return *(_BYTE *)(v3 + 44) ^ 1;
}

//----- (0040C6F4) --------------------------------------------------------
char __fastcall sub_40C6F4(int a1, int a2)
{
  int v2; // edi@1
  int v3; // ebp@1
  unsigned int v4; // esi@1
  int v5; // ebx@2
  char result; // al@6

  v2 = a2;
  v3 = a1;
  v4 = 0;
  if ( *(_DWORD *)(a2 + 72) / 4 - 1 < 0 )
  {
LABEL_8:
    result = 1;
  }
  else
  {
    v5 = *(_DWORD *)(a2 + 72) / 4;
    while ( 1 )
    {
      if ( v4 > 0xFF )
        sub_402CA8();
      if ( !sub_40C6AC(v3, *(_DWORD *)(v2 + 68) + 4 * v4) )
        break;
      v4 += 4;
      --v5;
      if ( !v5 )
        goto LABEL_8;
    }
    result = 0;
  }
  return result;
}

//----- (0040C740) --------------------------------------------------------
int __fastcall sub_40C740(int result)
{
  unsigned int v1; // edx@1

  v1 = (result & 4u) >> 2;
  if ( v1 > 0x10 )
    sub_402CA8();
  *(_DWORD *)(result + 68) = result + 4 * v1;
  return result;
}

//----- (0040C75C) --------------------------------------------------------
int __fastcall sub_40C75C(int a1)
{
  return sub_40C740(a1 + 12);
}

//----- (0040C768) --------------------------------------------------------
char __fastcall sub_40C768(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1
  char result; // al@2

  v2 = a2;
  v3 = a1;
  if ( (unsigned int)(*(_DWORD *)a2 - 4) < 4 )
  {
    if ( sub_40B154(a1, a2 + 8) )
    {
      if ( (unsigned int)(*(_DWORD *)v2 - 4) >= 2 )
      {
        if ( sub_40864C(v3, 1) )
          *(_DWORD *)(v2 + 84) = 16;
        else
          *(_DWORD *)(v2 + 84) = 8;
        *(_BYTE *)(v2 + 4) = sub_408704(v3) != 0;
        *(_BYTE *)(v2 + 5) = sub_408704(v3) != 0;
        result = sub_40C6F4(v3, v2 + 12);
      }
      else
      {
        result = sub_408834(v3, 10, *(_DWORD *)(v2 + 80));
      }
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 1;
  }
  return result;
}

//----- (0040C7F8) --------------------------------------------------------
char __fastcall sub_40C7F8(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  return sub_408814(a1, 3, a2) && sub_40C768(v3, v2);
}

//----- (0040C828) --------------------------------------------------------
int __usercall sub_40C828<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>)
{
  int v3; // ebx@2

  if ( ecx0 >= 2 )
  {
    result += 4 * (ecx0 & 0xFFFFFFFE);
    a2 += 4 * (ecx0 & 0xFFFFFFFE);
    v3 = -(ecx0 & 0xFFFFFFFE);
    do
    {
      *(_DWORD *)(a2 + 4 * v3) += *(_DWORD *)(result + 4 * v3);
      *(_DWORD *)(a2 + 4 * v3 + 4) += *(_DWORD *)(result + 4 * v3 + 4);
      v3 += 2;
    }
    while ( v3 );
  }
  if ( ecx0 & 1 )
  {
    result = *(_DWORD *)result;
    *(_DWORD *)a2 += result;
  }
  return result;
}

//----- (0040C860) --------------------------------------------------------
int __usercall sub_40C860<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>)
{
  int v3; // ebx@2

  if ( ecx0 >= 2 )
  {
    result += 4 * (ecx0 & 0xFFFFFFFE);
    a2 += 4 * (ecx0 & 0xFFFFFFFE);
    v3 = -(ecx0 & 0xFFFFFFFE);
    do
    {
      *(_DWORD *)(a2 + 4 * v3) = *(_DWORD *)(result + 4 * v3) - *(_DWORD *)(a2 + 4 * v3);
      *(_DWORD *)(a2 + 4 * v3 + 4) = *(_DWORD *)(result + 4 * v3 + 4) - *(_DWORD *)(a2 + 4 * v3 + 4);
      v3 += 2;
    }
    while ( v3 );
  }
  if ( ecx0 & 1 )
  {
    result = *(_DWORD *)result - *(_DWORD *)a2;
    *(_DWORD *)a2 = result;
  }
  return result;
}

//----- (0040C8A0) --------------------------------------------------------
int __usercall sub_40C8A0<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ecx@1
  int v4; // ebx@3
  int v5; // esi@3
  int v6; // [sp+0h] [bp-10h]@2

  v3 = ecx0 - 1;
  if ( v3 >= 0 )
  {
    v6 = v3 + 1;
    do
    {
      v4 = *(_DWORD *)a2;
      v5 = (*(_DWORD *)a2 & 1) + 2 * *(_DWORD *)result;
      *(_DWORD *)result = ((*(_DWORD *)a2 & 1) + 2 * *(_DWORD *)result - *(_DWORD *)a2) & 0x80000000 | (((*(_DWORD *)a2 & 1u) + 2 * *(_DWORD *)result - *(_DWORD *)a2) >> 1);
      *(_DWORD *)a2 = (v4 + v5) & 0x80000000 | ((unsigned int)(v4 + v5) >> 1);
      result += 4;
      a2 += 4;
      --v6;
    }
    while ( v6 );
  }
  return result;
}

//----- (0040C8F0) --------------------------------------------------------
int __usercall sub_40C8F0<eax>(int a1<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>)
{
  int v4; // ebx@1
  int v5; // edi@1
  int v6; // esi@1
  int v7; // edx@2

  v4 = a3;
  v5 = a2;
  v6 = a1;
  if ( a3 >= 16 )
  {
    sub_4093C7(a1, a2, a3, a4);
    v7 = 4 * (v4 & 0xFFFFFFFC);
    v6 += v7;
    v5 += v7;
    v4 -= v4 & 0xFFFFFFFC;
  }
  return sub_40C8A0(v6, v5, v4);
}

//----- (0040C928) --------------------------------------------------------
int __userpurge sub_40C928<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // esi@5
  signed int v7; // [sp+Ch] [bp-4h]@2

  if ( a3 )
    v7 = -1 << (32 - a3);
  else
    v7 = 0;
  if ( ecx0 - 1 >= 0 )
  {
    v6 = ecx0;
    do
    {
      *(_DWORD *)a2 = ((-((a4 * (v7 & (unsigned int)-(*(_DWORD *)result >> 31) | (*(_DWORD *)result >> a3)) + 128) >> 31) & 0xFF000000 | ((a4 * (v7 & (unsigned int)-(*(_DWORD *)result >> 31) | (*(_DWORD *)result >> a3)) + 128) >> 8)) << a3)
                    - *(_DWORD *)a2;
      a2 += 4;
      result += 4;
      --v6;
    }
    while ( v6 );
  }
  return result;
}

//----- (0040C9A4) --------------------------------------------------------
int __userpurge sub_40C9A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // ebx@1
  int result; // eax@1
  unsigned int v8; // eax@5
  int v9; // edx@7
  int v10; // eax@7
  int v11; // edx@14
  unsigned int v12; // eax@14
  int v13; // [sp+0h] [bp-1Ch]@0
  int v14; // [sp+0h] [bp-1Ch]@1
  int v16; // [sp+8h] [bp-14h]@3
  unsigned int i; // [sp+Ch] [bp-10h]@1
  int v18; // [sp+10h] [bp-Ch]@1
  int v19; // [sp+14h] [bp-8h]@1
  int v20; // [sp+18h] [bp-4h]@1

  v19 = ecx0;
  v20 = a2;
  v6 = a1;
  sub_409510(ecx0, *(_DWORD *)(a1 + 8), *(_DWORD *)(a2 + 84), *(_DWORD *)(a2 + 8), v13);
  v18 = 544 - *(_DWORD *)(v20 + 84);
  result = 0;
  for ( i = 0; a3 > 0; a3 -= v16 )
  {
    if ( a3 <= v18 )
      v16 = a3;
    else
      v16 = v18;
    v8 = *(_DWORD *)(v20 + 84);
    if ( v8 > 0x3FFF )
      sub_402CA8();
    v9 = *(_DWORD *)(v6 + 8) + 4 * v8;
    v10 = i + v8;
    if ( (unsigned int)v10 > 0x3FFF )
      sub_402CA8();
    sub_409510(v19 + 4 * v10, v9, v16, *(_DWORD *)(v20 + 8), v14);
    if ( i > 0x3FFF )
      sub_402CA8();
    if ( i > 0x3FFF )
      sub_402CA8();
    sub_40BEF8(
      a4 + 4 * i,
      v16,
      *(_DWORD *)(v6 + 8),
      *(_DWORD *)(v20 + 8),
      0,
      *(_DWORD *)(v20 + 84),
      *(_DWORD *)(v20 + 80),
      a4 + 4 * i,
      v14);
    if ( *(_DWORD *)(v20 + 84) - 1 >= 0 )
    {
      v11 = *(_DWORD *)(v20 + 84);
      v12 = 0;
      do
      {
        if ( v12 + v16 > 0x3FFF )
          sub_402CA8();
        if ( v12 > 0x3FFF )
          sub_402CA8();
        *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v12) = *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * (v12 + v16));
        ++v12;
        --v11;
      }
      while ( v11 );
    }
    i += v16;
    result = v16;
  }
  return result;
}

//----- (0040CAE4) --------------------------------------------------------
void __userpurge sub_40CAE4(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<esi>, unsigned int a5, int a6)
{
  int v6; // ebx@1
  unsigned int v7; // eax@9
  int v8; // edx@11
  int v9; // eax@11
  int v10; // edx@19
  unsigned int v11; // eax@19
  int v12; // ecx@20
  int v13; // esi@28
  int v14; // [sp+0h] [bp-2Ch]@0
  unsigned int v15; // [sp+0h] [bp-2Ch]@1
  char v16; // [sp+Ch] [bp-20h]@4
  unsigned int v17; // [sp+18h] [bp-14h]@1
  unsigned int v18; // [sp+1Ch] [bp-10h]@1
  int v19; // [sp+20h] [bp-Ch]@1
  int v20; // [sp+24h] [bp-8h]@1
  int v21; // [sp+28h] [bp-4h]@1

  v20 = a3;
  v21 = a2;
  v6 = a1;
  sub_40BB9C(*(_DWORD *)(a2 + 80), *(_DWORD *)(a2 + 84), 0, *(_DWORD *)(a1 + 12), 0, *(_DWORD *)(a2 + 8), v14);
  sub_4088BD(v20, *(_DWORD *)(v6 + 8), *(_DWORD *)(v21 + 84), *(_DWORD *)(v21 + 8), v15);
  v19 = (544 - *(_DWORD *)(v21 + 84)) & 0xFFFFFFFC;
  v18 = 0;
  v17 = (4 - (a5 & 3)) & 3;
  if ( (signed int)v17 > 0 )
  {
    if ( a5 > 0x3FFF )
      sub_402CA8();
    System::Move(a6 + 4 * a5, &v16);
    a5 += v17;
  }
  while ( (signed int)a5 > 0 )
  {
    if ( (signed int)a5 <= v19 )
      a4 = a5;
    else
      a4 = v19;
    v7 = *(_DWORD *)(v21 + 84);
    if ( v7 > 0x3FFF )
      sub_402CA8();
    v8 = *(_DWORD *)(v6 + 8) + 2 * v7;
    v9 = v18 + v7;
    if ( (unsigned int)v9 > 0x3FFF )
      sub_402CA8();
    sub_4088BD(v20 + 4 * v9, v8, a4, *(_DWORD *)(v21 + 8), v15);
    if ( v18 > 0x3FFF )
      sub_402CA8();
    if ( v18 > 0x3FFF )
      sub_402CA8();
    sub_408B6B(
      a6 + 4 * v18,
      a6,
      a6 + 4 * v18,
      a4,
      *(_DWORD *)(v6 + 8),
      a6 + 4 * v18,
      *(_DWORD *)(v6 + 12),
      *(_DWORD *)(v21 + 84));
    a5 -= a4;
    if ( (signed int)a5 > 0 )
    {
      if ( *(_DWORD *)(v21 + 84) / 2 - 1 >= 0 )
      {
        v10 = *(_DWORD *)(v21 + 84) / 2;
        v11 = 0;
        do
        {
          v12 = v11 + a4 / 2;
          if ( (unsigned int)v12 > 0x3FFF )
            sub_402CA8();
          if ( v11 > 0x3FFF )
            sub_402CA8();
          *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v11++) = *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v12);
          --v10;
        }
        while ( v10 );
      }
      v18 += a4;
    }
  }
  if ( (signed int)v17 > 0 )
  {
    v13 = v18 + a4 - v17;
    if ( (unsigned int)v13 > 0x3FFF )
      sub_402CA8();
    System::Move(&v16, a6 + 4 * v13);
  }
}

//----- (0040CCB8) --------------------------------------------------------
char __userpurge sub_40CCB8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  char result; // al@2
  int v7; // [sp+0h] [bp-8h]@0

  if ( a3 >= 64 )
  {
    if ( *(_BYTE *)(*(_DWORD *)(a1 + 4) + 19) )
      sub_409459(ecx0, a4, a3 + 3, *(_DWORD *)(a2 + 8), **(_DWORD **)(a2 + 80), v7);
    else
      sub_40C928(ecx0, a4, a3, *(_DWORD *)(a2 + 8), **(_DWORD **)(a2 + 80), v7);
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040CD10) --------------------------------------------------------
char __userpurge sub_40CD10<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4, int a5)
{
  int v6; // ebx@1
  char result; // al@2
  int v8; // esi@3
  int v9; // edi@3
  int v10; // [sp+0h] [bp-14h]@0
  int v11; // [sp+Ch] [bp-8h]@1
  int v12; // [sp+10h] [bp-4h]@1

  v11 = ecx0;
  v6 = a2;
  v12 = a1;
  if ( a3 >= 256 )
  {
    v8 = *(_DWORD *)(a2 + 84) / 2;
    v9 = a3 - (*(_DWORD *)(a2 + 84) - 1);
    if ( *(_BYTE *)(a2 + 4) )
      sub_40C828(ecx0, a4, v8);
    if ( *(_BYTE *)(v6 + 5) )
    {
      if ( (unsigned int)(v9 + v8) > 0x3FFF )
        sub_402CA8();
      if ( (unsigned int)(v9 + v8) > 0x3FFF )
        sub_402CA8();
      sub_40C828(v11 + 4 * (v9 + v8), a4 + 4 * (v9 + v8), a3 - (v9 + v8));
    }
    if ( *(_BYTE *)(*(_DWORD *)(v12 + 4) + 19) )
    {
      if ( (unsigned int)v8 > 0x3FFF )
        sub_402CA8();
      sub_40CAE4(v12, v6, v11, v8, v9, a4 + 4 * v8);
    }
    else
    {
      if ( (unsigned int)v8 > 0x3FFF )
        sub_402CA8();
      sub_40C9A4(v12, v6, v11, v9, a4 + 4 * v8, v10);
    }
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040CDF8) --------------------------------------------------------
int __userpurge sub_40CDF8<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // edi@3
  char v6; // ST1F_1@3
  int v7; // ebx@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v5 = ecx0;
  v6 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 4) = v5;
  *(_DWORD *)(v7 + 8) = a3;
  *(_DWORD *)(v7 + 12) = a3 + 2176;
  if ( v6 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (0040CE50) --------------------------------------------------------
int __userpurge sub_40CE50<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebx>, __m64 a5<mm5>, signed int a6, int a7)
{
  int v7; // eax@7
  int v8; // eax@8
  int v9; // eax@9
  int v10; // eax@10
  int v12; // [sp+0h] [bp-8h]@0

  LOBYTE(a4) = 1;
  switch ( *(_DWORD *)a2 )
  {
    case 1:
      sub_40C828(a3, a7, a6);
      break;
    case 2:
      sub_40C860(a7, a3, a6);
      break;
    case 3:
      if ( *(_BYTE *)(*(_DWORD *)(a1 + 4) + 19) )
        sub_40C8F0(a3, a7, a6, a5);
      else
        sub_40C8A0(a3, a7, a6);
      break;
    case 4:
      LOBYTE(v7) = sub_40CCB8(a1, a2, a3, a6, a7, v12);
      a4 = v7;
      break;
    case 5:
      LOBYTE(v8) = sub_40CCB8(a1, a2, a7, a6, a3, v12);
      a4 = v8;
      break;
    case 6:
      LOBYTE(v9) = sub_40CD10(a1, a2, a3, a6, a7, v12);
      a4 = v9;
      break;
    case 7:
      LOBYTE(v10) = sub_40CD10(a1, a2, a7, a6, a3, v12);
      a4 = v10;
      break;
    case 0:
      return a4;
    default:
      a4 = 0;
      break;
  }
  return a4;
}

//----- (0040CF2C) --------------------------------------------------------
int __cdecl sub_40CF2C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8A4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8A4: using guessed type int dword_41A8A4;

//----- (0040CF5C) --------------------------------------------------------
void __cdecl sub_40CF5C()
{
  --dword_41A8A4;
}
// 41A8A4: using guessed type int dword_41A8A4;

//----- (0040CF64) --------------------------------------------------------
char __usercall sub_40CF64<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  int v5; // esi@1
  char result; // al@2

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_408814(a1, 1, ecx0) )
  {
    ++*(_DWORD *)v3;
    result = sub_40B3B4(v5, v4, v3);
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040CF94) --------------------------------------------------------
int __cdecl sub_40CF94()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8A8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8A8: using guessed type int dword_41A8A8;

//----- (0040CFC4) --------------------------------------------------------
void __cdecl sub_40CFC4()
{
  --dword_41A8A8;
}
// 41A8A8: using guessed type int dword_41A8A8;

//----- (0040D034) --------------------------------------------------------
int __usercall sub_40D034<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  int result; // eax@3
  int v6; // [sp+0h] [bp-Ch]@1

  v6 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408854(a1, (int)&v6) )
  {
    if ( v6 )
    {
      if ( !sub_408814(v4, 4, v3) )
        return 0;
      ++*(_DWORD *)v3;
    }
    else
    {
      result = 0;
      *(_DWORD *)v3 = 0;
    }
    LOBYTE(result) = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040D078) --------------------------------------------------------
int __userpurge sub_40D078<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, const void *a5)
{
  int v6; // edi@3
  char v7; // ST27_1@3
  int v8; // ebx@3
  int v9; // ST08_4@3
  signed int v10; // ST08_4@3
  int v11; // ST08_4@3
  signed int v13; // [sp-10h] [bp-20h]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v6 = ecx0;
  v7 = a2;
  v8 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v8 + 4) = v6;
  memcpy((void *)(v8 + 8), (const void *)a4, 0x30u);
  *(_DWORD *)(v8 + 128) = *(_DWORD *)(v8 + 16);
  *(_DWORD *)(v8 + 56) = sub_40B224((int)off_40B1C8, 1, *(_DWORD *)(v8 + 12), 2, a3, v13);
  *(_DWORD *)(v8 + 60) = sub_40B6FC((int)off_40B51C, 1, *(_DWORD *)(v8 + 12), a3, v9);
  sub_40BB50(v8 + 64, 256);
  *(_DWORD *)(v8 + 116) = sub_409664((int)off_4095DC, 1, 4336, v8 + 120, 64, v10);
  *(_DWORD *)(v8 + 92) = v8 + 64;
  *(_DWORD *)(v8 + 112) = *(_DWORD *)(v8 + 120);
  *(_DWORD *)(v8 + 208) = sub_40CDF8((int)off_40C420, 1, *(_DWORD *)(v8 + 4), *(_DWORD *)(v8 + 120), v11);
  sub_40C75C(v8 + 212);
  if ( v7 )
    System::__linkproc___AfterConstruction(v8);
  return v8;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 4095DC: using guessed type char *off_4095DC;
// 40B1C8: using guessed type char *off_40B1C8;
// 40B51C: using guessed type char *off_40B51C;
// 40C420: using guessed type char *off_40C420;

//----- (0040D15C) --------------------------------------------------------
int __cdecl sub_40D15C()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 208));
  System::TObject::Free(*(_DWORD *)(v3 + 116));
  unknown_libname_103(v3 + 64);
  System::TObject::Free(*(_DWORD *)(v3 + 60));
  System::TObject::Free(*(_DWORD *)(v3 + 56));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);
// 40BB90: using guessed type int __fastcall unknown_libname_103(_DWORD);

//----- (0040D1AC) --------------------------------------------------------
char __fastcall sub_40D1AC(int a1)
{
  int v1; // ebx@1
  int v2; // esi@3
  char v3; // al@3

  v1 = a1;
  return !*(_BYTE *)(*(_DWORD *)(a1 + 124) + 44)
      && (!(sub_408568(*(_DWORD *)(a1 + 124)) & 7)
       || (v2 = *(_DWORD *)(v1 + 124), v3 = sub_408568(*(_DWORD *)(v1 + 124)), !sub_40864C(v2, 8 - (v3 & 7))));
}

//----- (0040D1F0) --------------------------------------------------------
char __usercall sub_40D1F0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebp@1
  int v4; // ebx@1
  int v5; // esi@2
  unsigned int v6; // edi@2
  unsigned int v7; // eax@3

  v3 = a2;
  v4 = a1;
  if ( ecx0 - 1 >= 0 )
  {
    v5 = ecx0;
    v6 = 0;
    do
    {
      v7 = sub_4086E0(*(_DWORD *)(v4 + 124), *(_DWORD *)(v4 + 128));
      if ( v6 > 0x3FFF )
        sub_402CA8();
      *(_DWORD *)(v3 + 4 * v6++) = v7;
      --v5;
    }
    while ( v5 );
  }
  return *(_BYTE *)(*(_DWORD *)(v4 + 124) + 44) ^ 1;
}

//----- (0040D234) --------------------------------------------------------
int __userpurge sub_40D234<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@1
  int v6; // ebx@1
  int v7; // eax@5
  int v8; // eax@7
  unsigned int v9; // edi@17
  int v10; // ecx@19
  signed int v12; // [sp+0h] [bp-18h]@0
  int v13; // [sp+Ch] [bp-Ch]@10
  unsigned int v14; // [sp+10h] [bp-8h]@1
  int v15; // [sp+14h] [bp-4h]@1

  v15 = ecx0;
  v5 = a1;
  v6 = 0;
  *(_DWORD *)(a1 + 100) = a2;
  *(_DWORD *)(a1 + 104) = v15;
  if ( sub_408814(*(_DWORD *)(a1 + 124), 4, (int)&v14) && (signed int)v14 < 15 )
  {
    if ( v14 > 0xE )
      sub_402CA8();
    v7 = *((_DWORD *)off_4193EC + v14);
    *(_DWORD *)(v5 + 108) = v7;
    *(_DWORD *)(*(_DWORD *)(v5 + 92) + 8) = v7;
    if ( a3 > 0 && sub_408704(*(_DWORD *)(v5 + 124)) )
    {
      v8 = *(_DWORD *)(v5 + 108);
      if ( v8 > a3 )
        return 0;
      *(_DWORD *)(v5 + 100) -= 4 * v8;
      *(_DWORD *)(v5 + 104) += *(_DWORD *)(v5 + 108);
    }
    else
    {
      if ( !sub_408814(*(_DWORD *)(v5 + 124), 2, (int)&v13)
        || v13 > 2
        || !sub_40B790(*(_DWORD *)(v5 + 60), *(_DWORD *)(v5 + 124), *(_DWORD *)(v5 + 100), *(_DWORD *)(v5 + 108), v12) )
        return 0;
      sub_40B0F0(v13, *(_DWORD *)(v5 + 100), *(_DWORD *)(v5 + 108));
    }
    if ( sub_40B154(*(_DWORD *)(v5 + 124), v5 + 96) && sub_40BBF8(*(_DWORD *)(v5 + 124), *(_DWORD *)(v5 + 92)) )
    {
      sub_40BB1C(*(_DWORD *)(v5 + 92));
      v9 = *(_DWORD *)(v5 + 108);
      if ( v9 > 0x3FFF )
        sub_402CA8();
      if ( sub_40B790(
             *(_DWORD *)(v5 + 60),
             *(_DWORD *)(v5 + 124),
             *(_DWORD *)(v5 + 100) + 4 * v9,
             *(_DWORD *)(v5 + 104) - v9,
             v12) )
      {
        sub_40C39C(*(_DWORD *)(v5 + 4) + 4, v5 + 92, v10);
        LOBYTE(v6) = 1;
      }
    }
  }
  return v6;
}
// 4193EC: using guessed type void *off_4193EC;

//----- (0040D370) --------------------------------------------------------
char __userpurge sub_40D370<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // edi@1
  int v6; // esi@1
  int v7; // ebx@1
  char result; // al@3
  int v9; // [sp+0h] [bp-10h]@0
  char v10; // [sp+Ch] [bp-4h]@1

  v5 = ecx0;
  v6 = a2;
  v7 = a1;
  if ( sub_408814(*(_DWORD *)(a1 + 124), 1, (int)&v10) )
  {
    if ( v10 == 1 )
      result = sub_40D234(v7, v6, v5, a3, v9);
    else
      result = sub_40B790(*(_DWORD *)(v7 + 60), *(_DWORD *)(v7 + 124), v6, v5, v9);
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040D3C4) --------------------------------------------------------
char __userpurge sub_40D3C4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // ebx@1
  unsigned int v6; // edi@8
  int v7; // esi@12
  char result; // al@21
  int v9; // [sp+0h] [bp-20h]@0
  int v10; // [sp+Ch] [bp-14h]@8
  int v11; // [sp+10h] [bp-10h]@7
  signed int v12; // [sp+14h] [bp-Ch]@7
  int v13; // [sp+18h] [bp-8h]@1
  int v14; // [sp+18h] [bp-8h]@7
  int v15; // [sp+1Ch] [bp-4h]@1

  v13 = ecx0;
  v15 = a2;
  v5 = a1;
  if ( (unsigned __int8)sub_40D034(*(_DWORD *)(a1 + 124), a3, ecx0)
    && *(_DWORD *)a3 < *(_DWORD *)(v5 + 128)
    && sub_408834(*(_DWORD *)(v5 + 124), *(_DWORD *)(v5 + 128) - *(_DWORD *)a3, v15)
    && sub_408814(*(_DWORD *)(v5 + 124), 2, a3 + 4)
    && *(_DWORD *)(a3 + 4) <= 3
    && sub_40B4B4(*(_DWORD *)(v5 + 124), *(_DWORD *)(v5 + 56), v5 + 132) )
  {
    v14 = v13 - 1;
    v11 = 0;
    v12 = 1;
    if ( *(_DWORD *)(v5 + 132) - 1 < 0 )
    {
LABEL_23:
      result = 1;
    }
    else
    {
      v10 = *(_DWORD *)(v5 + 132);
      v6 = 0;
      while ( 1 )
      {
        if ( v6 == *(_DWORD *)(v5 + 132) - 1 )
        {
          if ( v6 > 8 )
            sub_402CA8();
          v7 = v14 - *(_DWORD *)(v5 + 8 * v6 + 140);
        }
        else
        {
          if ( v6 + 1 > 8 )
            sub_402CA8();
          if ( v6 > 8 )
            sub_402CA8();
          v7 = *(_DWORD *)(v5 + 8 * (v6 + 1) + 140) - *(_DWORD *)(v5 + 8 * v6 + 140);
        }
        if ( (unsigned int)v12 > 0x3FFF )
          sub_402CA8();
        if ( !sub_40D370(v5, v15 + 4 * v12, v7, v11, v9) )
          break;
        v11 = v7;
        v12 += v7;
        ++v6;
        --v10;
        if ( !v10 )
          goto LABEL_23;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040D500) --------------------------------------------------------
char __userpurge sub_40D500<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5)
{
  int v5; // ebx@1
  signed int v6; // esi@4
  int v7; // edi@8
  char result; // al@14
  int v9; // [sp+0h] [bp-1Ch]@0
  int v10; // [sp+0h] [bp-1Ch]@1
  int v11; // [sp+Ch] [bp-10h]@5
  int v12; // [sp+10h] [bp-Ch]@5
  int v13; // [sp+14h] [bp-8h]@1
  int v14; // [sp+18h] [bp-4h]@1

  v13 = a3;
  v14 = a2;
  v5 = a1;
  if ( sub_40D3C4(a1, a2, a5, a1 + 300, v9)
    && sub_40D3C4(v5, v13, a5, v5 + 308, v10)
    && sub_40CF64(*(_DWORD *)(v5 + 124), *(_DWORD *)(v5 + 56), v5 + 132) )
  {
    v6 = 1;
    if ( *(_DWORD *)(v5 + 132) - 1 < 0 )
    {
LABEL_16:
      result = 1;
    }
    else
    {
      v11 = *(_DWORD *)(v5 + 132);
      v12 = 0;
      while ( 1 )
      {
        if ( (unsigned int)(v12 + 1) > 8 )
          sub_402CA8();
        v7 = *(_DWORD *)(v5 + 8 * (v12 + 1) + 140) + 1;
        if ( !sub_40C7F8(*(_DWORD *)(v5 + 124), v5 + 212) )
          break;
        if ( (unsigned int)v6 > 0x3FFF )
          sub_402CA8();
        if ( (unsigned int)v6 > 0x3FFF )
          sub_402CA8();
        if ( !(unsigned __int8)sub_40CE50(*(_DWORD *)(v5 + 208), v5 + 212, v14 + 4 * v6, v5, a4, v7 - v6, v13 + 4 * v6) )
          break;
        v6 = v7;
        ++v12;
        --v11;
        if ( !v11 )
          goto LABEL_16;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040D608) --------------------------------------------------------
int __userpurge sub_40D608<eax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4)
{
  int v5; // edi@1
  int v6; // esi@1
  int result; // eax@1

  v5 = ecx0;
  v6 = a2;
  sub_40B0F0(*(_BYTE *)(a3 + 4), a2, ecx0);
  result = *(_DWORD *)a3;
  if ( *(_DWORD *)a3 > 0 )
    result = sub_40957C(v6, v5, *(_DWORD *)a3);
  return result;
}

//----- (0040D63C) --------------------------------------------------------
char __userpurge sub_40D63C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4)
{
  int v5; // edi@1
  int v6; // ebx@1
  char v7; // al@4
  int v9; // [sp+0h] [bp-14h]@0
  int v10; // [sp+0h] [bp-14h]@7
  char v11; // [sp+Fh] [bp-5h]@1

  v5 = ecx0;
  v6 = a1;
  v11 = 0;
  *(_DWORD *)(a1 + 124) = a2;
  sub_40B2E4(*(_DWORD *)(a1 + 56), a3 - 1);
  if ( a3 >= 16 )
  {
    if ( sub_40D3C4(v6, v5, a3, v6 + 300, v9) )
    {
      sub_40D608(v6, v5, a3, v6 + 300, v10);
      v11 = sub_40D1AC(v6);
    }
  }
  else
  {
    v7 = sub_40D1F0(v6, v5, a3) && sub_40D1AC(v6);
    v11 = v7;
  }
  return v11;
}

//----- (0040D6CC) --------------------------------------------------------
char __userpurge sub_40D6CC<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, signed int a5, int a6)
{
  int v6; // edi@1
  int v7; // ebx@1
  char v8; // al@5
  int v9; // ST04_4@9
  int v11; // [sp+0h] [bp-14h]@0
  char v12; // [sp+Fh] [bp-5h]@1

  v6 = a3;
  v7 = a1;
  v12 = 0;
  *(_DWORD *)(a1 + 124) = a2;
  sub_40B2E4(*(_DWORD *)(a1 + 56), a5 - 1);
  if ( a5 >= 16 )
  {
    if ( sub_40D500(v7, v6, a6, a4, a5) )
    {
      sub_40D608(v7, v6, a5, v7 + 300, v11);
      sub_40D608(v7, a6, a5, v7 + 308, v9);
      v12 = sub_40D1AC(v7);
    }
  }
  else
  {
    v8 = sub_40D1F0(v7, v6, a5) && sub_40D1F0(v7, a6, a5) && sub_40D1AC(v7);
    v12 = v8;
  }
  return v12;
}

//----- (0040D77C) --------------------------------------------------------
char __userpurge sub_40D77C<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5)
{
  int v5; // ebx@1
  int v6; // eax@1
  int v7; // eax@2
  unsigned int v8; // esi@3
  unsigned int v9; // edi@11
  unsigned int v10; // eax@20
  unsigned int v11; // eax@24
  unsigned int v12; // esi@29
  unsigned int v13; // esi@49
  int v15; // [sp-4h] [bp-E8h]@22
  int v16; // [sp+0h] [bp-E4h]@0
  int v17; // [sp+Ch] [bp-D8h]@9
  char v18; // [sp+10h] [bp-D4h]@29
  char v19[3]; // [sp+11h] [bp-D3h]@14
  int v20; // [sp+14h] [bp-D0h]@17
  char v21[184]; // [sp+18h] [bp-CCh]@20
  int v22; // [sp+D0h] [bp-14h]@3
  unsigned int v23; // [sp+D4h] [bp-10h]@41
  int v24; // [sp+D8h] [bp-Ch]@1
  char v25; // [sp+DFh] [bp-5h]@1
  int v26; // [sp+E0h] [bp-4h]@1

  v26 = a3;
  v5 = a1;
  v25 = 0;
  *(_DWORD *)(a1 + 124) = a2;
  sub_40B2E4(*(_DWORD *)(a1 + 56), a5 - 1);
  v6 = *(_DWORD *)(v5 + 20);
  v24 = *(_DWORD *)(v5 + 20);
  if ( a5 < 16 )
  {
    v7 = v6 - 1;
    if ( v7 >= 0 )
    {
      v22 = v7 + 1;
      v8 = 0;
      while ( 1 )
      {
        if ( v8 > 5 )
          sub_402CA8();
        if ( !sub_40D1F0(v5, *(_DWORD *)(v26 + 4 * v8), a5) )
          break;
        ++v8;
        --v22;
        if ( !v22 )
          return sub_40D1AC(v5);
      }
      return v25;
    }
    return sub_40D1AC(v5);
  }
  if ( !sub_40C484(*(_DWORD *)(v5 + 124), v24, (int)&v17) )
    return v25;
  if ( v17 - 1 < 0 )
  {
LABEL_48:
    if ( v24 - 1 >= 0 )
    {
      v22 = v24;
      v13 = 0;
      do
      {
        if ( v13 > 5 )
          sub_402CA8();
        if ( v13 > 5 )
          sub_402CA8();
        sub_40D608(v5, *(_DWORD *)(v26 + 4 * v13), a5, v5 + 8 * v13 + 300, v16);
        ++v13;
        --v22;
      }
      while ( v22 );
    }
    return sub_40D1AC(v5);
  }
  v22 = v17;
  v9 = 0;
  while ( 1 )
  {
    if ( v9 > 0xF )
      sub_402CA8();
    if ( v19[12 * v9] )
    {
      if ( v9 > 0xF )
        sub_402CA8();
      if ( *(&v20 + 3 * v9) == 2 )
      {
        if ( v9 > 0xF )
          sub_402CA8();
        v10 = (unsigned __int8)v21[12 * v9];
        if ( v10 > 5 )
          sub_402CA8();
        v15 = v5 + 8 * v10 + 300;
        if ( v9 > 0xF )
          sub_402CA8();
        v11 = (unsigned __int8)v21[12 * v9];
        if ( v11 > 5 )
          sub_402CA8();
        if ( !sub_40D3C4(v5, *(_DWORD *)(v26 + 4 * v11), a5, v15, v16) )
          return v25;
      }
    }
    if ( v9 > 0xF )
      sub_402CA8();
    v12 = (unsigned __int8)*(&v18 + 12 * v9);
    if ( v12 > 5 )
      sub_402CA8();
    if ( v12 > 5 )
      sub_402CA8();
    if ( !sub_40D3C4(v5, *(_DWORD *)(v26 + 4 * v12), a5, v5 + 8 * v12 + 300, v16) )
      return v25;
    if ( v9 > 0xF )
      sub_402CA8();
    if ( v19[12 * v9] )
    {
      if ( v9 > 0xF )
        sub_402CA8();
      *(_DWORD *)(v5 + 212) = sub_40C698(*(&v20 + 3 * v9));
      if ( v9 > 0xF )
        sub_402CA8();
      v23 = (unsigned __int8)v21[12 * v9];
      if ( !sub_40C768(*(_DWORD *)(v5 + 124), v5 + 212) )
        return v25;
      if ( v12 > 5 )
        sub_402CA8();
      if ( v23 > 5 )
        sub_402CA8();
      if ( !(unsigned __int8)sub_40CE50(
                               *(_DWORD *)(v5 + 208),
                               v5 + 212,
                               *(_DWORD *)(v26 + 4 * v23) + 4,
                               v5,
                               a4,
                               a5 - 1,
                               *(_DWORD *)(v26 + 4 * v12) + 4) )
        return v25;
    }
    ++v9;
    --v22;
    if ( !v22 )
      goto LABEL_48;
  }
}
// 40D77C: using guessed type char var_D3[3];
// 40D77C: using guessed type char var_CC[184];

//----- (0040D9FC) --------------------------------------------------------
int __cdecl sub_40D9FC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8AC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8AC: using guessed type int dword_41A8AC;

//----- (0040DA2C) --------------------------------------------------------
void __cdecl sub_40DA2C()
{
  --dword_41A8AC;
}
// 41A8AC: using guessed type int dword_41A8AC;

//----- (0040DBAC) --------------------------------------------------------
int __fastcall sub_40DBAC(int result, unsigned __int8 a2)
{
  unsigned __int8 v2; // cl@1

  v2 = *(_BYTE *)(result + 4);
  if ( !v2 || v2 > a2 )
    *(_BYTE *)(result + 4) = a2;
  return result;
}

//----- (0040DBF0) --------------------------------------------------------
char __cdecl sub_40DBF0()
{
  return 1;
}

//----- (0040DBF4) --------------------------------------------------------
char __fastcall sub_40DBF4(int a1)
{
  return *(_BYTE *)(a1 + 4) != 0;
}

//----- (0040DBFC) --------------------------------------------------------
char __fastcall sub_40DBFC(int a1)
{
  return (unsigned __int8)(*(_BYTE *)(a1 + 4) - 1) < 2u;
}

//----- (0040DC08) --------------------------------------------------------
int __cdecl sub_40DC08()
{
  return 0;
}

//----- (0040DC0C) --------------------------------------------------------
int __cdecl sub_40DC0C()
{
  return 0;
}

//----- (0040DC10) --------------------------------------------------------
int __cdecl sub_40DC10()
{
  return 0;
}

//----- (0040DC14) --------------------------------------------------------
char __fastcall sub_40DC14(int a1)
{
  int v1; // ebx@1
  char result; // al@1

  v1 = a1;
  result = sub_40DE2C(a1);
  *(_DWORD *)(v1 + 8) = 0;
  *(_DWORD *)(v1 + 12) = 0;
  *(_DWORD *)(v1 + 16) = 0;
  *(_DWORD *)(v1 + 20) = 0;
  return result;
}

//----- (0040DC3C) --------------------------------------------------------
char __fastcall sub_40DC3C(int a1)
{
  int v1; // ebx@1

  v1 = a1;
  if ( (unsigned __int8)(**(int (__fastcall ***)(_DWORD, _DWORD))a1)(a1, a1 + 16) )
    *(_BYTE *)(v1 + 4) = 0;
  else
    *(_BYTE *)(v1 + 4) = 1;
  return sub_40DBF4(v1) ^ 1;
}

//----- (0040DC64) --------------------------------------------------------
int __fastcall sub_40DC64(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  *(_BYTE *)(v3 + 4) = 1;
  *(_DWORD *)(v3 + 8) = 0;
  *(_DWORD *)(v3 + 12) = 0;
  *(_DWORD *)(v3 + 16) = 0;
  *(_DWORD *)(v3 + 20) = 0;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (0040DCBC) --------------------------------------------------------
int __cdecl sub_40DCBC()
{
  int v0; // eax@1
  char v1; // dl@1
  unsigned int v2; // edx@1
  unsigned int v4; // [sp-Ch] [bp-14h]@1
  int (*v5)(); // [sp-8h] [bp-10h]@1
  int (*v6)(); // [sp-4h] [bp-Ch]@1
  char v7; // [sp+3h] [bp-5h]@1
  int v8; // [sp+4h] [bp-4h]@1
  int v9; // [sp+8h] [bp+0h]@1

  v0 = System::__linkproc___BeforeDestruction();
  v7 = v1;
  v8 = v0;
  v6 = (int (*)())&v9;
  v5 = loc_40DCFF;
  v4 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v4);
  sub_40DE2C(v0);
  v2 = v4;
  __writefsdword(0, v4);
  v6 = loc_40DD06;
  LOBYTE(v2) = v7 & 0xFC;
  return System::TObject::_TObject(v8, v2);
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);
// 40DCFF: using guessed type int loc_40DCFF();
// 40DD06: using guessed type int loc_40DD06();

//----- (0040DD18) --------------------------------------------------------
char __fastcall sub_40DD18(int a1)
{
  int v1; // ebx@1
  char result; // al@2

  v1 = a1;
  if ( sub_40DBFC(a1) )
  {
    result = 0;
  }
  else
  {
    *(_BYTE *)(v1 + 4) = 0;
    result = 1;
  }
  return result;
}

//----- (0040DD34) --------------------------------------------------------
char __fastcall sub_40DD34(int a1, int a2, int a3, __int64 a4)
{
  int v4; // ebx@1
  char result; // al@2

  v4 = a1;
  if ( sub_40DBF4(a1) )
  {
    result = 0;
  }
  else
  {
    if ( __PAIR__(a4, a3) == *(_QWORD *)(v4 + 8) )
    {
      result = 1;
    }
    else
    {
      if ( (unsigned __int8)(*(int (__fastcall **)(_DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)v4 + 4))(
                              v4,
                              v4 + 8,
                              a3,
                              a4)
        && *(_QWORD *)(v4 + 8) == __PAIR__(a4, a3) )
      {
        result = 1;
      }
      else
      {
        sub_40DBAC(v4, 5u);
        result = 0;
      }
    }
  }
  return result;
}

//----- (0040DD98) --------------------------------------------------------
char __fastcall sub_40DD98(int a1, int a2, int a3, int a4)
{
  int v4; // ebx@1
  char result; // al@2
  __int64 v6; // qax@4
  unsigned __int8 v7; // cf@4
  int v8; // [sp+10h] [bp-4h]@1

  v8 = a2;
  v4 = a1;
  if ( sub_40DBF4(a1) )
  {
    result = 0;
  }
  else
  {
    if ( (unsigned __int8)(*(int (__fastcall **)(int, int, int))(*(_DWORD *)v4 + 8))(v4, v8, a3) )
    {
      v6 = *(_DWORD *)a3;
      v7 = __CFADD__((_DWORD)v6, *(_DWORD *)(v4 + 8));
      *(_DWORD *)(v4 + 8) += v6;
      *(_DWORD *)(v4 + 12) += HIDWORD(v6) + v7;
      result = 1;
    }
    else
    {
      sub_40DBAC(v4, 3u);
      result = 0;
    }
  }
  return result;
}

//----- (0040DDF0) --------------------------------------------------------
int __usercall sub_40DDF0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  int result; // eax@5
  int v6; // [sp+0h] [bp-10h]@1

  v6 = ecx0;
  v3 = ecx0;
  v4 = a1;
  if ( ecx0 && sub_40DD98(a1, a2, (int)&v6, v6) && v3 != v6 )
    sub_40DBAC(v4, 3u);
  LOBYTE(result) = sub_40DBF4(v4) ^ 1;
  return result;
}

//----- (0040DE2C) --------------------------------------------------------
char __fastcall sub_40DE2C(int a1)
{
  char result; // al@2
  unsigned int v2; // [sp-Ch] [bp-14h]@3
  int (*v3)(); // [sp-8h] [bp-10h]@3
  int *v4; // [sp-4h] [bp-Ch]@3
  int v5; // [sp+4h] [bp-4h]@1
  int v6; // [sp+8h] [bp+0h]@3

  v5 = a1;
  if ( *(_BYTE *)(a1 + 4) == 1 )
  {
    result = 0;
  }
  else
  {
    v4 = &v6;
    v3 = loc_40DE9E;
    v2 = __readfsdword(0);
    __writefsdword(0, (unsigned int)&v2);
    if ( !(unsigned __int8)(*(int (__cdecl **)(unsigned int, int (*)(), int *))(*(_DWORD *)v5 + 16))(
                             v2,
                             loc_40DE9E,
                             &v6) )
    {
      if ( (unsigned __int8)(*(int (**)(void))(*(_DWORD *)v5 + 20))() )
        sub_40DBAC(v5, 3u);
      else
        sub_40DBAC(v5, 4u);
    }
    __writefsdword(0, v2);
    result = v5;
    *(_BYTE *)(v5 + 4) = 1;
  }
  return result;
}
// 40DE9E: using guessed type int loc_40DE9E();

//----- (0040DEAC) --------------------------------------------------------
int __usercall sub_40DEAC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  DWORD v5; // ebx@1
  __int64 v6; // qax@3
  __int64 v7; // qax@4
  int v9; // [sp+8h] [bp-10h]@1

  v9 = ecx0;
  v3 = a2;
  v4 = a1;
  v5 = GetFileSize(*(HANDLE *)(a1 + 24), (LPDWORD)&v9);
  if ( v5 == -1 && GetLastError() )
  {
    sub_40DBAC(v4, 5u);
    LODWORD(v6) = 0;
  }
  else
  {
    LODWORD(v7) = unknown_libname_56(0, 1);
    v6 = v7 + v5;
    *(_QWORD *)v3 = v6;
    LOBYTE(v6) = 1;
  }
  return v6;
}
// 403DE4: using guessed type _DWORD __stdcall unknown_libname_56(_DWORD, _DWORD);

//----- (0040DF08) --------------------------------------------------------
char __fastcall sub_40DF08(int a1, int a2, int a3, LONG lDistanceToMove, LONG a5)
{
  int v5; // esi@1
  DWORD v6; // ebx@1
  char result; // al@3
  __int64 v8; // qax@4
  LONG DistanceToMoveHigh; // [sp+10h] [bp-4h]@1

  v5 = a2;
  DistanceToMoveHigh = lDistanceToMove;
  v6 = SetFilePointer(*(HANDLE *)(a1 + 24), a3, &DistanceToMoveHigh, 0);
  if ( v6 == -1 && GetLastError() )
  {
    result = 0;
  }
  else
  {
    LODWORD(v8) = unknown_libname_56(0, 1);
    *(_QWORD *)v5 = v8 + v6;
    result = 1;
  }
  return result;
}
// 403DE4: using guessed type _DWORD __stdcall unknown_libname_56(_DWORD, _DWORD);

//----- (0040DF6C) --------------------------------------------------------
char __userpurge sub_40DF6C<al>(int a1<eax>, LPVOID lpBuffer<edx>, DWORD a3<ecx>, DWORD nNumberOfBytesToRead, int a4)
{
  char result; // al@4
  DWORD NumberOfBytesRead; // [sp+Ch] [bp-4h]@3

  if ( (a3 & 0x80000000u) != 0 )
    sub_402CA8();
  if ( ReadFile(*(HANDLE *)(a1 + 24), lpBuffer, a3, &NumberOfBytesRead, 0) )
  {
    *(_DWORD *)nNumberOfBytesToRead = NumberOfBytesRead;
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040DFB0) --------------------------------------------------------
char __userpurge sub_40DFB0<al>(int a1<eax>, LPCVOID lpBuffer<edx>, DWORD a3<ecx>, DWORD nNumberOfBytesToWrite, int a4)
{
  char result; // al@4
  DWORD NumberOfBytesWritten; // [sp+Ch] [bp-4h]@3

  if ( (a3 & 0x80000000u) != 0 )
    sub_402CA8();
  if ( WriteFile_0(*(HANDLE *)(a1 + 24), lpBuffer, a3, &NumberOfBytesWritten, 0) )
  {
    *(_DWORD *)nNumberOfBytesToWrite = NumberOfBytesWritten;
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040DFF4) --------------------------------------------------------
bool __fastcall sub_40DFF4(int a1)
{
  return (unsigned int)CloseHandle(*(HANDLE *)(a1 + 24)) >= 1;
}

//----- (0040E008) --------------------------------------------------------
char __fastcall sub_40E008(int a1)
{
  char v1; // al@1

  v1 = *(_BYTE *)(a1 + 28);
  return !v1 || v1 == 2;
}

//----- (0040E01C) --------------------------------------------------------
char __fastcall sub_40E01C(int a1)
{
  return (unsigned __int8)(*(_BYTE *)(a1 + 28) - 1) < 2u;
}

//----- (0040E028) --------------------------------------------------------
char __cdecl sub_40E028()
{
  return 1;
}

//----- (0040E02C) --------------------------------------------------------
char __userpurge sub_40E02C<al>(int a1<eax>, int a2<edx>, unsigned __int8 cl0<cl>, unsigned __int8 a3, unsigned __int8 a4)
{
  unsigned __int8 v5; // ST2F_1@1
  int v6; // esi@1
  DWORD v7; // edi@2
  DWORD v8; // ebx@10
  const CHAR *v9; // eax@12
  DWORD dwDesiredAccess; // [sp+Ch] [bp-Ch]@6
  int v12; // [sp+14h] [bp-4h]@1

  v5 = cl0;
  v12 = a2;
  v6 = a1;
  sub_40DC14(a1);
  *(_BYTE *)(v6 + 28) = a3;
  if ( v5 >= 1u )
    v7 = 3;
  else
    v7 = 2;
  if ( a3 < 1u )
  {
    dwDesiredAccess = -2147483648;
  }
  else
  {
    if ( a3 == 1 )
      dwDesiredAccess = 1073741824;
    else
      dwDesiredAccess = -1073741824;
  }
  if ( a3 )
    v8 = 0;
  else
    v8 = 1;
  v9 = (const CHAR *)System::__linkproc___LStrToPChar(v12);
  *(_DWORD *)(v6 + 24) = CreateFileA(v9, dwDesiredAccess, v8, 0, v7, 0x80u, 0);
  if ( *(_DWORD *)(v6 + 24) != -1 && !sub_40DC3C(v6) )
    CloseHandle(*(HANDLE *)(v6 + 24));
  return *(_BYTE *)(v6 + 4);
}
// 403B1C: using guessed type int __fastcall System____linkproc__ LStrToPChar(_DWORD);

//----- (0040E0D4) --------------------------------------------------------
#error "40E0D7: call analysis failed (funcsize=4)"

//----- (0040E0E0) --------------------------------------------------------
char __fastcall sub_40E0E0(int a1, int a2)
{
  return (*(int (__cdecl **)(_DWORD, int))(a1 + 56))(*(_DWORD *)(a1 + 60), a2) != 0;
}

//----- (0040E0FC) --------------------------------------------------------
char __fastcall sub_40E0FC(int a1, int a2, int a3, int a4, int a5)
{
  int v5; // esi@1
  char result; // al@2

  v5 = a2;
  if ( (*(int (__cdecl **)(_DWORD, _DWORD, _DWORD))(a1 + 52))(*(_DWORD *)(a1 + 60), a3, a4) )
  {
    *(_DWORD *)v5 = a3;
    *(_DWORD *)(v5 + 4) = a4;
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040E130) --------------------------------------------------------
char __userpurge sub_40E130<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  return (*(int (__cdecl **)(_DWORD, int, int, int))(a1 + 36))(*(_DWORD *)(a1 + 60), a2, ecx0, a3) != 0;
}

//----- (0040E158) --------------------------------------------------------
char __userpurge sub_40E158<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@1
  char result; // al@2

  v5 = ecx0;
  if ( (*(int (__cdecl **)(_DWORD, int, int))(a1 + 40))(*(_DWORD *)(a1 + 60), a2, ecx0) )
  {
    *(_DWORD *)a3 = v5;
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0040E188) --------------------------------------------------------
char __fastcall sub_40E188(int a1)
{
  return *(_BYTE *)(a1 + 64);
}

//----- (0040E18C) --------------------------------------------------------
char __fastcall sub_40E18C(int a1)
{
  return *(_BYTE *)(a1 + 65);
}

//----- (0040E190) --------------------------------------------------------
char __fastcall sub_40E190(int a1)
{
  return *(_BYTE *)(a1 + 66);
}

//----- (0040E194) --------------------------------------------------------
char __usercall sub_40E194<al>(int a1<eax>, const void *a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  const void *v4; // esi@1
  int v5; // ebx@1

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  sub_40DC14(a1);
  memcpy((void *)(v5 + 24), v4, 0x24u);
  *(_DWORD *)(v5 + 60) = v3;
  *(_BYTE *)(v5 + 64) = (*(int (**)(void))(v5 + 24))() != 0;
  *(_BYTE *)(v5 + 65) = (*(int (__cdecl **)(_DWORD))(v5 + 28))(*(_DWORD *)(v5 + 60)) != 0;
  *(_BYTE *)(v5 + 66) = (*(int (__cdecl **)(_DWORD))(v5 + 32))(*(_DWORD *)(v5 + 60)) != 0;
  sub_40DC3C(v5);
  return *(_BYTE *)(v5 + 4);
}

//----- (0040E1F0) --------------------------------------------------------
int __cdecl sub_40E1F0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8B0;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8B0: using guessed type int dword_41A8B0;

//----- (0040E220) --------------------------------------------------------
void __cdecl sub_40E220()
{
  --dword_41A8B0;
}
// 41A8B0: using guessed type int dword_41A8B0;

//----- (0040E228) --------------------------------------------------------
int __cdecl sub_40E228()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8B4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8B4: using guessed type int dword_41A8B4;

//----- (0040E258) --------------------------------------------------------
void __cdecl sub_40E258()
{
  --dword_41A8B4;
}
// 41A8B4: using guessed type int dword_41A8B4;

//----- (0040E260) --------------------------------------------------------
char __fastcall sub_40E260(unsigned int a1, int a2)
{
  int v2; // ecx@1
  char v3; // cf@7
  unsigned int v4; // eax@7
  int v5; // eax@8
  char result; // al@10

  v2 = *(_DWORD *)(a2 + 8);
  if ( v2 != 8 && v2 != 16 && v2 != 24
    || *(_DWORD *)(a2 + 4) < 8000
    || *(_DWORD *)(a2 + 4) > 192000
    || *(_DWORD *)(a2 + 12) < 1 )
  {
    result = 0;
  }
  else
  {
    v3 = a1 < 1;
    v4 = a1 - 1;
    if ( v3 || (v5 = v4 - 1) == 0 )
    {
      result = *(_DWORD *)(a2 + 12) <= 2;
    }
    else
    {
      if ( v5 == 2 )
        result = *(_DWORD *)(a2 + 12) <= 6;
      else
        result = 0;
    }
  }
  return result;
}

//----- (0040E2B4) --------------------------------------------------------
int __usercall sub_40E2B4<eax>(signed int a1<eax>, int a2<edx>, int a3<ebx>, int a4<edi>, int a5<esi>)
{
  int v5; // edi@1
  unsigned int v7; // [sp-18h] [bp-1Ch]@1
  int (*v8)(); // [sp-14h] [bp-18h]@1
  int (*v9)(); // [sp-10h] [bp-14h]@1
  int v10; // [sp-Ch] [bp-10h]@1
  int v11; // [sp-8h] [bp-Ch]@1
  int v12; // [sp-4h] [bp-8h]@1
  int v13; // [sp+0h] [bp-4h]@1
  int v14; // [sp+4h] [bp+0h]@1

  v13 = 0;
  v12 = a3;
  v11 = a5;
  v10 = a4;
  v5 = a2;
  v9 = (int (*)())&v14;
  v8 = loc_40E385;
  v7 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v7);
  if ( a1 >= 0 && a1 <= 63 )
  {
    switch ( a1 )
    {
      case 0:
        System::__linkproc___LStrAsg(a2, &str_0_Integer_24_bi[1]);
        break;
      case 1:
        System::__linkproc___LStrAsg(a2, &str_1_Experimental_[1]);
        break;
      case 2:
        System::__linkproc___LStrAsg(a2, &str_2_Integer_24_bi[1]);
        break;
      case 3:
        System::__linkproc___LStrAsg(a2, &str_3_LossyWav__TAK[1]);
        break;
      case 4:
        System::__linkproc___LStrAsg(a2, &str_4_Integer_24_bi[1]);
        break;
      default:
        Sysutils::IntToStr(a1, &v13);
        System::__linkproc___LStrCat3(v5, v13, v7);
        break;
    }
  }
  else
  {
    System::__linkproc___LStrAsg(a2, &str_Invalid_codec_v[1]);
  }
  __writefsdword(0, v7);
  v9 = loc_40E38C;
  return System::__linkproc___LStrClr(&v13);
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 4037BC: using guessed type int __fastcall System____linkproc__ LStrAsg(_DWORD, _DWORD);
// 403A24: using guessed type int __fastcall System____linkproc__ LStrCat3(_DWORD, _DWORD, _DWORD);
// 4057D4: using guessed type int __fastcall Sysutils__IntToStr(_DWORD, _DWORD);
// 40E385: using guessed type int loc_40E385();
// 40E38C: using guessed type int loc_40E38C();
// 40E394: using guessed type _strings str_Invalid_codec_v[3];
// 40E3B0: using guessed type _strings str_0_Integer_24_bi[4];
// 40E3D4: using guessed type _strings str_1_Experimental_[3];
// 40E3EC: using guessed type _strings str_2_Integer_24_bi[4];
// 40E410: using guessed type _strings str_3_LossyWav__TAK[4];
// 40E434: using guessed type _strings str_4_Integer_24_bi[4];
// 40E45C: using guessed type _strings str__Unknown[2];

//----- (0040E470) --------------------------------------------------------
char __fastcall sub_40E470(unsigned int a1, int a2)
{
  unsigned int v2; // ebx@1
  unsigned int v3; // eax@2

  v2 = a1;
  return (!a1 || (v3 = a1 - 2) == 0 || v3 == 2) && sub_40E260(v2, a2);
}

//----- (0040E4A0) --------------------------------------------------------
int __cdecl sub_40E4A0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8B8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8B8: using guessed type int dword_41A8B8;

//----- (0040E4D0) --------------------------------------------------------
void __cdecl sub_40E4D0()
{
  --dword_41A8B8;
}
// 41A8B8: using guessed type int dword_41A8B8;

//----- (0040E53C) --------------------------------------------------------
int __fastcall sub_40E53C(int a1, int a2)
{
  return *(_DWORD *)(a1 + 4) + *(_DWORD *)(a1 + 28) * a2;
}

//----- (0040E548) --------------------------------------------------------
int __fastcall sub_40E548(int a1, int a2)
{
  return *(_DWORD *)(a1 + 4) + a2;
}

//----- (0040E550) --------------------------------------------------------
int __fastcall sub_40E550(int a1, int a2)
{
  return *(_DWORD *)(a1 + 4) + 4 * a2;
}

//----- (0040E55C) --------------------------------------------------------
int __fastcall sub_40E55C(int a1, int a2)
{
  return *(_DWORD *)(a1 + 4) + 8 * a2;
}

//----- (0040E568) --------------------------------------------------------
int __fastcall sub_40E568(int a1, int a2)
{
  return *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4 * a2);
}

//----- (0040E570) --------------------------------------------------------
int __usercall sub_40E570<eax>(int a1<edx>, int a2<ecx>)
{
  return System::Move(a1, a2);
}

//----- (0040E57C) --------------------------------------------------------
int __usercall sub_40E57C<eax>(int a1<edx>, int a2<ecx>)
{
  int result; // eax@1

  result = *(_BYTE *)a1;
  *(_BYTE *)a2 = result;
  return result;
}

//----- (0040E584) --------------------------------------------------------
int __usercall sub_40E584<eax>(int a1<edx>, int a2<ecx>)
{
  int result; // eax@1

  result = *(_DWORD *)a1;
  *(_DWORD *)a2 = *(_DWORD *)a1;
  return result;
}

//----- (0040E598) --------------------------------------------------------
void __usercall sub_40E598(int a1<edx>, int a2<ecx>)
{
  *(_DWORD *)a2 = a1;
}

//----- (0040E59C) --------------------------------------------------------
char __usercall sub_40E59C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int i; // edi@1
  int v4; // ebx@2
  int j; // edi@3
  char v6; // bl@4
  char v8; // [sp-4h] [bp-Ch]@1

  v8 = *(_DWORD *)(a1 + 28);
  for ( i = *(_DWORD *)(a1 + 28) >> 2; i; --i )
  {
    a1 = *(_DWORD *)a2;
    v4 = *(_DWORD *)ecx0;
    *(_DWORD *)ecx0 = *(_DWORD *)a2;
    *(_DWORD *)a2 = v4;
    a2 += 4;
    ecx0 += 4;
  }
  for ( j = v8 & 3; j; --j )
  {
    LOBYTE(a1) = *(_BYTE *)a2;
    v6 = *(_BYTE *)ecx0;
    *(_BYTE *)ecx0 = *(_BYTE *)a2;
    *(_BYTE *)a2++ = v6;
    ++ecx0;
  }
  return a1;
}

//----- (0040E5D0) --------------------------------------------------------
__int16 __usercall sub_40E5D0<ax>(int a1<edx>, int a2<ecx>)
{
  __int16 result; // ax@1

  LOBYTE(result) = *(_BYTE *)a1;
  HIBYTE(result) = *(_BYTE *)a2;
  *(_BYTE *)a2 = *(_BYTE *)a1;
  *(_BYTE *)a1 = HIBYTE(result);
  return result;
}

//----- (0040E5DC) --------------------------------------------------------
int __usercall sub_40E5DC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int result; // eax@1
  int v4; // ebx@1

  result = *(_DWORD *)a2;
  v4 = *(_DWORD *)ecx0;
  *(_DWORD *)ecx0 = *(_DWORD *)a2;
  *(_DWORD *)a2 = v4;
  return result;
}

//----- (0040E5E8) --------------------------------------------------------
int __usercall sub_40E5E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int result; // eax@1
  int v5; // ebx@1

  v3 = *(_DWORD *)ecx0;
  *(_DWORD *)ecx0 = *(_DWORD *)a2;
  *(_DWORD *)a2 = v3;
  result = *(_DWORD *)(a2 + 4);
  v5 = *(_DWORD *)(ecx0 + 4);
  *(_DWORD *)(ecx0 + 4) = result;
  *(_DWORD *)(a2 + 4) = v5;
  return result;
}

//----- (0040E600) --------------------------------------------------------
int __usercall sub_40E600<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  unsigned int v4; // [sp-Ch] [bp-20h]@3
  int (*v5)(); // [sp-8h] [bp-1Ch]@3
  int *v6; // [sp-4h] [bp-18h]@3
  int v7; // [sp+Ch] [bp-8h]@1
  int v8; // [sp+10h] [bp-4h]@1
  int v9; // [sp+14h] [bp+0h]@3

  v7 = ecx0;
  v8 = a2;
  v3 = result;
  if ( *(_DWORD *)(result + 40) )
  {
    if ( *(_BYTE *)(result + 24) )
    {
      v6 = &v9;
      v5 = loc_40E655;
      v4 = __readfsdword(0);
      __writefsdword(0, (unsigned int)&v4);
      for ( ; v7 > 0; --v7 )
      {
        (*(void (__fastcall **)(_DWORD, int))(v3 + 40))(*(_DWORD *)(v3 + 44), v8);
        v8 += 4;
      }
      result = 0;
      __writefsdword(0, v4);
    }
    else
    {
      for ( ; v7 > 0; --v7 )
      {
        (*(void (__fastcall **)(_DWORD, int))(v3 + 40))(*(_DWORD *)(v3 + 44), v8);
        result = *(_DWORD *)(v3 + 28);
        v8 += result;
      }
    }
  }
  return result;
}
// 40E655: using guessed type int loc_40E655();

//----- (0040E6A8) --------------------------------------------------------
int __usercall sub_40E6A8<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1

  v3 = ecx0;
  v4 = a2;
  v5 = result;
  if ( *(_DWORD *)(result + 48) )
  {
    if ( *(_BYTE *)(result + 24) )
    {
      if ( ecx0 > 0 )
      {
        do
        {
          (*(void (__fastcall **)(_DWORD, _DWORD))(v5 + 48))(*(_DWORD *)(v5 + 52), *(_DWORD *)v4);
          result = *(_DWORD *)(v5 + 28);
          v4 += result;
          --v3;
        }
        while ( v3 > 0 );
      }
    }
    else
    {
      if ( ecx0 > 0 )
      {
        do
        {
          (*(void (__fastcall **)(_DWORD, int))(v5 + 48))(*(_DWORD *)(v5 + 52), v4);
          result = *(_DWORD *)(v5 + 28);
          v4 += result;
          --v3;
        }
        while ( v3 > 0 );
      }
    }
  }
  return result;
}

//----- (0040E6F0) --------------------------------------------------------
int __fastcall sub_40E6F0(int a1, signed int a2)
{
  int v2; // ebx@1
  int v3; // ecx@1
  int v4; // edx@5

  v2 = *(_DWORD *)(a1 + 32);
  v3 = a2 - v2;
  if ( a2 - v2 < a2 / 4 )
    v3 = a2 / 4;
  if ( v3 < 4 )
    v3 = 4;
  v4 = v3 + v2;
  if ( v3 + v2 > *(_DWORD *)(a1 + 8) )
    v4 = *(_DWORD *)(a1 + 8);
  return v4;
}

//----- (0040E728) --------------------------------------------------------
int __fastcall sub_40E728(int result, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // eax@4

  v2 = a2;
  v3 = result;
  if ( a2 > *(_DWORD *)(result + 32) )
  {
    if ( a2 > *(_DWORD *)(result + 8) )
      System::__linkproc___Assert(&str_TtbArrayBase_Te[1], &str_D__VocComp_Win__2[1]);
    v4 = (**(int (__fastcall ***)(_DWORD, _DWORD))v3)(v3, v2);
    result = sub_40E7BC(v3, v4);
  }
  return result;
}
// 40E728: using guessed type int __fastcall sub_40E728(_DWORD, _DWORD);
// 40E760: using guessed type _strings str_D__VocComp_Win__2[6];
// 40E794: using guessed type _strings str_TtbArrayBase_Te[4];

//----- (0040E7BC) --------------------------------------------------------
int __fastcall sub_40E7BC(int result, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // eax@5

  v2 = a2;
  v3 = result;
  if ( a2 != *(_DWORD *)(result + 32) )
  {
    if ( a2 < 0 || a2 > *(_DWORD *)(result + 8) )
      System::__linkproc___Assert(&str_TtbArrayBase_Se[1], &str_D__VocComp_Win__3[1]);
    v4 = *(_DWORD *)(v3 + 32);
    if ( v2 <= v4 )
    {
      if ( v2 < *(_DWORD *)(v3 + 36) )
        sub_40E8A0(v3, v2);
      if ( v2 )
        result = System::__linkproc___ReallocMem(v3 + 4, *(_DWORD *)(v3 + 28) * v2);
      else
        result = sub_409634(v3 + 4);
    }
    else
    {
      if ( v4 )
      {
        result = System::__linkproc___ReallocMem(v3 + 4, *(_DWORD *)(v3 + 28) * v2);
      }
      else
      {
        result = System::__linkproc___GetMem(*(_DWORD *)(v3 + 28) * v2);
        *(_DWORD *)(v3 + 4) = result;
      }
    }
    *(_DWORD *)(v3 + 32) = v2;
  }
  return result;
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);
// 402524: using guessed type int __fastcall System____linkproc__ ReallocMem(_DWORD, _DWORD);
// 40E848: using guessed type _strings str_D__VocComp_Win__3[6];
// 40E87C: using guessed type _strings str_TtbArrayBase_Se[4];

//----- (0040E8A0) --------------------------------------------------------
int __fastcall sub_40E8A0(int result, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // eax@6
  int v5; // eax@7

  v2 = a2;
  v3 = result;
  if ( a2 != *(_DWORD *)(result + 36) )
  {
    if ( a2 < 0 || a2 > *(_DWORD *)(result + 8) )
      System::__linkproc___Assert(&str_TtbArrayBase_Se_0[1], &str_D__VocComp_Win__4[1]);
    if ( v2 <= *(_DWORD *)(v3 + 36) )
    {
      v5 = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), v2);
      result = sub_40E6A8(v3, v5, *(_DWORD *)(v3 + 36) - v2);
    }
    else
    {
      sub_40E728(v3, v2);
      v4 = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), *(_DWORD *)(v3 + 36));
      result = sub_40E600(v3, v4, v2 - *(_DWORD *)(v3 + 36));
    }
    *(_DWORD *)(v3 + 36) = v2;
  }
  return result;
}
// 40E728: using guessed type int __fastcall sub_40E728(_DWORD, _DWORD);
// 40E90C: using guessed type _strings str_D__VocComp_Win__4[6];
// 40E940: using guessed type _strings str_TtbArrayBase_Se_0[3];

//----- (0040E960) --------------------------------------------------------
int __fastcall sub_40E960(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int result; // eax@1

  v2 = a2;
  v3 = a1;
  sub_40E728(a1, *(_DWORD *)(a1 + 36) + 1);
  (*(void (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), *(_DWORD *)(v3 + 36));
  result = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 56))(*(_DWORD *)(v3 + 60), v2);
  ++*(_DWORD *)(v3 + 36);
  return result;
}
// 40E728: using guessed type int __fastcall sub_40E728(_DWORD, _DWORD);

//----- (0040E98C) --------------------------------------------------------
int __usercall sub_40E98C<eax>(int a1<eax>, int a2<edx>, int a3<ecx>)
{
  int v3; // ebx@1
  int result; // eax@1
  int v5; // edi@2
  int v6; // esi@2
  int v7; // eax@6
  int v8; // eax@10
  int v9; // eax@12
  int v10; // eax@12
  int v11; // eax@15
  int v12; // eax@15
  int v13; // ST04_4@16
  int v14; // [sp+0h] [bp-18h]@1
  int v15; // [sp+4h] [bp-14h]@1
  int v16; // [sp+8h] [bp-10h]@2

  v15 = a3;
  v14 = a2;
  v3 = a1;
  result = a2;
  if ( a2 < a3 )
  {
    v16 = (*(int (__fastcall **)(_DWORD, int))(v3 + 80))(*(_DWORD *)(v3 + 84), a2);
    (*(void (__fastcall **)(_DWORD, unsigned int))(v3 + 80))(*(_DWORD *)(v3 + 84), (unsigned int)(v15 + v14) >> 1);
    (*(void (__fastcall **)(_DWORD, int))(v3 + 72))(*(_DWORD *)(v3 + 76), v16);
    v5 = v14 + 1;
    v6 = v15;
    while ( v6 >= v5 )
    {
      while ( v5 <= v15 )
      {
        v7 = (*(int (__fastcall **)(_DWORD, int))(v3 + 80))(*(_DWORD *)(v3 + 84), v5);
        if ( (*(int (__fastcall **)(int, int))(v3 + 96))(v16, v7) < 0 )
          break;
        ++v5;
      }
      while ( v6 >= v14 )
      {
        v8 = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), v6);
        if ( (*(int (__fastcall **)(int, int))(v3 + 96))(v16, v8) >= 0 )
          break;
        --v6;
      }
      if ( v6 > v5 )
      {
        v9 = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), v6);
        v10 = (*(int (__cdecl **)(int))(v3 + 80))(v9);
        (*(void (__fastcall **)(_DWORD, int))(v3 + 72))(*(_DWORD *)(v3 + 76), v10);
        ++v5;
        --v6;
      }
    }
    if ( v6 != v14 )
    {
      v11 = (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 80))(*(_DWORD *)(v3 + 84), v14);
      v12 = (*(int (__cdecl **)(int))(v3 + 80))(v11);
      (*(void (__fastcall **)(_DWORD, _DWORD))(v3 + 72))(*(_DWORD *)(v3 + 76), v12);
    }
    sub_40E98C(v3, v14, v14);
    result = sub_40E98C(v3, v5, v13);
  }
  return result;
}

//----- (0040EA7C) --------------------------------------------------------
unsigned int __usercall sub_40EA7C<eax>(int a1<eax>, unsigned int a2<edx>, signed int ecx0<ecx>)
{
  int v3; // ebx@1
  unsigned int result; // eax@1
  unsigned int v5; // eax@2
  int v6; // ebp@8
  int v7; // edi@8
  unsigned int v8; // esi@8
  int v9; // [sp+0h] [bp-18h]@1
  int v10; // [sp+4h] [bp-14h]@1

  v10 = ecx0;
  v9 = a2;
  v3 = a1;
  result = a2;
  if ( (signed int)a2 < ecx0 )
  {
    v5 = (ecx0 + a2) >> 1;
    if ( v5 > 0x1FFFFFFE )
      sub_402CA8();
    if ( a2 > 0x1FFFFFFE )
      sub_402CA8();
    sub_40E5DC(v3, *(_DWORD *)(v3 + 4) + 4 * a2, *(_DWORD *)(v3 + 4) + 4 * v5);
    if ( (unsigned int)v9 > 0x1FFFFFFE )
      sub_402CA8();
    v6 = *(_DWORD *)(*(_DWORD *)(v3 + 4) + 4 * v9);
    v7 = v9 + 1;
    v8 = v10;
    if ( v10 >= v9 + 1 )
    {
      do
      {
        while ( v7 <= v10 )
        {
          if ( (unsigned int)v7 > 0x1FFFFFFE )
            sub_402CA8();
          if ( (*(int (__fastcall **)(int, _DWORD))(v3 + 96))(v6, *(_DWORD *)(*(_DWORD *)(v3 + 4) + 4 * v7)) < 0 )
            break;
          ++v7;
        }
        while ( (signed int)v8 >= v9 )
        {
          if ( v8 > 0x1FFFFFFE )
            sub_402CA8();
          if ( (*(int (__fastcall **)(int, _DWORD))(v3 + 96))(v6, *(_DWORD *)(*(_DWORD *)(v3 + 4) + 4 * v8)) >= 0 )
            break;
          --v8;
        }
        if ( (signed int)v8 > v7 )
        {
          if ( v8 > 0x1FFFFFFE )
            sub_402CA8();
          if ( (unsigned int)v7 > 0x1FFFFFFE )
            sub_402CA8();
          sub_40E5DC(v3, *(_DWORD *)(v3 + 4) + 4 * v7++, *(_DWORD *)(v3 + 4) + 4 * v8--);
        }
      }
      while ( (signed int)v8 >= v7 );
    }
    if ( v8 != v9 )
    {
      if ( (unsigned int)v9 > 0x1FFFFFFE )
        sub_402CA8();
      if ( v8 > 0x1FFFFFFE )
        sub_402CA8();
      sub_40E5DC(v3, *(_DWORD *)(v3 + 4) + 4 * v8, *(_DWORD *)(v3 + 4) + 4 * v9);
    }
    sub_40E98C(v3, v9, v8 - 1);
    result = sub_40E98C(v3, v7, v10);
  }
  return result;
}

//----- (0040EBCC) --------------------------------------------------------
char __userpurge sub_40EBCC<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4, int a5, int (__fastcall *a6)(_DWORD, _DWORD))
{
  int v7; // ebx@1
  char result; // al@2
  int v9; // eax@4
  int v10; // eax@4
  int v11; // eax@10
  int v12; // eax@10
  unsigned int v13; // [sp+8h] [bp-Ch]@4
  unsigned int v14; // [sp+Ch] [bp-8h]@1
  int v15; // [sp+10h] [bp-4h]@1

  v14 = ecx0;
  v7 = a2;
  v15 = a1;
  if ( a2 > ecx0 )
  {
    *(_DWORD *)a3 = 0;
    return 0;
  }
  if ( a2 < ecx0 )
  {
    do
    {
      v13 = (v7 + v14) >> 1;
      v9 = (*(int (__fastcall **)(_DWORD, _DWORD))(v15 + 88))(*(_DWORD *)(v15 + 92), (v7 + v14) >> 1);
      v10 = ((int (__fastcall *)(_DWORD, _DWORD))a5)(v9, a4);
      if ( v10 >= 0 )
      {
        if ( !v10 )
        {
          *(_DWORD *)a3 = v13;
          return 1;
        }
        v14 = (v7 + v14) >> 1;
      }
      else
      {
        v7 = v13 + 1;
      }
    }
    while ( v7 != v14 );
  }
  v11 = (*(int (__fastcall **)(_DWORD, _DWORD))(v15 + 88))(*(_DWORD *)(v15 + 92), v7);
  v12 = ((int (__fastcall *)(_DWORD, _DWORD))a5)(v11, a4);
  if ( v12 )
  {
    if ( v12 >= 0 )
      *(_DWORD *)a3 = v7;
    else
      *(_DWORD *)a3 = v7 + 1;
    result = 0;
  }
  else
  {
    *(_DWORD *)a3 = v7;
    result = 1;
  }
  return result;
}

//----- (0040EC6C) --------------------------------------------------------
int __fastcall sub_40EC6C(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  if ( a2 < 0 || a2 >= *(_DWORD *)(a1 + 36) )
    System::__linkproc___Assert(&str_TtbArrayBase_pu[1], &str_D__VocComp_Win__5[1]);
  return (*(int (__fastcall **)(_DWORD, _DWORD))(v3 + 88))(*(_DWORD *)(v3 + 92), v2);
}
// 40EC9C: using guessed type _strings str_D__VocComp_Win__5[6];
// 40ECD0: using guessed type _strings str_TtbArrayBase_pu[4];

//----- (0040ECF0) --------------------------------------------------------
int __userpurge sub_40ECF0<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, char a5)
{
  int v6; // edi@3
  int v7; // ebx@3
  char v9; // [sp+Fh] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v6 = ecx0;
  v9 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 28) = v6;
  *(_BYTE *)(v7 + 24) = a4;
  if ( *(_DWORD *)(v7 + 28) <= 0 || *(_BYTE *)(v7 + 24) && *(_DWORD *)(v7 + 28) != 4 )
    System::__linkproc___Assert(&str_TtbArrayBase_Cr[1], &str_D__VocComp_Win__6[1]);
  *(_DWORD *)(v7 + 8) = 0x2000000u / *(_DWORD *)(v7 + 28);
  if ( a3 < 0 || a3 > *(_DWORD *)(v7 + 8) )
    System::__linkproc___Assert(&str_TtbArrayBase_Cr_0[1], &str_D__VocComp_Win__6[1]);
  sub_40E7BC(v7, a3);
  switch ( *(_DWORD *)(v7 + 28) )
  {
    case 1:
      *(_DWORD *)(v7 + 84) = v7;
      *(_DWORD *)(v7 + 80) = sub_40E548;
      *(_DWORD *)(v7 + 60) = v7;
      *(_DWORD *)(v7 + 56) = sub_40E57C;
      *(_DWORD *)(v7 + 76) = v7;
      *(_DWORD *)(v7 + 72) = sub_40E5D0;
      break;
    case 4:
      *(_DWORD *)(v7 + 84) = v7;
      *(_DWORD *)(v7 + 80) = sub_40E550;
      *(_DWORD *)(v7 + 60) = v7;
      *(_DWORD *)(v7 + 56) = sub_40E584;
      *(_DWORD *)(v7 + 76) = v7;
      *(_DWORD *)(v7 + 72) = sub_40E5DC;
      break;
    case 8:
      *(_DWORD *)(v7 + 84) = v7;
      *(_DWORD *)(v7 + 80) = sub_40E55C;
      *(_DWORD *)(v7 + 60) = v7;
      *(_DWORD *)(v7 + 56) = unknown_libname_107;
      *(_DWORD *)(v7 + 76) = v7;
      *(_DWORD *)(v7 + 72) = sub_40E5E8;
      break;
    default:
      *(_DWORD *)(v7 + 84) = v7;
      *(_DWORD *)(v7 + 80) = sub_40E53C;
      *(_DWORD *)(v7 + 60) = v7;
      *(_DWORD *)(v7 + 56) = sub_40E570;
      *(_DWORD *)(v7 + 76) = v7;
      *(_DWORD *)(v7 + 72) = sub_40E59C;
      break;
  }
  if ( *(_BYTE *)(v7 + 24) )
  {
    *(_DWORD *)(v7 + 92) = v7;
    *(_DWORD *)(v7 + 88) = sub_40E568;
    *(_DWORD *)(v7 + 60) = v7;
    *(_DWORD *)(v7 + 56) = sub_40E598;
    *(_DWORD *)(v7 + 20) = v7;
    *(_DWORD *)(v7 + 16) = sub_40EA7C;
  }
  else
  {
    *(_DWORD *)(v7 + 88) = *(_DWORD *)(v7 + 80);
    *(_DWORD *)(v7 + 92) = *(_DWORD *)(v7 + 84);
    *(_DWORD *)(v7 + 20) = v7;
    *(_DWORD *)(v7 + 16) = sub_40E98C;
  }
  if ( v9 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40E58C: using guessed type int unknown_libname_107();
// 40EE68: using guessed type _strings str_D__VocComp_Win__6[6];
// 40EE9C: using guessed type _strings str_TtbArrayBase_Cr[4];
// 40EEC4: using guessed type _strings str_TtbArrayBase_Cr_0[4];

//----- (0040EEEC) --------------------------------------------------------
int __cdecl sub_40EEEC()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  Actnmenus::TCustomActionPopupMenu::CloseMenu(v0);
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);
// 40EF18: using guessed type int __fastcall Actnmenus__TCustomActionPopupMenu__CloseMenu(_DWORD);

//----- (0040EF3C) --------------------------------------------------------
int __cdecl sub_40EF3C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8BC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8BC: using guessed type int dword_41A8BC;

//----- (0040EF6C) --------------------------------------------------------
void __cdecl sub_40EF6C()
{
  --dword_41A8BC;
}
// 41A8BC: using guessed type int dword_41A8BC;

//----- (0040F088) --------------------------------------------------------
void __cdecl sub_40F088()
{
  --dword_41A8C0;
}
// 41A8C0: using guessed type int dword_41A8C0;

//----- (0040F214) --------------------------------------------------------
int __fastcall sub_40F214(int result)
{
  int v1; // ebx@1
  unsigned int v2; // esi@3

  v1 = result;
  if ( *(_DWORD *)(result + 4) || !*(_DWORD *)(result + 16) )
  {
    *(_DWORD *)(result + 20) = 1;
  }
  else
  {
    result = 0;
    *(_DWORD *)(v1 + 20) = 0;
    v2 = 0;
    while ( v2 <= *(_DWORD *)(v1 + 16) )
    {
      if ( v2 > 0x7FFFFFFE )
        sub_402CA8();
      result = Sysutils::StrLen(v2 + *(_DWORD *)(v1 + 28)) + 1;
      v2 += result;
      ++*(_DWORD *)(v1 + 20);
    }
  }
  return result;
}
// 405930: using guessed type int __fastcall Sysutils__StrLen(_DWORD);

//----- (0040F25C) --------------------------------------------------------
int __fastcall sub_40F25C(int a1, char a2)
{
  char v2; // bl@3
  int v3; // edi@3
  int v4; // eax@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  v4 = System::__linkproc___GetMem(1);
  *(_DWORD *)(v3 + 28) = v4;
  *(_BYTE *)v4 = 0;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (0040F2A8) --------------------------------------------------------
int __cdecl sub_40F2A8()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // eax@1
  int v5; // eax@3
  int v6; // edx@5
  int result; // eax@5

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  v4 = *(_DWORD *)(v0 + 24);
  if ( v4 )
    System::__linkproc___FreeMem(v4);
  v5 = *(_DWORD *)(v3 + 28);
  if ( v5 )
    System::__linkproc___FreeMem(v5);
  v6 = v2;
  LOBYTE(v6) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v6);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (0040F2E8) --------------------------------------------------------
int __fastcall sub_40F2E8(int result, int a2)
{
  *(_DWORD *)(result + 4) = a2;
  return result;
}

//----- (0040F2EC) --------------------------------------------------------
int __usercall sub_40F2EC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1
  int result; // eax@1

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  result = *(_DWORD *)(a1 + 12);
  if ( a2 != result )
  {
    if ( result < 0 )
      sub_402CA8();
    result = sub_409634(v5 + 24);
    *(_DWORD *)(v5 + 12) = v4;
    if ( v4 )
    {
      result = System::__linkproc___GetMem(v4);
      *(_DWORD *)(v5 + 24) = result;
    }
  }
  if ( v4 && v3 )
  {
    if ( *(_DWORD *)(v5 + 12) < 0 )
      sub_402CA8();
    result = System::Move(v3, *(_DWORD *)(v5 + 24));
  }
  return result;
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);

//----- (0040F348) --------------------------------------------------------
int __usercall sub_40F348<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1
  int v6; // eax@1
  int v7; // eax@5
  unsigned int v8; // eax@9

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  v6 = *(_DWORD *)(a1 + 16);
  if ( a2 != v6 )
  {
    if ( v6 + 1 < 0 )
      sub_402CA8();
    sub_409634(v5 + 28);
    *(_DWORD *)(v5 + 16) = v4;
    *(_DWORD *)(v5 + 28) = System::__linkproc___GetMem(v4 + 1);
  }
  v7 = *(_DWORD *)(v5 + 16);
  if ( v7 )
  {
    if ( v7 < 0 )
      sub_402CA8();
    System::Move(v3, *(_DWORD *)(v5 + 28));
  }
  v8 = *(_DWORD *)(v5 + 16);
  if ( v8 > 0x7FFFFFFE )
    sub_402CA8();
  *(_BYTE *)(*(_DWORD *)(v5 + 28) + v8) = 0;
  return sub_40F214(v5);
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);

//----- (0040F3C8) --------------------------------------------------------
char __userpurge sub_40F3C8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@2
  unsigned int v6; // ebx@2
  int v7; // eax@5
  int v8; // eax@7
  char result; // al@8
  char v10; // [sp-4h] [bp-18h]@5
  int v11; // [sp+Ch] [bp-8h]@1
  int v12; // [sp+10h] [bp-4h]@1

  v11 = ecx0;
  v12 = a2;
  if ( a3 - 1 < 0 )
  {
LABEL_10:
    result = 1;
  }
  else
  {
    v5 = a3;
    v6 = 0;
    while ( 1 )
    {
      if ( v6 > 0x7FFFFFFE )
        sub_402CA8();
      v7 = v12;
      LOBYTE(v7) = *(_BYTE *)(v12 + v6);
      v10 = System::UpCase(v7);
      if ( v6 > 0x7FFFFFFE )
        sub_402CA8();
      v8 = v11;
      LOBYTE(v8) = *(_BYTE *)(v11 + v6);
      if ( v10 != (unsigned __int8)System::UpCase(v8) )
        break;
      ++v6;
      --v5;
      if ( !v5 )
        goto LABEL_10;
    }
    result = 0;
  }
  return result;
}
// 402668: using guessed type int __fastcall System__UpCase(_DWORD);

//----- (0040F430) --------------------------------------------------------
int __fastcall sub_40F430(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3
  char v5; // [sp-10h] [bp-18h]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  sub_40ECF0(a1, 0, 4, 16, 1, v5);
  *(_DWORD *)(v3 + 52) = v3;
  *(_DWORD *)(v3 + 48) = unknown_libname_108;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40F3BC: using guessed type int unknown_libname_108();

//----- (0040F478) --------------------------------------------------------
int __fastcall sub_40F478(int a1, int a2)
{
  return sub_40EC6C(a1, a2);
}

//----- (0040F48C) --------------------------------------------------------
int __fastcall sub_40F48C(int a1, int a2)
{
  return sub_40E960(a1, a2);
}

//----- (0040F494) --------------------------------------------------------
signed int __usercall sub_40F494<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // ebp@2
  int v5; // esi@2
  int v6; // ebx@3
  signed int result; // eax@7
  int v8; // [sp+0h] [bp-18h]@1
  int v9; // [sp+4h] [bp-14h]@1

  v9 = ecx0;
  v8 = a2;
  v3 = a1;
  if ( *(_DWORD *)(a1 + 36) - 1 < 0 )
  {
LABEL_9:
    result = -1;
  }
  else
  {
    v4 = *(_DWORD *)(a1 + 36);
    v5 = 0;
    while ( 1 )
    {
      v6 = sub_40EC6C(v3, v5);
      if ( *(_DWORD *)(v6 + 12) == v9 )
      {
        if ( v9 < 0 )
          sub_402CA8();
        if ( sub_40F3C8(v3, v8, *(_DWORD *)(v6 + 24), v9, v8) )
          break;
      }
      ++v5;
      --v4;
      if ( !v4 )
        goto LABEL_9;
    }
    result = v5;
  }
  return result;
}

//----- (0040F4F8) --------------------------------------------------------
int __fastcall sub_40F4F8(int result, signed int a2)
{
  if ( a2 > *(_DWORD *)(result + 4) && a2 >= 4 )
    *(_DWORD *)(result + 4) = a2;
  if ( a2 > *(_DWORD *)(result + 8) )
    *(_DWORD *)(result + 8) = a2;
  return result;
}

//----- (0040F510) --------------------------------------------------------
char __fastcall sub_40F510(int a1)
{
  return *(_DWORD *)(a1 + 4) < 4;
}

//----- (0040F518) --------------------------------------------------------
int __fastcall sub_40F518(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v3 + 12) = sub_40F430((int)off_40F0EC, 1);
  sub_40F708(v3);
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40F0EC: using guessed type int (**off_40F0EC)();

//----- (0040F564) --------------------------------------------------------
int __cdecl sub_40F564()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 12));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (0040F594) --------------------------------------------------------
int __usercall sub_40F594<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int result; // eax@2

  switch ( a2 )
  {
    case 1:
      result = System::__linkproc___LStrAsg(ecx0, &str_Item_not_availa[1]);
      break;
    case 2:
      result = System::__linkproc___LStrAsg(ecx0, &str_Invalid_item_ty[1]);
      break;
    case 3:
      result = System::__linkproc___LStrAsg(ecx0, &str_Buffer_too_smal_0[1]);
      break;
    case 4:
      result = System::__linkproc___LStrAsg(ecx0, &str_No_tag_found_[1]);
      break;
    case 5:
      result = System::__linkproc___LStrAsg(ecx0, &str_Incompatible_ta[1]);
      break;
    case 6:
      result = System::__linkproc___LStrAsg(ecx0, &str_Invalid_tag_[1]);
      break;
    case 7:
      result = System::__linkproc___LStrAsg(ecx0, &str_Error_reading_s[1]);
      break;
    default:
      result = sub_408158(a2, ecx0);
      break;
  }
  return result;
}
// 4037BC: using guessed type int __fastcall System____linkproc__ LStrAsg(_DWORD, _DWORD);
// 40F644: using guessed type _strings str_Item_not_availa[3];
// 40F660: using guessed type _strings str_Invalid_item_ty[3];
// 40F67C: using guessed type _strings str_Buffer_too_smal_0[3];
// 40F698: using guessed type _strings str_No_tag_found_[2];
// 40F6B0: using guessed type _strings str_Incompatible_ta[3];
// 40F6CC: using guessed type _strings str_Invalid_tag_[2];
// 40F6E4: using guessed type _strings str_Error_reading_s[4];

//----- (0040F708) --------------------------------------------------------
int __fastcall sub_40F708(int a1)
{
  int v1; // ebx@1
  int result; // eax@1

  v1 = a1;
  result = Actnmenus::TCustomActionPopupMenu::CloseMenu(*(_DWORD *)(a1 + 12));
  *(_DWORD *)(v1 + 4) = 4;
  *(_BYTE *)(v1 + 40) = 1;
  return result;
}
// 40EF18: using guessed type int __fastcall Actnmenus__TCustomActionPopupMenu__CloseMenu(_DWORD);

//----- (0040F720) --------------------------------------------------------
signed int __fastcall sub_40F720(int a1)
{
  int v1; // ebx@1
  signed int result; // eax@2

  v1 = a1;
  if ( sub_40F510(a1) )
    result = *(_DWORD *)(*(_DWORD *)(v1 + 12) + 36);
  else
    result = -1;
  return result;
}

//----- (0040F73C) --------------------------------------------------------
char __fastcall sub_40F73C(int a1)
{
  return *(_BYTE *)(a1 + 40);
}

//----- (0040F740) --------------------------------------------------------
int __fastcall sub_40F740(int a1, void *a2)
{
  void *v2; // esi@1
  int v3; // ebx@1
  int result; // eax@2

  v2 = a2;
  v3 = a1;
  if ( sub_40F510(a1) )
  {
    *(_DWORD *)(v3 + 8) = 0;
    if ( v2 )
      memcpy(v2, (const void *)(v3 + 16), 0x18u);
    else
      sub_40F4F8(v3, 2048);
    result = *(_DWORD *)(v3 + 8);
  }
  else
  {
    result = *(_DWORD *)(v3 + 4);
    *(_DWORD *)(v3 + 8) = result;
  }
  return result;
}

//----- (0040F784) --------------------------------------------------------
int __usercall sub_40F784<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1
  int result; // eax@2
  int v7; // eax@6

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_40F510(a1) )
  {
    *(_DWORD *)(v5 + 8) = 0;
    if ( v4 && v3 )
    {
      v7 = Sysutils::StrLen(v4);
      *(_DWORD *)v3 = sub_40F494(*(_DWORD *)(v5 + 12), v4, v7);
      if ( *(_DWORD *)v3 < 0 )
        sub_40F4F8(v5, 1);
      else
        sub_40F4F8(v5, 0);
    }
    else
    {
      sub_40F4F8(v5, 2048);
    }
    result = *(_DWORD *)(v5 + 8);
  }
  else
  {
    result = *(_DWORD *)(v5 + 4);
    *(_DWORD *)(v5 + 8) = result;
  }
  return result;
}
// 405930: using guessed type int __fastcall Sysutils__StrLen(_DWORD);

//----- (0040F7F4) --------------------------------------------------------
int __usercall sub_40F7F4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // edi@1
  int v5; // ebx@1
  int result; // eax@2
  int v7; // eax@6

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_40F510(a1) )
  {
    *(_DWORD *)(v5 + 8) = 0;
    if ( v4 >= 0 && v4 < *(_DWORD *)(*(_DWORD *)(v5 + 12) + 36) )
    {
      v7 = sub_40F478(*(_DWORD *)(v5 + 12), v4);
      *(_DWORD *)v3 = *(_DWORD *)(v7 + 4);
      *(_DWORD *)(v3 + 4) = *(_DWORD *)(v7 + 8);
      *(_DWORD *)(v3 + 8) = *(_DWORD *)(v7 + 12);
      *(_DWORD *)(v3 + 12) = *(_DWORD *)(v7 + 16);
      *(_DWORD *)(v3 + 16) = *(_DWORD *)(v7 + 20);
    }
    else
    {
      sub_40F4F8(v5, 2048);
    }
    result = *(_DWORD *)(v5 + 8);
  }
  else
  {
    result = *(_DWORD *)(v5 + 4);
    *(_DWORD *)(v5 + 8) = result;
  }
  return result;
}

//----- (0040F860) --------------------------------------------------------
int __userpurge sub_40F860<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // edi@1
  int v7; // ebx@1
  int result; // eax@2
  int v9; // eax@8
  int v10; // edx@8
  int v11; // eax@12
  int v12; // [sp+Ch] [bp-4h]@1

  v12 = ecx0;
  v6 = a2;
  v7 = a1;
  if ( sub_40F510(a1) )
  {
    *(_DWORD *)(v7 + 8) = 0;
    if ( v6 >= 0 && v6 < *(_DWORD *)(*(_DWORD *)(v7 + 12) + 36) && v12 && a3 )
    {
      v9 = sub_40F478(*(_DWORD *)(v7 + 12), v6);
      v10 = *(_DWORD *)(v9 + 12) + 1;
      if ( v10 < 0 )
        sub_402CA8();
      *(_DWORD *)a3 = v10;
      if ( *(_DWORD *)a3 <= a4 )
      {
        System::Move(*(_DWORD *)(v9 + 24), v12);
        v11 = *(_DWORD *)a3 - 1;
        if ( (unsigned int)v11 > 0x7FFFFFFE )
          sub_402CA8();
        *(_BYTE *)(v12 + v11) = 0;
      }
      else
      {
        sub_40F4F8(v7, 3);
      }
    }
    else
    {
      sub_40F4F8(v7, 2048);
    }
    result = *(_DWORD *)(v7 + 8);
  }
  else
  {
    result = *(_DWORD *)(v7 + 4);
    *(_DWORD *)(v7 + 8) = result;
  }
  return result;
}

//----- (0040F90C) --------------------------------------------------------
int __userpurge sub_40F90C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // esi@1
  int v7; // ebx@1
  int result; // eax@2
  int v9; // eax@7
  int v10; // edx@7
  int v11; // [sp+Ch] [bp-4h]@1

  v11 = ecx0;
  v6 = a2;
  v7 = a1;
  if ( sub_40F510(a1) )
  {
    *(_DWORD *)(v7 + 8) = 0;
    if ( v6 >= 0 && v6 < *(_DWORD *)(*(_DWORD *)(v7 + 12) + 36) && a3 )
    {
      v9 = sub_40F478(*(_DWORD *)(v7 + 12), v6);
      v10 = *(_DWORD *)(v9 + 16);
      if ( v10 < 0 )
        sub_402CA8();
      *(_DWORD *)a3 = v10;
      if ( v11 )
      {
        if ( *(_DWORD *)a3 <= a4 )
          System::Move(*(_DWORD *)(v9 + 28), v11);
        else
          sub_40F4F8(v7, 3);
      }
    }
    else
    {
      sub_40F4F8(v7, 2048);
    }
    result = *(_DWORD *)(v7 + 8);
  }
  else
  {
    result = *(_DWORD *)(v7 + 4);
    *(_DWORD *)(v7 + 8) = result;
  }
  return result;
}

//----- (0040F9A0) --------------------------------------------------------
int __userpurge sub_40F9A0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, signed int a5, int a6, char a7)
{
  int v8; // esi@1
  int v9; // ebx@1
  unsigned int v10; // ebx@13
  int v11; // esi@15
  int v12; // eax@18
  int v13; // edi@18
  int v14; // edx@26
  int v15; // ST08_4@28
  int v16; // ST04_4@28
  int v17; // esi@31
  int v18; // esi@32
  int v19; // eax@38
  int v20; // eax@51
  int v21; // eax@59
  unsigned int v23; // [sp-18h] [bp-40h]@13
  int (__stdcall *v24)(int, int, int, char); // [sp-14h] [bp-3Ch]@13
  int (__stdcall *v25)(int, int, int, char); // [sp-10h] [bp-38h]@13
  unsigned int v26; // [sp-Ch] [bp-34h]@1
  int (__stdcall *v27)(int, int, int, char); // [sp-8h] [bp-30h]@1
  int (__stdcall *v28)(int, int, int, char); // [sp-4h] [bp-2Ch]@1
  int v29; // [sp+Ch] [bp-1Ch]@1
  int v30; // [sp+10h] [bp-18h]@1
  int v31; // [sp+14h] [bp-14h]@15
  int v32; // [sp+18h] [bp-10h]@1
  int v33; // [sp+1Ch] [bp-Ch]@13
  int v34; // [sp+20h] [bp-8h]@9
  int v35; // [sp+24h] [bp-4h]@1
  int v36; // [sp+28h] [bp+0h]@1

  v30 = 0;
  v29 = 0;
  v32 = 0;
  v8 = ecx0;
  v9 = a2;
  v35 = a1;
  v28 = (int (__stdcall *)(int, int, int, char))&v36;
  v27 = loc_40FCF9;
  v26 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v26);
  if ( !sub_40F510(a1) )
  {
    *(_DWORD *)(v35 + 8) = *(_DWORD *)(v35 + 4);
LABEL_65:
    __writefsdword(0, v26);
    v28 = loc_40FD00;
    System::__linkproc___LStrArrayClr(&v29, 2);
    return System::__linkproc___LStrClr(&v32);
  }
  *(_DWORD *)(v35 + 8) = 0;
  if ( v9 < 0 || v9 >= *(_DWORD *)(*(_DWORD *)(v35 + 12) + 36) || v8 < 0 && !(_BYTE)a6 || !a3 )
  {
    sub_40F4F8(v35, 2048);
    goto LABEL_65;
  }
  v34 = sub_40F478(*(_DWORD *)(v35 + 12), v9);
  if ( *(_DWORD *)(v34 + 4) )
  {
    sub_40F4F8(v35, 2);
    goto LABEL_65;
  }
  if ( v8 >= *(_DWORD *)(v34 + 20) )
  {
    sub_40F4F8(v35, 2048);
    goto LABEL_65;
  }
  v33 = System::__linkproc___GetMem(2 * (*(_DWORD *)(v34 + 16) + 1));
  v25 = (int (__stdcall *)(int, int, int, char))&v36;
  v24 = loc_40FCC9;
  v23 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v23);
  v10 = 0;
  if ( v8 >= 0 )
  {
    v17 = v8 - 1;
    if ( v17 >= 0 )
    {
      v18 = v17 + 1;
      do
      {
        if ( v10 > 0x7FFFFFFE )
          sub_402CA8();
        v10 += Sysutils::StrLen(v10 + *(_DWORD *)(v34 + 28)) + 1;
        --v18;
      }
      while ( v18 );
    }
    if ( v10 > 0x7FFFFFFE )
      sub_402CA8();
    v19 = Sysutils::StrLen(v10 + *(_DWORD *)(v34 + 28));
    if ( v19 < 0 )
      sub_402CA8();
    if ( v19 < 0 )
      sub_402CA8();
    if ( v10 > 0x7FFFFFFE )
      sub_402CA8();
    if ( v19 + 1 < 0 )
      sub_402CA8();
    System::Utf8ToUnicode(v19);
    sub_403D74(v33, (int)&v32);
  }
  else
  {
    System::__linkproc___LStrClr(&v32);
    if ( *(_DWORD *)(v34 + 20) - 1 >= 0 )
    {
      v11 = *(_DWORD *)(v34 + 20);
      v31 = 0;
      do
      {
        if ( v10 > 0x7FFFFFFE )
          sub_402CA8();
        v12 = Sysutils::StrLen(v10 + *(_DWORD *)(v34 + 28));
        v13 = v12;
        if ( v12 < 0 )
          sub_402CA8();
        if ( v12 < 0 )
          sub_402CA8();
        if ( v10 > 0x7FFFFFFE )
          sub_402CA8();
        if ( v12 + 1 < 0 )
          sub_402CA8();
        System::Utf8ToUnicode(v12);
        v10 += v13 + 1;
        if ( v31 )
        {
          v15 = v32;
          LOBYTE(v14) = a6;
          unknown_libname_51(&v30, v14);
          v16 = v30;
          sub_403D74(v33, (int)&v29);
          sub_403A98(&v32, 3, v29, v16, v15);
        }
        else
        {
          sub_403D74(v33, (int)&v32);
        }
        ++v31;
        --v11;
      }
      while ( v11 );
    }
  }
  *(_DWORD *)a3 = sub_4039D8(v32) + 1;
  if ( a5 )
  {
    if ( *(_DWORD *)a3 <= a4 )
    {
      if ( *(_DWORD *)a3 <= 1 )
      {
        *(_BYTE *)a5 = 0;
      }
      else
      {
        v21 = j_unknown_libname_55(&v32);
        if ( !v21 || *(_DWORD *)(v21 - 4) <= 0u )
          sub_402CA8();
        System::Move(v21, a5);
      }
    }
    else
    {
      sub_40F4F8(v35, 3);
      if ( a4 > 0 )
      {
        if ( a4 > 1 )
        {
          v20 = j_unknown_libname_55(&v32);
          if ( !v20 || *(_DWORD *)(v20 - 4) <= 0u )
            sub_402CA8();
          System::Move(v20, a5);
        }
        if ( (unsigned int)(a4 - 1) > 0x7FFFFFFE )
          sub_402CA8();
        *(_BYTE *)(a5 + a4 - 1) = 0;
      }
    }
  }
  __writefsdword(0, v23);
  v25 = loc_40FCD0;
  return System::__linkproc___FreeMem(v33);
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 40378C: using guessed type int __fastcall System____linkproc__ LStrArrayClr(_DWORD, _DWORD);
// 403930: using guessed type int __fastcall unknown_libname_51(_DWORD, _DWORD);
// 403A98: using guessed type int __fastcall sub_403A98(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD);
// 403B6C: using guessed type int __fastcall j_unknown_libname_55(_DWORD);
// 404578: using guessed type _DWORD __stdcall System__Utf8ToUnicode(_DWORD);
// 405930: using guessed type int __fastcall Sysutils__StrLen(_DWORD);
// 40FCC9: using guessed type int __stdcall loc_40FCC9(int, int, int, char);
// 40FCD0: using guessed type int __stdcall loc_40FCD0(int, int, int, char);
// 40FCF9: using guessed type int __stdcall loc_40FCF9(int, int, int, char);
// 40FD00: using guessed type int __stdcall loc_40FD00(int, int, int, char);

//----- (0040FD0C) --------------------------------------------------------
int __fastcall sub_40FD0C(int result, unsigned __int8 a2)
{
  if ( a2 > *(_BYTE *)(result + 4) )
    *(_BYTE *)(result + 4) = a2;
  return result;
}

//----- (0040FD18) --------------------------------------------------------
char __fastcall sub_40FD18(int a1)
{
  return *(_BYTE *)(a1 + 4) == 0;
}

//----- (0040FD20) --------------------------------------------------------
char __usercall sub_40FD20<al>(int a1<eax>, int a2<edx>, unsigned __int8 cl0<cl>)
{
  unsigned __int8 v3; // bl@1
  int v4; // esi@1
  char result; // al@2

  v3 = cl0;
  v4 = a2;
  if ( (unsigned __int8)Sysutils::CompareMem(a2, "APETAGEX@") )
  {
    if ( (*(_BYTE *)(v4 + 23) & 0x20) != 0 ^ v3 )
    {
      result = 1;
    }
    else
    {
      if ( *(_DWORD *)(v4 + 8) >= 0x7D0u && *(_DWORD *)(v4 + 16) <= 0x64u && *(_DWORD *)(v4 + 12) <= 0x1000000u )
        result = 0;
      else
        result = 2;
    }
  }
  else
  {
    result = 1;
  }
  return result;
}

//----- (0040FD70) --------------------------------------------------------
char __fastcall sub_40FD70(int a1)
{
  return *(_DWORD *)(a1 + 13) == *(_DWORD *)(a1 + 45)
      && *(_DWORD *)(a1 + 17) == *(_DWORD *)(a1 + 49)
      && *(_BYTE *)(a1 + 28) & 0x80
      && !(*(_BYTE *)(a1 + 28) & 0x40)
      && *(_BYTE *)(a1 + 60) & 0x80
      && !(*(_BYTE *)(a1 + 60) & 0x40);
}

//----- (0040FDA8) --------------------------------------------------------
char __userpurge sub_40FDA8<al>(int a1<eax>, unsigned __int8 a2<dl>, int ecx0<ecx>, int a3, __int64 a4)
{
  int v5; // esi@1
  unsigned __int8 v6; // bl@1
  int v7; // edi@1
  int v8; // eax@3
  int v9; // edx@3
  unsigned int v10; // eax@3
  unsigned __int8 v11; // sf@3
  unsigned __int8 v12; // of@3
  int v13; // edx@4
  char result; // al@7
  __int64 v15; // [sp+4h] [bp-10h]@0

  v5 = ecx0;
  v6 = a2;
  v7 = a1;
  if ( (_DWORD)a4 && (signed int)a4 < 0 )
    return 1;
  v8 = *(_DWORD *)(a1 + 72);
  v9 = *(_DWORD *)(v8 + 20);
  v10 = *(_DWORD *)(v8 + 16);
  v12 = __OFSUB__(v9, (__PAIR__(a4, a3) + 32) >> 32);
  v11 = ((v9 - ((__PAIR__(a4, a3) + 32) >> 32)) & 0x80000000u) != 0i64;
  if ( v9 == (__PAIR__(a4, a3) + 32) >> 32 )
  {
    v13 = a3 + 32;
    if ( v10 < a3 + 32 )
      return 1;
  }
  else
  {
    v13 = a3 + 32;
    if ( v11 ^ v12 )
      return 1;
  }
  LODWORD(v15) = a4;
  if ( sub_40DD34(*(_DWORD *)(v7 + 72), v13, a3, v15) && (unsigned __int8)sub_40DDF0(*(_DWORD *)(v7 + 72), v5, 32) )
    result = sub_40FD20(v7, v5, v6);
  else
    result = 4;
  return result;
}

//----- (0040FE30) --------------------------------------------------------
char __fastcall sub_40FE30(int a1, int a2, int a3, __int64 a4)
{
  int v4; // ebx@1
  int v5; // ebx@8
  int v6; // esi@9
  signed int i; // ebx@17
  int v8; // ebx@26
  int v9; // esi@31
  int v10; // edi@39
  signed __int64 v11; // qax@41
  int v12; // ecx@41
  char result; // al@42
  __int64 v14; // [sp-20h] [bp-58h]@26
  unsigned int v15; // [sp-18h] [bp-50h]@26
  int (__stdcall *v16)(__int64); // [sp-14h] [bp-4Ch]@26
  int (__stdcall *v17)(__int64); // [sp-10h] [bp-48h]@10
  unsigned int v18; // [sp-Ch] [bp-44h]@8
  int (__stdcall *v19)(__int64); // [sp-8h] [bp-40h]@8
  int (__stdcall *v20)(__int64); // [sp-4h] [bp-3Ch]@8
  int v21; // [sp+Ch] [bp-2Ch]@26
  __int64 v22; // [sp+10h] [bp-28h]@8
  int v23; // [sp+1Ch] [bp-1Ch]@8
  int v24; // [sp+20h] [bp-18h]@6
  int v25; // [sp+24h] [bp-14h]@31
  unsigned __int64 v26; // [sp+28h] [bp-10h]@1
  int v27; // [sp+30h] [bp-8h]@1
  int v28; // [sp+34h] [bp-4h]@1
  int v29; // [sp+38h] [bp+0h]@8

  v27 = a2;
  v28 = a1;
  v4 = *(_DWORD *)(a1 + 72);
  v26 = __PAIR__(a4, a3) - *(_QWORD *)(v4 + 8) + 1;
  if ( HIDWORD(v26) )
  {
    if ( SHIDWORD(v26) < 0 )
    {
LABEL_5:
      sub_40FD0C(v28, 3u);
      return sub_40FD18(v28);
    }
  }
  else
  {
    if ( (unsigned int)v26 < 8 )
      goto LABEL_5;
  }
  if ( !(unsigned __int8)sub_40DDF0(v4, (int)&v24, 8) )
  {
    sub_40FD0C(v28, 4u);
    return sub_40FD18(v28);
  }
  v26 -= 8i64;
  v23 = System::__linkproc___GetMem(256);
  v20 = (int (__stdcall *)(__int64))&v29;
  v19 = loc_4100BE;
  v18 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v18);
  v5 = *(_DWORD *)(v28 + 72);
  v22 = *(_QWORD *)(v5 + 8);
  if ( (signed __int64)v26 <= 256 )
  {
    v17 = (int (__stdcall *)(__int64))v26;
    if ( (signed int)v26 >> 31 != HIDWORD(v26) )
      sub_402CA8();
    v6 = v26;
  }
  else
  {
    v6 = 256;
  }
  if ( !v6 )
  {
    sub_40FD0C(v28, 3u);
LABEL_45:
    __writefsdword(0, v18);
    v20 = loc_4100C5;
    return System::__linkproc___FreeMem(v23);
  }
  if ( !(unsigned __int8)sub_40DDF0(v5, v23, v6) )
  {
    sub_40FD0C(v28, 4u);
    goto LABEL_45;
  }
  for ( i = 0; ; ++i )
  {
    if ( v6 > i )
    {
      if ( (unsigned int)i > 0x7FFFFFFE )
        sub_402CA8();
      if ( *(_BYTE *)(v23 + i) )
        continue;
    }
    break;
  }
  if ( i < 2 || v6 == i )
  {
    sub_40FD0C(v28, 3u);
    goto LABEL_45;
  }
  v8 = i + 1;
  v21 = System::__linkproc___GetMem(v24);
  v17 = (int (__stdcall *)(__int64))&v29;
  v16 = loc_4100A1;
  v15 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v15);
  v14 = v22 + v8;
  if ( !sub_40DD34(*(_DWORD *)(v28 + 72), (unsigned __int64)(v22 + v8) >> 32, v22 + v8, *(__int64 *)((char *)&v14 + 4)) )
    goto LABEL_49;
  if ( v24 < 0 )
    sub_402CA8();
  if ( (unsigned __int8)sub_40DDF0(*(_DWORD *)(v28 + 72), v21, v24) )
  {
    v9 = (v25 & 6u) >> 1;
    if ( v9 < 0 )
      sub_402CA8();
    if ( v9 <= 2 )
    {
      if ( v8 < 0 )
        sub_402CA8();
      if ( sub_40F494(*(_DWORD *)(*(_DWORD *)(v28 + 76) + 12), v23, v8) < 0 )
      {
        v10 = sub_40F25C((int)off_40F090, 1);
        sub_40F2E8(v10, v9);
        if ( v8 - 1 < 0 )
          sub_402CA8();
        sub_40F2EC(v10, v8 - 1, v23);
        sub_40F348(v10, v24, v21);
        sub_40F48C(*(_DWORD *)(*(_DWORD *)(v28 + 76) + 12), v10);
        v11 = *(_QWORD *)(*(_DWORD *)(v28 + 72) + 8) - 1i64;
        v12 = v27;
        *(_DWORD *)v27 = v11;
        *(_DWORD *)(v12 + 4) = HIDWORD(v11);
      }
      else
      {
        sub_40FD0C(v28, 3u);
      }
    }
    else
    {
      sub_40FD0C(v28, 3u);
    }
  }
  else
  {
LABEL_49:
    sub_40FD0C(v28, 4u);
  }
  __writefsdword(0, v15);
  v17 = loc_4100A8;
  result = v24;
  if ( v24 )
    result = System::__linkproc___FreeMem(v21);
  return result;
}
// 4024E4: using guessed type int __fastcall System____linkproc__ GetMem(_DWORD);
// 402504: using guessed type int __fastcall System____linkproc__ FreeMem(_DWORD);
// 40F090: using guessed type char *off_40F090;
// 4100A1: using guessed type int __stdcall loc_4100A1(__int64);
// 4100A8: using guessed type int __stdcall loc_4100A8(__int64);
// 4100BE: using guessed type int __stdcall loc_4100BE(__int64);
// 4100C5: using guessed type int __stdcall loc_4100C5(__int64);

//----- (004100D8) --------------------------------------------------------
char __fastcall sub_4100D8(int a1, int a2, int a3, __int64 a4, __int64 a5)
{
  int v5; // esi@1
  int v6; // ebx@1
  __int64 v8; // [sp-4h] [bp-14h]@0
  __int64 v9; // [sp-4h] [bp-14h]@1
  __int64 v10; // [sp+8h] [bp-8h]@5

  v5 = a2;
  v6 = a1;
  LODWORD(v8) = a5;
  if ( sub_40DD34(*(_DWORD *)(a1 + 72), a2, SHIDWORD(a4), v8) )
  {
    while ( v5 > 0 )
    {
      LODWORD(v9) = a4;
      if ( !sub_40FE30(v6, (int)&v10, a3, v9) )
        break;
      --v5;
    }
    if ( sub_40FD18(v6) && v10 != __PAIR__(a4, a3) )
      sub_40FD0C(v6, 3u);
  }
  else
  {
    sub_40FD0C(v6, 4u);
  }
  return sub_40FD18(v6);
}

//----- (00410150) --------------------------------------------------------
int __fastcall sub_410150(int result)
{
  switch ( *(_BYTE *)(result + 4) )
  {
    case 0:
      result = *(_DWORD *)(result + 76);
      *(_DWORD *)(result + 4) = 0;
      break;
    case 1:
      result = *(_DWORD *)(result + 76);
      *(_DWORD *)(result + 4) = 4;
      break;
    case 2:
      result = *(_DWORD *)(result + 76);
      *(_DWORD *)(result + 4) = 5;
      break;
    case 3:
      result = *(_DWORD *)(result + 76);
      *(_DWORD *)(result + 4) = 6;
      break;
    case 4:
      result = *(_DWORD *)(result + 76);
      *(_DWORD *)(result + 4) = 7;
      break;
    default:
      return result;
  }
  return result;
}

//----- (004101AC) --------------------------------------------------------
int __fastcall sub_4101AC(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  *(_BYTE *)(v3 + 4) = 1;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (004101E8) --------------------------------------------------------
// local variable allocation has failed!
int __usercall sub_4101E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  unsigned __int8 v5; // al@3
  char v6; // al@5
  char v7; // cf@5
  char v8; // al@5
  int v9; // ecx@12
  int v10; // edx@15
  int v11; // edx@18
  int result; // eax@21
  _BYTE v13[24]; // [sp-8h] [bp-20h]@3 OVERLAPPED

  v3 = a2;
  v4 = a1;
  *(_DWORD *)(a1 + 72) = a2;
  *(_DWORD *)(a1 + 76) = ecx0;
  sub_40F708(ecx0);
  *(_DWORD *)(*(_DWORD *)(v4 + 76) + 4) = 0;
  *(_BYTE *)(v4 + 4) = 0;
  if ( sub_40DBFC(v3) )
  {
    sub_40FD0C(v4, 4u);
  }
  else
  {
    *(_QWORD *)&v13[16] = *(_QWORD *)(v3 + 8);
    *(_QWORD *)&v13[8] = *(_QWORD *)(*(_DWORD *)(v4 + 72) + 16) - 32i64;
    v5 = sub_40FDA8(v4, 0, v4 + 37, *(_DWORD *)(*(_DWORD *)(v4 + 72) + 16) - 32, *(__int64 *)&v13[12]);
    sub_40FD0C(v4, v5);
    if ( sub_40FD18(v4) )
    {
      *(_BYTE *)(v4 + 69) = 1;
      if ( *(_BYTE *)(v4 + 60) & 0x80 )
      {
        *(_QWORD *)&v13[8] = *(_QWORD *)(*(_DWORD *)(v4 + 72) + 16) - 32i64 - *(_DWORD *)(v4 + 49);
        v6 = sub_40FDA8(
               v4,
               1u,
               v4 + 5,
               *(_DWORD *)(*(_DWORD *)(v4 + 72) + 16) - 32 - *(_DWORD *)(v4 + 49),
               *(__int64 *)&v13[12]);
        v7 = (unsigned __int8)v6 < 1u;
        v8 = v6 - 1;
        if ( v7 )
        {
          if ( !sub_40FD70(v4) )
            sub_40FD0C(v4, 3u);
        }
        else
        {
          if ( v8 == 3 )
            sub_40FD0C(v4, 4u);
          else
            sub_40FD0C(v4, 3u);
        }
      }
      if ( sub_40FD18(v4) )
      {
        v9 = *(_DWORD *)(v4 + 76);
        *(_DWORD *)(v9 + 16) = *(_DWORD *)(v4 + 45);
        *(_DWORD *)(v9 + 20) = *(_DWORD *)(v4 + 57);
        if ( *(_BYTE *)(v4 + 60) & 0x80 )
        {
          *(_DWORD *)(v9 + 32) = *(_DWORD *)(v4 + 49) + 32;
          *(_DWORD *)(v9 + 36) = 0;
        }
        else
        {
          *(_DWORD *)(v9 + 32) = *(_DWORD *)(v4 + 49);
          *(_DWORD *)(v9 + 36) = 0;
        }
        *(_QWORD *)(*(_DWORD *)(v4 + 76) + 24) = *(_QWORD *)(*(_DWORD *)(v4 + 72) + 16)
                                               - *(_QWORD *)(*(_DWORD *)(v4 + 76) + 32);
        *(_QWORD *)&v13[8] = *(_QWORD *)(*(_DWORD *)(v4 + 72) + 16) - *(_DWORD *)(v4 + 49);
        *(_QWORD *)v13 = *(_QWORD *)(*(_DWORD *)(v4 + 72) + 16) - 33i64;
        v10 = *(_DWORD *)(v4 + 53);
        if ( v10 < 0 )
          sub_402CA8();
        sub_4100D8(v4, v10, *(int *)v13, *(__int64 *)&v13[4], *(__int64 *)&v13[12]);
      }
    }
    if ( !sub_40DBFC(*(_DWORD *)(v4 + 72)) )
    {
      *(_DWORD *)&v13[12] = *(_DWORD *)&v13[20];
      if ( !sub_40DD34(v3, v11, *(int *)&v13[16], *(__int64 *)&v13[12]) )
        sub_40FD0C(v4, 4u);
    }
  }
  result = sub_410150(v4);
  LOBYTE(result) = *(_BYTE *)(v4 + 4);
  return result;
}
// 4101E8: variables would overlap: ST08_12/12 and ST04_8/8

//----- (004103A4) --------------------------------------------------------
int __cdecl sub_4103A4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8C4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8C4: using guessed type int dword_41A8C4;

//----- (004103D4) --------------------------------------------------------
void __cdecl sub_4103D4()
{
  --dword_41A8C4;
}
// 41A8C4: using guessed type int dword_41A8C4;

//----- (004105C0) --------------------------------------------------------
int __fastcall sub_4105C0(int a1, int a2)
{
  int v2; // edi@1
  int v3; // ebx@1
  int v4; // esi@1
  int v5; // edx@2
  int v6; // ebp@4
  __int64 v7; // qax@4
  __int64 v9; // [sp+0h] [bp-20h]@3
  __int64 v10; // [sp+8h] [bp-18h]@2

  v2 = a2;
  v3 = a1;
  v4 = *(_DWORD *)(a1 + 4);
  if ( (signed __int64)((unsigned int)*(_QWORD *)(v4 + 16) - *(_DWORD *)(v4 + 8)) >= 4
    && (unsigned __int8)sub_40DDF0(v4, (int)&v10, 4)
    && (HIDWORD(v9) = HIDWORD(v10), sub_40A824(v2, v5, v10, *(__int64 *)((char *)&v9 + 4)))
    && (v6 = *(_DWORD *)(v3 + 4), v7 = *(_QWORD *)(v6 + 8) + *(_DWORD *)(v2 + 4), v7 < *(_QWORD *)(v6 + 16)) )
    LOBYTE(v7) = 1;
  else
    LODWORD(v7) = 0;
  return v7;
}

//----- (00410640) --------------------------------------------------------
signed int __fastcall sub_410640(int a1)
{
  int v1; // esi@1
  signed int v2; // ebx@1
  int v3; // ecx@7
  int v4; // eax@8
  int v6; // [sp+8h] [bp-30h]@1
  int v7; // [sp+Ch] [bp-2Ch]@3
  char v8; // [sp+10h] [bp-28h]@6

  v1 = a1;
  v2 = 0;
  if ( (unsigned __int8)sub_4105C0(a1, (int)&v6) )
  {
    if ( v6 == 1 )
    {
      if ( v7 >= 13 )
      {
        if ( v7 <= 26 )
        {
          if ( (signed __int64)v7 <= *(_QWORD *)(*(_DWORD *)(v1 + 4) + 16) - *(_QWORD *)(*(_DWORD *)(v1 + 4) + 8) )
          {
            if ( (unsigned __int8)sub_40DDF0(*(_DWORD *)(v1 + 4), (int)&v8, v7) )
            {
              sub_4085B4(*(_DWORD *)(v1 + 8), (int)&v8, v7);
              if ( (unsigned __int8)sub_40A874(*(_DWORD *)(v1 + 8), v1 + 28, v3) )
              {
                v2 = *(_DWORD *)(v1 + 40);
                *(_DWORD *)(v1 + 140) = v2;
                v4 = *(_DWORD *)(v1 + 44);
                if ( v4 >> 31 != *(_DWORD *)(v1 + 48) )
                  sub_402CA8();
                *(_DWORD *)(v1 + 144) = sub_40A3FC(v4, v2);
                *(_DWORD *)(v1 + 20) |= 1u;
                LOBYTE(v2) = 1;
              }
            }
          }
        }
      }
    }
  }
  if ( !(_BYTE)v2 )
    *(_DWORD *)(v1 + 24) |= 1u;
  return v2;
}

//----- (00410718) --------------------------------------------------------
int __fastcall sub_410718(int a1, int a2)
{
  int v2; // edi@1
  int v3; // ebx@1
  int v4; // ecx@3
  int result; // eax@4
  int v6; // [sp+0h] [bp-14h]@1

  v2 = a2;
  v3 = a1;
  sub_4085B4(*(_DWORD *)(a1 + 8), (int)&v6, 7);
  if ( *(_DWORD *)(v2 + 4) == 7
    && *(_QWORD *)(*(_DWORD *)(v3 + 4) + 16) - *(_QWORD *)(*(_DWORD *)(v3 + 4) + 8) >= 7i64
    && (unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 4), (int)&v6, 7)
    && (result = sub_40A900(*(_DWORD *)(v3 + 8), v3 + 100, v4), (_BYTE)result) )
    LOBYTE(result) = 1;
  else
    result = 0;
  return result;
}

//----- (00410784) --------------------------------------------------------
char __fastcall sub_410784(int a1, int a2)
{
  int v2; // ebx@1
  int v4; // [sp+0h] [bp-20h]@3

  v2 = a1;
  return *(_DWORD *)(a2 + 4) == 19
      && *(_QWORD *)(*(_DWORD *)(a1 + 4) + 16) - *(_QWORD *)(*(_DWORD *)(a1 + 4) + 8) >= 19i64
      && (unsigned __int8)sub_40DDF0(*(_DWORD *)(a1 + 4), (int)&v4, 19)
      && (unsigned __int8)sub_40A97C((int)&v4, v2 + 112);
}

//----- (004107E0) --------------------------------------------------------
char __fastcall sub_4107E0(int a1, int a2)
{
  int v2; // ebx@1
  int v4; // [sp+0h] [bp-18h]@3

  v2 = a1;
  return *(_DWORD *)(a2 + 4) == 11
      && *(_QWORD *)(*(_DWORD *)(a1 + 4) + 16) - *(_QWORD *)(*(_DWORD *)(a1 + 4) + 8) >= 11i64
      && (unsigned __int8)sub_40DDF0(*(_DWORD *)(a1 + 4), (int)&v4, 11)
      && (unsigned __int8)sub_40A9B8((int)&v4, v2 + 128);
}

//----- (00410840) --------------------------------------------------------
char __fastcall sub_410840(int a1)
{
  int v1; // esi@1
  char v2; // bl@1
  int v3; // eax@12
  int v4; // ebx@30
  char result; // al@34
  _BYTE v6[12]; // [sp+8h] [bp-Ch]@0
  signed int v7; // [sp+Ch] [bp-8h]@12
  int v8; // [sp+14h] [bp+0h]@2
  int v9; // [sp+18h] [bp+4h]@3
  unsigned __int8 v10; // [sp+1Ch] [bp+8h]@4

  v1 = a1;
  v2 = 0;
  v6[8] = 0;
  while ( !v2 && !v6[8] )
  {
    if ( (unsigned __int8)sub_4105C0(v1, (int)&v8)
      && *(_QWORD *)(*(_DWORD *)(v1 + 4) + 16) - *(_QWORD *)(*(_DWORD *)(v1 + 4) + 8) > (signed __int64)v9 )
    {
      v10 = 1;
      switch ( v8 )
      {
        case 0:
          v6[8] = 1;
          break;
        case 1:
          *(_DWORD *)(v1 + 24) |= 4u;
          v2 = 1;
          break;
        case 2:
          if ( *(_BYTE *)(v1 + 20) & 2 )
          {
            *(_DWORD *)(v1 + 24) |= 4u;
            v2 = 1;
          }
          else
          {
            *(_DWORD *)(v1 + 20) |= 2u;
          }
          break;
        case 3:
          if ( *(_BYTE *)(v1 + 20) & 4 )
          {
            *(_DWORD *)(v1 + 24) |= 4u;
            v2 = 1;
          }
          else
          {
            *(_DWORD *)(v1 + 20) |= 4u;
            v3 = *(_DWORD *)(v1 + 4);
            v7 = *(_DWORD *)(v3 + 8);
            if ( v7 >> 31 != *(_DWORD *)(v3 + 12) )
              sub_402CA8();
            *(_DWORD *)(v1 + 148) = v7;
            *(_DWORD *)(v1 + 152) = v9;
          }
          break;
        case 4:
          if ( !(*(_BYTE *)(v1 + 20) & 8) && (unsigned __int8)sub_410718(v1, (int)&v8) )
          {
            *(_DWORD *)(v1 + 20) |= 8u;
            v10 = 0;
          }
          else
          {
            *(_DWORD *)(v1 + 24) |= 4u;
            v2 = 1;
          }
          break;
        case 5:
          *(_DWORD *)(v1 + 156) += v9 + 4;
          v10 = v9 > 0;
          break;
        case 6:
          if ( !(*(_BYTE *)(v1 + 20) & 0x10) && sub_410784(v1, (int)&v8) )
          {
            *(_DWORD *)(v1 + 20) |= 0x10u;
            v10 = 0;
          }
          else
          {
            *(_DWORD *)(v1 + 24) |= 4u;
            v2 = 1;
          }
          break;
        case 7:
          if ( !(*(_BYTE *)(v1 + 20) & 0x20) && sub_4107E0(v1, (int)&v8) )
          {
            *(_DWORD *)(v1 + 20) |= 0x20u;
            v10 = 0;
          }
          else
          {
            *(_DWORD *)(v1 + 24) |= 4u;
            v2 = 1;
          }
          break;
        default:
          *(_DWORD *)(v1 + 20) |= 0x40u;
          break;
      }
      if ( v10 & (unsigned __int8)(v2 ^ 1) )
      {
        v4 = *(_DWORD *)(v1 + 4);
        *(_QWORD *)v6 = *(_QWORD *)(v4 + 8) + v9;
        v2 = sub_40DD34(
               *(_DWORD *)(v1 + 4),
               (unsigned __int64)(*(_QWORD *)(v4 + 8) + v9) >> 32,
               *(_DWORD *)(v4 + 8) + v9,
               *(__int64 *)&v6[4]) ^ 1;
      }
    }
    else
    {
      *(_DWORD *)(v1 + 24) |= 4u;
      v2 = 1;
    }
  }
  result = v2 ^ 1;
  if ( v2 != 1 && !(*(_BYTE *)(v1 + 20) & 8) )
  {
    if ( !*(_DWORD *)(v1 + 28) )
    {
      *(_DWORD *)(v1 + 100) = 65536;
      *(_DWORD *)(v1 + 104) = *(_DWORD *)(v1 + 32);
      *(_DWORD *)(v1 + 108) = 0;
      *(_DWORD *)(v1 + 20) |= 8u;
    }
  }
  return result;
}

//----- (00410A44) --------------------------------------------------------
char __userpurge sub_410A44<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // ebx@1
  signed int v6; // eax@1
  int v7; // eax@4
  int v8; // eax@7
  int v9; // eax@10
  signed int v11; // [sp-4h] [bp-Ch]@4
  signed int v12; // [sp-4h] [bp-Ch]@7

  v5 = a1;
  *(_DWORD *)(a1 + 4) = a2;
  *(_DWORD *)(a1 + 8) = ecx0;
  v6 = *(_DWORD *)(a2 + 8);
  if ( v6 >> 31 != *(_DWORD *)(a2 + 12) )
    sub_402CA8();
  *(_DWORD *)(v5 + 12) = v6;
  *(_DWORD *)(v5 + 16) = v6;
  *(_DWORD *)(v5 + 20) = 0;
  *(_DWORD *)(v5 + 140) = 0;
  *(_DWORD *)(v5 + 144) = 0;
  *(_DWORD *)(v5 + 156) = 0;
  *(_DWORD *)(v5 + 24) = 0;
  if ( (unsigned __int8)sub_410640(v5) )
  {
    v7 = *(_DWORD *)(v5 + 4);
    v11 = *(_DWORD *)(v7 + 8);
    if ( v11 >> 31 != *(_DWORD *)(v7 + 12) )
      sub_402CA8();
    *(_DWORD *)(v5 + 16) = v11;
    if ( sub_410840(v5) )
    {
      v8 = *(_DWORD *)(v5 + 4);
      v12 = *(_DWORD *)(v8 + 8);
      if ( v12 >> 31 != *(_DWORD *)(v8 + 12) )
        sub_402CA8();
      *(_DWORD *)(v5 + 16) = v12;
    }
  }
  sub_40DD18(*(_DWORD *)(v5 + 4));
  v9 = *(_DWORD *)(v5 + 24);
  *(_DWORD *)a3 = v9;
  return v9 == 0;
}

//----- (00410AF8) --------------------------------------------------------
int __fastcall sub_410AF8(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // eax@3
  int v5; // ST08_4@3
  int v6; // eax@5
  int v7; // ebx@8
  int v8; // edx@8
  _BYTE v10[12]; // [sp-8h] [bp-24h]@3
  int v11; // [sp+4h] [bp-18h]@3
  char v12; // [sp+8h] [bp-14h]@4

  v2 = a2;
  v3 = a1;
  if ( *(_BYTE *)(a1 + 24) & 4 || !(*(_BYTE *)(a1 + 20) & 4) )
  {
    v7 = 0;
  }
  else
  {
    v4 = *(_DWORD *)(a1 + 4);
    v5 = *(_DWORD *)(v4 + 8);
    v11 = *(_DWORD *)(v4 + 12);
    *(_QWORD *)v10 = *(_DWORD *)(v3 + 148);
    if ( sub_40DD34(
           *(_DWORD *)(v3 + 4),
           (unsigned __int64)*(_DWORD *)(v3 + 148) >> 32,
           *(_DWORD *)(v3 + 148),
           *(__int64 *)&v10[4])
      && (unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 4), (int)&v12, 6)
      && sub_40A8CC((int)&v12, v2) )
      LOBYTE(v6) = 1;
    else
      v6 = 0;
    v7 = v6;
    if ( !sub_40DD18(*(_DWORD *)(v3 + 4))
      || (*(_DWORD *)&v10[4] = v11, !sub_40DD34(*(_DWORD *)(v3 + 4), v8, *(int *)&v10[8], *(__int64 *)&v10[4])) )
      v7 = 0;
  }
  return v7;
}

//----- (00410B8C) --------------------------------------------------------
int __fastcall sub_410B8C(int a1, int a2)
{
  int v2; // edi@1
  int v3; // esi@1
  int v4; // eax@3
  int v5; // ST08_4@3
  int v6; // ebx@7
  int v7; // ebx@8
  int v8; // eax@8
  int v9; // ebx@12
  int v10; // edx@15
  _BYTE v12[12]; // [sp-8h] [bp-34h]@3
  int v13; // [sp+4h] [bp-28h]@3
  char v14; // [sp+8h] [bp-24h]@4
  int v15; // [sp+11h] [bp-1Bh]@5
  int v16; // [sp+15h] [bp-17h]@6
  int v17; // [sp+1Ch] [bp-10h]@8

  v2 = a2;
  v3 = a1;
  if ( *(_BYTE *)(a1 + 24) & 4 || !(*(_BYTE *)(a1 + 20) & 4) )
  {
    v9 = 0;
  }
  else
  {
    v4 = *(_DWORD *)(a1 + 4);
    v5 = *(_DWORD *)(v4 + 8);
    v13 = *(_DWORD *)(v4 + 12);
    *(_QWORD *)v12 = *(_DWORD *)(v3 + 148);
    if ( sub_40DD34(
           *(_DWORD *)(v3 + 4),
           (unsigned __int64)*(_DWORD *)(v3 + 148) >> 32,
           *(_DWORD *)(v3 + 148),
           *(__int64 *)&v12[4])
      && (unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 4), (int)&v14, 6)
      && sub_40A8CC((int)&v14, (int)&v15)
      && v16 + v15 + 9 == *(_DWORD *)(v3 + 152) )
    {
      v6 = sub_409AC8((int)&v14, 6);
      if ( (unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 4), v2, v16 + v15) )
      {
        v7 = sub_409A04(v2, v16 + v15, v6);
        v17 = 0;
        v8 = sub_40DDF0(*(_DWORD *)(v3 + 4), (int)&v17, 3);
        if ( (_BYTE)v8 && v7 == v17 )
          LOBYTE(v8) = 1;
        else
          v8 = 0;
        v9 = v8;
      }
      else
      {
        v9 = 0;
      }
    }
    else
    {
      v9 = 0;
    }
    if ( !sub_40DD18(*(_DWORD *)(v3 + 4)) )
    {
      *(_DWORD *)&v12[4] = v13;
      if ( sub_40DD34(*(_DWORD *)(v3 + 4), v10, *(int *)&v12[8], *(__int64 *)&v12[4]) )
        v9 = 0;
    }
  }
  return v9;
}

//----- (00410CAC) --------------------------------------------------------
char __fastcall sub_410CAC(int a1, int a2)
{
  char result; // al@3

  if ( *(_BYTE *)(a1 + 24) & 4 || !(*(_BYTE *)(a1 + 20) & 8) )
  {
    result = 0;
  }
  else
  {
    *(_DWORD *)a2 = *(_DWORD *)(a1 + 100);
    *(_DWORD *)(a2 + 4) = *(_DWORD *)(a1 + 104);
    *(_DWORD *)(a2 + 8) = *(_DWORD *)(a1 + 108);
    result = 1;
  }
  return result;
}

//----- (00410CD0) --------------------------------------------------------
char __fastcall sub_410CD0(int a1, int a2)
{
  char result; // al@3

  if ( *(_BYTE *)(a1 + 24) & 4 || !(*(_BYTE *)(a1 + 20) & 0x10) )
  {
    result = 0;
  }
  else
  {
    *(_DWORD *)a2 = *(_DWORD *)(a1 + 112);
    *(_DWORD *)(a2 + 4) = *(_DWORD *)(a1 + 116);
    *(_DWORD *)(a2 + 8) = *(_DWORD *)(a1 + 120);
    *(_DWORD *)(a2 + 12) = *(_DWORD *)(a1 + 124);
    result = 1;
  }
  return result;
}

//----- (00410CF4) --------------------------------------------------------
int __fastcall sub_410CF4(int result, int a2)
{
  if ( a2 > *(_DWORD *)(result + 4) )
    *(_DWORD *)(result + 4) = a2;
  return result;
}

//----- (00410D00) --------------------------------------------------------
int __fastcall sub_410D00(int a1)
{
  return *(_DWORD *)(a1 + 24) - *(_DWORD *)(a1 + 20);
}

//----- (00410D0C) --------------------------------------------------------
unsigned int __fastcall sub_410D0C(int a1)
{
  int v1; // ebx@1
  unsigned int result; // eax@1

  v1 = a1;
  result = *(_DWORD *)(a1 + 20);
  if ( (signed int)result > 0 )
  {
    if ( (signed int)result < *(_DWORD *)(v1 + 24) )
    {
      if ( result > 0x7FFFFFFE )
        sub_402CA8();
      System::Move(*(_DWORD *)(v1 + 16) + result, *(_DWORD *)(v1 + 16));
    }
    *(_DWORD *)(v1 + 24) -= *(_DWORD *)(v1 + 20);
    result = 0;
    *(_DWORD *)(v1 + 20) = 0;
  }
  return result;
}

//----- (00410D48) --------------------------------------------------------
char __fastcall sub_410D48(int a1)
{
  return *(_DWORD *)(a1 + 4) == 0;
}

//----- (00410DB8) --------------------------------------------------------
int __cdecl sub_410DB8()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 12));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (00410DE8) --------------------------------------------------------
signed int __userpurge sub_410DE8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, __int64 a6)
{
  int v7; // ebx@1
  signed int result; // eax@2
  __int64 v9; // [sp-4h] [bp-8h]@0

  v7 = a1;
  *(_DWORD *)(a1 + 56) = a2;
  *(_DWORD *)(a1 + 40) = a3;
  *(_DWORD *)(a1 + 44) = a4;
  *(_DWORD *)(a1 + 60) = ecx0;
  *(_DWORD *)(a1 + 32) = 0;
  *(_DWORD *)(a1 + 20) = 0;
  *(_DWORD *)(a1 + 24) = 0;
  *(_BYTE *)(a1 + 48) = 0;
  LODWORD(v9) = a6;
  if ( sub_40DD34(*(_DWORD *)(a1 + 56), a2, a5, v9) )
  {
    *(_DWORD *)(v7 + 4) = 0;
    result = 1;
  }
  else
  {
    *(_DWORD *)(v7 + 4) = 1;
    result = 0;
  }
  return result;
}

//----- (00410E3C) --------------------------------------------------------
char __fastcall sub_410E3C(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  signed __int64 v4; // qax@5
  unsigned __int8 v5; // sf@5
  unsigned __int8 v6; // of@5
  int v7; // edx@6
  unsigned int v8; // eax@15

  v2 = a2;
  v3 = a1;
  if ( a2 < 0 )
    v2 = *(_DWORD *)(a1 + 8);
  if ( v2 > *(_DWORD *)(a1 + 8) - sub_410D00(a1) )
    v2 = *(_DWORD *)(v3 + 8) - sub_410D00(v3);
  v4 = *(_QWORD *)(v3 + 40) - *(_QWORD *)(*(_DWORD *)(v3 + 56) + 8) + 1i64;
  v6 = __OFSUB__(HIDWORD(v4), (unsigned __int64)v2 >> 32);
  v5 = ((HIDWORD(v4) - ((unsigned __int64)v2 >> 32)) & 0x80000000u) != 0i64;
  if ( HIDWORD(v4) == (unsigned __int64)v2 >> 32 )
  {
    HIDWORD(v4) = v2;
    if ( (unsigned int)v4 >= v2 )
      goto LABEL_12;
  }
  else
  {
    v7 = v2;
    if ( !(v5 ^ v6) )
      goto LABEL_12;
  }
  if ( (*(_DWORD *)(v3 + 40) - *(_DWORD *)(*(_DWORD *)(v3 + 56) + 8) + 1) >> 31 != v7 )
    sub_402CA8();
  v2 = *(_DWORD *)(v3 + 40) - *(_DWORD *)(*(_DWORD *)(v3 + 56) + 8) + 1;
LABEL_12:
  if ( v2 > 0 )
  {
    if ( v2 > *(_DWORD *)(v3 + 8) - *(_DWORD *)(v3 + 24) )
      sub_410D0C(v3);
    v8 = *(_DWORD *)(v3 + 24);
    if ( v8 > 0x7FFFFFFE )
      sub_402CA8();
    if ( !(unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 56), v8 + *(_DWORD *)(v3 + 16), v2) )
    {
      sub_410CF4(v3, 1);
      return 0;
    }
    *(_DWORD *)(v3 + 24) += v2;
  }
  return sub_410D00(v3) > 0;
}

//----- (00410F14) --------------------------------------------------------
int __fastcall sub_410F14(int a1, signed int a2)
{
  signed int v2; // esi@1
  int v3; // ebx@1
  int result; // eax@2
  signed int v5; // edi@7
  int v6; // eax@7
  int v7; // ebp@7
  unsigned int v8; // eax@7
  int v9; // ebp@10
  unsigned int v10; // eax@15
  int v11; // edx@17
  int v12; // eax@17

  v2 = a2;
  v3 = a1;
  if ( a2 < 0 || (result = sub_410D00(a1), v2 > result) )
    result = System::__linkproc___Assert(&str_Assertion_failu_1[1], &str_D__VocComp_Win__7[1]);
  if ( *(_BYTE *)(v3 + 48) && v2 > 0 )
  {
    if ( v2 <= 3 )
    {
      v5 = v2;
      v9 = *(_DWORD *)(v3 + 32) - (3 - v2);
      if ( *(_DWORD *)(v3 + 32) - (3 - v2) > 0 )
      {
        *(_DWORD *)(v3 + 52) = sub_409A04(v3 + 28, *(_DWORD *)(v3 + 32) - (3 - v2), *(_DWORD *)(v3 + 52));
        *(_DWORD *)(v3 + 32) -= v9;
        if ( *(_DWORD *)(v3 + 32) > 0 )
        {
          if ( (unsigned int)v9 > 0x7FFFFFFE )
            sub_402CA8();
          System::Move(v9 + v3 + 28, v3 + 28);
        }
      }
    }
    else
    {
      v5 = 3;
      v6 = sub_409A04(v3 + 28, *(_DWORD *)(v3 + 32), *(_DWORD *)(v3 + 52));
      v7 = v6;
      *(_DWORD *)(v3 + 52) = v6;
      v8 = *(_DWORD *)(v3 + 20);
      if ( v8 > 0x7FFFFFFE )
        sub_402CA8();
      *(_DWORD *)(v3 + 52) = sub_409A04(*(_DWORD *)(v3 + 16) + v8, v2 - 3, v7);
      *(_DWORD *)(v3 + 32) = 0;
    }
    v10 = *(_DWORD *)(v3 + 32);
    if ( v10 > 0x7FFFFFFE )
      sub_402CA8();
    v11 = v10 + v3 + 28;
    v12 = v2 + *(_DWORD *)(v3 + 20) - v5;
    if ( (unsigned int)v12 > 0x7FFFFFFE )
      sub_402CA8();
    result = System::Move(*(_DWORD *)(v3 + 16) + v12, v11);
    *(_DWORD *)(v3 + 32) += v5;
  }
  *(_DWORD *)(v3 + 20) += v2;
  return result;
}
// 411024: using guessed type _strings str_D__VocComp_Win__7[6];
// 41105C: using guessed type _strings str_Assertion_failu_1[3];

//----- (00411078) --------------------------------------------------------
int __fastcall sub_411078(int a1)
{
  unsigned int v1; // edx@1

  v1 = *(_DWORD *)(a1 + 20);
  if ( v1 > 0x7FFFFFFE )
    sub_402CA8();
  return v1 + *(_DWORD *)(a1 + 16);
}

//----- (00411090) --------------------------------------------------------
__int64 __fastcall sub_411090(int a1)
{
  return *(_QWORD *)(*(_DWORD *)(a1 + 56) + 8) - sub_410D00(a1);
}

//----- (004110C4) --------------------------------------------------------
char __fastcall sub_4110C4(int a1)
{
  int i; // ebx@1
  unsigned int v2; // eax@2
  int v3; // edx@2
  unsigned __int8 v4; // of@2
  int v5; // edx@2
  int v6; // edx@3
  int v8; // eax@12

  for ( i = a1; ; sub_410F14(i, v8 - 1) )
  {
    if ( sub_410D00(i) < 2 && (!sub_410E3C(i, -1) || sub_410D00(i) <= 2) || !sub_410D48(i) )
      return 0;
    v2 = *(_DWORD *)(i + 20);
    v3 = *(_DWORD *)(i + 24) - 2;
    v4 = __OFSUB__(v3, v2);
    v5 = v3 - v2;
    if ( !(v5 < 0 ^ v4) )
      break;
LABEL_12:
    v8 = sub_410D00(i);
  }
  v6 = v5 + 1;
  while ( 1 )
  {
    if ( v2 > 0x7FFFFFFE )
      sub_402CA8();
    if ( *(_BYTE *)(*(_DWORD *)(i + 16) + v2) == -1 )
    {
      if ( v2 + 1 > 0x7FFFFFFE )
        sub_402CA8();
      if ( *(_BYTE *)(*(_DWORD *)(i + 16) + v2 + 1) == -96 )
        break;
    }
    ++v2;
    --v6;
    if ( !v6 )
      goto LABEL_12;
  }
  sub_410F14(i, v2 - *(_DWORD *)(i + 20));
  return 1;
}

//----- (00411168) --------------------------------------------------------
char __userpurge sub_411168<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // esi@1
  int v6; // edi@1
  int i; // ebx@1
  int v8; // ST00_4@2
  int v9; // eax@2
  int v10; // ecx@2
  int v12; // eax@7

  v5 = ecx0;
  v6 = a2;
  for ( i = a1; sub_4110C4(i); sub_410F14(i, 1) )
  {
    if ( sub_410D00(i) < 37 )
    {
      v12 = sub_410D00(i);
      if ( !sub_410E3C(i, 37 - v12) )
        break;
    }
    v8 = sub_410D00(i);
    v9 = sub_411078(i);
    sub_4085B4(*(_DWORD *)(i + 60), v9, v8);
    if ( sub_40A760(*(_DWORD *)(i + 60), v5, v10) )
    {
      *(_DWORD *)a3 = sub_408580(*(_DWORD *)(i + 60));
      *(_QWORD *)v6 = sub_411090(i);
      return 1;
    }
  }
  return 0;
}

//----- (00411204) --------------------------------------------------------
int __fastcall sub_411204(int result)
{
  *(_DWORD *)(result + 32) = 0;
  *(_DWORD *)(result + 52) = 11994318;
  *(_BYTE *)(result + 48) = 1;
  return result;
}

//----- (00411218) --------------------------------------------------------
int __fastcall sub_411218(int result)
{
  *(_BYTE *)(result + 48) = 0;
  return result;
}

//----- (00411220) --------------------------------------------------------
char __fastcall sub_411220(int a1)
{
  int v1; // edx@2

  return *(_DWORD *)(a1 + 32) == 3 && (v1 = *(_DWORD *)(a1 + 28), (v1 & 0xFFFFFF) == *(_DWORD *)(a1 + 52));
}

//----- (0041123C) --------------------------------------------------------
int __fastcall sub_41123C(int result, int a2)
{
  *(_DWORD *)(result + 8) |= a2;
  return result;
}

//----- (00411240) --------------------------------------------------------
int __fastcall sub_411240(int result)
{
  int v1; // ebx@1
  unsigned int v2; // [sp-Ch] [bp-14h]@2
  int (*v3)(); // [sp-8h] [bp-10h]@2
  int (*v4)(); // [sp-4h] [bp-Ch]@2
  int v5; // [sp+4h] [bp-4h]@2
  int v6; // [sp+8h] [bp+0h]@2

  v1 = result;
  if ( !*(_BYTE *)(result + 272) )
  {
    v5 = sub_4101AC((int)off_40F1B4, 1);
    v4 = (int (*)())&v6;
    v3 = loc_4112A6;
    v2 = __readfsdword(0);
    __writefsdword(0, (unsigned int)&v2);
    if ( (unsigned __int8)sub_4101E8(v5, *(_DWORD *)(v1 + 12), *(_DWORD *)(v1 + 268)) == 4 )
      *(_DWORD *)(v1 + 4) = 1;
    *(_BYTE *)(v1 + 272) = 1;
    __writefsdword(0, v2);
    v4 = loc_4112AD;
    result = System::TObject::Free(v5);
  }
  return result;
}
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 40F1B4: using guessed type char *off_40F1B4;
// 4112A6: using guessed type int loc_4112A6();
// 4112AD: using guessed type int loc_4112AD();

//----- (004112B4) --------------------------------------------------------
char __fastcall sub_4112B4(int a1, int a2)
{
  int v2; // edi@1
  int v3; // ebx@1
  int v4; // esi@1
  int v5; // edx@2
  int v6; // ecx@6
  signed int v8; // [sp+4h] [bp-38h]@2
  int v9; // [sp+8h] [bp-34h]@5

  v2 = a2;
  v3 = a1;
  v4 = 37;
  if ( sub_411568(a1) < 37 )
  {
    v8 = sub_411568(v3);
    if ( v8 >> 31 != v5 )
      sub_402CA8();
    v4 = v8;
  }
  sub_4085B4(*(_DWORD *)(v3 + 16), (int)&v9, v4);
  return v4 >= 8
      && (unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 12), (int)&v9, v4)
      && sub_40A760(*(_DWORD *)(v3 + 16), v2, v6);
}

//----- (00411338) --------------------------------------------------------
char __userpurge sub_411338<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, __int64 a5, int a6, int a7)
{
  char v8; // bl@1
  int v9; // esi@1
  char result; // al@8
  int v11; // [sp-10h] [bp-2Ch]@1
  unsigned __int32 v12; // [sp-Ch] [bp-28h]@1
  int (__stdcall *v13)(int, __int64, int, int); // [sp-8h] [bp-24h]@1
  int (__stdcall *v14)(int, __int64, int, int); // [sp-4h] [bp-20h]@1
  char v15; // [sp+Ch] [bp-10h]@7
  int v16; // [sp+10h] [bp-Ch]@1
  char v17; // [sp+17h] [bp-5h]@2
  int v18; // [sp+18h] [bp-4h]@1
  int v19; // [sp+1Ch] [bp+0h]@1

  v18 = ecx0;
  v8 = a2;
  v9 = a1;
  LOBYTE(a2) = 1;
  v16 = unknown_libname_109(off_41043C, a2);
  v14 = (int (__stdcall *)(int, __int64, int, int))&v19;
  v13 = loc_4113F7;
  v12 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v12);
  v11 = a6;
  if ( (unsigned __int8)sub_410DE8(
                          v16,
                          *(_DWORD *)(v9 + 12),
                          *(_DWORD *)(v9 + 16),
                          a4,
                          a5,
                          SHIDWORD(a5),
                          *(__int64 *)&v11) )
  {
    while ( sub_411168(v16, v18, a3, (int)&v15, v12) )
    {
      if ( !v8 || *(_BYTE *)(a3 + 1) )
      {
        v17 = 1;
        System::__linkproc___TryFinallyExit(v12, v13, v14);
        goto LABEL_9;
      }
      sub_410F14(v16, 1);
    }
    sub_40DD18(*(_DWORD *)(v9 + 12));
    v17 = 0;
    __writefsdword(0, v12);
    v14 = loc_4113FE;
    result = System::TObject::Free(v16);
  }
  else
  {
    sub_40DD18(*(_DWORD *)(v9 + 12));
    v17 = 0;
    System::__linkproc___TryFinallyExit(v12, v13, v14);
LABEL_9:
    result = v17;
  }
  return result;
}
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 4031CC: using guessed type _DWORD __stdcall System____linkproc__ TryFinallyExit(_DWORD, _DWORD, _DWORD);
// 41043C: using guessed type char *off_41043C;
// 4113F7: using guessed type int __stdcall loc_4113F7(int, __int64, int, int);
// 4113FE: using guessed type int __stdcall loc_4113FE(int, __int64, int, int);

//----- (0041140C) --------------------------------------------------------
char __userpurge sub_41140C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, __int64 a5)
{
  int v7; // [sp+0h] [bp-10h]@0
  unsigned __int64 v8; // [sp+8h] [bp-8h]@1

  v8 = __PAIR__(a5, a4) + 5242879;
  if ( *(_QWORD *)(*(_DWORD *)(a1 + 12) + 16) <= (signed __int64)(__PAIR__(a5, a4) + 5242879) )
    v8 = *(_QWORD *)(*(_DWORD *)(a1 + 12) + 16) - 1i64;
  return sub_411338(a1, a2, ecx0, a3, v8, __PAIR__(a4, HIDWORD(v8)), a5, v7);
}

//----- (00411484) --------------------------------------------------------
// local variable allocation has failed!
char __fastcall sub_411484(int a1, void *a2, int a3, __int64 a4)
{
  void *v4; // edi@1
  int v5; // esi@1
  char v6; // bl@3
  int v7; // ST0C_4@7 OVERLAPPED
  signed __int64 v8; // qax@7
  signed __int64 v9; // ST04_8@7 OVERLAPPED
  int v11; // [sp+0h] [bp-80h]@0
  char v12; // [sp+Ch] [bp-74h]@4
  __int64 v13; // [sp+68h] [bp-18h]@4
  char v14; // [sp+77h] [bp-9h]@3
  __int64 v15; // [sp+78h] [bp-8h]@1

  v4 = a2;
  v5 = a1;
  v15 = *(_QWORD *)(*(_DWORD *)(a1 + 12) + 16) - 2097152i64;
  if ( v15 < (signed __int64)__PAIR__(a4, a3) )
    v15 = __PAIR__(a4, a3);
  v14 = 0;
  v6 = 0;
  while ( !v6 )
  {
    if ( *(_QWORD *)(*(_DWORD *)(v5 + 12) + 16) <= v15 )
      break;
    v7 = v15;
    v8 = *(_QWORD *)(*(_DWORD *)(v5 + 12) + 16) - 1i64;
    v9 = *(_QWORD *)(*(_DWORD *)(v5 + 12) + 16) - 1i64;
    BYTE4(v8) = 1;
    if ( !sub_411338(
            v5,
            SHIDWORD(v8),
            (int)&v13,
            (int)&v12,
            *(_DWORD *)(*(_DWORD *)(v5 + 12) + 16) - 1,
            *(__int64 *)(&v7 - 1),
            SHIDWORD(v15),
            v11) )
      break;
    v6 = v12;
    memcpy(v4, &v12, 0x5Cu);
    v15 = v13 + 1;
    v14 = 1;
  }
  return v14 && !sub_40DBF4(*(_DWORD *)(v5 + 12));
}
// 411484: failed to expand linear variable ST0C_4_7

//----- (00411560) --------------------------------------------------------
char __fastcall sub_411560(int a1)
{
  return *(_DWORD *)(a1 + 4) == 0;
}

//----- (00411568) --------------------------------------------------------
__int64 __fastcall sub_411568(int a1)
{
  return *(_QWORD *)(*(_DWORD *)(a1 + 12) + 16) - *(_QWORD *)(*(_DWORD *)(a1 + 12) + 8);
}

//----- (00411590) --------------------------------------------------------
int __fastcall sub_411590(int a1)
{
  int v1; // ebx@1

  v1 = a1;
  sub_411240(a1);
  return *(_DWORD *)(v1 + 268);
}

//----- (004115A4) --------------------------------------------------------
int __fastcall sub_4115A4(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3
  int v4; // edx@3
  int v5; // edx@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  LOBYTE(v4) = 1;
  *(_DWORD *)(v3 + 16) = unknown_libname_33(off_408460, v4);
  LOBYTE(v5) = 1;
  *(_DWORD *)(v3 + 20) = unknown_libname_33(off_4103DC, v5);
  *(_DWORD *)(v3 + 268) = sub_40F518((int)off_40F158, 1);
  *(_BYTE *)(v3 + 272) = 0;
  *(_DWORD *)(v3 + 264) = sub_4123C8((int)off_410508, 1);
  *(_DWORD *)(v3 + 4) = 4;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 408460: using guessed type char *off_408460;
// 40F158: using guessed type char *off_40F158;
// 4103DC: using guessed type char *off_4103DC;
// 410508: using guessed type char *off_410508;

//----- (0041162C) --------------------------------------------------------
int __cdecl sub_41162C()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int v5; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 264));
  System::TObject::Free(*(_DWORD *)(v3 + 268));
  System::TObject::Free(*(_DWORD *)(v3 + 20));
  LOBYTE(v4) = 1;
  (*(void (__fastcall **)(_DWORD, int))(**(_DWORD **)(v3 + 16) - 4))(*(_DWORD *)(v3 + 16), v4);
  v5 = v2;
  LOBYTE(v5) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v5);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (0041167C) --------------------------------------------------------
signed int __fastcall sub_41167C(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // esi@1
  __int64 v4; // qax@1
  signed int result; // eax@5
  char v6; // zf@8
  __int64 v7; // qax@11
  char v8; // bl@15
  int v9; // ecx@23
  int v10; // eax@25
  int v11; // edx@30
  int v12; // eax@46
  int v13; // edx@60
  int v14; // [sp-4h] [bp-84h]@11
  int v15; // [sp+0h] [bp-80h]@6
  char v16; // [sp+4h] [bp-7Ch]@10
  char v17; // [sp+8h] [bp-78h]@11
  char v18; // [sp+10h] [bp-70h]@30
  char v19; // [sp+18h] [bp-68h]@12
  char v20; // [sp+19h] [bp-67h]@13
  int v21; // [sp+1Ch] [bp-64h]@14
  char v22; // [sp+24h] [bp-5Ch]@31
  int v23; // [sp+34h] [bp-4Ch]@40
  int v24; // [sp+38h] [bp-48h]@40

  v2 = a2;
  v3 = a1;
  sub_411A0C(a1);
  *(_DWORD *)(v3 + 12) = v2;
  *(_DWORD *)(v3 + 96) = *(_DWORD *)(v2 + 8);
  *(_DWORD *)(v3 + 100) = *(_DWORD *)(v2 + 12);
  *(_DWORD *)(v3 + 8) = 0;
  v4 = sub_411568(v3);
  if ( HIDWORD(v4) )
  {
    if ( SHIDWORD(v4) < 0 )
    {
LABEL_5:
      *(_DWORD *)(v3 + 4) = 3;
      return 0;
    }
  }
  else
  {
    if ( (unsigned int)v4 < 0x15 )
      goto LABEL_5;
  }
  if ( !(unsigned __int8)sub_40DDF0(*(_DWORD *)(v3 + 12), (int)&v15, 4) )
  {
    *(_DWORD *)(v3 + 4) = 1;
    return 0;
  }
  System::__linkproc___AStrCmp(&v15, off_41948C, v15);
  if ( !v6 )
    sub_41123C(v3, 1);
  if ( sub_410A44(*(_DWORD *)(v3 + 20), *(_DWORD *)(v3 + 12), *(_DWORD *)(v3 + 16), (int)&v16, v15) )
  {
    v17 = 1;
    v7 = *(_DWORD *)(*(_DWORD *)(v3 + 20) + 16);
    *(_QWORD *)(v3 + 104) = v7;
    v14 = *(_DWORD *)(v3 + 108);
    v8 = sub_40DD34(*(_DWORD *)(v3 + 12), SHIDWORD(v7), *(_DWORD *)(v3 + 104), *(__int64 *)&v14)
      && sub_4112B4(v3, (int)&v19)
      && v20
      && !v21;
    if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
    {
      *(_DWORD *)(v3 + 4) = 1;
      return 0;
    }
    if ( v8 )
    {
      *(_DWORD *)(v3 + 120) = 0;
      *(_DWORD *)(v3 + 124) = 8;
    }
  }
  else
  {
    if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
    {
      *(_DWORD *)(v3 + 4) = 1;
      return 0;
    }
    v9 = *(_DWORD *)(v3 + 20);
    v17 = (*(_BYTE *)(v9 + 20) & 1) != 0;
    *(_QWORD *)(v3 + 104) = *(_DWORD *)(v9 + 16);
    sub_41123C(v3, 4);
    v8 = 0;
  }
  if ( v17 )
  {
    v10 = *(_DWORD *)(v3 + 20);
    if ( *(_DWORD *)(v10 + 48) )
    {
      if ( *(_DWORD *)(v10 + 48) > 0 )
      {
LABEL_29:
        memcpy((void *)(v3 + 24), (const void *)(*(_DWORD *)(v3 + 20) + 28), 0x48u);
        *(_DWORD *)(v3 + 260) = *(_DWORD *)(*(_DWORD *)(v3 + 20) + 144);
        goto LABEL_49;
      }
    }
    else
    {
      if ( *(_DWORD *)(v10 + 44) )
        goto LABEL_29;
    }
  }
  sub_41123C(v3, 2);
  v14 = *(_DWORD *)(v3 + 108);
  LOBYTE(v11) = 1;
  if ( !sub_41140C(v3, v11, (int)&v18, (int)&v19, *(_DWORD *)(v3 + 104), *(__int64 *)&v14) )
  {
    if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
      *(_DWORD *)(v3 + 4) = 1;
    else
      *(_DWORD *)(v3 + 4) = 3;
    return 0;
  }
  memcpy((void *)(v3 + 24), &v22, 0x48u);
  if ( !*(_DWORD *)(v3 + 44) && !*(_DWORD *)(v3 + 40) )
  {
    v14 = *(_DWORD *)(v3 + 108);
    if ( !sub_411484(v3, &v19, *(_DWORD *)(v3 + 104), *(__int64 *)&v14) )
    {
      if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
        *(_DWORD *)(v3 + 4) = 1;
      else
        *(_DWORD *)(v3 + 4) = 3;
      return 0;
    }
    if ( v19 )
    {
      *(_DWORD *)(v3 + 40) = v23;
      *(_DWORD *)(v3 + 44) = v24;
    }
    else
    {
      *(_QWORD *)(v3 + 40) = *(_DWORD *)(v3 + 36) * (v21 + 1);
      sub_41123C(v3, 48);
    }
  }
  v12 = *(_DWORD *)(v3 + 40);
  if ( v12 >> 31 != *(_DWORD *)(v3 + 44) )
    sub_402CA8();
  *(_DWORD *)(v3 + 260) = sub_40A3FC(v12, *(_DWORD *)(v3 + 36));
LABEL_49:
  if ( *(_DWORD *)(v3 + 260) <= 0 )
  {
    *(_DWORD *)(v3 + 4) = 3;
    return 0;
  }
  if ( v8 )
    goto LABEL_60;
  v14 = *(_DWORD *)(v3 + 108);
  if ( sub_41140C(v3, 0, v3 + 104, (int)&v19, *(_DWORD *)(v3 + 104), *(__int64 *)&v14) )
  {
    if ( v21 )
      sub_41123C(v3, 8);
    *(_DWORD *)(v3 + 120) = v21;
    *(_DWORD *)(v3 + 124) = 8;
LABEL_60:
    if ( sub_40E260(*(_DWORD *)(v3 + 24), v3 + 48) )
    {
      v14 = *(_DWORD *)(v3 + 108);
      if ( sub_40DD34(*(_DWORD *)(v3 + 12), v13, *(_DWORD *)(v3 + 104), *(__int64 *)&v14) )
      {
        sub_412430(
          *(_DWORD *)(v3 + 264),
          *(_DWORD *)(v3 + 12),
          *(_DWORD *)(v3 + 260),
          v3 + 24,
          *(_DWORD *)(v3 + 124),
          *(_DWORD *)(v3 + 120),
          *(_DWORD *)(*(_DWORD *)(v3 + 12) + 16) - 1,
          (unsigned __int64)(*(_QWORD *)(*(_DWORD *)(v3 + 12) + 16) - 1i64) >> 32,
          *(_DWORD *)(v3 + 104),
          *(_DWORD *)(v3 + 108),
          v15);
        *(_DWORD *)(v3 + 4) = 0;
        *(_DWORD *)(v3 + 112) = 0;
        *(_DWORD *)(v3 + 116) = 0;
        result = 1;
      }
      else
      {
        *(_DWORD *)(v3 + 4) = 1;
        result = 0;
      }
    }
    else
    {
      *(_DWORD *)(v3 + 4) = 2;
      result = 0;
    }
    return result;
  }
  if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
    *(_DWORD *)(v3 + 4) = 1;
  else
    *(_DWORD *)(v3 + 4) = 3;
  return 0;
}
// 402748: using guessed type int __fastcall System____linkproc__ AStrCmp(_DWORD, _DWORD, _DWORD);
// 41948C: using guessed type void *off_41948C;

//----- (00411A0C) --------------------------------------------------------
int __fastcall sub_411A0C(int result)
{
  int v1; // ebx@1

  v1 = result;
  if ( *(_DWORD *)(result + 12) )
  {
    sub_412518(*(_DWORD *)(result + 264));
    *(_DWORD *)(v1 + 12) = 0;
    result = sub_40F708(*(_DWORD *)(v1 + 268));
    *(_BYTE *)(v1 + 272) = 0;
    *(_DWORD *)(v1 + 4) = 4;
  }
  return result;
}

//----- (00411A40) --------------------------------------------------------
char __fastcall sub_411A40(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  char result; // al@2

  v2 = a2;
  v3 = a1;
  if ( sub_411560(a1) )
  {
    if ( (unsigned __int8)sub_410AF8(*(_DWORD *)(v3 + 20), v2) )
    {
      result = 1;
    }
    else
    {
      if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
        *(_DWORD *)(v3 + 4) = 1;
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00411A80) --------------------------------------------------------
char __fastcall sub_411A80(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  char result; // al@2

  v2 = a2;
  v3 = a1;
  if ( sub_411560(a1) )
  {
    if ( (unsigned __int8)sub_410B8C(*(_DWORD *)(v3 + 20), v2) )
    {
      result = 1;
    }
    else
    {
      if ( sub_40DBFC(*(_DWORD *)(v3 + 12)) )
        *(_DWORD *)(v3 + 4) = 1;
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00411AC0) --------------------------------------------------------
char __fastcall sub_411AC0(int a1, signed int *a2)
{
  signed int *v2; // esi@1
  int v3; // ebx@1
  char result; // al@1

  v2 = a2;
  v3 = a1;
  result = sub_411560(a1);
  if ( result )
    result = sub_41253C(*(_DWORD *)(v3 + 264), v2);
  return result;
}

//----- (00411AE4) --------------------------------------------------------
char __usercall sub_411AE4<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  signed int v4; // esi@1
  int v5; // ebx@1
  char result; // al@2
  int v7; // [sp+0h] [bp-1Ch]@3
  int v8; // [sp+8h] [bp-14h]@4
  int v9; // [sp+Ch] [bp-10h]@4

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_411560(a1) )
  {
    if ( sub_41255C(*(_DWORD *)(v5 + 264), v4, (int)&v7) )
    {
      if ( *(_DWORD *)(*(_DWORD *)(v5 + 264) + 4) == 1 )
        *(_DWORD *)(v5 + 4) = 3;
      else
        *(_DWORD *)(v5 + 4) = 1;
      result = 0;
    }
    else
    {
      *(_DWORD *)v3 = v8;
      *(_DWORD *)(v3 + 4) = v9;
      result = 1;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00411B48) --------------------------------------------------------
char __fastcall sub_411B48(int a1, int a2)
{
  return sub_410CAC(*(_DWORD *)(a1 + 20), a2);
}

//----- (00411B54) --------------------------------------------------------
char __fastcall sub_411B54(int a1, int a2)
{
  return sub_410CD0(*(_DWORD *)(a1 + 20), a2);
}

//----- (00411B60) --------------------------------------------------------
int __fastcall sub_411B60(int a1, signed int a2)
{
  int v2; // ecx@1
  int result; // eax@1
  int v4; // edx@1

  v2 = a1;
  result = a2 / *(_DWORD *)(a1 + 32);
  v4 = *(_DWORD *)(v2 + 36);
  if ( result >= v4 )
    result = v4 - 1;
  return result;
}

//----- (00411B78) --------------------------------------------------------
int __fastcall sub_411B78(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3
  signed int v5; // [sp-10h] [bp-18h]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v3 + 4) = sub_409664((int)off_4095DC, 1, 1024, v3 + 8, 8, v5);
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 4095DC: using guessed type char *off_4095DC;

//----- (00411BF8) --------------------------------------------------------
signed int __usercall sub_411BF8<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  signed int v4; // edi@1
  signed int v5; // edi@3
  int v6; // eax@4
  unsigned int v7; // edx@4

  v3 = a1;
  *(_DWORD *)(a1 + 16) = *(_DWORD *)ecx0;
  *(_DWORD *)(a1 + 20) = *(_DWORD *)(ecx0 + 4);
  *(_DWORD *)(a1 + 24) = *(_DWORD *)(ecx0 + 8);
  *(_DWORD *)(a1 + 28) = *(_DWORD *)(ecx0 + 12);
  v4 = a2 + 63;
  if ( a2 + 63 < 0 )
    v4 = a2 + 126;
  v5 = v4 >> 6;
  *(_DWORD *)(a1 + 32) = v5;
  *(_DWORD *)(a1 + 36) = a2 / v5;
  if ( a2 / v5 - 1 >= 0 )
  {
    v6 = a2 / v5;
    v7 = 0;
    do
    {
      if ( v7 > 0x3F )
        sub_402CA8();
      *(_DWORD *)(*(_DWORD *)(v3 + 8) + 16 * v7++) = -1;
      --v6;
    }
    while ( v6 );
  }
  return sub_411C64(v3, (signed int *)ecx0);
}

//----- (00411C64) --------------------------------------------------------
signed int __fastcall sub_411C64(int a1, signed int *a2)
{
  signed int *v2; // esi@1
  int v3; // ebx@1
  int v4; // eax@1
  int v5; // eax@3
  signed int *v6; // ST00_4@5
  int v7; // esi@5
  signed int result; // eax@6
  int v9; // esi@7

  v2 = a2;
  v3 = a1;
  v4 = sub_411B60(a1, *a2);
  if ( (unsigned int)v4 > 0x3F )
    sub_402CA8();
  v5 = *(_DWORD *)(v3 + 8) + 16 * v4;
  if ( *(_DWORD *)v5 == -1 || *(_DWORD *)v5 > *v2 )
  {
    v6 = v2;
    *(_DWORD *)v5 = *v2;
    v7 = (int)(v2 + 1);
    *(_DWORD *)(v5 + 4) = *(_DWORD *)v7;
    v7 += 4;
    *(_DWORD *)(v5 + 8) = *(_DWORD *)v7;
    *(_DWORD *)(v5 + 12) = *(_DWORD *)(v7 + 4);
    v2 = v6;
  }
  result = *v2;
  if ( *v2 > *(_DWORD *)(v3 + 16) )
  {
    *(_DWORD *)(v3 + 16) = *v2;
    v9 = (int)(v2 + 1);
    *(_DWORD *)(v3 + 20) = *(_DWORD *)v9;
    v9 += 4;
    *(_DWORD *)(v3 + 24) = *(_DWORD *)v9;
    *(_DWORD *)(v3 + 28) = *(_DWORD *)(v9 + 4);
  }
  return result;
}

//----- (00411CAC) --------------------------------------------------------
char __usercall sub_411CAC<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  signed int v4; // edi@1
  int v5; // ebx@1
  int v6; // eax@1
  int v7; // edx@3
  char result; // al@5
  int v9; // eax@7
  int v10; // edx@10

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  v6 = sub_411B60(a1, a2);
  if ( (unsigned int)v6 > 0x3F )
    sub_402CA8();
  v7 = *(_DWORD *)(v5 + 8) + 16 * v6;
  if ( *(_DWORD *)v7 == -1 || v4 < *(_DWORD *)v7 )
  {
    if ( v6 - 1 < 0 )
    {
LABEL_13:
      result = 0;
    }
    else
    {
      v9 = v6 - 1;
      while ( 1 )
      {
        if ( (unsigned int)v9 > 0x3F )
          sub_402CA8();
        v10 = *(_DWORD *)(v5 + 8) + 16 * v9;
        if ( *(_DWORD *)v10 != -1 )
          break;
        --v9;
        if ( v9 == -1 )
          goto LABEL_13;
      }
      *(_DWORD *)v3 = *(_DWORD *)v10;
      *(_DWORD *)(v3 + 4) = *(_DWORD *)(v10 + 4);
      *(_DWORD *)(v3 + 8) = *(_DWORD *)(v10 + 8);
      *(_DWORD *)(v3 + 12) = *(_DWORD *)(v10 + 12);
      result = 1;
    }
  }
  else
  {
    *(_DWORD *)v3 = *(_DWORD *)v7;
    *(_DWORD *)(v3 + 4) = *(_DWORD *)(v7 + 4);
    *(_DWORD *)(v3 + 8) = *(_DWORD *)(v7 + 8);
    *(_DWORD *)(v3 + 12) = *(_DWORD *)(v7 + 12);
    result = 1;
  }
  return result;
}

//----- (00411D28) --------------------------------------------------------
char __usercall sub_411D28<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  signed int v4; // edi@1
  int v5; // ebx@1
  char result; // al@2
  int v7; // eax@3
  int v8; // edx@3
  int v9; // eax@5
  int v10; // edx@8
  int v11; // edi@8
  unsigned __int8 v12; // of@8
  int v13; // edi@8
  int v14; // edi@9
  int v15; // eax@12

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( a2 <= *(_DWORD *)(a1 + 16) )
  {
    v7 = sub_411B60(a1, a2);
    v8 = v7;
    if ( (unsigned int)v7 > 0x3F )
      sub_402CA8();
    v9 = *(_DWORD *)(v5 + 8) + 16 * v7;
    if ( *(_DWORD *)v9 == -1 || v4 > *(_DWORD *)v9 )
    {
      v10 = v8 + 1;
      v11 = *(_DWORD *)(v5 + 36) - 1;
      v12 = __OFSUB__(v11, v10);
      v13 = v11 - v10;
      if ( v13 < 0 ^ v12 )
      {
LABEL_15:
        *(_DWORD *)v3 = *(_DWORD *)(v5 + 16);
        *(_DWORD *)(v3 + 4) = *(_DWORD *)(v5 + 20);
        *(_DWORD *)(v3 + 8) = *(_DWORD *)(v5 + 24);
        *(_DWORD *)(v3 + 12) = *(_DWORD *)(v5 + 28);
        result = 1;
      }
      else
      {
        v14 = v13 + 1;
        while ( 1 )
        {
          if ( (unsigned int)v10 > 0x3F )
            sub_402CA8();
          v15 = *(_DWORD *)(v5 + 8) + 16 * v10;
          if ( *(_DWORD *)v15 != -1 )
            break;
          ++v10;
          --v14;
          if ( !v14 )
            goto LABEL_15;
        }
        *(_DWORD *)v3 = *(_DWORD *)v15;
        *(_DWORD *)(v3 + 4) = *(_DWORD *)(v15 + 4);
        *(_DWORD *)(v3 + 8) = *(_DWORD *)(v15 + 8);
        *(_DWORD *)(v3 + 12) = *(_DWORD *)(v15 + 12);
        result = 1;
      }
    }
    else
    {
      *(_DWORD *)v3 = *(_DWORD *)v9;
      *(_DWORD *)(v3 + 4) = *(_DWORD *)(v9 + 4);
      *(_DWORD *)(v3 + 8) = *(_DWORD *)(v9 + 8);
      *(_DWORD *)(v3 + 12) = *(_DWORD *)(v9 + 12);
      result = 1;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00411DB4) --------------------------------------------------------
int __fastcall sub_411DB4(int result, int a2)
{
  if ( a2 > *(_DWORD *)(result + 4) )
    *(_DWORD *)(result + 4) = a2;
  return result;
}

//----- (00411DC0) --------------------------------------------------------
char __fastcall sub_411DC0(int a1)
{
  int v1; // ebx@1
  char result; // al@2

  v1 = a1;
  if ( sub_410D48(*(_DWORD *)(a1 + 8)) )
  {
    result = 1;
  }
  else
  {
    sub_411DB4(v1, 2);
    result = 0;
  }
  return result;
}

//----- (00411DE4) --------------------------------------------------------
// local variable allocation has failed!
char __userpurge sub_411DE4<al>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, int a3, signed int *a4, int a5, __int64 a6, signed __int64 a7)
{
  int v8; // ebx@1
  unsigned __int64 v10; // qax@23
  __int64 v11; // [sp-4h] [bp-1Ch]@0
  char v12; // [sp+Eh] [bp-Ah]@4
  char v13; // [sp+Fh] [bp-9h]@4
  signed int v14; // [sp+10h] [bp-8h]@1
  int v15; // [sp+14h] [bp-4h]@1

  v14 = ecx0;
  v15 = a2;
  v8 = a1;
  do
  {
    LODWORD(v11) = a7;
    if ( !(unsigned __int8)sub_410DE8(
                             *(_DWORD *)(v8 + 8),
                             *(_DWORD *)(v8 + 16),
                             *(_DWORD *)(v8 + 52),
                             a5,
                             a6,
                             SHIDWORD(a6),
                             v11) )
    {
      sub_411DC0(v8);
      return 0;
    }
    v13 = 0;
    v12 = 0;
    while ( !v13 && sub_411168(*(_DWORD *)(v8 + 8), (int)(a4 + 2), v8 + 56, (int)(a4 + 1), SHIDWORD(v11)) )
    {
      *a4 = *(_DWORD *)(v8 + 60);
      if ( *a4 < v15 || *a4 > v14 )
        sub_410F14(*(_DWORD *)(v8 + 8), 1);
      else
        v13 = 1;
    }
    if ( !v13 )
    {
      sub_411DC0(v8);
      return 0;
    }
    sub_410F14(*(_DWORD *)(v8 + 8), a4[1]);
    sub_411204(*(_DWORD *)(v8 + 8));
    while ( !v12 && sub_411168(*(_DWORD *)(v8 + 8), a3 + 8, v8 + 56, a3 + 4, SHIDWORD(v11)) )
    {
      *(_DWORD *)a3 = *(_DWORD *)(v8 + 60);
      if ( *a4 + 1 == *(_DWORD *)(v8 + 60) && sub_411220(*(_DWORD *)(v8 + 8)) )
        v12 = 1;
      else
        sub_410F14(*(_DWORD *)(v8 + 8), 1);
    }
    if ( !sub_411DC0(v8) )
      return 0;
    if ( !v12 )
    {
      *(__int64 *)((char *)&a6 + 4) = *((_QWORD *)a4 + 1) + 1i64;
      v10 = __PAIR__(a6, a5) - (*((_QWORD *)a4 + 1) + 1i64) + 1;
      if ( HIDWORD(v10) )
      {
        if ( SHIDWORD(v10) < 0 )
          return 0;
      }
      else
      {
        if ( (unsigned int)v10 < 0xE )
          return 0;
      }
    }
  }
  while ( !((unsigned __int8)v12 & (unsigned __int8)v13) );
  sub_411C64(*(_DWORD *)(v8 + 12), a4);
  if ( *(_DWORD *)a3 == *(_DWORD *)(v8 + 40) - 1 )
    sub_411C64(*(_DWORD *)(v8 + 12), (signed int *)a3);
  return 1;
}
// 411DE4: variables would overlap: ST3C_8/8 and ST3C_12/12
// 411DE4: variables would overlap: ST48_4/4 and ST44_8/8
// 411DE4: variables would overlap: ST48_4/4 and ST40_8/8

//----- (00411F64) --------------------------------------------------------
char __fastcall sub_411F64(int a1, unsigned int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  _BYTE v5[20]; // [sp-Ch] [bp-2Ch]@2
  char v6; // [sp+8h] [bp-18h]@1
  int v7; // [sp+Ch] [bp-14h]@2
  __int64 v8; // [sp+10h] [bp-10h]@2

  v2 = a2;
  v3 = a1;
  if ( sub_411CAC(*(_DWORD *)(a1 + 12), *(_DWORD *)(a1 + 40) - 2, (int)&v6) )
    *(_QWORD *)&v5[12] = v8 + v7;
  else
    *(_QWORD *)&v5[12] = *(_QWORD *)(v3 + 24);
  if ( *(_QWORD *)(v3 + 32) - *(_QWORD *)&v5[12] + 1i64 > 5242880 )
    *(_QWORD *)&v5[12] = *(_QWORD *)(v3 + 32) - 5242880i64 + 1;
  *(_QWORD *)&v5[4] = *(_QWORD *)&v5[12];
  *(_DWORD *)v5 = *(_DWORD *)(v3 + 36);
  return sub_411DE4(
           v3,
           *(_DWORD *)(v3 + 40) - 2,
           *(_DWORD *)(v3 + 40) - 2,
           v2,
           (signed int *)&v6,
           *(_DWORD *)(v3 + 32),
           *(__int64 *)v5,
           *(signed __int64 *)&v5[8]);
}

//----- (00412010) --------------------------------------------------------
char __userpurge sub_412010<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4, __int64 a5)
{
  char result; // al@2
  __int64 v7; // ST0C_8@3
  signed __int64 v8; // [sp-4h] [bp-20h]@0
  char v9; // [sp+Ch] [bp-10h]@3

  if ( ecx0 == *(_DWORD *)a2 )
  {
    *(_DWORD *)a3 = *(_DWORD *)a2;
    *(_DWORD *)(a3 + 4) = *(_DWORD *)(a2 + 4);
    *(_DWORD *)(a3 + 8) = *(_DWORD *)(a2 + 8);
    *(_DWORD *)(a3 + 12) = *(_DWORD *)(a2 + 12);
    result = 1;
  }
  else
  {
    LODWORD(v8) = *(_DWORD *)(a2 + 12);
    HIDWORD(v7) = *(_DWORD *)(a2 + 8);
    LODWORD(v7) = a5;
    result = sub_411DE4(a1, ecx0 - 1, ecx0 - 1, a3, (signed int *)&v9, a4, v7, v8);
  }
  return result;
}

//----- (00412058) --------------------------------------------------------
char __usercall sub_412058<al>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  signed int v3; // esi@1
  int v4; // ebx@1
  signed int v5; // edi@10
  char result; // al@18
  signed __int64 v7; // qax@20
  long double v8; // fst7@20
  __int64 v9; // qax@20
  __int128 v10; // [sp-4h] [bp-2Ch]@1
  __int64 v11; // [sp+18h] [bp-10h]@20
  __int64 v12; // [sp+20h] [bp-8h]@22
  __int64 v13; // [sp+28h] [bp+0h]@1
  __int64 v14; // [sp+30h] [bp+8h]@1
  __int64 v15; // [sp+38h] [bp+10h]@1
  __int64 v16; // [sp+40h] [bp+18h]@1
  __int64 v17; // [sp+48h] [bp+20h]@2
  __int64 v18; // [sp+50h] [bp+28h]@5
  __int64 v19; // [sp+58h] [bp+30h]@25
  __int64 v20; // [sp+60h] [bp+38h]@27
  __int64 v21; // [sp+68h] [bp+40h]@25
  __int64 v22; // [sp+70h] [bp+48h]@28
  __int64 v23; // [sp+78h] [bp+50h]@20
  int v24; // [sp+80h] [bp+58h]@20

  DWORD3(v10) = ecx0;
  v3 = a2;
  v4 = a1;
  LODWORD(v13) = *(_DWORD *)(a1 + 44);
  v14 = *(_QWORD *)(a1 + 24);
  HIDWORD(v13) = *(_DWORD *)(a1 + 48);
  v15 = *(_DWORD *)(a1 + 40);
  v16 = *(_QWORD *)(a1 + 32) + 1i64;
  while ( 1 )
  {
    if ( !sub_4123B8(v4) )
      return 0;
    if ( sub_411CAC(*(_DWORD *)(v4 + 12), v3, (int)&v17) && (signed int)v17 > (signed int)v13 && v3 >= (signed int)v17 )
    {
      v13 = v17;
      v14 = v18;
    }
    if ( sub_411D28(*(_DWORD *)(v4 + 12), v3, (int)&v17) && (signed int)v17 < (signed int)v15 && v3 <= (signed int)v17 )
    {
      v15 = v17;
      v16 = v18;
    }
    v5 = v15 - v13;
    if ( (unsigned __int64)(v16 - v14) >> 32 && (((unsigned __int64)(v16 - v14) >> 32) & 0x80000000u) != 0i64 )
      System::__linkproc___Assert(&str_Assertion_failu_2[1], &str_D__VocComp_Win__8[1]);
    if ( v5 <= 10 || 2 * *(_DWORD *)(v4 + 148) >= v16 - v14 || v3 - (signed int)v13 <= 8 || v3 == (_DWORD)v15 )
      break;
    LODWORD(v7) = unknown_libname_56(v3 - v13, (unsigned __int64)(v3 - (signed int)v13) >> 32);
    v23 = v7;
    v24 = v15 - v13;
    v8 = (long double)v7 / (long double)v5;
    LODWORD(v9) = System::__linkproc___ROUND(v8);
    v11 = v14 + v9 - *(_DWORD *)(v4 + 148) / 2;
    if ( v14 + SHIDWORD(v13) > v11 )
      v11 = v14 + SHIDWORD(v13);
    v12 = v11 + *(_DWORD *)(v4 + 148);
    if ( v12 >= v16 )
    {
      v12 = v16 - 1;
      v11 = v16 - 1 - *(_DWORD *)(v4 + 148);
      if ( v14 + SHIDWORD(v13) > v16 - 1 - *(_DWORD *)(v4 + 148) )
        v11 = v14 + SHIDWORD(v13);
    }
    *(_QWORD *)((char *)&v10 + 4) = v11;
    LODWORD(v10) = HIDWORD(v12);
    if ( sub_411DE4(v4, v13 + 1, v15 - 1, (int)&v21, (signed int *)&v19, v12, v10, *((signed __int64 *)&v10 + 1)) )
    {
      if ( (signed int)v19 - v3 < 0 )
      {
        v13 = v21;
        v14 = v22;
      }
      else
      {
        v15 = v19;
        v16 = v20;
      }
    }
    else
    {
      if ( !sub_4123B8(v4)
        || *(_DWORD *)(*(_DWORD *)(v4 + 12) + 16) == *(_DWORD *)(v4 + 40) - 1
        || !sub_411F64(v4, (unsigned int)&v21) )
        return 0;
    }
  }
  if ( v3 == (_DWORD)v15 )
  {
    *DWORD3(v10) = v15;
    *(_QWORD *)(DWORD3(v10) + 8) = v16;
    result = 1;
  }
  else
  {
    *(_QWORD *)((char *)&v10 + 4) = v16 - 1;
    result = sub_412010(v4, (int)&v13, v3, SDWORD3(v10), v16 - 1, *((__int64 *)&v10 + 1));
  }
  return result;
}
// 402674: using guessed type int __usercall System____linkproc__ ROUND<eax>(double<st0>);
// 403DE4: using guessed type _DWORD __stdcall unknown_libname_56(_DWORD, _DWORD);
// 412364: using guessed type _strings str_D__VocComp_Win__8[6];
// 41239C: using guessed type _strings str_Assertion_failu_2[3];

//----- (004123B8) --------------------------------------------------------
char __fastcall sub_4123B8(int a1)
{
  return *(_DWORD *)(a1 + 4) == 0;
}

//----- (004123C0) --------------------------------------------------------
char __fastcall sub_4123C0(int a1)
{
  return *(_DWORD *)(a1 + 8) != 0;
}

//----- (004123C8) --------------------------------------------------------
int __fastcall sub_4123C8(int a1, char a2)
{
  char v2; // bl@3
  int v3; // esi@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v2 = a2;
  v3 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v3 + 4) = 2;
  if ( v2 )
    System::__linkproc___AfterConstruction(v3);
  return v3;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (00412404) --------------------------------------------------------
int __cdecl sub_412404()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  sub_412518(v0);
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (00412430) --------------------------------------------------------
int __userpurge sub_412430<eax>(int a1<eax>, int a2<edx>, signed int ecx0<ecx>, signed int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10)
{
  signed int v11; // edi@1
  int v12; // esi@1
  int v13; // ebx@1
  int v14; // edx@1
  int v15; // edx@1
  int v17; // [sp+Ch] [bp-10h]@1
  int v18; // [sp+10h] [bp-Ch]@1
  int v19; // [sp+14h] [bp-8h]@1
  int v20; // [sp+18h] [bp-4h]@1

  v11 = ecx0;
  v12 = a2;
  v13 = a1;
  sub_412518(a1);
  LOBYTE(v14) = 1;
  *(_DWORD *)(v13 + 8) = unknown_libname_109(off_41043C, v14);
  *(_DWORD *)(v13 + 12) = sub_411B78((int)off_4104A0, 1);
  LOBYTE(v15) = 1;
  *(_DWORD *)(v13 + 52) = unknown_libname_33(off_408460, v15);
  *(_DWORD *)(v13 + 16) = v12;
  *(_DWORD *)(v13 + 24) = a8;
  *(_DWORD *)(v13 + 28) = a9;
  *(_DWORD *)(v13 + 32) = a6;
  *(_DWORD *)(v13 + 36) = a7;
  *(_DWORD *)(v13 + 40) = v11;
  *(_DWORD *)(v13 + 44) = a5;
  *(_DWORD *)(v13 + 48) = a4;
  v17 = a5;
  v18 = a4;
  v19 = a8;
  v20 = a9;
  sub_411BF8(*(_DWORD *)(v13 + 12), v11, (int)&v17);
  if ( sub_40DBFC(v12) )
  {
    *(_DWORD *)(v13 + 4) = 2;
  }
  else
  {
    *(_DWORD *)(v13 + 148) = 2 * (*(_DWORD *)(a3 + 12) * *(_DWORD *)(a3 + 36) * (*(_DWORD *)(a3 + 32) + 4) / 8 + 39);
    *(_DWORD *)(v13 + 4) = 0;
  }
  return *(_DWORD *)(v13 + 4);
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 408460: using guessed type char *off_408460;
// 41043C: using guessed type char *off_41043C;
// 4104A0: using guessed type char *off_4104A0;

//----- (00412518) --------------------------------------------------------
int __fastcall sub_412518(int a1)
{
  int v1; // ebx@1
  int result; // eax@1

  v1 = a1;
  unknown_libname_101(a1 + 52);
  unknown_libname_101(v1 + 12);
  result = unknown_libname_101(v1 + 8);
  *(_DWORD *)(v1 + 4) = 2;
  return result;
}
// 409654: using guessed type int __fastcall unknown_libname_101(_DWORD);

//----- (0041253C) --------------------------------------------------------
char __fastcall sub_41253C(int a1, signed int *a2)
{
  signed int *v2; // esi@1
  int v3; // ebx@1
  char result; // al@1

  v2 = a2;
  v3 = a1;
  result = sub_4123B8(a1);
  if ( result )
    result = sub_411C64(*(_DWORD *)(v3 + 12), v2);
  return result;
}

//----- (0041255C) --------------------------------------------------------
int __usercall sub_41255C<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  signed int v4; // esi@1
  int v5; // ebx@1
  int result; // eax@6

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( a2 < 0 || a2 >= *(_DWORD *)(a1 + 40) || !sub_4123C0(a1) )
    System::__linkproc___Assert(&str_Assertion_failu_3[1], &str_D__VocComp_Win__9[1]);
  if ( sub_4123B8(v5) )
  {
    if ( sub_40DBFC(*(_DWORD *)(v5 + 16)) )
    {
      sub_411DB4(v5, 2);
      result = *(_DWORD *)(v5 + 4);
    }
    else
    {
      if ( !sub_412058(v5, v4, v3) )
        sub_411DB4(v5, 1);
      result = *(_DWORD *)(v5 + 4);
    }
  }
  else
  {
    result = *(_DWORD *)(v5 + 4);
  }
  return result;
}
// 4125DC: using guessed type _strings str_D__VocComp_Win__9[6];
// 412614: using guessed type _strings str_Assertion_failu_3[3];

//----- (00412630) --------------------------------------------------------
int __cdecl sub_412630()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8C8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8C8: using guessed type int dword_41A8C8;

//----- (00412660) --------------------------------------------------------
void __cdecl sub_412660()
{
  --dword_41A8C8;
}
// 41A8C8: using guessed type int dword_41A8C8;

//----- (00412668) --------------------------------------------------------
int __cdecl sub_412668()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8CC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8CC: using guessed type int dword_41A8CC;

//----- (00412698) --------------------------------------------------------
void __cdecl sub_412698()
{
  --dword_41A8CC;
}
// 41A8CC: using guessed type int dword_41A8CC;

//----- (004126A0) --------------------------------------------------------
int __userpurge sub_4126A0<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, char a4)
{
  int v5; // esi@2

  if ( ecx0 - 1 >= 0 )
  {
    v5 = ecx0;
    do
    {
      *(_DWORD *)a2 = (-(*(_DWORD *)result >> 31) ^ ((-(*(_DWORD *)result >> 31) ^ (unsigned int)(*(_DWORD *)result
                                                                                                - (*(_DWORD *)result >> 31))) >> a3))
                    + (*(_DWORD *)result >> 31);
      result += 4;
      a2 += 4;
      --v5;
    }
    while ( v5 );
  }
  return result;
}

//----- (004126D8) --------------------------------------------------------
int __userpurge sub_4126D8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int result; // eax@2
  char v6; // [sp+0h] [bp-4h]@0

  if ( a3 )
    result = sub_4126A0(a1, a2, ecx0, a3, v6);
  else
    result = System::Move(a1, a2);
  return result;
}

//----- (004126F8) --------------------------------------------------------
int __usercall sub_4126F8<eax>(int result<eax>, unsigned int a2<edx>, char cl0<cl>)
{
  unsigned int v3; // ebx@2

  if ( (((a2 >> 1) - 1) & 0x80000000u) == 0 )
  {
    v3 = a2 >> 1;
    do
    {
      *(_DWORD *)result <<= cl0;
      *(_DWORD *)(result + 4) <<= cl0;
      result += 8;
      --v3;
    }
    while ( v3 );
  }
  if ( a2 & 1 )
    *(_DWORD *)result <<= cl0;
  return result;
}

//----- (00412725) --------------------------------------------------------
int __userpurge sub_412725<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>, int a3, unsigned int a4)
{
  int v5; // edi@1
  unsigned int v6; // esi@2
  int v7; // ebx@2
  int v8; // ebx@3
  __m64 v9; // mm6@4
  __m64 v10; // mm7@4

  v5 = ecx0;
  if ( ecx0 > 0 )
  {
    v6 = (1 << a3) - 1;
    v7 = ecx0 & 0xFFFFFFFC;
    if ( !(ecx0 & 0xFFFFFFFC) )
      goto LABEL_12;
    result += 4 * v7;
    a2 += 2 * v7;
    v8 = -v7;
    if ( a3 )
    {
      v9 = _m_por(_m_psllq(_mm_cvtsi32_si64(v6), 0x20u), _mm_cvtsi32_si64(v6));
      v10 = _mm_cvtsi32_si64(a3);
      do
      {
        *(_QWORD *)(a2 + 2 * v8) = _m_packssdw(
                                     _m_psrad(
                                       _m_paddd(
                                         *(__m64 *)(result + 4 * v8),
                                         _m_pand(_m_psrad(*(__m64 *)(result + 4 * v8), 0x1Fu), v9)),
                                       v10),
                                     _m_psrad(
                                       _m_paddd(
                                         *(__m64 *)(result + 4 * v8 + 8),
                                         _m_pand(_m_psrad(*(__m64 *)(result + 4 * v8 + 8), 0x1Fu), v9)),
                                       v10));
        v8 += 4;
      }
      while ( v8 < 0 );
    }
    else
    {
      do
      {
        *(_QWORD *)(a2 + 2 * v8) = _m_packssdw(*(__m64 *)(result + 4 * v8), *(__m64 *)(result + 4 * v8 + 8));
        v8 += 4;
      }
      while ( v8 < 0 );
    }
    _m_femms();
    v5 = ecx0 & 3;
    if ( ecx0 & 3 )
    {
LABEL_12:
      do
      {
        *(_WORD *)a2 = (signed int)((v6 & (*(_DWORD *)result >> 31)) + *(_DWORD *)result) >> a3;
        result += 4;
        a2 += 2;
        --v5;
      }
      while ( v5 );
    }
  }
  return result;
}

//----- (004127D8) --------------------------------------------------------
int __cdecl sub_4127D8()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8D0;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8D0: using guessed type int dword_41A8D0;

//----- (00412808) --------------------------------------------------------
void __cdecl sub_412808()
{
  --dword_41A8D0;
}
// 41A8D0: using guessed type int dword_41A8D0;

//----- (004128CC) --------------------------------------------------------
int __fastcall sub_4128CC(int a1)
{
  int v1; // ecx@1
  unsigned int v2; // ebx@1
  int v3; // edi@6
  int result; // eax@6

  v1 = a1;
  *(_DWORD *)(a1 + 44) = 0;
  v2 = 0;
  do
  {
    ++v2;
    if ( v2 > 0x80 )
      sub_402CA8();
    *(_DWORD *)(v1 + 4 * v2 + 44) = *(_DWORD *)(v1 + 24) & (*(_DWORD *)(v1 + 28)
                                                          + (signed int)(v2 * *(_DWORD *)(v1 + 4))
                                                          / *(_DWORD *)(v1 + 32));
    if ( v2 > 0x80 )
      sub_402CA8();
    v3 = *(_DWORD *)(v1 + 4 * v2 + 44);
    result = *(_DWORD *)(v1 + 8);
  }
  while ( v3 < result && v2 != *(_DWORD *)(v1 + 36) );
  if ( v2 > 0x80 )
    sub_402CA8();
  if ( result <= v3 )
  {
    if ( v2 > 0x80 )
      sub_402CA8();
    if ( result < *(_DWORD *)(v1 + 4 * v2 + 44) )
    {
      if ( v2 > 0x80 )
        sub_402CA8();
      *(_DWORD *)(v1 + 4 * v2 + 44) = result;
      if ( v2 > 0x80 )
        sub_402CA8();
      if ( v2 - 1 > 0x80 )
        sub_402CA8();
      result = *(_DWORD *)(v1 + 4 * v2 + 44) - *(_DWORD *)(v1 + 4 * (v2 - 1) + 44);
      if ( result < *(_DWORD *)(v1 + 20) )
      {
        --v2;
        if ( v2 > 0x80 )
          sub_402CA8();
        result = *(_DWORD *)(v1 + 8);
        *(_DWORD *)(v1 + 4 * v2 + 44) = result;
      }
    }
  }
  else
  {
    if ( v2 > 0x80 )
      sub_402CA8();
    *(_DWORD *)(v1 + 4 * v2 + 44) = result;
  }
  *(_DWORD *)(v1 + 40) = v2;
  return result;
}

//----- (004129A8) --------------------------------------------------------
int __usercall sub_4129A8<eax>(signed int a1<edx>, int a2<ecx>, int a3<ebx>)
{
  if ( a2 < 4 )
    a2 = 4;
  LOBYTE(a3) = 3;
  while ( (_BYTE)a3 && a2 > a1 / *((_DWORD *)off_419504 + (unsigned __int8)a3) )
  {
    --a3;
    if ( (unsigned int)(char)a3 > 3 )
      sub_402CA8();
  }
  return a3;
}
// 419504: using guessed type void *off_419504;

//----- (004129EC) --------------------------------------------------------
int __userpurge sub_4129EC<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5, int a6, int a7, int a8)
{
  int v9; // ST1C_4@3
  int v10; // ebx@3
  signed int v11; // esi@3
  char v13; // [sp+13h] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v9 = ecx0;
  v13 = a2;
  v10 = a1;
  v11 = a3;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v10 + 4) = v9;
  *(_DWORD *)(v10 + 8) = a7;
  *(_BYTE *)(v10 + 12) = a6;
  *(_DWORD *)(v10 + 36) = a5;
  *(_DWORD *)(v10 + 16) = a4;
  *(_DWORD *)(v10 + 24) = ~(a4 - 1);
  *(_DWORD *)(v10 + 28) = *(_DWORD *)(v10 + 16) / 2;
  if ( a3 < 4 )
    v11 = 4;
  if ( a4 > v11 )
    v11 = a4;
  *(_DWORD *)(v10 + 20) = v11;
  *(_BYTE *)(v10 + 13) = sub_4129A8(*(_DWORD *)(v10 + 4), v11, v10);
  if ( *(_BYTE *)(v10 + 13) < *(_BYTE *)(v10 + 12) )
    *(_BYTE *)(v10 + 12) = *(_BYTE *)(v10 + 13);
  *(_DWORD *)(v10 + 32) = *((_DWORD *)off_419504 + *(_BYTE *)(v10 + 12));
  sub_4128CC(v10);
  *(double *)(v10 + 560) = (long double)*(signed int *)(v10 + 32) / (long double)*(signed int *)(v10 + 4);
  if ( v13 )
    System::__linkproc___AfterConstruction(v10);
  return v10;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 419504: using guessed type void *off_419504;

//----- (00412AC4) --------------------------------------------------------
signed int __fastcall sub_412AC4(int a1, signed int a2)
{
  signed int v2; // esi@1
  int v3; // ebx@1
  long double v4; // fst7@1
  signed int result; // eax@1
  int v6; // edx@1

  v2 = a2;
  v3 = a1;
  v4 = (long double)a2 * *(double *)(a1 + 560);
  result = System::__linkproc___ROUND(v4);
  if ( result >> 31 != v6 )
    sub_402CA8();
  if ( result <= *(_DWORD *)(v3 + 40) )
  {
    while ( result < *(_DWORD *)(v3 + 40) )
    {
      if ( (unsigned int)(result + 1) > 0x80 )
        sub_402CA8();
      if ( v2 < *(_DWORD *)(v3 + 4 * (result + 1) + 44) )
        break;
      ++result;
    }
  }
  else
  {
    result = *(_DWORD *)(v3 + 40);
  }
  while ( 1 )
  {
    if ( (unsigned int)result > 0x80 )
      sub_402CA8();
    if ( v2 >= *(_DWORD *)(v3 + 4 * result + 44) || result <= 0 )
      break;
    --result;
  }
  return result;
}
// 402674: using guessed type int __usercall System____linkproc__ ROUND<eax>(double<st0>);

//----- (00412B30) --------------------------------------------------------
int __usercall sub_412B30<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>)
{
  int v3; // esi@3
  char v4; // ST1F_1@3
  int v5; // ebx@3
  int v7; // [sp-10h] [bp-1Ch]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v5 + 4) = v3;
  sub_412B84(v5, *(_DWORD *)(v3 + 8), *(_BYTE *)(v3 + 12), -1, v7);
  if ( v4 )
    System::__linkproc___AfterConstruction(v5);
  return v5;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (00412B84) --------------------------------------------------------
int __userpurge sub_412B84<eax>(int a1<eax>, signed int a2<edx>, char cl0<cl>, int a3, int a4)
{
  signed int v5; // ST10_4@1
  int v6; // ebx@1
  int v7; // edx@1
  int v8; // eax@1
  unsigned int v9; // eax@2
  int result; // eax@6

  v5 = a2;
  v6 = a1;
  *(_BYTE *)(a1 + 12) = cl0;
  v7 = *(_BYTE *)(*(_DWORD *)(a1 + 4) + 12) - (cl0 & 0x7F);
  *(_DWORD *)(a1 + 16) = v7;
  *(_DWORD *)(a1 + 20) = 1 << v7;
  *(_DWORD *)(a1 + 8) = v5;
  *(_DWORD *)(v6 + 24) = (unsigned int)sub_412AC4(*(_DWORD *)(a1 + 4), v5) >> *(_DWORD *)(v6 + 16);
  v8 = *(_DWORD *)(v6 + 24);
  if ( !v8 )
    goto LABEL_12;
  v9 = v8 << *(_DWORD *)(v6 + 16);
  if ( v9 > 0x80 )
    sub_402CA8();
  if ( *(_DWORD *)(v6 + 8) - *(_DWORD *)(*(_DWORD *)(v6 + 4) + 4 * v9 + 44) >= *(_DWORD *)(*(_DWORD *)(v6 + 4) + 20) )
LABEL_12:
    ++*(_DWORD *)(v6 + 24);
  result = *(_DWORD *)(v6 + 4);
  if ( a3 > *(_DWORD *)(result + 20) )
  {
    result = sub_412C48(v6, *(_DWORD *)(v6 + 24) - 1);
    if ( a3 > result )
    {
      if ( *(_DWORD *)(v6 + 24) > 1 )
        --*(_DWORD *)(v6 + 24);
    }
  }
  return result;
}

//----- (00412C24) --------------------------------------------------------
int __fastcall sub_412C24(int a1, int a2)
{
  int v2; // edx@2
  int result; // eax@4

  if ( a2 >= *(_DWORD *)(a1 + 24) )
  {
    result = *(_DWORD *)(a1 + 8);
  }
  else
  {
    v2 = a2 << *(_DWORD *)(a1 + 16);
    if ( (unsigned int)v2 > 0x80 )
      sub_402CA8();
    result = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4 * v2 + 44);
  }
  return result;
}

//----- (00412C48) --------------------------------------------------------
int __fastcall sub_412C48(int a1, int a2)
{
  int v2; // ebx@2
  int v3; // esi@2
  int v4; // esi@4
  int v5; // edx@4
  int result; // eax@6
  int v7; // edx@7

  if ( a2 >= *(_DWORD *)(a1 + 24) - 1 )
  {
    v7 = a2 << *(_DWORD *)(a1 + 16);
    if ( (unsigned int)v7 > 0x80 )
      sub_402CA8();
    result = *(_DWORD *)(a1 + 8) - *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4 * v7 + 44);
  }
  else
  {
    v2 = *(_DWORD *)(a1 + 16);
    v3 = (a2 + 1) << *(_DWORD *)(a1 + 16);
    if ( (unsigned int)v3 > 0x80 )
      sub_402CA8();
    v4 = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4 * v3 + 44);
    v5 = a2 << v2;
    if ( (unsigned int)v5 > 0x80 )
      sub_402CA8();
    result = v4 - *(_DWORD *)(*(_DWORD *)(a1 + 4) + 4 * v5 + 44);
  }
  return result;
}

//----- (00412CAC) --------------------------------------------------------
int __cdecl sub_412CAC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8D4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8D4: using guessed type int dword_41A8D4;

//----- (00412CDC) --------------------------------------------------------
void __cdecl sub_412CDC()
{
  --dword_41A8D4;
}
// 41A8D4: using guessed type int dword_41A8D4;

//----- (00412CE4) --------------------------------------------------------
int *__fastcall sub_412CE4(int *a1, int a2)
{
  signed int v2; // edx@1
  int v3; // ecx@1
  int *result; // eax@1
  int v5; // ebx@2
  int v6; // ecx@3
  int v7; // ecx@3
  int v8; // ecx@3
  int v9; // ecx@5

  v2 = a2 - 1;
  v3 = *a1;
  result = a1 + 1;
  if ( v2 / 4 - 1 >= 0 )
  {
    v5 = v2 / 4;
    do
    {
      v6 = *result + v3;
      *result = v6;
      v7 = result[1] + v6;
      result[1] = v7;
      v8 = result[2] + v7;
      result[2] = v8;
      v3 = result[3] + v8;
      result[3] = v3;
      result += 4;
      --v5;
    }
    while ( v5 );
  }
  if ( v2 & 2 )
  {
    v9 = *result + v3;
    *result = v9;
    v3 = result[1] + v9;
    result[1] = v3;
    result += 2;
  }
  if ( v2 & 1 )
    *result += v3;
  return result;
}

//----- (00412D38) --------------------------------------------------------
int __fastcall sub_412D38(int result, signed int a2)
{
  int v2; // ebx@2
  int v3; // ecx@2
  int v4; // esi@4
  int v5; // ebx@5
  int v6; // ecx@5

  if ( a2 > 1 )
  {
    v2 = *(_DWORD *)(result + 4);
    v3 = v2 + *(_DWORD *)result;
    *(_DWORD *)(result + 4) = v3;
    if ( a2 > 2 )
    {
      result += 8;
      if ( (a2 - 2) / 2 - 1 >= 0 )
      {
        v4 = (a2 - 2) / 2;
        do
        {
          v5 = *(_DWORD *)result + v2;
          v6 = v5 + v3;
          *(_DWORD *)result = v6;
          v2 = *(_DWORD *)(result + 4) + v5;
          v3 = v2 + v6;
          *(_DWORD *)(result + 4) = v3;
          result += 8;
          --v4;
        }
        while ( v4 );
      }
      if ( a2 & 1 )
        *(_DWORD *)result += v3 + v2;
    }
  }
  return result;
}

//----- (00412D84) --------------------------------------------------------
int __fastcall sub_412D84(int result)
{
  if ( *(_BYTE *)(result + 8) == 1 )
  {
    result = (int)sub_412CE4(*(int **)result, *(_DWORD *)(result + 4));
  }
  else
  {
    if ( *(_BYTE *)(result + 8) == 2 )
      result = sub_412D38(*(_DWORD *)result, *(_DWORD *)(result + 4));
  }
  return result;
}

//----- (00412DAC) --------------------------------------------------------
int __cdecl sub_412DAC()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8D8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8D8: using guessed type int dword_41A8D8;

//----- (00412DDC) --------------------------------------------------------
void __cdecl sub_412DDC()
{
  --dword_41A8D8;
}
// 41A8D8: using guessed type int dword_41A8D8;

//----- (00412DE4) --------------------------------------------------------
int __cdecl sub_412DE4()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8DC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8DC: using guessed type int dword_41A8DC;

//----- (00412E14) --------------------------------------------------------
void __cdecl sub_412E14()
{
  --dword_41A8DC;
}
// 41A8DC: using guessed type int dword_41A8DC;

//----- (00412E7C) --------------------------------------------------------
signed int __fastcall sub_412E7C(int a1)
{
  signed int result; // eax@1

  _EDX = a1;
  __asm { bsr     eax, edx }
  if ( _ZF )
    result = -1;
  return result;
}

//----- (00412E8C) --------------------------------------------------------
bool __fastcall sub_412E8C(signed int a1)
{
  bool result; // eax@3

  if ( a1 > 1 )
    result = sub_412E7C(a1 - 1) + 1;
  else
    result = a1 == 1;
  return result;
}

//----- (00412EB0) --------------------------------------------------------
int __fastcall sub_412EB0(int a1, unsigned __int8 a2)
{
  int v2; // edi@3
  int v3; // ebx@4

  if ( (unsigned int)a2 - 1 > 2 )
    sub_402CA8();
  v2 = *((_DWORD *)&unk_418EF4 + 7 * a2 + 3);
  if ( a1 <= v2 )
    v3 = 1;
  else
    v3 = sub_412E8C(a1 - v2) + 1;
  if ( v3 <= 0 )
    System::__linkproc___Assert(&str_Assertion_failu_4[1], &str_D__VocComp_Win__10[1]);
  return v3;
}
// 412F0C: using guessed type _strings str_D__VocComp_Win__10[6];
// 412F40: using guessed type _strings str_Assertion_failu_4[3];

//----- (00412F5C) --------------------------------------------------------
char __userpurge sub_412F5C<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // edi@1
  int v7; // esi@5
  unsigned int v8; // eax@6
  int v9; // ebx@10
  int v10; // eax@11
  unsigned int v11; // eax@12
  int v13; // [sp+Ch] [bp-10h]@5
  int v14; // [sp+10h] [bp-Ch]@3
  signed int v15; // [sp+14h] [bp-8h]@1
  int v16; // [sp+18h] [bp-4h]@1

  v6 = ecx0;
  v16 = a2;
  v15 = 1 << (a2 - 1);
  if ( (unsigned int)a1 - 1 > 2 )
    sub_402CA8();
  v14 = dword_418EF8[7 * a1];
  if ( (a1 & 0x7Fu) - 1 > 2 )
    sub_402CA8();
  v13 = dword_418EFC[7 * a1];
  v7 = a3;
  if ( a3 > 0 )
  {
    do
    {
      v8 = sub_40864C(v6, v14);
      if ( v8 )
      {
        if ( (signed int)v8 > v13 )
          *(_DWORD *)a4 = -(v8 - v13);
        else
          *(_DWORD *)a4 = v8 - 1;
      }
      else
      {
        v9 = sub_408758(v6, 4);
        if ( v9 >= 4 )
        {
          v11 = sub_40864C(v6, v16);
          if ( (signed int)v11 >= v15 )
            *(_DWORD *)a4 = -(v13 + 4 + v11 - v15);
          else
            *(_DWORD *)a4 = v13 + 4 + v11;
        }
        else
        {
          v10 = sub_408704(v6);
          *(_DWORD *)a4 = (-v10 ^ (v13 + v9)) + v10;
        }
      }
      a4 += 4;
      --v7;
    }
    while ( v7 );
  }
  return *(_BYTE *)(v6 + 44) ^ 1;
}
// 418EF8: using guessed type int dword_418EF8[];
// 418EFC: using guessed type int dword_418EFC[];

//----- (00413060) --------------------------------------------------------
int __fastcall sub_413060(int a1, unsigned __int8 a2)
{
  char *v2; // ebx@3
  signed int v3; // ebp@3
  int result; // eax@4

  if ( (unsigned int)a2 - 4 > 0x2E )
    sub_402CA8();
  v2 = (char *)&unk_418F04 + 24 * a2;
  v3 = *((_DWORD *)v2 + 4);
  if ( 2 * a1 < v3 + *((_DWORD *)v2 + 5) )
    result = 10;
  else
    result = sub_412E8C((2 * a1 - *((_DWORD *)v2 + 5)) / v3 + 1) + 10;
  return result;
}

//----- (004130B4) --------------------------------------------------------
int __fastcall sub_4130B4(void *a1, int a2)
{
  void *v2; // edi@1
  int result; // eax@1

  v2 = a1;
  result = 0;
  memset(v2, 0, 4 * a2);
  return result;
}

//----- (004130C4) --------------------------------------------------------
char __fastcall sub_4130C4(signed int a1, int a2)
{
  int v2; // edx@1
  char result; // al@3

  v2 = a2 - 8;
  if ( v2 )
  {
    if ( (unsigned int)(v2 - 8) < 9 )
    {
      if ( a1 < 44100 )
      {
        if ( a1 < 22050 )
          result = a1 >= 11025;
        else
          result = 2;
      }
      else
      {
        result = 3;
      }
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    if ( a1 < 48000 )
    {
      if ( a1 < 32000 )
        result = a1 >= 16000;
      else
        result = 2;
    }
    else
    {
      result = 3;
    }
  }
  return result;
}

//----- (00413120) --------------------------------------------------------
int __fastcall sub_413120(int a1, unsigned __int8 a2)
{
  int result; // eax@3

  if ( (unsigned __int8)(a2 - 1) < 3u )
  {
    result = sub_412EB0(a1, a2);
  }
  else
  {
    if ( (unsigned __int8)(a2 - 4) >= 0x2Fu )
      result = 1;
    else
      result = sub_413060(a1, a2);
  }
  return result;
}

//----- (00413140) --------------------------------------------------------
char __userpurge sub_413140<al>(unsigned __int8 a1<al>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // ebx@1
  int v7; // eax@4
  char result; // al@6
  int v9; // [sp+0h] [bp-4h]@0

  v6 = ecx0;
  if ( a1 < 1u )
  {
    sub_4130B4((void *)a4, a3);
    result = 1;
  }
  else
  {
    if ( (unsigned __int8)(a1 - 1) < 3u )
    {
      result = sub_412F5C(a1, a2, ecx0, a3, a4, v9);
    }
    else
    {
      if ( (unsigned __int8)(a1 - 4) >= 0x2Fu )
      {
        result = 1;
      }
      else
      {
        v7 = (a1 & 0x7F) - 4;
        if ( (unsigned int)v7 > 0x2E )
          sub_402CA8();
        sub_413749((int)((char *)&unk_418F04 + 24 * (v7 + 4)), a2, ecx0, a4, a3);
        result = *(_BYTE *)(v6 + 44) ^ 1;
      }
    }
  }
  return result;
}

//----- (004131B8) --------------------------------------------------------
char __usercall sub_4131B8<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  char result; // al@5
  int v6; // ebx@6
  int v7; // ebx@7
  unsigned int v8; // esi@7
  unsigned int v9; // eax@8
  int v10; // eax@8
  int v11; // [sp+0h] [bp-18h]@1
  int v12; // [sp+4h] [bp-14h]@1
  int v13; // [sp+8h] [bp-10h]@4

  v11 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408814(a1, 6, (int)&v12) && v12 >= 0 && v12 <= 50 && sub_408814(v4, 3, (int)&v13) )
  {
    ++v13;
    v6 = v3 - 1;
    if ( v6 < 0 )
    {
LABEL_13:
      result = *(_BYTE *)(v4 + 44) ^ 1;
    }
    else
    {
      v7 = v6 + 1;
      v8 = 0;
      while ( 1 )
      {
        v9 = sub_40864C(v4, v13);
        v10 = v12 + v9;
        if ( v10 > 50 )
          break;
        if ( v8 > 0x7F )
          sub_402CA8();
        *(_BYTE *)(v11 + v8++) = v10;
        --v7;
        if ( !v7 )
          goto LABEL_13;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00413244) --------------------------------------------------------
char __usercall sub_413244<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int v4; // edi@1
  char result; // al@4
  int v6; // esi@5
  signed int v7; // ebp@6
  int v8; // eax@7
  int v9; // ebx@7
  int v10; // eax@9
  int v11; // [sp+0h] [bp-18h]@1
  unsigned int v12; // [sp+4h] [bp-14h]@1

  v11 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408814(a1, 6, (int)&v12) && (v12 & 0x80000000u) == 0 && (signed int)v12 <= 50 )
  {
    *(_BYTE *)v11 = v12;
    v6 = v3 - 1;
    if ( v3 - 1 <= 0 )
    {
LABEL_16:
      result = *(_BYTE *)(v4 + 44) ^ 1;
    }
    else
    {
      v7 = 1;
      while ( 1 )
      {
        v8 = sub_408758(v4, 9);
        v9 = v8;
        if ( v8 > 0 )
        {
          if ( v8 >= 9 )
          {
            v12 = sub_40864C(v4, 6);
          }
          else
          {
            v10 = sub_408704(v4);
            v12 += (-v10 ^ v9) + v10;
          }
          if ( (signed int)(v12 & 0xFFFFFFF) > 50 )
            break;
        }
        if ( (unsigned int)v7 > 0x7F )
          sub_402CA8();
        *(_BYTE *)(v11 + v7++) = v12;
        --v6;
        if ( !v6 )
          goto LABEL_16;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00413304) --------------------------------------------------------
char __usercall sub_413304<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // ebx@1
  char result; // al@4
  int v6; // esi@5
  signed int v7; // ebp@6
  unsigned int v8; // eax@7
  int v9; // edi@8
  int v10; // eax@9
  int v11; // [sp+0h] [bp-18h]@1
  unsigned int v12; // [sp+4h] [bp-14h]@1

  v11 = ecx0;
  v3 = a2;
  v4 = a1;
  if ( sub_408814(a1, 6, (int)&v12) && (v12 & 0x80000000u) == 0 && (signed int)v12 <= 50 )
  {
    *(_BYTE *)v11 = v12;
    v6 = v3 - 1;
    if ( v6 <= 0 )
    {
LABEL_17:
      result = *(_BYTE *)(v4 + 44) ^ 1;
    }
    else
    {
      v7 = 1;
      while ( 1 )
      {
        v8 = sub_40864C(v4, 2);
        if ( v8 )
        {
          v12 += -(v8 >> 1) & (2 * (v8 & 1) - 1);
        }
        else
        {
          v9 = sub_408758(v4, 7);
          if ( v9 >= 7 )
          {
            v12 = sub_40864C(v4, 6);
          }
          else
          {
            v10 = sub_408704(v4);
            v12 += (-v10 ^ (v9 + 2)) + v10;
          }
        }
        if ( (signed int)(v12 & 0xFFFFFFF) > 50 )
          break;
        if ( (unsigned int)v7 > 0x7F )
          sub_402CA8();
        *(_BYTE *)(v11 + v7++) = v12;
        --v6;
        if ( !v6 )
          goto LABEL_17;
      }
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (004133F0) --------------------------------------------------------
char __usercall sub_4133F0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1
  unsigned int v6; // eax@1
  char result; // al@2

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  v6 = sub_40864C(a1, 2);
  if ( v6 )
  {
    if ( v6 == 1 )
    {
      result = sub_413244(v5, v4, v3);
    }
    else
    {
      if ( v6 == 2 )
        result = sub_413304(v5, v4, v3);
      else
        result = 0;
    }
  }
  else
  {
    result = sub_4131B8(v5, v4, v3);
  }
  return result;
}

//----- (00413440) --------------------------------------------------------
signed int __fastcall sub_413440(int a1)
{
  signed int result; // eax@2

  if ( a1 <= 0 )
    result = 0;
  else
    result = 1 << a1;
  return result;
}

//----- (00413454) --------------------------------------------------------
int __userpurge sub_413454<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5)
{
  int v6; // esi@3
  int v7; // ebx@3
  unsigned __int8 v8; // al@3
  int v10; // [sp-10h] [bp-20h]@0
  char v11; // [sp+Fh] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v6 = ecx0;
  v11 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 4) = a3;
  *(_DWORD *)(v7 + 12) = sub_4129EC((int)off_412810, 1, v6, 4, 4, 128, 3, a3, v10);
  *(_DWORD *)(v7 + 16) = sub_412B30((int)off_41286C, 1, *(_DWORD *)(v7 + 12));
  *(_BYTE *)(v7 + 8) = sub_4130C4(v6, a4);
  v8 = *(_BYTE *)(*(_DWORD *)(v7 + 12) + 12);
  if ( v8 < *(_BYTE *)(v7 + 8) )
    *(_BYTE *)(v7 + 8) = v8;
  if ( v11 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 412810: using guessed type char *off_412810;
// 41286C: using guessed type char *off_41286C;

//----- (004134E8) --------------------------------------------------------
int __cdecl sub_4134E8()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  System::TObject::Free(*(_DWORD *)(v0 + 16));
  System::TObject::Free(*(_DWORD *)(v3 + 12));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);

//----- (00413520) --------------------------------------------------------
char __userpurge sub_413520<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4)
{
  int v5; // edi@1
  unsigned __int8 v6; // bl@8
  unsigned int v7; // edi@19
  unsigned __int8 v8; // bl@22
  int v9; // esi@22
  int v10; // ST04_4@27
  int v11; // eax@27
  int v13; // [sp+0h] [bp-ACh]@0
  int v14; // [sp+0h] [bp-ACh]@14
  char v15[128]; // [sp+Ch] [bp-A0h]@15
  int v16; // [sp+8Ch] [bp-20h]@19
  int v17; // [sp+90h] [bp-1Ch]@19
  int v18; // [sp+94h] [bp-18h]@3
  int v19; // [sp+98h] [bp-14h]@9
  int v20; // [sp+9Ch] [bp-10h]@5
  char v21; // [sp+A3h] [bp-9h]@3
  int v22; // [sp+A4h] [bp-8h]@1
  int v23; // [sp+A8h] [bp-4h]@1

  v5 = ecx0;
  v22 = a2;
  v23 = a1;
  if ( a3 > *(_DWORD *)(a1 + 4) )
    System::__linkproc___Assert(&str_Assertion_failu_5[1], &str_D__VocComp_Win__11[1]);
  v21 = 0;
  if ( sub_408814(v22, 1, (int)&v18) )
  {
    if ( v18 )
    {
      sub_412B84(*(_DWORD *)(v23 + 16), a3, *(_BYTE *)(v23 + 8), -1, v13);
      v18 = *(_DWORD *)(*(_DWORD *)(v23 + 16) + 24);
      if ( v18 > 1 && sub_4133F0(v22, v18, (int)v15) && sub_408814(v22, 5, (int)&v19) && v19 >= 0 && v19 <= 28 )
      {
        v17 = sub_413440(v19);
        v16 = v5;
        v7 = 0;
        if ( v18 <= 0 )
        {
LABEL_29:
          v21 = 1;
        }
        else
        {
          while ( 1 )
          {
            if ( v7 > 0x7F )
              sub_402CA8();
            v8 = v15[v7];
            v9 = 0;
            do
            {
              v9 += sub_412C48(*(_DWORD *)(v23 + 16), v7++);
              if ( v7 == v18 )
                break;
              if ( v7 > 0x7F )
                sub_402CA8();
            }
            while ( v8 == v15[v7] );
            v10 = v16;
            v11 = sub_413120(v17, v8);
            if ( !sub_413140(v8, v11, v22, v9, v10, v14) )
              break;
            v16 += 4 * v9;
            if ( (signed int)v7 >= v18 )
              goto LABEL_29;
          }
        }
      }
    }
    else
    {
      if ( sub_408814(v22, 6, (int)&v20) )
      {
        if ( v20 >= 0 )
        {
          if ( v20 <= 50 )
          {
            v6 = v20;
            if ( !(_BYTE)v20 || sub_408814(v22, 5, (int)&v19) && v19 > 0 && v19 >= 0 && v19 <= 28 )
              v21 = sub_413140(v6, v19, v22, a3, v5, v13);
          }
        }
      }
    }
  }
  return v21;
}
// 4136F8: using guessed type _strings str_D__VocComp_Win__11[6];
// 41372C: using guessed type _strings str_Assertion_failu_5[3];
// 413520: using guessed type char var_A0[128];

//----- (00413749) --------------------------------------------------------
int __cdecl sub_413749(int a1, int a2, int a3, int a4, int a5)
{
  unsigned int v5; // eax@1
  signed int v6; // eax@1
  int result; // eax@1
  int v8; // edi@1
  int v9; // ecx@3
  int v10; // ecx@4
  unsigned int v11; // ebx@4
  int v12; // esi@5
  int v13; // edx@6
  int v14; // edx@7
  int v15; // edx@13
  int v16; // edx@14
  int v17; // esi@14
  int v18; // edx@15
  int v19; // ST04_4@16
  int v20; // ebx@18
  int v21; // esi@22
  int v22; // edx@22
  int v23; // edi@23
  int v30; // [sp-8h] [bp-38h]@21
  int v31; // [sp-4h] [bp-34h]@21
  int v32; // [sp+0h] [bp-30h]@1
  unsigned int v33; // [sp+4h] [bp-2Ch]@1
  signed int v34; // [sp+8h] [bp-28h]@1
  int v35; // [sp+Ch] [bp-24h]@1
  int v36; // [sp+10h] [bp-20h]@1
  int v37; // [sp+14h] [bp-1Ch]@1
  int v38; // [sp+18h] [bp-18h]@1
  int v39; // [sp+1Ch] [bp-14h]@1
  int v40; // [sp+40h] [bp+10h]@1

  v32 = *(_DWORD *)a1;
  v5 = *(_DWORD *)(a1 + 8);
  v33 = v5;
  v35 = (v5 >> 1) - v5;
  v6 = *(_DWORD *)(a1 + 4);
  v34 = v6;
  v36 = (*(_DWORD *)(a1 + 12) >> 1) - v6;
  v38 = (*(_DWORD *)(a1 + 20) >> 1) - v6;
  v37 = *(_DWORD *)(a1 + 16) >> 1;
  v39 = a2 - 10;
  result = a4 + 4 * a5;
  v40 = a4 + 4 * a5;
  v8 = -a5;
  if ( a5 )
  {
    do
    {
      while ( 1 )
      {
        result = a3;
        if ( v32 > *(_DWORD *)(a3 + 36) )
        {
          v11 = sub_408518(a3, v32);
          result = a3;
        }
        else
        {
          v9 = *(_DWORD *)(a3 + 40);
          *(_DWORD *)(a3 + 36) -= v32;
          if ( v32 > v9 )
          {
            v12 = 32 - v32;
            if ( v9 )
            {
              *(_DWORD *)(a3 + 40) = v9 + v12;
              v13 = *(_DWORD *)(a3 + 24) + 4;
              *(_DWORD *)(a3 + 24) = v13;
              v11 = (*(_DWORD *)v13 << (v9 + v12) >> v12) | (*(_DWORD *)(v13 - 4) >> (32 - v9));
            }
            else
            {
              *(_DWORD *)(a3 + 40) = v12;
              v14 = *(_DWORD *)(a3 + 24) + 4;
              *(_DWORD *)(a3 + 24) = v14;
              v11 = (0xFFFFFFFFu >> v12) & *(_DWORD *)v14;
            }
          }
          else
          {
            v10 = v9 - v32;
            *(_DWORD *)(a3 + 40) = v10;
            v11 = **(_DWORD **)(a3 + 24) << v10 >> (32 - v32);
          }
        }
        if ( (signed int)v11 >= (signed int)v33 )
          break;
        *(_DWORD *)(v40 + 4 * v8++) = (v11 >> 1) ^ -(v11 & 1);
        if ( v8 >= 0 )
          return result;
      }
      if ( *(_DWORD *)(result + 36) )
      {
        v15 = *(_DWORD *)(result + 40);
        --*(_DWORD *)(result + 36);
        if ( v15 )
        {
          v16 = v15 - 1;
          *(_DWORD *)(result + 40) = v16;
          v17 = (**(_DWORD **)(result + 24) >> (31 - v16)) & 1;
        }
        else
        {
          *(_DWORD *)(result + 40) = 31;
          v18 = *(_DWORD *)(result + 24) + 4;
          *(_DWORD *)(result + 24) = v18;
          v17 = *(_DWORD *)v18 & 1;
        }
      }
      else
      {
        v19 = result;
        v17 = sub_408704(result);
        result = v19;
      }
      if ( (signed int)v11 >= v34 )
      {
        v31 = v8;
        v30 = v17;
        if ( *(_DWORD *)(result + 36) < 9 )
        {
          _EDX = sub_408758(result, 9);
        }
        else
        {
          v21 = *(_DWORD *)(result + 40);
          v22 = *(_DWORD *)(result + 24);
          if ( v21 )
          {
            v23 = *(_DWORD *)v22 >> (32 - v21);
            if ( v21 < 9 )
              v23 |= *(_DWORD *)(v22 + 4) << v21;
          }
          else
          {
            v23 = *(_DWORD *)(v22 + 4);
          }
          _EDI = v23 | 0x200;
          __asm { bsf     edx, edi }
          if ( v21 < ((unsigned int)_EDX < 9) + _EDX )
          {
            *(_DWORD *)(result + 24) += 4;
            v21 += 32;
          }
          *(_DWORD *)(result + 40) = (__PAIR__(v21, _EDX) - __PAIR__(_EDX, 9)) >> 32;
          *(_DWORD *)(result + 36) = (__PAIR__(*(_DWORD *)(result + 36), _EDX) - __PAIR__(_EDX, 9)) >> 32;
        }
        v17 = v30;
        v8 = v31;
        if ( (unsigned int)_EDX >= 9 )
        {
          v20 = v38 + v11;
          if ( v39 > 0 )
            v20 += v37 * sub_40864C(a3, v39);
        }
        else
        {
          v20 = v37 * _EDX + v36 + v11;
        }
      }
      else
      {
        v20 = v35 + v11;
      }
      result = -(v17 != 0);
      *(_DWORD *)(v40 + 4 * v8++) = result ^ v20;
    }
    while ( v8 < 0 );
  }
  return result;
}

//----- (0041395C) --------------------------------------------------------
int __cdecl sub_41395C()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8E0;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8E0: using guessed type int dword_41A8E0;

//----- (0041398C) --------------------------------------------------------
void __cdecl sub_41398C()
{
  --dword_41A8E0;
}
// 41A8E0: using guessed type int dword_41A8E0;

//----- (00413994) --------------------------------------------------------
char __fastcall sub_413994(int a1, int a2)
{
  int v2; // esi@1
  signed int v3; // ecx@2
  signed int v5; // [sp+0h] [bp-10h]@1

  v5 = abs(*(_DWORD *)a1);
  v2 = a2 - 1;
  if ( a2 - 1 > 0 )
  {
    v3 = 1;
    do
    {
      if ( (unsigned int)(v3 - 1) > 0xFF )
        sub_402CA8();
      if ( (unsigned int)v3 > 0xFF )
        sub_402CA8();
      *(_DWORD *)(a1 + 4 * v3) -= *(_DWORD *)(a1 + 4 * (v3 - 1));
      if ( (unsigned int)v3 > 0xFF )
        sub_402CA8();
      v5 |= abs(*(_DWORD *)(a1 + 4 * v3++));
      --v2;
    }
    while ( v2 );
  }
  return v5 <= 8191;
}

//----- (00413A04) --------------------------------------------------------
int __fastcall sub_413A04(int a1, int a2)
{
  int v2; // ebx@1
  int result; // eax@1
  signed int v4; // [sp+0h] [bp-8h]@0

  v2 = a1;
  *(_DWORD *)(a1 + 4) = 0;
  *(_DWORD *)a1 = a2;
  *(_DWORD *)(a1 + 8) = 0;
  result = sub_409664((int)off_4095DC, 1, 4 * a2, a1 + 16, 64, v4);
  *(_DWORD *)(v2 + 4) = result;
  return result;
}
// 4095DC: using guessed type char *off_4095DC;

//----- (00413A40) --------------------------------------------------------
int __userpurge sub_413A40<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // esi@1
  int v7; // eax@1
  int result; // eax@1

  v6 = ecx0;
  sub_413C98(a1, a3 + 64, a2);
  *(_DWORD *)a3 = 0x200u >> v6;
  *(_DWORD *)(a3 + 4) = 0x200u >> v6;
  *(_DWORD *)(a3 + 8) = a4;
  *(_DWORD *)(a3 + 12) = 0;
  *(_WORD *)(a3 + 16) = -8192;
  *(_WORD *)(a3 + 18) = -8192;
  *(_DWORD *)(a3 + 20) = *(_DWORD *)(a3 + 16);
  v7 = (1 << a4) - 1;
  *(_DWORD *)(a3 + 24) = v7;
  *(_DWORD *)(a3 + 28) = v7;
  *(_DWORD *)(a3 + 32) = 10 - v6;
  result = 0;
  *(_DWORD *)(a3 + 36) = 0;
  return result;
}

//----- (00413AB8) --------------------------------------------------------
char __fastcall sub_413AB8(int a1, int a2)
{
  int v2; // ebp@1
  int v3; // edi@3
  char result; // al@4
  unsigned int v5; // esi@5
  signed int v6; // ebx@6
  unsigned int v7; // eax@7
  int v8; // [sp+0h] [bp-1Ch]@1
  unsigned int v9; // [sp+4h] [bp-18h]@1
  int v10; // [sp+8h] [bp-14h]@2

  v8 = a2;
  v2 = a1;
  v9 = 0;
  if ( *(_DWORD *)(a2 + 8) / 4 - 1 < 0 )
  {
LABEL_11:
    result = *(_BYTE *)(v2 + 44) ^ 1;
  }
  else
  {
    v10 = *(_DWORD *)(a2 + 8) / 4;
    while ( 1 )
    {
      v3 = sub_40864C(v2, 4);
      if ( v3 < 1 )
        break;
      v5 = v9;
      if ( !__OFSUB__(v9 + 3, v9) )
      {
        v6 = 4;
        do
        {
          v7 = sub_4086E0(v2, v3);
          if ( v5 > 0xFF )
            sub_402CA8();
          *(_DWORD *)(*(_DWORD *)(v8 + 16) + 4 * v5++) = v7;
          --v6;
        }
        while ( v6 );
      }
      v9 += 4;
      --v10;
      if ( !v10 )
        goto LABEL_11;
    }
    result = 0;
  }
  return result;
}

//----- (00413B48) --------------------------------------------------------
char __fastcall sub_413B48(int a1, int a2)
{
  int v2; // ebp@1
  unsigned int v3; // eax@5
  int v4; // edi@5
  unsigned int v5; // esi@6
  signed int v6; // ebx@7
  unsigned int v7; // eax@8
  int v9; // [sp+0h] [bp-28h]@1
  char v10; // [sp+4h] [bp-24h]@1
  int v11; // [sp+8h] [bp-20h]@1
  unsigned int v12; // [sp+Ch] [bp-1Ch]@3
  int v13; // [sp+10h] [bp-18h]@2
  int v14; // [sp+14h] [bp-14h]@4

  v9 = a2;
  v2 = a1;
  v10 = 0;
  if ( sub_408814(a1, 4, (int)&v11) && sub_408814(v2, 1, (int)&v13) )
  {
    v13 += 2;
    v12 = 0;
    if ( *(_DWORD *)(v9 + 8) / 4 - 1 < 0 )
    {
LABEL_12:
      v10 = *(_BYTE *)(v2 + 44) ^ 1;
    }
    else
    {
      v14 = *(_DWORD *)(v9 + 8) / 4;
      while ( 1 )
      {
        v3 = sub_40864C(v2, v13);
        v4 = v11 - v3;
        if ( (signed int)(v11 - v3) < 1 )
          break;
        v5 = v12;
        if ( !__OFSUB__(v12 + 3, v12) )
        {
          v6 = 4;
          do
          {
            v7 = sub_4086E0(v2, v4);
            if ( v5 > 0xFF )
              sub_402CA8();
            *(_DWORD *)(*(_DWORD *)(v9 + 16) + 4 * v5++) = v7;
            --v6;
          }
          while ( v6 );
        }
        v12 += 4;
        --v14;
        if ( !v14 )
          goto LABEL_12;
      }
    }
  }
  return v10;
}

//----- (00413C18) --------------------------------------------------------
int __usercall sub_413C18<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // edi@1
  int v5; // ebx@1
  int v6; // eax@8
  int v7; // eax@9
  int v9; // [sp+0h] [bp-10h]@1

  v9 = ecx0;
  v3 = a2;
  v4 = a1;
  v5 = 0;
  if ( sub_408814(a1, 3, a2 + 12) && *(_DWORD *)(v3 + 12) <= 7 )
  {
    if ( *(_DWORD *)(v3 + 8) < 12 )
    {
      v9 = 0;
    }
    else
    {
      if ( !sub_408854(v4, (int)&v9) )
        return v5;
    }
    if ( *(_DWORD *)(v3 + 8) > 16 )
    {
      LOBYTE(v7) = sub_413B48(v4, v3);
      v5 = v7;
    }
    else
    {
      LOBYTE(v6) = sub_413AB8(v4, v3);
      v5 = v6;
    }
    if ( (_BYTE)v5 && v9 && !sub_413994(*(_DWORD *)(v3 + 16), *(_DWORD *)(v3 + 8)) )
      v5 = 0;
  }
  return v5;
}

//----- (00413C98) --------------------------------------------------------
int __usercall sub_413C98<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  __m64 v3; // mm0@1
  __m64 v4; // mm1@1
  __m64 v5; // mm1@1
  int result; // eax@1
  int v7; // edx@1
  int i; // ecx@1
  __m64 v9; // mm1@2
  __m64 v10; // mm3@2
  __m64 v11; // mm3@2
  __m64 v12; // mm0@3
  __m64 v13; // mm0@3

  v3 = _m_packssdw(*(__m64 *)a1, *(__m64 *)(a1 + 8));
  *(_QWORD *)a2 = v3;
  v4 = _m_psllq(v3, 0x10u);
  *(_QWORD *)(a2 + 8) = v4;
  v5 = _m_psllq(v4, 0x10u);
  *(_QWORD *)(a2 + 16) = v5;
  *(_QWORD *)(a2 + 24) = _m_psllq(v5, 0x10u);
  result = a1 + 16;
  v7 = a2 + 32;
  for ( i = ecx0 - 4; i; i -= 4 )
  {
    v9 = _m_packssdw(*(__m64 *)result, *(__m64 *)(result + 8));
    *(_QWORD *)v7 = v9;
    v10 = _m_psllq(v9, 0x10u);
    *(_QWORD *)(v7 + 8) = _m_por(_m_psrlq(v3, 0x30u), v10);
    v11 = _m_psllq(v10, 0x10u);
    *(_QWORD *)(v7 + 16) = _m_por(_m_psrlq(v3, 0x20u), v11);
    *(_QWORD *)(v7 + 24) = _m_por(_m_psrlq(v3, 0x10u), _m_psllq(v11, 0x10u));
    v3 = v9;
    result += 16;
    v7 += 32;
  }
  v12 = _m_psrlq(v3, 0x10u);
  *(_QWORD *)(v7 + 24) = v12;
  v13 = _m_psrlq(v12, 0x10u);
  *(_QWORD *)(v7 + 16) = v13;
  *(_QWORD *)(v7 + 8) = _m_psrlq(v13, 0x10u);
  _m_femms();
  return result;
}

//----- (00413D34) --------------------------------------------------------
int __cdecl sub_413D34()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8E4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8E4: using guessed type int dword_41A8E4;

//----- (00413D64) --------------------------------------------------------
void __cdecl sub_413D64()
{
  --dword_41A8E4;
}
// 41A8E4: using guessed type int dword_41A8E4;

//----- (00413D6C) --------------------------------------------------------
int __userpurge sub_413D6C<eax>(int a1<eax>, signed int a2<edx>, char cl0<cl>, char a3, int a4, int a5, unsigned int a6, int a7)
{
  signed int v8; // kr00_4@1
  int result; // eax@1
  int v10; // edx@3
  int v11; // ecx@3
  unsigned int v12; // ebx@3
  int v13; // eax@5
  int v14; // esi@7
  unsigned int v15; // ebx@7
  unsigned int v16; // eax@9
  int v17; // [sp+8h] [bp-20h]@2
  int v18; // [sp+Ch] [bp-1Ch]@1
  unsigned int v19; // [sp+10h] [bp-18h]@1
  char v20; // [sp+1Bh] [bp-Dh]@1
  signed int v21; // [sp+1Ch] [bp-Ch]@1
  char v22; // [sp+20h] [bp-8h]@1
  int v23; // [sp+24h] [bp-4h]@1

  v23 = a1;
  v22 = 10 - cl0;
  v21 = 1 << (10 - cl0 - 1);
  v20 = (a2 & 4) != 0;
  v8 = a2;
  v19 = a6;
  v18 = a4;
  result = a5;
  if ( a5 > 0 )
  {
    v17 = a5;
    do
    {
      v10 = v18;
      v11 = v23;
      v12 = 0;
      if ( v20 )
      {
        v12 = *(_DWORD *)(v23 + 12) * *(_DWORD *)(v18 + 12)
            + *(_DWORD *)(v23 + 8) * *(_DWORD *)(v18 + 8)
            + *(_DWORD *)(v23 + 4) * *(_DWORD *)(v18 + 4)
            + *(_DWORD *)v23 * *(_DWORD *)v18;
        v10 = v18 + 16;
        v11 = v23 + 16;
      }
      v13 = v8 / 8;
      if ( v8 / 8 > 0 )
      {
        do
        {
          v12 += *(_DWORD *)(v11 + 28) * *(_DWORD *)(v10 + 28)
               + *(_DWORD *)(v11 + 24) * *(_DWORD *)(v10 + 24)
               + *(_DWORD *)(v11 + 20) * *(_DWORD *)(v10 + 20)
               + *(_DWORD *)(v11 + 16) * *(_DWORD *)(v10 + 16)
               + *(_DWORD *)(v11 + 12) * *(_DWORD *)(v10 + 12)
               + *(_DWORD *)(v11 + 8) * *(_DWORD *)(v10 + 8)
               + *(_DWORD *)(v11 + 4) * *(_DWORD *)(v10 + 4)
               + *(_DWORD *)v11 * *(_DWORD *)v10;
          v10 += 32;
          v11 += 32;
          --v13;
        }
        while ( v13 );
      }
      v14 = -(v12 >> 31);
      v15 = (v21 + (v14 ^ (v12 - (v12 >> 31)))) >> v22;
      if ( (signed int)v15 > 8191 )
        v15 = 8191;
      v16 = (((v14 ^ v15) - v14) << a3) - *(_DWORD *)v19;
      *(_DWORD *)v19 = v16;
      result = (-(v16 >> 31) ^ ((-(v16 >> 31) ^ (v16 - (v16 >> 31))) >> a3)) + (v16 >> 31);
      *(_DWORD *)v10 = result;
      v19 += 4;
      v18 += 4;
      --v17;
    }
    while ( v17 );
  }
  return result;
}

//----- (00413EB0) --------------------------------------------------------
int __usercall sub_413EB0<eax>(int a1<eax>, int a2<ecx>)
{
  int v2; // ebx@1
  int result; // eax@1
  int v4; // ebp@1
  int v5; // esi@1
  int v6; // edi@3
  int v7; // [sp+0h] [bp-14h]@1

  v2 = a1;
  sub_4126D8(*(_DWORD *)(a1 + 8), *(_DWORD *)(a1 + 20), *(_DWORD *)(a1 + 16), *(_DWORD *)(a1 + 4), a2);
  result = *(_DWORD *)(v2 + 16);
  v7 = *(_DWORD *)(v2 + 8) + 4 * result;
  v4 = 544 - result;
  v5 = *(_DWORD *)(v2 + 12) - result;
  while ( v5 > 0 )
  {
    if ( v4 >= v5 )
      v6 = v5;
    else
      v6 = v4;
    result = sub_413D6C(
               *(_DWORD *)(*(_DWORD *)v2 + 16),
               *(_DWORD *)(v2 + 16),
               *(_DWORD *)(*(_DWORD *)v2 + 12),
               *(_DWORD *)(v2 + 4),
               *(_DWORD *)(v2 + 20),
               v6,
               v7,
               v7);
    v5 -= v6;
    if ( v5 > 0 )
    {
      System::Move(*(_DWORD *)(v2 + 20) + 4 * v4, *(_DWORD *)(v2 + 20));
      result = 4 * v6;
      v7 += 4 * v6;
    }
  }
  return result;
}

//----- (00413F38) --------------------------------------------------------
int __usercall sub_413F38<eax>(int a1<eax>, int a2<ecx>)
{
  int v2; // ebx@1
  unsigned int v3; // ST14_4@1
  signed int v4; // eax@1
  int v5; // ebp@1
  int v6; // esi@1
  int result; // eax@2
  int v8; // esi@3
  unsigned int v9; // edi@5
  int v10; // [sp+0h] [bp-14h]@3

  v2 = a1;
  sub_413A40(
    *(_DWORD *)(*(_DWORD *)a1 + 16),
    *(_DWORD *)(a1 + 16),
    *(_DWORD *)(*(_DWORD *)a1 + 12),
    *(_DWORD *)(a1 + 20) + 2176,
    *(_DWORD *)(a1 + 4),
    a2);
  sub_412725(*(_DWORD *)(v2 + 8), *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 16), *(_DWORD *)(v2 + 4), v3);
  v4 = *(_DWORD *)(v2 + 16);
  v5 = *(_DWORD *)(v2 + 8) + 4 * v4;
  v6 = *(_DWORD *)(v2 + 12) - v4;
  if ( v4 > 12 )
  {
    v8 = (v6 + 3) & 0xFFFFFFFC;
    result = (544 - *(_DWORD *)(v2 + 16)) & 0xFFFFFFFC;
    v10 = (544 - *(_DWORD *)(v2 + 16)) & 0xFFFFFFFC;
    while ( v8 > 0 )
    {
      if ( v8 <= v10 )
        v9 = v8;
      else
        v9 = v10;
      sub_414234(v5, v9, *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 20) + 2176, *(_DWORD *)(v2 + 16));
      v8 -= v9;
      if ( v8 > 0 )
      {
        System::Move(*(_DWORD *)(v2 + 20) + 2 * v9, *(_DWORD *)(v2 + 20));
        result = 4 * v9;
        v5 += 4 * v9;
      }
    }
  }
  else
  {
    result = sub_414078(v5, v6, *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 20) + 2176, *(_DWORD *)(v2 + 16));
  }
  return result;
}

//----- (00414004) --------------------------------------------------------
int __usercall sub_414004<eax>(int a1<eax>, int a2<edx>, int a3<ecx>)
{
  int result; // eax@2

  if ( *(_BYTE *)a1 & 2 )
    result = sub_413F38(a2, a3);
  else
    result = sub_413EB0(a2, a3);
  return result;
}

//----- (0041401C) --------------------------------------------------------
signed int __usercall sub_41401C<eax>(__int64 a1<edx:eax>, int a2<ebp>, int a3<esi>)
{
  __int64 v3; // qax@1
  int v4; // ecx@1
  unsigned int v5; // eax@3

  a1 = (signed int)a1;
  LODWORD(v3) = (unsigned int)(*(_DWORD *)a2 + abs(a1)) >> *(_DWORD *)(a2 + 32);
  v4 = *(_DWORD *)(a2 + 8);
  if ( (unsigned int)v3 > 0x1FFF )
    LODWORD(v3) = 8191;
  v5 = (((HIDWORD(v3) ^ (unsigned int)v3) - HIDWORD(v3)) << v4) - *(_DWORD *)a3;
  *(_DWORD *)a3 = v5;
  return (signed int)((*(_DWORD *)(a2 + 24) & ((unsigned __int64)(signed int)v5 >> 32)) + v5) >> v4;
}

//----- (00414050) --------------------------------------------------------
int __usercall sub_414050<eax>(__int64 a1<edx:eax>, int a2<ebp>, int a3<esi>)
{
  __int64 v3; // qax@1
  int result; // eax@3

  a1 = (signed int)a1;
  LODWORD(v3) = (unsigned int)(*(_DWORD *)a2 + abs(a1)) >> *(_DWORD *)(a2 + 32);
  if ( (unsigned int)v3 > 0x1FFF )
    LODWORD(v3) = 8191;
  result = (HIDWORD(v3) ^ v3) - HIDWORD(v3) - *(_DWORD *)a3;
  *(_DWORD *)a3 = result;
  return result;
}

//----- (00414078) --------------------------------------------------------
signed int __cdecl sub_414078(int a1, int a2, int a3, int a4, int a5)
{
  int v5; // ebx@1
  int v6; // edx@1
  __m64 v7; // mm0@1
  int v8; // esi@2
  int v9; // ebx@2
  __m64 v10; // mm1@2
  __m64 v11; // mm2@3
  __m64 v12; // mm0@3
  __m64 v13; // mm2@3
  __int64 v14; // qax@3
  signed int result; // eax@5
  __m64 v16; // mm2@7
  __m64 v17; // mm0@7
  __m64 v18; // mm2@7
  __int64 v19; // qax@7
  int v20; // ecx@7
  unsigned int v21; // eax@9
  __m64 v22; // mm1@11
  int (__usercall *v23)<eax>(__int64<edx:eax>, int<ebp>, int<esi>); // edi@11
  __m64 v24; // mm2@14
  __m64 v25; // mm3@14
  __m64 v26; // mm4@14
  __m64 v27; // mm5@14
  __m64 v28; // mm4@15
  __m64 v29; // mm4@15
  __int64 v30; // qax@15
  __m64 v31; // mm2@17
  __m64 v32; // mm3@17
  __m64 v33; // mm4@17
  __m64 v34; // mm5@17
  __m64 v35; // mm3@18
  __int64 v36; // qax@18

  v5 = a2;
  v6 = *(_DWORD *)(a4 + 8);
  v7 = *(__m64 *)a3;
  if ( a5 == 4 )
  {
    v8 = a1 + 4 * a2;
    v9 = -a2;
    v10 = *(__m64 *)(a4 + 64);
    if ( v6 )
    {
      do
      {
        v16 = v7;
        v17 = _m_pmaddwd(v7, v10);
        v18 = _m_psrlq(v16, 0x10u);
        v19 = _mm_cvtsi64_si32(_m_psrlq(v17, 0x20u)) + _mm_cvtsi64_si32(v17);
        LODWORD(v19) = (*(_DWORD *)a4 + (HIDWORD(v19) ^ (unsigned int)v19) - HIDWORD(v19)) >> *(_DWORD *)(a4 + 32);
        v20 = *(_DWORD *)(a4 + 8);
        if ( (unsigned int)v19 > 0x1FFF )
          LODWORD(v19) = 8191;
        v21 = (((HIDWORD(v19) ^ (unsigned int)v19) - HIDWORD(v19)) << v20) - *(_DWORD *)(v8 + 4 * v9);
        *(_DWORD *)(v8 + 4 * v9) = v21;
        result = (signed int)((*(_DWORD *)(a4 + 24) & ((unsigned __int64)(signed int)v21 >> 32)) + v21) >> v20;
        v7 = _m_por(_m_psllq(_mm_cvtsi32_si64(result), 0x30u), v18);
        ++v9;
      }
      while ( v9 < 0 );
    }
    else
    {
      do
      {
        v11 = v7;
        v12 = _m_pmaddwd(v7, v10);
        v13 = _m_psrlq(v11, 0x10u);
        v14 = _mm_cvtsi64_si32(_m_psrlq(v12, 0x20u)) + _mm_cvtsi64_si32(v12);
        LODWORD(v14) = (*(_DWORD *)a4 + (HIDWORD(v14) ^ (unsigned int)v14) - HIDWORD(v14)) >> *(_DWORD *)(a4 + 32);
        if ( (unsigned int)v14 > 0x1FFF )
          LODWORD(v14) = 8191;
        result = (HIDWORD(v14) ^ v14) - HIDWORD(v14) - *(_DWORD *)(v8 + 4 * v9);
        *(_DWORD *)(v8 + 4 * v9) = result;
        v7 = _m_por(_m_psllq(_mm_cvtsi32_si64(result), 0x30u), v13);
        ++v9;
      }
      while ( v9 < 0 );
    }
  }
  else
  {
    v22 = *(__m64 *)(a3 + 8);
    v23 = sub_414050;
    if ( v6 )
      v23 = sub_41401C;
    if ( a5 == 8 )
    {
      v24 = *(__m64 *)(a4 + 64);
      v25 = *(__m64 *)(a4 + 96);
      v26 = *(__m64 *)(a4 + 64);
      v27 = *(__m64 *)(a4 + 96);
      do
      {
        v28 = _m_pmaddwd(v26, v7);
        v7 = _m_por(_m_psrlq(v7, 0x10u), _m_psllq(v22, 0x30u));
        v29 = _m_paddd(v28, _m_pmaddwd(v27, v22));
        v27 = v25;
        v30 = __PAIR__(_mm_cvtsi64_si32(_m_psrlq(v29, 0x20u)), _mm_cvtsi64_si32(v29));
        v26 = v24;
        LODWORD(v30) = HIDWORD(v30) + v30;
        result = v23(v30, a4, a1);
        v22 = _m_por(_m_psrlq(v22, 0x10u), _m_psllq(_mm_cvtsi32_si64(result), 0x30u));
        --v5;
      }
      while ( v5 );
    }
    else
    {
      v31 = *(__m64 *)(a3 + 16);
      v32 = *(__m64 *)(a4 + 64);
      v33 = *(__m64 *)(a4 + 96);
      v34 = *(__m64 *)(a4 + 128);
      do
      {
        v35 = _m_paddd(_m_paddd(_m_pmaddwd(v32, v7), _m_pmaddwd(v33, v22)), _m_pmaddwd(v34, v31));
        v7 = _m_por(_m_psrlq(v7, 0x10u), _m_psllq(v22, 0x30u));
        v22 = _m_por(_m_psrlq(v22, 0x10u), _m_psllq(v31, 0x30u));
        HIDWORD(v36) = _mm_cvtsi64_si32(_m_psrlq(v35, 0x20u));
        LODWORD(v36) = HIDWORD(v36) + _mm_cvtsi64_si32(v35);
        v32 = *(__m64 *)(a4 + 64);
        v33 = *(__m64 *)(a4 + 96);
        v34 = *(__m64 *)(a4 + 128);
        result = v23(v36, a4, a1);
        v31 = _m_por(_m_psrlq(v31, 0x10u), _m_psllq(_mm_cvtsi32_si64(result), 0x30u));
        --v5;
      }
      while ( v5 );
    }
  }
  _m_femms();
  return result;
}

//----- (00414234) --------------------------------------------------------
void __cdecl sub_414234(int a1, unsigned int a2, int a3, int a4, int a5)
{
  void *v5; // edx@1
  int (__usercall *v6)<eax>(__int64<edx:eax>, int<ebp>, int<esi>); // eax@5

  *(_DWORD *)(a4 + 40) = a2 >> 2;
  v5 = sub_4143AC;
  if ( a5 != 16 )
  {
    if ( a5 == 24 )
    {
      v5 = sub_41434C;
      *(_DWORD *)(a4 + 44) = 1;
    }
    else
    {
      v5 = sub_4142F5;
      *(_DWORD *)(a4 + 44) = (unsigned int)(a5 - 16) >> 4;
    }
  }
  *(_DWORD *)(a4 + 52) = v5;
  *(_DWORD *)(a4 + 48) = 2 * a5;
  v6 = sub_414050;
  if ( *(_DWORD *)(a4 + 8) )
    v6 = sub_41401C;
  *(_DWORD *)(a4 + 56) = v6;
  JUMPOUT(__CS__, *(_DWORD *)(a4 + 52));
}
// 4143AC: using guessed type int sub_4143AC();

//----- (004142F5) --------------------------------------------------------
void __cdecl sub_4142F5()
{
  JUMPOUT(*(int *)sub_41434C);
}

//----- (0041434C) --------------------------------------------------------
void __fastcall sub_41434C(int a1, int a2)
{
  JUMPOUT(a2 - 1, 0, sub_4142F5);
  JUMPOUT(*(int *)sub_4143AC);
}
// 4143AC: using guessed type int sub_4143AC();

//----- (004143AC) --------------------------------------------------------
#error "FFFFFFFF: positive sp value has been found (funcsize=0)"

//----- (004144A8) --------------------------------------------------------
int __cdecl sub_4144A8()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8E8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8E8: using guessed type int dword_41A8E8;

//----- (004144D8) --------------------------------------------------------
void __cdecl sub_4144D8()
{
  --dword_41A8E8;
}
// 41A8E8: using guessed type int dword_41A8E8;

//----- (004144E0) --------------------------------------------------------
char __fastcall sub_4144E0(int a1, int a2)
{
  int v2; // ebx@1
  int v3; // edi@3
  signed int v4; // esi@4
  int v6; // [sp+0h] [bp-18h]@1
  char v7; // [sp+4h] [bp-14h]@1

  v2 = a2;
  v6 = a1;
  v7 = 0;
  if ( sub_408814(a1, 3, a2) && *(_DWORD *)v2 < 5 )
  {
    ++*(_DWORD *)v2;
    *(_DWORD *)(v2 + 4) = 0;
    v3 = *(_DWORD *)v2 - 1;
    if ( *(_DWORD *)v2 - 1 <= 0 )
    {
LABEL_14:
      v7 = 1;
    }
    else
    {
      v4 = 1;
      while ( 1 )
      {
        if ( (unsigned int)v4 > 5 )
          sub_402CA8();
        if ( !sub_408814(v6, 6, v2 + 8 * v4 + 4) )
          break;
        if ( (unsigned int)v4 > 5 )
          sub_402CA8();
        if ( (unsigned int)(v4 - 1) > 5 )
          sub_402CA8();
        if ( *(_DWORD *)(v2 + 8 * v4 + 4) <= *(_DWORD *)(v2 + 8 * (v4 - 1) + 4) )
          break;
        ++v4;
        --v3;
        if ( !v3 )
          goto LABEL_14;
      }
    }
  }
  return v7;
}

//----- (00414574) --------------------------------------------------------
int __cdecl sub_414574()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8EC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8EC: using guessed type int dword_41A8EC;

//----- (004145A4) --------------------------------------------------------
void __cdecl sub_4145A4()
{
  --dword_41A8EC;
}
// 41A8EC: using guessed type int dword_41A8EC;

//----- (00414610) --------------------------------------------------------
int __userpurge sub_414610<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int result; // eax@1

  *(_DWORD *)a4 = a1;
  result = a3;
  *(_DWORD *)a3 = ecx0 - *(_DWORD *)a4 - (a2 - 1);
  return result;
}

//----- (00414628) --------------------------------------------------------
int __fastcall sub_414628(int a1)
{
  return sub_413A04(a1 + 8, 8);
}

//----- (00414638) --------------------------------------------------------
int __fastcall sub_414638(int a1)
{
  return unknown_libname_111(a1 + 8);
}
// 413A34: using guessed type int __fastcall unknown_libname_111(_DWORD);

//----- (00414644) --------------------------------------------------------
char __fastcall sub_414644(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // ecx@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a2 + 16) = 8;
  *(_BYTE *)a2 = sub_408704(a1) != 0;
  *(_BYTE *)(v2 + 1) = sub_408704(v3) != 0;
  *(_DWORD *)(v2 + 4) = sub_40864C(v3, 4);
  return sub_40864C(v3, 2) == 1 && (unsigned __int8)sub_413C18(v3, v2 + 8, v4);
}

//----- (004146A4) --------------------------------------------------------
int __usercall sub_4146A4<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>)
{
  int v3; // ebx@2

  if ( ecx0 / 2 - 1 >= 0 )
  {
    v3 = ecx0 / 2;
    do
    {
      *(_DWORD *)a2 += *(_DWORD *)result;
      *(_DWORD *)(a2 + 4) += *(_DWORD *)(result + 4);
      result += 8;
      a2 += 8;
      --v3;
    }
    while ( v3 );
  }
  if ( ecx0 & 1 )
  {
    result = *(_DWORD *)result;
    *(_DWORD *)a2 += result;
  }
  return result;
}

//----- (004146D4) --------------------------------------------------------
int __usercall sub_4146D4<eax>(int result<eax>, int a2<edx>, signed int ecx0<ecx>)
{
  int v3; // ebx@2

  if ( ecx0 / 2 - 1 >= 0 )
  {
    v3 = ecx0 / 2;
    do
    {
      *(_DWORD *)a2 = *(_DWORD *)result - *(_DWORD *)a2;
      *(_DWORD *)(a2 + 4) = *(_DWORD *)(result + 4) - *(_DWORD *)(a2 + 4);
      result += 8;
      a2 += 8;
      --v3;
    }
    while ( v3 );
  }
  if ( ecx0 & 1 )
  {
    result = *(_DWORD *)result - *(_DWORD *)a2;
    *(_DWORD *)a2 = result;
  }
  return result;
}

//----- (0041470C) --------------------------------------------------------
int __usercall sub_41470C<eax>(int result<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ecx@1
  int v4; // ebx@3
  int v5; // esi@3
  int v6; // [sp+0h] [bp-10h]@2

  v3 = ecx0 - 1;
  if ( v3 >= 0 )
  {
    v6 = v3 + 1;
    do
    {
      v4 = *(_DWORD *)a2;
      v5 = (*(_DWORD *)a2 & 1) + 2 * *(_DWORD *)result;
      *(_DWORD *)result = ((*(_DWORD *)a2 & 1) + 2 * *(_DWORD *)result - *(_DWORD *)a2) & 0x80000000 | (((*(_DWORD *)a2 & 1u) + 2 * *(_DWORD *)result - *(_DWORD *)a2) >> 1);
      *(_DWORD *)a2 = (v4 + v5) & 0x80000000 | ((unsigned int)(v4 + v5) >> 1);
      result += 4;
      a2 += 4;
      --v6;
    }
    while ( v6 );
  }
  return result;
}

//----- (0041475C) --------------------------------------------------------
int __usercall sub_41475C<eax>(int a1<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>)
{
  int v4; // ebx@1
  int v5; // edi@1
  int v6; // esi@1
  int v7; // edx@2

  v4 = a3;
  v5 = a2;
  v6 = a1;
  if ( a3 >= 16 )
  {
    sub_414D37(a1, a2, a3, a4);
    v7 = 4 * (v4 & 0xFFFFFFFC);
    v6 += v7;
    v5 += v7;
    v4 -= v4 & 0xFFFFFFFC;
  }
  return sub_41470C(v6, v5, v4);
}

//----- (00414794) --------------------------------------------------------
signed int __userpurge sub_414794<eax>(signed int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  signed int result; // eax@1
  signed int v7; // eax@3
  unsigned int v8; // ebx@3
  int v9; // [sp+8h] [bp-10h]@2
  signed int v10; // [sp+14h] [bp-4h]@1

  v10 = a1;
  result = 512;
  if ( ecx0 - 1 >= 0 )
  {
    v9 = ecx0;
    do
    {
      v7 = -((unsigned int)(*(_DWORD *)(a2 + 28) * *(_DWORD *)(a4 + 28)
                          + *(_DWORD *)(a2 + 24) * *(_DWORD *)(a4 + 24)
                          + *(_DWORD *)(a2 + 20) * *(_DWORD *)(a4 + 20)
                          + *(_DWORD *)(a2 + 16) * *(_DWORD *)(a4 + 16)
                          + *(_DWORD *)(a2 + 12) * *(_DWORD *)(a4 + 12)
                          + *(_DWORD *)(a2 + 8) * *(_DWORD *)(a4 + 8)
                          + *(_DWORD *)(a2 + 4) * *(_DWORD *)(a4 + 4)
                          + *(_DWORD *)a2 * *(_DWORD *)a4) >> 31);
      v8 = ((v7 ^ (*(_DWORD *)(a2 + 28) * *(_DWORD *)(a4 + 28)
                 + *(_DWORD *)(a2 + 24) * *(_DWORD *)(a4 + 24)
                 + *(_DWORD *)(a2 + 20) * *(_DWORD *)(a4 + 20)
                 + *(_DWORD *)(a2 + 16) * *(_DWORD *)(a4 + 16)
                 + *(_DWORD *)(a2 + 12) * *(_DWORD *)(a4 + 12)
                 + *(_DWORD *)(a2 + 8) * *(_DWORD *)(a4 + 8)
                 + *(_DWORD *)(a2 + 4) * *(_DWORD *)(a4 + 4)
                 + *(_DWORD *)a2 * *(_DWORD *)a4
                 - ((unsigned int)(*(_DWORD *)(a2 + 28) * *(_DWORD *)(a4 + 28)
                                 + *(_DWORD *)(a2 + 24) * *(_DWORD *)(a4 + 24)
                                 + *(_DWORD *)(a2 + 20) * *(_DWORD *)(a4 + 20)
                                 + *(_DWORD *)(a2 + 16) * *(_DWORD *)(a4 + 16)
                                 + *(_DWORD *)(a2 + 12) * *(_DWORD *)(a4 + 12)
                                 + *(_DWORD *)(a2 + 8) * *(_DWORD *)(a4 + 8)
                                 + *(_DWORD *)(a2 + 4) * *(_DWORD *)(a4 + 4)
                                 + *(_DWORD *)a2 * *(_DWORD *)a4) >> 31)))
          + 512) >> 10;
      if ( (signed int)v8 > 8191 )
        v8 = 8191;
      result = v10;
      *(_DWORD *)v10 = (((-((unsigned int)(*(_DWORD *)(a2 + 28) * *(_DWORD *)(a4 + 28)
                                         + *(_DWORD *)(a2 + 24) * *(_DWORD *)(a4 + 24)
                                         + *(_DWORD *)(a2 + 20) * *(_DWORD *)(a4 + 20)
                                         + *(_DWORD *)(a2 + 16) * *(_DWORD *)(a4 + 16)
                                         + *(_DWORD *)(a2 + 12) * *(_DWORD *)(a4 + 12)
                                         + *(_DWORD *)(a2 + 8) * *(_DWORD *)(a4 + 8)
                                         + *(_DWORD *)(a2 + 4) * *(_DWORD *)(a4 + 4)
                                         + *(_DWORD *)a2 * *(_DWORD *)a4) >> 31) ^ v8)
                       + ((unsigned int)(*(_DWORD *)(a2 + 28) * *(_DWORD *)(a4 + 28)
                                       + *(_DWORD *)(a2 + 24) * *(_DWORD *)(a4 + 24)
                                       + *(_DWORD *)(a2 + 20) * *(_DWORD *)(a4 + 20)
                                       + *(_DWORD *)(a2 + 16) * *(_DWORD *)(a4 + 16)
                                       + *(_DWORD *)(a2 + 12) * *(_DWORD *)(a4 + 12)
                                       + *(_DWORD *)(a2 + 8) * *(_DWORD *)(a4 + 8)
                                       + *(_DWORD *)(a2 + 4) * *(_DWORD *)(a4 + 4)
                                       + *(_DWORD *)a2 * *(_DWORD *)a4) >> 31)) << a3)
                     - *(_DWORD *)v10;
      v10 += 4;
      a2 += 4;
      --v9;
    }
    while ( v9 );
  }
  return result;
}

//----- (00414858) --------------------------------------------------------
int __userpurge sub_414858<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // ebx@1
  int result; // eax@1
  unsigned int v8; // eax@5
  int v9; // edx@7
  int v10; // eax@7
  int v11; // edx@12
  unsigned int v12; // eax@12
  int v13; // [sp+0h] [bp-1Ch]@0
  int v14; // [sp+0h] [bp-1Ch]@1
  int v16; // [sp+8h] [bp-14h]@3
  unsigned int i; // [sp+Ch] [bp-10h]@1
  int v18; // [sp+10h] [bp-Ch]@1
  int v19; // [sp+14h] [bp-8h]@1
  int v20; // [sp+18h] [bp-4h]@1

  v19 = ecx0;
  v20 = a2;
  v6 = a1;
  sub_4126D8(ecx0, *(_DWORD *)(a1 + 8), *(_DWORD *)(a2 + 16), *(_DWORD *)(a2 + 4), v13);
  v18 = 544 - *(_DWORD *)(v20 + 16);
  result = 0;
  for ( i = 0; a3 > 0; a3 -= v16 )
  {
    if ( a3 <= v18 )
      v16 = a3;
    else
      v16 = v18;
    v8 = *(_DWORD *)(v20 + 16);
    if ( v8 > 0x3FFF )
      sub_402CA8();
    v9 = *(_DWORD *)(v6 + 8) + 4 * v8;
    v10 = i + v8;
    if ( (unsigned int)v10 > 0x3FFF )
      sub_402CA8();
    sub_4126D8(v19 + 4 * v10, v9, v16, *(_DWORD *)(v20 + 4), v14);
    if ( i > 0x3FFF )
      sub_402CA8();
    sub_414794(a4 + 4 * i, *(_DWORD *)(v6 + 8), v16, *(_DWORD *)(v20 + 4), *(_DWORD *)(v20 + 24), v14);
    if ( *(_DWORD *)(v20 + 16) - 1 >= 0 )
    {
      v11 = *(_DWORD *)(v20 + 16);
      v12 = 0;
      do
      {
        if ( v12 + v16 > 0x3FFF )
          sub_402CA8();
        if ( v12 > 0x3FFF )
          sub_402CA8();
        *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v12) = *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * (v12 + v16));
        ++v12;
        --v11;
      }
      while ( v11 );
    }
    i += v16;
    result = v16;
  }
  return result;
}

//----- (00414978) --------------------------------------------------------
void __userpurge sub_414978(int a1<eax>, int a2<edx>, int a3<ecx>, signed int a4<esi>, unsigned int a5, int a6)
{
  int v6; // ebx@1
  unsigned int v7; // eax@9
  int v8; // edx@11
  int v9; // eax@11
  int v10; // edx@17
  unsigned int v11; // eax@17
  int v12; // ecx@18
  int v13; // esi@26
  int v14; // [sp+0h] [bp-2Ch]@0
  unsigned int v15; // [sp+0h] [bp-2Ch]@1
  char v16; // [sp+Ch] [bp-20h]@4
  unsigned int v17; // [sp+18h] [bp-14h]@1
  unsigned int v18; // [sp+1Ch] [bp-10h]@1
  int v19; // [sp+20h] [bp-Ch]@1
  int v20; // [sp+24h] [bp-8h]@1
  int v21; // [sp+28h] [bp-4h]@1

  v20 = a3;
  v21 = a2;
  v6 = a1;
  sub_413A40(
    *(_DWORD *)(a2 + 24),
    *(_DWORD *)(a2 + 16),
    *(_DWORD *)(a2 + 20),
    *(_DWORD *)(a1 + 12),
    *(_DWORD *)(a2 + 4),
    v14);
  sub_412725(v20, *(_DWORD *)(v6 + 8), *(_DWORD *)(v21 + 16), *(_DWORD *)(v21 + 4), v15);
  v19 = (544 - *(_DWORD *)(v21 + 16)) & 0xFFFFFFFC;
  v18 = 0;
  v17 = (4 - (a5 & 3)) & 3;
  if ( (signed int)v17 > 0 )
  {
    if ( a5 > 0x3FFF )
      sub_402CA8();
    System::Move(a6 + 4 * a5, &v16);
    a5 += v17;
  }
  while ( (signed int)a5 > 0 )
  {
    if ( (signed int)a5 <= v19 )
      a4 = a5;
    else
      a4 = v19;
    v7 = *(_DWORD *)(v21 + 16);
    if ( v7 > 0x3FFF )
      sub_402CA8();
    v8 = *(_DWORD *)(v6 + 8) + 2 * v7;
    v9 = v18 + v7;
    if ( (unsigned int)v9 > 0x3FFF )
      sub_402CA8();
    sub_412725(v20 + 4 * v9, v8, a4, *(_DWORD *)(v21 + 4), v15);
    if ( v18 > 0x3FFF )
      sub_402CA8();
    sub_414DB8(*(_DWORD *)(v6 + 8), a6 + 4 * v18, a4, *(_DWORD *)(v6 + 12));
    a5 -= a4;
    if ( (signed int)a5 > 0 )
    {
      if ( *(_DWORD *)(v21 + 16) / 2 - 1 >= 0 )
      {
        v10 = *(_DWORD *)(v21 + 16) / 2;
        v11 = 0;
        do
        {
          v12 = v11 + a4 / 2;
          if ( (unsigned int)v12 > 0x3FFF )
            sub_402CA8();
          if ( v11 > 0x3FFF )
            sub_402CA8();
          *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v11++) = *(_DWORD *)(*(_DWORD *)(v6 + 8) + 4 * v12);
          --v10;
        }
        while ( v10 );
      }
      v18 += a4;
    }
  }
  if ( (signed int)v17 > 0 )
  {
    v13 = v18 + a4 - v17;
    if ( (unsigned int)v13 > 0x3FFF )
      sub_402CA8();
    System::Move(&v16, a6 + 4 * v13);
  }
}

//----- (00414B30) --------------------------------------------------------
char __userpurge sub_414B30<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // ebx@1
  int v7; // esi@1
  char result; // al@2
  int v9; // [sp+0h] [bp-18h]@0
  int v10; // [sp+0h] [bp-18h]@3
  unsigned int v11; // [sp+Ch] [bp-Ch]@3
  int v12; // [sp+10h] [bp-8h]@3
  int v13; // [sp+14h] [bp-4h]@1

  v13 = ecx0;
  v6 = a2;
  v7 = a1;
  if ( a3 >= 256 )
  {
    sub_414610(*(_DWORD *)(a2 + 16) / 2, *(_DWORD *)(a2 + 16) / 2, a3, (int)&v11, (int)&v12, v9);
    if ( *(_BYTE *)v6 )
      sub_4146A4(v13, a4, v12);
    if ( *(_BYTE *)(v6 + 1) )
    {
      if ( v11 + v12 > 0x3FFF )
        sub_402CA8();
      if ( v11 + v12 > 0x3FFF )
        sub_402CA8();
      sub_4146A4(v13 + 4 * (v11 + v12), a4 + 4 * (v11 + v12), a3 - (v11 + v12));
    }
    if ( *(_BYTE *)(*(_DWORD *)(v7 + 4) + 19) )
    {
      if ( (unsigned int)v12 > 0x3FFF )
        sub_402CA8();
      sub_414978(v7, v6, v13, v7, v11, a4 + 4 * v12);
    }
    else
    {
      if ( (unsigned int)v12 > 0x3FFF )
        sub_402CA8();
      sub_414858(v7, v6, v13, v11, a4 + 4 * v12, v10);
    }
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00414C28) --------------------------------------------------------
int __userpurge sub_414C28<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // edi@3
  char v6; // ST1F_1@3
  int v7; // ebx@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v5 = ecx0;
  v6 = a2;
  v7 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v7 + 4) = v5;
  *(_DWORD *)(v7 + 8) = a3;
  *(_DWORD *)(v7 + 12) = a3 + 2176;
  if ( v6 )
    System::__linkproc___AfterConstruction(v7);
  return v7;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);

//----- (00414C80) --------------------------------------------------------
int __userpurge sub_414C80<eax>(int a1<eax>, int a2<edx>, int a3<ecx>, int a4<ebx>, __m64 a5<mm5>, int a6, int a7, int a8)
{
  int v8; // eax@2
  int v9; // eax@3
  int v11; // [sp+0h] [bp-8h]@0

  LOBYTE(a4) = 1;
  switch ( a2 )
  {
    case 1:
      LOBYTE(v8) = sub_414B30(a1, a3, a8, a6, a7, v11);
      a4 = v8;
      break;
    case 2:
      LOBYTE(v9) = sub_414B30(a1, a3, a7, a6, a8, v11);
      a4 = v9;
      break;
    case 3:
      sub_4146A4(a8, a7, a6);
      break;
    case 4:
      sub_4146D4(a7, a8, a6);
      break;
    case 5:
      if ( *(_BYTE *)(*(_DWORD *)(a1 + 4) + 19) )
        sub_41475C(a8, a7, a6, a5);
      else
        sub_41470C(a8, a7, a6);
      break;
    case 0:
      return a4;
    default:
      a4 = 0;
      break;
  }
  return a4;
}

//----- (00414D37) --------------------------------------------------------
int __usercall sub_414D37<eax>(int result<eax>, int a2<edx>, signed int a3<ecx>, __m64 a4<mm5>)
{
  int v4; // ecx@2
  int v5; // edx@2
  int v6; // ecx@2
  __m64 v7; // mm4@2
  __m64 v8; // mm2@3
  __m64 v9; // mm3@3
  __m64 v10; // mm0@3
  __m64 v11; // mm1@3

  if ( a3 >= 4 )
  {
    v4 = a3 & 0xFFFFFFFC;
    result += 4 * v4;
    v5 = a2 + 4 * v4;
    v6 = -v4;
    v7 = _m_psubd(0i64, _m_pcmpeqd(a4, a4));
    do
    {
      v8 = *(__m64 *)(v5 + 4 * v6);
      v9 = *(__m64 *)(v5 + 4 * v6 + 8);
      v10 = _m_paddd(_m_pslld(*(__m64 *)(result + 4 * v6), 1u), _m_pand(*(__m64 *)(v5 + 4 * v6), v7));
      v11 = _m_paddd(_m_pslld(*(__m64 *)(result + 4 * v6 + 8), 1u), _m_pand(*(__m64 *)(v5 + 4 * v6 + 8), v7));
      *(_QWORD *)(result + 4 * v6) = _m_psrad(_m_psubd(v10, v8), 1u);
      *(_QWORD *)(result + 4 * v6 + 8) = _m_psrad(_m_psubd(v11, v9), 1u);
      *(_QWORD *)(v5 + 4 * v6) = _m_psrad(_m_paddd(v10, v8), 1u);
      *(_QWORD *)(v5 + 4 * v6 + 8) = _m_psrad(_m_paddd(v11, v9), 1u);
      v6 += 4;
    }
    while ( v6 < 0 );
    _m_femms();
  }
  return result;
}

//----- (00414DB8) --------------------------------------------------------
void __cdecl sub_414DB8(int a1, int a2, unsigned int a3, int a4)
{
  int v4; // ebx@1
  int v5; // edx@1
  unsigned int v6; // ecx@1
  int v7; // edi@1
  __m64 v8; // mm6@1
  __m64 v9; // mm7@1
  __m64 v10; // mm4@2
  __m64 v11; // mm0@2
  __m64 v12; // mm5@2
  __m64 v13; // mm1@2
  __m64 v14; // mm2@2
  __m64 v15; // mm3@2
  __m64 v16; // mm0@2
  __m64 v17; // mm1@2
  __m64 v18; // mm2@2
  __m64 v19; // mm3@2
  __m64 v20; // mm0@2
  __m64 v21; // mm2@2
  __m64 v22; // mm0@2
  __m64 v23; // mm1@2

  v4 = a1;
  v5 = a2;
  v6 = a3 >> 2;
  v7 = a4;
  v8 = *(__m64 *)a4;
  v9 = *(__m64 *)(a4 + 32);
  do
  {
    v10 = *(__m64 *)(v4 + 8);
    v11 = _m_paddd(_m_pmaddwd(*(__m64 *)v4, *(__m64 *)(v7 + 64)), _m_pmaddwd(v10, *(__m64 *)(v7 + 96)));
    v12 = *(__m64 *)(v4 + 16);
    v13 = _m_paddd(
            _m_paddd(_m_pmaddwd(*(__m64 *)v4, *(__m64 *)(v7 + 72)), _m_pmaddwd(v10, *(__m64 *)(v7 + 104))),
            _m_pmaddwd(v12, *(__m64 *)(v7 + 136)));
    v14 = _m_paddd(
            _m_paddd(_m_pmaddwd(*(__m64 *)v4, *(__m64 *)(v7 + 80)), _m_pmaddwd(v10, *(__m64 *)(v7 + 112))),
            _m_pmaddwd(v12, *(__m64 *)(v7 + 144)));
    v15 = _m_paddd(
            _m_paddd(
              _m_pmaddwd(*(__m64 *)v4, *(__m64 *)(v7 + 88)),
              _m_pmaddwd(*(__m64 *)(v4 + 8), *(__m64 *)(v7 + 120))),
            _m_pmaddwd(v12, *(__m64 *)(v7 + 152)));
    v7 = a4;
    v16 = _m_paddd(_m_punpckldq(v11, v13), _m_punpckhdq(v11, v13));
    v17 = _m_paddd(_m_punpckhdq(v14, v15), _m_punpckldq(v14, v15));
    v18 = _m_psrad(v16, 0x1Fu);
    v19 = _m_psrad(v17, 0x1Fu);
    v20 = _m_psrld(_m_paddd(_m_psubd(_m_pxor(v16, v18), v18), v8), v9);
    v21 = _m_packssdw(v18, v19);
    v22 = _m_psubw(
            _m_pxor(
              _m_psubw(
                _m_paddusw(
                  _m_packssdw(v20, _m_psrld(_m_paddd(_m_psubd(_m_pxor(v17, v19), v19), v8), v9)),
                  *(__m64 *)(a4 + 16)),
                *(__m64 *)(a4 + 16)),
              v21),
            v21);
    v23 = _m_psubd(_m_pslld(_m_psrad(_m_punpckhwd(v22, v22), 0x10u), *(__m64 *)(a4 + 8)), *(__m64 *)(v5 + 8));
    *(_QWORD *)v5 = _m_psubd(_m_pslld(_m_psrad(_m_punpcklwd(v22, v22), 0x10u), *(__m64 *)(a4 + 8)), *(__m64 *)v5);
    *(_QWORD *)(v5 + 8) = v23;
    v4 += 8;
    v5 += 16;
    --v6;
  }
  while ( v6 );
  _m_femms();
}

//----- (00414ED8) --------------------------------------------------------
int __cdecl sub_414ED8()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8F0;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8F0: using guessed type int dword_41A8F0;

//----- (00414F08) --------------------------------------------------------
void __cdecl sub_414F08()
{
  --dword_41A8F0;
}
// 41A8F0: using guessed type int dword_41A8F0;

//----- (00414F70) --------------------------------------------------------
int __fastcall sub_414F70(int a1)
{
  return sub_413A04(a1 + 4, 4);
}

//----- (00414F8C) --------------------------------------------------------
char __fastcall sub_414F8C(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // ecx@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a2 + 12) = 4;
  *(_DWORD *)a2 = sub_40864C(a1, 4);
  return !sub_40864C(v3, 2) && (unsigned __int8)sub_413C18(v3, v2 + 4, v4);
}

//----- (00415018) --------------------------------------------------------
int __userpurge sub_415018<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4)
{
  int v5; // ecx@1

  *(_DWORD *)(a1 + 16) = ecx0;
  *(_DWORD *)(a1 + 20) = a3;
  *(_DWORD *)(a1 + 12) = *(_DWORD *)a2;
  v5 = *(_DWORD *)(a2 + 12);
  *(_DWORD *)(a1 + 24) = v5;
  *(_DWORD *)(a1 + 8) = a2 + 4;
  return sub_414004(*(_DWORD *)(a1 + 4) + 4, a1 + 8, v5);
}

//----- (00415048) --------------------------------------------------------
int __cdecl sub_415048()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8F4;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8F4: using guessed type int dword_41A8F4;

//----- (00415078) --------------------------------------------------------
void __cdecl sub_415078()
{
  --dword_41A8F4;
}
// 41A8F4: using guessed type int dword_41A8F4;

//----- (004150EC) --------------------------------------------------------
int __usercall sub_4150EC<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // esi@1
  int v4; // edi@1
  int v5; // ebx@1
  int v7; // [sp+0h] [bp-10h]@1

  v7 = ecx0;
  v3 = a2;
  v4 = a1;
  v5 = 0;
  if ( sub_408854(a1, (int)&v7) )
  {
    if ( !v7 )
    {
      *(_DWORD *)v3 = 0;
      goto LABEL_6;
    }
    if ( sub_408814(v4, 4, v3) )
    {
      ++*(_DWORD *)v3;
LABEL_6:
      LOBYTE(v5) = 1;
      return v5;
    }
  }
  return v5;
}

//----- (0041512C) --------------------------------------------------------
int __userpurge sub_41512C<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, signed int a4, int a5, int a6)
{
  int v7; // ST30_4@3
  char v8; // ST37_1@3
  int v9; // ebx@3
  int v10; // ST14_4@3
  signed int v11; // ST14_4@3
  int v12; // ST14_4@3
  int v14; // [sp-10h] [bp-24h]@0

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v7 = ecx0;
  v8 = a2;
  v9 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v9 + 4) = v7;
  *(_DWORD *)(v9 + 88) = a4;
  *(_DWORD *)(v9 + 8) = sub_4129EC((int)off_412810, 1, a5, 8, 8, 64, 2, a3, v14);
  *(_DWORD *)(v9 + 12) = sub_412B30((int)off_41286C, 1, *(_DWORD *)(v9 + 8));
  *(_DWORD *)(v9 + 16) = sub_413454((int)off_412E1C, 1, a5, a3, *(_DWORD *)(v9 + 88), v10);
  sub_413A04(v9 + 32, 256);
  *(_DWORD *)(v9 + 76) = sub_409664((int)off_4095DC, 1, 4320, v9 + 80, 64, v11);
  *(_DWORD *)(v9 + 52) = v9 + 32;
  *(_DWORD *)(v9 + 72) = *(_DWORD *)(v9 + 80);
  *(_DWORD *)(v9 + 144) = sub_414C28((int)off_4145AC, 1, *(_DWORD *)(v9 + 4), *(_DWORD *)(v9 + 80), v12);
  sub_414628(v9 + 148);
  *(_DWORD *)(v9 + 176) = unknown_libname_113(*(_DWORD *)(v9 + 80));
  sub_414F70(v9 + 180);
  sub_414F70(v9 + 204);
  if ( v8 )
    System::__linkproc___AfterConstruction(v9);
  return v9;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 4095DC: using guessed type char *off_4095DC;
// 412810: using guessed type char *off_412810;
// 41286C: using guessed type char *off_41286C;
// 412E1C: using guessed type char *off_412E1C;
// 4145AC: using guessed type char *off_4145AC;
// 414FD0: using guessed type _DWORD __stdcall unknown_libname_113(_DWORD);

//----- (00415250) --------------------------------------------------------
int __cdecl sub_415250()
{
  int v0; // eax@1
  int v1; // edx@1
  int v2; // ebx@1
  int v3; // esi@1
  int v4; // edx@1
  int result; // eax@1

  v0 = System::__linkproc___BeforeDestruction();
  v2 = v1;
  v3 = v0;
  unknown_libname_112(v0 + 204);
  unknown_libname_112(v3 + 180);
  System::TObject::Free(*(_DWORD *)(v3 + 176));
  sub_414638(v3 + 148);
  System::TObject::Free(*(_DWORD *)(v3 + 144));
  System::TObject::Free(*(_DWORD *)(v3 + 76));
  unknown_libname_111(v3 + 32);
  System::TObject::Free(*(_DWORD *)(v3 + 16));
  System::TObject::Free(*(_DWORD *)(v3 + 12));
  System::TObject::Free(*(_DWORD *)(v3 + 8));
  v4 = v2;
  LOBYTE(v4) = v2 & 0xFC;
  result = System::TObject::_TObject(v3, v4);
  if ( (char)v2 > 0 )
    result = System::__linkproc___ClassDestroy(v3);
  return result;
}
// 402D1C: using guessed type int __fastcall System__TObject___TObject(_DWORD, _DWORD);
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);
// 402EA4: using guessed type int __fastcall System____linkproc__ ClassDestroy(_DWORD);
// 402EBC: using guessed type int System____linkproc__ BeforeDestruction(void);
// 413A34: using guessed type int __fastcall unknown_libname_111(_DWORD);
// 414F80: using guessed type int __fastcall unknown_libname_112(_DWORD);

//----- (004152D4) --------------------------------------------------------
char __fastcall sub_4152D4(int a1)
{
  int v1; // ebx@1
  int v2; // esi@3
  char v3; // al@3

  v1 = a1;
  return !*(_BYTE *)(*(_DWORD *)(a1 + 84) + 44)
      && (!(sub_408568(*(_DWORD *)(a1 + 84)) & 7)
       || (v2 = *(_DWORD *)(v1 + 84), v3 = sub_408568(*(_DWORD *)(v1 + 84)), !sub_40864C(v2, 8 - (v3 & 7))));
}

//----- (00415318) --------------------------------------------------------
char __fastcall sub_415318(int a1)
{
  int v1; // ebx@1
  int v2; // eax@1
  char result; // al@4
  int v4; // edi@5
  signed int v5; // esi@6
  int v6; // eax@9

  v1 = a1;
  v2 = *(_DWORD *)(a1 + 92) - 1;
  if ( (unsigned int)v2 > 5 )
    sub_402CA8();
  if ( *(_DWORD *)(v1 + 8 * v2 + 96) < *(_DWORD *)(*(_DWORD *)(v1 + 12) + 24) )
  {
    *(_DWORD *)(v1 + 100) = 0;
    v4 = *(_DWORD *)(v1 + 92) - 1;
    if ( *(_DWORD *)(v1 + 92) - 1 > 0 )
    {
      v5 = 1;
      do
      {
        if ( (unsigned int)v5 > 5 )
          sub_402CA8();
        v6 = sub_412C24(*(_DWORD *)(v1 + 12), *(_DWORD *)(v1 + 8 * v5 + 96));
        if ( (unsigned int)v5 > 5 )
          sub_402CA8();
        *(_DWORD *)(v1 + 8 * v5++ + 100) = v6;
        --v4;
      }
      while ( v4 );
    }
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00415380) --------------------------------------------------------
char __usercall sub_415380<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebp@1
  int v4; // ebx@1
  int v5; // esi@2
  unsigned int v6; // edi@2
  unsigned int v7; // eax@3

  v3 = a2;
  v4 = a1;
  if ( ecx0 - 1 >= 0 )
  {
    v5 = ecx0;
    v6 = 0;
    do
    {
      v7 = sub_4086E0(*(_DWORD *)(v4 + 84), *(_DWORD *)(v4 + 88));
      if ( v6 > 0x3FFF )
        sub_402CA8();
      *(_DWORD *)(v3 + 4 * v6++) = v7;
      --v5;
    }
    while ( v5 );
  }
  return *(_BYTE *)(*(_DWORD *)(v4 + 84) + 44) ^ 1;
}

//----- (004153C0) --------------------------------------------------------
int __usercall sub_4153C0<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int result; // eax@3
  int v5; // [sp+0h] [bp-8h]@1

  v5 = ecx0;
  v3 = a1;
  *(_DWORD *)(a1 + 20) = a2;
  *(_DWORD *)(a1 + 24) = ecx0;
  if ( sub_408814(*(_DWORD *)(a1 + 84), 2, (int)&v5) && v5 <= 2 )
  {
    *(_BYTE *)(v3 + 28) = v5;
    if ( sub_413520(*(_DWORD *)(v3 + 16), *(_DWORD *)(v3 + 84), *(_DWORD *)(v3 + 20), *(_DWORD *)(v3 + 24), v5) )
    {
      result = sub_412D84(v3 + 20);
      LOBYTE(result) = 1;
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (00415418) --------------------------------------------------------
int __usercall sub_415418<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebx@1
  int result; // eax@4
  int v5; // eax@7
  int v6; // ecx@7
  unsigned int v7; // esi@9
  int v8; // ecx@11
  int v9; // [sp+0h] [bp-Ch]@1

  v9 = ecx0;
  v3 = a1;
  *(_DWORD *)(a1 + 60) = a2;
  *(_DWORD *)(a1 + 64) = ecx0;
  if ( sub_408814(*(_DWORD *)(a1 + 84), 4, a1 + 56) && sub_408814(*(_DWORD *)(v3 + 84), 4, (int)&v9) && v9 < 16 )
  {
    if ( (unsigned int)v9 > 0xF )
      sub_402CA8();
    v5 = *((_DWORD *)off_4193F0 + v9);
    *(_DWORD *)(v3 + 68) = v5;
    *(_DWORD *)(*(_DWORD *)(v3 + 52) + 8) = v5;
    if ( !(unsigned __int8)sub_4153C0(v3, *(_DWORD *)(v3 + 60), *(_DWORD *)(v3 + 68))
      || !(unsigned __int8)sub_413C18(*(_DWORD *)(v3 + 84), *(_DWORD *)(v3 + 52), v6) )
      goto LABEL_16;
    v7 = *(_DWORD *)(v3 + 68);
    if ( v7 > 0x3FFF )
      sub_402CA8();
    if ( sub_413520(
           *(_DWORD *)(v3 + 16),
           *(_DWORD *)(v3 + 84),
           *(_DWORD *)(v3 + 60) + 4 * v7,
           *(_DWORD *)(v3 + 64) - v7,
           v9) )
    {
      result = sub_414004(*(_DWORD *)(v3 + 4) + 4, v3 + 52, v8);
      LOBYTE(result) = 1;
    }
    else
    {
LABEL_16:
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}
// 4193F0: using guessed type void *off_4193F0;

//----- (004154D8) --------------------------------------------------------
int __usercall sub_4154D8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  int v4; // esi@1
  int v5; // ebx@1
  int result; // eax@3
  int v7; // [sp+0h] [bp-10h]@1

  v7 = ecx0;
  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_408814(*(_DWORD *)(a1 + 84), 1, (int)&v7) && v7 <= 1 )
  {
    if ( (unsigned __int8)v7 < 1u )
    {
      result = sub_4153C0(v5, v4, v3);
    }
    else
    {
      if ( (_BYTE)v7 == 1 )
        result = sub_415418(v5, v4, v3);
      else
        result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}

//----- (0041552C) --------------------------------------------------------
char __userpurge sub_41552C<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, int a6)
{
  int v7; // ebx@1
  unsigned int v8; // esi@11
  int v9; // edi@15
  int v11; // [sp+Ch] [bp-14h]@11
  signed int v12; // [sp+10h] [bp-10h]@10
  char v13; // [sp+17h] [bp-9h]@1
  int v14; // [sp+18h] [bp-8h]@1
  int v15; // [sp+18h] [bp-8h]@8
  int v16; // [sp+1Ch] [bp-4h]@1

  v14 = ecx0;
  v16 = a2;
  v7 = a1;
  v13 = 0;
  if ( (unsigned __int8)sub_4150EC(*(_DWORD *)(a1 + 84), a5, ecx0)
    && *(_DWORD *)a5 < *(_DWORD *)(v7 + 88)
    && sub_408834(*(_DWORD *)(v7 + 84), *(_DWORD *)(v7 + 88) - *(_DWORD *)a5, v16) )
  {
    *(_DWORD *)v16 <<= *(_DWORD *)a5;
    if ( sub_408704(*(_DWORD *)(v7 + 84)) == 1 )
    {
      *(_BYTE *)a4 = 1;
      if ( !sub_414F8C(*(_DWORD *)(v7 + 84), a3) )
        return v13;
    }
    else
    {
      *(_BYTE *)a4 = 0;
    }
    v15 = v14 - 1;
    if ( sub_4144E0(*(_DWORD *)(v7 + 84), v7 + 92) && sub_415318(v7) )
    {
      v12 = 1;
      if ( *(_DWORD *)(v7 + 92) - 1 < 0 )
      {
LABEL_25:
        v13 = 1;
      }
      else
      {
        v11 = *(_DWORD *)(v7 + 92);
        v8 = 0;
        while ( 1 )
        {
          if ( v8 == *(_DWORD *)(v7 + 92) - 1 )
          {
            if ( v8 > 5 )
              sub_402CA8();
            v9 = v15 - *(_DWORD *)(v7 + 8 * v8 + 100);
          }
          else
          {
            if ( v8 + 1 > 5 )
              sub_402CA8();
            if ( v8 > 5 )
              sub_402CA8();
            v9 = *(_DWORD *)(v7 + 8 * (v8 + 1) + 100) - *(_DWORD *)(v7 + 8 * v8 + 100);
          }
          if ( (unsigned int)v12 > 0x3FFF )
            sub_402CA8();
          if ( !(unsigned __int8)sub_4154D8(v7, v16 + 4 * v12, v9) )
            break;
          v12 += v9;
          ++v8;
          --v11;
          if ( !v11 )
            goto LABEL_25;
        }
      }
    }
  }
  return v13;
}

//----- (00415654) --------------------------------------------------------
char __userpurge sub_415654<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, int a5, int a6)
{
  int v6; // esi@1
  char v7; // bl@3
  char result; // al@6
  int v9; // [sp+0h] [bp-10h]@0
  int v10; // [sp+0h] [bp-10h]@6
  int v11; // [sp+8h] [bp-8h]@1
  int v12; // [sp+Ch] [bp-4h]@1

  v11 = a3;
  v12 = a2;
  v6 = a1;
  v7 = a5 == 2 || a5 == 4;
  if ( v7 )
    result = sub_41552C(a1, a3, a6, a1 + 204, a1 + 229, a1 + 236, v9);
  else
    result = sub_41552C(a1, a2, a6, a1 + 180, a1 + 228, a1 + 232, v9);
  if ( result )
  {
    if ( (unsigned int)(a5 - 1) >= 2 || sub_414644(*(_DWORD *)(v6 + 84), v6 + 148) )
    {
      if ( v7 )
        result = sub_41552C(v6, v12, a6, v6 + 180, v6 + 228, v6 + 232, v10);
      else
        result = sub_41552C(v6, v11, a6, v6 + 204, v6 + 229, v6 + 236, v10);
      if ( result )
      {
        if ( (unsigned int)(a5 - 3) < 3 && (*(_BYTE *)(v6 + 228) || *(_BYTE *)(v6 + 229)) )
          result = 0;
        else
          result = sub_414C80(*(_DWORD *)(v6 + 144), a5, v6 + 148, v7, a4, a6 - 1, v11 + 4, v12 + 4);
      }
    }
    else
    {
      result = 0;
    }
  }
  return result;
}

//----- (0041578C) --------------------------------------------------------
int *__userpurge sub_41578C<eax>(int a1<eax>, int *a2<edx>, int ecx0<ecx>, int a3, int a4, int a5, char a6)
{
  int v7; // esi@1
  int *v8; // ebx@1
  int v10; // [sp+0h] [bp-8h]@0

  v7 = ecx0;
  v8 = a2;
  if ( (_BYTE)a5 )
    sub_415018(*(_DWORD *)(a1 + 176), a4, (int)(a2 + 1), ecx0 - 1, v10);
  if ( a3 > 0 )
    sub_4126F8((int)(v8 + 1), v7 - 1, a3);
  return sub_412CE4(v8, v7);
}

//----- (004157D4) --------------------------------------------------------
char __userpurge sub_4157D4<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, signed int a4)
{
  int v5; // edi@1
  int v6; // ebx@1
  char v7; // al@4
  int v8; // eax@7
  int v10; // [sp+0h] [bp-14h]@0
  int v11; // [sp+0h] [bp-14h]@1
  int v12; // [sp+0h] [bp-14h]@7
  char v13; // [sp+Fh] [bp-5h]@1

  v5 = ecx0;
  v6 = a1;
  v13 = 0;
  *(_DWORD *)(a1 + 84) = a2;
  sub_412B84(*(_DWORD *)(a1 + 12), a3, *(_BYTE *)(*(_DWORD *)(a1 + 8) + 12), -1, v10);
  if ( a3 >= 16 )
  {
    if ( sub_41552C(v6, v5, a3, v6 + 180, v6 + 228, v6 + 232, v11) )
    {
      LOBYTE(v8) = *(_BYTE *)(v6 + 228);
      sub_41578C(v6, (int *)v5, a3, *(_DWORD *)(v6 + 232), v6 + 180, v8, v12);
      v13 = sub_4152D4(v6);
    }
  }
  else
  {
    v7 = sub_415380(v6, v5, a3) && sub_4152D4(v6);
    v13 = v7;
  }
  return v13;
}

//----- (00415888) --------------------------------------------------------
char __userpurge sub_415888<al>(int a1<eax>, int a2<edx>, int a3<ecx>, __m64 a4<mm5>, signed int a5, int a6)
{
  int v6; // edi@1
  int v7; // ebx@1
  char v8; // al@5
  int v9; // eax@10
  int v10; // eax@11
  char v11; // ST0C_1@11
  int v13; // [sp+0h] [bp-18h]@0
  int v14; // [sp+0h] [bp-18h]@1
  int v15; // [sp+Ch] [bp-Ch]@8
  char v16; // [sp+13h] [bp-5h]@1
  int v17; // [sp+14h] [bp-4h]@1

  v6 = a3;
  v17 = a2;
  v7 = a1;
  v16 = 0;
  *(_DWORD *)(a1 + 84) = a2;
  sub_412B84(*(_DWORD *)(a1 + 12), a5, *(_BYTE *)(*(_DWORD *)(a1 + 8) + 12), -1, v13);
  if ( a5 >= 16 )
  {
    if ( sub_408814(*(_DWORD *)(v7 + 84), 3, (int)&v15) && v15 <= 5 && sub_415654(v7, v6, a6, a4, v15, a5) )
    {
      LOBYTE(v9) = *(_BYTE *)(v7 + 228);
      v10 = (int)sub_41578C(v7, (int *)v6, a5, *(_DWORD *)(v7 + 232), v7 + 180, v9, v14);
      LOBYTE(v10) = *(_BYTE *)(v7 + 229);
      sub_41578C(v7, (int *)a6, a5, *(_DWORD *)(v7 + 236), v7 + 204, v10, v11);
      v16 = sub_4152D4(v7);
    }
  }
  else
  {
    v8 = sub_415380(v7, v6, a5) && sub_415380(v7, a6, a5) && sub_4152D4(v7);
    v16 = v8;
  }
  return v16;
}

//----- (00415978) --------------------------------------------------------
int __cdecl sub_415978()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8F8;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8F8: using guessed type int dword_41A8F8;

//----- (004159A8) --------------------------------------------------------
void __cdecl sub_4159A8()
{
  --dword_41A8F8;
}
// 41A8F8: using guessed type int dword_41A8F8;

//----- (00415A28) --------------------------------------------------------
int __fastcall sub_415A28(int result)
{
  *(_DWORD *)(result + 16) = 0;
  *(_DWORD *)(result + 20) = 0;
  *(_DWORD *)(result + 24) = 0;
  *(_DWORD *)(result + 28) = 0;
  *(_DWORD *)(result + 32) = 0;
  return result;
}

//----- (00415A4C) --------------------------------------------------------
int __fastcall sub_415A4C(int a1)
{
  *(_DWORD *)a1 = 0;
  *(_DWORD *)(a1 + 4) = 0;
  *(_DWORD *)(a1 + 8) = 0;
  *(_DWORD *)(a1 + 12) = 0;
  return sub_415A28(a1);
}

//----- (00415A6C) --------------------------------------------------------
int __fastcall sub_415A6C(int result, signed int a2)
{
  if ( a2 > *(_DWORD *)(result + 28) && a2 >= 2 )
    *(_DWORD *)(result + 28) = a2;
  if ( a2 > *(_DWORD *)(result + 60) )
    *(_DWORD *)(result + 60) = a2;
  return result;
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00415A84) --------------------------------------------------------
int __fastcall sub_415A84(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
{
  int v7; // ebx@1
  int v9; // [sp+4h] [bp-10h]@2
  int v10; // [sp+8h] [bp-Ch]@2
  int v11; // [sp+Ch] [bp-8h]@2
  int v12; // [sp+10h] [bp-4h]@2

  v7 = a1;
  if ( *(_DWORD *)(a1 + 16) )
  {
    v9 = a5;
    v10 = a6;
    v11 = a3;
    v12 = a4;
    (*(void (__cdecl **)(_DWORD, int *))(a1 + 16))(*(_DWORD *)(a1 + 20), &v9);
  }
  return sub_415A6C(v7, 3);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00415ACC) --------------------------------------------------------
char __fastcall sub_415ACC(int a1)
{
  int v1; // ebx@1
  int v2; // eax@1
  char result; // al@9
  int v4; // eax@10
  int v5; // eax@15
  int v6; // edx@15
  signed int v7; // eax@15
  char v8; // al@17
  int v9; // edx@21

  v1 = a1;
  v2 = sub_4115A4((int)off_410568, 1);
  *(_DWORD *)(v1 + 132) = v2;
  if ( (unsigned __int8)sub_41167C(v2, *(_DWORD *)(v1 + 128)) )
  {
    *(_DWORD *)(v1 + 24) = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 8);
    v4 = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 8);
    if ( v4 && v4 & 7 )
      sub_415A6C(v1, 2);
    if ( sub_40E470(*(_DWORD *)(*(_DWORD *)(v1 + 132) + 24), *(_DWORD *)(v1 + 132) + 48) )
    {
      *(_DWORD *)(v1 + 152) = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 52);
      *(_DWORD *)(v1 + 156) = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 36);
      v5 = *(_DWORD *)(v1 + 132);
      *(_DWORD *)(v1 + 32) = *(_DWORD *)(v5 + 40);
      v6 = *(_DWORD *)(v5 + 44);
      *(_DWORD *)(v1 + 36) = v6;
      v7 = *(_DWORD *)(v1 + 156);
      v8 = v7 >= 512 && v7 <= 16384;
      if ( v8 )
      {
        LOBYTE(v6) = 1;
        *(_DWORD *)(v1 + 68) = unknown_libname_109(off_41043C, v6);
        LOBYTE(v9) = 1;
        *(_DWORD *)(v1 + 136) = unknown_libname_33(off_408460, v9);
        result = 1;
      }
      else
      {
        sub_415A6C(v1, 5);
        result = 0;
      }
    }
    else
    {
      sub_415A6C(v1, 5);
      result = 0;
    }
  }
  else
  {
    *(_DWORD *)(v1 + 24) = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 8);
    switch ( *(_DWORD *)(*(_DWORD *)(v1 + 132) + 4) )
    {
      case 1:
        sub_415A6C(v1, 4);
        break;
      case 2:
        sub_415A6C(v1, 5);
        break;
      case 3:
        sub_415A6C(v1, 6);
        break;
    }
    result = 0;
  }
  return result;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 408460: using guessed type char *off_408460;
// 41043C: using guessed type char *off_41043C;
// 410568: using guessed type char *off_410568;
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00415C1C) --------------------------------------------------------
int __fastcall sub_415C1C(int a1)
{
  int v1; // ebx@1
  int v2; // eax@1
  int v3; // eax@3

  v1 = a1;
  System::TObject::Free(*(_DWORD *)(a1 + 136));
  v2 = *(_DWORD *)(v1 + 132);
  if ( v2 )
  {
    sub_411A0C(v2);
    System::TObject::Free(*(_DWORD *)(v1 + 132));
  }
  v3 = *(_DWORD *)(v1 + 128);
  if ( v3 )
  {
    sub_40DE2C(v3);
    System::TObject::Free(*(_DWORD *)(v1 + 128));
  }
  return System::TObject::Free(*(_DWORD *)(v1 + 68));
}
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);

//----- (00415C68) --------------------------------------------------------
char __usercall sub_415C68<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebp@1
  int v4; // edi@1
  int v5; // ebx@1
  int v6; // esi@2
  int v7; // eax@2
  char result; // al@3

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  if ( sub_4162E4(a1) )
  {
    v6 = *(_DWORD *)(v5 + 68);
    v7 = sub_410D00(*(_DWORD *)(v5 + 68));
    sub_410F14(v6, v7);
    if ( sub_410E3C(*(_DWORD *)(v5 + 68), -1) )
    {
      *(_DWORD *)v4 = sub_411078(*(_DWORD *)(v5 + 68));
      *(_DWORD *)v3 = sub_410D00(*(_DWORD *)(v5 + 68));
      result = 1;
    }
    else
    {
      if ( !sub_410D48(*(_DWORD *)(v5 + 68)) )
        sub_415A6C(v5, 4);
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00415CDC) --------------------------------------------------------
int __fastcall sub_415CDC(int a1)
{
  int v1; // ebx@1
  int v2; // esi@1
  signed int v3; // edi@2
  int v4; // edi@4
  int v5; // esi@4
  int result; // eax@6
  int v7; // edx@6
  int v8; // [sp+0h] [bp-Ch]@0
  signed int v9; // [sp+0h] [bp-Ch]@2

  v1 = a1;
  v2 = *(_DWORD *)(a1 + 132);
  if ( *(_DWORD *)(v2 + 24) )
  {
    *(_DWORD *)(a1 + 140) = sub_40D078(
                              (int)off_40CFCC,
                              1,
                              *(_DWORD *)(a1 + 4),
                              *(_DWORD *)(a1 + 156),
                              v2 + 48,
                              (const void *)v8);
    v3 = 3;
  }
  else
  {
    *(_DWORD *)(a1 + 140) = sub_41512C(
                              (int)off_415080,
                              1,
                              *(_DWORD *)(a1 + 4),
                              *(_DWORD *)(a1 + 156),
                              *(_DWORD *)(v2 + 56),
                              *(_DWORD *)(v2 + 52),
                              v8);
    v3 = 3;
  }
  v4 = 4 * (*(_DWORD *)(v1 + 156) + v3);
  v5 = (v4 + 63) & 0xFFFFFFC0;
  if ( !((v4 + 63) & 0x7C0) )
    v5 += 64;
  *(_DWORD *)(v1 + 72) = sub_409664(
                           (int)off_4095DC,
                           1,
                           v4 + v5 * (*(_DWORD *)(*(_DWORD *)(v1 + 132) + 60) - 1) + 64,
                           v1 + 76,
                           64,
                           v9);
  *(_DWORD *)(v1 + 76) += 60;
  result = *(_DWORD *)(v1 + 132);
  v7 = *(_DWORD *)(result + 60) - 1;
  if ( *(_DWORD *)(result + 60) - 1 > 0 )
  {
    result = 1;
    do
    {
      if ( (unsigned int)(result - 1) > 5 )
        sub_402CA8();
      if ( (unsigned int)result > 5 )
        sub_402CA8();
      *(_DWORD *)(v1 + 4 * result + 76) = v5 + *(_DWORD *)(v1 + 4 * (result - 1) + 76);
      ++result;
      --v7;
    }
    while ( v7 );
  }
  if ( *(_BYTE *)(v1 + 12) & 0x10 )
  {
    result = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 20);
    if ( *(_BYTE *)(result + 20) & 0x10 )
    {
      result = sub_409B64((int)off_409B0C, 1);
      *(_DWORD *)(v1 + 144) = result;
    }
    else
    {
      *(_DWORD *)(v1 + 12) &= 0xFFFFFFEFu;
    }
  }
  return result;
}
// 4095DC: using guessed type char *off_4095DC;
// 409B0C: using guessed type void *off_409B0C;
// 40CFCC: using guessed type int (__stdcall **off_40CFCC)(int);
// 415080: using guessed type int (__stdcall **off_415080)(int);

//----- (00415DF0) --------------------------------------------------------
int __fastcall sub_415DF0(int a1)
{
  int v1; // ebx@1

  v1 = a1;
  System::TObject::Free(*(_DWORD *)(a1 + 144));
  System::TObject::Free(*(_DWORD *)(v1 + 140));
  return System::TObject::Free(*(_DWORD *)(v1 + 72));
}
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);

//----- (00415E14) --------------------------------------------------------
char __fastcall sub_415E14(int a1)
{
  int v1; // ebx@1
  __int64 v2; // qax@4
  int v3; // esi@5
  __int64 v4; // qax@6

  v1 = a1;
  return *(_DWORD *)(*(_DWORD *)(a1 + 132) + 260) > *(_DWORD *)(a1 + 164)
      && (!*(_BYTE *)(a1 + 160)
       || *(_DWORD *)(*(_DWORD *)(a1 + 132) + 260) - 1 == *(_DWORD *)(a1 + 164)
       && ((LODWORD(v2) = System::__linkproc____llmod(
                            *(_DWORD *)(a1 + 156),
                            (unsigned __int64)*(_DWORD *)(a1 + 156) >> 32),
            *(_DWORD *)(v1 + 168) == v2)
        || (v3 = *(_DWORD *)(v1 + 156), v3 == *(_DWORD *)(v1 + 168))
        && (LODWORD(v4) = System::__linkproc____llmod(v3, (unsigned __int64)v3 >> 32), !v4)));
}
// 403ED0: using guessed type _DWORD __stdcall System____linkproc__ _llmod(_DWORD, _DWORD);

//----- (00415EB4) --------------------------------------------------------
char __usercall sub_415EB4<al>(int a1<eax>, signed int *a2<edx>, int ecx0<ecx>)
{
  int v3; // edi@1
  signed int *v4; // esi@1
  int v5; // ebx@1
  int v6; // ST08_4@1
  int v7; // ST00_4@1
  int v8; // eax@1
  int v9; // eax@1
  char result; // al@3
  signed int v11; // eax@11
  long double v12; // fst7@13
  int v13; // edx@13
  signed int v14; // [sp-8h] [bp-18h]@13
  int v15; // [sp-4h] [bp-14h]@1

  v15 = ecx0;
  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  v6 = a1;
  v7 = sub_410D00(*(_DWORD *)(a1 + 68));
  v8 = sub_411078(*(_DWORD *)(v5 + 68));
  sub_4085E4(*(_DWORD *)(v5 + 136), v8, v7, (int)sub_415C68, v6, v15);
  sub_411204(*(_DWORD *)(v5 + 68));
  v9 = *(_DWORD *)(*(_DWORD *)(v5 + 132) + 60);
  if ( v9 == 1 )
  {
    if ( !(unsigned __int8)(***(int (__fastcall ****)(_DWORD, _DWORD, _DWORD))(v5 + 140))(
                             *(_DWORD *)(v5 + 140),
                             *(_DWORD *)(v5 + 136),
                             *v4) )
      return 0;
  }
  else
  {
    if ( v9 == 2 )
    {
      if ( !(unsigned __int8)(*(int (__fastcall **)(_DWORD, _DWORD, signed int, _DWORD))(**(_DWORD **)(v5 + 140) + 4))(
                               *(_DWORD *)(v5 + 140),
                               *(_DWORD *)(v5 + 136),
                               *v4,
                               *(_DWORD *)(v5 + 80)) )
        return 0;
    }
    else
    {
      if ( !(unsigned __int8)(*(int (__fastcall **)(_DWORD, _DWORD, signed int))(**(_DWORD **)(v5 + 140) + 8))(
                               *(_DWORD *)(v5 + 140),
                               *(_DWORD *)(v5 + 136),
                               *v4) )
        return 0;
    }
  }
  if ( sub_408814(*(_DWORD *)(v5 + 136), 24, (int)&v15) )
  {
    v11 = sub_40859C(*(_DWORD *)(v5 + 136));
    sub_410F14(*(_DWORD *)(v5 + 68), v11);
    if ( sub_411220(*(_DWORD *)(v5 + 68)) )
    {
      sub_411218(*(_DWORD *)(v5 + 68));
      *(_DWORD *)v3 = *(_DWORD *)(v5 + 252) + sub_408580(*(_DWORD *)(v5 + 136));
      v12 = (long double)*(signed int *)(*(_DWORD *)(v5 + 132) + 52)
          / (long double)*v4
          * (long double)*(signed int *)v3
          * 8.0;
      v14 = System::__linkproc___ROUND(v12);
      if ( v14 >> 31 != v13 )
        sub_402CA8();
      *(_DWORD *)(v5 + 116) = v14;
      result = 1;
    }
    else
    {
      result = 0;
    }
  }
  else
  {
    result = 0;
  }
  return result;
}
// 402674: using guessed type int __usercall System____linkproc__ ROUND<eax>(double<st0>);

//----- (00415FFC) --------------------------------------------------------
char __fastcall sub_415FFC(int a1)
{
  int v1; // ebx@1
  char result; // al@2
  _BYTE v3[12]; // [sp-8h] [bp-10h]@0

  v1 = a1;
  *(_QWORD *)v3 = *(_QWORD *)(a1 + 256) + 1i64;
  if ( (unsigned __int8)sub_410DE8(
                          *(_DWORD *)(a1 + 68),
                          *(_DWORD *)(a1 + 128),
                          *(_DWORD *)(a1 + 136),
                          *(_DWORD *)(*(_DWORD *)(a1 + 128) + 16) - 1,
                          (unsigned __int64)(*(_QWORD *)(*(_DWORD *)(a1 + 128) + 16) - 1i64) >> 32,
                          *(_DWORD *)(a1 + 256) + 1,
                          *(__int64 *)&v3[4]) )
  {
    result = 1;
  }
  else
  {
    sub_415A6C(v1, 4);
    result = 0;
  }
  return result;
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416054) --------------------------------------------------------
char __fastcall sub_416054(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  char result; // al@2
  int v5; // [sp+0h] [bp-20h]@6
  int v6; // [sp+4h] [bp-1Ch]@8
  int v7; // [sp+8h] [bp-18h]@14
  int v8; // [sp+Ch] [bp-14h]@14
  int v9; // [sp+10h] [bp-10h]@14
  int v10; // [sp+14h] [bp-Ch]@14

  v2 = a2;
  v3 = a1;
  if ( *(_BYTE *)(a1 + 64) )
  {
    result = 0;
  }
  else
  {
    while ( 1 )
    {
      while ( 1 )
      {
        if ( !sub_411168(*(_DWORD *)(v3 + 68), v3 + 256, v3 + 160, v3 + 252, v5) )
        {
          *(_BYTE *)(v3 + 64) = 1;
          return 0;
        }
        if ( sub_415E14(v3) && v2 <= *(_DWORD *)(v3 + 164) )
          break;
        sub_410F14(*(_DWORD *)(v3 + 68), *(_DWORD *)(v3 + 252) - 1);
      }
      sub_410F14(*(_DWORD *)(v3 + 68), *(_DWORD *)(v3 + 252));
      v5 = *(_BYTE *)(v3 + 160) ? *(_DWORD *)(v3 + 168) : *(_DWORD *)(v3 + 156);
      if ( sub_415EB4(v3, &v5, (int)&v6) )
        break;
      if ( sub_4162E4(v3) )
        sub_415FFC(v3);
    }
    if ( *(_DWORD *)(*(_DWORD *)(v3 + 132) + 260) - 1 > *(_DWORD *)(v3 + 164) )
    {
      *(_BYTE *)(v3 + 64) = *(_BYTE *)(v3 + 160);
    }
    else
    {
      *(_BYTE *)(v3 + 64) = 1;
      if ( *(_DWORD *)(*(_DWORD *)(v3 + 132) + 260) - 1 < *(_DWORD *)(v3 + 164) )
        return 0;
    }
    *(_DWORD *)(v3 + 104) = v5;
    *(_DWORD *)(v3 + 100) = 0;
    if ( !(*(_BYTE *)(v3 + 12) & 4) )
    {
      v7 = *(_DWORD *)(v3 + 164);
      v8 = v6;
      v9 = *(_DWORD *)(v3 + 256);
      v10 = *(_DWORD *)(v3 + 260);
      sub_411AC0(*(_DWORD *)(v3 + 132), &v7);
    }
    result = 1;
  }
  return result;
}

//----- (004161A4) --------------------------------------------------------
int __usercall sub_4161A4<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  *(_DWORD *)(a1 + 108) = 0;
  *(_DWORD *)(a1 + 100) = 0;
  *(_DWORD *)(a1 + 104) = 0;
  *(_DWORD *)(a1 + 112) = ecx0;
  *(_DWORD *)(a1 + 120) = a2 - 1;
  *(_BYTE *)(a1 + 64) = 0;
  *(_DWORD *)(a1 + 116) = *(_DWORD *)(*(_DWORD *)(a1 + 132) + 56)
                        * *(_DWORD *)(*(_DWORD *)(a1 + 132) + 60)
                        * *(_DWORD *)(*(_DWORD *)(a1 + 132) + 52);
  return sub_415A28(a1 + 24);
}

//----- (004161E0) --------------------------------------------------------
char __userpurge sub_4161E0<al>(int a1<eax>, int a2<edx>, int ecx0<ecx>, int a3, int a4, int a5)
{
  int v6; // esi@1
  int v7; // edi@1
  int v8; // ebx@1
  char result; // al@2
  int v10; // eax@3
  int v11; // eax@6

  v6 = ecx0;
  v7 = a2;
  v8 = a1;
  unknown_libname_33(a1, 0);
  *(_DWORD *)(v8 + 60) = 0;
  sub_415A4C(v8 + 24);
  if ( v6 )
  {
    *(_DWORD *)(v8 + 4) = v7;
    sub_409924(v7, *(_DWORD *)v6);
    *(_DWORD *)(v8 + 8) = *(_DWORD *)v6;
    *(_DWORD *)(v8 + 12) = *(_DWORD *)(v6 + 4);
    *(_DWORD *)(v8 + 16) = a4;
    *(_DWORD *)(v8 + 20) = a3;
    v10 = *(_DWORD *)(v8 + 12);
    if ( !(v10 & 8) || v10 & 4 )
    {
      v11 = *(_DWORD *)(v8 + 12);
      if ( !(v11 & 0x10) || v11 & 4 )
      {
        result = 1;
      }
      else
      {
        sub_415A6C(v8, 2048);
        result = 0;
      }
    }
    else
    {
      sub_415A6C(v8, 2048);
      result = 0;
    }
  }
  else
  {
    sub_415A6C(v8, 2048);
    result = 0;
  }
  return result;
}
// 402CFC: using guessed type int __fastcall unknown_libname_33(_DWORD, _DWORD);
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416278) --------------------------------------------------------
char __fastcall sub_416278(int a1)
{
  int v1; // ebx@1
  char result; // al@1
  int v3; // esi@2
  __int64 v4; // [sp-4h] [bp-Ch]@0

  v1 = a1;
  result = sub_415ACC(a1);
  if ( result )
  {
    *(_DWORD *)(v1 + 124) = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 64);
    sub_415CDC(v1);
    sub_4161A4(v1, 0, 0);
    v3 = *(_DWORD *)(v1 + 128);
    LODWORD(v4) = *(_DWORD *)(v3 + 12);
    result = sub_410DE8(
               *(_DWORD *)(v1 + 68),
               *(_DWORD *)(v1 + 128),
               *(_DWORD *)(v1 + 136),
               *(_DWORD *)(v3 + 16) - 1,
               (unsigned __int64)(*(_QWORD *)(v3 + 16) - 1i64) >> 32,
               *(_DWORD *)(v3 + 8),
               v4);
    if ( !result )
      result = sub_415A6C(v1, 4);
  }
  return result;
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (004162E4) --------------------------------------------------------
char __fastcall sub_4162E4(int a1)
{
  return *(_DWORD *)(a1 + 28) < 4;
}

//----- (004162F8) --------------------------------------------------------
int __userpurge sub_4162F8<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, int a5, int a6, int a7)
{
  char v8; // bl@3
  int v9; // edi@3
  int v10; // eax@7
  int v12; // [sp-10h] [bp-1Ch]@0
  int v13; // [sp-10h] [bp-1Ch]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v8 = a2;
  v9 = a1;
  if ( sub_4161E0(a1, ecx0, a5, a3, a4, v12) )
  {
    if ( sub_4083DC(a6, v9 + 148, 256) && *(_DWORD *)(v9 + 148) )
    {
      v10 = sub_40DC64((int)off_40DAB0, 1);
      *(_DWORD *)(v9 + 128) = v10;
      if ( sub_40E0D4(v10, *(_DWORD *)(v9 + 148), v13) )
        sub_415A6C(v9, 4);
      else
        sub_416278(v9);
    }
    else
    {
      sub_415A6C(v9, 2048);
    }
  }
  if ( v8 )
    System::__linkproc___AfterConstruction(v9);
  return v9;
}
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40DAB0: using guessed type int (**off_40DAB0)();
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (004163B0) --------------------------------------------------------
int __userpurge sub_4163B0<eax>(int a1<eax>, char a2<dl>, int ecx0<ecx>, int a3, int a4, int a5, int a6, int a7, int a8)
{
  int v9; // esi@3
  int v11; // [sp-10h] [bp-24h]@0
  char v12; // [sp+13h] [bp-1h]@3

  if ( a2 )
    a1 = System::__linkproc___ClassCreate();
  v12 = a2;
  v9 = a1;
  if ( sub_4161E0(a1, ecx0, a5, a3, a4, v11) )
  {
    if ( a7
      && *(_DWORD *)a7
      && *(_DWORD *)(a7 + 4)
      && *(_DWORD *)(a7 + 8)
      && *(_DWORD *)(a7 + 12)
      && *(_DWORD *)(a7 + 28)
      && *(_DWORD *)(a7 + 32)
      && (*(int (__cdecl **)(_DWORD))a7)(a6)
      && (*(int (__cdecl **)(_DWORD))(a7 + 8))(a6) )
    {
      *(_DWORD *)(v9 + 128) = sub_40DC64((int)off_40DB2C, 1);
      if ( sub_40E194(*(_DWORD *)(v9 + 128), (const void *)a7, a6) )
        sub_415A6C(v9, 4);
      else
        sub_416278(v9);
    }
    else
    {
      sub_415A6C(v9, 2049);
    }
  }
  if ( v12 )
    System::__linkproc___AfterConstruction(v9);
  return v9;
}
// 402EAC: using guessed type int __fastcall System____linkproc__ AfterConstruction(_DWORD);
// 40DB2C: using guessed type int (**off_40DB2C)();
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (004164C8) --------------------------------------------------------
int __usercall sub_4164C8<eax>(int a1<eax>, signed int a2<edx>, int ecx0<ecx>)
{
  int result; // eax@2

  switch ( a2 )
  {
    case 1:
      result = System::__linkproc___LStrAsg(ecx0, &str_Meta_data_missi[1]);
      break;
    case 2:
      result = System::__linkproc___LStrAsg(ecx0, &str_Meta_data_damag[1]);
      break;
    case 3:
      result = System::__linkproc___LStrAsg(ecx0, &str_Audio_data_dama[1]);
      break;
    case 4:
      result = System::__linkproc___LStrAsg(ecx0, &str_Error_reading_s_0[1]);
      break;
    case 5:
      result = System::__linkproc___LStrAsg(ecx0, &str_Incompatible_fi[1]);
      break;
    case 6:
      result = System::__linkproc___LStrAsg(ecx0, &str_Undecodable_[1]);
      break;
    default:
      result = sub_408158(a2, ecx0);
      break;
  }
  return result;
}
// 4037BC: using guessed type int __fastcall System____linkproc__ LStrAsg(_DWORD, _DWORD);
// 416560: using guessed type _strings str_Meta_data_missi[3];
// 41657C: using guessed type _strings str_Meta_data_damag[3];
// 416598: using guessed type _strings str_Audio_data_dama[3];
// 4165B4: using guessed type _strings str_Error_reading_s_0[4];
// 4165D8: using guessed type _strings str_Incompatible_fi[4];
// 4165FC: using guessed type _strings str_Undecodable_[2];

//----- (00416614) --------------------------------------------------------
int __fastcall sub_416614(int a1, void *a2)
{
  int v2; // ebx@1

  v2 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
    memcpy(a2, (const void *)(a1 + 24), 0x24u);
  else
    sub_415A6C(a1, 2048);
  return *(_DWORD *)(v2 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416644) --------------------------------------------------------
int __fastcall sub_416644(int a1, void *a2)
{
  void *v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
  {
    if ( sub_4162E4(a1) )
      memcpy(v2, (const void *)(*(_DWORD *)(v3 + 132) + 24), 0x48u);
    else
      *(_DWORD *)(v3 + 60) = *(_DWORD *)(v3 + 28);
  }
  else
  {
    sub_415A6C(a1, 2048);
  }
  return *(_DWORD *)(v3 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416690) --------------------------------------------------------
signed int __fastcall sub_416690(int a1)
{
  int v1; // ebx@1
  signed int result; // eax@2

  v1 = a1;
  if ( sub_4162E4(a1) )
    result = *(_DWORD *)(*(_DWORD *)(v1 + 132) + 36);
  else
    result = -1;
  return result;
}

//----- (004166B0) --------------------------------------------------------
signed __int64 __fastcall sub_4166B0(int a1)
{
  int v1; // ebx@1
  signed __int64 v3; // [sp+0h] [bp-Ch]@2

  v1 = a1;
  if ( sub_4162E4(a1) )
    v3 = *(_DWORD *)(v1 + 112);
  else
    v3 = -1i64;
  return v3;
}

//----- (004166E8) --------------------------------------------------------
signed int __fastcall sub_4166E8(int a1)
{
  int v1; // ebx@1
  signed int result; // eax@2

  v1 = a1;
  if ( sub_4162E4(a1) )
    result = *(_DWORD *)(v1 + 116);
  else
    result = -1;
  return result;
}

//----- (00416700) --------------------------------------------------------
int __fastcall sub_416700(int a1, int a2, int a3, __int64 a4)
{
  int v4; // ebx@1
  int result; // eax@2
  int v6; // edi@9
  __int64 v7; // ST08_8@9
  signed int v8; // eax@9
  int v9; // edx@9
  int v10; // esi@11
  signed int v11; // ST08_4@11
  unsigned __int64 v12; // qax@11
  int v13; // edi@13
  signed __int64 v14; // ST00_8@18
  int v15; // eax@24
  int v16; // ecx@25
  __int64 v17; // [sp+4h] [bp-18h]@0
  __int64 v18; // [sp+4h] [bp-18h]@18
  __int64 v19; // [sp+14h] [bp-8h]@13

  v4 = a1;
  if ( sub_4162E4(a1) )
  {
    *(_DWORD *)(v4 + 60) = 0;
    if ( *(_BYTE *)(v4 + 12) & 4 )
    {
      sub_415A6C(v4, 2050);
      result = *(_DWORD *)(v4 + 60);
    }
    else
    {
      if ( (_DWORD)a4 && (signed int)a4 < 0
        || *(_QWORD *)(*(_DWORD *)(v4 + 132) + 40) <= (signed __int64)__PAIR__(a4, a3) )
      {
        sub_415A6C(v4, 2048);
        result = *(_DWORD *)(v4 + 60);
      }
      else
      {
        v6 = *(_DWORD *)(*(_DWORD *)(v4 + 132) + 36);
        v7 = *(_DWORD *)(*(_DWORD *)(v4 + 132) + 36);
        v8 = System::__linkproc____lldiv(v7, HIDWORD(v7));
        if ( v8 >> 31 != v9 )
          sub_402CA8();
        v10 = v8;
        v11 = a3 - v8 * v6;
        v12 = __PAIR__(a4, a3) - v8 * v6;
        if ( v11 >> 31 != HIDWORD(v12) )
          sub_402CA8();
        v13 = v12;
        if ( sub_411AE4(*(_DWORD *)(v4 + 132), v10, (int)&v19) )
        {
          LODWORD(v17) = HIDWORD(v19);
          v14 = *(_QWORD *)(*(_DWORD *)(v4 + 128) + 16) - 1i64;
          if ( (unsigned __int8)sub_410DE8(
                                  *(_DWORD *)(v4 + 68),
                                  *(_DWORD *)(v4 + 128),
                                  *(_DWORD *)(v4 + 136),
                                  v14,
                                  SHIDWORD(v14),
                                  v19,
                                  v17) )
          {
            if ( a3 >> 31 != (_DWORD)a4 )
              sub_402CA8();
            sub_4161A4(v4, v10, a3);
            if ( sub_416054(v4, v10) )
            {
              *(_DWORD *)(v4 + 120) = v10;
              v15 = *(_DWORD *)(v4 + 164);
              if ( v10 >= v15 )
              {
                if ( v13 >= *(_DWORD *)(v4 + 104) )
                {
                  sub_415A6C(v4, 6);
                }
                else
                {
                  *(_DWORD *)(v4 + 100) += v13;
                  *(_DWORD *)(v4 + 104) -= v13;
                }
              }
              else
              {
                v16 = *(_DWORD *)(v4 + 156) * (v15 - v10) - v13;
                *(_DWORD *)(v4 + 108) = v16;
                sub_415A84(v4, (unsigned __int64)v16 >> 32, v16, (unsigned __int64)v16 >> 32, a3, a4, SHIDWORD(v18));
              }
              result = *(_DWORD *)(v4 + 60);
            }
            else
            {
              sub_415A6C(v4, 6);
              result = *(_DWORD *)(v4 + 60);
            }
          }
          else
          {
            sub_415A6C(v4, 4);
            result = *(_DWORD *)(v4 + 60);
          }
        }
        else
        {
          if ( *(_DWORD *)(*(_DWORD *)(v4 + 132) + 4) == 1 )
            sub_415A6C(v4, 4);
          else
            sub_415A6C(v4, 6);
          result = *(_DWORD *)(v4 + 60);
        }
      }
    }
  }
  else
  {
    result = *(_DWORD *)(v4 + 28);
    *(_DWORD *)(v4 + 60) = result;
  }
  return result;
}
// 403E08: using guessed type _DWORD __stdcall System____linkproc__ _lldiv(_DWORD, _DWORD);
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (004168E8) --------------------------------------------------------
int __userpurge sub_4168E8<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>, unsigned int a3, int a4)
{
  int v5; // edi@1
  int v6; // ebx@1
  int result; // eax@3
  int v8; // eax@6
  int v9; // esi@8
  unsigned __int8 v10; // cf@10
  int v11; // eax@12
  int v12; // esi@14
  unsigned int v13; // eax@17
  unsigned int v14; // ecx@20
  unsigned int v15; // ecx@26
  int v16; // ecx@34
  __int64 v17; // qax@39
  __int64 v18; // qax@45
  __int64 v19; // [sp+0h] [bp-34h]@39
  int v20; // [sp+8h] [bp-2Ch]@0
  int v21[6]; // [sp+14h] [bp-20h]@24
  int v22; // [sp+2Ch] [bp-8h]@17
  int v23; // [sp+30h] [bp-4h]@1

  v5 = ecx0;
  v23 = a2;
  v6 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  *(_DWORD *)a3 = 0;
  if ( v23 && a3 )
  {
    if ( sub_4162E4(a1) )
    {
      while ( v5 > 0 && sub_4162E4(v6) )
      {
        v8 = *(_DWORD *)(v6 + 108);
        if ( v8 > 0 )
        {
          if ( v5 <= v8 )
            v9 = v5;
          else
            v9 = *(_DWORD *)(v6 + 108);
          sub_40AE7C(*(_DWORD *)(v6 + 132) + 48, v9, v20);
          *(_DWORD *)a3 += v9;
          v5 -= v9;
          *(_DWORD *)(v6 + 108) -= v9;
          *(_DWORD *)(v6 + 112) += v9;
          v23 += *(_DWORD *)(v6 + 124) * v9;
          v10 = __CFADD__(v9, *(_DWORD *)(v6 + 48));
          *(_DWORD *)(v6 + 48) += v9;
          *(_DWORD *)(v6 + 52) += ((unsigned __int64)v9 >> 32) + v10;
        }
        if ( v5 > 0 )
        {
          v11 = *(_DWORD *)(v6 + 104);
          if ( v11 > 0 )
          {
            if ( v5 <= v11 )
              v12 = v5;
            else
              v12 = *(_DWORD *)(v6 + 104);
            if ( *(_DWORD *)(*(_DWORD *)(v6 + 132) + 60) - 1 >= 0 )
            {
              v22 = *(_DWORD *)(*(_DWORD *)(v6 + 132) + 60);
              v13 = 0;
              do
              {
                if ( v13 > 5 )
                  sub_402CA8();
                v14 = *(_DWORD *)(v6 + 100);
                if ( v14 > 0x1FFFFFFE )
                  sub_402CA8();
                if ( v13 > 5 )
                  sub_402CA8();
                v21[v13] = *(_DWORD *)(v6 + 4 * v13 + 76) + 4 * v14;
                ++v13;
                --v22;
              }
              while ( v22 );
            }
            sub_40ACDC(*(_DWORD *)(v6 + 132) + 48, (int)v21, v12, v23, v20);
            if ( *(_BYTE *)(v6 + 12) & 0x10 )
            {
              v15 = v12 * *(_DWORD *)(*(_DWORD *)(v6 + 132) + 64);
              if ( (v15 & 0x80000000u) != 0 )
                sub_402CA8();
              sub_409BD0(*(_DWORD *)(v6 + 144), v23, v15);
            }
            *(_DWORD *)a3 += v12;
            v5 -= v12;
            *(_DWORD *)(v6 + 104) -= v12;
            *(_DWORD *)(v6 + 100) += v12;
            *(_DWORD *)(v6 + 112) += v12;
            v23 += *(_DWORD *)(v6 + 124) * v12;
          }
          if ( v5 > 0 )
          {
            if ( *(_BYTE *)(v6 + 64) )
            {
              v5 = 0;
            }
            else
            {
              if ( sub_416054(v6, *(_DWORD *)(v6 + 120) + 1) )
              {
                v16 = *(_DWORD *)(v6 + 156) * (*(_DWORD *)(v6 + 164) - *(_DWORD *)(v6 + 120) - 1);
                *(_DWORD *)(v6 + 108) = v16;
                if ( v16 > 0 )
                {
                  sub_415A84(
                    v6,
                    (unsigned __int64)v16 >> 32,
                    v16,
                    (unsigned __int64)v16 >> 32,
                    *(_DWORD *)(v6 + 112),
                    (unsigned __int64)*(_DWORD *)(v6 + 112) >> 32,
                    v20);
                  ++*(_DWORD *)(v6 + 56);
                  if ( *(_BYTE *)(v6 + 12) & 8 )
                  {
                    *(_DWORD *)(v6 + 112) += *(_DWORD *)(v6 + 108);
                    *(_DWORD *)(v6 + 108) = 0;
                  }
                }
                *(_DWORD *)(v6 + 120) = *(_DWORD *)(v6 + 164);
              }
              else
              {
                if ( sub_4162E4(v6) )
                {
                  v19 = *(_QWORD *)(*(_DWORD *)(v6 + 132) + 40) - *(_DWORD *)(v6 + 112);
                  v17 = *(_QWORD *)(*(_DWORD *)(v6 + 132) + 40) - *(_DWORD *)(v6 + 112);
                  if ( (signed int)v19 >> 31 != HIDWORD(v17) )
                    sub_402CA8();
                  *(_DWORD *)(v6 + 108) = v19;
                  sub_415A84(
                    v6,
                    (unsigned __int64)(signed int)v17 >> 32,
                    v17,
                    (unsigned __int64)(signed int)v17 >> 32,
                    *(_DWORD *)(v6 + 112),
                    (unsigned __int64)*(_DWORD *)(v6 + 112) >> 32,
                    v20);
                  ++*(_DWORD *)(v6 + 56);
                  if ( *(_BYTE *)(v6 + 12) & 8 )
                    *(_DWORD *)(v6 + 108) = 0;
                }
              }
            }
          }
        }
      }
      v18 = *(_DWORD *)a3;
      v10 = __CFADD__((_DWORD)v18, *(_DWORD *)(v6 + 40));
      *(_DWORD *)(v6 + 40) += v18;
      *(_DWORD *)(v6 + 44) += HIDWORD(v18) + v10;
      if ( *(_BYTE *)(v6 + 12) & 0x10
        && *(_BYTE *)(v6 + 64)
        && *(_DWORD *)a3 > 0
        && !*(_DWORD *)(v6 + 108)
        && !*(_DWORD *)(v6 + 104)
        && *(_DWORD *)(v6 + 28) < 3 )
      {
        sub_409C78(*(_DWORD *)(v6 + 144));
        if ( !sub_409CD8(*(_DWORD *)(v6 + 144) + 4, *(_DWORD *)(*(_DWORD *)(v6 + 132) + 20) + 112) )
          sub_415A6C(v6, 3);
      }
      result = *(_DWORD *)(v6 + 60);
    }
    else
    {
      result = *(_DWORD *)(v6 + 28);
      *(_DWORD *)(v6 + 60) = result;
    }
  }
  else
  {
    sub_415A6C(a1, 2048);
    result = *(_DWORD *)(v6 + 60);
  }
  return result;
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);
// 4168E8: using guessed type int var_20[6];

//----- (00416B8C) --------------------------------------------------------
int __fastcall sub_416B8C(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // edi@4

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
  {
    if ( sub_4162E4(a1) )
    {
      v4 = *(_DWORD *)(v3 + 132);
      if ( *(_BYTE *)(*(_DWORD *)(v4 + 20) + 20) & 4 )
      {
        if ( !sub_411A40(*(_DWORD *)(v3 + 132), v2) )
        {
          if ( sub_411560(*(_DWORD *)(v3 + 132)) )
            sub_415A6C(v3, 2);
          else
            sub_415A6C(v3, 4);
        }
      }
      else
      {
        if ( *(_BYTE *)(v4 + 8) & 4 )
          sub_415A6C(v3, 2);
        else
          sub_415A6C(v3, 1);
      }
    }
    else
    {
      *(_DWORD *)(v3 + 60) = *(_DWORD *)(v3 + 28);
    }
  }
  else
  {
    sub_415A6C(a1, 2048);
  }
  return *(_DWORD *)(v3 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416C2C) --------------------------------------------------------
int __usercall sub_416C2C<eax>(int a1<eax>, int a2<edx>, int ecx0<ecx>)
{
  int v3; // ebp@1
  int v4; // esi@1
  int v5; // ebx@1
  int v6; // eax@3
  int v8; // [sp+0h] [bp-18h]@3
  int v9; // [sp+4h] [bp-14h]@4

  v3 = ecx0;
  v4 = a2;
  v5 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
  {
    v6 = sub_416B8C(a1, (int)&v8);
    *(_DWORD *)(v5 + 60) = v6;
    if ( !v6 )
    {
      if ( v3 >= v9 + v8 )
      {
        if ( !sub_411A80(*(_DWORD *)(v5 + 132), v4) )
        {
          if ( sub_411560(*(_DWORD *)(v5 + 132)) )
            sub_415A6C(v5, 2);
          else
            sub_415A6C(v5, 4);
        }
      }
      else
      {
        sub_415A6C(v5, 2051);
      }
    }
  }
  else
  {
    sub_415A6C(a1, 2048);
  }
  return *(_DWORD *)(v5 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416CC0) --------------------------------------------------------
int __fastcall sub_416CC0(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
  {
    if ( sub_4162E4(a1) )
    {
      if ( !sub_411B48(*(_DWORD *)(v3 + 132), v2) )
      {
        if ( sub_411560(*(_DWORD *)(v3 + 132)) )
          sub_415A6C(v3, 2);
        else
          sub_415A6C(v3, 4);
      }
    }
    else
    {
      *(_DWORD *)(v3 + 60) = *(_DWORD *)(v3 + 28);
    }
  }
  else
  {
    sub_415A6C(a1, 2048);
  }
  return *(_DWORD *)(v3 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416D30) --------------------------------------------------------
int __fastcall sub_416D30(int a1, int a2)
{
  int v2; // esi@1
  int v3; // ebx@1
  int v4; // edi@4

  v2 = a2;
  v3 = a1;
  *(_DWORD *)(a1 + 60) = 0;
  if ( a2 )
  {
    if ( sub_4162E4(a1) )
    {
      v4 = *(_DWORD *)(v3 + 132);
      if ( *(_BYTE *)(*(_DWORD *)(v4 + 20) + 20) & 0x10 )
      {
        if ( !sub_411B54(*(_DWORD *)(v3 + 132), v2) )
        {
          if ( sub_411560(*(_DWORD *)(v3 + 132)) )
            sub_415A6C(v3, 2);
          else
            sub_415A6C(v3, 4);
        }
      }
      else
      {
        if ( *(_BYTE *)(v4 + 8) & 4 )
          sub_415A6C(v3, 2);
        else
          sub_415A6C(v3, 1);
      }
    }
    else
    {
      *(_DWORD *)(v3 + 60) = *(_DWORD *)(v3 + 28);
    }
  }
  else
  {
    sub_415A6C(a1, 2048);
  }
  return *(_DWORD *)(v3 + 60);
}
// 415A6C: using guessed type int __fastcall sub_415A6C(_DWORD, _DWORD);

//----- (00416DD0) --------------------------------------------------------
int __cdecl sub_416DD0()
{
  int result; // eax@1
  unsigned int v1; // [sp-Ch] [bp-Ch]@1

  v1 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v1);
  ++dword_41A8FC;
  result = 0;
  __writefsdword(0, v1);
  return result;
}
// 41A8FC: using guessed type int dword_41A8FC;

//----- (00416E00) --------------------------------------------------------
void __cdecl sub_416E00()
{
  --dword_41A8FC;
}
// 41A8FC: using guessed type int dword_41A8FC;

//----- (00416E08) --------------------------------------------------------
signed int __cdecl tak_GetLibraryVersion(int a1, int a2)
{
  signed int result; // eax@3

  if ( a1 && a2 )
  {
    *(_DWORD *)a1 = 131584;
    *(_DWORD *)a2 = 65536;
    result = 0;
  }
  else
  {
    result = 2048;
  }
  return result;
}

//----- (00416E30) --------------------------------------------------------
int __usercall tak_GetCodecName<eax>(int a1<ebx>, int a2<edi>, int a3<esi>, signed int a4, int a5, int a6)
{
  unsigned int v7; // [sp-10h] [bp-14h]@1
  int (__cdecl *v8)(int, int, int); // [sp-Ch] [bp-10h]@1
  int (__cdecl *v9)(int, int, int); // [sp-8h] [bp-Ch]@1
  int v10; // [sp-4h] [bp-8h]@1
  int v11; // [sp+0h] [bp-4h]@1
  int v12; // [sp+4h] [bp+0h]@1

  v11 = 0;
  v10 = a1;
  v9 = (int (__cdecl *)(int, int, int))&v12;
  v8 = loc_416E80;
  v7 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v7);
  if ( (unsigned __int8)sub_40E2B4(a4, (int)&v11, a1, a2, a3) )
    sub_4083A4(v11, a5, a6);
  __writefsdword(0, v7);
  v9 = loc_416E87;
  return System::__linkproc___LStrClr(&v11);
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 416E80: using guessed type int __cdecl loc_416E80(int, int, int);
// 416E87: using guessed type int __cdecl loc_416E87(int, int, int);

//----- (00416E90) --------------------------------------------------------
bool __cdecl tak_GetWaveExtensibleSpeakerMask(int a1, int a2)
{
  return *(_DWORD *)(a1 + 20) == 1 && *(_DWORD *)(a1 + 28) == 1 && (unsigned __int8)sub_40A53C(a1, a2);
}

//----- (00416EC0) --------------------------------------------------------
int __cdecl tak_SSD_Create_FromFile(int a1, int a2, int a3, int a4)
{
  int v4; // ebx@1
  int v6; // [sp+0h] [bp-8h]@0

  v4 = sub_409980((int)off_40989C, 1);
  sub_409924(v4, *(_DWORD *)a2);
  return sub_4162F8((int)off_4159B0, 1, v4, a4, a3, a2, a1, v6);
}
// 40989C: using guessed type char *off_40989C;
// 4159B0: using guessed type int (*off_4159B0)[2];

//----- (00416F00) --------------------------------------------------------
int __cdecl tak_SSD_Create_FromStream(int a1, int a2, int a3, int a4, int a5)
{
  int v5; // ebx@1
  int v7; // [sp+0h] [bp-8h]@0

  v5 = sub_409980((int)off_40989C, 1);
  sub_409924(v5, *(_DWORD *)a3);
  return sub_4163B0((int)off_4159B0, 1, v5, a5, a4, a3, a2, a1, v7);
}
// 40989C: using guessed type char *off_40989C;
// 4159B0: using guessed type int (*off_4159B0)[2];

//----- (00416F44) --------------------------------------------------------
int __cdecl tak_SSD_Destroy(int a1)
{
  int result; // eax@1
  int v2; // ebx@2

  result = a1;
  if ( a1 )
  {
    v2 = *(_DWORD *)(a1 + 4);
    System::TObject::Free(a1);
    result = System::TObject::Free(v2);
  }
  return result;
}
// 402D2C: using guessed type int __fastcall System__TObject__Free(_DWORD);

//----- (00416F68) --------------------------------------------------------
bool __cdecl tak_SSD_Valid(int a1)
{
  return a1 && sub_4162E4(a1);
}

//----- (00416F8C) --------------------------------------------------------
signed int __cdecl tak_SSD_State(int a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = *(_DWORD *)(a1 + 28);
  else
    result = 2048;
  return result;
}

//----- (00416FA4) --------------------------------------------------------
int __cdecl tak_SSD_GetStateInfo(int a1, void *a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416614(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (00416FC0) --------------------------------------------------------
int __usercall tak_SSD_GetErrorString<eax>(int a1<ebx>, signed int a2, int a3, int a4)
{
  unsigned int v5; // [sp-10h] [bp-14h]@1
  int (__cdecl *v6)(int, int, int); // [sp-Ch] [bp-10h]@1
  int (__cdecl *v7)(int, int, int); // [sp-8h] [bp-Ch]@1
  int v8; // [sp-4h] [bp-8h]@1
  int v9; // [sp+0h] [bp-4h]@1
  int v10; // [sp+4h] [bp+0h]@1

  v9 = 0;
  v8 = a1;
  v7 = (int (__cdecl *)(int, int, int))&v10;
  v6 = loc_41700A;
  v5 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v5);
  sub_4164C8((int)off_4159B0, a2, (int)&v9);
  sub_4083A4(v9, a3, a4);
  __writefsdword(0, v5);
  v7 = loc_417011;
  return System::__linkproc___LStrClr(&v9);
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 4159B0: using guessed type int (*off_4159B0)[2];
// 41700A: using guessed type int __cdecl loc_41700A(int, int, int);
// 417011: using guessed type int __cdecl loc_417011(int, int, int);

//----- (00417018) --------------------------------------------------------
int __cdecl tak_SSD_GetStreamInfo(int a1, int a2)
{
  int result; // eax@2
  int v3; // [sp+Ch] [bp-48h]@3
  int v4; // [sp+10h] [bp-44h]@4
  int v5; // [sp+14h] [bp-40h]@4
  int v6; // [sp+18h] [bp-3Ch]@4
  int v7; // [sp+1Ch] [bp-38h]@4
  int v8; // [sp+20h] [bp-34h]@4
  int v9; // [sp+24h] [bp-30h]@4
  int v10; // [sp+28h] [bp-2Ch]@4
  int v11; // [sp+2Ch] [bp-28h]@4
  int v12; // [sp+30h] [bp-24h]@4
  int v13; // [sp+34h] [bp-20h]@4

  if ( a1 )
  {
    result = sub_416644(a1, &v3);
    if ( !result )
    {
      *(_DWORD *)a2 = v3;
      *(_DWORD *)(a2 + 4) = v4;
      *(_DWORD *)(a2 + 8) = v5;
      *(_DWORD *)(a2 + 12) = v6;
      *(_DWORD *)(a2 + 16) = v7;
      *(_DWORD *)(a2 + 20) = v8;
      *(_DWORD *)(a2 + 24) = v9;
      *(_DWORD *)(a2 + 28) = v10;
      *(_DWORD *)(a2 + 32) = v11;
      *(_DWORD *)(a2 + 36) = v12;
      *(_DWORD *)(a2 + 40) = v13;
    }
  }
  else
  {
    result = 2048;
  }
  return result;
}

//----- (00417078) --------------------------------------------------------
int __cdecl tak_SSD_GetStreamInfo_V22(int a1, void *a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416644(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (00417094) --------------------------------------------------------
signed int __cdecl tak_SSD_GetFrameSize(int a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = sub_416690(a1);
  else
    result = -1;
  return result;
}

//----- (004170AC) --------------------------------------------------------
int __fastcall tak_SSD_Seek(int a1, int a2, int a3, int a4, __int64 a5)
{
  int result; // eax@2
  __int64 v6; // [sp-4h] [bp-4h]@0

  if ( a3 )
  {
    LODWORD(v6) = a5;
    result = sub_416700(a3, a2, a4, v6);
  }
  else
  {
    result = 2048;
  }
  return result;
}

//----- (004170CC) --------------------------------------------------------
int __cdecl tak_SSD_ReadAudio(int a1, int a2, unsigned int a3, int a4)
{
  int result; // eax@2
  int v5; // [sp+0h] [bp+0h]@0

  if ( a1 )
    result = sub_4168E8(a1, a2, a3, a4, v5);
  else
    result = 2048;
  return result;
}

//----- (004170F0) --------------------------------------------------------
signed __int64 __cdecl tak_SSD_GetReadPos(int a1)
{
  signed __int64 v2; // [sp+0h] [bp-8h]@2

  if ( a1 )
    v2 = sub_4166B0(a1);
  else
    v2 = -1i64;
  return v2;
}

//----- (00417124) --------------------------------------------------------
signed int __cdecl tak_SSD_GetCurFrameBitRate(int a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = sub_4166E8(a1);
  else
    result = -1;
  return result;
}

//----- (0041713C) --------------------------------------------------------
int __cdecl tak_SSD_GetSimpleWaveDataDesc(int a1, int a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416B8C(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (00417158) --------------------------------------------------------
int __cdecl tak_SSD_ReadSimpleWaveData(int a1, int a2, int a3)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416C2C(a1, a2, a3);
  else
    result = 2048;
  return result;
}

//----- (00417178) --------------------------------------------------------
int __cdecl tak_SSD_GetEncoderInfo(int a1, int a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416CC0(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (00417194) --------------------------------------------------------
int __cdecl tak_SSD_GetMD5(int a1, int a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_416D30(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (004171B0) --------------------------------------------------------
int __cdecl tak_SSD_GetAPEv2Tag(int a1)
{
  int result; // eax@2

  if ( a1 )
    result = unknown_libname_114();
  else
    result = 0;
  return result;
}
// 4162EC: using guessed type int unknown_libname_114(void);

//----- (004171C8) --------------------------------------------------------
bool __cdecl tak_APE_Valid(int a1)
{
  return a1 && sub_40F510(a1);
}

//----- (004171EC) --------------------------------------------------------
signed int __cdecl tak_APE_State(int a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = *(_DWORD *)(a1 + 4);
  else
    result = 2048;
  return result;
}

//----- (00417204) --------------------------------------------------------
int __usercall tak_APE_GetErrorString<eax>(int a1<ebx>, signed int a2, int a3, int a4)
{
  unsigned int v5; // [sp-10h] [bp-14h]@1
  int (__cdecl *v6)(int, int, int); // [sp-Ch] [bp-10h]@1
  int (__cdecl *v7)(int, int, int); // [sp-8h] [bp-Ch]@1
  int v8; // [sp-4h] [bp-8h]@1
  int v9; // [sp+0h] [bp-4h]@1
  int v10; // [sp+4h] [bp+0h]@1

  v9 = 0;
  v8 = a1;
  v7 = (int (__cdecl *)(int, int, int))&v10;
  v6 = loc_41724E;
  v5 = __readfsdword(0);
  __writefsdword(0, (unsigned int)&v5);
  sub_40F594((int)off_40F158, a2, (int)&v9);
  sub_4083A4(v9, a3, a4);
  __writefsdword(0, v5);
  v7 = loc_417255;
  return System::__linkproc___LStrClr(&v9);
}
// 403768: using guessed type int __fastcall System____linkproc__ LStrClr(_DWORD);
// 40F158: using guessed type char *off_40F158;
// 41724E: using guessed type int __cdecl loc_41724E(int, int, int);
// 417255: using guessed type int __cdecl loc_417255(int, int, int);

//----- (0041725C) --------------------------------------------------------
bool __cdecl tak_APE_ReadOnly(int a1)
{
  return a1 && sub_40F73C(a1);
}

//----- (00417280) --------------------------------------------------------
int __cdecl tak_APE_GetDesc(int a1, void *a2)
{
  int result; // eax@2

  if ( a1 )
    result = sub_40F740(a1, a2);
  else
    result = 2048;
  return result;
}

//----- (0041729C) --------------------------------------------------------
signed int __cdecl tak_APE_GetItemNum(int a1)
{
  signed int result; // eax@2

  if ( a1 )
    result = sub_40F720(a1);
  else
    result = -1;
  return result;
}

//----- (004172B4) --------------------------------------------------------
int __cdecl tak_APE_GetIndexOfKey(int a1, int a2, int a3)
{
  int result; // eax@2

  if ( a1 )
    result = sub_40F784(a1, a2, a3);
  else
    result = -1;
  return result;
}

//----- (004172D0) --------------------------------------------------------
int __cdecl tak_APE_GetItemDesc(int a1, int a2, int a3)
{
  int result; // eax@2

  if ( a1 )
    result = sub_40F7F4(a1, a2, a3);
  else
    result = -1;
  return result;
}

//----- (004172EC) --------------------------------------------------------
int __cdecl tak_APE_GetItemKey(int a1, int a2, int a3, int a4, int a5)
{
  int result; // eax@2
  int v6; // [sp+0h] [bp+0h]@0

  if ( a1 )
    result = sub_40F860(a1, a2, a3, a5, a4, v6);
  else
    result = -1;
  return result;
}

//----- (00417310) --------------------------------------------------------
int __cdecl tak_APE_GetItemValue(int a1, int a2, int a3, int a4, int a5)
{
  int result; // eax@2
  int v6; // [sp+0h] [bp+0h]@0

  if ( a1 )
    result = sub_40F90C(a1, a2, a3, a5, a4, v6);
  else
    result = -1;
  return result;
}

//----- (00417334) --------------------------------------------------------
int __cdecl tak_APE_GetTextItemValueAsAnsi(int a1, int a2, int a3, char a4, signed int a5, int a6, int a7)
{
  int result; // eax@2
  char v8; // [sp+0h] [bp+0h]@0

  if ( a1 )
    result = sub_40F9A0(a1, a2, a3, a7, a6, a5, a4, v8);
  else
    result = -1;
  return result;
}

#error "There were 5 decompilation failure(s) on 584 function(s)"
