palcfg.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "global.h"
  2. #include "resampler.h"
  3. #include "palcfg.h"
  4. #include <stdint.h>
  5. static const ConfigItem gConfigItems[PALCFG_ALL_MAX] = {
  6. { PALCFG_DOS, PALCFG_BOOLEAN, "DOS", 3, TRUE, FALSE, TRUE }, // Default for DOS
  7. { PALCFG_FULLSCREEN, PALCFG_BOOLEAN, "FULLSCREEN", 10, FALSE, FALSE, TRUE },
  8. { PALCFG_KEEPASPECTRATIO, PALCFG_BOOLEAN, "KEEPASPECTRATIO", 15, TRUE, FALSE, TRUE },
  9. { PALCFG_LAUNCHSETTING, PALCFG_BOOLEAN, "LAUNCHSETTING", 13, TRUE, FALSE, TRUE },
  10. { PALCFG_STEREO, PALCFG_BOOLEAN, "STEREO", 6, TRUE, FALSE, TRUE }, // Default for stereo audio
  11. { PALCFG_USEEMBEDDEDFONTS, PALCFG_BOOLEAN, "USEEMBEDDEDFONTS", 16, TRUE, FALSE, TRUE }, // Default for using embedded fonts in DOS version
  12. { PALCFG_USESURROUNDOPL, PALCFG_BOOLEAN, "USESURROUNDOPL", 14, TRUE, FALSE, TRUE }, // Default for using surround opl
  13. { PALCFG_USETOUCHOVERLAY, PALCFG_BOOLEAN, "USETOUCHOVERLAY", 15, TRUE, FALSE, TRUE },
  14. { PALCFG_SURROUNDOPLOFFSET, PALCFG_INTEGER, "SURROUNDOPLOFFSET", 17, 384, INT32_MIN, INT32_MAX },
  15. { PALCFG_AUDIOBUFFERSIZE, PALCFG_UNSIGNED, "AUDIOBUFFERSIZE", 15, PAL_AUDIO_DEFAULT_BUFFER_SIZE, 2, 32768 },
  16. { PALCFG_CODEPAGE, PALCFG_UNSIGNED, "CODEPAGE", 8, CP_BIG5, CP_BIG5, CP_MAX - 1 }, // Default for BIG5
  17. { PALCFG_OPLSAMPLERATE, PALCFG_UNSIGNED, "OPLSAMPLERATE", 13, 49716, 0, UINT32_MAX },
  18. { PALCFG_RESAMPLEQUALITY, PALCFG_UNSIGNED, "RESAMPLEQUALITY", 15, RESAMPLER_QUALITY_MAX, RESAMPLER_QUALITY_MIN, RESAMPLER_QUALITY_MAX }, // Default for best quality
  19. { PALCFG_SAMPLERATE, PALCFG_UNSIGNED, "SAMPLERATE", 10, 44100, 0, PAL_MAX_SAMPLERATE },
  20. { PALCFG_VOLUME, PALCFG_UNSIGNED, "VOLUME", 6, 100, 0, 100 }, // Default for maximum volume
  21. { PALCFG_WINDOWHEIGHT, PALCFG_UNSIGNED, "WINDOWHEIGHT", 12, PAL_DEFAULT_WINDOW_HEIGHT, 0, UINT32_MAX },
  22. { PALCFG_WINDOWWIDTH, PALCFG_UNSIGNED, "WINDOWWIDTH", 11, PAL_DEFAULT_WINDOW_WIDTH, 0, UINT32_MAX },
  23. { PALCFG_CD, PALCFG_STRING, "CD", 2, "OGG", NULL, NULL },
  24. { PALCFG_GAMEPATH, PALCFG_STRING, "GAMEPATH", 8, NULL, NULL, NULL },
  25. { PALCFG_MESSAGEFILE, PALCFG_STRING, "MESSAGEFILENAME", 15, NULL, NULL, NULL },
  26. { PALCFG_MUSIC, PALCFG_STRING, "MUSIC", 5, "RIX", NULL, NULL },
  27. { PALCFG_OPL, PALCFG_STRING, "OPL", 3, "DOSBOX", NULL, NULL },
  28. { PALCFG_RIXEXTRAINIT, PALCFG_STRING, "RIXEXTRAINIT", 12, NULL, NULL, NULL },
  29. { PALCFG_SAVEPATH, PALCFG_STRING, "SAVEPATH", 8, NULL, NULL, NULL },
  30. };
  31. BOOL
  32. PAL_ParseConfigLine(
  33. const char * line,
  34. const ConfigItem ** ppItem,
  35. ConfigValue * pValue
  36. )
  37. {
  38. //
  39. // Skip leading spaces
  40. //
  41. while (*line && isspace(*line)) line++;
  42. //
  43. // Skip comments
  44. //
  45. if (*line && *line != '#')
  46. {
  47. const char *ptr;
  48. if (ptr = strchr(line, '='))
  49. {
  50. const char *end = ptr++;
  51. //
  52. // Skip tailing spaces
  53. //
  54. while (end > line && isspace(end[-1])) end--;
  55. int len = end - line;
  56. for (int i = 0; i < sizeof(gConfigItems) / sizeof(ConfigItem); i++)
  57. {
  58. if (gConfigItems[i].NameLength == len &&
  59. SDL_strncasecmp(line, gConfigItems[i].Name, len) == 0)
  60. {
  61. if (ppItem) *ppItem = &gConfigItems[i];
  62. if (pValue)
  63. {
  64. if (gConfigItems[i].Type != PALCFG_STRING)
  65. {
  66. switch (gConfigItems[i].Type)
  67. {
  68. case PALCFG_UNSIGNED:
  69. sscanf(ptr, "%u", &pValue->uValue);
  70. if (pValue->uValue < gConfigItems[i].MinValue.uValue)
  71. pValue->uValue = gConfigItems[i].MinValue.uValue;
  72. else if (pValue->uValue > gConfigItems[i].MaxValue.uValue)
  73. pValue->uValue = gConfigItems[i].MaxValue.uValue;
  74. break;
  75. case PALCFG_INTEGER:
  76. sscanf(ptr, "%d", &pValue->iValue);
  77. if (pValue->iValue < gConfigItems[i].MinValue.iValue)
  78. pValue->iValue = gConfigItems[i].MinValue.iValue;
  79. else if (pValue->iValue > gConfigItems[i].MaxValue.iValue)
  80. pValue->iValue = gConfigItems[i].MaxValue.iValue;
  81. break;
  82. case PALCFG_BOOLEAN:
  83. sscanf(ptr, "%d", &pValue->bValue);
  84. pValue->bValue = pValue->bValue ? TRUE : FALSE;
  85. break;
  86. }
  87. }
  88. else
  89. {
  90. //
  91. // Skip leading spaces
  92. //
  93. while (*ptr && isspace(*ptr)) ptr++;
  94. pValue->sValue = ptr;
  95. }
  96. return TRUE;
  97. }
  98. }
  99. }
  100. }
  101. }
  102. return FALSE;
  103. }
  104. ConfigValue
  105. PAL_DefaultConfig(
  106. PALCFG_ITEM item
  107. )
  108. {
  109. return gConfigItems[item].DefaultValue;
  110. }
  111. const char *
  112. PAL_ConfigName(
  113. PALCFG_ITEM item
  114. )
  115. {
  116. return gConfigItems[item].Name;
  117. }
  118. BOOL
  119. PAL_LimitConfig(
  120. PALCFG_ITEM item,
  121. ConfigValue * pValue
  122. )
  123. {
  124. if (!pValue) return FALSE;
  125. switch (gConfigItems[item].Type)
  126. {
  127. case PALCFG_UNSIGNED:
  128. if (pValue->uValue < gConfigItems[item].MinValue.uValue)
  129. {
  130. pValue->uValue = gConfigItems[item].MinValue.uValue;
  131. return TRUE;
  132. }
  133. else if (pValue->uValue > gConfigItems[item].MaxValue.uValue)
  134. {
  135. pValue->uValue = gConfigItems[item].MaxValue.uValue;
  136. return TRUE;
  137. }
  138. else
  139. return FALSE;
  140. case PALCFG_INTEGER:
  141. if (pValue->iValue < gConfigItems[item].MinValue.iValue)
  142. {
  143. pValue->iValue = gConfigItems[item].MinValue.iValue;
  144. return TRUE;
  145. }
  146. else if (pValue->iValue > gConfigItems[item].MaxValue.iValue)
  147. {
  148. pValue->iValue = gConfigItems[item].MaxValue.iValue;
  149. return TRUE;
  150. }
  151. else
  152. return FALSE;
  153. case PALCFG_BOOLEAN:
  154. if (pValue->bValue != TRUE && pValue->bValue != FALSE)
  155. {
  156. pValue->bValue = pValue->bValue ? TRUE : FALSE;
  157. return TRUE;
  158. }
  159. else
  160. return FALSE;
  161. default:
  162. return FALSE;
  163. }
  164. }
  165. static char *move_to_next_line(char *ptr)
  166. {
  167. while (*ptr && (*ptr != '\r' && *ptr != '\n')) ptr++;
  168. while (*ptr && (*ptr == '\r' || *ptr == '\n')) ptr++;
  169. return (*ptr == '\0') ? NULL : ptr;
  170. }