395 lines
12 KiB
C++
395 lines
12 KiB
C++
/* This file is part of BKBTL.
|
|
BKBTL is free software: you can redistribute it and/or modify it under the terms
|
|
of the GNU Lesser General Public License as published by the Free Software Foundation,
|
|
either version 3 of the License, or (at your option) any later version.
|
|
BKBTL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU Lesser General Public License for more details.
|
|
You should have received a copy of the GNU Lesser General Public License along with
|
|
BKBTL. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
// Settings.cpp
|
|
|
|
#include "stdafx.h"
|
|
#include "Main.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
const TCHAR m_Settings_IniAppName[] = _T("BKBTL");
|
|
TCHAR m_Settings_IniPath[MAX_PATH];
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Options
|
|
|
|
bool Option_ShowHelp = false;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void Settings_Init()
|
|
{
|
|
// Prepare m_Settings_IniPath: get .exe file path and change extension to .ini
|
|
::GetModuleFileName(GetModuleHandle(NULL), m_Settings_IniPath, MAX_PATH);
|
|
TCHAR* pExt = m_Settings_IniPath + _tcslen(m_Settings_IniPath) - 3;
|
|
*pExt++ = _T('i');
|
|
*pExt++ = _T('n');
|
|
*pExt = _T('i');
|
|
}
|
|
void Settings_Done()
|
|
{
|
|
}
|
|
|
|
BOOL Settings_SaveStringValue(LPCTSTR sName, LPCTSTR sValue)
|
|
{
|
|
BOOL result = WritePrivateProfileString(
|
|
m_Settings_IniAppName, sName, sValue, m_Settings_IniPath);
|
|
return result;
|
|
}
|
|
BOOL Settings_LoadStringValue(LPCTSTR sName, LPTSTR sBuffer, int nBufferLengthChars)
|
|
{
|
|
DWORD result = GetPrivateProfileString(
|
|
m_Settings_IniAppName, sName, NULL, sBuffer, nBufferLengthChars, m_Settings_IniPath);
|
|
if (result > 0)
|
|
return TRUE;
|
|
|
|
sBuffer[0] = _T('\0');
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL Settings_SaveDwordValue(LPCTSTR sName, DWORD dwValue)
|
|
{
|
|
TCHAR buffer[12];
|
|
_sntprintf(buffer, sizeof(buffer) / sizeof(TCHAR) - 1, _T("%lu"), dwValue);
|
|
|
|
return Settings_SaveStringValue(sName, buffer);
|
|
}
|
|
BOOL Settings_LoadDwordValue(LPCTSTR sName, DWORD* dwValue)
|
|
{
|
|
TCHAR buffer[12];
|
|
if (!Settings_LoadStringValue(sName, buffer, 12))
|
|
return FALSE;
|
|
|
|
int result = _stscanf(buffer, _T("%lu"), dwValue);
|
|
if (result == 0)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL Settings_SaveColorValue(LPCTSTR sName, COLORREF color)
|
|
{
|
|
// 00BBGGRR -> 00RRGGBB conversion
|
|
DWORD dwValue = ((color & 0x0000ff) << 16) | (color & 0x00ff00) | ((color & 0xff0000) >> 16);
|
|
|
|
TCHAR buffer[12];
|
|
_sntprintf(buffer, sizeof(buffer) / sizeof(TCHAR) - 1, _T("%06lX"), dwValue);
|
|
|
|
return Settings_SaveStringValue(sName, buffer);
|
|
}
|
|
BOOL Settings_LoadColorValue(LPCTSTR sName, COLORREF* pColor)
|
|
{
|
|
TCHAR buffer[12];
|
|
if (!Settings_LoadStringValue(sName, buffer, 12))
|
|
return FALSE;
|
|
|
|
DWORD dwValue;
|
|
int result = _stscanf(buffer, _T("%lX"), &dwValue);
|
|
if (result == 0)
|
|
return FALSE;
|
|
|
|
// 00RRGGBB -> 00BBGGRR conversion
|
|
*pColor = ((dwValue & 0x0000ff) << 16) | (dwValue & 0x00ff00) | ((dwValue & 0xff0000) >> 16);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL Settings_SaveBinaryValue(LPCTSTR sName, const void * pData, int size)
|
|
{
|
|
TCHAR* buffer = static_cast<TCHAR*>(::calloc(size * 2 + 1, sizeof(TCHAR)));
|
|
if (buffer == NULL)
|
|
return FALSE;
|
|
const BYTE* p = static_cast<const BYTE*>(pData);
|
|
TCHAR* buf = buffer;
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
int a = *p;
|
|
_sntprintf(buf, 3, _T("%02X"), a);
|
|
p++;
|
|
buf += 2;
|
|
}
|
|
|
|
BOOL result = Settings_SaveStringValue(sName, buffer);
|
|
|
|
free(buffer);
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL Settings_LoadBinaryValue(LPCTSTR sName, void * pData, int size)
|
|
{
|
|
size_t buffersize = size * 2 + 1;
|
|
TCHAR* buffer = static_cast<TCHAR*>(::calloc(buffersize, sizeof(TCHAR)));
|
|
if (buffer == NULL)
|
|
return FALSE;
|
|
if (!Settings_LoadStringValue(sName, buffer, buffersize))
|
|
{
|
|
free(buffer);
|
|
return FALSE;
|
|
}
|
|
|
|
BYTE* p = static_cast<BYTE*>(pData);
|
|
TCHAR* buf = buffer;
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
BYTE v = 0;
|
|
|
|
TCHAR ch = *buf;
|
|
if (ch >= _T('0') && ch <= _T('9'))
|
|
v = (BYTE)(ch - _T('0'));
|
|
else if (ch >= _T('A') && ch <= _T('F'))
|
|
v = (BYTE)(ch - _T('A') + 10);
|
|
else // Not hex
|
|
{
|
|
free(buffer);
|
|
return FALSE;
|
|
}
|
|
buf++;
|
|
|
|
v = v << 4;
|
|
|
|
ch = *buf;
|
|
if (ch >= _T('0') && ch <= _T('9'))
|
|
v |= (BYTE)(ch - _T('0'));
|
|
else if (ch >= _T('A') && ch <= _T('F'))
|
|
v |= (BYTE)(ch - _T('A') + 10);
|
|
else // Not hex
|
|
{
|
|
free(buffer);
|
|
return FALSE;
|
|
}
|
|
buf++;
|
|
|
|
*p = v;
|
|
p++;
|
|
}
|
|
|
|
free(buffer);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#define SETTINGS_GETSET_DWORD(PARAMNAME, PARAMNAMESTR, OUTTYPE, DEFVALUE) \
|
|
OUTTYPE m_Settings_##PARAMNAME = DEFVALUE; \
|
|
BOOL m_Settings_##PARAMNAME##_Valid = FALSE; \
|
|
void Settings_Set##PARAMNAME(OUTTYPE newvalue) { \
|
|
m_Settings_##PARAMNAME = newvalue; \
|
|
m_Settings_##PARAMNAME##_Valid = TRUE; \
|
|
Settings_SaveDwordValue(PARAMNAMESTR, (DWORD) newvalue); \
|
|
} \
|
|
OUTTYPE Settings_Get##PARAMNAME() { \
|
|
if (!m_Settings_##PARAMNAME##_Valid) { \
|
|
DWORD dwValue = (DWORD)(DEFVALUE); \
|
|
Settings_LoadDwordValue(PARAMNAMESTR, &dwValue); \
|
|
m_Settings_##PARAMNAME = (OUTTYPE) dwValue; \
|
|
m_Settings_##PARAMNAME##_Valid = TRUE; \
|
|
} \
|
|
return m_Settings_##PARAMNAME; \
|
|
}
|
|
|
|
|
|
BOOL Settings_GetWindowRect(RECT * pRect)
|
|
{
|
|
RECT rc;
|
|
if (Settings_LoadBinaryValue(_T("WindowRect"), &rc, sizeof(RECT)))
|
|
{
|
|
::memcpy(pRect, &rc, sizeof(RECT));
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
void Settings_SetWindowRect(const RECT * pRect)
|
|
{
|
|
Settings_SaveBinaryValue(_T("WindowRect"), pRect, sizeof(RECT));
|
|
}
|
|
|
|
SETTINGS_GETSET_DWORD(WindowMaximized, _T("WindowMaximized"), BOOL, FALSE);
|
|
|
|
SETTINGS_GETSET_DWORD(Configuration, _T("Configuration"), int, 0);
|
|
|
|
void Settings_GetFloppyFilePath(int slot, LPTSTR buffer)
|
|
{
|
|
TCHAR bufValueName[8];
|
|
lstrcpy(bufValueName, _T("Floppy0"));
|
|
bufValueName[6] = _T('0') + (TCHAR)slot;
|
|
Settings_LoadStringValue(bufValueName, buffer, MAX_PATH);
|
|
}
|
|
void Settings_SetFloppyFilePath(int slot, LPCTSTR sFilePath)
|
|
{
|
|
TCHAR bufValueName[8];
|
|
lstrcpy(bufValueName, _T("Floppy0"));
|
|
bufValueName[6] = _T('0') + (TCHAR)slot;
|
|
Settings_SaveStringValue(bufValueName, sFilePath);
|
|
}
|
|
|
|
SETTINGS_GETSET_DWORD(ScreenViewMode, _T("ScreenViewMode"), int, 0);
|
|
|
|
SETTINGS_GETSET_DWORD(ScreenHeightMode, _T("ScreenHeightMode"), int, 0);
|
|
|
|
SETTINGS_GETSET_DWORD(Toolbar, _T("Toolbar"), BOOL, TRUE);
|
|
|
|
SETTINGS_GETSET_DWORD(Debug, _T("Debug"), BOOL, FALSE);
|
|
|
|
void Settings_GetDebugFontName(LPTSTR buffer)
|
|
{
|
|
if (!Settings_LoadStringValue(_T("DebugFontName"), buffer, 32))
|
|
{
|
|
_tcscpy(buffer, _T("Lucida Console"));
|
|
}
|
|
}
|
|
void Settings_SetDebugFontName(LPCTSTR sFontName)
|
|
{
|
|
Settings_SaveStringValue(_T("DebugFontName"), sFontName);
|
|
}
|
|
|
|
void Settings_SetDebugBreakpoint(int bpno, WORD address)
|
|
{
|
|
TCHAR bufValueName[14];
|
|
lstrcpy(bufValueName, _T("DebugBreakpt0"));
|
|
bufValueName[12] = bpno < 10 ? _T('0') + (TCHAR)bpno : _T('A') + (TCHAR)(bpno - 10);
|
|
if (address == 0177777)
|
|
Settings_SaveStringValue(bufValueName, NULL); // delete value
|
|
else
|
|
Settings_SaveDwordValue(bufValueName, address);
|
|
}
|
|
WORD Settings_GetDebugBreakpoint(int bpno)
|
|
{
|
|
TCHAR bufValueName[14];
|
|
lstrcpy(bufValueName, _T("DebugBreakpt0"));
|
|
bufValueName[12] = bpno < 10 ? _T('0') + (TCHAR)bpno : _T('A') + (TCHAR)(bpno - 10);
|
|
DWORD dwValue = 0xFFFFFFFF;
|
|
Settings_LoadDwordValue(bufValueName, &dwValue);
|
|
return (WORD)dwValue;
|
|
}
|
|
|
|
SETTINGS_GETSET_DWORD(DebugMemoryAddress, _T("DebugMemoryAddress"), WORD, 0);
|
|
SETTINGS_GETSET_DWORD(DebugMemoryBase, _T("DebugMemoryBase"), WORD, 0);
|
|
SETTINGS_GETSET_DWORD(DebugMemoryByte, _T("DebugMemoryByte"), BOOL, FALSE);
|
|
SETTINGS_GETSET_DWORD(DebugMemoryNumeral, _T("DebugMemoryNumeral"), WORD, 0);
|
|
|
|
SETTINGS_GETSET_DWORD(Autostart, _T("Autostart"), BOOL, FALSE);
|
|
|
|
SETTINGS_GETSET_DWORD(RealSpeed, _T("RealSpeed"), WORD, 1);
|
|
|
|
SETTINGS_GETSET_DWORD(Sound, _T("Sound"), BOOL, FALSE);
|
|
SETTINGS_GETSET_DWORD(SoundVolume, _T("SoundVolume"), WORD, 0x3fff);
|
|
SETTINGS_GETSET_DWORD(SoundCovox, _T("SoundCovox"), BOOL, FALSE);
|
|
SETTINGS_GETSET_DWORD(SoundAY, _T("SoundAY"), BOOL, FALSE);
|
|
|
|
SETTINGS_GETSET_DWORD(Joystick, _T("Joystick"), int, 0);
|
|
|
|
SETTINGS_GETSET_DWORD(Keyboard, _T("Keyboard"), BOOL, TRUE);
|
|
|
|
SETTINGS_GETSET_DWORD(Tape, _T("Tape"), BOOL, FALSE);
|
|
|
|
SETTINGS_GETSET_DWORD(MemoryMap, _T("MemoryMap"), BOOL, FALSE);
|
|
|
|
SETTINGS_GETSET_DWORD(SpriteAddress, _T("SpriteAddress"), WORD, 0);
|
|
|
|
SETTINGS_GETSET_DWORD(SpriteWidth, _T("SpriteWidth"), WORD, 2);
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Colors
|
|
|
|
struct ColorDescriptorStruct
|
|
{
|
|
LPCTSTR settingname;
|
|
COLORREF defaultcolor;
|
|
BOOL valid;
|
|
LPCTSTR friendlyname;
|
|
COLORREF currentcolor;
|
|
}
|
|
static ColorDescriptors[ColorIndicesCount] =
|
|
{
|
|
{ _T("ColorDebugText"), RGB(0, 0, 0), FALSE, _T("Debug Text") },
|
|
{ _T("ColorDebugBackCurrent"), RGB(255, 255, 224), FALSE, _T("Debug Current Line Background") },
|
|
{ _T("ColorDebugValueChanged"), RGB(255, 0, 0), FALSE, _T("Debug Value Changed") },
|
|
{ _T("ColorDebugPrevious"), RGB(0, 0, 255), FALSE, _T("Debug Previous Address Marker") },
|
|
{ _T("ColorDebugMemoryROM"), RGB(0, 0, 255), FALSE, _T("Debug Memory ROM") },
|
|
{ _T("ColorDebugMemoryIO"), RGB(0, 128, 0), FALSE, _T("Debug Memory IO") },
|
|
{ _T("ColorDebugMemoryNA"), RGB(128, 128, 128), FALSE, _T("Debug Memory NA") },
|
|
{ _T("ColorDebugValue"), RGB(128, 128, 128), FALSE, _T("Debug Value") },
|
|
{ _T("ColorDebugValueRom"), RGB(128, 128, 192), FALSE, _T("Debug Value ROM") },
|
|
{ _T("ColorDebugSubtitles"), RGB(0, 128, 0), FALSE, _T("Debug Subtitles") },
|
|
{ _T("ColorDebugJump"), RGB(80, 192, 224), FALSE, _T("Debug Jump") },
|
|
{ _T("ColorDebugJumpYes"), RGB(80, 240, 80), FALSE, _T("Debug Jump Yes") },
|
|
{ _T("ColorDebugJumpNo"), RGB(180, 180, 180), FALSE, _T("Debug Jump No") },
|
|
{ _T("ColorDebugJumpHint"), RGB(40, 128, 160), FALSE, _T("Debug Jump Hint") },
|
|
{ _T("ColorDebugHint"), RGB(40, 40, 160), FALSE, _T("Debug Hint") },
|
|
{ _T("ColorDebugBreakpoint"), RGB(255, 128, 128), FALSE, _T("Debug Breakpoint") },
|
|
{ _T("ColorDebugHighlight"), RGB(200, 230, 255), FALSE, _T("Debug Highlight") },
|
|
{ _T("ColorDebugBreakptZone"), RGB(242, 242, 242), FALSE, _T("Debug Breakpoint Zone") },
|
|
};
|
|
|
|
LPCTSTR Settings_GetColorFriendlyName(ColorIndices colorIndex)
|
|
{
|
|
ColorDescriptorStruct* desc = ColorDescriptors + colorIndex;
|
|
|
|
return desc->friendlyname;
|
|
}
|
|
|
|
COLORREF Settings_GetColor(ColorIndices colorIndex)
|
|
{
|
|
if (colorIndex < 0 || colorIndex >= ColorIndicesCount)
|
|
return 0;
|
|
|
|
ColorDescriptorStruct* desc = ColorDescriptors + colorIndex;
|
|
|
|
if (desc->valid)
|
|
return desc->currentcolor;
|
|
|
|
COLORREF color;
|
|
if (Settings_LoadColorValue(desc->settingname, &color))
|
|
desc->currentcolor = color;
|
|
else
|
|
desc->currentcolor = desc->defaultcolor;
|
|
|
|
desc->valid = TRUE;
|
|
return desc->currentcolor;
|
|
}
|
|
|
|
void Settings_SetColor(ColorIndices colorIndex, COLORREF color)
|
|
{
|
|
if (colorIndex < 0 || colorIndex >= ColorIndicesCount)
|
|
return;
|
|
|
|
ColorDescriptorStruct* desc = ColorDescriptors + colorIndex;
|
|
|
|
desc->currentcolor = color;
|
|
desc->valid = TRUE;
|
|
|
|
Settings_SaveColorValue(desc->settingname, color);
|
|
}
|
|
|
|
COLORREF Settings_GetDefaultColor(ColorIndices colorIndex)
|
|
{
|
|
if (colorIndex < 0 || colorIndex >= ColorIndicesCount)
|
|
return 0;
|
|
|
|
ColorDescriptorStruct* desc = ColorDescriptors + colorIndex;
|
|
|
|
return desc->defaultcolor;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|