2014-04-08 01:05:05 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
* Copyright (c) 2014 Ted John
|
|
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
|
|
*
|
|
|
|
* This file is part of OpenRCT2.
|
|
|
|
*
|
|
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2014-05-03 15:04:40 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <shlobj.h>
|
2014-04-08 01:05:05 +02:00
|
|
|
#include <windows.h>
|
2014-05-03 15:04:40 +02:00
|
|
|
#include <SDL_keycode.h>
|
2014-04-08 01:05:05 +02:00
|
|
|
#include "addresses.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "rct2.h"
|
|
|
|
|
2014-04-26 02:16:32 +02:00
|
|
|
// Current keyboard shortcuts
|
|
|
|
uint16 gShortcutKeys[SHORTCUT_COUNT];
|
|
|
|
|
|
|
|
// Magic number for original game cfg file
|
2014-04-24 22:29:57 +02:00
|
|
|
static const int MagicNumber = 0x0003113A;
|
|
|
|
|
2014-04-26 02:16:32 +02:00
|
|
|
// Default keyboard shortcuts
|
|
|
|
static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = {
|
|
|
|
SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_TOP_MOST_WINDOW
|
|
|
|
0x0100 | SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_ALL_FLOATING_WINDOWS
|
|
|
|
SDL_SCANCODE_ESCAPE, // SHORTCUT_CANCEL_CONSTRUCTION_MODE
|
|
|
|
SDL_SCANCODE_PAUSE, // SHORTCUT_PAUSE_GAME
|
|
|
|
SDL_SCANCODE_PAGEUP, // SHORTCUT_ZOOM_VIEW_OUT
|
|
|
|
SDL_SCANCODE_PAGEDOWN, // SHORTCUT_ZOOM_VIEW_IN
|
|
|
|
SDL_SCANCODE_RETURN, // SHORTCUT_ROTATE_VIEW
|
|
|
|
SDL_SCANCODE_Z, // SHORTCUT_ROTATE_CONSTRUCTION_OBJECT
|
|
|
|
SDL_SCANCODE_1, // SHORTCUT_UNDERGROUND_VIEW_TOGGLE
|
|
|
|
SDL_SCANCODE_H, // SHORTCUT_REMOVE_BASE_LAND_TOGGLE
|
|
|
|
SDL_SCANCODE_V, // SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE
|
|
|
|
SDL_SCANCODE_3, // SHORTCUT_SEE_THROUGH_RIDES_TOGGLE
|
|
|
|
SDL_SCANCODE_4, // SHORTCUT_SEE_THROUGH_SCENERY_TOGGLE
|
|
|
|
SDL_SCANCODE_5, // SHORTCUT_INVISIBLE_SUPPORTS_TOGGLE
|
|
|
|
SDL_SCANCODE_6, // SHORTCUT_INVISIBLE_PEOPLE_TOGGLE
|
|
|
|
SDL_SCANCODE_8, // SHORTCUT_HEIGHT_MARKS_ON_LAND_TOGGLE
|
|
|
|
SDL_SCANCODE_9, // SHORTCUT_HEIGHT_MARKS_ON_RIDE_TRACKS_TOGGLE
|
|
|
|
SDL_SCANCODE_0, // SHORTCUT_HEIGHT_MARKS_ON_PATHS_TOGGLE
|
|
|
|
SDL_SCANCODE_F1, // SHORTCUT_ADJUST_LAND
|
|
|
|
SDL_SCANCODE_F2, // SHORTCUT_ADJUST_WATER
|
|
|
|
SDL_SCANCODE_F3, // SHORTCUT_BUILD_SCENERY
|
|
|
|
SDL_SCANCODE_F4, // SHORTCUT_BUILD_PATHS
|
|
|
|
SDL_SCANCODE_F5, // SHORTCUT_BUILD_NEW_RIDE
|
|
|
|
SDL_SCANCODE_F, // SHORTCUT_SHOW_FINANCIAL_INFORMATION
|
|
|
|
SDL_SCANCODE_D, // SHORTCUT_SHOW_RESEARCH_INFORMATION
|
|
|
|
SDL_SCANCODE_R, // SHORTCUT_SHOW_RIDES_LIST
|
|
|
|
SDL_SCANCODE_P, // SHORTCUT_SHOW_PARK_INFORMATION
|
|
|
|
SDL_SCANCODE_G, // SHORTCUT_SHOW_GUEST_LIST
|
|
|
|
SDL_SCANCODE_S, // SHORTCUT_SHOW_STAFF_LIST
|
|
|
|
SDL_SCANCODE_M, // SHORTCUT_SHOW_RECENT_MESSAGES
|
|
|
|
SDL_SCANCODE_TAB, // SHORTCUT_SHOW_MAP
|
|
|
|
0x0200 | SDL_SCANCODE_S // SHORTCUT_SCREENSHOT
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006E3604
|
|
|
|
*/
|
|
|
|
void config_reset_shortcut_keys()
|
|
|
|
{
|
|
|
|
memcpy(gShortcutKeys, _defaultShortcutKeys, sizeof(gShortcutKeys));
|
|
|
|
}
|
|
|
|
|
2014-04-24 22:29:57 +02:00
|
|
|
/**
|
2014-05-04 12:14:18 +02:00
|
|
|
* Reads the config file data/config.cfg
|
2014-04-24 22:29:57 +02:00
|
|
|
* rct2: 0x006752D5
|
|
|
|
*/
|
2014-04-08 01:05:05 +02:00
|
|
|
void config_load()
|
|
|
|
{
|
|
|
|
HANDLE hFile;
|
2014-04-24 22:29:57 +02:00
|
|
|
DWORD bytesRead;
|
2014-04-08 01:05:05 +02:00
|
|
|
|
2014-05-04 12:14:18 +02:00
|
|
|
char* path = get_file_path(PATH_ID_GAMECFG);
|
2014-04-08 01:05:05 +02:00
|
|
|
hFile = CreateFile(get_file_path(PATH_ID_GAMECFG), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
|
|
|
FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
|
|
// Read and check magic number
|
2014-04-24 22:29:57 +02:00
|
|
|
ReadFile(hFile, RCT2_ADDRESS(0x013CE928, void), 4, &bytesRead, NULL);
|
|
|
|
if (RCT2_GLOBAL(0x013CE928, int) == MagicNumber) {
|
2014-04-08 01:05:05 +02:00
|
|
|
// Read options
|
2014-04-24 22:29:57 +02:00
|
|
|
ReadFile(hFile, (void*)0x009AAC5C, 2155, &bytesRead, NULL);
|
2014-04-08 01:05:05 +02:00
|
|
|
CloseHandle(hFile);
|
|
|
|
if (RCT2_GLOBAL(0x009AB4C6, sint8) == 1)
|
|
|
|
return;
|
|
|
|
RCT2_GLOBAL(0x009AB4C6, sint8) = 1;
|
2014-05-04 12:14:18 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = 0;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FAHRENHEIT, sint8) = 1;
|
|
|
|
RCT2_GLOBAL(0x009AACBB, sint8) = 1;
|
|
|
|
RCT2_GLOBAL(0x009AACBD, sint16) = 0;
|
2014-04-11 03:42:39 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS))
|
2014-04-16 03:05:49 +02:00
|
|
|
RCT2_GLOBAL(0x009AACBD, sint16) = (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) + 1) * 256;
|
2014-04-08 01:05:05 +02:00
|
|
|
RCT2_GLOBAL(0x009AA00D, sint8) = 1;
|
|
|
|
}
|
2014-05-04 12:14:18 +02:00
|
|
|
|
2014-04-08 01:05:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x009AAC77, sint8) = 0;
|
2014-05-04 17:16:03 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_MEM_TOTAL_PHYSICAL, uint32) > 0x4000000) {
|
2014-04-08 01:05:05 +02:00
|
|
|
RCT2_GLOBAL(0x009AAC77, sint8) = 1;
|
2014-05-04 17:16:03 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_MEM_TOTAL_PHYSICAL, uint32) > 0x8000000)
|
2014-04-08 01:05:05 +02:00
|
|
|
RCT2_GLOBAL(0x009AAC77, sint8) = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x009AAC75, sint8) = RCT2_ADDRESS(0x009AF601, sint8)[RCT2_GLOBAL(0x009AAC77, sint8)];
|
|
|
|
RCT2_GLOBAL(0x009AAC76, sint8) = RCT2_ADDRESS(0x009AF604, sint8)[RCT2_GLOBAL(0x009AAC77, sint8)];
|
|
|
|
RCT2_GLOBAL(0x009AACBD, sint16) = 0;
|
2014-04-11 03:42:39 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS))
|
2014-04-16 03:05:49 +02:00
|
|
|
RCT2_GLOBAL(0x009AACBD, sint16) = (RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) + 1) * 256;
|
2014-04-08 01:05:05 +02:00
|
|
|
RCT2_GLOBAL(0x009AA00D, sint8) = 1;
|
2014-04-21 11:27:48 +02:00
|
|
|
}
|
2014-04-24 22:29:57 +02:00
|
|
|
|
|
|
|
/**
|
2014-05-04 12:14:18 +02:00
|
|
|
* Save configuration to the data/config.cfg file
|
2014-04-24 22:29:57 +02:00
|
|
|
* rct2: 0x00675487
|
|
|
|
*/
|
|
|
|
void config_save()
|
|
|
|
{
|
|
|
|
HANDLE hFile;
|
|
|
|
DWORD bytesWritten;
|
|
|
|
|
|
|
|
hFile = CreateFile(get_file_path(PATH_ID_GAMECFG), GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
|
|
WriteFile(hFile, &MagicNumber, 4, &bytesWritten, NULL);
|
|
|
|
WriteFile(hFile, 0x009AAC5C, 2155, &bytesWritten, NULL);
|
|
|
|
CloseHandle(hFile);
|
|
|
|
}
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// New config format
|
|
|
|
|
|
|
|
configuration_t gConfig;
|
|
|
|
|
|
|
|
static void config_parse_settings(FILE *fp);
|
|
|
|
static int config_get_line(FILE *fp, char *setting, char *value);
|
2014-05-08 11:05:07 +02:00
|
|
|
static int config_parse_setting(FILE *fp, char *setting);
|
|
|
|
static int config_parse_value(FILE *fp, char *value);
|
|
|
|
static int config_parse_section(FILE *fp, char *setting, char *value);
|
2014-05-03 15:04:40 +02:00
|
|
|
static void config_create_default(char *path);
|
2014-05-08 11:05:07 +02:00
|
|
|
static void config_error(char *msg);
|
2014-05-03 15:04:40 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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)) {
|
2014-05-08 11:05:07 +02:00
|
|
|
config_error("Could not create config file (do you have write acces to you documents folder?)");
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
strcat(path, "\\config.ini");
|
|
|
|
fp = fopen(path, "r");
|
|
|
|
if (!fp) {
|
|
|
|
config_create_default(path);
|
|
|
|
fp = fopen(path, "r");
|
|
|
|
if (!fp)
|
2014-05-08 11:05:07 +02:00
|
|
|
config_error("Could not create config file");
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
config_parse_settings(fp);
|
2014-05-03 15:59:23 +02:00
|
|
|
|
|
|
|
fclose(fp);
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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",
|
2014-05-03 19:13:10 +02:00
|
|
|
"C:\\Program Files\\Infogrames Interactive\\RollerCoaster Tycoon 2",
|
|
|
|
"C:\\Program Files (x86)\\Infogrames Interactive\\RollerCoaster Tycoon 2",
|
|
|
|
"C:\\Program Files\\Atari\\RollerCoaster Tycoon 2",
|
|
|
|
"C:\\Program Files (x86)\\Atari\\RollerCoaster Tycoon 2",
|
2014-05-03 15:04:40 +02:00
|
|
|
"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);
|
2014-05-03 22:30:29 +02:00
|
|
|
fprintf(fp, "screenshot_format = PNG\n");
|
2014-05-04 20:59:24 +02:00
|
|
|
fprintf(fp, "play_intro = false\n");
|
2014-05-03 15:04:40 +02:00
|
|
|
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;
|
2014-05-04 12:14:18 +02:00
|
|
|
char *section;
|
2014-05-03 15:59:23 +02:00
|
|
|
setting = (char *)malloc(MAX_CONFIG_LENGTH);
|
|
|
|
value = (char *)malloc(MAX_CONFIG_LENGTH);
|
2014-05-08 11:05:07 +02:00
|
|
|
section = (char*)malloc(MAX_CONFIG_LENGTH);
|
2014-05-03 15:04:40 +02:00
|
|
|
|
|
|
|
while (config_get_line(fp, setting, value) > 0) {
|
2014-05-08 11:05:07 +02:00
|
|
|
if (strcmp(setting, "section") == 0){
|
|
|
|
strcpy(section, value);
|
2014-05-04 12:14:18 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
if (strcmp(setting, "game_path") == 0){
|
2014-05-03 15:59:23 +02:00
|
|
|
strcpy(gConfig.game_path, value);
|
2014-05-03 15:04:40 +02:00
|
|
|
} else if(strcmp(setting, "screenshot_format") == 0) {
|
2014-05-03 22:30:29 +02:00
|
|
|
if (strcmp(value, "png") == 0 || strcmp(value, "PNG") == 0) {
|
|
|
|
gConfig.screenshot_format = SCREENSHOT_FORMAT_PNG;
|
2014-05-08 11:05:07 +02:00
|
|
|
} else if (strcmp(value, "1") == 0) { //TODO: REMOVE LINE AT LATER DATE WHEN EVERYONE HAS NEW CONFIG FORMAT
|
2014-05-03 22:30:29 +02:00
|
|
|
gConfig.screenshot_format = SCREENSHOT_FORMAT_PNG;
|
2014-05-03 15:04:40 +02:00
|
|
|
} else {
|
2014-05-03 22:30:29 +02:00
|
|
|
gConfig.screenshot_format = SCREENSHOT_FORMAT_BMP;
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-04 20:59:24 +02:00
|
|
|
} else if (strcmp(setting, "play_intro") == 0) {
|
|
|
|
gConfig.play_intro = (strcmp(value, "true") == 0);
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
}
|
2014-05-03 15:59:23 +02:00
|
|
|
free(setting);
|
|
|
|
free(value);
|
2014-05-08 11:05:07 +02:00
|
|
|
free(section);
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read one line in the settings file
|
2014-05-08 11:05:07 +02:00
|
|
|
* @param fp filepointer to the config file
|
2014-05-03 15:04:40 +02:00
|
|
|
* @param setting pointer where to to store the setting
|
|
|
|
* @param value pointer to where to store the value
|
2014-05-08 11:05:07 +02:00
|
|
|
* @return < 0 if EOF file is reached or other error
|
2014-05-03 15:04:40 +02:00
|
|
|
*/
|
|
|
|
static int config_get_line(FILE *fp, char *setting, char *value)
|
|
|
|
{
|
2014-05-08 11:05:07 +02:00
|
|
|
int c;
|
|
|
|
|
2014-05-03 15:04:40 +02:00
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
while (isspace(c)){
|
|
|
|
c = getc(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == '['){
|
|
|
|
return config_parse_section(fp, setting, value);
|
|
|
|
}
|
|
|
|
else if(c == '#'){
|
|
|
|
while (c != '\n'){
|
|
|
|
c = fgetc(fp);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (c == EOF){
|
2014-05-03 15:04:40 +02:00
|
|
|
return -1;
|
2014-05-08 11:05:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
while (!isalpha(c)){
|
2014-05-03 15:59:23 +02:00
|
|
|
c = fgetc(fp);
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-08 11:05:07 +02:00
|
|
|
|
|
|
|
//if the first char is not the '[' char, it belongs to the setting name. We want to leave that for the next fn
|
|
|
|
fseek(fp, -1, SEEK_CUR);
|
|
|
|
|
|
|
|
config_parse_setting(fp, setting);
|
2014-05-03 15:04:40 +02:00
|
|
|
|
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
while (isspace(c)){
|
|
|
|
c = getc(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c != '='){
|
|
|
|
config_error("There is an error in your configuration file");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
config_parse_value(fp, value);
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2014-05-03 15:04:40 +02:00
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
/**
|
|
|
|
* Parse the value of a setting
|
|
|
|
* @param fp a filepointer to the config file
|
|
|
|
* @param value a pointer to where to store the setting
|
|
|
|
* @return < 0 if EOF is reached
|
|
|
|
*/
|
|
|
|
static int config_parse_setting(FILE *fp, char *setting){
|
|
|
|
long start, end;
|
|
|
|
int size, c, pos = 0;
|
|
|
|
|
|
|
|
|
|
|
|
start = ftell(fp);
|
|
|
|
c = fgetc(fp);
|
|
|
|
|
|
|
|
while (isspace(c)){
|
|
|
|
start = ftell(fp);
|
2014-05-04 12:14:18 +02:00
|
|
|
c = fgetc(fp);
|
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
}
|
|
|
|
if (c == EOF){
|
|
|
|
return -1;
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-03 15:59:23 +02:00
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
while (isalpha(c) || c == '_'){
|
|
|
|
c = fgetc(fp);
|
|
|
|
}
|
2014-05-03 15:59:23 +02:00
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
end = ftell(fp);
|
|
|
|
size = end - start;
|
|
|
|
|
|
|
|
|
|
|
|
fseek(fp, start, SEEK_SET);
|
|
|
|
c = fgetc(fp);
|
2014-05-03 15:04:40 +02:00
|
|
|
while (isalpha(c) || c == '_'){
|
|
|
|
setting[pos] = (char)c;
|
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
pos++;
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
|
|
|
setting[pos] = '\0';
|
2014-05-08 11:05:07 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse the value of a setting
|
|
|
|
* @param fp a filepointer to the config file
|
|
|
|
* @param value a pointer to where to store the value
|
|
|
|
* @return < 0 if EOF is reached
|
|
|
|
*/
|
|
|
|
static int config_parse_value(FILE *fp, char *value){
|
|
|
|
long start, end;
|
|
|
|
int size, c, pos = 0;
|
|
|
|
|
|
|
|
start = ftell(fp);
|
|
|
|
c = fgetc(fp);
|
|
|
|
while (isspace(c)){
|
|
|
|
start = ftell(fp);
|
2014-05-03 15:04:40 +02:00
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
while (c != EOF && c != '\n'){
|
|
|
|
c = fgetc(fp);
|
|
|
|
}
|
|
|
|
end = ftell(fp);
|
|
|
|
size = end - start;
|
|
|
|
if (size > MAX_CONFIG_LENGTH){
|
|
|
|
config_error("One of your settings is too long");
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-08 11:05:07 +02:00
|
|
|
fseek(fp, start, SEEK_SET);
|
2014-05-03 15:04:40 +02:00
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
while (c != EOF && c != '\n'){
|
|
|
|
|
|
|
|
value[pos] = (char)c;
|
2014-05-03 15:04:40 +02:00
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
pos++;
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-08 11:05:07 +02:00
|
|
|
value[pos] = '\0';
|
|
|
|
return;
|
|
|
|
}
|
2014-05-03 15:04:40 +02:00
|
|
|
|
2014-05-08 11:05:07 +02:00
|
|
|
/**
|
|
|
|
* Parse the current section
|
|
|
|
* @param fp Filepointer to the config file
|
|
|
|
* @param setting This is set to contain the string "section"
|
|
|
|
* @param value Pointer to where the section name should be put
|
|
|
|
* @return < 0 if EOF is reached
|
|
|
|
*/
|
|
|
|
static int config_parse_section(FILE *fp, char *setting, char *value){
|
|
|
|
int size, c, pos = 0;
|
|
|
|
long start, end;
|
|
|
|
|
|
|
|
strcpy(setting, "section\0");
|
|
|
|
c = fgetc(fp);
|
2014-05-03 15:04:40 +02:00
|
|
|
start = ftell(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
while (c != ']' && c != EOF){
|
2014-05-03 15:04:40 +02:00
|
|
|
c = fgetc(fp);
|
|
|
|
}
|
|
|
|
end = ftell(fp);
|
|
|
|
size = end - start;
|
|
|
|
fseek(fp, start - 1, SEEK_SET);
|
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
while (c != ']' && c != EOF){
|
2014-05-03 15:04:40 +02:00
|
|
|
value[pos] = (char)c;
|
|
|
|
c = fgetc(fp);
|
2014-05-08 11:05:07 +02:00
|
|
|
pos++;
|
2014-05-03 15:04:40 +02:00
|
|
|
}
|
2014-05-08 11:05:07 +02:00
|
|
|
|
2014-05-03 15:04:40 +02:00
|
|
|
value[pos] = '\0';
|
2014-05-08 11:05:07 +02:00
|
|
|
if (c != ']'){
|
|
|
|
config_error("There is an error with the section headers");
|
|
|
|
}
|
|
|
|
c = fgetc(fp); //devour ']'
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Error with config file. Print error message an quit the game
|
|
|
|
* @param msg Message to print in message box
|
|
|
|
*/
|
|
|
|
static void config_error(char *msg){
|
|
|
|
MessageBox(NULL, msg, "OpenRCT2", MB_OK);
|
|
|
|
//TODO:SHUT DOWN EVERYTHING!
|
|
|
|
}
|
|
|
|
|
|
|
|
|