Browse Source

Move config function definitions to palcfg.c & slightly layout change of WinRT setting page

louyihua 7 years ago
parent
commit
05c493e98b

+ 0 - 266
global.c

@@ -49,272 +49,6 @@ CONFIGURATION gConfig;
       DO_BYTESWAP(buf, size);                                    \
    } while(0)
 
-VOID
-PAL_LoadConfig(
-   BOOL fFromFile
-)
-{
-	FILE     *fp;
-	ConfigValue  values[PALCFG_ALL_MAX];
-	MUSICTYPE eMusicType = MUSIC_RIX;
-	MUSICTYPE eCDType = MUSIC_OGG;
-	OPLTYPE   eOPLType = OPL_DOSBOX;
-	SCREENLAYOUT screen_layout = {
-		// Equipment Screen
-		PAL_XY(8, 8), PAL_XY(2, 95), PAL_XY(5, 70), PAL_XY(51, 57),
-		{ PAL_XY(92, 11), PAL_XY(92, 33), PAL_XY(92, 55), PAL_XY(92, 77), PAL_XY(92, 99), PAL_XY(92, 121) },
-		{ PAL_XY(130, 11), PAL_XY(130, 33), PAL_XY(130, 55), PAL_XY(130, 77), PAL_XY(130, 99), PAL_XY(130, 121) },
-		{ PAL_XY(226, 10), PAL_XY(226, 32), PAL_XY(226, 54), PAL_XY(226, 76), PAL_XY(226, 98) },
-		{ PAL_XY(260, 14), PAL_XY(260, 36), PAL_XY(260, 58), PAL_XY(260, 80), PAL_XY(260, 102) },
-
-		// Status Screen
-		PAL_XY(110, 8), PAL_XY(110, 30), PAL_XY(6, 6),  PAL_XY(6, 32),  PAL_XY(6, 54),  PAL_XY(6, 76),
-		{ PAL_XY(6, 98),   PAL_XY(6, 118),  PAL_XY(6, 138),  PAL_XY(6, 158),  PAL_XY(6, 178) },
-		PAL_XY(58, 6), PAL_XY(58, 15), PAL_XY(0, 0), PAL_XY(54, 35), PAL_XY(42, 56),
-		PAL_XY(63, 61), PAL_XY(65, 58), PAL_XY(42, 78), PAL_XY(63, 83), PAL_XY(65, 80),
-		{ PAL_XY(42, 102), PAL_XY(42, 122), PAL_XY(42, 142), PAL_XY(42, 162), PAL_XY(42, 182) },
-		{ PAL_XY(189, -1), PAL_XY(247, 39), PAL_XY(251, 101), PAL_XY(201, 133), PAL_XY(141, 141), PAL_XY(81, 125) },
-		{ PAL_XY(195, 38), PAL_XY(253, 78), PAL_XY(257, 140), PAL_XY(207, 172), PAL_XY(147, 180), PAL_XY(87, 164) },
-		{ PAL_XY(185, 58), PAL_XY(185, 76), PAL_XY(185, 94), PAL_XY(185, 112), PAL_XY(185, 130), PAL_XY(185, 148), PAL_XY(185, 166), PAL_XY(185, 184), PAL_XY(185, 184), PAL_XY(185, 184) },
-
-		// Extra Lines
-		PAL_XY(0, 0), PAL_XY(0, 0)
-	};
-
-	for (PALCFG_ITEM i = PALCFG_ALL_MIN; i < PALCFG_ALL_MAX; i++) values[i] = PAL_DefaultConfig(i);
-
-	if (fFromFile && (fp = fopen(va("%ssdlpal.cfg", PAL_CONFIG_PREFIX), "r")))
-	{
-		PAL_LARGE char buf[512];
-
-		//
-		// Load the configuration data
-		//
-		while (fgets(buf, 512, fp) != NULL)
-		{
-			ConfigValue value;
-			const ConfigItem * item;
-			if (PAL_ParseConfigLine(buf, &item, &value))
-			{
-				switch (item->Item)
-				{
-				case PALCFG_AUDIOBUFFERSIZE:
-					if ((value.uValue & (value.uValue - 1)) != 0)
-					{
-						/* Make sure iAudioBufferSize is power of 2 */
-						int n = 0;
-						while (value.uValue) { value.uValue >>= 1; n++; }
-						value.uValue = 1 << (n - 1);
-					}
-					values[item->Item] = value;
-					break;
-				case PALCFG_MESSAGEFILE:
-				{
-					int n = strlen(value.sValue);
-					while (n > 0 && isspace(value.sValue[n - 1])) n--;
-					if (n > 0)
-					{
-						gConfig.pszMsgFile = (char *)realloc(gConfig.pszMsgFile, n + 1);
-						memcpy(gConfig.pszMsgFile, value.sValue, n);
-						gConfig.pszMsgFile[n] = '\0';
-					}
-					break;
-				}
-				case PALCFG_GAMEPATH:
-				{
-					int n = strlen(value.sValue);
-					while (n > 0 && isspace(value.sValue[n - 1])) n--;
-					if (n > 0)
-					{
-						gConfig.pszGamePath = (char *)realloc(gConfig.pszGamePath, n + 1);
-						memcpy(gConfig.pszGamePath, value.sValue, n);
-						gConfig.pszGamePath[n] = '\0';
-					}
-					break;
-				}
-				case PALCFG_CD:
-				{
-					if (PAL_HAS_MP3 && SDL_strncasecmp(value.sValue, "MP3", 3) == 0)
-						eCDType = MUSIC_MP3;
-					else if (PAL_HAS_OGG && SDL_strncasecmp(value.sValue, "OGG", 3) == 0)
-						eCDType = MUSIC_OGG;
-					else if (PAL_HAS_SDLCD && SDL_strncasecmp(value.sValue, "RAW", 3) == 0)
-						eCDType = MUSIC_SDLCD;
-					break;
-				}
-				case PALCFG_MUSIC:
-				{
-					if (PAL_HAS_NATIVEMIDI && SDL_strncasecmp(value.sValue, "MIDI", 4) == 0)
-						eMusicType = MUSIC_MIDI;
-					else if (PAL_HAS_MP3 && SDL_strncasecmp(value.sValue, "MP3", 3) == 0)
-						eMusicType = MUSIC_MP3;
-					else if (PAL_HAS_OGG && SDL_strncasecmp(value.sValue, "OGG", 3) == 0)
-						eMusicType = MUSIC_OGG;
-					else if (SDL_strncasecmp(value.sValue, "RIX", 3) == 0)
-						eMusicType = MUSIC_RIX;
-					break;
-				}
-				case PALCFG_OPL:
-				{
-					if (SDL_strncasecmp(value.sValue, "DOSBOXNEW", 9) == 0)
-						eOPLType = OPL_DOSBOX_NEW;
-					else if (SDL_strncasecmp(value.sValue, "DOSBOX", 6) == 0)
-						eOPLType = OPL_DOSBOX;
-					else if (SDL_strncasecmp(value.sValue, "MAME", 4) == 0)
-						eOPLType = OPL_MAME;
-					break;
-				}
-				case PALCFG_RIXEXTRAINIT:
-				{
-#if USE_RIX_EXTRA_INIT
-					int n = 1;
-					char *p;
-					for (p = ptr; *p < *end; p++)
-					{
-						if (*p == ',')
-							n++;
-					}
-					n &= ~0x1;
-
-					if (n > 0)
-					{
-						uint32_t *regs = malloc(sizeof(uint32_t) * (n >> 1));
-						uint8_t *vals = malloc(sizeof(uint8_t) * (n >> 1));
-						uint32_t d, i, v = 1;
-						if (regs && vals)
-						{
-							for (p = ptr, i = 0; *p < *end; p++, i++)
-							{
-								if (sscanf(p, "%u", &regs[i]) == 0) { v = 0; break; }
-								while (*p < *end && *p != ',') p++; p++;
-								if (sscanf(p, "%u", &d) == 0) { v = 0; break; }
-								while (*p < *end && *p != ',') p++;
-								vals[i] = (uint8_t)d;
-							}
-							if (v)
-							{
-								gConfig.pExtraFMRegs = regs;
-								gConfig.pExtraFMVals = vals;
-								gConfig.dwExtraLength = n >> 1;
-							}
-							else
-							{
-								free(regs);
-								free(vals);
-							}
-						}
-					}
-#endif
-					break;
-				}
-				default:
-					values[item->Item] = value;
-					break;
-				}
-			}
-		}
-
-		UTIL_CloseFile(fp);
-	}
-
-	//
-	// Set configurable global options
-	//
-	if (!gConfig.pszGamePath) gConfig.pszGamePath = strdup(PAL_PREFIX);
-	gConfig.eMusicType = eMusicType;
-	gConfig.eCDType = eCDType;
-	gConfig.eOPLType = eOPLType;
-	gConfig.dwWordLength = 10;	// This is the default value for Chinese version
-	gConfig.ScreenLayout = screen_layout;
-
-	gConfig.fIsWIN95 = !values[PALCFG_DOS].bValue;
-	gConfig.fUseEmbeddedFonts = values[PALCFG_DOS].bValue && values[PALCFG_USEEMBEDDEDFONTS].bValue;
-	gConfig.fUseSurroundOPL = values[PALCFG_STEREO].bValue && values[PALCFG_USESURROUNDOPL].bValue;
-	gConfig.fLaunchSetting = values[PALCFG_LAUNCHSETTING].bValue;
-#if PAL_HAS_TOUCH
-	gConfig.fUseTouchOverlay = values[PALCFG_USETOUCHOVERLAY].bValue;
-#endif
-#if SDL_VERSION_ATLEAST(2,0,0)
-	gConfig.fKeepAspectRatio = values[PALCFG_KEEPASPECTRATIO].bValue;
-#else
-	gConfig.fFullScreen = values[PALCFG_FULLSCREEN].bValue;
-#endif
-	gConfig.iAudioChannels = values[PALCFG_STEREO].bValue ? 2 : 1;
-
-	gConfig.iSurroundOPLOffset = values[PALCFG_SURROUNDOPLOFFSET].iValue;
-
-	gConfig.iSampleRate = values[PALCFG_SAMPLERATE].uValue;
-	gConfig.iOPLSampleRate = values[PALCFG_OPLSAMPLERATE].uValue;
-	gConfig.iResampleQuality = values[PALCFG_RESAMPLEQUALITY].uValue;
-	gConfig.uCodePage = values[PALCFG_CODEPAGE].uValue;
-	gConfig.wAudioBufferSize = (WORD)values[PALCFG_AUDIOBUFFERSIZE].uValue;
-	gConfig.iVolume = SDL_MIX_MAXVOLUME * values[PALCFG_VOLUME].uValue / 100;
-
-	if (UTIL_GetScreenSize(&values[PALCFG_WINDOWWIDTH].uValue, &values[PALCFG_WINDOWHEIGHT].uValue))
-	{
-		gConfig.dwScreenWidth = values[PALCFG_WINDOWWIDTH].uValue;
-		gConfig.dwScreenHeight = values[PALCFG_WINDOWHEIGHT].uValue;
-	}
-	else
-	{
-		gConfig.dwScreenWidth = PAL_DEFAULT_WINDOW_WIDTH;
-		gConfig.dwScreenHeight = PAL_DEFAULT_WINDOW_HEIGHT;
-	}
-}
-
-
-BOOL
-PAL_SaveConfig(
-	VOID
-)
-{
-	static const char *music_types[] = { "RIX", "MIDI", "MP3", "OGG", "RAW" };
-	static const char *opl_types[] = { "DOSBOX", "MAME" };
-	char buf[512];
-	FILE *fp = fopen(va("%ssdlpal.cfg", PAL_CONFIG_PREFIX), "w");
-
-	if (fp)
-	{
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_DOS), !gConfig.fIsWIN95); fputs(buf, fp);
-#if SDL_VERSION_ATLEAST(2,0,0)
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_KEEPASPECTRATIO), gConfig.fKeepAspectRatio); fputs(buf, fp);
-#else
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_FULLSCREEN), gConfig.fKeepAspectRatio); fputs(buf, fp);
-#endif
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_LAUNCHSETTING), gConfig.fLaunchSetting); fputs(buf, fp);
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_STEREO), gConfig.iAudioChannels == 2 ? TRUE : FALSE); fputs(buf, fp);
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USEEMBEDDEDFONTS), gConfig.fUseEmbeddedFonts); fputs(buf, fp);
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USESURROUNDOPL), gConfig.fUseSurroundOPL); fputs(buf, fp);
-#if PAL_HAS_TOUCH
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USETOUCHOVERLAY), gConfig.fUseTouchOverlay); fputs(buf, fp);
-#endif
-
-		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_SURROUNDOPLOFFSET), gConfig.iSurroundOPLOffset); fputs(buf, fp);
-
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_AUDIOBUFFERSIZE), gConfig.wAudioBufferSize); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_CODEPAGE), gConfig.uCodePage); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_OPLSAMPLERATE), gConfig.iOPLSampleRate); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_RESAMPLEQUALITY), gConfig.iResampleQuality); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_SAMPLERATE), gConfig.iSampleRate); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_VOLUME), gConfig.iVolume); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_WINDOWHEIGHT), gConfig.dwScreenHeight); fputs(buf, fp);
-		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_WINDOWWIDTH), gConfig.dwScreenWidth); fputs(buf, fp);
-
-		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_CD), music_types[gConfig.eCDType]); fputs(buf, fp);
-		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_MUSIC), music_types[gConfig.eMusicType]); fputs(buf, fp);
-		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_OPL), opl_types[gConfig.eOPLType]); fputs(buf, fp);
-
-		if (gConfig.pszGamePath) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_GAMEPATH), gConfig.pszGamePath); fputs(buf, fp); }
-		if (gConfig.pszMsgFile) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_MESSAGEFILE), gConfig.pszMsgFile); fputs(buf, fp); }
-
-		fclose(fp);
-
-		return TRUE;
-	}
-	else
-		return FALSE;
-}
-
 INT
 PAL_InitGlobals(
    VOID

+ 0 - 100
global.h

@@ -93,8 +93,6 @@ extern "C"
 
 #define     MINIMAL_WORD_COUNT           (MAX_OBJECTS + 13)
 
-#define     PAL_MAX_SAMPLERATE           48000
-
 // status of characters
 typedef enum tagSTATUS
 {
@@ -621,104 +619,6 @@ typedef struct tagGLOBALVARS
 
 extern GLOBALVARS * const gpGlobals;
 
-typedef struct tagSCREENLAYOUT
-{
-	PAL_POS          EquipImageBox;
-	PAL_POS          EquipRoleListBox;
-	PAL_POS          EquipItemName;
-	PAL_POS          EquipItemAmount;
-	PAL_POS          EquipLabels[MAX_PLAYER_EQUIPMENTS];
-	PAL_POS          EquipNames[MAX_PLAYER_EQUIPMENTS];
-	PAL_POS          EquipStatusLabels[5];
-	PAL_POS          EquipStatusValues[5];
-
-	PAL_POS          RoleName;
-	PAL_POS          RoleImage;
-	PAL_POS          RoleExpLabel;
-	PAL_POS          RoleLevelLabel;
-	PAL_POS          RoleHPLabel;
-	PAL_POS          RoleMPLabel;
-	PAL_POS          RoleStatusLabels[5];
-	PAL_POS          RoleCurrExp;
-	PAL_POS          RoleNextExp;
-	PAL_POS          RoleExpSlash;
-	PAL_POS          RoleLevel;
-	PAL_POS          RoleCurHP;
-	PAL_POS          RoleMaxHP;
-	PAL_POS          RoleHPSlash;
-	PAL_POS          RoleCurMP;
-	PAL_POS          RoleMaxMP;
-	PAL_POS          RoleMPSlash;
-	PAL_POS          RoleStatusValues[5];
-	PAL_POS          RoleEquipImageBoxes[MAX_PLAYER_EQUIPMENTS];
-	PAL_POS          RoleEquipNames[MAX_PLAYER_EQUIPMENTS];
-	PAL_POS          RolePoisonNames[MAX_POISONS];
-
-	PAL_POS          ExtraItemDescLines;
-	PAL_POS          ExtraMagicDescLines;
-} SCREENLAYOUT;
-
-typedef struct tagCONFIGURATION
-{
-	union {
-	SCREENLAYOUT     ScreenLayout;
-	PAL_POS          ScreenLayoutArray[sizeof(SCREENLAYOUT) / sizeof(PAL_POS)];
-	};
-	enum {
-		USE_8x8_FONT = 1,
-		DISABLE_SHADOW = 2,
-	}                ScreenLayoutFlag[sizeof(SCREENLAYOUT) / sizeof(PAL_POS)];
-
-	/* Configurable options */
-	char            *pszGamePath;
-	char            *pszMsgFile;
-	CODEPAGE         uCodePage;
-	DWORD            dwWordLength;
-	DWORD            dwScreenWidth;
-	DWORD            dwScreenHeight;
-	INT              iSurroundOPLOffset;
-	INT              iAudioChannels;
-	INT              iSampleRate;
-	INT              iOPLSampleRate;
-	INT              iResampleQuality;
-	INT              iVolume;
-	MUSICTYPE        eMusicType;
-	MUSICTYPE        eCDType;
-	OPLTYPE          eOPLType;
-	WORD             wAudioBufferSize;
-	BOOL             fIsWIN95;
-	BOOL             fUseEmbeddedFonts;
-	BOOL             fUseSurroundOPL;
-#if SDL_VERSION_ATLEAST(2,0,0)
-	BOOL             fKeepAspectRatio;
-#else
-	BOOL             fFullScreen;
-#endif
-	BOOL             fEnableJoyStick;
-	BOOL             fUseCustomScreenLayout;
-	BOOL             fLaunchSetting;
-#if PAL_HAS_TOUCH
-	BOOL             fUseTouchOverlay;
-#endif
-#if USE_RIX_EXTRA_INIT
-	uint32_t        *pExtraFMRegs;
-	uint8_t         *pExtraFMVals;
-	uint32_t         dwExtraLength;
-#endif
-} CONFIGURATION, *LPCONFIGURATION;
-
-extern CONFIGURATION gConfig;
-
-VOID
-PAL_LoadConfig(
-   BOOL fFromFile
-);
-
-BOOL
-PAL_SaveConfig(
-	VOID
-);
-
 INT
 PAL_InitGlobals(
    VOID

+ 1 - 0
main.h

@@ -27,6 +27,7 @@
 #include "palcommon.h"
 #include "font.h"
 #include "global.h"
+#include "palcfg.h"
 #include "map.h"
 #include "res.h"
 #include "scene.h"

+ 1 - 0
mp3play.c

@@ -22,6 +22,7 @@
 
 #include "util.h"
 #include "global.h"
+#include "palcfg.h"
 
 #if PAL_HAS_MP3
 

+ 1 - 0
oggplay.c

@@ -24,6 +24,7 @@
 
 #include "util.h"
 #include "global.h"
+#include "palcfg.h"
 #include "players.h"
 #include "sound.h"
 #include <math.h>

+ 265 - 5
palcfg.c

@@ -1,7 +1,8 @@
 
 #include "global.h"
-#include "resampler.h"
 #include "palcfg.h"
+#include "util.h"
+#include "resampler.h"
 #include <stdint.h>
 
 static const ConfigItem gConfigItems[PALCFG_ALL_MAX] = {
@@ -177,9 +178,268 @@ PAL_LimitConfig(
 	}
 }
 
-static char *move_to_next_line(char *ptr)
+VOID
+PAL_LoadConfig(
+	BOOL fFromFile
+)
 {
-	while (*ptr && (*ptr != '\r' && *ptr != '\n')) ptr++;
-	while (*ptr && (*ptr == '\r' || *ptr == '\n')) ptr++;
-	return (*ptr == '\0') ? NULL : ptr;
+	FILE     *fp;
+	ConfigValue  values[PALCFG_ALL_MAX];
+	MUSICTYPE eMusicType = MUSIC_RIX;
+	MUSICTYPE eCDType = MUSIC_OGG;
+	OPLTYPE   eOPLType = OPL_DOSBOX;
+	SCREENLAYOUT screen_layout = {
+		// Equipment Screen
+		PAL_XY(8, 8), PAL_XY(2, 95), PAL_XY(5, 70), PAL_XY(51, 57),
+		{ PAL_XY(92, 11), PAL_XY(92, 33), PAL_XY(92, 55), PAL_XY(92, 77), PAL_XY(92, 99), PAL_XY(92, 121) },
+		{ PAL_XY(130, 11), PAL_XY(130, 33), PAL_XY(130, 55), PAL_XY(130, 77), PAL_XY(130, 99), PAL_XY(130, 121) },
+		{ PAL_XY(226, 10), PAL_XY(226, 32), PAL_XY(226, 54), PAL_XY(226, 76), PAL_XY(226, 98) },
+		{ PAL_XY(260, 14), PAL_XY(260, 36), PAL_XY(260, 58), PAL_XY(260, 80), PAL_XY(260, 102) },
+
+		// Status Screen
+		PAL_XY(110, 8), PAL_XY(110, 30), PAL_XY(6, 6),  PAL_XY(6, 32),  PAL_XY(6, 54),  PAL_XY(6, 76),
+		{ PAL_XY(6, 98),   PAL_XY(6, 118),  PAL_XY(6, 138),  PAL_XY(6, 158),  PAL_XY(6, 178) },
+		PAL_XY(58, 6), PAL_XY(58, 15), PAL_XY(0, 0), PAL_XY(54, 35), PAL_XY(42, 56),
+		PAL_XY(63, 61), PAL_XY(65, 58), PAL_XY(42, 78), PAL_XY(63, 83), PAL_XY(65, 80),
+		{ PAL_XY(42, 102), PAL_XY(42, 122), PAL_XY(42, 142), PAL_XY(42, 162), PAL_XY(42, 182) },
+		{ PAL_XY(189, -1), PAL_XY(247, 39), PAL_XY(251, 101), PAL_XY(201, 133), PAL_XY(141, 141), PAL_XY(81, 125) },
+		{ PAL_XY(195, 38), PAL_XY(253, 78), PAL_XY(257, 140), PAL_XY(207, 172), PAL_XY(147, 180), PAL_XY(87, 164) },
+		{ PAL_XY(185, 58), PAL_XY(185, 76), PAL_XY(185, 94), PAL_XY(185, 112), PAL_XY(185, 130), PAL_XY(185, 148), PAL_XY(185, 166), PAL_XY(185, 184), PAL_XY(185, 184), PAL_XY(185, 184) },
+
+		// Extra Lines
+		PAL_XY(0, 0), PAL_XY(0, 0)
+	};
+
+	for (PALCFG_ITEM i = PALCFG_ALL_MIN; i < PALCFG_ALL_MAX; i++) values[i] = PAL_DefaultConfig(i);
+
+	if (fFromFile && (fp = fopen(va("%ssdlpal.cfg", PAL_CONFIG_PREFIX), "r")))
+	{
+		PAL_LARGE char buf[512];
+
+		//
+		// Load the configuration data
+		//
+		while (fgets(buf, 512, fp) != NULL)
+		{
+			ConfigValue value;
+			const ConfigItem * item;
+			if (PAL_ParseConfigLine(buf, &item, &value))
+			{
+				switch (item->Item)
+				{
+				case PALCFG_AUDIOBUFFERSIZE:
+					if ((value.uValue & (value.uValue - 1)) != 0)
+					{
+						/* Make sure iAudioBufferSize is power of 2 */
+						int n = 0;
+						while (value.uValue) { value.uValue >>= 1; n++; }
+						value.uValue = 1 << (n - 1);
+					}
+					values[item->Item] = value;
+					break;
+				case PALCFG_MESSAGEFILE:
+				{
+					int n = strlen(value.sValue);
+					while (n > 0 && isspace(value.sValue[n - 1])) n--;
+					if (n > 0)
+					{
+						gConfig.pszMsgFile = (char *)realloc(gConfig.pszMsgFile, n + 1);
+						memcpy(gConfig.pszMsgFile, value.sValue, n);
+						gConfig.pszMsgFile[n] = '\0';
+					}
+					break;
+				}
+				case PALCFG_GAMEPATH:
+				{
+					int n = strlen(value.sValue);
+					while (n > 0 && isspace(value.sValue[n - 1])) n--;
+					if (n > 0)
+					{
+						gConfig.pszGamePath = (char *)realloc(gConfig.pszGamePath, n + 1);
+						memcpy(gConfig.pszGamePath, value.sValue, n);
+						gConfig.pszGamePath[n] = '\0';
+					}
+					break;
+				}
+				case PALCFG_CD:
+				{
+					if (PAL_HAS_MP3 && SDL_strncasecmp(value.sValue, "MP3", 3) == 0)
+						eCDType = MUSIC_MP3;
+					else if (PAL_HAS_OGG && SDL_strncasecmp(value.sValue, "OGG", 3) == 0)
+						eCDType = MUSIC_OGG;
+					else if (PAL_HAS_SDLCD && SDL_strncasecmp(value.sValue, "RAW", 3) == 0)
+						eCDType = MUSIC_SDLCD;
+					break;
+				}
+				case PALCFG_MUSIC:
+				{
+					if (PAL_HAS_NATIVEMIDI && SDL_strncasecmp(value.sValue, "MIDI", 4) == 0)
+						eMusicType = MUSIC_MIDI;
+					else if (PAL_HAS_MP3 && SDL_strncasecmp(value.sValue, "MP3", 3) == 0)
+						eMusicType = MUSIC_MP3;
+					else if (PAL_HAS_OGG && SDL_strncasecmp(value.sValue, "OGG", 3) == 0)
+						eMusicType = MUSIC_OGG;
+					else if (SDL_strncasecmp(value.sValue, "RIX", 3) == 0)
+						eMusicType = MUSIC_RIX;
+					break;
+				}
+				case PALCFG_OPL:
+				{
+					if (SDL_strncasecmp(value.sValue, "DOSBOXNEW", 9) == 0)
+						eOPLType = OPL_DOSBOX_NEW;
+					else if (SDL_strncasecmp(value.sValue, "DOSBOX", 6) == 0)
+						eOPLType = OPL_DOSBOX;
+					else if (SDL_strncasecmp(value.sValue, "MAME", 4) == 0)
+						eOPLType = OPL_MAME;
+					break;
+				}
+				case PALCFG_RIXEXTRAINIT:
+				{
+#if USE_RIX_EXTRA_INIT
+					int n = 1;
+					char *p;
+					for (p = ptr; *p < *end; p++)
+					{
+						if (*p == ',')
+							n++;
+					}
+					n &= ~0x1;
+
+					if (n > 0)
+					{
+						uint32_t *regs = malloc(sizeof(uint32_t) * (n >> 1));
+						uint8_t *vals = malloc(sizeof(uint8_t) * (n >> 1));
+						uint32_t d, i, v = 1;
+						if (regs && vals)
+						{
+							for (p = ptr, i = 0; *p < *end; p++, i++)
+							{
+								if (sscanf(p, "%u", &regs[i]) == 0) { v = 0; break; }
+								while (*p < *end && *p != ',') p++; p++;
+								if (sscanf(p, "%u", &d) == 0) { v = 0; break; }
+								while (*p < *end && *p != ',') p++;
+								vals[i] = (uint8_t)d;
+							}
+							if (v)
+							{
+								gConfig.pExtraFMRegs = regs;
+								gConfig.pExtraFMVals = vals;
+								gConfig.dwExtraLength = n >> 1;
+							}
+							else
+							{
+								free(regs);
+								free(vals);
+							}
+						}
+					}
+#endif
+					break;
+				}
+				default:
+					values[item->Item] = value;
+					break;
+				}
+			}
+		}
+
+		UTIL_CloseFile(fp);
+	}
+
+	//
+	// Set configurable global options
+	//
+	if (!gConfig.pszGamePath) gConfig.pszGamePath = strdup(PAL_PREFIX);
+	gConfig.eMusicType = eMusicType;
+	gConfig.eCDType = eCDType;
+	gConfig.eOPLType = eOPLType;
+	gConfig.dwWordLength = 10;	// This is the default value for Chinese version
+	gConfig.ScreenLayout = screen_layout;
+
+	gConfig.fIsWIN95 = !values[PALCFG_DOS].bValue;
+	gConfig.fUseEmbeddedFonts = values[PALCFG_DOS].bValue && values[PALCFG_USEEMBEDDEDFONTS].bValue;
+	gConfig.fUseSurroundOPL = values[PALCFG_STEREO].bValue && values[PALCFG_USESURROUNDOPL].bValue;
+	gConfig.fLaunchSetting = values[PALCFG_LAUNCHSETTING].bValue;
+#if PAL_HAS_TOUCH
+	gConfig.fUseTouchOverlay = values[PALCFG_USETOUCHOVERLAY].bValue;
+#endif
+#if SDL_VERSION_ATLEAST(2,0,0)
+	gConfig.fKeepAspectRatio = values[PALCFG_KEEPASPECTRATIO].bValue;
+#else
+	gConfig.fFullScreen = values[PALCFG_FULLSCREEN].bValue;
+#endif
+	gConfig.iAudioChannels = values[PALCFG_STEREO].bValue ? 2 : 1;
+
+	gConfig.iSurroundOPLOffset = values[PALCFG_SURROUNDOPLOFFSET].iValue;
+
+	gConfig.iSampleRate = values[PALCFG_SAMPLERATE].uValue;
+	gConfig.iOPLSampleRate = values[PALCFG_OPLSAMPLERATE].uValue;
+	gConfig.iResampleQuality = values[PALCFG_RESAMPLEQUALITY].uValue;
+	gConfig.uCodePage = values[PALCFG_CODEPAGE].uValue;
+	gConfig.wAudioBufferSize = (WORD)values[PALCFG_AUDIOBUFFERSIZE].uValue;
+	gConfig.iVolume = SDL_MIX_MAXVOLUME * values[PALCFG_VOLUME].uValue / 100;
+
+	if (UTIL_GetScreenSize(&values[PALCFG_WINDOWWIDTH].uValue, &values[PALCFG_WINDOWHEIGHT].uValue))
+	{
+		gConfig.dwScreenWidth = values[PALCFG_WINDOWWIDTH].uValue;
+		gConfig.dwScreenHeight = values[PALCFG_WINDOWHEIGHT].uValue;
+	}
+	else
+	{
+		gConfig.dwScreenWidth = PAL_DEFAULT_WINDOW_WIDTH;
+		gConfig.dwScreenHeight = PAL_DEFAULT_WINDOW_HEIGHT;
+	}
+}
+
+
+BOOL
+PAL_SaveConfig(
+	VOID
+)
+{
+	static const char *music_types[] = { "RIX", "MIDI", "MP3", "OGG", "RAW" };
+	static const char *opl_types[] = { "DOSBOX", "MAME" };
+	char buf[512];
+	FILE *fp = fopen(va("%ssdlpal.cfg", PAL_CONFIG_PREFIX), "w");
+
+	if (fp)
+	{
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_DOS), !gConfig.fIsWIN95); fputs(buf, fp);
+#if SDL_VERSION_ATLEAST(2,0,0)
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_KEEPASPECTRATIO), gConfig.fKeepAspectRatio); fputs(buf, fp);
+#else
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_FULLSCREEN), gConfig.fKeepAspectRatio); fputs(buf, fp);
+#endif
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_LAUNCHSETTING), gConfig.fLaunchSetting); fputs(buf, fp);
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_STEREO), gConfig.iAudioChannels == 2 ? TRUE : FALSE); fputs(buf, fp);
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USEEMBEDDEDFONTS), gConfig.fUseEmbeddedFonts); fputs(buf, fp);
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USESURROUNDOPL), gConfig.fUseSurroundOPL); fputs(buf, fp);
+#if PAL_HAS_TOUCH
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_USETOUCHOVERLAY), gConfig.fUseTouchOverlay); fputs(buf, fp);
+#endif
+
+		sprintf(buf, "%s=%d\n", PAL_ConfigName(PALCFG_SURROUNDOPLOFFSET), gConfig.iSurroundOPLOffset); fputs(buf, fp);
+
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_AUDIOBUFFERSIZE), gConfig.wAudioBufferSize); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_CODEPAGE), gConfig.uCodePage); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_OPLSAMPLERATE), gConfig.iOPLSampleRate); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_RESAMPLEQUALITY), gConfig.iResampleQuality); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_SAMPLERATE), gConfig.iSampleRate); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_VOLUME), gConfig.iVolume); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_WINDOWHEIGHT), gConfig.dwScreenHeight); fputs(buf, fp);
+		sprintf(buf, "%s=%u\n", PAL_ConfigName(PALCFG_WINDOWWIDTH), gConfig.dwScreenWidth); fputs(buf, fp);
+
+		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_CD), music_types[gConfig.eCDType]); fputs(buf, fp);
+		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_MUSIC), music_types[gConfig.eMusicType]); fputs(buf, fp);
+		sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_OPL), opl_types[gConfig.eOPLType]); fputs(buf, fp);
+
+		if (gConfig.pszGamePath) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_GAMEPATH), gConfig.pszGamePath); fputs(buf, fp); }
+		if (gConfig.pszMsgFile) { sprintf(buf, "%s=%s\n", PAL_ConfigName(PALCFG_MESSAGEFILE), gConfig.pszMsgFile); fputs(buf, fp); }
+
+		fclose(fp);
+
+		return TRUE;
+	}
+	else
+		return FALSE;
 }

