www.pudn.com > ncdzsrc.rar > config.c
/***************************************************************************
config.c
オプション設定ファイルの読み書き
***************************************************************************/
#include "neogeocd.h"
#include "win32/win32.h"
#include "win32/misc.h"
#define LINEBUF_SIZE 256
enum
{
CFG_NONE = 0,
CFG_INT,
CFG_BOOL,
CFG_STR,
CFG_KEY,
CFG_JOY
};
typedef struct cfg_t
{
int type;
const char *name;
void *value;
int min;
int max;
} cfg_type;
/****************************************************************************
プロトタイプ
***************************************************************************/
static void init_options(void);
static int load_inifile(const char *fname, cfg_type *cfg);
static int save_inifile(const char *fname, cfg_type *cfg);
static int get_config_bool(char *str);
static int get_config_int(char *str, int minval, int maxval);
static void get_config_string(char *str, char *value_str);
static const char *set_config_bool(int value);
static int set_config_int(int value, int minval, int maxval);
/****************************************************************************
ローカル変数
***************************************************************************/
static const char *inifile_name = "ncdz.ini";
/****************************************************************************
グローバル構造体
***************************************************************************/
options_type options;
/****************************************************************************
ローカル構造体
***************************************************************************/
static cfg_type default_cfg[] =
{
{ CFG_NONE, "[Path and File Settings]", },
{ CFG_STR, "ScreenShotDirectory", options.snapdir, 0, 0 },
{ CFG_NONE, "[Machine Settings]", },
{ CFG_INT, "RegionSwitch", &options.region, 0, 2 },
{ CFG_STR, "CDRomDrive", options.drive_str, 0, 0 },
{ CFG_INT, "CDRomSpeedLimit", &options.cdspeed, 0, 5 },
{ CFG_NONE, "[Video Settings]", },
{ CFG_BOOL, "FullScreen", &options.fullscreen, 0, 0 },
{ CFG_BOOL, "SoftwareStretch2x", &options.sw_stretch2x, 0, 0 },
{ CFG_BOOL, "Scanlines", &options.scanlines, 0, 0 },
{ CFG_INT, "ScanlineBrightness", &options.sl_brightness, 0, 100 },
{ CFG_INT, "HardwareStretch", &options.hw_stretch, 0, 3 },
{ CFG_BOOL, "TripleBuffer", &options.use_triplebuffer, 0, 0 },
{ CFG_BOOL, "WaitVsync", &options.wait_vsync, 0, 0 },
{ CFG_BOOL, "DirectDrawHEL", &options.use_ddhel, 0, 0 },
{ CFG_BOOL, "UseSystemMemory", &options.use_sysmem, 0, 0 },
{ CFG_INT, "RefreshRate", &options.refreshrate, 0, 2 },
{ CFG_NONE, "[Audio Settings]", },
{ CFG_INT, "SampleRate", &options.samplerate, 0, 48000 },
{ CFG_INT, "SoundVolume", &options.sound_volume, 0, 200 },
{ CFG_INT, "SoundLatency", &options.latency, 1, 10 },
{ CFG_BOOL, "EnableCDDA", &options.enable_cdda, 0, 0 },
{ CFG_INT, "CDDAVolume", &options.cdda_volume, -1, 200 },
{ CFG_NONE, "[Other Settings]", },
{ CFG_BOOL, "AutoPause", &options.auto_pause, 0, 0 },
{ CFG_BOOL, "EnableMMX", &options.enable_mmx, 0, 0 },
{ CFG_BOOL, "EnableSSE", &options.enable_sse, 0, 0 },
{ CFG_INT, "SleepTime", &options.sleep_time, -1, 16 },
{ CFG_BOOL, "OutputLog", &options.errorlog, 0, 0 },
{ CFG_NONE, "[Player1 Keyboard]", },
{ CFG_KEY, "P1KeyUp", &options.key[0][0], 0, 0 },
{ CFG_KEY, "P1KeyDown", &options.key[0][1], 0, 0 },
{ CFG_KEY, "P1KeyLeft", &options.key[0][2], 0, 0 },
{ CFG_KEY, "P1KeyRight", &options.key[0][3], 0, 0 },
{ CFG_KEY, "P1KeyButtonA", &options.key[0][4], 0, 0 },
{ CFG_KEY, "P1KeyButtonB", &options.key[0][5], 0, 0 },
{ CFG_KEY, "P1KeyButtonC", &options.key[0][6], 0, 0 },
{ CFG_KEY, "P1KeyButtonD", &options.key[0][7], 0, 0 },
{ CFG_KEY, "P1KeyStart", &options.key[0][8], 0, 0 },
{ CFG_KEY, "P1KeySelect", &options.key[0][9], 0, 0 },
{ CFG_KEY, "P1KeyHotkey1", &options.key[0][10], 0, 0 },
{ CFG_KEY, "P1KeyHotkey2", &options.key[0][11], 0, 0 },
{ CFG_KEY, "P1KeyHotkey3", &options.key[0][12], 0, 0 },
{ CFG_KEY, "P1KeyHotkey4", &options.key[0][13], 0, 0 },
{ CFG_NONE, "[Player2 Keyboard]", },
{ CFG_KEY, "P2KeyUp", &options.key[1][0], 0, 0 },
{ CFG_KEY, "P2KeyDown", &options.key[1][1], 0, 0 },
{ CFG_KEY, "P2KeyLeft", &options.key[1][2], 0, 0 },
{ CFG_KEY, "P2KeyRight", &options.key[1][3], 0, 0 },
{ CFG_KEY, "P2KeyButtonA", &options.key[1][4], 0, 0 },
{ CFG_KEY, "P2KeyButtonB", &options.key[1][5], 0, 0 },
{ CFG_KEY, "P2KeyButtonC", &options.key[1][6], 0, 0 },
{ CFG_KEY, "P2KeyButtonD", &options.key[1][7], 0, 0 },
{ CFG_KEY, "P2KeyStart", &options.key[1][8], 0, 0 },
{ CFG_KEY, "P2KeySelect", &options.key[1][9], 0, 0 },
{ CFG_KEY, "P2KeyHotkey1", &options.key[1][10], 0, 0 },
{ CFG_KEY, "P2KeyHotkey2", &options.key[1][11], 0, 0 },
{ CFG_KEY, "P2KeyHotkey3", &options.key[1][12], 0, 0 },
{ CFG_KEY, "P2KeyHotkey4", &options.key[1][13], 0, 0 },
{ CFG_NONE, "[Player1 Joystick]", },
{ CFG_INT, "P1JoyID", &options.joyid[0], -1, 7 },
{ CFG_JOY, "P1JoyUp", &options.joy[0][0], 0, 0 },
{ CFG_JOY, "P1JoyDown", &options.joy[0][1], 0, 0 },
{ CFG_JOY, "P1JoyLeft", &options.joy[0][2], 0, 0 },
{ CFG_JOY, "P1JoyRight", &options.joy[0][3], 0, 0 },
{ CFG_JOY, "P1JoyButtonA", &options.joy[0][4], 0, 0 },
{ CFG_JOY, "P1JoyButtonB", &options.joy[0][5], 0, 0 },
{ CFG_JOY, "P1JoyButtonC", &options.joy[0][6], 0, 0 },
{ CFG_JOY, "P1JoyButtonD", &options.joy[0][7], 0, 0 },
{ CFG_JOY, "P1JoyStart", &options.joy[0][8], 0, 0 },
{ CFG_JOY, "P1JoySelect", &options.joy[0][9], 0, 0 },
{ CFG_JOY, "P1JoyHotkey1", &options.joy[0][10], 0, 0 },
{ CFG_JOY, "P1JoyHotkey2", &options.joy[0][11], 0, 0 },
{ CFG_JOY, "P1JoyHotkey3", &options.joy[0][12], 0, 0 },
{ CFG_JOY, "P1JoyHotkey4", &options.joy[0][13], 0, 0 },
{ CFG_NONE, "[Player2 Joystick]", },
{ CFG_INT, "P2JoyID", &options.joyid[1], -1, 7 },
{ CFG_JOY, "P2JoyUp", &options.joy[1][0], 0, 0 },
{ CFG_JOY, "P2JoyDown", &options.joy[1][1], 0, 0 },
{ CFG_JOY, "P2JoyLeft", &options.joy[1][2], 0, 0 },
{ CFG_JOY, "P2JoyRight", &options.joy[1][3], 0, 0 },
{ CFG_JOY, "P2JoyButtonA", &options.joy[1][4], 0, 0 },
{ CFG_JOY, "P2JoyButtonB", &options.joy[1][5], 0, 0 },
{ CFG_JOY, "P2JoyButtonC", &options.joy[1][6], 0, 0 },
{ CFG_JOY, "P2JoyButtonD", &options.joy[1][7], 0, 0 },
{ CFG_JOY, "P2JoyStart", &options.joy[1][8], 0, 0 },
{ CFG_JOY, "P2JoySelect", &options.joy[1][9], 0, 0 },
{ CFG_JOY, "P2JoyHotkey1", &options.joy[1][10], 0, 0 },
{ CFG_JOY, "P2JoyHotkey2", &options.joy[1][11], 0, 0 },
{ CFG_JOY, "P2JoyHotkey3", &options.joy[1][12], 0, 0 },
{ CFG_JOY, "P2JoyHotkey4", &options.joy[1][13], 0, 0 },
{ CFG_NONE, "[Player1 Hotkey]", },
{ CFG_INT, "P1Hotkey1", &options.hotkey[0][0], 0, 15 },
{ CFG_INT, "P1Hotkey2", &options.hotkey[0][1], 0, 15 },
{ CFG_INT, "P1Hotkey3", &options.hotkey[0][2], 0, 15 },
{ CFG_INT, "P1Hotkey4", &options.hotkey[0][3], 0, 15 },
{ CFG_INT, "P1AutofireInterval", &options.afinterval[0], 0, 20 },
{ CFG_NONE, "[Player2 Hotkey]", },
{ CFG_INT, "P2Hotkey1", &options.hotkey[1][0], 0, 15 },
{ CFG_INT, "P2Hotkey2", &options.hotkey[1][1], 0, 15 },
{ CFG_INT, "P2Hotkey3", &options.hotkey[1][2], 0, 15 },
{ CFG_INT, "P2Hotkey4", &options.hotkey[1][3], 0, 15 },
{ CFG_INT, "P2AutofireInterval", &options.afinterval[1], 0, 20 },
{ CFG_NONE, NULL, NULL, 0, 0 }
};
static cfg_type game_cfg[] =
{
{ CFG_NONE, "[Player1 Keyboard]", },
{ CFG_KEY, "P1KeyUp", &options.key[0][0], 0, 0 },
{ CFG_KEY, "P1KeyDown", &options.key[0][1], 0, 0 },
{ CFG_KEY, "P1KeyLeft", &options.key[0][2], 0, 0 },
{ CFG_KEY, "P1KeyRight", &options.key[0][3], 0, 0 },
{ CFG_KEY, "P1KeyButtonA", &options.key[0][4], 0, 0 },
{ CFG_KEY, "P1KeyButtonB", &options.key[0][5], 0, 0 },
{ CFG_KEY, "P1KeyButtonC", &options.key[0][6], 0, 0 },
{ CFG_KEY, "P1KeyButtonD", &options.key[0][7], 0, 0 },
{ CFG_KEY, "P1KeyStart", &options.key[0][8], 0, 0 },
{ CFG_KEY, "P1KeySelect", &options.key[0][9], 0, 0 },
{ CFG_KEY, "P1KeyHotkey1", &options.key[0][10], 0, 0 },
{ CFG_KEY, "P1KeyHotkey2", &options.key[0][11], 0, 0 },
{ CFG_KEY, "P1KeyHotkey3", &options.key[0][12], 0, 0 },
{ CFG_KEY, "P1KeyHotkey4", &options.key[0][13], 0, 0 },
{ CFG_NONE, "[Player2 Keyboard]", },
{ CFG_KEY, "P2KeyUp", &options.key[1][0], 0, 0 },
{ CFG_KEY, "P2KeyDown", &options.key[1][1], 0, 0 },
{ CFG_KEY, "P2KeyLeft", &options.key[1][2], 0, 0 },
{ CFG_KEY, "P2KeyRight", &options.key[1][3], 0, 0 },
{ CFG_KEY, "P2KeyButtonA", &options.key[1][4], 0, 0 },
{ CFG_KEY, "P2KeyButtonB", &options.key[1][5], 0, 0 },
{ CFG_KEY, "P2KeyButtonC", &options.key[1][6], 0, 0 },
{ CFG_KEY, "P2KeyButtonD", &options.key[1][7], 0, 0 },
{ CFG_KEY, "P2KeyStart", &options.key[1][8], 0, 0 },
{ CFG_KEY, "P2KeySelect", &options.key[1][9], 0, 0 },
{ CFG_KEY, "P2KeyHotkey1", &options.key[1][10], 0, 0 },
{ CFG_KEY, "P2KeyHotkey2", &options.key[1][11], 0, 0 },
{ CFG_KEY, "P2KeyHotkey3", &options.key[1][12], 0, 0 },
{ CFG_KEY, "P2KeyHotkey4", &options.key[1][13], 0, 0 },
{ CFG_NONE, "[Player1 Joystick]", },
{ CFG_INT, "P1JoyID", &options.joyid[0], -1, 7 },
{ CFG_JOY, "P1JoyUp", &options.joy[0][0], 0, 0 },
{ CFG_JOY, "P1JoyDown", &options.joy[0][1], 0, 0 },
{ CFG_JOY, "P1JoyLeft", &options.joy[0][2], 0, 0 },
{ CFG_JOY, "P1JoyRight", &options.joy[0][3], 0, 0 },
{ CFG_JOY, "P1JoyButtonA", &options.joy[0][4], 0, 0 },
{ CFG_JOY, "P1JoyButtonB", &options.joy[0][5], 0, 0 },
{ CFG_JOY, "P1JoyButtonC", &options.joy[0][6], 0, 0 },
{ CFG_JOY, "P1JoyButtonD", &options.joy[0][7], 0, 0 },
{ CFG_JOY, "P1JoyStart", &options.joy[0][8], 0, 0 },
{ CFG_JOY, "P1JoySelect", &options.joy[0][9], 0, 0 },
{ CFG_JOY, "P1JoyHotkey1", &options.joy[0][10], 0, 0 },
{ CFG_JOY, "P1JoyHotkey2", &options.joy[0][11], 0, 0 },
{ CFG_JOY, "P1JoyHotkey3", &options.joy[0][12], 0, 0 },
{ CFG_JOY, "P1JoyHotkey4", &options.joy[0][13], 0, 0 },
{ CFG_NONE, "[Player2 Joystick]", },
{ CFG_INT, "P2JoyID", &options.joyid[1], -1, 7 },
{ CFG_JOY, "P2JoyUp", &options.joy[1][0], 0, 0 },
{ CFG_JOY, "P2JoyDown", &options.joy[1][1], 0, 0 },
{ CFG_JOY, "P2JoyLeft", &options.joy[1][2], 0, 0 },
{ CFG_JOY, "P2JoyRight", &options.joy[1][3], 0, 0 },
{ CFG_JOY, "P2JoyButtonA", &options.joy[1][4], 0, 0 },
{ CFG_JOY, "P2JoyButtonB", &options.joy[1][5], 0, 0 },
{ CFG_JOY, "P2JoyButtonC", &options.joy[1][6], 0, 0 },
{ CFG_JOY, "P2JoyButtonD", &options.joy[1][7], 0, 0 },
{ CFG_JOY, "P2JoyStart", &options.joy[1][8], 0, 0 },
{ CFG_JOY, "P2JoySelect", &options.joy[1][9], 0, 0 },
{ CFG_JOY, "P2JoyHotkey1", &options.joy[1][10], 0, 0 },
{ CFG_JOY, "P2JoyHotkey2", &options.joy[1][11], 0, 0 },
{ CFG_JOY, "P2JoyHotkey3", &options.joy[1][12], 0, 0 },
{ CFG_JOY, "P2JoyHotkey4", &options.joy[1][13], 0, 0 },
{ CFG_NONE, "[Player1 Hotkey]", },
{ CFG_INT, "P1Hotkey1", &options.hotkey[0][0], 0, 15 },
{ CFG_INT, "P1Hotkey2", &options.hotkey[0][1], 0, 15 },
{ CFG_INT, "P1Hotkey3", &options.hotkey[0][2], 0, 15 },
{ CFG_INT, "P1Hotkey4", &options.hotkey[0][3], 0, 15 },
{ CFG_INT, "P1AutofireInterval", &options.afinterval[0], 0, 20 },
{ CFG_NONE, "[Player2 Hotkey]", },
{ CFG_INT, "P2Hotkey1", &options.hotkey[1][0], 0, 15 },
{ CFG_INT, "P2Hotkey2", &options.hotkey[1][1], 0, 15 },
{ CFG_INT, "P2Hotkey3", &options.hotkey[1][2], 0, 15 },
{ CFG_INT, "P2Hotkey4", &options.hotkey[1][3], 0, 15 },
{ CFG_INT, "P2AutofireInterval", &options.afinterval[1], 0, 20 },
{ CFG_NONE, NULL, NULL, 0, 0 }
};
/***************************************************************************
グローバル関数
***************************************************************************/
/*------------------------------------------------------
設定ファイルの読み込み
引 数: なし
戻り値: なし
-----------------------------------------------------*/
void load_config(void)
{
init_options();
if (load_inifile(inifile_name, default_cfg) == 0)
save_config();
osd_mkdir(options.snapdir);
osd_mkdir("config");
}
/*------------------------------------------------------
設定ファイルの書き込み
引 数: なし
戻り値: なし
-----------------------------------------------------*/
void save_config(void)
{
save_inifile(inifile_name, default_cfg);
}
/*------------------------------------------------------
設定ファイルの読み込み (ゲーム用)
引 数: なし
戻り値: なし
-----------------------------------------------------*/
void load_game_config(void)
{
char fname[MAX_PATH];
sprintf(fname, "config/%s.ini", game_name);
load_inifile((const char *)fname, game_cfg);
}
/*------------------------------------------------------
設定ファイルの書き込み
引 数: なし
戻り値: なし
-----------------------------------------------------*/
void save_game_config(void)
{
char fname[MAX_PATH];
sprintf(fname, "config/%s.ini", game_name);
save_inifile((const char *)fname, game_cfg);
}
/*------------------------------------------------------
コマンドライン引数の反映
引 数: int argc コマンドライン引数の数
char *argv[] コマンドライン引数の値
戻り値: なし
※このプログラムではコマンドライン引数は未使用
オプションの値チェックのみしています
-----------------------------------------------------*/
void parse_commandline(int argc, char *argv[])
{
int i;
if (argc == 4)
{
if (stricmp(argv[1], "-c") ==0 || stricmp(argv[1], "/c") == 0)
{
if ((argv[2][0] >= 'A' && argv[2][0] <= 'Z')
|| (argv[2][0] >= 'a' && argv[2][0] <= 'z'))
{
extern void debug_output_cdrom_data(int drive, char *name);
debug_output_cdrom_data(toupper(argv[2][0]) - 'A', argv[3]);
exit(1);
}
}
}
options.cpuid_result = CheckCPUID();
if ((options.cpuid_result & HAS_MMX) == 0)
options.enable_mmx = 0;
if ((options.cpuid_result & HAS_SSE) == 0)
options.enable_sse = 0;
if (options.sw_stretch2x == 0)
options.scanlines = 0;
if (options.sl_brightness < 25)
options.sl_brightness = 0;
else
if (options.sl_brightness < 50)
options.sl_brightness = 25;
else
if (options.sl_brightness < 75)
options.sl_brightness = 50;
else
options.sl_brightness = 75;
i = toupper(options.drive_str[0]);
if (!stricmp(options.drive_str, "auto"))
options.drive = -1;
else
if (i >= 'A' && i <= 'Z')
options.drive = i - 'A';
else
options.drive = -1;
if (options.refreshrate == 1)
{
video_fps = 15625.0 / 264;
}
else
{
video_fps = 60.0;
}
}
/*------------------------------------------------------
アプリケーション名の取得
引 数: なし
戻り値: アプリケーション名の文字列
※APPNAMEはwin32.hに登録してあります
-----------------------------------------------------*/
const char *get_appname(void)
{
return APPNAME;
}
/*------------------------------------------------------
アプリケーションのバージョン取得
引 数: なし
戻り値: アプリケーションのバージョン文字列
※APPVERはwin32.hに登録してあります
-----------------------------------------------------*/
const char *get_version(void)
{
return APPVER;
}
/***************************************************************************
ローカル関数
***************************************************************************/
/*------------------------------------------------------
オプションの値を初期化
引 数: なし
戻り値: なし
-----------------------------------------------------*/
static void init_options(void)
{
options.region = 0;
options.raster = 0;
options.drive = -1;
options.cdspeed = 0;
strcpy(options.drive_str, "auto");
options.fullscreen = 0;
options.sw_stretch2x = 1;
options.scanlines = 0;
options.sl_brightness = 0;
options.hw_stretch = 0;
options.use_triplebuffer = 1;
options.wait_vsync = 1;
options.use_ddhel = 0;
options.use_sysmem = 0;
options.refreshrate = 1;
options.samplerate = 44100;
options.sound_volume = 100;
options.latency = 4;
options.enable_cdda = 1;
options.cdda_volume = -1;
options.auto_pause = 1;
options.enable_mmx = 1;
options.enable_sse = 1;
options.sleep_time = -1;
options.errorlog = 0;
strcpy(options.snapdir, "snap");
options.key[0][0] = KEYCODE_UP;
options.key[0][1] = KEYCODE_DOWN;
options.key[0][2] = KEYCODE_LEFT;
options.key[0][3] = KEYCODE_RIGHT;
options.key[0][4] = KEYCODE_LCONTROL;
options.key[0][5] = KEYCODE_LALT;
options.key[0][6] = KEYCODE_SPACE;
options.key[0][7] = KEYCODE_LSHIFT;
options.key[0][8] = KEYCODE_1;
options.key[0][9] = KEYCODE_5;
options.key[0][10] = KEYCODE_NONE;
options.key[0][11] = KEYCODE_NONE;
options.key[0][12] = KEYCODE_NONE;
options.key[0][13] = KEYCODE_NONE;
options.key[1][0] = KEYCODE_R;
options.key[1][1] = KEYCODE_F;
options.key[1][2] = KEYCODE_D;
options.key[1][3] = KEYCODE_G;
options.key[1][4] = KEYCODE_A;
options.key[1][5] = KEYCODE_S;
options.key[1][6] = KEYCODE_Q;
options.key[1][7] = KEYCODE_W;
options.key[1][8] = KEYCODE_2;
options.key[1][9] = KEYCODE_6;
options.key[1][10] = KEYCODE_NONE;
options.key[1][11] = KEYCODE_NONE;
options.key[1][12] = KEYCODE_NONE;
options.key[1][13] = KEYCODE_NONE;
options.joyid[0] = 0;
options.joy[0][0] = JOY_AXIS_Y_NEG;
options.joy[0][1] = JOY_AXIS_Y_POS;
options.joy[0][2] = JOY_AXIS_X_NEG;
options.joy[0][3] = JOY_AXIS_X_POS;
options.joy[0][4] = JOY_BUTTON1;
options.joy[0][5] = JOY_BUTTON2;
options.joy[0][6] = JOY_BUTTON3;
options.joy[0][7] = JOY_BUTTON4;
options.joy[0][8] = JOY_BUTTON5;
options.joy[0][9] = JOY_BUTTON6;
options.joy[0][10] = JOY_BUTTON7;
options.joy[0][11] = JOY_BUTTON8;
options.joy[0][12] = JOY_BUTTON9;
options.joy[0][13] = JOY_BUTTON10;
options.joyid[1] = 1;
options.joy[1][0] = JOY_AXIS_Y_NEG;
options.joy[1][1] = JOY_AXIS_Y_POS;
options.joy[1][2] = JOY_AXIS_X_NEG;
options.joy[1][3] = JOY_AXIS_X_POS;
options.joy[1][4] = JOY_BUTTON1;
options.joy[1][5] = JOY_BUTTON2;
options.joy[1][6] = JOY_BUTTON3;
options.joy[1][7] = JOY_BUTTON4;
options.joy[1][8] = JOY_BUTTON5;
options.joy[1][9] = JOY_BUTTON6;
options.joy[1][10] = JOY_BUTTON7;
options.joy[1][11] = JOY_BUTTON8;
options.joy[1][12] = JOY_BUTTON9;
options.joy[1][13] = JOY_BUTTON10;
options.hotkey[0][0] = 0;
options.hotkey[0][1] = 0;
options.hotkey[0][2] = 0;
options.hotkey[0][3] = 0;
options.afinterval[0] = 0;
options.hotkey[1][0] = 0;
options.hotkey[1][1] = 0;
options.hotkey[1][2] = 0;
options.hotkey[1][3] = 0;
options.afinterval[1] = 0;
options.cpuid_result = 0;
options.sound_enable = 1;
}
/*------------------------------------------------------
iniファイルから設定を読み込む
引 数: const char *fname ファイル名
戻り値: 0:ファイルがない 1:正常終了
-----------------------------------------------------*/
static int load_inifile(const char *fname, cfg_type *cfg)
{
FILE *fp;
int i;
char linebuf[LINEBUF_SIZE];
fp = fopen(fname, "r");
if (fp == NULL)
{
// ファイルオープン失敗
return 0;
}
while (1)
{
char *name, *value;
memset(linebuf, LINEBUF_SIZE, 0);
if (fgets(linebuf, LINEBUF_SIZE - 1, fp) == NULL)
break;
if (linebuf[0] == ';' || linebuf[0] == '[')
continue;
name = strtok(linebuf, " =\r\n");
if (name == NULL)
continue;
value = strtok(NULL, " =\r\n");
if (value == NULL)
continue;
/* check name and value */
for (i = 0; cfg[i].name; i++)
{
if (!strcmp(name, cfg[i].name))
{
int *v = (int *)cfg[i].value;
switch (cfg[i].type)
{
case CFG_INT: *v = get_config_int(value, cfg[i].min, cfg[i].max); break;
case CFG_BOOL: *v = get_config_bool(value); break;
case CFG_STR: get_config_string(value, cfg[i].value); break;
case CFG_KEY: *v = osd_get_keycode_by_name(value); break;
case CFG_JOY: *v = osd_get_joycode_by_name(value); break;
}
}
}
}
fclose(fp);
return 1;
}
/*------------------------------------------------------
iniファイルへ設定を書き込む
引 数: const char *fname ファイル名
戻り値: 0:ファイルがない 1:正常終了
-----------------------------------------------------*/
static int save_inifile(const char *fname, cfg_type *cfg)
{
FILE *fp;
int i;
fp = fopen(fname, "w");
if (fp == NULL)
{
return 0;
}
fprintf(fp, ";----------------------------------------\n");
fprintf(fp, "; " APPNAME " ver." APPVER "\n");
fprintf(fp, ";----------------------------------------\n");
for (i = 0; cfg[i].name; i++)
{
int *value = (int *)cfg[i].value;
switch (cfg[i].type)
{
case CFG_NONE: if (cfg[i].name) fprintf(fp, "\n%s\n", cfg[i].name); break;
case CFG_INT: fprintf(fp, "%s = %d\n", cfg[i].name, set_config_int(*value, cfg[i].min, cfg[i].max)); break;
case CFG_BOOL: fprintf(fp, "%s = %s\n", cfg[i].name, set_config_bool(*value)); break;
case CFG_STR: fprintf(fp, "%s = %s\n", cfg[i].name, (char *)cfg[i].value); break;
case CFG_KEY: fprintf(fp, "%s = %s\n", cfg[i].name, osd_get_keyname_by_code(*value)); break;
case CFG_JOY: fprintf(fp, "%s = %s\n", cfg[i].name, osd_get_joyname_by_code(*value)); break;
}
}
fclose(fp);
return 1;
}
/*------------------------------------------------------
yes/noタイプの値取得
引 数: char *str オプション文字列
戻り値: yes:1 no:0
-----------------------------------------------------*/
static int get_config_bool(char *str)
{
if (!stricmp(str, "yes"))
return 1;
else
return 0;
}
/*------------------------------------------------------
数値の値取得
引 数: char *str オプション文字列
int minval 最小値
int maxval 最大値
戻り値: 数値の値
-----------------------------------------------------*/
static int get_config_int(char *str, int minval, int maxval)
{
int value = atoi(str);
if (value < minval) value = minval;
if (value > maxval) value = maxval;
return value;
}
/*------------------------------------------------------
文字列の値取得
引 数: char *str オプション文字列
char *value_str 設定する文字列
戻り値: なし
-----------------------------------------------------*/
static void get_config_string(char *str, char *value_str)
{
int length = strlen(str);
if (length == 0)
return;
if (length > CFG_STR_MAXLEN)
{
memset(value_str, 0, CFG_STR_MAXLEN);
strncpy(value_str, str, CFG_STR_MAXLEN - 1);
}
else
{
strcpy(value_str, str);
}
}
/*------------------------------------------------------
yes/noタイプの値設定
引 数: int value 数値の値
戻り値: yes/noの文字列
-----------------------------------------------------*/
static const char *set_config_bool(int value)
{
if (value)
return "yes";
else
return "no";
}
/*------------------------------------------------------
数値の値設定
引 数: int value 数値の値
int minval 最小値
int maxval 最大値
戻り値: 範囲をチェックした数値の値
-----------------------------------------------------*/
static int set_config_int(int value, int minval, int maxval)
{
if (value < minval) value = minval;
if (value > maxval) value = maxval;
return value;
}