From 8935503b862c5242b340a18dcfec5e669b9b98a2 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 14 Jun 2015 12:24:01 +0100 Subject: [PATCH 1/9] Implemented select object in object selection window. --- src/windows/editor_object_selection.c | 259 +++++++++++++++++++++++--- 1 file changed, 238 insertions(+), 21 deletions(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 6697ec28cc..96ff407e62 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -202,7 +202,7 @@ static void* window_editor_object_selection_events[] = { static void window_editor_object_set_page(rct_window *w, int page); static void window_editor_object_selection_set_pressed_tab(rct_window *w); static void window_editor_object_selection_select_default_objects(); -static int window_editor_object_selection_select_object(int flags, rct_object_entry *entry); +static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry); static int get_object_from_object_selection(uint8 object_type, int y, uint8 *object_selection_flags, rct_object_entry **installed_entry); static void window_editor_object_selection_manage_tracks(); static void editor_load_selected_objects(); @@ -530,7 +530,7 @@ static void window_editor_object_selection_scroll_mousedown() if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { - if (!window_editor_object_selection_select_object(1, installed_entry)) + if (!window_editor_object_selection_select_object(0, 1, installed_entry)) return; // Close any other open windows such as options/colour schemes to prevent a crash. @@ -548,7 +548,7 @@ static void window_editor_object_selection_scroll_mousedown() ebx = 7; RCT2_GLOBAL(0xF43411, uint8) = 0; - if (!window_editor_object_selection_select_object(ebx, installed_entry)) { + if (!window_editor_object_selection_select_object(0, ebx, installed_entry)) { rct_string_id error_title = ebx & 1 ? STR_UNABLE_TO_SELECT_THIS_OBJECT : STR_UNABLE_TO_DE_SELECT_THIS_OBJECT; @@ -983,24 +983,25 @@ static void window_editor_object_selection_scrollpaint() // Draw text char *buffer = (char*)0x0141ED68; - *buffer = colour; - strcpy(buffer + 1, object_get_name(entry)); - if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { - while (*buffer != 0 && *buffer != 9) - buffer++; +*buffer = colour; +strcpy(buffer + 1, object_get_name(entry)); +if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { + while (*buffer != 0 && *buffer != 9) + buffer++; - *buffer = 0; - } + *buffer = 0; +} - if (*itemFlags & 0x20) { - colour = w->colours[1] & 0x7F; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1; - } else { - colour = 0; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224; - } - x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15; - gfx_draw_string(dpi, (char*)0x0141ED68, colour, x, y); +if (*itemFlags & 0x20) { + colour = w->colours[1] & 0x7F; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1; +} +else { + colour = 0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224; +} +x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15; +gfx_draw_string(dpi, (char*)0x0141ED68, colour, x, y); } y += 12; } @@ -1043,15 +1044,231 @@ static void window_editor_object_selection_select_default_objects() return; for (i = 0; i < countof(DefaultSelectedObjects); i++) - window_editor_object_selection_select_object(7, &DefaultSelectedObjects[i]); + window_editor_object_selection_select_object(0, 7, &DefaultSelectedObjects[i]); } /** * * rct2: 0x006AB54F */ -static int window_editor_object_selection_select_object(int flags, rct_object_entry *entry) +static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry) { + uint8* selection_flags; + if (bh == 0){ + // Unsure what this does?? + uint16 total_objects = 0; + for (uint8 i = 0; i < 11; ++i){ + total_objects += RCT2_ADDRESS(0x00F433E1, uint16)[i]; + } + + selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + for (; total_objects != 0; total_objects--, selection_flags++){ + uint8 select_flag = *selection_flags & 0xFD; + if (select_flag & 1){ + select_flag |= (1 << 1); + } + } + } + + selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + // There was previously a check to make sure the object list had an item + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + rct_object_entry* test = object_list_find(entry); + uint8 not_found = 1; + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + if (object_entry_compare(entry, installedObject)){ + not_found = 0; + break; + } + + installedObject = object_get_next(installedObject); + selection_flags++; + } + if (not_found){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3169; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + if (!(flags & 1)){ + if (!(*selection_flags & (1 << 0))) + { + if (bh == 0){ + RCT2_CALLPROC_EBPSAFE(0x006AB923); + } + return 1; + } else if (*selection_flags & (1 << 2)){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3173; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + else if (*selection_flags & (1 << 3)){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3174; + if (bh != 0){ + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + else if (*selection_flags & (1 << 4)){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3175; + if (bh != 0){ + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + uint32 size_of_chunk = *((uint32*)pos); + // Skip size of chunk + pos += 4; + + // Skip + pos += *pos * 16 + 1; + + uint8 no_theme_objects = *pos++; + + if (no_theme_objects != 0 && flags&(1 << 2)){ + rct_object_entry* theme_object = (rct_object_entry*)pos; + for (; no_theme_objects > 0; no_theme_objects--){ + window_editor_object_selection_select_object(++bh, flags, theme_object); + theme_object++; + } + } + + RCT2_GLOBAL(0x00F4340D, uint32) -= size_of_chunk; + uint8 object_type = installedObject->flags & 0xF; + RCT2_ADDRESS(0x00F433F7, uint16)[object_type]--; + *selection_flags &= ~(1 << 0); + if (bh == 0){ + RCT2_CALLPROC_EBPSAFE(0x006AB923); + } + return 1; + } + else{ + if (bh == 0){ + if (flags & (1 << 3)){ + *selection_flags |= (1 << 4); + } + } + if (*selection_flags&(1 << 0)){ + if (bh == 0){ + RCT2_CALLPROC_EBPSAFE(0x006AB923); + } + return 1; + } + + uint8 object_type = installedObject->flags & 0xF; + uint16 no_objects = object_entry_group_counts[object_type]; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER){ + no_objects = 4; + } + + if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3171; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + uint32 size_of_chunk = *((uint32*)pos); + // Skip size of chunk + pos += 4; + + uint8 num_unks = *pos++; + rct_object_entry* unks = (rct_object_entry*)pos; + for (; num_unks != 0; num_unks--){ + if (!window_editor_object_selection_select_object(++bh, flags, unks)){ + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + unks++; + } + pos = (uint8*)unks; + + uint8 num_theme_objects = *pos++; + rct_object_entry* theme_object = (rct_object_entry*)pos; + for (; num_theme_objects != 0; num_theme_objects--){ + if (flags & (1 << 2)){ + if (!window_editor_object_selection_select_object(++bh, flags, theme_object)){ + RCT2_GLOBAL(0x00F43411, uint8) |= 1; + } + } + theme_object++; + } + + if (bh != 0 && !(flags&(1 << 1))){ + RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)0x009BC95A, (int)installedObject); + RCT2_GLOBAL(0x141E9AC, uint16) = 3172; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + if (RCT2_GLOBAL(0x00F4340D, uint32) + size_of_chunk > 0x40000){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3170; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]){ + RCT2_GLOBAL(0x141E9AC, uint16) = 3171; + if (bh != 0){ + // Bunch of code that looks like it does nothing removed. + RCT2_CALLPROC_EBPSAFE(0x006AA770); + } + return 0; + } + + RCT2_GLOBAL(0x00F4340D, uint32) = size_of_chunk; + RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; + + *selection_flags |= (1 << 0); + if (bh == 0){ + RCT2_CALLPROC_EBPSAFE(0x006AB923); + } + return 1; + } return (RCT2_CALLPROC_X(0x006AB54F, 0, flags, 0, 0, 0, 0, (int)entry) & 0x100) == 0; } From 7a5887f67a0c31071e29288a31132328d0729a53 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 15 Jun 2015 20:17:40 +0100 Subject: [PATCH 2/9] Fix size bug. Implemented reset_required_object_flags and reset_selected_object_count_and_size. --- src/windows/editor_object_selection.c | 157 +++++++++++++++++++++++--- 1 file changed, 142 insertions(+), 15 deletions(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 96ff407e62..ebd90546d3 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -166,6 +166,8 @@ static void window_editor_object_selection_paint(); static void window_editor_object_selection_scrollpaint(); static void window_editor_object_selection_textinput(); +void reset_selected_object_count_and_size(); + static void* window_editor_object_selection_events[] = { window_editor_object_selection_close, (void*)window_editor_object_selection_mouseup, @@ -265,7 +267,7 @@ void window_editor_object_selection_open() return; RCT2_CALLPROC_EBPSAFE(0x006AB211); - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); // Not really where its called, but easy way to change default objects for now if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) @@ -1047,6 +1049,131 @@ static void window_editor_object_selection_select_default_objects() window_editor_object_selection_select_object(0, 7, &DefaultSelectedObjects[i]); } +/* rct2: 0x006AA770 */ +void reset_selected_object_count_and_size(){ + for (uint8 object_type = 0; object_type < 11; object_type++){ + RCT2_ADDRESS(0x00F443F7, uint16)[object_type] = 0; + } + + uint32 total_object_size = 0; + + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + uint8 object_type = installedObject->flags & 0xF; + + if (*selection_flags & (1 << 0)){ + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + uint32 size_of_chunk = *((uint32*)pos); + RCT2_ADDRESS(0x00F443F7, uint16)[object_type]++; + total_object_size += size_of_chunk; + } + selection_flags++; + installedObject = object_get_next(installedObject); + } + + RCT2_GLOBAL(0x00F4340D, uint32) = total_object_size; +} + +/* rct2: 0x006AB863 */ +void set_required_object_flags(rct_object_entry* required_object){ + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + if (object_entry_compare(required_object, installedObject)){ + *selection_flags |= (1 << 3); + + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + // Skip size of chunk + pos += 4; + + // Skip + uint8 no_unk_objects = *pos++; + + rct_object_entry* unk_object = (rct_object_entry*)pos; + for (; no_unk_objects > 0; no_unk_objects--){ + set_required_object_flags(unk_object); + unk_object++; + } + return; + } + + selection_flags++; + installedObject = object_get_next(installedObject); + } +} + +/* rct2: 0x006AB923 */ +void reset_required_object_flags(){ + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + *selection_flags &= ~(1 << 3); + selection_flags++; + } + + selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + if (*selection_flags&(1 << 0)){ + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + // Skip size of chunk + pos += 4; + + // Skip + uint8 no_unk_objects = *pos++; + + rct_object_entry* unk_object = (rct_object_entry*)pos; + for (; no_unk_objects > 0; no_unk_objects--){ + set_required_object_flags(unk_object); + unk_object++; + } + + } + + selection_flags++; + installedObject = object_get_next(installedObject); + } +} + /** * * rct2: 0x006AB54F @@ -1088,7 +1215,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x141E9AC, uint16) = 3169; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1097,28 +1224,28 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct if (!(*selection_flags & (1 << 0))) { if (bh == 0){ - RCT2_CALLPROC_EBPSAFE(0x006AB923); + reset_required_object_flags(); } return 1; } else if (*selection_flags & (1 << 2)){ RCT2_GLOBAL(0x141E9AC, uint16) = 3173; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } else if (*selection_flags & (1 << 3)){ RCT2_GLOBAL(0x141E9AC, uint16) = 3174; if (bh != 0){ - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } else if (*selection_flags & (1 << 4)){ RCT2_GLOBAL(0x141E9AC, uint16) = 3175; if (bh != 0){ - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1158,7 +1285,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_ADDRESS(0x00F433F7, uint16)[object_type]--; *selection_flags &= ~(1 << 0); if (bh == 0){ - RCT2_CALLPROC_EBPSAFE(0x006AB923); + reset_required_object_flags(); } return 1; } @@ -1170,7 +1297,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } if (*selection_flags&(1 << 0)){ if (bh == 0){ - RCT2_CALLPROC_EBPSAFE(0x006AB923); + reset_required_object_flags(); } return 1; } @@ -1185,7 +1312,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x141E9AC, uint16) = 3171; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1213,7 +1340,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct if (!window_editor_object_selection_select_object(++bh, flags, unks)){ if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1237,7 +1364,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x141E9AC, uint16) = 3172; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1246,7 +1373,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x141E9AC, uint16) = 3170; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } @@ -1255,17 +1382,17 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x141E9AC, uint16) = 3171; if (bh != 0){ // Bunch of code that looks like it does nothing removed. - RCT2_CALLPROC_EBPSAFE(0x006AA770); + reset_selected_object_count_and_size(); } return 0; } - RCT2_GLOBAL(0x00F4340D, uint32) = size_of_chunk; + RCT2_GLOBAL(0x00F4340D, uint32) += size_of_chunk; RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; *selection_flags |= (1 << 0); if (bh == 0){ - RCT2_CALLPROC_EBPSAFE(0x006AB923); + reset_required_object_flags(); } return 1; } From f7bbfa80a8c70829fa8c95a647087ab4564f7309 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 15 Jun 2015 20:52:04 +0100 Subject: [PATCH 3/9] Start refactoring --- src/object.c | 2 +- src/object.h | 11 +++ src/windows/editor_object_selection.c | 124 +++++++++++++------------- 3 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/object.c b/src/object.c index 0f83bab287..7e6609ec78 100644 --- a/src/object.c +++ b/src/object.c @@ -1619,7 +1619,7 @@ rct_object_entry *object_get_next(rct_object_entry *entry) // Skip size of chunk pos += 4; - // Skip + // Skip required objects pos += *pos * 16 + 1; // Skip theme objects diff --git a/src/object.h b/src/object.h index cfe41692d6..9cc6e71969 100644 --- a/src/object.h +++ b/src/object.h @@ -38,6 +38,17 @@ typedef enum{ OBJECT_TYPE_SCENARIO_TEXT }OBJECT_TYPE; +typedef enum{ + OBJECT_SELECTION_FLAG_SELECTED = (1 << 0), + OBJECT_SELECTION_FLAG_2 = (1 << 1), + OBJECT_SELECTION_FLAG_IN_USE = (1 << 2), + OBJECT_SELECTION_FLAG_REQUIRED = (1 << 3), + OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED = (1 << 4), + OBJECT_SELECTION_FLAG_6 = (1 << 5), + OBJECT_SELECTION_FLAG_7 = (1 << 6), + OBJECT_SELECTION_FLAG_8 = (1 << 7), +}OBJECT_SELECTION_FLAGS; + /** * Object entry structure. * size: 0x10 diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index ebd90546d3..99071a02da 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -523,7 +523,7 @@ static void window_editor_object_selection_scroll_mousedown() uint8 object_selection_flags; rct_object_entry* installed_entry; int selected_object = get_object_from_object_selection((w->selected_tab & 0xFF), y, &object_selection_flags, &installed_entry); - if (selected_object == -1 || (object_selection_flags & 0x20)) + if (selected_object == -1 || (object_selection_flags & OBJECT_SELECTION_FLAG_6)) return; window_invalidate(w); @@ -546,7 +546,7 @@ static void window_editor_object_selection_scroll_mousedown() int ebx = 6; // If already selected - if (!(object_selection_flags & 1)) + if (!(object_selection_flags & OBJECT_SELECTION_FLAG_SELECTED)) ebx = 7; RCT2_GLOBAL(0xF43411, uint8) = 0; @@ -582,7 +582,7 @@ static void window_editor_object_selection_scroll_mouseover() selectedObject = get_object_from_object_selection( w->selected_tab & 0xFF, y, &objectSelectionFlags, &installedEntry ); - if (objectSelectionFlags & 0x20) + if (objectSelectionFlags & OBJECT_SELECTION_FLAG_6) selectedObject = -1; if (selectedObject == w->selected_list_item) @@ -953,13 +953,13 @@ static void window_editor_object_selection_scrollpaint() numObjects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, sint32); entry = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); - itemFlags = RCT2_GLOBAL(0x009ADAEC, uint8*); + itemFlags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); y = 0; for (i = 0; i < numObjects; i++) { filter = get_object_filter(i); type = entry->flags & 0x0F; source = (entry->flags & 0xF0) >> 4; - if (type == w->selected_tab && !(*itemFlags & 0x20) && filter_source(entry) && filter_string(entry) && filter_chunks(entry, filter)) { + if (type == w->selected_tab && !(*itemFlags & OBJECT_SELECTION_FLAG_6) && filter_source(entry) && filter_string(entry) && filter_chunks(entry, filter)) { if (y + 12 >= dpi->y && y <= dpi->y + dpi->height) { // Draw checkbox if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && !(*itemFlags & 0x20)) @@ -967,17 +967,17 @@ static void window_editor_object_selection_scrollpaint() // Highlight background colour = 142; - if (entry == (rct_object_entry*)w->var_494 && !(*itemFlags & 0x20)) { + if (entry == (rct_object_entry*)w->var_494 && !(*itemFlags & OBJECT_SELECTION_FLAG_6)) { gfx_fill_rect(dpi, 0, y, w->width, y + 11, 0x2000031); colour = 14; } // Draw checkmark - if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && (*itemFlags & 1)) { + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && (*itemFlags & OBJECT_SELECTION_FLAG_SELECTED)) { x = 2; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = colour == 14 ? -2 : -1; colour2 = w->colours[1] & 0x7F; - if (*itemFlags & 0x1C) + if (*itemFlags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_REQUIRED | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED)) colour2 |= 0x40; gfx_draw_string(dpi, (char*)0x009DED72, colour2, x, y); @@ -985,25 +985,25 @@ static void window_editor_object_selection_scrollpaint() // Draw text char *buffer = (char*)0x0141ED68; -*buffer = colour; -strcpy(buffer + 1, object_get_name(entry)); -if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { - while (*buffer != 0 && *buffer != 9) - buffer++; + *buffer = colour; + strcpy(buffer + 1, object_get_name(entry)); + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) { + while (*buffer != 0 && *buffer != 9) + buffer++; - *buffer = 0; -} + *buffer = 0; + } -if (*itemFlags & 0x20) { - colour = w->colours[1] & 0x7F; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1; -} -else { - colour = 0; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224; -} -x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15; -gfx_draw_string(dpi, (char*)0x0141ED68, colour, x, y); + if (*itemFlags & OBJECT_SELECTION_FLAG_6) { + colour = w->colours[1] & 0x7F; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1; + } + else { + colour = 0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = 224; + } + x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15; + gfx_draw_string(dpi, (char*)0x0141ED68, colour, x, y); } y += 12; } @@ -1063,7 +1063,7 @@ void reset_selected_object_count_and_size(){ for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ uint8 object_type = installedObject->flags & 0xF; - if (*selection_flags & (1 << 0)){ + if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){ uint8* pos = (uint8*)installedObject; // Skip sizeof(rct_object_entry) pos += 16; @@ -1095,7 +1095,7 @@ void set_required_object_flags(rct_object_entry* required_object){ for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ if (object_entry_compare(required_object, installedObject)){ - *selection_flags |= (1 << 3); + *selection_flags |= OBJECT_SELECTION_FLAG_REQUIRED; uint8* pos = (uint8*)installedObject; // Skip sizeof(rct_object_entry) @@ -1113,13 +1113,12 @@ void set_required_object_flags(rct_object_entry* required_object){ // Skip size of chunk pos += 4; - // Skip - uint8 no_unk_objects = *pos++; + uint8 no_required_objects = *pos++; - rct_object_entry* unk_object = (rct_object_entry*)pos; - for (; no_unk_objects > 0; no_unk_objects--){ - set_required_object_flags(unk_object); - unk_object++; + required_object = (rct_object_entry*)pos; + for (; no_required_objects > 0; no_required_objects--){ + set_required_object_flags(required_object); + required_object++; } return; } @@ -1133,7 +1132,7 @@ void set_required_object_flags(rct_object_entry* required_object){ void reset_required_object_flags(){ uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ - *selection_flags &= ~(1 << 3); + *selection_flags &= ~OBJECT_SELECTION_FLAG_REQUIRED; selection_flags++; } @@ -1141,7 +1140,7 @@ void reset_required_object_flags(){ rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ - if (*selection_flags&(1 << 0)){ + if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){ uint8* pos = (uint8*)installedObject; // Skip sizeof(rct_object_entry) pos += 16; @@ -1158,13 +1157,12 @@ void reset_required_object_flags(){ // Skip size of chunk pos += 4; - // Skip - uint8 no_unk_objects = *pos++; + uint8 no_required_objects = *pos++; - rct_object_entry* unk_object = (rct_object_entry*)pos; - for (; no_unk_objects > 0; no_unk_objects--){ - set_required_object_flags(unk_object); - unk_object++; + rct_object_entry* required_object = (rct_object_entry*)pos; + for (; no_required_objects > 0; no_required_objects--){ + set_required_object_flags(required_object); + required_object++; } } @@ -1190,9 +1188,9 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); for (; total_objects != 0; total_objects--, selection_flags++){ - uint8 select_flag = *selection_flags & 0xFD; - if (select_flag & 1){ - select_flag |= (1 << 1); + uint8 select_flag = *selection_flags & ~OBJECT_SELECTION_FLAG_2; + if (select_flag & OBJECT_SELECTION_FLAG_SELECTED){ + select_flag |= OBJECT_SELECTION_FLAG_2; } } } @@ -1200,7 +1198,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); // There was previously a check to make sure the object list had an item rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); - rct_object_entry* test = object_list_find(entry); + uint8 not_found = 1; for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ if (object_entry_compare(entry, installedObject)){ @@ -1221,13 +1219,14 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } if (!(flags & 1)){ - if (!(*selection_flags & (1 << 0))) + if (!(*selection_flags & OBJECT_SELECTION_FLAG_SELECTED)) { if (bh == 0){ reset_required_object_flags(); } return 1; - } else if (*selection_flags & (1 << 2)){ + } + else if (*selection_flags & OBJECT_SELECTION_FLAG_IN_USE){ RCT2_GLOBAL(0x141E9AC, uint16) = 3173; if (bh != 0){ // Bunch of code that looks like it does nothing removed. @@ -1235,14 +1234,14 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } return 0; } - else if (*selection_flags & (1 << 3)){ + else if (*selection_flags & OBJECT_SELECTION_FLAG_REQUIRED){ RCT2_GLOBAL(0x141E9AC, uint16) = 3174; if (bh != 0){ reset_selected_object_count_and_size(); } return 0; } - else if (*selection_flags & (1 << 4)){ + else if (*selection_flags & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED){ RCT2_GLOBAL(0x141E9AC, uint16) = 3175; if (bh != 0){ reset_selected_object_count_and_size(); @@ -1267,7 +1266,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct // Skip size of chunk pos += 4; - // Skip + // Skip required objects pos += *pos * 16 + 1; uint8 no_theme_objects = *pos++; @@ -1283,7 +1282,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x00F4340D, uint32) -= size_of_chunk; uint8 object_type = installedObject->flags & 0xF; RCT2_ADDRESS(0x00F433F7, uint16)[object_type]--; - *selection_flags &= ~(1 << 0); + *selection_flags &= ~OBJECT_SELECTION_FLAG_SELECTED; if (bh == 0){ reset_required_object_flags(); } @@ -1292,10 +1291,10 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct else{ if (bh == 0){ if (flags & (1 << 3)){ - *selection_flags |= (1 << 4); + *selection_flags |= OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED; } } - if (*selection_flags&(1 << 0)){ + if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){ if (bh == 0){ reset_required_object_flags(); } @@ -1334,19 +1333,19 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct // Skip size of chunk pos += 4; - uint8 num_unks = *pos++; - rct_object_entry* unks = (rct_object_entry*)pos; - for (; num_unks != 0; num_unks--){ - if (!window_editor_object_selection_select_object(++bh, flags, unks)){ + uint8 num_required_objects = *pos++; + rct_object_entry* required_objects = (rct_object_entry*)pos; + for (; num_required_objects != 0; num_required_objects--){ + if (!window_editor_object_selection_select_object(++bh, flags, required_objects)){ if (bh != 0){ // Bunch of code that looks like it does nothing removed. reset_selected_object_count_and_size(); } return 0; } - unks++; + required_objects++; } - pos = (uint8*)unks; + pos = (uint8*)required_objects; uint8 num_theme_objects = *pos++; rct_object_entry* theme_object = (rct_object_entry*)pos; @@ -1390,13 +1389,12 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct RCT2_GLOBAL(0x00F4340D, uint32) += size_of_chunk; RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; - *selection_flags |= (1 << 0); + *selection_flags |= OBJECT_SELECTION_FLAG_SELECTED; if (bh == 0){ reset_required_object_flags(); } return 1; } - return (RCT2_CALLPROC_X(0x006AB54F, 0, flags, 0, 0, 0, 0, (int)entry) & 0x100) == 0; } /** @@ -1418,7 +1416,7 @@ static int get_object_from_object_selection(uint8 object_type, int y, uint8 *obj filter = get_object_filter(RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) - i); source = ((*installed_entry)->flags & 0xF0) >> 4; if (((*installed_entry)->flags & 0xF) == object_type && filter_source(*installed_entry) && filter_string(*installed_entry) && filter_chunks(*installed_entry, filter)){ - if (!(*selection_flags & 0x20)){ + if (!(*selection_flags & OBJECT_SELECTION_FLAG_6)){ y -= 12; *object_selection_flags = *selection_flags; if (y < 0)return object_count; @@ -1484,7 +1482,7 @@ static void editor_load_selected_objects() return; for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i != 0; i--, selection_flags++) { - if (*selection_flags & 1) { + if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED) { uint8 entry_index, entry_type; if (!find_object_in_entry_group(installed_entry, &entry_type, &entry_index)){ int chunk_size; From bed75bb2cf824e038c675d2c81981920cad2f157 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 16 Jun 2015 18:00:47 +0100 Subject: [PATCH 4/9] Refactor and start implementing setup functions for object selection --- src/addresses.h | 2 + src/windows/editor_object_selection.c | 126 ++++++++++++++------------ 2 files changed, 70 insertions(+), 58 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index e74cede5f2..34a652bdd9 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -298,6 +298,8 @@ // 1 if custom objects installed, 0 otherwise #define RCT2_ADDRESS_CUSTOM_OBJECTS_INSTALLED 0x00F42BDA +#define RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE 0x00F4340D + #define RCT2_ADDRESS_VOLUME_ADJUST_ZOOM 0x00F438AC #define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908 diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 99071a02da..55184d3799 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -303,6 +303,35 @@ void window_editor_object_selection_open() window->var_494 = 0xFFFFFFFF; } +/* rct2: 0x006AB211 */ +static int sub_6AB211(){ + uint32 total_objects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); + + RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) = rct2_malloc(total_objects); + + if (RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) == NULL){ + log_error("Failed to allocate memory for object flag list."); + return 0; + } + + memset(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*), 0, total_objects); + for (uint8 object_type = 0; object_type < 11; object_type++){ + RCT2_ADDRESS(0x00F433F7, uint16)[object_type] = 0; + RCT2_ADDRESS(0x00F433E1, uint16)[object_type] = 0; + } + + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + uint8 object_type = installedObject->flags & 0xF; + RCT2_ADDRESS(0x00F433E1, uint16)[object_type]++; + + installedObject = object_get_next(installedObject); + } + + //0x6ab2c4 +} + /** * * rct2: 0x006AB199 @@ -1052,7 +1081,7 @@ static void window_editor_object_selection_select_default_objects() /* rct2: 0x006AA770 */ void reset_selected_object_count_and_size(){ for (uint8 object_type = 0; object_type < 11; object_type++){ - RCT2_ADDRESS(0x00F443F7, uint16)[object_type] = 0; + RCT2_ADDRESS(0x00F433F7, uint16)[object_type] = 0; } uint32 total_object_size = 0; @@ -1085,7 +1114,7 @@ void reset_selected_object_count_and_size(){ installedObject = object_get_next(installedObject); } - RCT2_GLOBAL(0x00F4340D, uint32) = total_object_size; + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE, uint32) = total_object_size; } /* rct2: 0x006AB863 */ @@ -1172,6 +1201,18 @@ void reset_required_object_flags(){ } } +/* + * Master objects are objects that are not + * optional / required dependants of an + * object. + */ +void set_object_selection_error(uint8 is_master_object, rct_string_id error_msg){ + RCT2_GLOBAL(0x141E9AC, rct_string_id) = error_msg; + if (!is_master_object){ + reset_selected_object_count_and_size(); + } +} + /** * * rct2: 0x006AB54F @@ -1179,21 +1220,21 @@ void reset_required_object_flags(){ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry) { uint8* selection_flags; - if (bh == 0){ - // Unsure what this does?? - uint16 total_objects = 0; - for (uint8 i = 0; i < 11; ++i){ - total_objects += RCT2_ADDRESS(0x00F433E1, uint16)[i]; - } + //if (bh == 0){ + // // Unsure what this does?? + // uint16 total_objects = 0; + // for (uint8 i = 0; i < 11; ++i){ + // total_objects += RCT2_ADDRESS(0x00F433E1, uint16)[i]; + // } - selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); - for (; total_objects != 0; total_objects--, selection_flags++){ - uint8 select_flag = *selection_flags & ~OBJECT_SELECTION_FLAG_2; - if (select_flag & OBJECT_SELECTION_FLAG_SELECTED){ - select_flag |= OBJECT_SELECTION_FLAG_2; - } - } - } + // selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + // for (; total_objects != 0; total_objects--, selection_flags++){ + // uint8 select_flag = *selection_flags & ~OBJECT_SELECTION_FLAG_2; + // if (select_flag & OBJECT_SELECTION_FLAG_SELECTED){ + // select_flag |= OBJECT_SELECTION_FLAG_2; + // } + // } + //} selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); // There was previously a check to make sure the object list had an item @@ -1210,11 +1251,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct selection_flags++; } if (not_found){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3169; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3169); return 0; } @@ -1227,25 +1264,15 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct return 1; } else if (*selection_flags & OBJECT_SELECTION_FLAG_IN_USE){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3173; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3173); return 0; } else if (*selection_flags & OBJECT_SELECTION_FLAG_REQUIRED){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3174; - if (bh != 0){ - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3174); return 0; } else if (*selection_flags & OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3175; - if (bh != 0){ - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3175); return 0; } @@ -1279,7 +1306,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } } - RCT2_GLOBAL(0x00F4340D, uint32) -= size_of_chunk; + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE, uint32) -= size_of_chunk; uint8 object_type = installedObject->flags & 0xF; RCT2_ADDRESS(0x00F433F7, uint16)[object_type]--; *selection_flags &= ~OBJECT_SELECTION_FLAG_SELECTED; @@ -1308,11 +1335,7 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3171; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3171); return 0; } @@ -1338,7 +1361,6 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct for (; num_required_objects != 0; num_required_objects--){ if (!window_editor_object_selection_select_object(++bh, flags, required_objects)){ if (bh != 0){ - // Bunch of code that looks like it does nothing removed. reset_selected_object_count_and_size(); } return 0; @@ -1360,33 +1382,21 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct if (bh != 0 && !(flags&(1 << 1))){ RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)0x009BC95A, (int)installedObject); - RCT2_GLOBAL(0x141E9AC, uint16) = 3172; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3172); return 0; } - if (RCT2_GLOBAL(0x00F4340D, uint32) + size_of_chunk > 0x40000){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3170; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + if (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE, uint32) + size_of_chunk > 0x40000){ + set_object_selection_error(bh, 3170); return 0; } if (no_objects <= RCT2_ADDRESS(0x00F433F7, uint16)[object_type]){ - RCT2_GLOBAL(0x141E9AC, uint16) = 3171; - if (bh != 0){ - // Bunch of code that looks like it does nothing removed. - reset_selected_object_count_and_size(); - } + set_object_selection_error(bh, 3171); return 0; } - RCT2_GLOBAL(0x00F4340D, uint32) += size_of_chunk; + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_OBJECTS_FILE_SIZE, uint32) += size_of_chunk; RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; *selection_flags |= OBJECT_SELECTION_FLAG_SELECTED; From 468806337cefca65d3ebaea6cc9df2bb55aa6ce4 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 17 Jun 2015 19:51:41 +0100 Subject: [PATCH 5/9] Implement more of the setup functions. Fix bug in object counting. Split up required and optional objects. Corrected optional objects. --- src/windows/editor_object_selection.c | 245 +++++++++++++++++++++----- 1 file changed, 200 insertions(+), 45 deletions(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 55184d3799..09f754b951 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -166,8 +166,6 @@ static void window_editor_object_selection_paint(); static void window_editor_object_selection_scrollpaint(); static void window_editor_object_selection_textinput(); -void reset_selected_object_count_and_size(); - static void* window_editor_object_selection_events[] = { window_editor_object_selection_close, (void*)window_editor_object_selection_mouseup, @@ -204,6 +202,7 @@ static void* window_editor_object_selection_events[] = { static void window_editor_object_set_page(rct_window *w, int page); static void window_editor_object_selection_set_pressed_tab(rct_window *w); static void window_editor_object_selection_select_default_objects(); +static void window_editor_object_selection_select_required_objects(); static int window_editor_object_selection_select_object(uint8 bh, int flags, rct_object_entry *entry); static int get_object_from_object_selection(uint8 object_type, int y, uint8 *object_selection_flags, rct_object_entry **installed_entry); static void window_editor_object_selection_manage_tracks(); @@ -213,40 +212,46 @@ static bool filter_source(rct_object_entry *entry); static bool filter_chunks(rct_object_entry *entry, rct_object_filters *filter); static void filter_update_counts(); -static rct_object_entry DefaultSelectedObjects[] = { - // Objects that are always required - { 0x00000087, { "SCGTREES" }, 0 }, // Scenery: Trees - { 0x00000087, { "SCGSHRUB" }, 0 }, // Scenery: Shrubs and Ornaments - { 0x00000087, { "SCGGARDN" }, 0 }, // Scenery: Gardens - { 0x00000087, { "SCGFENCE" }, 0 }, // Scenery: Fences and Walls - { 0x00000087, { "SCGWALLS" }, 0 }, // Scenery: Walls and Roofs - { 0x00000087, { "SCGPATHX" }, 0 }, // Scenery: Signs and Items for Footpaths - { 0x00000085, { "TARMAC " }, 0 }, // Footpath: Tarmac +void reset_selected_object_count_and_size(); +void reset_required_object_flags(); +static int sub_6AB211(); +static rct_object_entry RequiredSelectedObjects[] = { + // Objects that are always required + { 0x00000087, { "SCGTREES" }, 0 }, // Scenery: Trees + { 0x00000087, { "SCGSHRUB" }, 0 }, // Scenery: Shrubs and Ornaments + { 0x00000087, { "SCGGARDN" }, 0 }, // Scenery: Gardens + { 0x00000087, { "SCGFENCE" }, 0 }, // Scenery: Fences and Walls + { 0x00000087, { "SCGWALLS" }, 0 }, // Scenery: Walls and Roofs + { 0x00000087, { "SCGPATHX" }, 0 }, // Scenery: Signs and Items for Footpaths + { 0x00000085, { "TARMAC " }, 0 }, // Footpath: Tarmac +}; + +static rct_object_entry DefaultSelectedObjects[] = { // An initial default selection - { 0x000080FF, { "TWIST1 " }, 0 }, // Ride: Twist - { 0x00008000, { "PTCT1 " }, 0 }, // Ride: Wooden Roller Coaster (Wooden Roller Coaster Trains) - { 0x00008000, { "ZLDB " }, 0 }, // Ride: Junior Roller Coaster (Ladybird Trains) - { 0x00008000, { "LFB1 " }, 0 }, // Ride: Log Flume - { 0x00008000, { "VCR " }, 0 }, // Ride: Vintage Cars - { 0x00008000, { "MGR1 " }, 0 }, // Ride: Merry-Go-Round - { 0x00008000, { "TLT1 " }, 0 }, // Ride: Restroom - { 0x00008000, { "ATM1 " }, 0 }, // Ride: Cash Machine - { 0x00008000, { "FAID1 " }, 0 }, // Ride: First Aid Room - { 0x00008000, { "INFOK " }, 0 }, // Ride: Information Kiosk - { 0x00008000, { "DRNKS " }, 0 }, // Ride: Drinks Stall - { 0x00008000, { "CNDYF " }, 0 }, // Ride: Cotten Candy Stall - { 0x00008000, { "BURGB " }, 0 }, // Ride: Burger Bar - { 0x00008000, { "BALLN " }, 0 }, // Ride: Balloon Stall - { 0x00008000, { "ARRT1 " }, 0 }, // Ride: Corkscrew Roller Coaster - { 0x00008000, { "RBOAT " }, 0 }, // Ride: Rowing Boats - { 0x00008800, { "PKENT1 " }, 0 }, // Park Entrace: Traditional Park Entrance - { 0x00008900, { "WTRCYAN " }, 0 }, // Water: Natural Water - { 0x00008500, { "TARMACB " }, 0 }, // Footpath: Brown Tarmac Footpath - { 0x00008500, { "PATHSPC " }, 0 }, // Footpath: Space Style Footpath - { 0x00008500, { "PATHDIR " }, 0 }, // Footpath: Dirt Footpath - { 0x00008500, { "PATHCRZ " }, 0 }, // Footpath: Crazy Paving Footpath - { 0x00008500, { "PATHASH " }, 0 }, // Footpath: Ash Footpath + { 0x00000080, { "TWIST1 " }, 0 }, // Ride: Twist + { 0x00000080, { "PTCT1 " }, 0 }, // Ride: Wooden Roller Coaster (Wooden Roller Coaster Trains) + { 0x00000080, { "ZLDB " }, 0 }, // Ride: Junior Roller Coaster (Ladybird Trains) + { 0x00000080, { "LFB1 " }, 0 }, // Ride: Log Flume + { 0x00000080, { "VCR " }, 0 }, // Ride: Vintage Cars + { 0x00000080, { "MGR1 " }, 0 }, // Ride: Merry-Go-Round + { 0x00000080, { "TLT1 " }, 0 }, // Ride: Restroom + { 0x00000080, { "ATM1 " }, 0 }, // Ride: Cash Machine + { 0x00000080, { "FAID1 " }, 0 }, // Ride: First Aid Room + { 0x00000080, { "INFOK " }, 0 }, // Ride: Information Kiosk + { 0x00000080, { "DRNKS " }, 0 }, // Ride: Drinks Stall + { 0x00000080, { "CNDYF " }, 0 }, // Ride: Cotten Candy Stall + { 0x00000080, { "BURGB " }, 0 }, // Ride: Burger Bar + { 0x00000080, { "BALLN " }, 0 }, // Ride: Balloon Stall + { 0x00000080, { "ARRT1 " }, 0 }, // Ride: Corkscrew Roller Coaster + { 0x00000080, { "RBOAT " }, 0 }, // Ride: Rowing Boats + { 0x00000088, { "PKENT1 " }, 0 }, // Park Entrace: Traditional Park Entrance + { 0x00000089, { "WTRCYAN " }, 0 }, // Water: Natural Water + { 0x00000085, { "TARMACB " }, 0 }, // Footpath: Brown Tarmac Footpath + { 0x00000085, { "PATHSPCE" }, 0 }, // Footpath: Space Style Footpath + { 0x00000085, { "PATHDIRT" }, 0 }, // Footpath: Dirt Footpath + { 0x00000085, { "PATHCRZY" }, 0 }, // Footpath: Crazy Paving Footpath + { 0x00000085, { "PATHASH " }, 0 }, // Footpath: Ash Footpath // The following are for all random map generation features to work out the box { 0x00000087, { "SCGJUNGL" }, 0 }, // Jungle Themeing @@ -266,13 +271,10 @@ void window_editor_object_selection_open() if (window != NULL) return; - RCT2_CALLPROC_EBPSAFE(0x006AB211); + if (!sub_6AB211()) + return; reset_selected_object_count_and_size(); - // Not really where its called, but easy way to change default objects for now - if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) - window_editor_object_selection_select_default_objects(); - window = window_create_centred( 600, 400, @@ -303,6 +305,126 @@ void window_editor_object_selection_open() window->var_494 = 0xFFFFFFFF; } +/* rct2: 0x006ABCD1 */ +static void setup_track_manager_objects(){ + uint8 ride_list[128] = { 0 }; + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + uint16 num_objects = 0; + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + uint8 object_type = installedObject->flags & 0xF; + if (object_type == OBJECT_TYPE_RIDE){ + *selection_flags |= OBJECT_SELECTION_FLAG_6; + + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + // Skip size of chunk + pos += 4; + + // Skip required objects + pos += *pos * 16 + 1; + + // Skip theme objects + pos += *pos * 16 + 1; + + for (uint8 j = 0; j < 3; j++){ + uint8 ride_type = pos[j]; + if (ride_type == 0xFF) + continue; + + if (!(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride_type * 2] & + RIDE_TYPE_FLAG_HAS_TRACK)) + continue; + + if (pos[3] & (1 << 0)){ + *selection_flags &= ~OBJECT_SELECTION_FLAG_6; + } + else if (ride_list[ride_type] & (1 << 0)){ + continue; + } + else{ + ride_list[ride_type] |= (1 << 0); + *selection_flags &= ~OBJECT_SELECTION_FLAG_6; + } + num_objects++; + break; + } + } + + installedObject = object_get_next(installedObject); + selection_flags++; + } + + RCT2_GLOBAL(0x00F43412, uint16) = num_objects; +} + +/* rct2: 0x006ABC1E */ +static void setup_track_designer_objects(){ + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + uint16 num_objects = 0; + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + uint8 object_type = installedObject->flags & 0xF; + if (object_type == OBJECT_TYPE_RIDE){ + *selection_flags |= OBJECT_SELECTION_FLAG_6; + + uint8* pos = (uint8*)installedObject; + // Skip sizeof(rct_object_entry) + pos += 16; + + // Skip filename + while (*pos++); + + // Skip no of images + pos += 4; + + // Skip name + while (*pos++); + + // Skip size of chunk + pos += 4; + + // Skip required objects + pos += *pos * 16 + 1; + + // Skip theme objects + pos += *pos * 16 + 1; + + for (uint8 j = 0; j < 3; j++){ + uint8 ride_type = pos[j]; + if (ride_type == 0xFF) + continue; + + if (!(RCT2_ADDRESS(0x0097D4F2, uint16)[ride_type * 4] & + (1 << 11))) + continue; + + *selection_flags &= ~OBJECT_SELECTION_FLAG_6; + num_objects++; + break; + } + } + + installedObject = object_get_next(installedObject); + selection_flags++; + } + + RCT2_GLOBAL(0x00F43412, uint16) = num_objects; +} + /* rct2: 0x006AB211 */ static int sub_6AB211(){ uint32 total_objects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); @@ -329,7 +451,28 @@ static int sub_6AB211(){ installedObject = object_get_next(installedObject); } - //0x6ab2c4 + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER){ + setup_track_designer_objects(); + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER){ + setup_track_manager_objects(); + } + + RCT2_CALLPROC_EBPSAFE(0x006AA82B); + reset_selected_object_count_and_size(); + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))){ + window_editor_object_selection_select_required_objects(); + + // To prevent it breaking in scenario mode. + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) + window_editor_object_selection_select_default_objects(); + } + + reset_required_object_flags(); + reset_selected_object_count_and_size(); + return 1; } /** @@ -1064,20 +1207,32 @@ static void window_editor_object_selection_set_pressed_tab(rct_window *w) } /** - * - * rct2: 0x006AA7E9 - */ +* +* rct2: 0x006AA805 +*/ static void window_editor_object_selection_select_default_objects() { int i; - if (RCT2_GLOBAL(0x00F433F7, uint16) == 0) + if (RCT2_GLOBAL(0x00F433F7, uint16) != 0) return; for (i = 0; i < countof(DefaultSelectedObjects); i++) window_editor_object_selection_select_object(0, 7, &DefaultSelectedObjects[i]); } +/** + * + * rct2: 0x006AA7E9 + */ +static void window_editor_object_selection_select_required_objects() +{ + int i; + + for (i = 0; i < countof(RequiredSelectedObjects); i++) + window_editor_object_selection_select_object(0, 0xF, &RequiredSelectedObjects[i]); +} + /* rct2: 0x006AA770 */ void reset_selected_object_count_and_size(){ for (uint8 object_type = 0; object_type < 11; object_type++){ @@ -1107,7 +1262,7 @@ void reset_selected_object_count_and_size(){ while (*pos++); uint32 size_of_chunk = *((uint32*)pos); - RCT2_ADDRESS(0x00F443F7, uint16)[object_type]++; + RCT2_ADDRESS(0x00F433F7, uint16)[object_type]++; total_object_size += size_of_chunk; } selection_flags++; From 07752aa1b416c704e383478e2684ecf9d6772565 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 17 Jun 2015 20:06:42 +0100 Subject: [PATCH 6/9] Implemented free object selection flags --- src/windows/editor_object_selection.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 09f754b951..b53495aa62 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -475,6 +475,15 @@ static int sub_6AB211(){ return 1; } +/* rct2: 0x006AB316 */ +static void editor_object_flags_free(){ + if (RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) == NULL){ + return; + } + free(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*)); + RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) = NULL; +} + /** * * rct2: 0x006AB199 @@ -491,7 +500,8 @@ static void window_editor_object_selection_close() editor_load_selected_objects(); reset_loaded_objects(); object_free_scenario_text(); - RCT2_CALLPROC_EBPSAFE(0x6AB316); + editor_object_flags_free(); + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_EDITOR) { research_populate_list_random(); research_remove_non_separate_vehicle_types(); From d67d9349b9fa94c455652e4bd1836fa45b28935b Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 18 Jun 2015 18:15:31 +0100 Subject: [PATCH 7/9] Implement setup in use selection flags. --- src/windows/editor_object_selection.c | 101 +++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index b53495aa62..8073955c87 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -425,6 +425,105 @@ static void setup_track_designer_objects(){ RCT2_GLOBAL(0x00F43412, uint16) = num_objects; } +/* rct2: 0x006AA82B */ +static void setup_in_use_selection_flags(){ + + for (uint8 object_type = 0; object_type < 11; object_type++){ + for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){ + RCT2_ADDRESS(0x0098DA38, uint8*)[object_type][i] = 0; + } + } + + for (uint8 object_type = 0; object_type < 11; object_type++){ + for (uint16 i = 0; i < object_entry_group_counts[object_type]; i++){ + if (object_entry_groups[object_type].chunks[i] != (uint8*)0xFFFFFFFF){ + RCT2_ADDRESS(0x0098DA38, uint8*)[object_type][i] |= (1 << 1); + } + } + } + + map_element_iterator iter; + map_element_iterator_begin(&iter); + do { + uint16 type; + uint8 path_additions; + rct_banner* banner; + + switch (map_element_get_type(iter.element)) { + default: + case MAP_ELEMENT_TYPE_SURFACE: + case MAP_ELEMENT_TYPE_TRACK: + break; + case MAP_ELEMENT_TYPE_PATH: + type = iter.element->properties.path.type; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATHS][type] |= (1 << 0); + + path_additions = iter.element->properties.path.additions & 0xF; + if (path_additions){ + path_additions--; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATH_BITS][path_additions] |= (1 << 0); + } + break; + case MAP_ELEMENT_TYPE_SCENERY: + type = iter.element->properties.scenery.type; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_SMALL_SCENERY][type] |= (1 << 0); + break; + case MAP_ELEMENT_TYPE_ENTRANCE: + if (iter.element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) + break; + + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PARK_ENTRANCE][0] |= (1 << 0); + + type = iter.element->properties.entrance.path_type; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_PATHS][type] |= (1 << 0); + break; + case MAP_ELEMENT_TYPE_FENCE: + type = iter.element->properties.fence.type; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_WALLS][type] |= (1 << 0); + break; + case MAP_ELEMENT_TYPE_SCENERY_MULTIPLE: + type = iter.element->properties.scenerymultiple.type & 0x3FF; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_LARGE_SCENERY][type] |= (1 << 0); + break; + case MAP_ELEMENT_TYPE_BANNER: + banner = &gBanners[iter.element->properties.banner.index]; + type = banner->type; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_BANNERS][type] |= (1 << 0); + break; + } + } while (map_element_iterator_next(&iter)); + + for (uint8 ride_index = 0; ride_index < 0xFF; ride_index++){ + rct_ride* ride = GET_RIDE(ride_index); + if (ride->type == RIDE_TYPE_NULL) + continue; + + uint8 type = ride->subtype; + RCT2_ADDRESS(0x0098DA38, uint8*)[OBJECT_TYPE_RIDE][type] |= (1 << 0); + } + + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + *selection_flags &= ~OBJECT_SELECTION_FLAG_IN_USE; + + uint8 entry_type, entry_index; + if (find_object_in_entry_group(installedObject, &entry_type, &entry_index)){ + if (RCT2_ADDRESS(0x0098DA38, uint8*)[entry_type][entry_index] & (1 << 0)){ + *selection_flags |= + OBJECT_SELECTION_FLAG_IN_USE | + OBJECT_SELECTION_FLAG_SELECTED; + } + if (RCT2_ADDRESS(0x0098DA38, uint8*)[entry_type][entry_index] & (1 << 1)){ + *selection_flags |= OBJECT_SELECTION_FLAG_SELECTED; + } + } + installedObject = object_get_next(installedObject); + selection_flags++; + } +} + /* rct2: 0x006AB211 */ static int sub_6AB211(){ uint32 total_objects = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); @@ -459,7 +558,7 @@ static int sub_6AB211(){ setup_track_manager_objects(); } - RCT2_CALLPROC_EBPSAFE(0x006AA82B); + setup_in_use_selection_flags(); reset_selected_object_count_and_size(); if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))){ From 15b2360e130465d4179b418dae0b5472204319cb Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 19 Jun 2015 19:11:23 +0100 Subject: [PATCH 8/9] Implemented object_create_identifier_name and start of last func. Note requires modification of the strings. --- data/language/english_uk.txt | 2 +- src/object.h | 1 + src/object_list.c | 26 ++++++++++++++++++++- src/windows/editor_object_selection.c | 33 ++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 0faa5a9dad..e6683e72b9 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3176,7 +3176,7 @@ STR_3168 :{WINDOW_COLOUR_2}Text: {BLACK}{STRINGID} STR_3169 :Data for the following object not found: STR_3170 :Not enough space for graphics STR_3171 :Too many objects of this type selected -STR_3172 :The following object must be selected first: +STR_3172 :The following object must be selected first: {STRING} STR_3173 :This object is currently in use STR_3174 :This object is required by another object STR_3175 :This object is always required diff --git a/src/object.h b/src/object.h index 9cc6e71969..cf5b735d61 100644 --- a/src/object.h +++ b/src/object.h @@ -112,6 +112,7 @@ rct_object_entry *object_get_next(rct_object_entry *entry); int write_object_file(FILE *file, rct_object_entry* entry); void reset_loaded_objects(); int find_object_in_entry_group(rct_object_entry* entry, uint8* entry_type, uint8* entry_index); +void object_create_identifier_name(uint8* string_buffer, rct_object_entry* object); rct_object_entry *object_list_find(rct_object_entry *entry); diff --git a/src/object_list.c b/src/object_list.c index 7c11b55a7b..e1493345ac 100644 --- a/src/object_list.c +++ b/src/object_list.c @@ -451,6 +451,30 @@ int check_object_entry(rct_object_entry *entry) return (0xFFFFFFFF & dwords[0] & dwords[1] & dwords[2] & dwords[3]) + 1 != 0; } +/* rct2: 0x006AB344 */ +void object_create_identifier_name(uint8* string_buffer, rct_object_entry* object){ + for (uint8 i = 0; i < 8; ++i){ + if (object->name[i] != ' '){ + *string_buffer++ = object->name[i]; + } + } + + *string_buffer++ = '/'; + + for (uint8 i = 0; i < 4; ++i){ + uint8 flag_part = (object->flags >> (i * 8)) & 0xFF; + *string_buffer++ = RCT2_ADDRESS(0x0098DA64, uint8)[flag_part >> 4]; + *string_buffer++ = RCT2_ADDRESS(0x0098DA64, uint8)[flag_part & 0xF]; + } + + for (uint8 i = 0; i < 4; ++i){ + uint8 checksum_part = (object->checksum >> (i * 8)) & 0xFF; + *string_buffer++ = RCT2_ADDRESS(0x0098DA64, uint8)[checksum_part >> 4]; + *string_buffer++ = RCT2_ADDRESS(0x0098DA64, uint8)[checksum_part & 0xF]; + } + *string_buffer++ = '\0'; +} + /* rct2: 0x675827 */ void set_load_objects_fail_reason(){ rct_object_entry* object = RCT2_ADDRESS(0x13CE952, rct_object_entry); @@ -463,7 +487,7 @@ void set_load_objects_fail_reason(){ format_string(string_buffer, 3323, 0); //Missing object data, ID: - RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)string_buffer, 0x13CE952); + object_create_identifier_name(string_buffer, object); RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 0xFF; RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3165; return; diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 8073955c87..7a3783ac4b 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -583,6 +583,35 @@ static void editor_object_flags_free(){ RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) = NULL; } +/* rct2: 0x00685791 */ +void sub_685791(rct_object_entry* installedObject){ + uint8 entry_type, entry_index; + if (!find_object_in_entry_group(installedObject, entry_type, entry_index)) + return; + + if (entry_type == OBJECT_TYPE_RIDE){ + //6857af + } + else if (entry_type == OBJECT_TYPE_SCENERY_SETS){ + //6857a5 + } +} + +/* rct2: 0x006ABB66 */ +void sub_6ABB66(){ + uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); + rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); + + for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ + if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){ + sub_685791(installedObject); + object_unload(0, installedObject); + } + selection_flags++; + installedObject = object_get_next(installedObject); + } +} + /** * * rct2: 0x006AB199 @@ -1645,7 +1674,9 @@ static int window_editor_object_selection_select_object(uint8 bh, int flags, rct } if (bh != 0 && !(flags&(1 << 1))){ - RCT2_CALLPROC_X(0x6AB344, 0, 0, 0, 0, 0, (int)0x009BC95A, (int)installedObject); + uint32* arguments = RCT2_ADDRESS(0x0013CE952, uint32); + object_create_identifier_name((char*)0x009BC95A, installedObject); + *arguments = (uint32)0x009BC95A; set_object_selection_error(bh, 3172); return 0; } From 895d4a81e431e223a63b7ed5c1c261b4a08d58c9 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 19 Jun 2015 21:33:37 +0100 Subject: [PATCH 9/9] finish implementing remove_selected_objects_from_research Fixed bug due to freeing rct2 memory. --- src/management/research.c | 12 ++++++++++++ src/management/research.h | 1 + src/windows/editor_object_selection.c | 21 ++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/management/research.c b/src/management/research.c index f44ed4c5b2..383c21750a 100644 --- a/src/management/research.c +++ b/src/management/research.c @@ -434,6 +434,18 @@ static void research_insert_researched(int entryIndex, int category) } while (entryIndex != (researchItem++)->entryIndex); } +/* rct2: 0x006857CF */ +void research_remove(sint32 entryIndex){ + for (rct_research_item *researchItem = gResearchItems; researchItem->entryIndex != RESEARCHED_ITEMS_END; researchItem++){ + if (researchItem->entryIndex == entryIndex){ + do{ + *researchItem = *(researchItem + 1); + } while (researchItem++->entryIndex != RESEARCHED_ITEMS_END_2); + return; + } + } +} + void research_insert(int researched, int entryIndex, int category) { if (researched) diff --git a/src/management/research.h b/src/management/research.h index e26725b6db..f2a0d4b3f6 100644 --- a/src/management/research.h +++ b/src/management/research.h @@ -83,5 +83,6 @@ void research_set_priority(int activeCategories); void game_command_set_research_funding(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void research_finish_item(sint32 entryIndex); void research_insert(int researched, int entryIndex, int category); +void research_remove(sint32 entryIndex); #endif \ No newline at end of file diff --git a/src/windows/editor_object_selection.c b/src/windows/editor_object_selection.c index 7a3783ac4b..68a6c4cbc9 100644 --- a/src/windows/editor_object_selection.c +++ b/src/windows/editor_object_selection.c @@ -579,33 +579,36 @@ static void editor_object_flags_free(){ if (RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) == NULL){ return; } - free(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*)); + rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*)); RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*) = NULL; } /* rct2: 0x00685791 */ -void sub_685791(rct_object_entry* installedObject){ +void remove_selected_objects_from_research(rct_object_entry* installedObject){ uint8 entry_type, entry_index; - if (!find_object_in_entry_group(installedObject, entry_type, entry_index)) + if (!find_object_in_entry_group(installedObject, &entry_type, &entry_index)) return; if (entry_type == OBJECT_TYPE_RIDE){ - //6857af + rct_ride_type* rideEntry = (rct_ride_type*)object_entry_groups[entry_type].chunks[entry_index]; + research_remove(entry_index | rideEntry->ride_type[0] << 8 | 0x10000); + research_remove(entry_index | rideEntry->ride_type[1] << 8 | 0x10000); + research_remove(entry_index | rideEntry->ride_type[2] << 8 | 0x10000); } else if (entry_type == OBJECT_TYPE_SCENERY_SETS){ - //6857a5 + research_remove(entry_index); } } /* rct2: 0x006ABB66 */ -void sub_6ABB66(){ +void unload_selected_objects(){ uint8* selection_flags = RCT2_GLOBAL(RCT2_ADDRESS_EDITOR_OBJECT_FLAGS_LIST, uint8*); rct_object_entry* installedObject = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, rct_object_entry*); for (int i = RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); i > 0; --i){ if (*selection_flags & OBJECT_SELECTION_FLAG_SELECTED){ - sub_685791(installedObject); - object_unload(0, installedObject); + remove_selected_objects_from_research(installedObject); + object_unload(0, (rct_object_entry_extended*)installedObject); } selection_flags++; installedObject = object_get_next(installedObject); @@ -624,7 +627,7 @@ static void window_editor_object_selection_close() //if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_EDITOR)) // return; - RCT2_CALLPROC_EBPSAFE(0x6ABB66); + unload_selected_objects(); editor_load_selected_objects(); reset_loaded_objects(); object_free_scenario_text();