From f0e56572860d92c45ef1bf083a2ed157a7fb0938 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 3 May 2014 14:04:40 +0100 Subject: [PATCH] move settings to config and improve --- src/config.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++- src/config.h | 13 ++++ src/rct2.c | 10 ++- src/rct2.h | 2 + src/screenshot.c | 5 +- src/screenshot.h | 2 - src/settings.c | 139 ---------------------------------- src/settings.h | 14 ---- 8 files changed, 216 insertions(+), 161 deletions(-) diff --git a/src/config.c b/src/config.c index 8a0fdbd6f6..bab8fd2c67 100644 --- a/src/config.c +++ b/src/config.c @@ -18,8 +18,10 @@ * along with this program. If not, see . *****************************************************************************/ -#include +#include +#include #include +#include #include "addresses.h" #include "config.h" #include "rct2.h" @@ -136,4 +138,192 @@ void config_save() WriteFile(hFile, 0x009AAC5C, 2155, &bytesWritten, NULL); CloseHandle(hFile); } +} + +// New config format + +configuration_t gConfig; + +static void config_parse_settings(FILE *fp); +static int config_get_line(FILE *fp, char *setting, char *value); +static void config_create_default(char *path); + +/** + * Initilise the settings. + * It checks if the OpenRCT2 folder exists and creates it if it does not + * parsing of the config file is done in config_parse_settings + */ +void config_init() +{ + TCHAR path[MAX_PATH]; + FILE* fp; + + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) { // find home folder + strcat(path, "\\OpenRCT2"); + DWORD dwAttrib = GetFileAttributes(path); + if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { // folder does not exist + if (!CreateDirectory(path, NULL)) { + return NULL; // error creating path + } + } + strcat(path, "\\config.ini"); + fp = fopen(path, "r"); + if (!fp) { + config_create_default(path); + fp = fopen(path, "r"); + if (!fp) + return NULL; + } + + config_parse_settings(fp); + } +} + +/** + * Attempts to find the RCT2 installation directory. + * This should be created from some other resource when OpenRCT2 grows. + * @param resultPath Pointer to where the absolute path of the RCT2 installation directory will be copied to. + * @returns 1 if successful, otherwise 0. + */ +static int config_find_rct2_path(char *resultPath) +{ + int i; + DWORD dwAttrib; + const char *searchLocations[] = { + "C:\\Program Files\\Infogrames\\RollerCoaster Tycoon 2", + "C:\\Program Files (x86)\\Infogrames\\RollerCoaster Tycoon 2", + "C:\\GOG Games\\RollerCoaster Tycoon 2 Triple Thrill Pack" + }; + + for (i = 0; i < countof(searchLocations); i++) { + dwAttrib = GetFileAttributes(searchLocations[i]); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + strcpy(resultPath, searchLocations[i]); + return 1; + } + } + + return 0; +} + +/** + * Create a new default settings file. + * This should be created from some other resource when openRCT2 grows + * @param path The aboslute path of the config file + */ +static void config_create_default(char *path) +{ + FILE* fp; + + if (!config_find_rct2_path(gConfig.game_path)) { + MessageBox(NULL, "Unable to find RCT2 installation directory. Please correct in config.ini.", "OpenRCT2", MB_OK); + strcpy(gConfig.game_path, "C:\\"); + } + + fp = fopen(path, "w"); + fprintf(fp, "[general]\n"); + fprintf(fp, "game_path = %s\n", gConfig.game_path); + fprintf(fp, "screenshot_format = 1\n"); + fclose(fp); +} + +/** + * Parse settings and set the game veriables + * @param fp file pointer to the settings file + */ +static void config_parse_settings(FILE *fp) +{ + int c = NULL, pos = 0; + char *setting; + char *value; + setting = (char *)malloc(128); + value = (char *)malloc(128); + + int size = 256; + + while (config_get_line(fp, setting, value) > 0) { + if (strcmp(setting, "game_path") == 0){ + strcpy(gConfig.game_path, value); // TODO: change to copy correct amount of bytes + } else if(strcmp(setting, "screenshot_format") == 0) { + if (strcmp(value, "1") == 0) { + gConfig.screenshot_format = 1; + } else { + gConfig.screenshot_format = 0; + } + } + } +} + +/** + * Read one line in the settings file + * @param fp filepointer to the settings file + * @param setting pointer where to to store the setting + * @param value pointer to where to store the value + * @return < 0 on error + */ +static int config_get_line(FILE *fp, char *setting, char *value) +{ + long start = ftell(fp); + long end; + int c; + int pos = 0; + long size; + c = fgetc(fp); + if (c == EOF) + return -1; + while (isalpha(c) || c == '_'){ + c = fgetc(fp); // find size of setting + if (c == EOF) + return -1; + } + + end = ftell(fp); + size = end - start; + realloc(setting, size); + fseek(fp, start, SEEK_SET); + c = fgetc(fp); + if (c == '[') { + // TODO support categories + setting[0] = '\0'; + value[0] = '\0'; + while (c != '\n' && c != EOF) { + pos++; + c = fgetc(fp); + } + + return 1; + } + while (isalpha(c) || c == '_'){ + setting[pos] = (char)c; + pos++; + c = fgetc(fp); + } + setting[pos] = '\0'; + while (c != '=') { + if (c == EOF || c == '\n') { // this is not a valid setting + return -1; + } + c = fgetc(fp); + } + c = fgetc(fp); + while (isspace(c)) { + c = fgetc(fp); + } + + start = ftell(fp); + while (c != '\n' && c!= EOF) { + c = fgetc(fp); + } + end = ftell(fp); + size = end - start; + realloc(value, size); + fseek(fp, start - 1, SEEK_SET); + pos = 0; + c = fgetc(fp); + while (c != '\n' && c != EOF) { + value[pos] = (char)c; + pos++; + c = fgetc(fp); + } + value[pos] = '\0'; } \ No newline at end of file diff --git a/src/config.h b/src/config.h index efc5df03ba..c5cfccf276 100644 --- a/src/config.h +++ b/src/config.h @@ -21,6 +21,7 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ +#include #include "rct2.h" enum { @@ -71,4 +72,16 @@ void config_reset_shortcut_keys(); void config_load(); void config_save(); + +// New config format + +typedef struct configuration { + uint8 screenshot_format; + char game_path[MAX_PATH]; +} configuration_t; + +extern configuration_t gConfig; + +void config_init(); + #endif diff --git a/src/rct2.c b/src/rct2.c index b54f1dbb5d..fa49f9d794 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -70,7 +70,7 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta get_system_info(); RCT2_CALLPROC(0x0040502E); // get_dsound_devices() - settings_init(); + config_init(); rct2_init(); rct2_loop(); osinterface_free(); @@ -149,8 +149,14 @@ void rct2_init() // rct2: 0x00683499 void rct2_init_directories() { + // check install directory + DWORD dwAttrib = GetFileAttributes(gConfig.game_path); + if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + MessageBox(NULL, "Invalid RCT2 installation path. Please correct in config.ini.", "OpenRCT2", MB_OK); + exit(-1); + } - strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), settings.GAME_PATH); + strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gConfig.game_path); strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char)); strcat(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), "\\"); diff --git a/src/rct2.h b/src/rct2.h index 7239b89b7a..2d4d479daa 100644 --- a/src/rct2.h +++ b/src/rct2.h @@ -44,6 +44,8 @@ typedef unsigned long long uint64; #define sgn(x) ((x > 0) ? 1 : ((x < 0) ? -1 : 0)) #define clamp(l, x, h) (min(h, max(l, x))) +#define countof(x) _countof(x) + void rct2_finish(); enum { diff --git a/src/screenshot.c b/src/screenshot.c index 727d2ffc4d..9aa0cb5c36 100644 --- a/src/screenshot.c +++ b/src/screenshot.c @@ -22,6 +22,7 @@ #include #include #include "addresses.h" +#include "config.h" #include "gfx.h" #include "rct2.h" #include "screenshot.h" @@ -33,8 +34,6 @@ enum { SCREENSHOT_FORMAT_PNG }; -int gScreenshotFormat = SCREENSHOT_FORMAT_PNG; - static int screenshot_dump_bmp(); static int screenshot_dump_png(); @@ -80,7 +79,7 @@ static int screenshot_get_next_path(char *path, char *extension) int screenshot_dump() { - switch (gScreenshotFormat) { + switch (gConfig.screenshot_format) { case SCREENSHOT_FORMAT_BMP: return screenshot_dump_bmp(); case SCREENSHOT_FORMAT_PNG: diff --git a/src/screenshot.h b/src/screenshot.h index 727e8a3b0d..2515ebe79d 100644 --- a/src/screenshot.h +++ b/src/screenshot.h @@ -21,8 +21,6 @@ #ifndef _SCREENSHOT_H_ #define _SCREENSHOT_H_ -extern int gScreenshotFormat; - void screenshot_check(); int screenshot_dump(); diff --git a/src/settings.c b/src/settings.c index e18e9bd437..6e281aa97a 100644 --- a/src/settings.c +++ b/src/settings.c @@ -26,142 +26,3 @@ #include "settings.h" #include "screenshot.h" -settings_t settings; - - -/** - * Initilize the settings. - * It checks if the openRCT2 folder exists and creates it if it does not - * parsing of the config file is done in settings_parse_settings - */ -void settings_init(){ - - TCHAR path[MAX_PATH]; - FILE* fp; - - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))){ //find home folder - strcat(path, "\\OpenRCT2"); - DWORD dwAttrib = GetFileAttributes(path); - if (!(dwAttrib != INVALID_FILE_ATTRIBUTES && dwAttrib & FILE_ATTRIBUTE_DIRECTORY)){ //folder does not exist - if (!CreateDirectory(path, NULL)){ - return NULL; //error createing path - } - } - strcat(path, "\\config.ini"); - fp = fopen(path, "r"); - if (!fp){ - settings_create_default(path); - fp = fopen(path, "r"); - if (!fp){ - return NULL; - } - } - - settings_parse_settings(fp); - - } -} - -/** - * Create a new default settings file. - * This should be created from some other resource when openRCT2 grows - * @param path The aboslute path of the config file - */ -void settings_create_default(char *path){ - FILE* fp = fopen(path, "w"); - fprintf(fp, "GAME_PATH = C:\\GOG Games\\RollerCoaster Tycoon 2 Triple Thrill Pack\n"); - fprintf(fp, "SCREENSHOT_AS_PNG = TRUE\n"); - fclose(fp); -} - -/** - * Parse settings and set the game veriables - * @param fp file pointer to the settings file - */ -void settings_parse_settings(FILE *fp){ - int c = NULL, pos = 0; - char *setting; - char *value; - setting = (char *)malloc(128); - value = (char *)malloc(128); - - int size = 256; - - while (settings_get_line(fp, setting, value) > 0){ - - if (strcmp(setting, "GAME_PATH") == 0){ - strcpy(settings.GAME_PATH, value); //TODO: change to copy correct amount of bytes - } - else if(strcmp(setting, "SCREENSHOT_AS_PNG") == 0){ - - if (value == '1'){ - settings.SCREENSHOT_AS_PNG = 1; - } - else{ - settings.SCREENSHOT_AS_PNG = 0; - } - } - } - -} - -/** - * Read one line in the settings file - * @param fp filepointer to the settings file - * @param setting pointer where to to store the setting - * @param value pointer to where to store the value - * @return < 0 on error - */ -int settings_get_line(FILE *fp, char *setting, char *value){ - long start = ftell(fp); - long end; - int c; - int pos = 0; - long size; - c = fgetc(fp); - if(c == EOF) return -1; - while (isalpha(c) || c == '_'){ - c = fgetc(fp); //find size of setting - if (c == EOF) return -1; - } - - end = ftell(fp); - size = end - start; - realloc(setting, size); - fseek(fp, start, SEEK_SET); - c = fgetc(fp); - while (isalpha(c) || c == '_'){ - setting[pos] = (char)c; - pos++; - c = fgetc(fp); - } - setting[pos] = '\0'; - while (c != '='){ - if (c == EOF || c == '\n'){ // this is not a valid setting - return -1; - } - c = fgetc(fp); - } - c = fgetc(fp); - while (isspace(c)){ - c = fgetc(fp); - } - - start = ftell(fp); - while (c != '\n' && c!= EOF){ - c = fgetc(fp); - } - end = ftell(fp); - size = end - start; - realloc(value, size); - fseek(fp, start - 1, SEEK_SET); - pos = 0; - c = fgetc(fp); - while (c != '\n' && c != EOF){ - value[pos] = (char)c; - pos++; - c = fgetc(fp); - } - value[pos] = '\0'; - -} \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index a47c943343..d5e2452ac0 100644 --- a/src/settings.h +++ b/src/settings.h @@ -26,22 +26,8 @@ #include "rct2.h" -void settings_parse_settings(FILE *fp); -int settings_get_line(FILE *fp, char *setting, char *value); -void settings_init(); -void settings_create_default(char *path); - - -typedef struct settings{ - uint8 SCREENSHOT_AS_PNG; - char GAME_PATH[MAX_PATH]; - -} settings_t; - -extern settings_t settings; - #endif \ No newline at end of file