diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 469425bc1e..f79ad746bf 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -170,7 +170,7 @@ static void move_research_item(rct_research_item *beforeItem); static sint32 research_item_is_always_researched(rct_research_item *researchItem) { - return (researchItem->entryIndex & (RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED)) != 0; + return (researchItem->flags & (RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED)) != 0; } /** @@ -194,18 +194,18 @@ static void research_rides_setup(){ Editor::SelectedObjects[OBJECT_TYPE_RIDE][ride->subtype] |= OBJECT_SELECTION_FLAG_SELECTED; } - for (rct_research_item* research = gResearchItems; research->entryIndex != RESEARCHED_ITEMS_END; research++) + for (rct_research_item* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END; research++) { - if (research->entryIndex & RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED) + if (research->flags & RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED) continue; // If not a ride - if ((research->entryIndex & 0xFFFFFF) < 0x10000) + if (research->type != RESEARCH_ENTRY_TYPE_RIDE) continue; - uint8 ride_base_type = research_get_ride_base_type(research->entryIndex); + uint8 ride_base_type = research->baseRideType; - uint8 object_index = research->entryIndex & 0xFF; + uint8 object_index = research->entryIndex; rct_ride_entry* ride_entry = get_ride_entry(object_index); bool master_found = false; @@ -258,7 +258,7 @@ static void research_rides_setup(){ } } - research->entryIndex |= RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED; + research->flags |= RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED; _editorInventionsListDraggedItem = research; move_research_item(gResearchItems); _editorInventionsListDraggedItem = nullptr; @@ -271,25 +271,25 @@ static void research_rides_setup(){ * rct2: 0x0068590C * Sets the critical scenery sets to always researched */ -static void research_scenery_sets_setup(){ - +static void research_scenery_groups_setup() +{ for (size_t i = 0; i < Util::CountOf(RequiredSelectedObjects); i++) { const rct_object_entry * object = &RequiredSelectedObjects[i]; - uint8 entry_type, entry_index; - if (!find_object_in_entry_group(object, &entry_type, &entry_index)) + uint8 entry_type, entryIndex; + if (!find_object_in_entry_group(object, &entry_type, &entryIndex)) continue; if (entry_type != OBJECT_TYPE_SCENERY_GROUP) continue; rct_research_item* research = gResearchItems; - for (; research->entryIndex != RESEARCHED_ITEMS_END; research++){ - - if ((research->entryIndex & 0xFFFFFF) != entry_index) + for (; research->rawValue != RESEARCHED_ITEMS_END; research++) + { + if ((research->rawValue & 0xFFFFFF) != entryIndex) continue; - research->entryIndex |= RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED; + research->flags |= RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED; _editorInventionsListDraggedItem = research; move_research_item(gResearchItems); _editorInventionsListDraggedItem = nullptr; @@ -304,7 +304,7 @@ static void research_scenery_sets_setup(){ static void research_always_researched_setup() { research_rides_setup(); - research_scenery_sets_setup(); + research_scenery_groups_setup(); } /** @@ -317,13 +317,13 @@ static void research_items_shuffle() sint32 i, numNonResearchedItems; // Skip pre-researched items - for (researchItem = gResearchItems; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) {} + for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) {} researchItem++; researchOrderBase = researchItem; // Count non pre-researched items numNonResearchedItems = 0; - for (; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) + for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) numNonResearchedItems++; // Shuffle list @@ -345,19 +345,19 @@ static void research_items_make_all_unresearched() sint32 sorted; do { sorted = 1; - for (researchItem = gResearchItems; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { + for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { if (research_item_is_always_researched(researchItem)) continue; nextResearchItem = researchItem + 1; - if (nextResearchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR || research_item_is_always_researched(nextResearchItem)) { + if (nextResearchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR || research_item_is_always_researched(nextResearchItem)) { // Bubble up always researched item or separator researchItemTemp = *researchItem; *researchItem = *nextResearchItem; *nextResearchItem = researchItemTemp; sorted = 0; - if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR) + if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) break; } } @@ -369,10 +369,10 @@ static void research_items_make_all_researched() rct_research_item *researchItem, researchItemTemp; // Find separator - for (researchItem = gResearchItems; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } + for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } // Move separator below all items - for (; (researchItem + 1)->entryIndex != RESEARCHED_ITEMS_END; researchItem++) { + for (; (researchItem + 1)->rawValue != RESEARCHED_ITEMS_END; researchItem++) { // Swap separator with research item researchItemTemp = *researchItem; *researchItem = *(researchItem + 1); @@ -400,7 +400,7 @@ static void move_research_item(rct_research_item *beforeItem) do { *researchItem = *(researchItem + 1); researchItem++; - } while (researchItem->entryIndex != RESEARCHED_ITEMS_END_2); + } while (researchItem->rawValue != RESEARCHED_ITEMS_END_2); // At end of this researchItem points to the end of the list if (beforeItem > _editorInventionsListDraggedItem) @@ -433,11 +433,11 @@ static rct_research_item *window_editor_inventions_list_get_item_from_scroll_y(s if (scrollIndex != 0) { // Skip pre-researched items - for (; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } + for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } researchItem++; } - for (; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR && researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) { + for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) return researchItem; @@ -458,11 +458,11 @@ static rct_research_item *window_editor_inventions_list_get_item_from_scroll_y_i if (scrollIndex != 0) { // Skip pre-researched items - for (; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } + for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } researchItem++; } - for (; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR && researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) { + for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) return researchItem; @@ -604,7 +604,7 @@ static void window_editor_inventions_list_scrollgetheight(rct_window *w, sint32 *height = 0; // Count / skip pre-researched items - for (researchItem = gResearchItems; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) + for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) *height += SCROLLABLE_ROW_HEIGHT; if (scrollIndex == 1) { @@ -612,7 +612,7 @@ static void window_editor_inventions_list_scrollgetheight(rct_window *w, sint32 // Count non pre-researched items *height = 0; - for (; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) + for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) *height += SCROLLABLE_ROW_HEIGHT; } } @@ -629,7 +629,7 @@ static void window_editor_inventions_list_scrollmousedown(rct_window *w, sint32 if (researchItem == nullptr) return; - if (researchItem->entryIndex < RESEARCHED_ITEMS_END_2 && research_item_is_always_researched(researchItem)) + if (researchItem->rawValue < RESEARCHED_ITEMS_END_2 && research_item_is_always_researched(researchItem)) return; window_invalidate(w); @@ -684,7 +684,7 @@ static void window_editor_inventions_list_cursor(rct_window *w, rct_widgetindex if (researchItem == nullptr) return; - if (researchItem->entryIndex < RESEARCHED_ITEMS_END_2 && research_item_is_always_researched(researchItem)) { + if (researchItem->rawValue < RESEARCHED_ITEMS_END_2 && research_item_is_always_researched(researchItem)) { return; } @@ -747,21 +747,20 @@ static void window_editor_inventions_list_paint(rct_window *w, rct_drawpixelinfo if (researchItem == nullptr) researchItem = w->research_item; // If the research item is null or a list separator. - if (researchItem == nullptr || researchItem->entryIndex < 0) + if (researchItem == nullptr || researchItem->rawValue < 0) return; // Preview image - sint32 objectEntryType = 7; - sint32 eax = researchItem->entryIndex & 0xFFFFFF; - if (eax >= 0x10000) - objectEntryType = 0; + sint32 objectEntryType = OBJECT_TYPE_SCENERY_GROUP; + if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) + objectEntryType = OBJECT_TYPE_RIDE; - void *chunk = object_entry_groups[objectEntryType].chunks[researchItem->entryIndex & 0xFF]; + void * chunk = object_entry_groups[objectEntryType].chunks[researchItem->entryIndex]; if (chunk == nullptr) return; - rct_object_entry * entry = &object_entry_groups[objectEntryType].entries[researchItem->entryIndex & 0xFF].entry; + rct_object_entry * entry = &object_entry_groups[objectEntryType].entries[researchItem->entryIndex].entry; // Draw preview widget = &w->widgets[WIDX_PREVIEW]; @@ -782,7 +781,7 @@ static void window_editor_inventions_list_paint(rct_window *w, rct_drawpixelinfo x = w->x + ((widget->left + widget->right) / 2) + 1; y = w->y + widget->bottom + 3; width = w->width - w->widgets[WIDX_RESEARCH_ORDER_SCROLL].right - 6; - stringId = research_item_get_name(eax); + stringId = research_item_get_name(researchItem); gfx_draw_string_centred_clipped(dpi, STR_WINDOW_COLOUR_2_STRINGID, &stringId, COLOUR_BLACK, x, y, width); y += 15; @@ -812,7 +811,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window *w, rct_drawpix if (scrollIndex == 1) { // Skip pre-researched items - for (; researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } + for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) { } researchItem++; researchItemEndMarker = RESEARCHED_ITEMS_END; } else { @@ -844,14 +843,14 @@ static void window_editor_inventions_list_scrollpaint(rct_window *w, rct_drawpix colour = COLOUR_BRIGHT_GREEN; } - if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR || researchItem->entryIndex == RESEARCHED_ITEMS_END) + if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR || researchItem->rawValue == RESEARCHED_ITEMS_END) continue; if (researchItem == _editorInventionsListDraggedItem) continue; disableItemMovement = research_item_is_always_researched(researchItem); - stringId = research_item_get_name(researchItem->entryIndex & 0xFFFFFF); + stringId = research_item_get_name(researchItem); ptr = buffer; if (!disableItemMovement) { @@ -874,7 +873,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window *w, rct_drawpix left = 1; top = itemY; gfx_draw_string(dpi, buffer, colour, left, top); - }while(researchItem++->entryIndex != researchItemEndMarker); + }while(researchItem++->rawValue != researchItemEndMarker); } #pragma region Drag item @@ -893,7 +892,7 @@ static void window_editor_inventions_list_drag_open(rct_research_item *researchI window_close_by_class(WC_EDITOR_INVENTION_LIST_DRAG); _editorInventionsListDraggedItem = researchItem; - stringId = research_item_get_name(researchItem->entryIndex & 0xFFFFFF); + stringId = research_item_get_name(researchItem); format_string(buffer, 256, stringId, nullptr); stringWidth = gfx_get_string_width(buffer); window_editor_inventions_list_drag_widgets[0].right = stringWidth; @@ -958,7 +957,7 @@ static void window_editor_inventions_list_drag_paint(rct_window *w, rct_drawpixe x = w->x; y = w->y + 2; - stringId = research_item_get_name(_editorInventionsListDraggedItem->entryIndex & 0xFFFFFF); + stringId = research_item_get_name(_editorInventionsListDraggedItem); gfx_draw_string_left(dpi, STR_WINDOW_COLOUR_2_STRINGID, &stringId, COLOUR_BLACK | COLOUR_FLAG_OUTLINE, x, y); } diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index ddf42b8c30..b07d4c0583 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -685,7 +686,7 @@ static void window_new_ride_mouseup(rct_window *w, rct_widgetindex widgetIndex) window_close(w); break; case WIDX_LAST_DEVELOPMENT_BUTTON: - news_item_open_subject(NEWS_ITEM_RESEARCH, (sint32)gResearchLastItemSubject); + news_item_open_subject(NEWS_ITEM_RESEARCH, gResearchLastItemSubject.rawValue); break; case WIDX_RESEARCH_FUNDING_BUTTON: context_open_window_view(WV_FINANCES_RESEARCH); @@ -803,10 +804,12 @@ static void window_new_ride_invalidate(rct_window *w) if (_windowNewRideCurrentTab == WINDOW_NEW_RIDE_PAGE_RESEARCH) { window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY; - uint32 typeId = gResearchLastItemSubject; - if (typeId != 0xFFFFFFFF) { + if (gResearchLastItemSubject.rawValue != RESEARCHED_ITEMS_SEPARATOR) + { + uint8 type = gResearchLastItemSubject.type; window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN; - window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = typeId >= 0x10000 ? SPR_NEW_RIDE : SPR_NEW_SCENERY; + window_new_ride_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = + (type == RESEARCH_ENTRY_TYPE_RIDE) ? SPR_NEW_RIDE : SPR_NEW_SCENERY; } } } diff --git a/src/openrct2-ui/windows/Research.cpp b/src/openrct2-ui/windows/Research.cpp index 0075167396..2808ffa217 100644 --- a/src/openrct2-ui/windows/Research.cpp +++ b/src/openrct2-ui/windows/Research.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -280,7 +281,7 @@ static void window_research_development_mouseup(rct_window *w, rct_widgetindex w window_research_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_LAST_DEVELOPMENT_BUTTON: - news_item_open_subject(NEWS_ITEM_RESEARCH, (sint32)gResearchLastItemSubject); + news_item_open_subject(NEWS_ITEM_RESEARCH, gResearchLastItemSubject.rawValue); break; } } @@ -311,10 +312,11 @@ static void window_research_development_invalidate(rct_window *w) window_research_set_pressed_tab(w); window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY; - uint32 typeId = gResearchLastItemSubject; - if (typeId != 0xFFFFFFFF) { + if (gResearchLastItemSubject.rawValue != RESEARCHED_ITEMS_SEPARATOR) + { + uint8 type = gResearchLastItemSubject.type; window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN; - window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = typeId >= 0x10000 ? SPR_NEW_RIDE : SPR_NEW_SCENERY; + window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = type == RESEARCH_ENTRY_TYPE_RIDE? SPR_NEW_RIDE : SPR_NEW_SCENERY; } } @@ -358,7 +360,7 @@ void window_research_development_page_paint(rct_window *w, rct_drawpixelinfo *dp stringId = ResearchCategoryNames[gResearchNextCategory]; if (gResearchProgressStage != RESEARCH_STAGE_DESIGNING) { - stringId = research_item_get_name(gResearchNextItem); + stringId = research_item_get_name(&gResearchNextItem); } } gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, COLOUR_BLACK); @@ -387,12 +389,11 @@ void window_research_development_page_paint(rct_window *w, rct_drawpixelinfo *dp x = w->x + 10; y = w->y + w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12; - uint32 typeId = gResearchLastItemSubject; rct_string_id lastDevelopmentFormat; - if (typeId != 0xFFFFFFFF) + if (gResearchLastItemSubject.rawValue != RESEARCHED_ITEMS_SEPARATOR) { - stringId = research_item_get_name(typeId); - lastDevelopmentFormat = (typeId >= 0x10000) ? STR_RESEARCH_RIDE_LABEL : STR_RESEARCH_SCENERY_LABEL; + uint8 type = gResearchLastItemSubject.type; + lastDevelopmentFormat = type == RESEARCH_ENTRY_TYPE_RIDE ? STR_RESEARCH_RIDE_LABEL : STR_RESEARCH_SCENERY_LABEL; gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, lastDevelopmentFormat, COLOUR_BLACK); } diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 549e7a962a..28a3835140 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -280,11 +280,19 @@ static void remove_selected_objects_from_research(const rct_object_entry* instal for (auto rideType : rideEntry->ride_type) { - research_remove(entry_index | rideType << 8 | 0x10000); + rct_research_item tmp = {}; + tmp.type = RESEARCH_ENTRY_TYPE_RIDE; + tmp.entryIndex = entry_index; + tmp.baseRideType = rideType; + research_remove(&tmp); } } - else if (entry_type == OBJECT_TYPE_SCENERY_GROUP){ - research_remove(entry_index); + else if (entry_type == OBJECT_TYPE_SCENERY_GROUP) + { + rct_research_item tmp = {}; + tmp.type = RESEARCH_ENTRY_TYPE_SCENERY; + tmp.entryIndex = entry_index; + research_remove(&tmp); } } diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 3f61904ebb..1297b0d30a 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -42,11 +42,11 @@ uint8 gResearchFundingLevel; uint8 gResearchPriorities; uint16 gResearchProgress; uint8 gResearchProgressStage; -uint32 gResearchLastItemSubject; +rct_research_item gResearchLastItemSubject; uint8 gResearchExpectedMonth; uint8 gResearchExpectedDay; uint8 gResearchNextCategory; -uint32 gResearchNextItem; +rct_research_item gResearchNextItem; // 0x01358844[500] rct_research_item gResearchItems[MAX_RESEARCH_ITEMS]; @@ -70,9 +70,9 @@ static void ride_entry_set_invented(sint32 rideEntryIndex); */ void research_reset_items() { - gResearchItems[0].entryIndex = RESEARCHED_ITEMS_SEPARATOR; - gResearchItems[1].entryIndex = RESEARCHED_ITEMS_END; - gResearchItems[2].entryIndex = RESEARCHED_ITEMS_END_2; + gResearchItems[0].rawValue = RESEARCHED_ITEMS_SEPARATOR; + gResearchItems[1].rawValue = RESEARCHED_ITEMS_END; + gResearchItems[2].rawValue = RESEARCHED_ITEMS_END_2; } /** @@ -83,9 +83,9 @@ void research_update_uncompleted_types() { sint32 uncompletedResearchTypes = 0; rct_research_item * researchItem = gResearchItems; - while (researchItem++->entryIndex != RESEARCHED_ITEMS_SEPARATOR); + while (researchItem++->rawValue != RESEARCHED_ITEMS_SEPARATOR); - for (; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) + for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) { uncompletedResearchTypes |= (1 << researchItem->category); } @@ -138,7 +138,7 @@ static void research_next_design() // Skip already researched items firstUnresearchedItem = gResearchItems; - while (firstUnresearchedItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR) + while (firstUnresearchedItem->rawValue != RESEARCHED_ITEMS_SEPARATOR) { firstUnresearchedItem++; } @@ -148,7 +148,7 @@ static void research_next_design() for (;;) { researchItem++; - if (researchItem->entryIndex == RESEARCHED_ITEMS_END) + if (researchItem->rawValue == RESEARCHED_ITEMS_END) { if (!ignoreActiveResearchTypes) { @@ -172,7 +172,7 @@ static void research_next_design() } } - gResearchNextItem = researchItem->entryIndex; + gResearchNextItem = *researchItem; gResearchNextCategory = researchItem->category; gResearchProgress = 0; gResearchProgressStage = RESEARCH_STAGE_DESIGNING; @@ -185,7 +185,7 @@ static void research_next_design() *(researchItem - 1) = tmp; researchItem--; } - while ((researchItem + 1)->entryIndex != RESEARCHED_ITEMS_SEPARATOR); + while ((researchItem + 1)->rawValue != RESEARCHED_ITEMS_SEPARATOR); research_invalidate_related_windows(); } @@ -194,16 +194,16 @@ static void research_next_design() * * rct2: 0x006848D4 */ -void research_finish_item(uint32 entryIndex) +void research_finish_item(rct_research_item * researchItem) { - gResearchLastItemSubject = entryIndex; + gResearchLastItemSubject = *researchItem; research_invalidate_related_windows(); - if (entryIndex >= RESEARCH_ENTRY_RIDE_MASK) + if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { // Ride - uint32 base_ride_type = research_get_ride_base_type(entryIndex); - sint32 rideEntryIndex = entryIndex & 0xFF; + uint32 base_ride_type = researchItem->baseRideType; + sint32 rideEntryIndex = researchItem->entryIndex; rct_ride_entry * rideEntry = get_ride_entry(rideEntryIndex); if (rideEntry != nullptr && base_ride_type != RIDE_TYPE_NULL) @@ -284,7 +284,7 @@ void research_finish_item(uint32 entryIndex) { if (gConfigNotifications.ride_researched) { - news_item_add_to_queue(NEWS_ITEM_RESEARCH, availabilityString, entryIndex); + news_item_add_to_queue(NEWS_ITEM_RESEARCH, availabilityString, researchItem->rawValue); } } @@ -294,7 +294,7 @@ void research_finish_item(uint32 entryIndex) else { // Scenery - rct_scenery_group_entry * sceneryGroupEntry = get_scenery_group_entry(entryIndex & 0xFFFF); + rct_scenery_group_entry * sceneryGroupEntry = get_scenery_group_entry(researchItem->entryIndex); if (sceneryGroupEntry != nullptr) { for (sint32 i = 0; i < sceneryGroupEntry->entry_count; i++) @@ -309,7 +309,7 @@ void research_finish_item(uint32 entryIndex) { if (gConfigNotifications.ride_researched) { - news_item_add_to_queue(NEWS_ITEM_RESEARCH, STR_NEWS_ITEM_RESEARCH_NEW_SCENERY_SET_AVAILABLE, entryIndex); + news_item_add_to_queue(NEWS_ITEM_RESEARCH, STR_NEWS_ITEM_RESEARCH_NEW_SCENERY_SET_AVAILABLE, researchItem->rawValue); } } @@ -361,7 +361,7 @@ void research_update() research_invalidate_related_windows(); break; case RESEARCH_STAGE_COMPLETING_DESIGN: - research_finish_item(gResearchNextItem); + research_finish_item(&gResearchNextItem); gResearchProgress = 0; gResearchProgressStage = RESEARCH_STAGE_INITIAL_RESEARCH; research_calculate_expected_date(); @@ -379,10 +379,10 @@ void research_update() void research_reset_current_item() { rct_research_item * research = gResearchItems; - for (; research->entryIndex != RESEARCHED_ITEMS_END; research++) { } + for (; research->rawValue != RESEARCHED_ITEMS_END; research++) { } research++; - for (; research->entryIndex != RESEARCHED_ITEMS_END_2; research += 2) + for (; research->rawValue != RESEARCHED_ITEMS_END_2; research += 2) { if (scenario_rand() & 1) { @@ -394,20 +394,20 @@ void research_reset_current_item() rct_research_item * inner_research = gResearchItems; do { - if (research->entryIndex == inner_research->entryIndex) + if (research->rawValue == inner_research->rawValue) { edx = inner_research; } - if ((research + 1)->entryIndex == inner_research->entryIndex) + if ((research + 1)->rawValue == inner_research->rawValue) { ebp = inner_research; } } - while ((inner_research++)->entryIndex != RESEARCHED_ITEMS_END); + while ((inner_research++)->rawValue != RESEARCHED_ITEMS_END); assert(edx != nullptr); - edx->entryIndex = research->entryIndex; + edx->rawValue = research->rawValue; assert(ebp != nullptr); - ebp->entryIndex = (research + 1)->entryIndex; + ebp->rawValue = (research + 1)->rawValue; uint8 cat = edx->category; edx->category = ebp->category; @@ -437,14 +437,14 @@ void research_reset_current_item() } - for (research = gResearchItems; research->entryIndex != RESEARCHED_ITEMS_SEPARATOR; research++) + for (research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_SEPARATOR; research++) { - research_finish_item(research->entryIndex); + research_finish_item(research); } - gResearchLastItemSubject = (uint32) -1; - gResearchProgressStage = 0; - gResearchProgress = 0; + gResearchLastItemSubject.rawValue = RESEARCHED_ITEMS_SEPARATOR; + gResearchProgressStage = 0; + gResearchProgress = 0; } /** @@ -456,7 +456,7 @@ void research_remove_non_separate_vehicle_types() rct_research_item * researchItem, * researchItem2; researchItem = gResearchItems; - while ((researchItem + 1)->entryIndex != RESEARCHED_ITEMS_END) + while ((researchItem + 1)->rawValue != RESEARCHED_ITEMS_END) { researchItem++; } @@ -466,12 +466,11 @@ void research_remove_non_separate_vehicle_types() loopBeginning: if ( researchItem != gResearchItems && - researchItem->entryIndex != RESEARCHED_ITEMS_SEPARATOR && - researchItem->entryIndex != RESEARCHED_ITEMS_END && - researchItem->entryIndex >= RESEARCH_ENTRY_RIDE_MASK - ) + researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR && + researchItem->rawValue != RESEARCHED_ITEMS_END && + researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { - rct_ride_entry * rideEntry = get_ride_entry(researchItem->entryIndex & 0xFF); + rct_ride_entry * rideEntry = get_ride_entry(researchItem->entryIndex); if (!(rideEntry->flags & (RIDE_ENTRY_FLAG_SEPARATE_RIDE))) { // Check if ride type already exists further up for a vehicle type that isn't displayed as a ride @@ -479,16 +478,15 @@ void research_remove_non_separate_vehicle_types() do { if ( - researchItem2->entryIndex != RESEARCHED_ITEMS_SEPARATOR && - researchItem2->entryIndex >= RESEARCH_ENTRY_RIDE_MASK + researchItem2->rawValue != RESEARCHED_ITEMS_SEPARATOR && + researchItem2->type == RESEARCH_ENTRY_TYPE_RIDE ) { - rideEntry = get_ride_entry(researchItem2->entryIndex & 0xFF); + rideEntry = get_ride_entry(researchItem2->entryIndex); if (!(rideEntry->flags & (RIDE_ENTRY_FLAG_SEPARATE_RIDE))) { - if (research_get_ride_base_type(researchItem->entryIndex) == - research_get_ride_base_type(researchItem2->entryIndex)) + if (researchItem->baseRideType == researchItem2->baseRideType) { // Remove item researchItem2 = researchItem; @@ -496,7 +494,7 @@ void research_remove_non_separate_vehicle_types() { *researchItem2 = *(researchItem2 + 1); } - while ((researchItem2++)->entryIndex != RESEARCHED_ITEMS_END_2); + while ((researchItem2++)->rawValue != RESEARCHED_ITEMS_END_2); goto loopBeginning; } } @@ -520,23 +518,23 @@ static void research_insert_unresearched(sint32 entryIndex, sint32 category) researchItem = gResearchItems; do { - if (researchItem->entryIndex == RESEARCHED_ITEMS_END) + if (researchItem->rawValue == RESEARCHED_ITEMS_END) { // Insert slot researchItem2 = researchItem; - while (researchItem2->entryIndex != RESEARCHED_ITEMS_END_2) + while (researchItem2->rawValue != RESEARCHED_ITEMS_END_2) { researchItem2++; } memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item)); // Place new item - researchItem->entryIndex = entryIndex; + researchItem->rawValue = entryIndex; researchItem->category = category; break; } } - while (entryIndex != (researchItem++)->entryIndex); + while (entryIndex != (researchItem++)->rawValue); } /** @@ -549,9 +547,9 @@ static void research_insert_researched(sint32 entryIndex, sint32 category) researchItem = gResearchItems; // First check to make sure that entry is not already accounted for - for (; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) + for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) { - if (researchItem->entryIndex == entryIndex) + if (researchItem->rawValue == entryIndex) { return; } @@ -559,41 +557,41 @@ static void research_insert_researched(sint32 entryIndex, sint32 category) researchItem = gResearchItems; do { - if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR) + if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) { // Insert slot researchItem2 = researchItem; - while (researchItem2->entryIndex != RESEARCHED_ITEMS_END_2) + while (researchItem2->rawValue != RESEARCHED_ITEMS_END_2) { researchItem2++; } memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item)); // Place new item - researchItem->entryIndex = entryIndex; + researchItem->rawValue = entryIndex; researchItem->category = category; break; } } - while (entryIndex != (researchItem++)->entryIndex); + while (entryIndex != (researchItem++)->rawValue); } /** * * rct2: 0x006857CF */ -void research_remove(sint32 entryIndex) +void research_remove(rct_research_item * researchItem) { - for (rct_research_item * researchItem = gResearchItems; - researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++) + for (rct_research_item * researchItem2 = gResearchItems; + researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) { - if (researchItem->entryIndex == entryIndex) + if (researchItem2->rawValue == researchItem->rawValue) { do { - *researchItem = *(researchItem + 1); + *researchItem2 = *(researchItem2 + 1); } - while (researchItem++->entryIndex != RESEARCHED_ITEMS_END_2); + while (researchItem2++->rawValue != RESEARCHED_ITEMS_END_2); return; } } @@ -830,14 +828,15 @@ void set_every_ride_entry_not_invented() * * rct2: 0x0068563D */ -rct_string_id research_item_get_name(uint32 researchItem) +rct_string_id research_item_get_name(rct_research_item * researchItem) { - if (researchItem >= RESEARCH_ENTRY_RIDE_MASK) + + if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { - rct_ride_entry * rideEntry = get_ride_entry(researchItem & 0xFF); + rct_ride_entry * rideEntry = get_ride_entry(researchItem->entryIndex); if (rideEntry == nullptr) { - return 0; + return STR_EMPTY; } else if (rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) { @@ -845,17 +844,17 @@ rct_string_id research_item_get_name(uint32 researchItem) } else { - uint8 baseRideType = research_get_ride_base_type(researchItem); + uint8 baseRideType = researchItem->baseRideType; // Makes sure the correct track name is displayed, e.g. Hyper-Twister instead of Steel Twister. return research_get_friendly_base_ride_type_name(baseRideType, rideEntry); } } else { - rct_scenery_group_entry * sceneryEntry = get_scenery_group_entry(researchItem & 0xFF); + rct_scenery_group_entry * sceneryEntry = get_scenery_group_entry(researchItem->entryIndex); if (sceneryEntry == nullptr) { - return 0; + return STR_EMPTY; } else { @@ -864,11 +863,6 @@ rct_string_id research_item_get_name(uint32 researchItem) } } -uint8 research_get_ride_base_type(sint32 researchItem) -{ - return (researchItem >> 8) & 0xFF; -} - /** * This will return the name of the base ride type or ride group, as seen in the research window. */ @@ -892,12 +886,12 @@ rct_string_id research_get_friendly_base_ride_type_name(uint8 trackType, rct_rid */ void research_remove_flags() { - for (rct_research_item * research = gResearchItems; research->entryIndex != RESEARCHED_ITEMS_END_2; research++) + for (rct_research_item * research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END_2; research++) { // Clear the always researched flags. - if (research->entryIndex > RESEARCHED_ITEMS_SEPARATOR) + if (research->rawValue > RESEARCHED_ITEMS_SEPARATOR) { - research->entryIndex &= 0x00FFFFFF; + research->flags = 0; } } } @@ -908,36 +902,34 @@ void research_fix() for (sint32 i = 0; i < MAX_RESEARCH_ITEMS; i++) { rct_research_item * researchItem = &gResearchItems[i]; - if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPARATOR) + if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) continue; - if (researchItem->entryIndex == RESEARCHED_ITEMS_END) + if (researchItem->rawValue == RESEARCHED_ITEMS_END) { if (i == MAX_RESEARCH_ITEMS - 1) { - (--researchItem)->entryIndex = RESEARCHED_ITEMS_END; + (--researchItem)->rawValue = RESEARCHED_ITEMS_END; } - (++researchItem)->entryIndex = RESEARCHED_ITEMS_END_2; + (++researchItem)->rawValue = RESEARCHED_ITEMS_END_2; break; } - if (researchItem->entryIndex == RESEARCHED_ITEMS_END_2) + if (researchItem->rawValue == RESEARCHED_ITEMS_END_2) break; - if (researchItem->entryIndex & RESEARCH_ENTRY_RIDE_MASK) + if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { - uint8 entryIndex = researchItem->entryIndex & 0xFF; - rct_ride_entry * rideEntry = get_ride_entry(entryIndex); + rct_ride_entry * rideEntry = get_ride_entry(researchItem->entryIndex); if (rideEntry == nullptr) { - research_remove(researchItem->entryIndex); + research_remove(researchItem); i--; } } else { - uint8 entryIndex = researchItem->entryIndex; - rct_scenery_group_entry * sceneryGroupEntry = get_scenery_group_entry(entryIndex); + rct_scenery_group_entry * sceneryGroupEntry = get_scenery_group_entry(researchItem->rawValue); if (sceneryGroupEntry == nullptr) { - research_remove(researchItem->entryIndex); + research_remove(researchItem); i--; } } diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 5245a3decd..cdd804add6 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -23,17 +23,35 @@ typedef struct rct_ride_entry rct_ride_entry; #pragma pack(push, 1) -typedef struct rct_research_item { +typedef struct rct_research_item +{ // Bit 16 (0: scenery entry, 1: ride entry) - sint32 entryIndex; + union + { + sint32 rawValue; + struct + { + uint8 entryIndex; + uint8 baseRideType; + uint8 type; // 0: scenery entry, 1: ride entry + uint8 flags; + }; + }; uint8 category; } rct_research_item; assert_struct_size(rct_research_item, 5); #pragma pack(pop) -enum{ - RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED = (1 << 29), - RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED = (1 << 30), +enum +{ + RESEARCH_ENTRY_TYPE_SCENERY = 0, + RESEARCH_ENTRY_TYPE_RIDE = 1, +}; + +enum +{ + RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED = (1 << 5), + RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED = (1 << 6), }; // Everything before this point has been researched @@ -84,11 +102,11 @@ extern uint8 gResearchFundingLevel; extern uint8 gResearchPriorities; extern uint16 gResearchProgress; extern uint8 gResearchProgressStage; -extern uint32 gResearchLastItemSubject; +extern rct_research_item gResearchLastItemSubject; extern uint8 gResearchExpectedMonth; extern uint8 gResearchExpectedDay; extern uint8 gResearchNextCategory; -extern uint32 gResearchNextItem; +extern rct_research_item gResearchNextItem; extern rct_research_item gResearchItems[MAX_RESEARCH_ITEMS]; extern uint8 gResearchUncompletedCategories; @@ -108,9 +126,9 @@ void research_populate_list_researched(); void research_set_funding(sint32 amount); void research_set_priority(sint32 activeCategories); void game_command_set_research_funding(sint32* eax, sint32* ebx, sint32* ecx, sint32* edx, sint32* esi, sint32* edi, sint32* ebp); -void research_finish_item(uint32 entryIndex); +void research_finish_item(rct_research_item * researchItem); void research_insert(sint32 researched, sint32 entryIndex, sint32 category); -void research_remove(sint32 entryIndex); +void research_remove(rct_research_item * researchItem); void research_insert_ride_entry(uint8 entryIndex, bool researched); void research_insert_scenery_group_entry(uint8 entryIndex, bool researched); @@ -123,8 +141,7 @@ bool scenery_is_invented(uint16 sceneryItem); void set_all_scenery_items_invented(); void set_every_ride_entry_invented(); void set_every_ride_entry_not_invented(); -rct_string_id research_item_get_name(uint32 researchItem); -uint8 research_get_ride_base_type(sint32 researchItem); +rct_string_id research_item_get_name(rct_research_item * researchItem); rct_string_id research_get_friendly_base_ride_type_name(uint8 trackType, rct_ride_entry * rideEntry); void research_remove_flags(); void research_fix(); diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index e93c6d2f3a..ab40ec0dae 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -222,7 +222,7 @@ extern "C" { bool object_entry_is_empty(const rct_object_entry *entry); bool object_entry_compare(const rct_object_entry *a, const rct_object_entry *b); sint32 object_calculate_checksum(const rct_object_entry * entry, const void * data, size_t dataLength); - sint32 find_object_in_entry_group(const rct_object_entry* entry, uint8* entry_type, uint8* entry_index); + bool find_object_in_entry_group(const rct_object_entry* entry, uint8* entry_type, uint8* entry_index); void object_create_identifier_name(char* string_buffer, size_t size, const rct_object_entry* object); const rct_object_entry * object_list_find_by_name(const char *name); diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index 8dda72d32b..c15e64f7cd 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -124,25 +124,28 @@ void object_create_identifier_name(char* string_buffer, size_t size, const rct_o * bl = entry_index * ecx = entry_type */ -sint32 find_object_in_entry_group(const rct_object_entry* entry, uint8* entry_type, uint8* entry_index){ +bool find_object_in_entry_group(const rct_object_entry * entry, uint8 * entry_type, uint8 * entry_index) +{ if ((entry->flags & 0xF) >= Util::CountOf(object_entry_groups)) { - return 0; + return false; } *entry_type = entry->flags & 0xF; rct_object_entry_group entry_group = object_entry_groups[*entry_type]; for (*entry_index = 0; - *entry_index < object_entry_group_counts[*entry_type]; - ++(*entry_index), - entry_group.chunks++, - entry_group.entries++){ + *entry_index < object_entry_group_counts[*entry_type]; + ++(*entry_index), entry_group.chunks++, entry_group.entries++) + { + if (*entry_group.chunks == nullptr) + continue; - if (*entry_group.chunks == nullptr) continue; - - if (object_entry_compare((rct_object_entry*)entry_group.entries, entry))break; + if (object_entry_compare((rct_object_entry*)entry_group.entries, entry)) + break; } - if (*entry_index == object_entry_group_counts[*entry_type])return 0; - return 1; + if (*entry_index == object_entry_group_counts[*entry_type]) + return false; + + return true; } void get_type_entry_index(size_t index, uint8 * outObjectType, uint8 * outEntryIndex) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 8162fd6a15..f16d7e0aff 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2049,7 +2049,7 @@ private: // Research history gResearchProgress = _s4.research_progress; // gResearchProgressStage = - gResearchNextItem = _s4.next_research_item; + gResearchNextItem.rawValue = _s4.next_research_item; gResearchNextCategory = _s4.next_research_category; // gResearchExpectedDay = // gResearchExpectedMonth = diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 5a35fc8b4e..66c845115b 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -247,9 +247,9 @@ void S6Exporter::Export() _s6.active_research_types = gResearchPriorities; _s6.research_progress_stage = gResearchProgressStage; - _s6.last_researched_item_subject = gResearchLastItemSubject; + _s6.last_researched_item_subject = gResearchLastItemSubject.rawValue; // pad_01357CF8 - _s6.next_research_item = gResearchNextItem; + _s6.next_research_item = gResearchNextItem.rawValue; _s6.research_progress = gResearchProgress; _s6.next_research_category = gResearchNextCategory; _s6.next_research_expected_day = gResearchExpectedDay; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 136062d6fc..7fdab5cd54 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -263,11 +263,11 @@ public: memcpy(gParkRatingHistory, _s6.park_rating_history, sizeof(_s6.park_rating_history)); memcpy(gGuestsInParkHistory, _s6.guests_in_park_history, sizeof(_s6.guests_in_park_history)); - gResearchPriorities = _s6.active_research_types; - gResearchProgressStage = _s6.research_progress_stage; - gResearchLastItemSubject = _s6.last_researched_item_subject; + gResearchPriorities = _s6.active_research_types; + gResearchProgressStage = _s6.research_progress_stage; + gResearchLastItemSubject.rawValue = _s6.last_researched_item_subject; // pad_01357CF8 - gResearchNextItem = _s6.next_research_item; + gResearchNextItem.rawValue = _s6.next_research_item; gResearchProgress = _s6.research_progress; gResearchNextCategory = _s6.next_research_category; gResearchExpectedDay = _s6.next_research_expected_day; diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 1b8cd6a5b4..6e7cef4faa 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -101,7 +101,7 @@ void park_init() gParkRating = 0; _guestGenerationProbability = 0; gTotalRideValueForMoney = 0; - gResearchLastItemSubject = (uint32)-1; + gResearchLastItemSubject.rawValue = RESEARCHED_ITEMS_SEPARATOR; for (i = 0; i < 20; i++) gMarketingCampaignDaysLeft[i] = 0;