
#include "stdafx.h"
#include "Globals.h"
#include "Config.h"
#include "BKMessageBox.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

CConfig::CConfig()
{
	m_BKFDDModel = DEV_FDD_NONE;
	m_nSoundSampleRate = 44100;
	/*
	 Получение версии виндовса.
	 Выход: TRUE - версию получить удалось,
	        FALSE - версию получить не удалось по каким-то причинам

	Если dwMajor < 6 то это winxp или хуже того, вин 2000 какой-нибудь
	в зависимости от этого надо выбирать разные рендеры осциллографа и экрана.
	 */
	BOOL bRet = FALSE;
	//Пытаемся вызвать GetVersionEx используя структуру OSVERSIONINFOEX.
	//В случае ошибки пытаемся проделать тоже самое со структурой OSVERSIONINFO.
	ZeroMemory(&m_osvi, sizeof(OSVERSIONINFOEX));
	m_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

	if (!(bRet = GetVersionEx(reinterpret_cast<OSVERSIONINFO *>(&m_osvi))))
	{
		// Если OSVERSIONINFOEX не работает, то используем OSVERSIONINFO.
		m_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		bRet = GetVersionEx(reinterpret_cast<OSVERSIONINFO *>(&m_osvi));
	}
}

CConfig::~CConfig()
{
	UnInitConfig();
}

//инициализация конфига и всяких переменных, типа пути к проге
void CConfig::InitConfig(const CString &strIniName)
{
	m_strCurrentPath = _GetCurrentPath();
	m_strIniFilePath = m_strCurrentPath + strIniName;
	iniFile.SetIniFileName(m_strIniFilePath);
	CFile file;

	if (file.Open(m_strIniFilePath, CFile::modeRead | CFile::shareDenyWrite))
	{
		// если файл открылся, значит всё в порядке, он существует
		file.Close();
	}
	else
	{
		// иначе - создадим конфиг по умолчанию
		DefaultConfig();
	}

	LoadConfig();
}

void CConfig::UnInitConfig()
{
	SaveConfig();
	iniFile.Clear();
}

const CString &CConfig::GetCurrentPath()
{
	if (m_strCurrentPath.IsEmpty())
	{
		m_strCurrentPath = _GetCurrentPath();
	}

	return m_strCurrentPath;
}

CString &CConfig::NormalizePath(CString &strPath)
{
	if (!strPath.IsEmpty())
	{
		strPath.TrimRight(_T('\\'));
		strPath += _T('\\');
	}

	return strPath;
}

CString CConfig::_GetCurrentPath()
{
	TCHAR pDrive[_MAX_DIR] = { 0 };
	TCHAR pPath[_MAX_PATH] = { 0 };
	TCHAR pModuleName[_MAX_PATH] = { 0 };
	::GetModuleFileName(AfxGetInstanceHandle(), pModuleName, _MAX_PATH);
	_tsplitpath_s(pModuleName, pDrive, _MAX_DIR, pPath, _MAX_PATH, NULL, 0, NULL, 0);
	return NormalizePath(CString(pDrive).Trim() + CString(pPath).Trim());
}

CString CConfig::GetFilePath(const CString &strPath)
{
	TCHAR pDrive[_MAX_DIR] = { 0 };
	TCHAR pPath[_MAX_PATH] = { 0 };
	_tsplitpath_s(strPath, pDrive, _MAX_DIR, pPath, _MAX_PATH, NULL, 0, NULL, 0);
	return NormalizePath(CString(pDrive).Trim() + CString(pPath).Trim());
}

CString CConfig::GetFileTitle(const CString &strPath)
{
	TCHAR pName[_MAX_FNAME] = { 0 };
	_tsplitpath_s(strPath, NULL, 0, NULL, 0, pName, _MAX_FNAME, NULL, 0);
	return CString(pName).Trim();
}

CString CConfig::GetFileName(const CString &strPath)
{
	TCHAR pName[_MAX_FNAME] = { 0 };
	TCHAR pExt[_MAX_EXT] = { 0 };
	_tsplitpath_s(strPath, NULL, 0, NULL, 0, pName, _MAX_FNAME, pExt, _MAX_EXT);
	return CString(pName).Trim() + CString(pExt).Trim();
}

