From d905dde070c62802b5817f758a0abfe2de2dd6ce Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 11 Feb 2018 17:56:12 +0000 Subject: [PATCH] Simplify selected object flags --- .../windows/EditorInventionsList.cpp | 27 ++++--- .../windows/EditorObjectSelection.cpp | 8 +- src/openrct2/Editor.cpp | 60 ++++++++------- src/openrct2/Editor.h | 6 +- src/openrct2/EditorObjectSelectionSession.cpp | 73 ++++++++----------- src/openrct2/EditorObjectSelectionSession.h | 5 +- src/openrct2/object/Object.h | 1 + 7 files changed, 93 insertions(+), 87 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 40809bee96..3e02c3b520 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -175,18 +175,23 @@ static void move_research_item(rct_research_item *beforeItem); */ static void research_rides_setup(){ // Reset all objects to not required - for (uint8 object_type = OBJECT_TYPE_RIDE; object_type < OBJECT_TYPE_COUNT; object_type++){ - uint8* in_use = Editor::SelectedObjects[object_type]; - for (uint8 num_objects = object_entry_group_counts[object_type]; num_objects != 0; num_objects--){ - *in_use++ = OBJECT_SELECTION_NOT_SELECTED_OR_REQUIRED; + for (uint8 objectType = OBJECT_TYPE_RIDE; objectType < OBJECT_TYPE_COUNT; objectType++) + { + auto maxObjects = object_entry_group_counts[objectType]; + for (sint32 i = 0; i < maxObjects; i++) + { + Editor::ClearSelectedObject(objectType, i, OBJECT_SELECTION_FLAG_ALL); } } // Set research required for rides in use - for (uint16 rideIndex = 0; rideIndex < 255; rideIndex++){ - Ride * ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL)continue; - Editor::SelectedObjects[OBJECT_TYPE_RIDE][ride->subtype] |= OBJECT_SELECTION_FLAG_SELECTED; + for (uint16 rideIndex = 0; rideIndex < MAX_RIDES; rideIndex++) + { + auto ride = get_ride(rideIndex); + if (ride->type != RIDE_TYPE_NULL) + { + Editor::SetSelectedObject(OBJECT_TYPE_RIDE, ride->subtype, OBJECT_SELECTION_FLAG_SELECTED); + } } for (rct_research_item* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END; research++) @@ -216,7 +221,8 @@ static void research_rides_setup(){ continue; // If master ride not in use - if (!(Editor::SelectedObjects[OBJECT_TYPE_RIDE][rideType] & OBJECT_SELECTION_FLAG_SELECTED)) + auto flags = Editor::GetSelectedObjectFlags(OBJECT_TYPE_RIDE, rideType); + if (!(flags & OBJECT_SELECTION_FLAG_SELECTED)) continue; for (uint8 j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) @@ -237,7 +243,8 @@ static void research_rides_setup(){ if (!master_found){ // If not in use - if (!(Editor::SelectedObjects[OBJECT_TYPE_RIDE][object_index] & OBJECT_SELECTION_FLAG_SELECTED)) { + auto flags = Editor::GetSelectedObjectFlags(OBJECT_TYPE_RIDE, object_index); + if (!(flags & OBJECT_SELECTION_FLAG_SELECTED)) { continue; } diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 66034628cb..c2469778ab 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -385,8 +385,7 @@ rct_window * window_editor_object_selection_open() if (window != nullptr) return window; - if (!sub_6AB211()) - return nullptr; + sub_6AB211(); reset_selected_object_count_and_size(); window = window_create_centred( @@ -1419,7 +1418,7 @@ static bool filter_chunks(const ObjectRepositoryItem * item) static void filter_update_counts() { if (!_FILTER_ALL || strlen(_filter_string) > 0) { - uint8 *selectionFlags = _objectSelectionFlags; + const auto &selectionFlags = _objectSelectionFlags; for (sint32 i = 0; i < 11; i++) { _filter_object_counts[i] = 0; } @@ -1431,12 +1430,11 @@ static void filter_update_counts() if (filter_source(item) && filter_string(item) && filter_chunks(item) && - filter_selected(*selectionFlags) + filter_selected(selectionFlags[i]) ) { uint8 objectType = item->ObjectEntry.flags & 0xF; _filter_object_counts[objectType]++; } - selectionFlags++; } } } diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index ddc9875cf3..88a5f2d6be 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -14,6 +14,8 @@ *****************************************************************************/ #pragma endregion +#include +#include #include "Context.h" #include "Editor.h" #include "EditorObjectSelectionSession.h" @@ -38,32 +40,7 @@ namespace Editor { - static uint8 _editorSelectedRides[MAX_RIDE_OBJECTS]; - static uint8 _editorSelectedSmallScenery[MAX_SMALL_SCENERY_OBJECTS]; - static uint8 _editorSelectedLargeScenery[MAX_LARGE_SCENERY_OBJECTS]; - static uint8 _editorSelectedWalls[MAX_WALL_SCENERY_OBJECTS]; - static uint8 _editorSelectedBanners[MAX_BANNER_OBJECTS]; - static uint8 _editorSelectedFootpaths[MAX_PATH_OBJECTS]; - static uint8 _editorSelectedFootpathAdditions[MAX_PATH_ADDITION_OBJECTS]; - static uint8 _editorSelectedSceneryGroups[MAX_SCENERY_GROUP_OBJECTS]; - static uint8 _editorSelectedParkEntrances[MAX_PARK_ENTRANCE_OBJECTS]; - static uint8 _editorSelectedWaters[MAX_WATER_OBJECTS]; - static uint8 _editorSelectedStexs[MAX_SCENARIO_TEXT_OBJECTS]; - - uint8 * SelectedObjects[OBJECT_TYPE_COUNT] = - { - _editorSelectedRides, - _editorSelectedSmallScenery, - _editorSelectedLargeScenery, - _editorSelectedWalls, - _editorSelectedBanners, - _editorSelectedFootpaths, - _editorSelectedFootpathAdditions, - _editorSelectedSceneryGroups, - _editorSelectedParkEntrances, - _editorSelectedWaters, - _editorSelectedStexs, - }; + static std::array, OBJECT_TYPE_COUNT> _editorSelectedObjectFlags; static void ConvertSaveToScenarioCallback(sint32 result, const utf8 * path); static void SetAllLandOwned(); @@ -806,6 +783,37 @@ namespace Editor window_invalidate_by_class(WC_EDITOR_SCENARIO_OPTIONS); *ebx = 0; } + + uint8 GetSelectedObjectFlags(sint32 objectType, size_t index) + { + uint8 result = 0; + auto &list = _editorSelectedObjectFlags[objectType]; + if (list.size() > index) + { + result = list[index]; + } + return result; + } + + void ClearSelectedObject(sint32 objectType, size_t index, uint32 flags) + { + auto &list = _editorSelectedObjectFlags[objectType]; + if (list.size() <= index) + { + list.resize(index + 1); + } + list[index] &= ~flags; + } + + void SetSelectedObject(sint32 objectType, size_t index, uint32 flags) + { + auto &list = _editorSelectedObjectFlags[objectType]; + if (list.size() <= index) + { + list.resize(index + 1); + } + list[index] |= flags; + } } void editor_open_windows_for_current_step() diff --git a/src/openrct2/Editor.h b/src/openrct2/Editor.h index 8cefe57662..1972c010d8 100644 --- a/src/openrct2/Editor.h +++ b/src/openrct2/Editor.h @@ -25,8 +25,6 @@ namespace Editor { - extern uint8 * SelectedObjects[OBJECT_TYPE_COUNT]; - void Load(); void ConvertSaveToScenario(); void LoadTrackDesigner(); @@ -38,6 +36,10 @@ namespace Editor void OpenWindowsForCurrentStep(); void GameCommandEditScenarioOptions(sint32*, sint32*, sint32*, sint32*, sint32*, sint32*, sint32*); + + uint8 GetSelectedObjectFlags(sint32 objectType, size_t index); + void ClearSelectedObject(sint32 objectType, size_t index, uint32 flags); + void SetSelectedObject(sint32 objectType, size_t index, uint32 flags); } typedef enum diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 7dbdfbd532..83fa314449 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -14,6 +14,7 @@ *****************************************************************************/ #pragma endregion +#include #include "Context.h" #include "core/Util.hpp" #include "Editor.h" @@ -30,7 +31,7 @@ #include "world/LargeScenery.h" bool _maxObjectsWasHit; -uint8 * _objectSelectionFlags = nullptr; +std::vector _objectSelectionFlags; sint32 _numSelectedObjectsForType[OBJECT_TYPE_COUNT]; static sint32 _numAvailableObjectsForType[OBJECT_TYPE_COUNT]; @@ -107,16 +108,14 @@ static void setup_track_designer_objects() */ void setup_in_use_selection_flags() { - for (uint8 object_type = 0; object_type < OBJECT_TYPE_COUNT; object_type++){ - for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){ - Editor::SelectedObjects[object_type][i] = OBJECT_SELECTION_NOT_SELECTED_OR_REQUIRED; - } - } - - for (uint8 object_type = 0; object_type < OBJECT_TYPE_COUNT; object_type++){ - for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){ - if (object_entry_groups[object_type].chunks[i] != nullptr) { - Editor::SelectedObjects[object_type][i] |= OBJECT_SELECTION_FLAG_2; + for (uint8 objectType = 0; objectType < OBJECT_TYPE_COUNT; objectType++) + { + for (sint32 i = 0; i < object_entry_group_counts[objectType]; i++) + { + Editor::ClearSelectedObject(objectType, i, OBJECT_SELECTION_FLAG_ALL); + if (object_entry_groups[objectType].chunks[i] != nullptr) + { + Editor::SetSelectedObject(objectType, i, OBJECT_SELECTION_FLAG_2); } } } @@ -136,17 +135,17 @@ void setup_in_use_selection_flags() type = iter.element->properties.path.type; type >>= 4; assert(type < object_entry_group_counts[OBJECT_TYPE_PATHS]); - Editor::SelectedObjects[OBJECT_TYPE_PATHS][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_PATHS, type, OBJECT_SELECTION_FLAG_SELECTED); if (footpath_element_has_path_scenery(iter.element)) { uint8 path_additions = footpath_element_get_path_scenery_index(iter.element); - Editor::SelectedObjects[OBJECT_TYPE_PATH_BITS][path_additions] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_PATH_BITS, path_additions, OBJECT_SELECTION_FLAG_SELECTED); } break; case TILE_ELEMENT_TYPE_SMALL_SCENERY: type = iter.element->properties.scenery.type; assert(type < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]); - Editor::SelectedObjects[OBJECT_TYPE_SMALL_SCENERY][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_SMALL_SCENERY, type, OBJECT_SELECTION_FLAG_SELECTED); break; case TILE_ELEMENT_TYPE_ENTRANCE: if (iter.element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) @@ -155,27 +154,27 @@ void setup_in_use_selection_flags() if (iter.element->properties.entrance.index != 0) break; - Editor::SelectedObjects[OBJECT_TYPE_PARK_ENTRANCE][0] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_PARK_ENTRANCE, 0, OBJECT_SELECTION_FLAG_SELECTED); type = iter.element->properties.entrance.path_type; assert(type < object_entry_group_counts[OBJECT_TYPE_PATHS]); - Editor::SelectedObjects[OBJECT_TYPE_PATHS][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_PATHS, type, OBJECT_SELECTION_FLAG_SELECTED); break; case TILE_ELEMENT_TYPE_WALL: type = iter.element->properties.wall.type; assert(type < object_entry_group_counts[OBJECT_TYPE_WALLS]); - Editor::SelectedObjects[OBJECT_TYPE_WALLS][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_WALLS, type, OBJECT_SELECTION_FLAG_SELECTED); break; case TILE_ELEMENT_TYPE_LARGE_SCENERY: type = scenery_large_get_type(iter.element); assert(type < object_entry_group_counts[OBJECT_TYPE_LARGE_SCENERY]); - Editor::SelectedObjects[OBJECT_TYPE_LARGE_SCENERY][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_LARGE_SCENERY, type, OBJECT_SELECTION_FLAG_SELECTED); break; case TILE_ELEMENT_TYPE_BANNER: banner = &gBanners[iter.element->properties.banner.index]; type = banner->type; assert(type < object_entry_group_counts[OBJECT_TYPE_BANNERS]); - Editor::SelectedObjects[OBJECT_TYPE_BANNERS][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_BANNERS, type, OBJECT_SELECTION_FLAG_SELECTED); break; } } while (tile_element_iterator_next(&iter)); @@ -184,7 +183,7 @@ void setup_in_use_selection_flags() Ride* ride = get_ride(ride_index); if (ride->type != RIDE_TYPE_NULL) { uint8 type = ride->subtype; - Editor::SelectedObjects[OBJECT_TYPE_RIDE][type] |= OBJECT_SELECTION_FLAG_SELECTED; + Editor::SetSelectedObject(OBJECT_TYPE_RIDE, type, OBJECT_SELECTION_FLAG_SELECTED); } } @@ -197,12 +196,15 @@ void setup_in_use_selection_flags() uint8 entryType, entryIndex; if (find_object_in_entry_group(&item->ObjectEntry, &entryType, &entryIndex)) { - if (Editor::SelectedObjects[entryType][entryIndex] & OBJECT_SELECTION_FLAG_SELECTED) { + auto flags = Editor::GetSelectedObjectFlags(entryType, entryIndex); + if (flags & OBJECT_SELECTION_FLAG_SELECTED) + { *selectionFlags |= OBJECT_SELECTION_FLAG_IN_USE | - OBJECT_SELECTION_FLAG_SELECTED; + OBJECT_SELECTION_FLAG_SELECTED; } - if (Editor::SelectedObjects[entryType][entryIndex] & OBJECT_SELECTION_FLAG_2) { + if (flags & OBJECT_SELECTION_FLAG_2) + { *selectionFlags |= OBJECT_SELECTION_FLAG_SELECTED; } } @@ -213,14 +215,10 @@ void setup_in_use_selection_flags() * * rct2: 0x006AB211 */ -bool sub_6AB211() +void sub_6AB211() { sint32 numObjects = (sint32)object_repository_get_items_count(); - _objectSelectionFlags = (uint8*)calloc(numObjects, sizeof(uint8)); - if (_objectSelectionFlags == nullptr){ - log_error("Failed to allocate memory for object flag list."); - return false; - } + _objectSelectionFlags = std::vector(numObjects); for (uint8 objectType = 0; objectType < 11; objectType++) { _numSelectedObjectsForType[objectType] = 0; @@ -254,7 +252,6 @@ bool sub_6AB211() } reset_selected_object_count_and_size(); - return true; } /** @@ -263,7 +260,8 @@ bool sub_6AB211() */ void editor_object_flags_free() { - SafeFree(_objectSelectionFlags); + _objectSelectionFlags.clear(); + _objectSelectionFlags.shrink_to_fit(); } /** @@ -492,12 +490,7 @@ bool editor_check_object_group_at_least_one_selected(sint32 checkObjectType) sint32 editor_remove_unused_objects() { - bool createSelectionFlags = (_objectSelectionFlags == nullptr); - if (createSelectionFlags && !sub_6AB211()) - { - return 0; - } - + sub_6AB211(); setup_in_use_selection_flags(); sint32 numObjects = (sint32)object_repository_get_items_count(); @@ -522,11 +515,7 @@ sint32 editor_remove_unused_objects() } } unload_unselected_objects(); - - if (createSelectionFlags) - { - editor_object_flags_free(); - } + editor_object_flags_free(); auto intent = Intent(INTENT_ACTION_REFRESH_SCENERY); context_broadcast_intent(&intent); diff --git a/src/openrct2/EditorObjectSelectionSession.h b/src/openrct2/EditorObjectSelectionSession.h index 8eb526007f..349169a783 100644 --- a/src/openrct2/EditorObjectSelectionSession.h +++ b/src/openrct2/EditorObjectSelectionSession.h @@ -16,17 +16,18 @@ #pragma once +#include #include "common.h" #include "object/Object.h" extern bool _maxObjectsWasHit; -extern uint8 * _objectSelectionFlags; +extern std::vector _objectSelectionFlags; extern sint32 _numSelectedObjectsForType[OBJECT_TYPE_COUNT]; bool editor_check_object_group_at_least_one_selected(sint32 objectType); void editor_object_flags_free(); void unload_unselected_objects(); -bool sub_6AB211(); +void sub_6AB211(); void reset_selected_object_count_and_size(); sint32 window_editor_object_selection_select_object(uint8 bh, sint32 flags, const rct_object_entry *entry); diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index cbec22fa75..1faa12af8d 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -48,6 +48,7 @@ typedef enum OBJECT_SELECTION_FLAG_6 = (1 << 5), OBJECT_SELECTION_FLAG_7 = (1 << 6), OBJECT_SELECTION_FLAG_8 = (1 << 7), + OBJECT_SELECTION_FLAG_ALL = 0xFF, } OBJECT_SELECTION_FLAGS; #define OBJECT_SELECTION_NOT_SELECTED_OR_REQUIRED 0