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:
@@ -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");
|
||||
|
||||
|
||||
140
src/rct2.c
140
src/rct2.c
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
107
src/rct2.h
107
src/rct2.h
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user