CString CConfig::GetFileExt(const CString &strPath)
{
	TCHAR pExt[_MAX_EXT] = { 0 };
	_tsplitpath_s(strPath, NULL, 0, NULL, 0, NULL, 0, pExt, _MAX_EXT);
	return CString(pExt).Trim();
}

/*
В конфиге есть значения только для чтения, которые не будут изменяться
и есть текущие опции, которые как раз будут изменяться.
*/
void CConfig::LoadConfig(BOOL bLoadFromMemory, BYTE *pBuff, UINT nSize)
{
	if (bLoadFromMemory)
	{
		iniFile.ReadIniFromMemory(pBuff, nSize);
	}

	// Инициализация Rom модулей, читаем их лишь для того, чтобы проверить наличие
	m_strBK10_017_Monitor   = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_017_MONITOR, _T(""));
	m_strBK10_018_Focal     = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_018_FOCAL, _T(""));
	m_strBK10_019_MSTD      = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_019_MSTD, _T(""));
	m_strBK10_106_basic1    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_106_BASIC1, _T(""));
	m_strBK10_107_basic2    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_107_BASIC2, _T(""));
	m_strBK10_108_basic3    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_108_BASIC3, _T(""));
	m_strBK11_201_bos       = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_201_BOS, _T(""));
	m_strBK11_202_ext       = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_202_EXT, _T(""));
	m_strBK11_203_mstd      = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_203_MSTD, _T(""));
	m_strBK11_198_basic1    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_198_BASIC1, _T(""));
	m_strBK11_199_basic2    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_199_BASIC2, _T(""));
	m_strBK11_200_basic3    = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_200_BASIC3, _T(""));
	m_strBK11m_324_bos      = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_324_BOS, _T(""));
	m_strBK11m_325_ext      = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_325_EXT, _T(""));
	m_strBK11m_330_mstd     = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_330_MSTD, _T(""));
	m_strBK11m_327_basic1   = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_327_BASIC1, _T(""));
	m_strBK11m_328_basic2   = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_328_BASIC2, _T(""));
	m_strBK11m_329_basic3   = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_329_BASIC3, _T(""));
	m_strFDD_Std            = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR, _T(""));
	m_strFDD_A16M           = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR_A16M, _T(""));
	m_strFDD_SMK512         = iniFile.GetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR_SMK512, _T(""));
	// Инициализация директорий
	m_strBinPath        = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_PROGRAM_DIRECTORY, _T("Bin")));
	m_strToolsPath      = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_TOOLS_DIRECTORY, _T("Tools")));
	m_strMemPath        = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_MEM_DIRECTORY, _T("Memory")));
	m_strSavesPath      = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_SAVES_DIRECTORY, _T("UserSaves")));
	m_strTapePath       = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_TAPES_DIRECTORY, _T("Tapes")));
	m_strScriptsPath    = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_SCRIPTS_DIRECTORY, _T("Scripts")));
	m_strROMPath        = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_ROM_DIRECTORY, _T("ROM")));
	m_strIMGPath        = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_IMG_DIRECTORY, _T("Img")));
	m_strScreenShotsPath = NormalizePath(GetCurrentPath() + iniFile.GetValueString(IDS_INI_DIRECTORIES, IDS_INI_SSHOT_DIRECTORY, _T("Screenshots")));
	// Инициализация параметров
	m_strBKBoardType = iniFile.GetValueString(IDS_INI_PARAMETERS, IDS_INI_BKMODEL, g_mstrConfigBKModelParameters[CONFIG_BKMODEL_STRING_BK_0010_01].strBKModelConfigName);
	m_nCPURunAddr       = OctStringToWord(iniFile.GetValueString(IDS_INI_PARAMETERS, IDS_INI_CPU_RUN_ADDR, _T("0")));  //если 0, то берётся значение по умолчанию для своей конфигурации
	m_nCPUFrequency     = iniFile.GetValueInt(IDS_INI_PARAMETERS, IDS_INI_CPU_FREQUENCY, 0);  //если 0, то берётся значение по умолчанию для своей конфигурации
	m_nRegistersDumpInterval = iniFile.GetValueInt(IDS_INI_PARAMETERS, IDS_INI_REGSDUMP_INTERVAL, 0);  //если 0, то выключено
	m_nScreenshotNumber = iniFile.GetValueInt(IDS_INI_PARAMETERS, IDS_INI_SSHOT_NUM, 1);
	CString strSoundVal = iniFile.GetValueString(IDS_INI_PARAMETERS, IDS_INI_SOUNDVOLUME, _T("30%"));// Громкость
	m_nSoundVolume      = 0xffff * _tstoi(strSoundVal) / 100;
	m_nScreenRenderType = iniFile.GetValueInt(IDS_INI_PARAMETERS, IDS_INI_SCRRENDER_TYPE, ((IsWindowsVistaOrGreater()) ? CONF_SCREEN_RENDER_D2D : CONF_SCREEN_RENDER_DIB));

	//проверим на корректность подсунутых нам значений из ini
	if (m_nScreenRenderType < CONF_SCREEN_RENDER_OGL || m_nScreenRenderType > CONF_SCREEN_RENDER_D3D)
	{
		m_nScreenRenderType = CONF_SCREEN_RENDER_D2D;
	}

	if (!IsWindowsVistaOrGreater())
	{
		//если windows xp, то проверим на предмет неподдержиывемых рендеров
		if (m_nScreenRenderType == CONF_SCREEN_RENDER_D2D) //D2D не поддерживается
		{
			m_nScreenRenderType = CONF_SCREEN_RENDER_DIB; //заменяется на DIB
		}
	}

	m_nOscRenderType = iniFile.GetValueInt(IDS_INI_PARAMETERS, IDS_INI_OSCRENDER_TYPE, ((IsWindowsVistaOrGreater()) ? CONF_OSCILL_RENDER_D2D : CONF_OSCILL_RENDER_OGL));

	//проверим на корректность подсунутых нам значений из ini
	if (m_nOscRenderType < CONF_OSCILL_RENDER_OGL || m_nOscRenderType > CONF_OSCILL_RENDER_GDI)
	{
		m_nOscRenderType = CONF_OSCILL_RENDER_D2D;
	}

	if (!IsWindowsVistaOrGreater())
	{
		//если windows xp, то проверим на предмет неподдержиывемых рендеров
		if (m_nOscRenderType == CONF_OSCILL_RENDER_D2D) //D2D не поддерживается
		{
			m_nOscRenderType = CONF_OSCILL_RENDER_OGL; //заменяется на OGL
		}
	}

	// Инициализация опций
	m_bSavesDefault     = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_SAVES_DEFAULT, FALSE);
	m_bSpeaker          = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER, TRUE);
	m_bSpeakerFilter    = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER_FILTHER, TRUE);
	m_bCovox            = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX, TRUE);
	m_bCovoxFilter      = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_FILTHER, TRUE);
	m_bStereoCovox      = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_STEREO, FALSE);
	m_bAY8910           = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910, TRUE);

	if (m_bAY8910) //у сопра приоритет перед ковоксом
	{
		m_bCovox = FALSE;
	}

	m_bAY8910Filter     = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910_FILTHER, TRUE);
	m_bBKKeyboard       = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_BKKEYBOARD, TRUE);
	m_bJoystick         = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_JOYSTICK, TRUE);
	m_bColorMode        = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_COLOR_MODE, TRUE); //параметры экрана
	m_bAdaptBWMode      = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_BLACK_WHITE, FALSE);
	m_bLuminoforeEmulMode = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_LUMINOFOREMODE, FALSE);
	m_bFullscreenMode   = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_FULL_SCREEN, FALSE);
	m_bPauseCPUAfterStart = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_PAUSE_CPU, FALSE);
	m_bAskForBreak      = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_ASK_FOR_BREAK, FALSE);
	m_bEmulateLoadTape  = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_LOAD_TAPE, TRUE);
	m_bEmulateSaveTape  = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_SAVE_TAPE, TRUE);
	m_bTapeAutoBeginDetection = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_BEG_TAPE, TRUE);
	m_bTapeAutoEnsDetection = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_END_TAPE, TRUE);
	m_bShowPerformance  = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_SHOW_PERFORMANCE_STRING, TRUE);
	m_bEmulateFDDIO     = iniFile.GetValueBool(IDS_INI_OPTIONS, IDS_INI_EMULATE_FDDIO, TRUE);
	m_nAdrDump          = OctStringToWord(iniFile.GetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DUMP, _T("0")));
	m_nAdrAsm           = OctStringToWord(iniFile.GetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DISASM, _T("1000")));
	m_nVKBDType         = iniFile.GetValueInt(IDS_INI_OPTIONS, IDS_INI_VKBD_TYPE, 0);
	// Инициализация приводов
	m_strDrives[0]      = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEA, g_strEmptyUnit);
	m_strDrives[1]      = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEB, g_strEmptyUnit);
	m_strDrives[2]      = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEC, g_strEmptyUnit);
	m_strDrives[3]      = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_DRIVED, g_strEmptyUnit);
	m_strHDDrives[0]    = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_HDD0, g_strEmptyUnit);
	m_strHDDrives[1]    = iniFile.GetValueString(IDS_INI_DRIVES, IDS_INI_HDD1, g_strEmptyUnit);
}