+ 102 - 0
palcfg.h

@@ -27,6 +27,10 @@ extern "C"
 {
 # endif
 
+#include "palcommon.h"
+
+#define     PAL_MAX_SAMPLERATE           48000
+
 typedef enum tagPALCFG_ITEM
 {
 	PALCFG_ALL_MIN = 0,
@@ -104,6 +108,104 @@ typedef struct tagConfigItem
 	const ConfigValue  MaxValue;
 } ConfigItem;
 
+typedef struct tagSCREENLAYOUT
+{
+	PAL_POS          EquipImageBox;
+	PAL_POS          EquipRoleListBox;
+	PAL_POS          EquipItemName;
+	PAL_POS          EquipItemAmount;
+	PAL_POS          EquipLabels[MAX_PLAYER_EQUIPMENTS];
+	PAL_POS          EquipNames[MAX_PLAYER_EQUIPMENTS];
+	PAL_POS          EquipStatusLabels[5];
+	PAL_POS          EquipStatusValues[5];
+
+	PAL_POS          RoleName;
+	PAL_POS          RoleImage;
+	PAL_POS          RoleExpLabel;
+	PAL_POS          RoleLevelLabel;
+	PAL_POS          RoleHPLabel;
+	PAL_POS          RoleMPLabel;
+	PAL_POS          RoleStatusLabels[5];
+	PAL_POS          RoleCurrExp;
+	PAL_POS          RoleNextExp;
+	PAL_POS          RoleExpSlash;
+	PAL_POS          RoleLevel;
+	PAL_POS          RoleCurHP;
+	PAL_POS          RoleMaxHP;
+	PAL_POS          RoleHPSlash;
+	PAL_POS          RoleCurMP;
+	PAL_POS          RoleMaxMP;
+	PAL_POS          RoleMPSlash;
+	PAL_POS          RoleStatusValues[5];
+	PAL_POS          RoleEquipImageBoxes[MAX_PLAYER_EQUIPMENTS];
+	PAL_POS          RoleEquipNames[MAX_PLAYER_EQUIPMENTS];
+	PAL_POS          RolePoisonNames[MAX_POISONS];
+
+	PAL_POS          ExtraItemDescLines;
+	PAL_POS          ExtraMagicDescLines;
+} SCREENLAYOUT;
+
+typedef struct tagCONFIGURATION
+{
+	union {
+		SCREENLAYOUT     ScreenLayout;
+		PAL_POS          ScreenLayoutArray[sizeof(SCREENLAYOUT) / sizeof(PAL_POS)];
+	};
+	enum {
+		USE_8x8_FONT = 1,
+		DISABLE_SHADOW = 2,
+	}                ScreenLayoutFlag[sizeof(SCREENLAYOUT) / sizeof(PAL_POS)];
+
+	/* Configurable options */
+	char            *pszGamePath;
+	char            *pszMsgFile;
+	CODEPAGE         uCodePage;
+	DWORD            dwWordLength;
+	DWORD            dwScreenWidth;
+	DWORD            dwScreenHeight;
+	INT              iSurroundOPLOffset;
+	INT              iAudioChannels;
+	INT              iSampleRate;
+	INT              iOPLSampleRate;
+	INT              iResampleQuality;
+	INT              iVolume;
+	MUSICTYPE        eMusicType;
+	MUSICTYPE        eCDType;
+	OPLTYPE          eOPLType;
+	WORD             wAudioBufferSize;
+	BOOL             fIsWIN95;
+	BOOL             fUseEmbeddedFonts;
+	BOOL             fUseSurroundOPL;
+#if SDL_VERSION_ATLEAST(2,0,0)
+	BOOL             fKeepAspectRatio;
+#else
+	BOOL             fFullScreen;
+#endif
+	BOOL             fEnableJoyStick;
+	BOOL             fUseCustomScreenLayout;
+	BOOL             fLaunchSetting;
+#if PAL_HAS_TOUCH
+	BOOL             fUseTouchOverlay;
+#endif
+#if USE_RIX_EXTRA_INIT
+	uint32_t        *pExtraFMRegs;
+	uint8_t         *pExtraFMVals;
+	uint32_t         dwExtraLength;
+#endif
+} CONFIGURATION, *LPCONFIGURATION;
+
+extern CONFIGURATION gConfig;
+
+VOID
+PAL_LoadConfig(
+	BOOL fFromFile
+);
+
+BOOL
+PAL_SaveConfig(
+	VOID
+);
+
 BOOL
 PAL_ParseConfigLine(
 	const char * line,

+ 1 - 0
palcommon.c

@@ -23,6 +23,7 @@
 
 #include "palcommon.h"
 #include "global.h"
+#include "palcfg.h"
 
 INT
 PAL_RLEBlitToSurface(

+ 1 - 0
rixplay.cpp

@@ -22,6 +22,7 @@
 
 #include <math.h>
 #include "global.h"
+#include "palcfg.h"
 #include "players.h"
 #include "sound.h"
 

+ 1 - 0
sound.c

@@ -21,6 +21,7 @@
 
 #include "palcommon.h"
 #include "global.h"
+#include "palcfg.h"
 #include "sound.h"
 #include "players.h"
 #include "util.h"

+ 7 - 7
winrt/SDLPal.Common/MainPage.xaml

@@ -9,7 +9,7 @@
 
     <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
         <ScrollViewer HorizontalScrollMode="Disabled">
-            <StackPanel VerticalAlignment="Top" Margin="15,0,15,0">
+            <StackPanel VerticalAlignment="Top" Margin="10,0,20,10">
                 <TextBlock Text="SDLPAL" FontSize="48" />
                 <TextBlock x:Uid="Title" Text="设置模式" FontSize="28" VerticalAlignment="Center" />
                 <TextBox x:Name="tbGamePath" x:Uid="GamePath" TextWrapping="Wrap" VerticalAlignment="Top" Header="游戏资源文件夹" IsReadOnly="True" PlaceholderText="未选择游戏资源文件夹"/>
@@ -27,33 +27,33 @@
                 <ToggleSwitch x:Name="tsStereo" x:Uid="Stereo" Header="立体声" OffContent="否" OnContent="是" />
                 <Slider x:Name="slVolume" x:Uid="Volume" Header="音量" TickPlacement="Inline" TickFrequency="10" />
                 <Slider x:Name="slQuality" x:Uid="Quality" Header="音频质量" Maximum="4" LargeChange="1" TickFrequency="1" />
-                <ComboBox x:Name="cbSampleRate" x:Uid="Samplerate" Header="音频输出采样率" PlaceholderText="音频输出采样率">
+                <ComboBox x:Name="cbSampleRate" x:Uid="Samplerate" HorizontalAlignment="Stretch" Header="音频输出采样率" PlaceholderText="音频输出采样率">
                     <ComboBoxItem Content="11025"/>
                     <ComboBoxItem Content="22050"/>
                     <ComboBoxItem Content="44100"/>
                 </ComboBox>
-                <ComboBox x:Name="cbAudioBuffer" x:Uid="AudioBuffer" Header="音频缓冲区大小" PlaceholderText="音频缓冲区大小">
+                <ComboBox x:Name="cbAudioBuffer" x:Uid="AudioBuffer" HorizontalAlignment="Stretch" Header="音频缓冲区大小" PlaceholderText="音频缓冲区大小">
                     <ComboBoxItem Content="512"/>
                     <ComboBoxItem Content="1024"/>
                     <ComboBoxItem Content="2048"/>
                     <ComboBoxItem Content="4096"/>
                     <ComboBoxItem Content="8192"/>
                 </ComboBox>
-                <ComboBox x:Name="cbCD" x:Uid="CD" Header="CD 音轨格式" PlaceholderText="CD 音轨格式">
+                <ComboBox x:Name="cbCD" x:Uid="CD" HorizontalAlignment="Stretch" Header="CD 音轨格式" PlaceholderText="CD 音轨格式">
                     <ComboBoxItem Content="MP3"/>
                     <ComboBoxItem Content="OGG"/>
                 </ComboBox>
-                <ComboBox x:Name="cbBGM" x:Uid="BGM" Header="背景音乐格式" PlaceholderText="背景音乐格式" SelectionChanged="cbBGM_SelectionChanged">
+                <ComboBox x:Name="cbBGM" x:Uid="BGM" HorizontalAlignment="Stretch" Header="背景音乐格式" PlaceholderText="背景音乐格式" SelectionChanged="cbBGM_SelectionChanged">
                     <ComboBoxItem Content="RIX"/>
                     <ComboBoxItem Content="MP3"/>
                     <ComboBoxItem Content="OGG"/>
                 </ComboBox>
-                <ComboBox x:Name="cbOPL" x:Uid="OPL" Header="OPL 模拟器" PlaceholderText="OPL 模拟器">
+                <ComboBox x:Name="cbOPL" x:Uid="OPL" HorizontalAlignment="Stretch" Header="OPL 模拟器" PlaceholderText="OPL 模拟器">
                     <ComboBoxItem Content="DOSBOX"/>
                     <ComboBoxItem Content="MAME"/>
                     <ComboBoxItem Content="DOSBOXNEW"/>
                 </ComboBox>
-                <ComboBox x:Name="cbOPLSR" x:Uid="OPLSR" Header="OPL 模拟器采样率" PlaceholderText="OPL 模拟器采样率">
+                <ComboBox x:Name="cbOPLSR" x:Uid="OPLSR" HorizontalAlignment="Stretch" Header="OPL 模拟器采样率" PlaceholderText="OPL 模拟器采样率">
                     <ComboBoxItem Content="12429"/>
                     <ComboBoxItem Content="24858"/>
                     <ComboBoxItem Content="49716"/>

+ 1 - 0
winrt/SDLPal.Common/MainPage.xaml.cpp

@@ -8,6 +8,7 @@
 #include "StringHelper.h"
 #include "AsyncHelper.h"
 #include "../../global.h"
+#include "../../palcfg.h"
 
 using namespace SDLPal;
 

+ 1 - 0
winrt/SDLPal.Common/SDLPal.cpp

@@ -4,6 +4,7 @@
 #include <windows.h>
 #include "../SDLPal.Common/AsyncHelper.h"
 #include "../../global.h"
+#include "../../palcfg.h"
 #include "App.xaml.h"
 
 HANDLE g_eventHandle = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);

+ 1 - 1
winrt/SDLPal.Common/Strings/en/Resources.resw

@@ -203,7 +203,7 @@
   </data>
   <data name="MBExitContent" xml:space="preserve">
     <value>Settings have been saved and the game will be started on next launch.
-You can use the "return setting" menu option inside the game to return to this page.</value>
+You can use the main menu option inside the game to return to this page.</value>
   </data>
   <data name="MBExitTitle" xml:space="preserve">
     <value>Setting finished</value>

+ 1 - 1
winrt/SDLPal.Common/Strings/zh-hans/Resources.resw

@@ -203,7 +203,7 @@
   </data>
   <data name="MBExitContent" xml:space="preserve">
     <value>您的设置已保存,下次启动时将直接开始游戏。
-在游戏中,您可以通过游戏系统菜单的返回设置选项回本设置页面。</value>
+在游戏中,您可以通过游戏系统菜单的返回设置选项回本设置页面。</value>
   </data>
   <data name="MBExitTitle" xml:space="preserve">
     <value>设置已完成</value>

+ 1 - 1
winrt/SDLPal.Common/Strings/zh-hant/Resources.resw

@@ -203,7 +203,7 @@
   </data>
   <data name="MBExitContent" xml:space="preserve">
     <value>您的設定已保存,下次啟動時將直接開始遊戲。
-在遊戲中,您可以通過遊戲系統功能表的返回設定選項回本設定頁面。</value>
+在遊戲中,您可以通過遊戲系統功能表的返回設定選項回本設定頁面。</value>
   </data>
   <data name="MBExitTitle" xml:space="preserve">
     <value>設定已完成</value>

+ 1 - 0
winrt/SDLPal.Common/WinRTUtil.cpp

@@ -7,6 +7,7 @@
 #include "../SDLPal.Common/AsyncHelper.h"
 #include "../SDLPal.Common/StringHelper.h"
 #include "../../global.h"
+#include "../../palcfg.h"
 
 #include "SDL.h"
 #include "SDL_endian.h"