diff --git a/build.bat b/build.bat new file mode 100644 index 0000000000..8864853060 --- /dev/null +++ b/build.bat @@ -0,0 +1 @@ +msbuild .\projects\openrct2.vcxproj /p:Configuration=Release /p:Platform=x86 \ No newline at end of file diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj index 3077811de3..00a5fd1e84 100644 --- a/projects/openrct2.vcxproj +++ b/projects/openrct2.vcxproj @@ -44,6 +44,7 @@ + @@ -58,6 +59,7 @@ + @@ -137,6 +139,7 @@ + diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters index 59424e14b6..525392db46 100644 --- a/projects/openrct2.vcxproj.filters +++ b/projects/openrct2.vcxproj.filters @@ -162,6 +162,12 @@ Header Files + + Header Files + + + Header Files + @@ -380,6 +386,9 @@ Source Files + + Windows + Source Files diff --git a/src/addresses.h b/src/addresses.h index 98434ec0b9..19263023c3 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -184,6 +184,13 @@ #define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28 #define RCT2_ADDRESS_PATH_TYPES 0x009ADA14 + +#define RCT2_ADDRESS_SMALL_SCENERY_ENTRIES 0x009AD1A4 +#define RCT2_ADDRESS_LARGE_SCENERY_ENTRIES 0x009AD594 +#define RCT2_ADDRESS_WALL_SCENERY_ENTRIES 0x009AD794 +#define RCT2_ADDRESS_BANNER_SCENERY_ENTRIES 0x009AD994 +#define RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES 0x009ADA54 +#define RCT2_ADDRESS_SCENERY_SET_ENTRIES 0x009ADA90 //Every pixel changed by rain is stored. //32bit (pixel_offset 24 bit)(pixel_colour 8 bit) diff --git a/src/game.c b/src/game.c index 06165b0520..621ba79b3c 100644 --- a/src/game.c +++ b/src/game.c @@ -515,7 +515,6 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int * if (!(flags & 0x20)) { // Update money balance finance_payment(cost, RCT2_GLOBAL(0x0141F56C, uint8)); - RCT2_CALLPROC_X(0x0069C674, 0, cost, 0, 0, 0, 0, 0); if (RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8)) { // Create a +/- money text effect if (cost != 0) diff --git a/src/peep.c b/src/peep.c index f45f919ef9..6a846ada5e 100644 --- a/src/peep.c +++ b/src/peep.c @@ -66,7 +66,7 @@ void peep_update_all() peep_update(peep); } else { RCT2_CALLPROC_X(0x0068F41A, 0, 0, 0, i, (int)peep, 0, 0); - if (peep->var_08 == 4) + if (peep->linked_list_type_offset == SPRITE_LINKEDLIST_OFFSET_PEEP) peep_update(peep); } diff --git a/src/peep.h b/src/peep.h index 93b35440cf..f5f0d9d5cd 100644 --- a/src/peep.h +++ b/src/peep.h @@ -308,7 +308,7 @@ typedef struct { uint16 var_02; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 var_09; // 0x09 uint16 sprite_index; // 0x0A uint16 var_0C; diff --git a/src/ride.c b/src/ride.c index e212989516..a705148105 100644 --- a/src/ride.c +++ b/src/ride.c @@ -185,7 +185,7 @@ void ride_update_favourited_stat() ride->guests_favourite = 0; FOR_ALL_PEEPS(spriteIndex, peep) { - if (peep->var_08 != 4) + if (peep->linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP) return; if (peep->favourite_ride != 0xff) { ride = &g_ride_list[peep->favourite_ride]; @@ -547,4 +547,4 @@ int ride_get_total_length(rct_ride *ride) for (i = 0; i < ride->num_stations; i++) totalLength += ride->length[i]; return totalLength; -} \ No newline at end of file +} diff --git a/src/scenery.h b/src/scenery.h new file mode 100644 index 0000000000..59704d94c0 --- /dev/null +++ b/src/scenery.h @@ -0,0 +1,130 @@ +/***************************************************************************** +* Copyright (c) 2014 Dániel Tar +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef _SCENERY_H_ +#define _SCENERY_H_ + +#include "rct2.h" +#include "string_ids.h" + +typedef struct { + uint32 flags; // 0x06 + uint8 height; // 0x0A + uint8 tool_id; // 0x0B + uint16 price; // 0x0C + uint8 pad_0E[12]; + uint8 scenery_tab_id; // 0x1A +} rct_small_scenery_entry; + +typedef enum { + SMALL_SCENERY_FLAG1 = (1 << 0), // 0x1 + SMALL_SCENERY_FLAG2 = (1 << 1), // 0x2 + SMALL_SCENERY_FLAG3 = (1 << 2), // 0x4 + SMALL_SCENERY_FLAG4 = (1 << 3), // 0x8 + SMALL_SCENERY_FLAG5 = (1 << 4), // 0x10 + SMALL_SCENERY_FLAG6 = (1 << 5), // 0x20 + SMALL_SCENERY_FLAG7 = (1 << 6), // 0x40 + SMALL_SCENERY_FLAG8 = (1 << 7), // 0x80 + SMALL_SCENERY_FLAG9 = (1 << 8), // 0x100 + SMALL_SCENERY_FLAG10 = (1 << 9), // 0x200 + SMALL_SCENERY_HAS_PRIMARY_COLOUR = (1 << 10), // 0x400 + SMALL_SCENERY_FLAG12 = (1 << 11), // 0x800 + SMALL_SCENERY_FLAG13 = (1 << 12), // 0x1000 + SMALL_SCENERY_FLAG14 = (1 << 13), // 0x2000 + SMALL_SCENERY_FLAG15 = (1 << 14), // 0x4000 + SMALL_SCENERY_FLAG16 = (1 << 15), // 0x8000 + SMALL_SCENERY_FLAG17 = (1 << 16), // 0x10000 + SMALL_SCENERY_FLAG18 = (1 << 17), // 0x20000 + SMALL_SCENERY_FLAG19 = (1 << 18), // 0x40000 + SMALL_SCENERY_HAS_SECONDARY_COLOUR = (1 << 19), // 0x80000 +} SMALL_SCENERY_FLAGS; + +typedef struct { + uint8 tool_id; // 0x06 + uint8 flags; // 0x07 + uint16 price; // 0x08 + uint8 pad_0A[6]; + uint8 scenery_tab_id; // 0x10 +} rct_large_scenery_entry; + + +typedef struct { + uint8 tool_id; // 0x06 + uint8 flags; // 0x07 + uint8 height; // 0x08 + uint8 flags2; // 0x09 + uint16 price; // 0x0A + uint8 scenery_tab_id; // 0x0C +} rct_wall_scenery_entry; + +typedef enum { + WALL_SCENERY_FLAG1 = (1 << 0), // 0x1 + WALL_SCENERY_FLAG2 = (1 << 1), // 0x2 + WALL_SCENERY_FLAG3 = (1 << 2), // 0x4 + WALL_SCENERY_FLAG4 = (1 << 3), // 0x8 + WALL_SCENERY_FLAG5 = (1 << 4), // 0x10 + WALL_SCENERY_FLAG6 = (1 << 5), // 0x20 + WALL_SCENERY_HAS_SECONDARY_COLOUR = (1 << 6), // 0x40 + WALL_SCENERY_HAS_TERNARY_COLOUR = (1 << 7), // 0x80 +} WALL_SCENERY_FLAGS; + +typedef struct { + uint8 pad_02[3]; + uint8 tool_id; // 0x09 + uint16 price; // 0x0A + uint8 scenery_tab_id; // 0x0C +} rct_path_bit_scenery_entry; + +typedef struct { + uint8 var_06; + uint8 flags; // 0x07 + uint16 price; // 0x08 + uint8 scenery_tab_id; // 0x0A +} rct_banner_scenery_entry; + +typedef struct { + rct_string_id name; // 0x00 + uint32 image; // 0x02 + union { + rct_small_scenery_entry small_scenery; + rct_large_scenery_entry large_scenery; + rct_wall_scenery_entry wall; + rct_path_bit_scenery_entry path_bit; + rct_banner_scenery_entry banner; + }; +} rct_scenery_entry; + +typedef struct { + rct_string_id name; // 0x00 + uint32 image; // 0x02 + uint16 scenery_entries[0x80]; // 0x06 + uint8 entry_count; // 0x106 + uint8 pad_107; + uint8 var_108; // 0x108, order? +} rct_scenery_set_entry; + +#define g_smallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_SMALL_SCENERY_ENTRIES, rct_scenery_entry*) +#define g_largeSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_LARGE_SCENERY_ENTRIES, rct_scenery_entry*) +#define g_wallSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_WALL_SCENERY_ENTRIES, rct_scenery_entry*) +#define g_bannerSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_BANNER_SCENERY_ENTRIES, rct_scenery_entry*) +#define g_pathBitSceneryEntries RCT2_ADDRESS(RCT2_ADDRESS_PATH_BIT_SCENERY_ENTRIES, rct_scenery_entry*) +#define g_scenerySetEntries RCT2_ADDRESS(RCT2_ADDRESS_SCENERY_SET_ENTRIES, rct_scenery_set_entry*) + +#endif \ No newline at end of file diff --git a/src/sprite.c b/src/sprite.c index ec511dfaeb..e6d589f5b1 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -53,7 +53,7 @@ void reset_sprite_list(){ spr->unknown.sprite_identifier = 0xFF; spr->unknown.sprite_index = i; spr->unknown.next = SPRITE_INDEX_NULL; - spr->unknown.var_08 = 0; + spr->unknown.linked_list_type_offset = 0; if (previous_spr != (rct_sprite*)SPRITE_INDEX_NULL){ spr->unknown.previous = previous_spr->unknown.sprite_index; @@ -108,11 +108,11 @@ void reset_0x69EBE4(){ /* * rct2: 0x0069EC6B -* bl: unclear what this does +* bl: if bl & 2 > 0, the sprite ends up in the FLOATING_TEXT linked list. */ rct_sprite *create_sprite(uint8 bl) { - int ecx = 0xA; + SPRITE_LINKEDLIST_OFFSET linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_UNKNOWN; // cl if ((bl & 2) != 0) { @@ -123,7 +123,7 @@ rct_sprite *create_sprite(uint8 bl) return NULL; } - ecx = 6; + linkedListTypeOffset = SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT; } else if (RCT2_GLOBAL(0x13573C8, uint16) <= 0) { @@ -132,7 +132,7 @@ rct_sprite *create_sprite(uint8 bl) rct_unk_sprite *sprite = &(g_sprite_list[RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX, uint16)]).unknown; - RCT2_CALLPROC_X(0x0069ED0B, 0, 0, ecx, 0, (int)sprite, 0, 0); + move_sprite_to_list((rct_sprite *)sprite, (uint8)linkedListTypeOffset); sprite->x = SPRITE_LOCATION_NULL; sprite->y = SPRITE_LOCATION_NULL; @@ -148,4 +148,56 @@ rct_sprite *create_sprite(uint8 bl) RCT2_GLOBAL(0xF3EF60, uint16) = sprite->sprite_index; return (rct_sprite*)sprite; +} + +/* +* rct2: 0x0069ED0B +* This function moves a sprite to the specified sprite linked list. +* There are 5/6 of those, and cl specifies a pointer offset +* of the desired linked list in a uint16 array. Known valid values are +* 2, 4, 6, 8 or 10 (SPRITE_LINKEDLIST_OFFSET_...) +*/ +void move_sprite_to_list(rct_sprite *sprite, uint8 cl) +{ + rct_unk_sprite *unkSprite = &sprite->unknown; + + // No need to move if the sprite is already in the desired list + if (unkSprite->linked_list_type_offset == cl) + return; + + // If the sprite is currently the head of the list, the + // sprite following this one becomes the new head of the list. + if (unkSprite->previous == SPRITE_INDEX_NULL) + { + RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + unkSprite->linked_list_type_offset, uint16) = unkSprite->next; + } + else + { + // Hook up sprite->previous->next to sprite->next, removing the sprite from its old list + g_sprite_list[unkSprite->previous].unknown.next = unkSprite->next; + } + + // Similarly, hook up sprite->next->previous to sprite->previous + if (unkSprite->next != SPRITE_INDEX_NULL) + { + g_sprite_list[unkSprite->next].unknown.previous = unkSprite->previous; + } + + int oldListTypeOffset = unkSprite->linked_list_type_offset; + unkSprite->previous = SPRITE_INDEX_NULL; // We become the new head of the target list, so there's no previous sprite + unkSprite->linked_list_type_offset = cl; + + unkSprite->next = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16); // This sprite's next sprite is the old head, since we're the new head + RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_NEXT_INDEX + cl, uint16) = unkSprite->sprite_index; // Store this sprite's index as head of its new list + + if (unkSprite->next != SPRITE_INDEX_NULL) + { + // Fix the chain by settings sprite->next->previous to sprite_index + g_sprite_list[unkSprite->next].unknown.previous = unkSprite->sprite_index; + } + + // These globals are probably counters for each sprite list? + // Decrement old list counter, increment new list counter. + --(RCT2_GLOBAL(0x13573C8 + oldListTypeOffset, uint16)); + ++(RCT2_GLOBAL(0x13573C8 + cl, uint16)); } \ No newline at end of file diff --git a/src/sprite.h b/src/sprite.h index 81f6955956..567c64af44 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -36,13 +36,21 @@ enum SPRITE_IDENTIFIER{ SPRITE_IDENTIFIER_LITTER = 3, }; +typedef enum { + SPRITE_LINKEDLIST_OFFSET_VEHICLE = 2, + SPRITE_LINKEDLIST_OFFSET_PEEP = 4, + SPRITE_LINKEDLIST_OFFSET_FLOATING_TEXT = 6, + SPRITE_LINKEDLIST_OFFSET_FLOATING_LITTER = 8, + SPRITE_LINKEDLIST_OFFSET_UNKNOWN = 10 +} SPRITE_LINKEDLIST_OFFSET; + typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01; uint16 var_02; uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0C[2]; @@ -66,7 +74,7 @@ typedef struct { uint16 var_02; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0B[0x19]; @@ -92,5 +100,6 @@ void create_balloon(int x, int y, int z, int colour); rct_sprite *create_sprite(uint8 bl); void reset_sprite_list(); void reset_0x69EBE4(); +void move_sprite_to_list(rct_sprite *sprite, uint8 cl); #endif diff --git a/src/staff.c b/src/staff.c index cead4581e3..ce46f47525 100644 --- a/src/staff.c +++ b/src/staff.c @@ -127,7 +127,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, RCT2_CALLPROC_X(0x0069EDB6, 0, 0, _ecx, 0, (int)newPeep, 0, 0); } else { - RCT2_CALLPROC_X(0x0069ED0B, 0, 0, 4, 0, (int)newPeep, 0, 0); + move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); newPeep->sprite_identifier = 1; newPeep->var_09 = 0x0F; diff --git a/src/string_ids.h b/src/string_ids.h index 28aae38707..ccea24de47 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -433,7 +433,7 @@ enum { STR_GUESTS = 1463, STR_STAFF = 1468, - + STR_EXCITEMENT_RATING = 1473, STR_EXCITEMENT_RATING_NOT_YET_AVAILABLE = 1474, STR_INTENSITY_RATING = 1475, @@ -585,7 +585,7 @@ enum { STR_NEVER = 1885, STR_INSPECTING_RIDE = 1886, - + STR_TIME_SINCE_LAST_INSPECTION_MINUTES = 1887, STR_TIME_SINCE_LAST_INSPECTION_MORE_THAN_4_HOURS = 1888, STR_DOWN_TIME_LABEL_1889 = 1889, @@ -1018,6 +1018,10 @@ enum { STR_SAME_PRICE_THROUGHOUT_PARK = 3071, STR_SAME_PRICE_THROUGHOUT_PARK_TIP = 3072, + STR_SELECT_COLOUR = 3099, + STR_SELECT_SECONDARY_COLOUR = 3100, + STR_SELECT_TERNARY_COLOUR = 3101, + STR_LIST_RIDES_TIP = 3104, STR_LIST_SHOPS_AND_STALLS_TIP = 3105, STR_LIST_KIOSKS_AND_FACILITIES_TIP = 3106, diff --git a/src/vehicle.h b/src/vehicle.h index 7d45ea9e2b..64ee1f0fc1 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -36,7 +36,7 @@ typedef struct { uint8 pad_01[0x03]; uint16 next; // 0x04 uint16 previous; // 0x06 - uint8 var_08; + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A uint8 pad_0C[2]; diff --git a/src/window.h b/src/window.h index 0ba56b43ba..3f6867f9aa 100644 --- a/src/window.h +++ b/src/window.h @@ -163,6 +163,11 @@ typedef struct { sint32 var_486; } ride_variables; +typedef struct { + sint16 selected_scenery_id; + sint16 hover_counter; +} scenery_variables; + /** * Window structure * size: 0x4C0 @@ -200,6 +205,7 @@ typedef struct rct_window { news_variables news; map_variables map; ride_variables ride; + scenery_variables scenery; }; sint16 page; // 0x48A sint16 var_48C; @@ -459,6 +465,7 @@ void window_new_ride_open(); void window_banner_open(); void window_cheats_open(); void window_research_open(); +void window_scenery_open(); void window_guest_list_init_vars_a(); void window_guest_list_init_vars_b(); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 4825f55128..a81eaf85df 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -259,7 +259,8 @@ static void window_game_top_toolbar_mouseup() case WIDX_SCENERY: if (!tool_set(w, WIDX_SCENERY, 0)) { RCT2_GLOBAL(0x009DE518, uint32) |= (1 << 6); - RCT2_CALLPROC_EBPSAFE(0x006E0FEF); + window_scenery_open(); + //RCT2_CALLPROC_EBPSAFE(0x006E0FEF); } break; case WIDX_PATH: diff --git a/src/window_new_ride.c b/src/window_new_ride.c index d63c5ef2c8..0c8585f1ab 100644 --- a/src/window_new_ride.c +++ b/src/window_new_ride.c @@ -25,6 +25,7 @@ #include "news_item.h" #include "ride.h" #include "string_ids.h" +#include "scenery.h" #include "track.h" #include "widget.h" #include "window.h" @@ -761,8 +762,7 @@ static void window_new_ride_paint() rideEntry->name : (typeId & 0xFF00) + 2; } else { - uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); - stringId = RCT2_GLOBAL(sceneryEntry, uint16); + stringId = g_scenerySetEntries[typeId]->name; } } } @@ -798,8 +798,7 @@ static void window_new_ride_paint() rideEntry->name : (typeId & 0xFF00) + 2; } else { - uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); - stringId = RCT2_GLOBAL(sceneryEntry, uint16); + stringId = g_scenerySetEntries[typeId]->name; } gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, STR_RESEARCH_RIDE_LABEL, 0); } diff --git a/src/window_research.c b/src/window_research.c index b65fc7dba4..5685c80da1 100644 --- a/src/window_research.c +++ b/src/window_research.c @@ -23,6 +23,7 @@ #include "game.h" #include "news_item.h" #include "ride.h" +#include "scenery.h" #include "string_ids.h" #include "sprites.h" #include "widget.h" @@ -348,8 +349,7 @@ static void window_research_development_paint() rideEntry->name : ((typeId >> 8) & 0xFF) + 2; } else { - uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); - stringId = RCT2_GLOBAL(sceneryEntry, uint16); + stringId = g_scenerySetEntries[typeId]->name; } } } @@ -388,8 +388,7 @@ static void window_research_development_paint() lastDevelopmentFormat = STR_RESEARCH_RIDE_LABEL; } else { - uint8 *sceneryEntry = RCT2_GLOBAL(0x009ADA90 + (typeId & 0xFFFF) * 4, uint8*); - stringId = RCT2_GLOBAL(sceneryEntry, uint16); + stringId = g_scenerySetEntries[typeId]->name; lastDevelopmentFormat = STR_RESEARCH_SCENERY_LABEL; } gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, lastDevelopmentFormat, 0); diff --git a/src/window_scenery.c b/src/window_scenery.c new file mode 100644 index 0000000000..86d3cbcdd8 --- /dev/null +++ b/src/window_scenery.c @@ -0,0 +1,1163 @@ +/***************************************************************************** +* Copyright (c) 2014 Dániel Tar +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#include +#include +#include "addresses.h" +#include "audio.h" +#include "game.h" +#include "map.h" +#include "gfx.h" +#include "peep.h" +#include "sprite.h" +#include "scenery.h" +#include "string_ids.h" +#include "viewport.h" +#include "widget.h" +#include "window.h" +#include "window_scenery.h" + +enum { + WINDOW_SCENERY_TAB_1, + WINDOW_SCENERY_TAB_2, + WINDOW_SCENERY_TAB_3, + WINDOW_SCENERY_TAB_4, + WINDOW_SCENERY_TAB_5, + WINDOW_SCENERY_TAB_6, + WINDOW_SCENERY_TAB_7, + WINDOW_SCENERY_TAB_8, + WINDOW_SCENERY_TAB_9, + WINDOW_SCENERY_TAB_10, + WINDOW_SCENERY_TAB_11, + WINDOW_SCENERY_TAB_12, + WINDOW_SCENERY_TAB_13, + WINDOW_SCENERY_TAB_14, + WINDOW_SCENERY_TAB_15, + WINDOW_SCENERY_TAB_16, + WINDOW_SCENERY_TAB_17, + WINDOW_SCENERY_TAB_18, + WINDOW_SCENERY_TAB_19, + WINDOW_SCENERY_TAB_20 +} WINDOW_SCENERY_LIST_TAB; + +static void window_scenery_emptysub() { } +static void window_scenery_close(); +static void window_scenery_mouseup(); +static void window_scenery_resize(); +static void window_scenery_mousedown(int widgetIndex, rct_window* w, rct_widget* widget); +static void window_scenery_dropdown(); +static void window_scenery_update(rct_window *w); +static void window_scenery_event_07(); +static void window_scenery_scrollgetsize(); +static void window_scenery_scrollmousedown(); +static void window_scenery_scrollmouseover(); +static void window_scenery_tooltip(); +static void window_scenery_invalidate(); +static void window_scenery_paint(); +static void window_scenery_scrollpaint(); + +static void* window_scenery_events[] = { + window_scenery_close, + window_scenery_mouseup, + window_scenery_resize, + window_scenery_mousedown, + window_scenery_dropdown, + window_scenery_emptysub, + window_scenery_update, + window_scenery_event_07, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_scrollgetsize, + window_scenery_scrollmousedown, + window_scenery_emptysub, + window_scenery_scrollmouseover, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_tooltip, + window_scenery_emptysub, + window_scenery_emptysub, + window_scenery_invalidate, + window_scenery_paint, + window_scenery_scrollpaint, +}; + + +enum WINDOW_SCENERY_LIST_WIDGET_IDX { + WIDX_SCENERY_BACKGROUND, // 1 + WIDX_SCENERY_TITLE, // 2 + WIDX_SCENERY_CLOSE, // 4 + WIDX_SCENERY_TAB_CONTENT_PANEL, // 8 + WIDX_SCENERY_TAB_1, // 10 + WIDX_SCENERY_TAB_2, // 20 + WIDX_SCENERY_TAB_3, // 40 + WIDX_SCENERY_TAB_4, // 80 + WIDX_SCENERY_TAB_5, // 100 + WIDX_SCENERY_TAB_6, // 200 + WIDX_SCENERY_TAB_7, // 400 + WIDX_SCENERY_TAB_8, // 800 + WIDX_SCENERY_TAB_9, // 1000 + WIDX_SCENERY_TAB_10, // 2000 + WIDX_SCENERY_TAB_11, // 4000 + WIDX_SCENERY_TAB_12, // 8000 + WIDX_SCENERY_TAB_13, // 10000 + WIDX_SCENERY_TAB_14, // 20000 + WIDX_SCENERY_TAB_15, // 40000 + WIDX_SCENERY_TAB_16, // 80000 + WIDX_SCENERY_TAB_17, // 100000 + WIDX_SCENERY_TAB_18, // 200000 + WIDX_SCENERY_TAB_19, // 400000 + WIDX_SCENERY_TAB_20, // 800000 + WIDX_SCENERY_LIST, // 1000000 + WIDX_SCENERY_ROTATE_OBJECTS_BUTTON, // 2000000 + WIDX_SCENERY_REPAINT_SCENERY_BUTTON, // 4000000 + WIDX_SCENERY_PRIMARY_COLOUR_BUTTON, // 8000000 + WIDX_SCENERY_SECONDARY_COLOUR_BUTTON, // 10000000 + WIDX_SCENERY_TERTIARY_COLOUR_BUTTON, // 20000000 + WIDX_SCENERY_BUILD_CLUSTER_BUTTON, // 40000000 +}; + +static rct_widget window_scenery_widgets[] = { + { WWT_FRAME, 0, 0, 633, 0, 141, 0xFFFFFFFF, STR_NONE }, // 1 0x009DE298 + { WWT_CAPTION, 0, 1, 632, 1, 14, 0xFFFFFFFF, STR_WINDOW_TITLE_TIP }, // 2 0x009DE2A8 + { WWT_CLOSEBOX, 0, 621, 631, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // 4 0x009DE2B8 + { WWT_RESIZE, 1, 0, 633, 43, 141, 0xFFFFFFFF, STR_NONE }, // 8 0x009DE2C8 + { WWT_TAB, 1, 3, 33, 17, 43, 0xFFFFFFFF, 1812 }, // 10 0x009DE2D8 + { WWT_TAB, 1, 34, 64, 17, 43, 0xFFFFFFFF, 1812 }, // 20 0x009DE2E8 + { WWT_TAB, 1, 65, 95, 17, 43, 0xFFFFFFFF, 1812 }, // 40 0x009DE2F8 + { WWT_TAB, 1, 96, 126, 17, 43, 0xFFFFFFFF, 1812 }, // 80 0x009DE308 + { WWT_TAB, 1, 127, 157, 17, 43, 0xFFFFFFFF, 1812 }, // 100 0x009DE318 + { WWT_TAB, 1, 158, 188, 17, 43, 0xFFFFFFFF, 1812 }, // 200 0x009DE328 + { WWT_TAB, 1, 189, 219, 17, 43, 0xFFFFFFFF, 1812 }, // 400 0x009DE338 + { WWT_TAB, 1, 220, 250, 17, 43, 0xFFFFFFFF, 1812 }, // 800 0x009DE348 + { WWT_TAB, 1, 251, 281, 17, 43, 0xFFFFFFFF, 1812 }, // 1000 0x009DE358 + { WWT_TAB, 1, 282, 312, 17, 43, 0xFFFFFFFF, 1812 }, // 2000 0x009DE368 + { WWT_TAB, 1, 313, 343, 17, 43, 0xFFFFFFFF, 1812 }, // 4000 0x009DE378 + { WWT_TAB, 1, 344, 374, 17, 43, 0xFFFFFFFF, 1812 }, // 8000 0x009DE388 + { WWT_TAB, 1, 375, 405, 17, 43, 0xFFFFFFFF, 1812 }, // 10000 0x009DE398 + { WWT_TAB, 1, 406, 436, 17, 43, 0xFFFFFFFF, 1812 }, // 20000 0x009DE3A8 + { WWT_TAB, 1, 437, 467, 17, 43, 0xFFFFFFFF, 1812 }, // 40000 0x009DE3B8 + { WWT_TAB, 1, 468, 498, 17, 43, 0xFFFFFFFF, 1812 }, // 80000 0x009DE3C8 + { WWT_TAB, 1, 468, 498, 17, 43, 0xFFFFFFFF, 1812 }, // 100000 0x009DE3D8 + { WWT_TAB, 1, 468, 498, 17, 43, 0xFFFFFFFF, 1812 }, // 200000 0x009DE3E8 + { WWT_TAB, 1, 468, 498, 17, 43, 0xFFFFFFFF, 1812 }, // 400000 0x009DE3F8 + { WWT_TAB, 1, 468, 498, 17, 43, 0x20001598, 1812 }, // 800000 0x009DE408 + { WWT_SCROLL, 1, 2, 608, 47, 126, 2, STR_NONE }, // 1000000 0x009DE418 + { WWT_FLATBTN, 1, 609, 632, 44, 67, 5169, STR_ROTATE_OBJECTS_90 }, // 2000000 0x009DE428 + { WWT_FLATBTN, 1, 609, 632, 68, 91, 5173, 3102 }, // 4000000 0x009DE438 + { WWT_COLORBTN, 1, 615, 626, 93, 104, 0xFFFFFFFF, STR_SELECT_COLOUR }, // 8000000 0x009DE448 + { WWT_COLORBTN, 1, 615, 626, 105, 116, 0xFFFFFFFF, STR_SELECT_SECONDARY_COLOUR }, // 10000000 0x009DE458 + { WWT_COLORBTN, 1, 615, 626, 117, 128, 0xFFFFFFFF, STR_SELECT_TERNARY_COLOUR }, // 20000000 0x009DE468 + { WWT_FLATBTN, 1, 609, 632, 117, 140, 5172, 3225 }, // 40000000 0x009DE478 + { WIDGETS_END }, +}; + +static sint16 window_scenery_tab_entries[0x13][SCENERY_ENTRIES_BY_TAB + 1]; + +/* +* Was part of 0x006DFA00 +* The same code repeated five times for every scenery entry type +*/ +void init_scenery_entry(rct_scenery_entry *sceneryEntry, int index, uint8 sceneryTabId) { + if (RCT2_ADDRESS(0x01357BD0, sint32)[index >> 5] & (1 << (index & 0x1F))) { + if (sceneryTabId != 0xFF) { + for (int i = 0; i < SCENERY_ENTRIES_BY_TAB; i++) { + if (window_scenery_tab_entries[sceneryTabId][i] == -1) + { + window_scenery_tab_entries[sceneryTabId][i] = index; + window_scenery_tab_entries[sceneryTabId][i + 1] = -1; + return; + } + } + } + + for (int i = 0; i < 0x13; i++) { + int counter = 0; + + while (window_scenery_tab_entries[i][counter] != -1) + { + if (window_scenery_tab_entries[i][counter] == index) { + return; + } + + counter++; + } + } + + for (int i = 0; i < SCENERY_ENTRIES_BY_TAB; i++) { + if (window_scenery_tab_entries[0x13][i] == -1) + { + window_scenery_tab_entries[0x13][i] = index; + window_scenery_tab_entries[0x13][i + 1] = -1; + break; + } + } + } +} + +/* +* rct2: 0x006DFA00 +**/ +void init_scenery() { + bool enabledScenerySets[0x13] = { false }; + + for (int scenerySetIndex = 0; scenerySetIndex < 0x14; scenerySetIndex++) { + window_scenery_tab_entries[scenerySetIndex][0] = -1; + if (scenerySetIndex == 0x13) + continue; + + rct_scenery_set_entry* scenerySetEntry = g_scenerySetEntries[scenerySetIndex]; + if ((uint32)scenerySetEntry == 0xFFFFFFFF) + continue; + + int sceneryTabEntryCount = 0; + + for (int i = 0; i < scenerySetEntry->entry_count; i++) { + uint16 sceneryEntryId = scenerySetEntry->scenery_entries[i]; + uint32 ecx = RCT2_ADDRESS(0x01357BD0, uint32)[sceneryEntryId >> 5]; + uint32 edx = 1 << (sceneryEntryId & 0x1F); + if (ecx & edx) { + window_scenery_tab_entries[scenerySetIndex][sceneryTabEntryCount] = sceneryEntryId; + window_scenery_tab_entries[scenerySetIndex][++sceneryTabEntryCount] = -1; + } else { + enabledScenerySets[scenerySetIndex] = true; + } + } + } + + // small scenery + for (uint16 sceneryId = 0; sceneryId < 0xFC; sceneryId++) { + if ((uint32)g_smallSceneryEntries[sceneryId] == 0xFFFFFFFF) + continue; + + rct_scenery_entry* sceneryEntry = g_smallSceneryEntries[sceneryId]; + init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->small_scenery.scenery_tab_id); + } + + // large scenery + for (int sceneryId = 0x300; sceneryId < 0x380; sceneryId++) { + int largeSceneryIndex = sceneryId - 0x300; + + if ((uint32)g_largeSceneryEntries[largeSceneryIndex] == 0xFFFFFFFF) + continue; + + rct_scenery_entry* sceneryEntry = g_largeSceneryEntries[largeSceneryIndex]; + init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->large_scenery.scenery_tab_id); + } + + // walls + for (int sceneryId = 0x200; sceneryId < 0x280; sceneryId++) { + int wallSceneryIndex = sceneryId - 0x200; + + if ((uint32)g_wallSceneryEntries[wallSceneryIndex] == 0xFFFFFFFF) + continue; + + rct_scenery_entry* sceneryEntry = g_wallSceneryEntries[wallSceneryIndex]; + init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->wall.scenery_tab_id); + } + + // banners + for (int sceneryId = 0x400; sceneryId < 0x420; sceneryId++) { + int bannerIndex = sceneryId - 0x400; + + if ((uint32)g_bannerSceneryEntries[bannerIndex] == 0xFFFFFFFF) + continue; + + rct_scenery_entry* sceneryEntry = g_bannerSceneryEntries[bannerIndex]; + init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->banner.scenery_tab_id); + } + + // path bits + for (int sceneryId = 0x100; sceneryId < 0x10F; sceneryId++) { + int pathBitIndex = sceneryId - 0x100; + + if ((uint32)g_pathBitSceneryEntries[pathBitIndex] == 0xFFFFFFFF) + continue; + + rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[pathBitIndex]; + init_scenery_entry(sceneryEntry, sceneryId, sceneryEntry->path_bit.scenery_tab_id); + } + + for (int widgetIndex = WIDX_SCENERY_TAB_1; widgetIndex < WIDX_SCENERY_LIST; widgetIndex++) + window_scenery_widgets[widgetIndex].type = 0; + + uint8 tabIndexes[0x13]; + uint8 order[0x13]; + int usedValues = 0; + + for (int scenerySetId = 0; scenerySetId < 0x13; scenerySetId++) { + rct_scenery_set_entry* sceneryEntry = g_scenerySetEntries[scenerySetId]; + if ((uint32)sceneryEntry == 0xFFFFFFFF) + continue; + + tabIndexes[usedValues] = scenerySetId; + order[usedValues] = sceneryEntry->var_108; + + usedValues++; + } + + while (true) { + bool finished = true; + for (int i = 1; i < usedValues; i++) { + if (order[i - 1] > order[i]) { + uint8 tmp = tabIndexes[i - 1]; + tabIndexes[i - 1] = tabIndexes[i]; + tabIndexes[i] = tmp; + tmp = order[i - 1]; + order[i - 1] = order[i]; + order[i] = tmp; + finished = false; + } + } + + if (finished) + break; + } + + tabIndexes[usedValues] = 0x13; + usedValues++; + + uint16 left = 3; + for (int i = 0; i < usedValues; i ++) { + uint32 tabIndex = tabIndexes[i]; + rct_widget* tabWidget = &window_scenery_widgets[tabIndex + WIDX_SCENERY_TAB_1]; + + if (left != 3 || tabIndex == 0x13) { + if (window_scenery_tab_entries[tabIndex][0] == -1) + continue; + + if (enabledScenerySets[tabIndex]) + continue; + } + + tabWidget->type = WWT_TAB; + tabWidget->left = left; + tabWidget->right = left + 0x1E; + left += 0x1F; + + if (tabIndex >= 0x13) + continue; + + tabWidget->image = g_scenerySetEntries[tabIndex]->image | 0x20000000; + } + + window_invalidate_by_id(WC_SCENERY, 0); +} + +/* +* rct2: 0x006E0FEF +**/ +void window_scenery_open() +{ + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_SCENERY, 0); + if (window != NULL) + return; + + init_scenery(); + + window = window_create(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16) - WINDOW_SCENERY_WIDTH, 0x1D, WINDOW_SCENERY_WIDTH, WINDOW_SCENERY_HEIGHT, + (uint32*)window_scenery_events, WC_SCENERY, WF_2); + window->widgets = window_scenery_widgets; + + window->enabled_widgets = + (1 << WIDX_SCENERY_CLOSE) | + (1 << WIDX_SCENERY_ROTATE_OBJECTS_BUTTON) | + (1 << WIDX_SCENERY_TAB_1) | + (1 << WIDX_SCENERY_TAB_2) | + (1 << WIDX_SCENERY_TAB_3) | + (1 << WIDX_SCENERY_TAB_4) | + (1 << WIDX_SCENERY_TAB_5) | + (1 << WIDX_SCENERY_TAB_6) | + (1 << WIDX_SCENERY_TAB_7) | + (1 << WIDX_SCENERY_TAB_8) | + (1 << WIDX_SCENERY_TAB_9) | + (1 << WIDX_SCENERY_TAB_10) | + (1 << WIDX_SCENERY_TAB_11) | + (1 << WIDX_SCENERY_TAB_12) | + (1 << WIDX_SCENERY_TAB_13) | + (1 << WIDX_SCENERY_TAB_14) | + (1 << WIDX_SCENERY_TAB_15) | + (1 << WIDX_SCENERY_TAB_16) | + (1 << WIDX_SCENERY_TAB_17) | + (1 << WIDX_SCENERY_TAB_18) | + (1 << WIDX_SCENERY_TAB_19) | + (1 << WIDX_SCENERY_TAB_20) | + (1 << WIDX_SCENERY_PRIMARY_COLOUR_BUTTON) | + (1 << WIDX_SCENERY_SECONDARY_COLOUR_BUTTON) | + (1 << WIDX_SCENERY_REPAINT_SCENERY_BUTTON) | + (1 << WIDX_SCENERY_TERTIARY_COLOUR_BUTTON) | + (1 << WIDX_SCENERY_BUILD_CLUSTER_BUTTON); + + window_init_scroll_widgets(window); + RCT2_CALLPROC_X(0x006E1EB4, 0, 0, 0, 0, (int)window, 0, 0); + show_gridlines(); + window_scenery_rotation = 3; + RCT2_GLOBAL(0x00F64F12, uint8) = 0; + RCT2_GLOBAL(0x00F64F13, uint8) = 0; + window->scenery.selected_scenery_id = -1; + window->scenery.hover_counter = 0; + window_push_others_below(window); + RCT2_GLOBAL(0x00F64F0D, uint8) = 0; + RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000; + RCT2_GLOBAL(0x00F64EC0, uint16) = 0; + window_scenery_is_repaint_scenery_tool_on = 0; // repaint colored scenery tool state + window_scenery_is_build_cluster_tool_on = 0; // build cluster tool state + + window->min_width = WINDOW_SCENERY_WIDTH; + window->max_width = WINDOW_SCENERY_WIDTH; + window->min_height = WINDOW_SCENERY_HEIGHT; + window->max_height = WINDOW_SCENERY_HEIGHT; + window->colours[0] = 0x18; + window->colours[1] = 0x0C; + window->colours[2] = 0x0C; +} + +/* + * rct2: 0x0066DB3D +*/ +bool window_scenery_is_scenery_tool_active() { + int toolWindowClassification = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass); + int toolWidgetIndex = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, rct_windownumber); + + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) + if (toolWindowClassification == WC_TOP_TOOLBAR && toolWidgetIndex == 9) // 9 is WIDX_SCENERY + return true; + + return false; +} + + +/* +* rct2: 0x006E1A73 +**/ +void window_scenery_close() { + rct_window *w; + + window_get_register(w); + + RCT2_CALLPROC_EBPSAFE(0x006E2712); + hide_gridlines(); + RCT2_CALLPROC_X(0x006CB70A, 0, 0, 0, 0, 0, 0, 0); + + if (window_scenery_is_scenery_tool_active()) + tool_cancel(); +} + +int window_scenery_scrollgetsize_num() { + int items = 0; + while (window_scenery_tab_entries[window_scenery_active_tab_index][items] != -1) + items++; + + items += 8; + int rows = items / 9; + if (rows == 0) + rows++; + + return rows * SCENERY_BUTTON_HEIGHT; +} + +/** +* +* rct2: 0x006BD94C +*/ +static void window_scenery_mouseup() +{ + short widgetIndex; + rct_window *w; + + window_widget_get_registers(w, widgetIndex); + + switch (widgetIndex) { + case WIDX_SCENERY_CLOSE: + window_close(w); + break; + case WIDX_SCENERY_ROTATE_OBJECTS_BUTTON: + window_scenery_rotation++; + window_scenery_rotation = window_scenery_rotation % 4; + RCT2_CALLPROC_EBPSAFE(0x006E2712); + window_invalidate(w); + break; + case WIDX_SCENERY_REPAINT_SCENERY_BUTTON: + window_scenery_is_repaint_scenery_tool_on ^= 1; + window_invalidate(w); + break; + case WIDX_SCENERY_BUILD_CLUSTER_BUTTON: + window_scenery_is_build_cluster_tool_on ^= 1; + window_invalidate(w); + break; + } +} + +/* +* +* rct2: 0x006E1EB4 +*/ +void window_scenery_update_scroll(rct_window *w) { + int scrollsize = window_scenery_scrollgetsize_num(); + w->scrolls[0].v_bottom = scrollsize; + + int tabIndex = window_scenery_active_tab_index; + + int itemIndex = 0; + sint16 sceneryId; + while ((sceneryId = window_scenery_tab_entries[tabIndex][itemIndex]) != -1) { + if (sceneryId == window_scenery_selected_scenery_by_tab[tabIndex]) + break; + itemIndex++; + } + + if (sceneryId == -1) { + itemIndex = 0; + sint16 sceneryId = window_scenery_tab_entries[tabIndex][itemIndex]; + if (sceneryId != -1) + window_scenery_selected_scenery_by_tab[tabIndex] = sceneryId; + } + + w->scrolls[0].v_top = (itemIndex / 9) * SCENERY_BUTTON_HEIGHT; + widget_scroll_update_thumbs(w, WIDX_SCENERY_LIST); +} + +/** +* +* rct2: 0x006E1E48 +*/ +static void window_scenery_resize() +{ + rct_window *w; + + window_get_register(w); + + if (w->width < w->min_width) { + w->width = w->min_width; + window_invalidate(w); + } + + if (w->width > w->max_width) { + w->width = w->max_width; + window_invalidate(w); + } + + if (w->height < w->min_height) { + w->height = w->min_height; + window_invalidate(w); + window_scenery_update_scroll(w); + } + + if (w->height > w->max_height) { + w->height = w->max_height; + window_invalidate(w); + window_scenery_update_scroll(w); + } +} + +/** +* +* rct2: 0x006E1A25 +*/ +static void window_scenery_mousedown(int widgetIndex, rct_window* w, rct_widget* widget) { + int eax; + + switch (widgetIndex) { + case WIDX_SCENERY_PRIMARY_COLOUR_BUTTON: + eax = (window_scenery_primary_colour << 8) + 0x80 + w->colours[1]; + RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF); + break; + case WIDX_SCENERY_SECONDARY_COLOUR_BUTTON: + eax = (window_scenery_secondary_colour << 8) + 0x80 + w->colours[1]; + RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF); + break; + case WIDX_SCENERY_TERTIARY_COLOUR_BUTTON: + eax = (window_scenery_tertiary_colour << 8) + 0x80 + w->colours[1]; + RCT2_CALLPROC_X(0x006ED43D, eax, 0, 0, widgetIndex, (int)w, (int)widget, 0xFFFFFFFF); + break; + } + + if (widgetIndex >= WIDX_SCENERY_TAB_1 && widgetIndex <= WIDX_SCENERY_TAB_20) { + window_scenery_active_tab_index = widgetIndex - WIDX_SCENERY_TAB_1; + window_invalidate(w); + RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000; + window_scenery_update_scroll(w); + } +} + +/** +* +* rct2: 0x006E1A54 +*/ +static void window_scenery_dropdown() { + rct_window* w; + short widgetIndex, dropdownIndex; + window_dropdown_get_registers(w, widgetIndex, dropdownIndex); + + if (dropdownIndex == -1) + return; + + if (widgetIndex == WIDX_SCENERY_PRIMARY_COLOUR_BUTTON) { + window_scenery_primary_colour = (uint8)dropdownIndex; + } + else if (widgetIndex == WIDX_SCENERY_SECONDARY_COLOUR_BUTTON) { + window_scenery_secondary_colour = (uint8)dropdownIndex; + } + else if (widgetIndex == WIDX_SCENERY_TERTIARY_COLOUR_BUTTON) { + window_scenery_tertiary_colour = (uint8)dropdownIndex; + } + + window_invalidate(w); +} + +/** +* +* rct2: 0x006E1B9F +*/ +static void window_scenery_event_07() { + rct_window *w; + + window_get_register(w); + + if (w->scenery.selected_scenery_id != -1) { + w->scenery.selected_scenery_id = -1; + } +} + +/** +* +* rct2: 0x006E1CD3 +*/ +static void window_scenery_update(rct_window *w) +{ + rct_window* other = window_find_from_point(RCT2_GLOBAL(0x0142406C, int), RCT2_GLOBAL(0x01424070, int)); + if (other == w) { + int window_x = RCT2_GLOBAL(0x0142406C, int) - w->x + 0x1A; + int window_y = RCT2_GLOBAL(0x01424070, int) - w->y; + + if (window_y < 0x2C || window_x <= w->width) { + int widgetIndex = window_find_widget_from_point(w, + RCT2_GLOBAL(0x0142406C, int), RCT2_GLOBAL(0x01424070, int)); + + if (widgetIndex >= 3) { + w->scenery.hover_counter++; + if (w->scenery.hover_counter < 8) { + if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) != INPUT_STATE_SCROLL_LEFT) { + w->min_width = WINDOW_SCENERY_WIDTH; + w->max_width = WINDOW_SCENERY_WIDTH; + w->min_height = WINDOW_SCENERY_HEIGHT; + w->max_height = WINDOW_SCENERY_HEIGHT; + } + } else { + int windowHeight = w->scrolls[0].v_bottom + 0x3E; + if (windowHeight > 0x1C6) + windowHeight = 0x1C6; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) < 0x258){ + if (windowHeight > 0x176) + windowHeight = 0x176; + } + + w->min_width = WINDOW_SCENERY_WIDTH; + w->max_width = WINDOW_SCENERY_WIDTH; + w->min_height = windowHeight; + w->max_height = windowHeight; + } + } + } + } else { + w->scenery.hover_counter = 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, sint8) != INPUT_STATE_SCROLL_LEFT) { + w->min_width = WINDOW_SCENERY_WIDTH; + w->max_width = WINDOW_SCENERY_WIDTH; + w->min_height = WINDOW_SCENERY_HEIGHT; + w->max_height = WINDOW_SCENERY_HEIGHT; + } + } + + gfx_invalidate_screen(); + + if (!window_scenery_is_scenery_tool_active()) + window_close(w); + + if (window_scenery_is_repaint_scenery_tool_on == 1) { // the repaint scenery tool is active + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 0x17; + } else { + uint16 tabIndex = window_scenery_active_tab_index; + sint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex]; + + if (tabSelectedSceneryId != -1) { + if (tabSelectedSceneryId > 0x400) { // banner + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = 0x18; + } else if (tabSelectedSceneryId > 0x300) { // large scenery + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = + g_largeSceneryEntries[tabSelectedSceneryId - 0x300]->large_scenery.tool_id; + } else if (tabSelectedSceneryId > 0x200) { // wall + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = + g_wallSceneryEntries[tabSelectedSceneryId - 0x200]->wall.tool_id; + } else if (tabSelectedSceneryId > 0x100) { // path bit + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = + g_pathBitSceneryEntries[tabSelectedSceneryId - 0x100]->path_bit.tool_id; + } else { // small scenery + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) = + g_smallSceneryEntries[tabSelectedSceneryId]->small_scenery.tool_id; + } + } + } +} + +/** +* +* rct2: 0x006E1A91 +*/ +void window_scenery_scrollgetsize() { + int scrollHeight = window_scenery_scrollgetsize_num(); + +#ifdef _MSC_VER + __asm mov edx, scrollHeight +#else + __asm__("mov edx, %[scrollHeight] " : [scrollHeight] "+m" (scrollHeight)); +#endif +} + +short get_scenery_id_by_cursor_pos(short x, short y) { + int tabSceneryIndex = x / SCENERY_BUTTON_WIDTH + (y / SCENERY_BUTTON_HEIGHT) * 9; + uint8 tabIndex = window_scenery_active_tab_index; + + int itemCounter = 0; + sint16 sceneryId = 0; + while (itemCounter <= tabSceneryIndex) { + sceneryId = window_scenery_tab_entries[tabIndex][itemCounter]; + if (sceneryId == -1) + return -1; + + itemCounter++; + } + + return sceneryId; +} + +/** +* +* rct2: 0x006E1C4A +*/ +void window_scenery_scrollmousedown() { + short x, y; + rct_window *w; + + window_scrollmouse_get_registers(w, x, y); + + short sceneryId = get_scenery_id_by_cursor_pos(x, y); + if (sceneryId == -1) + return; + + uint8 tabIndex = window_scenery_active_tab_index; + window_scenery_selected_scenery_by_tab[tabIndex] = sceneryId; + + window_scenery_is_repaint_scenery_tool_on &= 0xFE; + sound_play_panned(4, (w->width >> 1) + w->x); + w->scenery.hover_counter = -16; + RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000; + window_invalidate(w); +} + +/** +* +* rct2: 0x006E1BB8 +*/ +void window_scenery_scrollmouseover() { + short x, y; + rct_window *w; + + window_scrollmouse_get_registers(w, x, y); + short sceneryId = get_scenery_id_by_cursor_pos(x, y); + if (sceneryId != -1) { + w->scenery.selected_scenery_id = sceneryId; + window_invalidate(w); + } +} + +/** +* +* rct2: 0x006E1C05 +*/ +void window_scenery_tooltip() { + uint16 tooltipIndex; + + #ifdef _MSC_VER + __asm mov tooltipIndex, ax + #else + __asm__("mov %[tooltipIndex], ax " : [tooltipIndex] "+m" (tooltipIndex)); + #endif + + if (tooltipIndex == 0x18) + { + RCT2_GLOBAL(0x013CE952, uint16) = 3159; + } + else if (tooltipIndex >= 4 && tooltipIndex < 0x17) + { + RCT2_GLOBAL(0x013CE952, uint16) = g_scenerySetEntries[tooltipIndex - 4]->name; + } +} + +/** +* +* rct2: 0x006E118B +*/ +void window_scenery_invalidate() { + rct_window* w; + + window_get_register(w); + + uint16 tabIndex = window_scenery_active_tab_index; + uint32 titleStringId = 0x715; + if (tabIndex <= 0x13) { + titleStringId = g_scenerySetEntries[tabIndex]->name; + } + window_scenery_widgets[WIDX_SCENERY_TITLE].image = titleStringId; + + w->pressed_widgets = (((uint32)w->pressed_widgets & 0xFF00000F) | (1 << (tabIndex + 4))) & 0xBBFFFFFF; + + if (window_scenery_is_repaint_scenery_tool_on == 1) { + w->pressed_widgets |= (1 << WIDX_SCENERY_REPAINT_SCENERY_BUTTON); + } + + if (window_scenery_is_build_cluster_tool_on == 1) { + w->pressed_widgets |= (1 << WIDX_SCENERY_BUILD_CLUSTER_BUTTON); + } + + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_EMPTY; + window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_EMPTY; + + sint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex]; + if (tabSelectedSceneryId != -1) { + if (tabSelectedSceneryId < 0x100) { + if (!(window_scenery_is_repaint_scenery_tool_on & 1)) + window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WWT_FLATBTN; + + rct_scenery_entry* sceneryEntry = g_smallSceneryEntries[tabSelectedSceneryId]; + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG4) { + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_FLATBTN; + } + } + else if (tabSelectedSceneryId > 0x300) { + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_FLATBTN; + } + } + + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].image = + (window_scenery_primary_colour << 19) + 0x600013C3; + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].image = + (window_scenery_secondary_colour << 19) + 0x600013C3; + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].image = + (window_scenery_tertiary_colour << 19) + 0x600013C3; + + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_EMPTY; + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_EMPTY; + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_EMPTY; + + if (window_scenery_is_repaint_scenery_tool_on & 1) { // repaint colored scenery tool is on + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN; + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLORBTN; + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_COLORBTN; + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WWT_EMPTY; + } + else if (tabSelectedSceneryId != -1) { + rct_scenery_entry* sceneryEntry = NULL; + + if (tabSelectedSceneryId >= 0x400) { + sceneryEntry = g_bannerSceneryEntries[tabSelectedSceneryId - 0x400]; + + if (sceneryEntry->banner.flags & 1) + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN; + } + else if (tabSelectedSceneryId >= 0x300) { + sceneryEntry = g_largeSceneryEntries[tabSelectedSceneryId - 0x300]; + + if (sceneryEntry->large_scenery.flags & 1) + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN; + if (sceneryEntry->large_scenery.flags & 2) + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLORBTN; + } + else if (tabSelectedSceneryId >= 0x200) { + sceneryEntry = g_wallSceneryEntries[tabSelectedSceneryId - 0x200]; + if (sceneryEntry->wall.flags & (WALL_SCENERY_FLAG1 | WALL_SCENERY_FLAG2)) { + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN; + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) { + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLORBTN; + + if (sceneryEntry->wall.flags2 & WALL_SCENERY_FLAG1) + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_EMPTY; + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].type = WWT_COLORBTN; + } + } + } + else if (tabSelectedSceneryId < 0x100) { + sceneryEntry = g_smallSceneryEntries[tabSelectedSceneryId]; + + if (sceneryEntry->small_scenery.flags & (SMALL_SCENERY_HAS_PRIMARY_COLOUR | SMALL_SCENERY_FLAG10)) { + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].type = WWT_COLORBTN; + + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_HAS_SECONDARY_COLOUR) + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].type = WWT_COLORBTN; + } + } + } + + window_scenery_widgets[WIDX_SCENERY_BACKGROUND].right = w->width - 1; + window_scenery_widgets[WIDX_SCENERY_BACKGROUND].bottom = w->height - 1; + window_scenery_widgets[WIDX_SCENERY_TAB_CONTENT_PANEL].right = w->width - 1; + window_scenery_widgets[WIDX_SCENERY_TAB_CONTENT_PANEL].bottom = w->height - 1; + window_scenery_widgets[WIDX_SCENERY_TITLE].right = w->width - 2; + window_scenery_widgets[WIDX_SCENERY_CLOSE].left = w->width - 13; + window_scenery_widgets[WIDX_SCENERY_CLOSE].right = window_scenery_widgets[WIDX_SCENERY_CLOSE].left + 10; + window_scenery_widgets[WIDX_SCENERY_LIST].right = w->width - 0x1A; + window_scenery_widgets[WIDX_SCENERY_LIST].bottom = w->height - 0x0E; + + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].left = w->width - 25; + window_scenery_widgets[WIDX_SCENERY_REPAINT_SCENERY_BUTTON].left = w->width - 25; + window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].left = w->width - 25; + window_scenery_widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].right = w->width - 2; + window_scenery_widgets[WIDX_SCENERY_REPAINT_SCENERY_BUTTON].right = w->width - 2; + window_scenery_widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].right = w->width - 2; + + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].left = w->width - 19; + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].left = w->width - 19; + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].left = w->width - 19; + window_scenery_widgets[WIDX_SCENERY_PRIMARY_COLOUR_BUTTON].right = w->width - 8; + window_scenery_widgets[WIDX_SCENERY_SECONDARY_COLOUR_BUTTON].right = w->width - 8; + window_scenery_widgets[WIDX_SCENERY_TERTIARY_COLOUR_BUTTON].right = w->width - 8; +} + +/** +* +* rct2: 0x006E1462 +*/ +void window_scenery_paint() { + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + window_draw_widgets(w, dpi); + + uint16 tabIndex = window_scenery_active_tab_index; + uint16 selectedWidgetId = tabIndex + 4; + uint32 imageId = ((w->colours[1] << 19) | window_scenery_widgets[selectedWidgetId].image) + 1ul; + + gfx_draw_sprite(dpi, imageId, + w->x + window_scenery_widgets[selectedWidgetId].left, + w->y + window_scenery_widgets[selectedWidgetId].top, + selectedWidgetId); + + sint16 selectedSceneryEntryId = w->scenery.selected_scenery_id; + if (selectedSceneryEntryId == -1) { + if (window_scenery_is_repaint_scenery_tool_on & 1) // repaint colored scenery tool is on + return; + + selectedSceneryEntryId = window_scenery_selected_scenery_by_tab[tabIndex]; + + if (selectedSceneryEntryId == -1) + return; + } + + uint32 price = 0; + + rct_scenery_entry* sceneryEntry = NULL; + if (selectedSceneryEntryId >= 0x400) { + sceneryEntry = g_bannerSceneryEntries[selectedSceneryEntryId - 0x400]; + price = sceneryEntry->banner.price; + } else if (selectedSceneryEntryId >= 0x300) { + sceneryEntry = g_largeSceneryEntries[selectedSceneryEntryId - 0x300]; + price = sceneryEntry->large_scenery.price * 10; + } else if (selectedSceneryEntryId >= 0x200) { + sceneryEntry = g_wallSceneryEntries[selectedSceneryEntryId - 0x200]; + price = sceneryEntry->wall.price; + } else if (selectedSceneryEntryId >= 0x100) { + sceneryEntry = g_pathBitSceneryEntries[selectedSceneryEntryId - 0x100]; + price = sceneryEntry->path_bit.price; + } else { + sceneryEntry = g_smallSceneryEntries[selectedSceneryEntryId]; + price = sceneryEntry->small_scenery.price * 10; + } + + if (w->scenery.selected_scenery_id == -1 && RCT2_GLOBAL(0x00F64EB4, uint32) != 0x80000000) { + price = RCT2_GLOBAL(0x00F64EB4, uint32); + } + + RCT2_GLOBAL(0x013CE952, uint32) = price; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)) { + // -14 + gfx_draw_string_right(dpi, STR_COST_LABEL, (void*)0x013CE952, 0, + w->x + w->width - 0x1A, w->y + w->height - 13); + } + + RCT2_GLOBAL(0x013CE952, uint16) = sceneryEntry->name; + gfx_draw_string_left_clipped(dpi, 0x4A7, (void*)0x013CE952, 0, + w->x + 3, w->y + w->height - 13, w->width - 19); +} + +/** +* +* rct2: 0x006E15ED +*/ +void window_scenery_scrollpaint() +{ + rct_window *w; + rct_drawpixelinfo *dpi; + + window_paint_get_registers(w, dpi); + + gfx_clear(dpi, ((char*)0x0141FC48)[w->colours[1] * 8] * 0x1010101); + + uint8 tabIndex = window_scenery_active_tab_index; + + int sceneryTabItemIndex = 0; + sint16 currentSceneryGlobalId = -1; + sint16 left = 0, top = 0; + + while ((currentSceneryGlobalId = window_scenery_tab_entries[tabIndex][sceneryTabItemIndex]) != -1) { + uint16 tabSelectedSceneryId = window_scenery_selected_scenery_by_tab[tabIndex]; + + if (window_scenery_is_repaint_scenery_tool_on == 1) + { + if (w->scenery.selected_scenery_id == currentSceneryGlobalId) { + gfx_fill_rect_inset(dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, + top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1], 0x80); + } + } else { + if (tabSelectedSceneryId == currentSceneryGlobalId) { + gfx_fill_rect_inset(dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, + top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1], 0xA0); + } + else if (w->scenery.selected_scenery_id == currentSceneryGlobalId) { + gfx_fill_rect_inset(dpi, left, top, left + SCENERY_BUTTON_WIDTH - 1, + top + SCENERY_BUTTON_HEIGHT - 1, w->colours[1], 0x80); + } + } + + rct_scenery_entry* sceneryEntry; + if (currentSceneryGlobalId >= 0x400) { + sceneryEntry = g_bannerSceneryEntries[currentSceneryGlobalId - 0x400]; + uint32 imageId = sceneryEntry->image + window_scenery_rotation * 2; + imageId |= (window_scenery_primary_colour << 19) | 0x20000000; + + gfx_draw_sprite(dpi, imageId, left + 0x21, top + 0x28, w->colours[1]); + gfx_draw_sprite(dpi, imageId + 1, left + 0x21, top + 0x28, w->colours[1]); + } + else if (currentSceneryGlobalId >= 0x300) { + sceneryEntry = g_largeSceneryEntries[currentSceneryGlobalId - 0x300]; + uint32 imageId = sceneryEntry->image + window_scenery_rotation; + imageId |= (window_scenery_primary_colour << 19) | 0x20000000; + imageId |= (window_scenery_secondary_colour << 24) | 0x80000000; + + gfx_draw_sprite(dpi, imageId, left + 0x21, top, w->colours[1]); + } + else if (currentSceneryGlobalId >= 0x200) { + sceneryEntry = g_wallSceneryEntries[currentSceneryGlobalId - 0x200]; + rct_drawpixelinfo* clipdpi = clip_drawpixelinfo(dpi, left + 1, 64, top + 1, 78); + if (clipdpi != NULL) { + uint32 imageId = sceneryEntry->image; + uint8 tertiaryColour = w->colours[1]; + + if (sceneryEntry->wall.flags & WALL_SCENERY_FLAG2) { + imageId |= (window_scenery_primary_colour << 19) | 0x20000000; + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) { + imageId |= (window_scenery_secondary_colour << 24) | 0x80000000; + } + } + else { + imageId |= (window_scenery_primary_colour << 19) | 0x20000000; + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) { + imageId |= (window_scenery_secondary_colour << 24) | 0x80000000; + + if (sceneryEntry->wall.flags & WALL_SCENERY_HAS_TERNARY_COLOUR) { + imageId &= 0xDFFFFFFF; + tertiaryColour = window_scenery_tertiary_colour; + } + + } + } + + gfx_draw_sprite(clipdpi, imageId, 0x2F, (sceneryEntry->wall.height * 2) + 0x32, + tertiaryColour); + rct2_free(clipdpi); + } + } + else if (currentSceneryGlobalId >= 0x100) { + sceneryEntry = g_pathBitSceneryEntries[currentSceneryGlobalId - 0x100]; + uint32 imageId = sceneryEntry->image; + + gfx_draw_sprite(dpi, imageId, left + 0x0B, top + 0x10, w->colours[1]); + } else { + sceneryEntry = g_smallSceneryEntries[currentSceneryGlobalId]; + rct_drawpixelinfo* clipdpi = clip_drawpixelinfo(dpi, left + 1, SCENERY_BUTTON_WIDTH - 2, top + 1, SCENERY_BUTTON_HEIGHT - 2); + if (clipdpi != NULL) { + + uint32 imageId = sceneryEntry->image + window_scenery_rotation; + + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_HAS_PRIMARY_COLOUR) { + imageId |= (window_scenery_primary_colour << 19) | 0x20000000; + + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_HAS_SECONDARY_COLOUR) { + imageId |= (window_scenery_secondary_colour << 24) | 0x80000000; + } + } + + uint16 spriteTop = (sceneryEntry->small_scenery.height / 4) + 0x2B; + + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG1 && + sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG2) { + spriteTop -= 0x0C; + } + + gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]); + + if (sceneryEntry->small_scenery.flags & 0x200) { + imageId = ((sceneryEntry->image + window_scenery_rotation) + 0x40000004) + + ((window_scenery_primary_colour + 0x70) << 19); + + gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]); + } + + if (sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG8) { + imageId = (sceneryEntry->image + window_scenery_rotation) + 4; + gfx_draw_sprite(clipdpi, imageId, 0x20, spriteTop, w->colours[1]); + } + + rct2_free(clipdpi); + } + } + + left += SCENERY_BUTTON_WIDTH; + if (left >= 594) { + top += SCENERY_BUTTON_HEIGHT; + left = 0; + } + sceneryTabItemIndex++; + } +} \ No newline at end of file diff --git a/src/window_scenery.h b/src/window_scenery.h new file mode 100644 index 0000000000..f9868e5709 --- /dev/null +++ b/src/window_scenery.h @@ -0,0 +1,39 @@ +/***************************************************************************** +* Copyright (c) 2014 Dániel Tar +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* This file is part of OpenRCT2. +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*****************************************************************************/ + +#ifndef _WINDOW_SCENERY_H_ +#define _WINDOW_SCENERY_H_ + +#define WINDOW_SCENERY_WIDTH 0x27A +#define WINDOW_SCENERY_HEIGHT 0x8E +#define SCENERY_BUTTON_WIDTH 66 +#define SCENERY_BUTTON_HEIGHT 80 +#define SCENERY_ENTRIES_BY_TAB 128 + +#define window_scenery_active_tab_index RCT2_GLOBAL(0x00F64EDC, uint8) +#define window_scenery_selected_scenery_by_tab RCT2_ADDRESS(0x00F64EDD, sint16) +#define window_scenery_is_build_cluster_tool_on RCT2_GLOBAL(0x00F64F1A, uint8) +#define window_scenery_is_repaint_scenery_tool_on RCT2_GLOBAL(0x00F64F19, uint8) +#define window_scenery_rotation RCT2_GLOBAL(0x00F64F05, uint8) +#define window_scenery_primary_colour RCT2_GLOBAL(0x00F64F06, uint8) +#define window_scenery_secondary_colour RCT2_GLOBAL(0x00F64F07, uint8) +#define window_scenery_tertiary_colour RCT2_GLOBAL(0x00F64F08, uint8) + +#endif \ No newline at end of file diff --git a/src/window_staff.c b/src/window_staff.c index 217b58dc12..eed1574ee7 100644 --- a/src/window_staff.c +++ b/src/window_staff.c @@ -1,5 +1,5 @@ -/***************************************************************************** -* Copyright (c) 2014 Maciek Baron, Daniel Tar +/***************************************************************************** +* Copyright (c) 2014 Maciek Baron, Dániel Tar * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -171,11 +171,7 @@ void window_staff_open() window->colours[2] = 4; } -void window_staff_cancel_tools() { - rct_window *w; - - window_get_register(w); - +void window_staff_cancel_tools(rct_window *w) { int toolWindowClassification = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass); int toolWindowNumber = RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber); if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) @@ -264,7 +260,7 @@ static void window_staff_resize() * * rct2: 0x006BD971 */ -static void window_staff_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) +static void window_staff_mousedown(int widgetIndex, rct_window* w, rct_widget* widget) { short newSelectedTab; int eax;