Refactor rct_research_item, refactor access to rct_research_item

This takes away a lot of the bitshift and bit mask trickery previously used.
This commit is contained in:
Michael Steenbeek 2018-01-04 16:43:55 +01:00
parent 59439b778b
commit 7d5de63484
12 changed files with 203 additions and 180 deletions

View File

@ -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);
}

View File

@ -30,6 +30,7 @@
#include <openrct2/interface/Widget.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/management/NewsItem.h>
#include <openrct2/management/Research.h>
#include <openrct2/object/ObjectLimits.h>
#include <openrct2/rct1.h>
#include <openrct2/ride/ride_data.h>
@ -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;
}
}
}

View File

@ -20,6 +20,7 @@
#include <openrct2/localisation/Localisation.h>
#include <openrct2/interface/Widget.h>
#include <openrct2/management/NewsItem.h>
#include <openrct2/management/Research.h>
#include <openrct2/sprites.h>
#include <openrct2/world/scenery.h>
#include <openrct2-ui/interface/Dropdown.h>
@ -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);
}

View File

@ -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);
}
}

View File

@ -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--;
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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)

View File

@ -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 =

View File

@ -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;

View File

@ -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;

View File

@ -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;