1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-04 13:42:55 +01:00

Merge pull request #193 from DutchRPW/get_file_path

Port startup checks
This commit is contained in:
Ted John
2014-06-28 20:37:49 +01:00
3 changed files with 239 additions and 10 deletions

View File

@@ -125,7 +125,7 @@ void config_load()
{
FILE *fp=NULL;
char* path = get_file_path(PATH_ID_GAMECFG);
const char *path = get_file_path(PATH_ID_GAMECFG);
fp = fopen(path, "rb");

View File

@@ -232,9 +232,16 @@ void subsitute_path(char *dest, const char *path, const char *filename)
// rct2: 0x00674B42
void rct2_startup_checks()
{
// check if game is already running
// Check if game is already running
if (check_mutex())
{
RCT2_ERROR("Game is already running");
RCT2_CALLPROC_X(0x006E3838, 0x343, 0xB2B, 0, 0, 0, 0, 0); // exit_with_error
}
RCT2_CALLPROC_EBPSAFE(0x00674C0B);
// Check data files
check_file_paths();
check_files_integrity();
}
void rct2_update()
@@ -305,6 +312,99 @@ void check_cmdline_arg()
}
}
// rct2: 0x00407DB0
int check_mutex()
{
const char * const mutex_name = "RollerCoaster Tycoon 2_GSKMUTEX"; // rct2 @ 0x009AAC3D + 0x009A8B50
HANDLE mutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutex_name);
if (mutex != NULL)
{
// Already running
CloseHandle(mutex);
return 1;
}
HANDLE status = CreateMutex(NULL, FALSE, mutex_name);
return 0;
}
// rct2: 0x00674C95
void check_file_paths()
{
for (int pathId = 0; pathId < PATH_ID_END; pathId += 1)
{
check_file_path(pathId);
}
}
// rct2: 0x00674CA5
void check_file_path(int pathId)
{
const char * path = get_file_path(pathId);
HANDLE file = CreateFile(path, FILE_GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
switch (pathId)
{
case PATH_ID_GAMECFG:
case PATH_ID_SCORES:
// Do nothing; these will be created later if they do not exist yet
break;
case PATH_ID_CUSTOM1:
if (file != INVALID_HANDLE_VALUE)
RCT2_GLOBAL(0x009AF164, unsigned int) = SetFilePointer(file, 0, 0, FILE_END); // Store file size in music_custom1_size @ 0x009AF164
break;
case PATH_ID_CUSTOM2:
if (file != INVALID_HANDLE_VALUE)
RCT2_GLOBAL(0x009AF16E, unsigned int) = SetFilePointer(file, 0, 0, FILE_END); // Store file size in music_custom2_size @ 0x009AF16E
break;
default:
if (file == INVALID_HANDLE_VALUE) {
// A data file is missing from the installation directory. The original implementation
// asks for a CD-ROM path at this point and stores it in cdrom_path @ 0x9AA318.
// The file_on_cdrom[pathId] @ 0x009AA0B flag is set to 1 as well.
// For PATH_ID_SIXFLAGS_MAGICMOUNTAIN and PATH_ID_SIXFLAGS_BUILDYOUROWN,
// the original implementation always assumes they are stored on CD-ROM.
// This has been removed for now for the sake of simplicity and could be added
// later in a more convenient way using the INI file.
RCT2_ERROR("Could not find file %s", path);
RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error
}
break;
}
if (file != INVALID_HANDLE_VALUE)
CloseHandle(file);
}
// rct2: 0x00674C0B
void check_files_integrity()
{
int i = 0;
while (files_to_check[i].pathId != PATH_ID_END)
{
WIN32_FIND_DATA find_data;
const char * path = get_file_path(files_to_check[i].pathId);
HANDLE file = FindFirstFile(path, &find_data);
if (file == INVALID_HANDLE_VALUE || find_data.nFileSizeLow != files_to_check[i].fileSize)
{
if (file != INVALID_HANDLE_VALUE)
FindClose(file);
RCT2_ERROR("Integrity check failed for %s", path);
RCT2_CALLPROC_X(0x006E3838, 0x343, 0x337, 0, 0, 0, 0, 0); // exit_with_error
}
FindClose(file);
i += 1;
}
}
void rct2_update_2()
{
int tick, tick2;
@@ -346,13 +446,39 @@ void rct2_endupdate()
*
* rct2: 0x00674E6C
*/
char *get_file_path(int pathId)
const char *get_file_path(int pathId)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
static char path[MAX_PATH]; // get_file_path_buffer @ 0x009E3605
ebx = pathId;
RCT2_CALLFUNC_X(0x00674E6C, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return (char*)ebx;
// The original implementation checks if the file is on CD-ROM here (file_on_cdrom[pathId] @ 0x009AA0B1).
// If so, the CD-ROM path (cdrom_path @ 0x9AA318) is used instead. This has been removed for now for
// the sake of simplicity.
strcpy(path, gGeneral_config.game_path);
// Make sure base path is terminated with a slash
if (strlen(path) == 0 || path[strlen(path) - 1] != '\\')
{
if (strlen(path) >= MAX_PATH - 1)
{
RCT2_ERROR("Path for %s too long", file_paths[pathId]);
path[0] = '\0';
return path;
}
strcat(path, "\\");
}
// Concatenate file path
if (strlen(path) + strlen(file_paths[pathId]) > MAX_PATH)
{
RCT2_ERROR("Path for %s too long", file_paths[pathId]);
path[0] = '\0';
return path;
}
strcat(path, file_paths[pathId]);
return path;
}
/**

View File

@@ -157,13 +157,116 @@ enum {
PATH_ID_CSS43,
PATH_ID_CSS44,
PATH_ID_CSS45,
PATH_ID_CSS46
PATH_ID_CSS46,
PATH_ID_END
};
// rct2 @ 0x0097F67C
static const char * const file_paths[] =
{
"Data\\G1.DAT",
"Data\\PLUGIN.DAT",
"Data\\CSS1.DAT",
"Data\\CSS2.DAT",
"Data\\CSS4.DAT",
"Data\\CSS5.DAT",
"Data\\CSS6.DAT",
"Data\\CSS7.DAT",
"Data\\CSS8.DAT",
"Data\\CSS9.DAT",
"Data\\CSS10.DAT",
"Data\\CSS11.DAT",
"Data\\CSS12.DAT",
"Data\\CSS13.DAT",
"Data\\CSS14.DAT",
"Data\\CSS15.DAT",
"Data\\CSS16.DAT",
"Data\\CSS3.DAT",
"Data\\GAME.CFG",
"Data\\TUT640A.DAT",
"Data\\TUT640B.DAT",
"Data\\TUT640C.DAT",
"Data\\TUT800A.DAT",
"Data\\TUT800B.DAT",
"Data\\TUT800C.DAT",
"Data\\KANJI.DAT",
"Data\\CSS17.DAT",
"Data\\CSS18.DAT",
"Data\\CSS19.DAT",
"Data\\CSS20.DAT",
"Data\\CSS21.DAT",
"Data\\CSS22.DAT",
"Saved Games\\scores.DAT",
"Data\\CSS23.DAT",
"Data\\CSS24.DAT",
"Data\\CSS25.DAT",
"Data\\CSS26.DAT",
"Data\\CSS27.DAT",
"Data\\CSS28.DAT",
"Data\\CSS29.DAT",
"Data\\CSS30.DAT",
"Data\\CSS31.DAT",
"Data\\CSS32.DAT",
"Data\\CSS33.DAT",
"Data\\CSS34.DAT",
"Data\\CSS35.DAT",
"Data\\CSS36.DAT",
"Data\\CSS37.DAT",
"Data\\CSS38.DAT",
"Data\\CUSTOM1.WAV",
"Data\\CUSTOM2.WAV",
"Data\\CSS39.DAT",
"Data\\CSS40.DAT",
"Tracks\\Tracks.IDX",
"Data\\CSS41.DAT",
"Scenarios\\Six Flags Magic Mountain.SC6",
"Scenarios\\Build your own Six Flags Park.SC6",
"Data\\CSS42.DAT",
"Data\\CSS43.DAT",
"Data\\CSS44.DAT",
"Data\\CSS45.DAT",
"Data\\CSS46.DAT"
};
// Files to check (rct2 @ 0x0097FB5A)
static const struct file_to_check
{
int pathId; // ID of file
unsigned int fileSize; // Expected size in bytes
} files_to_check[] = {
{ PATH_ID_CSS18, 8429568 },
{ PATH_ID_CSS19, 10143784 },
{ PATH_ID_CSS20, 12271656 },
{ PATH_ID_CSS21, 9680968 },
{ PATH_ID_CSS22, 10062056 },
{ PATH_ID_CSS23, 11067432 },
{ PATH_ID_CSS24, 12427456 },
{ PATH_ID_CSS25, 15181512 },
{ PATH_ID_CSS26, 10694816 },
{ PATH_ID_CSS27, 10421232 },
{ PATH_ID_CSS28, 13118376 },
{ PATH_ID_CSS29, 15310892 },
{ PATH_ID_CSS30, 10215464 },
{ PATH_ID_CSS31, 11510316 },
{ PATH_ID_CSS32, 11771944 },
{ PATH_ID_CSS33, 10759724 },
{ PATH_ID_CSS34, 14030716 },
{ PATH_ID_CSS35, 11642576 },
{ PATH_ID_CSS36, 8953764 },
{ PATH_ID_CSS37, 13303852 },
{ PATH_ID_CSS38, 10093888 },
{ PATH_ID_CSS39, 7531564 },
{ PATH_ID_CSS40, 5291306 },
{ PATH_ID_END, 0 }
};
void rct2_endupdate();
void subsitute_path(char *dest, const char *path, const char *filename);
char *get_file_path(int pathId);
int check_mutex();
void check_file_paths();
void check_file_path(int pathId);
void check_files_integrity();
const char *get_file_path(int pathId);
void get_system_info();
void get_system_time();
void get_local_time();