diff --git a/src/editor.c b/src/editor.c index 138eeb1162..6a1ce41585 100644 --- a/src/editor.c +++ b/src/editor.c @@ -166,6 +166,16 @@ void trackmanager_load() rct2_endupdate(); } +/** + * + * rct2: 0x006758C0 + */ +void editor_load_landscape(const char *path) +{ + strcpy((char *)0x0141EF68, path); + RCT2_CALLPROC_EBPSAFE(0x006758C0); +} + /** * * rct2: 0x0068ABEC diff --git a/src/editor.h b/src/editor.h index 9022a6cd4d..c544bf3a16 100644 --- a/src/editor.h +++ b/src/editor.h @@ -25,6 +25,7 @@ void editor_load(); void editor_convert_save_to_scenario(); void trackdesigner_load(); void trackmanager_load(); +void editor_load_landscape(const char *path); void sub_6BD3A4(); diff --git a/src/game.c b/src/game.c index 68f5448448..b837b67215 100644 --- a/src/game.c +++ b/src/game.c @@ -694,14 +694,13 @@ static void load_landscape() * * rct2: 0x00675E1B */ -int game_load_save() +int game_load_save(const char *path) { rct_window *mainWindow; FILE *file; - char *path; int i, j; - path = (char*)0x0141EF68; + strcpy((char*)0x0141EF68, path); file = fopen(path, "rb"); if (file == NULL) { RCT2_GLOBAL(0x009AC31B, uint8) = 255; @@ -831,7 +830,7 @@ static void load_game() } strcpy((char*)RCT2_ADDRESS_SAVED_GAMES_PATH_2, (char*)0x0141EF68); - if (game_load_save()) { + if (game_load_save((char *)0x0141EF68)) { gfx_invalidate_screen(); rct2_endupdate(); } else { diff --git a/src/game.h b/src/game.h index d10b3f533e..b968ca42f7 100644 --- a/src/game.h +++ b/src/game.h @@ -100,7 +100,7 @@ void game_increase_game_speed(); void game_reduce_game_speed(); void game_load_or_quit_no_save_prompt(); -int game_load_save(); +int game_load_save(const char *path); void game_pause_toggle(); char save_game(); void rct2_exit(); diff --git a/src/rct2.c b/src/rct2.c index 0af4c93dea..e67a093c6c 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -66,6 +66,8 @@ static void rct2_loop(); static void rct2_update(); static void rct2_update_2(); +PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc); + static int _finished; static jmp_buf _end_update_jump; @@ -269,51 +271,47 @@ void rct2_update() rct2_update_2(); } +int rct2_open_file(const char *path) +{ + char *extension = strrchr(path, '.'); + if (extension == NULL) + return 0; + extension++; + + if (_stricmp(extension, "sv6")) { + game_load_save(path); + } else if (!_stricmp(extension, "sc6")) { + // TODO scenario install + rct_scenario_basic scenarioBasic; + strcpy(scenarioBasic.path, path); + scenario_load_and_play_from_path(scenarioBasic.path); + } else if (!_stricmp(extension, "td6") || !_stricmp(extension, "td4")) { + // TODO track design install + } +} + void check_cmdline_arg() { - if(RCT2_GLOBAL(0x009AC310, uint32) == 0xFFFFFFFF) + int argc; + char **argv; + char *args; + + args = RCT2_GLOBAL(0x009AC310, char*); + if (args == (char*)0xFFFFFFFF) return; + RCT2_GLOBAL(0x009AC310, char*) = (char*)0xFFFFFFFF; - char *arg = RCT2_GLOBAL(0x009AC310, char *); - char processed_arg[255]; - int len, i, j; - int quote = 0; - int last_period = 0; - - RCT2_GLOBAL(0x009AC310, uint32) = 0xFFFFFFFF; - len = strlen(arg); - - for(i = 0, j = 0; i < len; i ++) - { - if(arg[i] == '\"') - { - if(quote) - quote = 0; - else - quote = 1; - continue; + argv = CommandLineToArgvA(args, &argc); + if (argc > 0) { + if (_stricmp(argv[0], "edit") == 0) { + if (argc >= 1) + editor_load_landscape(argv[1]); + } else { + rct2_open_file(argv[0]); } - if(arg[i] == ' ' && !quote) - break; - if(arg[i] == '.') - last_period = i; - processed_arg[j ++] = arg[i]; } - processed_arg[j ++] = 0; - if (!_stricmp(processed_arg + last_period, "sv6")) - { - strcpy((char*)0x00141EF68, processed_arg); - game_load_save(); - } - else if (!_stricmp(processed_arg + last_period, "sc6")) - { - //TODO: scenario install - } - else if (!_stricmp(processed_arg + last_period, "td6") || !_stricmp(processed_arg + last_period, "td4")) - { - //TODO: track design install - } + LocalFree(argv); } // rct2: 0x00407DB0 @@ -605,3 +603,86 @@ void rct2_free(void *block) { RCT2_CALLPROC_1(0x004068DE, void*, block); } + +/** + * http://alter.org.ua/en/docs/win/args/ + */ +PCHAR *CommandLineToArgvA(PCHAR CmdLine, int *_argc) +{ + PCHAR* argv; + PCHAR _argv; + ULONG len; + ULONG argc; + CHAR a; + ULONG i, j; + + BOOLEAN in_QM; + BOOLEAN in_TEXT; + BOOLEAN in_SPACE; + + len = strlen(CmdLine); + i = ((len + 2) / 2)*sizeof(PVOID) + sizeof(PVOID); + + argv = (PCHAR*)GlobalAlloc(GMEM_FIXED, + i + (len + 2)*sizeof(CHAR)); + + _argv = (PCHAR)(((PUCHAR)argv) + i); + + argc = 0; + argv[argc] = _argv; + in_QM = FALSE; + in_TEXT = FALSE; + in_SPACE = TRUE; + i = 0; + j = 0; + + while (a = CmdLine[i]) { + if (in_QM) { + if (a == '\"') { + in_QM = FALSE; + } else { + _argv[j] = a; + j++; + } + } else { + switch (a) { + case '\"': + in_QM = TRUE; + in_TEXT = TRUE; + if (in_SPACE) { + argv[argc] = _argv + j; + argc++; + } + in_SPACE = FALSE; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (in_TEXT) { + _argv[j] = '\0'; + j++; + } + in_TEXT = FALSE; + in_SPACE = TRUE; + break; + default: + in_TEXT = TRUE; + if (in_SPACE) { + argv[argc] = _argv + j; + argc++; + } + _argv[j] = a; + j++; + in_SPACE = FALSE; + break; + } + } + i++; + } + _argv[j] = '\0'; + argv[argc] = NULL; + + (*_argc) = argc; + return argv; +} diff --git a/src/scenario.c b/src/scenario.c index 4851a038d6..7a69cc050d 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -83,7 +83,7 @@ int scenario_load_basic(const char *path) * rct2: 0x00676053 * scenario (ebx) */ -void scenario_load(const char *path) +int scenario_load(const char *path) { FILE *file; int i, j; @@ -96,7 +96,7 @@ void scenario_load(const char *path) fclose(file); RCT2_GLOBAL(0x009AC31B, uint8) = 255; RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; - return; + return 0; } // Read first chunk @@ -158,7 +158,7 @@ void scenario_load(const char *path) RCT2_CALLPROC_EBPSAFE(0x006A9FC0); map_update_tile_pointers(); reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4); - return; + return 1; } fclose(file); @@ -166,6 +166,7 @@ void scenario_load(const char *path) RCT2_GLOBAL(0x009AC31B, uint8) = 255; RCT2_GLOBAL(0x009AC31C, uint16) = STR_FILE_CONTAINS_INVALID_DATA; + return 0; } /** @@ -173,7 +174,15 @@ void scenario_load(const char *path) * rct2: 0x00678282 * scenario (ebx) */ -void scenario_load_and_play(const rct_scenario_basic *scenario) +int scenario_load_and_play(const rct_scenario_basic *scenario) +{ + char path[MAX_PATH]; + + subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), scenario->path); + return scenario_load_and_play_from_path(path); +} + +int scenario_load_and_play_from_path(const char *path) { rct_window *mainWindow; rct_s6_info *s6Info = (rct_s6_info*)0x0141F570; @@ -185,12 +194,9 @@ void scenario_load_and_play(const rct_scenario_basic *scenario) RCT2_CALLPROC_EBPSAFE(0x006CBCC3); - subsitute_path( - RCT2_ADDRESS(0x0141EF68, char), - RCT2_ADDRESS(RCT2_ADDRESS_SCENARIOS_PATH, char), - scenario->path - ); - scenario_load((char*)0x0141EF68); + if (!scenario_load(path)) + return 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; viewport_init_all(); game_create_windows(); diff --git a/src/scenario.h b/src/scenario.h index 6f0fdd33f7..90563c3f31 100644 --- a/src/scenario.h +++ b/src/scenario.h @@ -402,8 +402,9 @@ extern rct_scenario_basic *gScenarioList; int scenario_scores_save(); void scenario_load_list(); int scenario_load_basic(const char *path); -void scenario_load(const char *path); -void scenario_load_and_play(const rct_scenario_basic *scenario); +int scenario_load(const char *path); +int scenario_load_and_play(const rct_scenario_basic *scenario); +int scenario_load_and_play_from_path(const char *path); void scenario_update(); int scenario_rand();