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; 
}