ULONGLONG CConfig::SaveConfig(BOOL bSaveToMemory, BYTE *pBuff, UINT nSize)
{
	// Сохранение Rom модулей - только по чтению, их не модифицируем
	// Сохранение директорий - только по чтению, их не модифицируем
	// Сохранение параметров
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_BKMODEL, m_strBKBoardType);
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_CPU_RUN_ADDR, WordToOctString(m_nCPURunAddr));
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_CPU_FREQUENCY, m_nCPUFrequency);
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_REGSDUMP_INTERVAL, m_nRegistersDumpInterval);
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_SSHOT_NUM, m_nScreenshotNumber);
	//Сохраняем Громкость
	CString strSoundVal;
	double d = (double)m_nSoundVolume * 100.0 / 0xffff + 0.01;
	strSoundVal.Format(_T("%d%%"), (int)d);
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_SOUNDVOLUME, strSoundVal);
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_SCRRENDER_TYPE, m_nScreenRenderType);
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_OSCRENDER_TYPE, m_nOscRenderType);
	// Сохранение опций
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SAVES_DEFAULT, m_bSavesDefault);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER, m_bSpeaker);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER_FILTHER, m_bSpeakerFilter);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX, m_bCovox);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_FILTHER, m_bCovoxFilter);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_STEREO, m_bStereoCovox);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910, m_bAY8910);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910_FILTHER, m_bAY8910Filter);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_BKKEYBOARD, m_bBKKeyboard);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_JOYSTICK, m_bJoystick);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COLOR_MODE, m_bColorMode);    //параметры экрана
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_BLACK_WHITE, m_bAdaptBWMode);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_LUMINOFOREMODE, m_bLuminoforeEmulMode);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_FULL_SCREEN, m_bFullscreenMode);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_PAUSE_CPU, m_bPauseCPUAfterStart);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_ASK_FOR_BREAK, m_bAskForBreak);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_LOAD_TAPE, m_bEmulateLoadTape);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_SAVE_TAPE, m_bEmulateSaveTape);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_BEG_TAPE, m_bTapeAutoBeginDetection);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_END_TAPE, m_bTapeAutoEnsDetection);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SHOW_PERFORMANCE_STRING, m_bShowPerformance);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMULATE_FDDIO, m_bEmulateFDDIO);
	iniFile.SetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DUMP, WordToOctString(m_nAdrDump));
	iniFile.SetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DISASM, WordToOctString(m_nAdrAsm));
	iniFile.SetValueInt(IDS_INI_OPTIONS, IDS_INI_VKBD_TYPE, m_nVKBDType);
	// Сохранение приводов
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEA, m_strDrives[0]);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEB, m_strDrives[1]);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEC, m_strDrives[2]);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVED, m_strDrives[3]);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_HDD0, m_strHDDrives[0]);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_HDD1, m_strHDDrives[1]);

	if (bSaveToMemory)
	{
		return iniFile.FlushIniToMemory(pBuff, nSize);
	}
	else
	{
		iniFile.FlushIni();
	}

	return 0;
}

