From 7c0d3a9077dfaa91e8402ac2d353204151c8602e Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 2 May 2016 01:18:46 +0100 Subject: [PATCH] fix install track --- src/addresses.h | 6 +- src/localisation/string_ids.h | 4 + src/ride/track_design.c | 71 +-------- src/ride/track_design.h | 2 +- src/ride/track_design_index.c | 49 ++---- src/windows/install_track.c | 287 ++++++++++++++-------------------- src/windows/track_list.c | 14 +- 7 files changed, 149 insertions(+), 284 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 9fad01604c..0eb5b424d2 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -248,9 +248,6 @@ #define RCT2_ADDRESS_TRACK_PREVIEW_Y_MAX 0x00F440FF #define RCT2_ADDRESS_TRACK_PREVIEW_Z_MIN 0x00F44101 #define RCT2_ADDRESS_TRACK_PREVIEW_Z_MAX 0x00F44103 -#define RCT2_ADDRESS_TRACK_DESIGN_CACHE 0x00F44105 -#define RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE 0x00F44109 -#define RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE 0x00F44119 #define RCT2_ADDRESS_ABOVE_GROUND_FLAGS 0x00F441D4 #define RCT2_ADDRESS_TRACK_LIST 0x00F441EC @@ -599,6 +596,9 @@ #define RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS 0x00F3EF9E #define RCT2_ADDRESS_TRACK_PREVIEW_ROTATION 0x00F440AE +#define RCT2_ADDRESS_TRACK_DESIGN_CACHE 0x00F44105 +#define RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE 0x00F44109 +#define RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE 0x00F44119 #define RCT2_ADDRESS_TRACK_DESIGN_COST 0x00F4411D #define RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE 0x00F44152 diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 33fd66c8ea..3bc7095379 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -1903,6 +1903,10 @@ enum { STR_INSTALL_NEW_TRACK_DESIGN = 3376, STR_INSTALL_NEW_TRACK_DESIGN_TIP = 3377, + STR_UNABLE_TO_INSTALL_THIS_TRACK_DESIGN = 3380, + STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN = 3383, + STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME = 3384, + STR_SAVE_TRACK_SCENERY_UNABLE_TO_SELECT_ADDITIONAL_ITEM_OF_SCENERY = 3389, STR_SAVE_TRACK_SCENERY_TOO_MANY_ITEMS_SELECTED = 3390, diff --git a/src/ride/track_design.c b/src/ride/track_design.c index 7858971ea1..d152c2a8b3 100644 --- a/src/ride/track_design.c +++ b/src/ride/track_design.c @@ -79,7 +79,7 @@ rct_track_td6 *track_design_open(const utf8 *path) static rct_track_td6 *track_design_open_from_buffer(uint8 *src, size_t srcLength) { - rct_track_td6 *td6 = calloc(sizeof(rct_track_td6), 1); + rct_track_td6 *td6 = calloc(1, sizeof(rct_track_td6)); uint8 *readPtr = src; // Clear top of track_design as this is not loaded from the td4 files @@ -1392,75 +1392,6 @@ bool sub_6D2189(rct_track_td6 *td6, money32 *cost, uint8 *rideId) } } -/** -* -* rct2: 0x006D399D -*/ -rct_track_design *temp_track_get_info(char* path, uint8** preview) -{ - rct_track_design *trackDesign; - uint8 *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8); - int i; - - trackDesign = NULL; - - // Check if track design has already been loaded - for (i = 0; i < 4; i++) { - if (RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i] == 0) { - trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i]; - break; - } - } - - if (trackDesign == NULL) { - // Load track design - i = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32)++; - if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) >= 4) - RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) = 0; - - RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i] = 0; - - rct_track_td6* loaded_track = NULL; - - log_verbose("Loading track: %s", path); - - // if (!(loaded_track = load_track_design(path))) { - // if (preview != NULL) *preview = NULL; - // log_error("Failed to load track: %s", path); - // return NULL; - // } - - trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i]; - - object_unload_all(); - if (loaded_track->type == RIDE_TYPE_NULL){ - if (preview != NULL) *preview = NULL; - log_error("Failed to load track (ride type null): %s", path); - return NULL; - } - - if (!object_load_chunk(0, &loaded_track->vehicle_object, NULL)){ - if (preview != NULL) *preview = NULL; - log_error("Failed to load track (vehicle load fail): %s", path); - return NULL; - } - - // Copy the track design apart from the preview image - memcpy(&trackDesign->track_td6, loaded_track, sizeof(rct_track_td6)); - // Load in a new preview image, calculate cost variable, calculate var_06 - draw_track_preview(&trackDesign->track_td6, (uint8**)trackDesign->preview); - - trackDesign->track_td6.cost = gTrackDesignCost; - trackDesign->track_td6.track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7; - } - - // Set preview to correct preview image based on rotation - if (preview != NULL) - *preview = trackDesign->preview[_currentTrackPieceDirection]; - - return trackDesign; -} - money32 place_track_design(sint16 x, sint16 y, sint16 z, uint8 flags, uint8 *outRideIndex) { *outRideIndex = 255; diff --git a/src/ride/track_design.h b/src/ride/track_design.h index b056e96121..ba6600ea5a 100644 --- a/src/ride/track_design.h +++ b/src/ride/track_design.h @@ -168,7 +168,6 @@ rct_track_td6 *track_design_open(const utf8 *path); void track_design_dispose(rct_track_td6 *td6); int sub_6D01B3(rct_track_td6 *td6, uint8 bl, uint8 rideIndex, int x, int y, int z); -int install_track(char* source_path, char* dest_name); void track_design_index_create(); size_t track_design_index_get_count_for_ride(uint8 rideType, const char *entry); @@ -176,6 +175,7 @@ size_t track_design_index_get_for_ride(track_design_file_ref **tdRefs, uint8 rid utf8 *track_design_get_name_from_path(const utf8 *path); bool track_design_index_rename(const utf8 *path, const utf8 *newName); bool track_design_index_delete(const utf8 *path); +bool track_design_index_install(const utf8 *srcPath, const utf8 *destPath); void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void game_command_place_maze_design(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); diff --git a/src/ride/track_design_index.c b/src/ride/track_design_index.c index 9df576d494..fe3ae927ff 100644 --- a/src/ride/track_design_index.c +++ b/src/ride/track_design_index.c @@ -203,43 +203,22 @@ bool track_design_index_delete(const utf8 *path) } /** -* -* rct2: 0x006D40B2 -* returns 0 for copy fail, 1 for success, 2 for file exists. -*/ -int install_track(char* source_path, char* dest_name){ + * + * rct2: 0x006D40B2 + */ +bool track_design_index_install(const utf8 *srcPath, const utf8 *destPath) +{ + if (!platform_file_copy(srcPath, destPath, false)) { + return false; + } - // Make a copy of the track name (no extension) - char track_name[MAX_PATH] = { 0 }; - char* dest = track_name; - char* dest_name_pointer = dest_name; - while (*dest_name_pointer != '.') *dest++ = *dest_name_pointer++; + track_design_index_create(); - // Check if .TD4 file exists under that name - char* temp_extension_pointer = dest; - strcat(track_name, ".TD4"); - - char dest_path[MAX_PATH]; - substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name); - - if (platform_file_exists(dest_path)) - return 2; - - // Allow a concat onto the track_name but before extension - *temp_extension_pointer = '\0'; - - // Check if .TD6 file exists under that name - strcat(track_name, ".TD6"); - - substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name); - - if (platform_file_exists(dest_path)) - return 2; - - // Set path for actual copy - substitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), dest_name); - - return platform_file_copy(source_path, dest_path, false); + rct_window *trackListWindow = window_find_by_class(WC_TRACK_DESIGN_LIST); + if (trackListWindow != NULL) { + trackListWindow->track_list.reload_track_designs = true; + } + return true; } static bool track_design_index_read_header(SDL_RWops *file, uint32 *tdidxCount) diff --git a/src/windows/install_track.c b/src/windows/install_track.c index 6259b3acf9..08fd9d7e5e 100644 --- a/src/windows/install_track.c +++ b/src/windows/install_track.c @@ -25,6 +25,7 @@ #include "../ride/track.h" #include "../ride/track_design.h" #include "../sprites.h" +#include "../util/util.h" #include "error.h" enum { @@ -87,127 +88,71 @@ static rct_window_event_list window_install_track_events = { NULL }; -ride_list_item _window_install_track_item; +static rct_track_td6 *_trackDesign; +static utf8 *_trackPath; +static utf8 *_trackName; +static uint8 *_trackDesignPreviewPixels; -char track_dest_name[MAX_PATH]; -char track_path[MAX_PATH]; +static void window_install_track_update_preview(); +static void window_install_track_design(rct_window *w); /** * * rct2: 0x006D386D */ -void window_install_track_open(const char* path) +void window_install_track_open(const utf8 *path) { - rct_window *w; - int x, y; - void *mem; + _trackDesign = track_design_open(path); + if (_trackDesign == NULL) { + window_error_open(3010, STR_NONE); + return; + } + + object_unload_all(); + if (_trackDesign->type == RIDE_TYPE_NULL){ + log_error("Failed to load track (ride type null): %s", path); + return; + } + if (!object_load_chunk(0, &_trackDesign->vehicle_object, NULL)){ + log_error("Failed to load track (vehicle load fail): %s", path); + return; + } window_close_by_class(WC_EDITOR_OBJECT_SELECTION); - window_close_construction_windows(); - ride_list_item item = { - .type = 0xFF, - .entry_index = 0 - }; - _window_install_track_item = item; - mem = malloc(1285292); - if (mem == NULL) - return; - - RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*) = mem; gTrackDesignSceneryToggle = false; _currentTrackPieceDirection = 2; - // reset_track_list_cache(); - x = gScreenWidth / 2 - 201; - y = max(28, gScreenHeight / 2 - 200); + int x = gScreenWidth / 2 - 201; + int y = max(28, gScreenHeight / 2 - 200); - w = window_create(x, y, 402, 400, &window_install_track_events, WC_INSTALL_TRACK, 0); + rct_window *w = window_create(x, y, 402, 400, &window_install_track_events, WC_INSTALL_TRACK, 0); w->widgets = window_install_track_widgets; w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_INSTALL) | (1 << WIDX_CANCEL); window_init_scroll_widgets(w); w->track_list.var_484 = 0; window_push_others_right(w); - strncpy(track_path, path, MAX_PATH); - track_path[MAX_PATH - 1] = '\0'; - - char* track_name_pointer = strrchr(track_path, platform_get_path_separator()); - track_name_pointer++; - - strncpy(track_dest_name, track_name_pointer, MAX_PATH); - track_dest_name[MAX_PATH - 1] = '\0'; + _trackPath = _strdup(path); + _trackName = track_design_get_name_from_path(path); + _trackDesignPreviewPixels = calloc(4, TRACK_PREVIEW_IMAGE_SIZE); + window_install_track_update_preview(); window_invalidate(w); } -/** -* -* rct2: 0x006CFB82 -*/ -static void window_install_track_select(rct_window *w, int index) -{ - utf8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, utf8); - // rct_track_design *trackDesign; - - w->track_list.var_480 = index; - - audio_play_sound_panned(SOUND_CLICK_1, w->x + (w->width / 2), 0, 0, 0); - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && index == 0) { - window_close(w); - ride_construct_new(_window_install_track_item); - return; - } - - if (RCT2_GLOBAL(0x00F44153, uint8) != 0) { - gTrackDesignSceneryToggle = true; - } - - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) - index--; - - trackDesignItem = trackDesignList + (index * 128); - RCT2_GLOBAL(0x00F4403C, utf8*) = trackDesignItem; - - // window_track_list_format_name( - // (char*)0x009BC313, - // trackDesignItem, - // gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER ? - // 0 : - // FORMAT_WHITE, - // 1); - - char track_path[MAX_PATH] = { 0 }; - substitute_path(track_path, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignItem); - - if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { - window_track_manage_open(NULL); - return; - } - - // if (!load_track_design(track_path)) { - // w->track_list.var_480 = 0xFFFF; - // window_invalidate(w); - // return; - // } - - // trackDesign = track_get_info(index, NULL); - // if (trackDesign == NULL) return; - // if (trackDesign->track_td6.track_flags & 4) - // window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1); - - window_close(w); - window_track_place_open(NULL); -} - /** * * rct2: 0x006D41DC */ static void window_install_track_close(rct_window *w) { - free(RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*)); + SafeFree(_trackPath); + SafeFree(_trackName); + SafeFree(_trackDesignPreviewPixels); + track_design_dispose(_trackDesign); + _trackDesign = NULL; } /** @@ -216,8 +161,6 @@ static void window_install_track_close(rct_window *w) */ static void window_install_track_mouseup(rct_window *w, int widgetIndex) { - int result; - switch (widgetIndex) { case WIDX_CLOSE: case WIDX_CANCEL: @@ -230,23 +173,11 @@ static void window_install_track_mouseup(rct_window *w, int widgetIndex) break; case WIDX_TOGGLE_SCENERY: gTrackDesignSceneryToggle = !gTrackDesignSceneryToggle; - // reset_track_list_cache(); + window_install_track_update_preview(); window_invalidate(w); break; case WIDX_INSTALL: - result = install_track(track_path, track_dest_name); - - if (result == 1) - window_close(w); - else if(result == 0){ - window_error_open(3380, 3382); - window_close(w); - } - else{ - // Copy the track name into the string buffer. - // window_track_list_format_name(RCT2_ADDRESS(0x009BC677, char), track_dest_name, 0, 0); - window_text_input_open(w, WIDX_INSTALL, 3383, 3384, 3165, 0, 255); - } + window_install_track_design(w); break; } } @@ -280,36 +211,18 @@ static void window_install_track_invalidate(rct_window *w) */ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) { - rct_widget *widget; - rct_track_design *trackDesign = NULL; - uint8 *image, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8); - uint16 holes, speed, drops, dropHeight, inversions; - fixed32_2dp rating; - int x, y, colour, gForces, airTime; - rct_g1_element tmpElement, *substituteElement; - window_draw_widgets(w, dpi); - // if (w->track_list.var_482 == 0xFFFF) - // return; - // Track preview - widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW]; - x = w->x + widget->left + 1; - y = w->y + widget->top + 1; - colour = ColourMapA[w->colours[0]].darkest; + rct_widget *widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW]; + int x = w->x + widget->left + 1; + int y = w->y + widget->top + 1; + int colour = ColourMapA[w->colours[0]].darkest; gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour); - //call 6d3993 (load track) - trackDesign = temp_track_get_info(track_path, &image); - if (trackDesign == NULL) - return; - - rct_track_td6* track_td6 = &trackDesign->track_td6; - - substituteElement = &g1Elements[0]; - tmpElement = *substituteElement; - substituteElement->offset = image; + rct_g1_element *substituteElement = &g1Elements[0]; + rct_g1_element tmpElement = *substituteElement; + substituteElement->offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); substituteElement->width = 370; substituteElement->height = 217; substituteElement->x_offset = 0; @@ -324,7 +237,8 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) RCT2_GLOBAL(0x00F44153, uint8) = 0; // Warnings - if (track_td6->track_flags & 1) { + rct_track_td6 *td6 = _trackDesign; + if (td6->track_flags & 1) { RCT2_GLOBAL(0x00F44153, uint8) = 1; if (!gTrackDesignSceneryToggle) { // Scenery not available @@ -334,8 +248,7 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) } // Track design name - // window_track_list_format_name((char*)0x009BC677, (char*)0x009E3504, FORMAT_WINDOW_COLOUR_1, 1); - gfx_draw_string_centred_clipped(dpi, 3165, NULL, 0, x, y, 368); + gfx_draw_string_centred_clipped(dpi, STR_TRACK_PREVIEW_NAME_FORMAT, &_trackName, 0, x, y, 368); // Information x = w->x + widget->left + 1; @@ -343,85 +256,85 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) // 0x006D3CF1 -- 0x006d3d71 missing // Stats - rating = track_td6->excitement * 10; + fixed32_2dp rating = td6->excitement * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_EXCITEMENT_RATING, &rating, 0, x, y); y += 10; - rating = track_td6->intensity * 10; + rating = td6->intensity * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_INTENSITY_RATING, &rating, 0, x, y); y += 10; - rating = track_td6->nausea * 10; + rating = td6->nausea * 10; gfx_draw_string_left(dpi, STR_TRACK_LIST_NAUSEA_RATING, &rating, 0, x, y); y += 14; - if (track_td6->type != RIDE_TYPE_MAZE) { - if (track_td6->type == RIDE_TYPE_MINI_GOLF) { + if (td6->type != RIDE_TYPE_MAZE) { + if (td6->type == RIDE_TYPE_MINI_GOLF) { // Holes - holes = track_td6->holes & 0x1F; + uint16 holes = td6->holes & 0x1F; gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y); y += 10; } else { // Maximum speed - speed = ((track_td6->max_speed << 16) * 9) >> 18; + uint16 speed = ((td6->max_speed << 16) * 9) >> 18; gfx_draw_string_left(dpi, STR_MAX_SPEED, &speed, 0, x, y); y += 10; // Average speed - speed = ((track_td6->average_speed << 16) * 9) >> 18; + speed = ((td6->average_speed << 16) * 9) >> 18; gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &speed, 0, x, y); y += 10; } // Ride length RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint16) = 1345; - RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = track_td6->ride_length; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = td6->ride_length; gfx_draw_string_left_clipped(dpi, STR_TRACK_LIST_RIDE_LENGTH, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x, y, 214); y += 10; } - if (ride_type_has_flag(track_td6->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) { + if (ride_type_has_flag(td6->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) { // Maximum positive vertical Gs - gForces = track_td6->max_positive_vertical_g * 32; + int gForces = td6->max_positive_vertical_g * 32; gfx_draw_string_left(dpi, STR_MAX_POSITIVE_VERTICAL_G, &gForces, 0, x, y); y += 10; // Maximum negative verical Gs - gForces = track_td6->max_negative_vertical_g * 32; + gForces = td6->max_negative_vertical_g * 32; gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y); y += 10; // Maximum lateral Gs - gForces = track_td6->max_lateral_g * 32; + gForces = td6->max_lateral_g * 32; gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y); y += 10; // If .TD6 - if (track_td6->version_and_colour_scheme / 4 >= 2) { - if (track_td6->total_air_time != 0) { + if (td6->version_and_colour_scheme / 4 >= 2) { + if (td6->total_air_time != 0) { // Total air time - airTime = track_td6->total_air_time * 25; + int airTime = td6->total_air_time * 25; gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &airTime, 0, x, y); y += 10; } } } - if (ride_type_has_flag(track_td6->type, RIDE_TYPE_FLAG_HAS_DROPS)) { + if (ride_type_has_flag(td6->type, RIDE_TYPE_FLAG_HAS_DROPS)) { // Drops - drops = track_td6->drops & 0x3F; + uint16 drops = td6->drops & 0x3F; gfx_draw_string_left(dpi, STR_DROPS, &drops, 0, x, y); y += 10; // Drop height is multiplied by 0.75 - dropHeight = (track_td6->highest_drop_height + (track_td6->highest_drop_height / 2)) / 2; + uint16 dropHeight = (td6->highest_drop_height + (td6->highest_drop_height / 2)) / 2; gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &drops, 0, x, y); y += 10; } - if (track_td6->type != RIDE_TYPE_MINI_GOLF) { - inversions = track_td6->inversions & 0x1F; + if (td6->type != RIDE_TYPE_MINI_GOLF) { + uint16 inversions = td6->inversions & 0x1F; if (inversions != 0) { // Inversions gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, 0, x, y); @@ -430,16 +343,16 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) } y += 4; - if (track_td6->space_required_x != 0xFF) { + if (td6->space_required_x != 0xFF) { // Space required - RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint16) = track_td6->space_required_x; - RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = track_td6->space_required_y; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint16) = td6->space_required_x; + RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = td6->space_required_y; gfx_draw_string_left(dpi, STR_TRACK_LIST_SPACE_REQUIRED, (void*)RCT2_ADDRESS_COMMON_FORMAT_ARGS, 0, x, y); y += 10; } - if (track_td6->cost != 0) { - gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &track_td6->cost, 0, x, y); + if (td6->cost != 0) { + gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &td6->cost, 0, x, y); y += 14; } } @@ -450,17 +363,53 @@ static void window_install_track_paint(rct_window *w, rct_drawpixelinfo *dpi) */ static void window_install_track_text_input(rct_window *w, int widgetIndex, char *text) { - if (text == NULL) { - window_close(w); + if (widgetIndex != WIDX_INSTALL || str_is_null_or_empty(text)) { return; } - if (widgetIndex == WIDX_INSTALL) { - char* extension_pointer = track_dest_name; - while (*extension_pointer++ != '.'); - --extension_pointer; - strcat(text, extension_pointer); - strcpy(track_dest_name, text); - window_event_mouse_up_call(w, WIDX_INSTALL); + free(_trackName); + _trackName = _strdup(text); + + window_event_mouse_up_call(w, WIDX_INSTALL); +} + +static void window_install_track_update_preview() +{ + draw_track_preview(_trackDesign, (uint8**)_trackDesignPreviewPixels); + _trackDesign->cost = gTrackDesignCost; + _trackDesign->track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7; +} + +static void window_install_track_design(rct_window *w) +{ + utf8 destPath[MAX_PATH]; + + platform_get_user_directory(destPath, "tracks"); + if (!platform_ensure_directory_exists(destPath)) { + log_error("Unable to create directory '%s'", destPath); + window_error_open(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE); + return; + } + + strcat(destPath, _trackName); + strcat(destPath, ".td6"); + + if (platform_file_exists(destPath)) { + log_info("%s already exists, prompting user for a different track design name", destPath); + window_error_open(STR_UNABLE_TO_INSTALL_THIS_TRACK_DESIGN, STR_NONE); + window_text_input_raw_open( + w, + WIDX_INSTALL, + STR_SELECT_NEW_NAME_FOR_TRACK_DESIGN, + STR_AN_EXISTING_TRACK_DESIGN_ALREADY_HAS_THIS_NAME, + _trackName, + 255 + ); + } else { + if (track_design_index_install(_trackPath, destPath)) { + window_close(w); + } else { + window_error_open(STR_CANT_SAVE_TRACK_DESIGN, STR_NONE); + } } } diff --git a/src/windows/track_list.c b/src/windows/track_list.c index c2818e6bc2..ef6628fc4a 100644 --- a/src/windows/track_list.c +++ b/src/windows/track_list.c @@ -99,7 +99,7 @@ static track_design_file_ref *_trackDesigns = NULL; static size_t _trackDesignsCount = 0; static uint16 _loadedTrackDesignIndex; static rct_track_td6 *_loadedTrackDesign; -static uint8 _loadedTrackDesignPreview[4][TRACK_PREVIEW_IMAGE_SIZE]; +static uint8 *_trackDesignPreviewPixels; static void track_list_load_designs(ride_list_item item); static bool track_list_load_design_for_preview(utf8 *path); @@ -145,6 +145,8 @@ void window_track_list_open(ride_list_item item) gTrackDesignSceneryToggle = false; window_push_others_right(w); _currentTrackPieceDirection = 2; + + _trackDesignPreviewPixels = calloc(4, TRACK_PREVIEW_IMAGE_SIZE); } /** @@ -153,8 +155,10 @@ void window_track_list_open(ride_list_item item) */ static void window_track_list_close(rct_window *w) { - free(_loadedTrackDesign); + // Dispose track design and preview + track_design_dispose(_loadedTrackDesign); _loadedTrackDesign = NULL; + SafeFree(_trackDesignPreviewPixels); // Dispose track list for (size_t i = 0; i < _trackDesignsCount; i++) { @@ -398,11 +402,9 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi) return; } - uint8 *image = _loadedTrackDesignPreview[_currentTrackPieceDirection]; - rct_g1_element *substituteElement = &g1Elements[0]; rct_g1_element tmpElement = *substituteElement; - substituteElement->offset = image; + substituteElement->offset = _trackDesignPreviewPixels + (_currentTrackPieceDirection * TRACK_PREVIEW_IMAGE_SIZE); substituteElement->width = 370; substituteElement->height = 217; substituteElement->x_offset = 0; @@ -619,7 +621,7 @@ static bool track_list_load_design_for_preview(utf8 *path) _loadedTrackDesign = track_design_open(path); if (_loadedTrackDesign != NULL) { // Load in a new preview image, calculate cost variable, calculate var_06 - draw_track_preview(_loadedTrackDesign, (uint8**)_loadedTrackDesignPreview); + draw_track_preview(_loadedTrackDesign, (uint8**)_trackDesignPreviewPixels); _loadedTrackDesign->cost = gTrackDesignCost; _loadedTrackDesign->track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7;