void CConfig::DefaultConfig()
{
	//идея следующая.
	//Создадим конфиг со значениями по умолчанию, и сохраним его на диске.
	// Создание Rom модулей
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_017_MONITOR, _T("bk10_017_mon.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_018_FOCAL, _T("bk10_018_focal.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_019_MSTD, _T("bk10_019_mstd.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_106_BASIC1, _T("bk10_106_basic1.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_107_BASIC2, _T("bk10_107_basic2.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK10_RE2_108_BASIC3, _T("bk10_108_basic3.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_201_BOS, _T("bk11_201_bos.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_202_EXT, _T("bk11_202_ext.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_203_MSTD, _T("bk11_203_mstd.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_198_BASIC1, _T("bk11_198_basic1.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_199_BASIC2, _T("bk11_199_basic2.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE2_200_BASIC3, _T("bk11_200_basic3.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_324_BOS, _T("bk11m_324_bos.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_325_EXT, _T("bk11m_325_ext.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_330_MSTD, _T("bk11m_330_mstd.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_327_BASIC1, _T("bk11m_327_basic1.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_328_BASIC2, _T("bk11m_328_basic2.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11M_RE2_329_BASIC3, _T("bk11m_329_basic3.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR, _T("DISK_326.ROM"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR_A16M, _T("DISK_A16M_v2.41.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_FDR_SMK512, _T("DISK_SMK512_v2.05.rom"));
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE_OPT_PG12_1, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE_OPT_PG12_2, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE_OPT_PG13_1, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_ROMMODULES, IDS_INI_BK11_RE_OPT_PG13_2, g_strEmptyUnit);
	// Создание директорий
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_PROGRAM_DIRECTORY, _T("Bin"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_TOOLS_DIRECTORY, _T("Tools"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_MEM_DIRECTORY, _T("Memory"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_SAVES_DIRECTORY, _T("UserSaves"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_TAPES_DIRECTORY, _T("Tapes"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_SCRIPTS_DIRECTORY, _T("Scripts"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_ROM_DIRECTORY, _T("ROM"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_IMG_DIRECTORY, _T("Img"));
	iniFile.SetValueString(IDS_INI_DIRECTORIES, IDS_INI_SSHOT_DIRECTORY, _T("Screenshots"));
	// Создание параметров
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_BKMODEL, g_mstrConfigBKModelParameters[CONFIG_BKMODEL_STRING_BK_0010_01].strBKModelConfigName);
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_CPU_RUN_ADDR, _T("0"));  //если 0, то берётся значение по умолчанию для своей конфигурации
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_CPU_FREQUENCY, 0);  //если 0, то берётся значение по умолчанию для своей конфигурации
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_REGSDUMP_INTERVAL, 10);
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_SSHOT_NUM, 1);
	iniFile.SetValueString(IDS_INI_PARAMETERS, IDS_INI_SOUNDVOLUME, _T("30%")); // Громкость
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_SCRRENDER_TYPE, ((IsWindowsVistaOrGreater()) ? CONF_SCREEN_RENDER_D2D : CONF_SCREEN_RENDER_DIB));
	iniFile.SetValueInt(IDS_INI_PARAMETERS, IDS_INI_OSCRENDER_TYPE, ((IsWindowsVistaOrGreater()) ? CONF_OSCILL_RENDER_D2D : CONF_OSCILL_RENDER_OGL));
	// Создание опций
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SAVES_DEFAULT, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SPEAKER_FILTHER, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_FILTHER, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COVOX_STEREO, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AY8910_FILTHER, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_BKKEYBOARD, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_JOYSTICK, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_COLOR_MODE, TRUE);    //параметры экрана
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_BLACK_WHITE, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_LUMINOFOREMODE, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_FULL_SCREEN, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_PAUSE_CPU, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_ASK_FOR_BREAK, FALSE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_LOAD_TAPE, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMUL_SAVE_TAPE, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_BEG_TAPE, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_AUTO_END_TAPE, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_SHOW_PERFORMANCE_STRING, TRUE);
	iniFile.SetValueBool(IDS_INI_OPTIONS, IDS_INI_EMULATE_FDDIO, TRUE);
	iniFile.SetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DUMP, _T("0"));
	iniFile.SetValueString(IDS_INI_OPTIONS, IDS_INI_ADDR_DISASM, _T("1000"));
	iniFile.SetValueInt(IDS_INI_OPTIONS, IDS_INI_VKBD_TYPE, 0);
	// Создание приводов
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEA, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEB, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVEC, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_DRIVED, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_HDD0, g_strEmptyUnit);
	iniFile.SetValueString(IDS_INI_DRIVES, IDS_INI_HDD1, g_strEmptyUnit);
	iniFile.FlushIni();
}

BOOL CConfig::VerifyRoms()
{
	static CString *pstrROMNames[] =
	{
		&m_strBK10_017_Monitor,
		&m_strBK10_018_Focal,
		&m_strBK10_019_MSTD,
		&m_strBK10_106_basic1,
		&m_strBK10_107_basic2,
		&m_strBK10_108_basic3,
		&m_strBK11_201_bos,
		&m_strBK11_202_ext,
		&m_strBK11_203_mstd,
		&m_strBK11_198_basic1,
		&m_strBK11_199_basic2,
		&m_strBK11_200_basic3,
		&m_strBK11m_324_bos,
		&m_strBK11m_325_ext,
		&m_strBK11m_330_mstd,
		&m_strBK11m_327_basic1,
		&m_strBK11m_328_basic2,
		&m_strBK11m_329_basic3,
		&m_strFDD_Std,
		&m_strFDD_A16M,
		&m_strFDD_SMK512,
		NULL
	};
	int p = 0;
	CString strPath;
	CString strError;
	strError.LoadString(IDS_ERRMSG_NOTROM);
	CString *pStr;
	CFile file;
	BOOL bRes = TRUE;

	while ((pStr = pstrROMNames[p]) != NULL)
	{
		BOOL bOK = FALSE;

		if (!pStr->IsEmpty())
		{
			strPath = m_strROMPath + *pStr;

			if (file.Open(strPath, CFile::modeRead))
			{
				file.Close();
				bOK = TRUE;
			}
		}

		if (!bOK)
		{
			CBKMessageBox(strError + _T(" \'") + strPath + _T("\'"), MB_OK | MB_ICONSTOP);
			bRes = FALSE;
		}

		p++;
	}

	return bRes;
}

//возвращает номер текущей конфигурации.
//выход: если найдено, то номер. если не найдено - то 0 (значение по умолчанию)
CONFIG_BKMODEL_STRING CConfig::GetBKModelNumber()
{
	for (int t = 0; t < CONFIG_BKMODEL_STRINGS_NUMBER; ++t)
	{
		if (g_mstrConfigBKModelParameters[t].strBKModelConfigName == m_strBKBoardType)
		{
			return static_cast<CONFIG_BKMODEL_STRING>(t);
		}
	}

	return CONFIG_BKMODEL_STRING_BK_0010_01;
}

void CConfig::SetBKModelNumber(CONFIG_BKMODEL_STRING n)
{
	m_strBKBoardType = g_mstrConfigBKModelParameters[n].strBKModelConfigName;
}

CString CConfig::GetHDDriveImgName(int nDrive)
{
	nDrive &= 1;

	if (m_strHDDrives[nDrive].CompareNoCase(g_strEmptyUnit))
	{
		//прочитаем путь заданного привода
		CString strPath = GetFilePath(m_strHDDrives[nDrive]);

		if (strPath.IsEmpty()) //если путь в имени образа отсутствует
		{
			//то возвращаем имя с полным путём к домашней папке
			return m_strIMGPath + m_strHDDrives[nDrive];
		}
	}

	//иначе, возвращаем имя как есть, предполагаем, что там путь верный.
	return m_strHDDrives[nDrive];
}

CString CConfig::GetDriveImgName(int nDrive)
{
	nDrive &= 3;

	if (m_strDrives[nDrive].CompareNoCase(g_strEmptyUnit))
	{
		//прочитаем путь заданного привода
		CString strPath = GetFilePath(m_strDrives[nDrive]);

		if (strPath.IsEmpty()) //если путь в имени образа отсутствует
		{
			//то возвращаем имя с полным путём к домашней папке
			return m_strIMGPath + m_strDrives[nDrive];
		}
	}

	//иначе, возвращаем имя как есть, предполагаем, что там путь верный.
	return m_strDrives[nDrive];
}

void CConfig::SetDriveImgName(int nDrive, const CString &strPathName)
{
	nDrive &= 3;

	if (strPathName.CompareNoCase(g_strEmptyUnit))
	{
		CString strPath = GetFilePath(strPathName); //выделим путь из входного имени

		//если путь совпадает с путем к домашней директории
		if (strPath.CompareNoCase(m_strIMGPath) == 0)
		{
			//то его удалим
			m_strDrives[nDrive & 3] = GetFileName(strPathName);
			return;
		}
	}

	//иначе - сохраним как есть.
	m_strDrives[nDrive & 3] = strPathName;
}
