diff --git a/src/addresses.h b/src/addresses.h index 990278eadc..56912ac3e9 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -162,6 +162,9 @@ #define RCT2_ADDRESS_G1_ELEMENTS 0x009EBD28 #define RCT2_ADDRESS_PATH_TYPES 0x009ADA14 + +#define RCT2_ADDRESS_MAP_IMAGE_DATA 0x00F1AD68 + #define RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS 0x00F3EF92 #define RCT2_ADDRESS_PROVISIONAL_PATH_X 0x00F3EF94 #define RCT2_ADDRESS_PROVISIONAL_PATH_Y 0x00F3EF96 @@ -175,7 +178,7 @@ #define RCT2_ADDRESS_CONSTRUCT_PATH_FROM_Z 0x00F3EF8E #define RCT2_ADDRESS_CONSTRUCT_PATH_DIRECTION 0x00F3EF90 -#define RCT2_ADDRESS_MAP_IMAGE_DATA 0x00F1AD68 +#define RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX 0x00F43908 #define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8 #define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA diff --git a/src/game.c b/src/game.c index 2d2dc996eb..fee22669de 100644 --- a/src/game.c +++ b/src/game.c @@ -2089,6 +2089,96 @@ int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int eb return 0x80000000; } +/** +* +* rct2: 0x006677F2 with pointers as arguments +* +* @param flags (ebx) +* @param command (esi) +*/ +int game_do_command_p(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) +{ + int cost, flags, insufficientFunds; + int original_ebx, original_edx, original_esi, original_edi, original_ebp; + + original_ebx = *ebx; + original_edx = *edx; + original_esi = *esi; + original_edi = *edi; + original_ebp = *ebp; + + flags = *ebx; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0xFFFF; + + // Increment nest count + RCT2_GLOBAL(0x009A8C28, uint8)++; + + *ebx &= ~1; + + // Primary command + RCT2_CALLFUNC_X(game_do_command_table[*esi], eax, ebx, ecx, edx, esi, edi, ebp); + cost = *ebx; + + if (cost != 0x80000000) { + // Check funds + insufficientFunds = 0; + if (RCT2_GLOBAL(0x009A8C28, uint8) == 1 && !(flags & 4) && !(flags & 0x20) && cost != 0) + insufficientFunds = game_check_affordability(cost); + + if (insufficientFunds != 0x80000000) { + *ebx = original_ebx; + *edx = original_edx; + *esi = original_esi; + *edi = original_edi; + *ebp = original_ebp; + + if (!(flags & 1)) { + // Decrement nest count + RCT2_GLOBAL(0x009A8C28, uint8)--; + return cost; + } + + // Secondary command + RCT2_CALLFUNC_X(game_do_command_table[*esi], eax, ebx, ecx, edx, esi, edi, ebp); + *edx = *ebx; + + if (*edx != 0x80000000 && *edx < cost) + cost = *edx; + + // Decrement nest count + RCT2_GLOBAL(0x009A8C28, uint8)--; + if (RCT2_GLOBAL(0x009A8C28, uint8) != 0) + return cost; + + // + 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) + RCT2_CALLPROC_X(0x0069C5D0, 0, cost, 0, 0, 0, 0, 0); + } + } + + return cost; + } + } + + // Error occured + + // Decrement nest count + RCT2_GLOBAL(0x009A8C28, uint8)--; + + // Show error window + if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & 1) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & 8)) + window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16)); + + return 0x80000000; +} + + /** * * rct2: 0x00667C15 @@ -2493,7 +2583,7 @@ static uint32 game_do_command_table[58] = { 0x00666A63, 0x006CD8CE, 0x00669E30, - 0x00669E55, + 0x00669E55, // updating the color of staff after setting a new one 0x006E519A, 0x006E5597, 0x006B893C, diff --git a/src/game.h b/src/game.h index 57e4bc2166..b0f7d86a5b 100644 --- a/src/game.h +++ b/src/game.h @@ -29,6 +29,7 @@ void update_rain_animation(); void update_water_animation(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); +int game_do_command_p(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_increase_game_speed(); void game_reduce_game_speed(); diff --git a/src/gfx.c b/src/gfx.c index 63acdd4d5f..272de4cdb0 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -2260,3 +2260,66 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in gLastDrawStringX = max_x; gLastDrawStringY = max_y; } + +/* +* +* rct2: 0x006EE53B +* left (ax) +* width (bx) +* top (cx) +* height (dx) +* drawpixelinfo (edi) +*/ +rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height) +{ + rct_drawpixelinfo* newDrawPixelInfo = rct2_malloc(sizeof(rct_drawpixelinfo)); + + int right = left + width; + int bottom = top + height; + + newDrawPixelInfo->bits = dpi->bits; + newDrawPixelInfo->x = dpi->x; + newDrawPixelInfo->y = dpi->y; + newDrawPixelInfo->width = dpi->width; + newDrawPixelInfo->height = dpi->height; + newDrawPixelInfo->pitch = dpi->pitch; + newDrawPixelInfo->zoom_level = 0; + newDrawPixelInfo->var_0F = dpi->var_0F; + + if (left > newDrawPixelInfo->x) { + uint16 newWidth = left - newDrawPixelInfo->x; + newDrawPixelInfo->width -= newWidth; + newDrawPixelInfo->x = left; + newDrawPixelInfo->pitch += newWidth; + newDrawPixelInfo->bits += newWidth; + } + + int stickOutWidth = newDrawPixelInfo->x + newDrawPixelInfo->width - right; + if (stickOutWidth < 0) { + newDrawPixelInfo->width -= stickOutWidth; + newDrawPixelInfo->pitch += stickOutWidth; + } + + if (top > newDrawPixelInfo->y) { + uint16 newHeight = top - newDrawPixelInfo->y; + newDrawPixelInfo->height = newHeight; + newDrawPixelInfo->y = top; + int bitsPlus = (newDrawPixelInfo->pitch + newDrawPixelInfo->width) * newHeight; + newDrawPixelInfo->bits += bitsPlus; + } + + int bp = newDrawPixelInfo->y + newDrawPixelInfo->height - bottom; + if (bp < 0) { + newDrawPixelInfo->height -= bp; + } + + if (newDrawPixelInfo->width > 0 && newDrawPixelInfo->height > 0) { + newDrawPixelInfo->x -= left; + newDrawPixelInfo->y -= top; + + return newDrawPixelInfo; + } + + rct2_free(newDrawPixelInfo); + return NULL; +} \ No newline at end of file diff --git a/src/gfx.h b/src/gfx.h index a259a76bbf..f20d37e428 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -92,4 +92,6 @@ void gfx_draw_all_dirty_blocks(); void gfx_redraw_screen_rect(short left, short top, short right, short bottom); void gfx_invalidate_screen(); +rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height); + #endif diff --git a/src/peep.c b/src/peep.c index 78f46ccd99..1a2cc8d739 100644 --- a/src/peep.c +++ b/src/peep.c @@ -408,4 +408,136 @@ rct_peep *peep_generate(int x, int y, int z) edx = z; RCT2_CALLFUNC_X(0x0069A05D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); return (rct_peep*)esi; +} + +/** +* rct2: 0x00698B0D +* peep.sprite_index (eax) +* thought.type (ebx) +* argument_1 (ecx & ebx) +* argument_2 (edx) +*/ +void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argument_2){ + rct_ride ride; + + switch (peep->state){ + case 0: + *argument_1 = peep->var_71 == 0xB ? STR_DROWNING : STR_WALKING; + *argument_2 = 0; + break; + case 1: + *argument_1 = STR_WALKING; + *argument_2 = 0; + break; + case PEEP_STATE_ON_RIDE: + case PEEP_STATE_LEAVING_RIDE: + case PEEP_STATE_ENTERING_RIDE: + *argument_1 = STR_ON_RIDE; + ride = g_ride_list[peep->current_ride]; + if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride.type * 8, uint32) & 0x400000){ + *argument_1 = STR_IN_RIDE; + } + *argument_1 |= (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_BUYING: + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_AT_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_WALKING: + case 0x14: + if (peep->var_C5 != 0xFF){ + ride = g_ride_list[peep->var_C5]; + *argument_1 = STR_HEADING_FOR | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + } + else{ + *argument_1 = peep->flags & PEEP_FLAGS_LEAVING_PARK ? STR_LEAVING_PARK : STR_WALKING; + *argument_2 = 0; + } + break; + case PEEP_STATE_QUEUING_FRONT: + case PEEP_STATE_QUEUING: + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_QUEUING_FOR | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_SITTING: + *argument_1 = STR_SITTING; + *argument_2 = 0; + break; + case PEEP_STATE_WATCHING: + if (peep->current_ride != 0xFF){ + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + if (peep->current_seat & 0x1) + *argument_1 = STR_WATCHING_CONSTRUCTION_OF | (ride.var_04A << 16); + else + *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); + } + else{ + *argument_1 = peep->current_seat & 0x1 ? STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED : STR_LOOKING_AT_SCENERY; + *argument_2 = 0; + } + break; + case PEEP_STATE_PICKED: + *argument_1 = STR_SELECT_LOCATION; + *argument_2 = 0; + break; + case PEEP_STATE_PATROLLING: + case PEEP_STATE_ENTERING_PARK: + case PEEP_STATE_LEAVING_PARK: + *argument_1 = STR_WALKING; + *argument_2 = 0; + break; + case PEEP_STATE_MOWING: + *argument_1 = STR_MOWING_GRASS; + *argument_2 = 0; + break; + case PEEP_STATE_SWEEPING: + *argument_1 = STR_SWEEPING_FOOTPATH; + *argument_2 = 0; + break; + case PEEP_STATE_WATERING: + *argument_1 = STR_WATERING_GARDENS; + *argument_2 = 0; + break; + case PEEP_STATE_EMPTYING_BIN: + *argument_1 = STR_EMPTYING_LITTER_BIN; + *argument_2 = 0; + break; + case PEEP_STATE_ANSWERING: + if (peep->pad_2C == 0){ + *argument_1 = STR_WALKING; + *argument_2 = 0; + } + else if (peep->pad_2C == 1){ + *argument_1 = STR_ANSWERING_RADIO_CALL; + *argument_2 = 0; + } + else{ + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + } + break; + case PEEP_STATE_FIXING: + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_FIXING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_HEADING_TO_INSPECTION: + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_HEADING_TO_RIDE_FOR_INSPECTION | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + case PEEP_STATE_INSPECTING: + ride = g_ride_list[peep->current_ride]; + *argument_1 = STR_INSPECTING_RIDE | (ride.var_04A << 16); + *argument_2 = ride.var_04C; + break; + } + } \ No newline at end of file diff --git a/src/peep.h b/src/peep.h index f71907cd36..dab4b3f66f 100644 --- a/src/peep.h +++ b/src/peep.h @@ -444,5 +444,6 @@ void peep_problem_warnings_update(); void peep_update_crowd_noise(); void peep_applause(); rct_peep *peep_generate(int x, int y, int z); +void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argument_2); #endif diff --git a/src/string_ids.h b/src/string_ids.h index 0fc81a9c64..475cc7a1ea 100644 --- a/src/string_ids.h +++ b/src/string_ids.h @@ -275,6 +275,7 @@ enum { STR_SLOPE_UP_TIP = 1188, STR_CONSTRUCT_THE_SELECTED_FOOTPATH_SECTION_TIP = 1189, STR_REMOVE_PREVIOUS_FOOTPATH_SECTION_TIP = 1190, + STR_COST = 1191, STR_CLOSED = 1194, STR_TEST_RUN = 1195, @@ -320,6 +321,8 @@ enum { STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED = 1448, STR_GUESTS = 1463, + + STR_STAFF = 1468, STR_THOUGHT_START = 1480, @@ -329,6 +332,12 @@ enum { STR_GUESTS_TIP = 1693, STR_STAFF_TIP = 1694, + STR_HIRE_HANDYMAN = 1700, + STR_HIRE_MECHANIC = 1700, + STR_HIRE_SECURITY_GUARD = 1700, + STR_HIRE_ENTERTAINER = 1700, + STR_CANT_HIRE_NEW_STAFF = 1704, + STR_CANT_RENAME_PARK = 1717, STR_PARK_NAME = 1718, STR_ENTER_PARK_NAME = 1719, @@ -348,6 +357,8 @@ enum { STR_ON = 1776, STR_MUSIC = 1777, + STR_STAFF_LIST_COLORBTN = 1790, + STR_UNIFORM_COLOR = 1791, STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL = 1792, STR_HEADING_TO_RIDE_FOR_INSPECTION = 1793, STR_FIXING_RIDE = 1794, @@ -384,6 +395,16 @@ enum { STR_RIDE_LIST_INFORMATION_TYPE_TIP = 1844, STR_NUM_GUESTS = 1846, + STR_HANDYMAN_PLURAL = 1859, + STR_MECHANIC_PLURAL = 1860, + STR_SECURITY_GUARD_PLURAL = 1861, + STR_ENTERTAINER_PLURAL = 1862, + STR_HANDYMAN_SINGULAR = 1863, + STR_MECHANIC_SINGULAR = 1864, + STR_SECURITY_GUARD_SINGULAR = 1865, + STR_ENTERTAINER_SINGULAR = 1866, + STR_STAFF_LIST_COUNTER = 1867, + STR_INSPECTING_RIDE = 1886, STR_BUILD_RIDE_TIP = 1895, @@ -395,6 +416,8 @@ enum { STR_SHOW_SUBJECT_TIP = 1937, + STR_SHOW_PATROL_AREA_TIP = 1947, + STR_STAFF_LIST_DROPDOWNBUTTON_TIP = 1948, STR_FINANCIAL_SUMMARY = 1949, STR_FINANCIAL_GRAPH = 1950, STR_PARK_VALUE_GRAPH = 1951, @@ -407,6 +430,11 @@ enum { STR_ITEM2_START = 2090, STR_ITEM2_SINGULAR_START = 2134, + STR_STAFF_HANDYMEN_TAB_TIP = 2210, + STR_STAFF_MECHANICS_TAB_TIP = 2211, + STR_STAFF_SECURITY_TAB_TIP = 2212, + STR_STAFF_ENTERTAINERS_TAB_TIP = 2213, + STR_CELSIUS_VALUE = 2216, STR_FAHRENHEIT_VALUE = 2217, @@ -576,6 +604,7 @@ enum { STR_MAP = 2802, STR_SHOW_GUESTS_ON_MAP_TIP = 2803, + STR_SHOW_STAFF_ON_MAP_TIP = 2803, STR_SHOW_MAP_TIP = 2805, STR_PEEPS_DISGUSTED_BY_PATHS = 2806, diff --git a/src/window.h b/src/window.h index b1e804387c..2bf0c07ada 100644 --- a/src/window.h +++ b/src/window.h @@ -359,10 +359,12 @@ void window_scenarioselect_open(); void window_clear_scenery_open(); void window_land_open(); void window_water_open(); +void window_staff_open(); void window_guest_list_open(); void window_map_open(); void window_options_open(); void window_peep_open(rct_peep* peep); +void window_staff_peep_open(rct_peep* peep); void window_park_awards_open(); void window_park_entrance_open(); void window_park_guests_open(); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index 8a78975390..39c1c476f7 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -247,7 +247,8 @@ static void window_game_top_toolbar_mouseup() window_park_entrance_open(); break; case WIDX_STAFF: - RCT2_CALLPROC_EBPSAFE(0x006BD3CC); + window_staff_open(); + //RCT2_CALLPROC_EBPSAFE(0x006BD3CC); break; case WIDX_GUESTS: window_guest_list_open(); diff --git a/src/window_guest_list.c b/src/window_guest_list.c index fa8a4a0dd1..d42b56e9ba 100644 --- a/src/window_guest_list.c +++ b/src/window_guest_list.c @@ -136,7 +136,6 @@ static int get_guest_face_sprite_small(rct_peep *peep); static int get_guest_face_sprite_large(rct_peep *peep); static void get_arguments_from_peep(rct_peep *peep, uint32 *argument_1, uint32* argument_2); void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, uint32* argument_2); -void get_arguments_from_action(rct_peep* peep, uint32* argument_1, uint32* argument_2); /** * * rct2: 0x006992E3 @@ -856,139 +855,6 @@ void get_arguments_from_thought(rct_peep_thought thought, uint32* argument_1, ui *argument_2 = *((uint32*)(esi+2)); //Always 0 apart from on rides? } -/** -* rct2: 0x00698B0D -* peep.sprite_index (eax) -* thought.type (ebx) -* argument_1 (ecx & ebx) -* argument_2 (edx) -*/ -void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argument_2){ - rct_ride ride; - - switch (peep->state){ - case 0: - *argument_1 = peep->var_71 == 0xB ? STR_DROWNING : STR_WALKING; - *argument_2 = 0; - break; - case 1: - *argument_1 = STR_WALKING; - *argument_2 = 0; - break; - case PEEP_STATE_ON_RIDE: - case PEEP_STATE_LEAVING_RIDE: - case PEEP_STATE_ENTERING_RIDE: - *argument_1 = STR_ON_RIDE; - ride = g_ride_list[peep->current_ride]; - if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + ride.type*8, uint32)& 0x400000){ - *argument_1 = STR_IN_RIDE; - } - *argument_1 |= (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - case PEEP_STATE_BUYING: - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_AT_RIDE | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - case PEEP_STATE_WALKING: - case 0x14: - if (peep->var_C5 != 0xFF){ - ride = g_ride_list[peep->var_C5]; - *argument_1 = STR_HEADING_FOR | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - } - else{ - *argument_1 = peep->flags & PEEP_FLAGS_LEAVING_PARK ? STR_LEAVING_PARK : STR_WALKING; - *argument_2 = 0; - } - break; - case PEEP_STATE_QUEUING_FRONT: - case PEEP_STATE_QUEUING: - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_QUEUING_FOR | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - case PEEP_STATE_SITTING: - *argument_1 = STR_SITTING; - *argument_2 = 0; - break; - case PEEP_STATE_WATCHING: - if (peep->current_ride != 0xFF){ - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - if (peep->current_seat & 0x1) - *argument_1 = STR_WATCHING_CONSTRUCTION_OF | (ride.var_04A << 16); - else - *argument_1 = STR_WATCHING_RIDE | (ride.var_04A << 16); - } - else{ - *argument_1 = peep->current_seat & 0x1 ? STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED : STR_LOOKING_AT_SCENERY; - *argument_2 = 0; - } - break; - case PEEP_STATE_PICKED: - *argument_1 = STR_SELECT_LOCATION; - *argument_2 = 0; - break; - case PEEP_STATE_PATROLLING: - case PEEP_STATE_ENTERING_PARK: - case PEEP_STATE_LEAVING_PARK: - *argument_1 = STR_WALKING; - *argument_2 = 0; - break; - case PEEP_STATE_MOWING: - *argument_1 = STR_MOWING_GRASS; - *argument_2 = 0; - break; - case PEEP_STATE_SWEEPING: - *argument_1 = STR_SWEEPING_FOOTPATH; - *argument_2 = 0; - break; - case PEEP_STATE_WATERING: - *argument_1 = STR_WATERING_GARDENS; - *argument_2 = 0; - break; - case PEEP_STATE_EMPTYING_BIN: - *argument_1 = STR_EMPTYING_LITTER_BIN; - *argument_2 = 0; - break; - case PEEP_STATE_ANSWERING: - if (peep->pad_2C == 0){ - *argument_1 = STR_WALKING; - *argument_2 = 0; - } - else if (peep->pad_2C == 1){ - *argument_1 = STR_ANSWERING_RADIO_CALL; - *argument_2 = 0; - } - else{ - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_RESPONDING_TO_RIDE_BREAKDOWN_CALL | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - } - break; - case PEEP_STATE_FIXING: - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_FIXING_RIDE | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - case PEEP_STATE_HEADING_TO_INSPECTION: - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_HEADING_TO_RIDE_FOR_INSPECTION | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - case PEEP_STATE_INSPECTING: - ride = g_ride_list[peep->current_ride]; - *argument_1 = STR_INSPECTING_RIDE | (ride.var_04A << 16); - *argument_2 = ride.var_04C; - break; - } - -} - - /** * rct2:0x0069B7EA * Calculates a hash value (arguments) for comparing peep actions/thoughts diff --git a/src/window_park.c b/src/window_park.c index b26b6da656..add958085a 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -649,8 +649,7 @@ static void window_park_entrance_close() #else __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); #endif - - + if (RCT2_GLOBAL(0x009DE518, uint32) & (1 << 3)) if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) tool_cancel(); diff --git a/src/window_peep.c b/src/window_peep.c index fd589e8f09..b3173c7bd5 100644 --- a/src/window_peep.c +++ b/src/window_peep.c @@ -173,3 +173,35 @@ void window_peep_open(rct_peep* peep){ window_init_scroll_widgets(window); RCT2_CALLPROC_X(0x0069883C, 0, 0, 0, 0, (int)window, 0, 0); } + +/** +* +* rct2: 0x006BEE98 +*/ +void window_staff_peep_open(rct_peep* peep) +{ + rct_window* w = window_bring_to_front_by_id(WC_PEEP, peep->sprite_index); + if (!w) { + int eax, ebx, ecx, edx, esi, edi, ebp; + + eax = peep->sprite_index; + ecx = WC_PEEP; + edx = peep->sprite_index; + + RCT2_CALLFUNC_X(0x006BEF1B, &eax, &ebx, &ecx, &edx, &esi, &edi, (int*)peep); + w = (rct_window*)esi; + } + + int PEEP_BACKGROUND_IDX = 0; + w->widgets = RCT2_GLOBAL(0x992998, rct_widget*); + w->enabled_widgets = RCT2_GLOBAL(0x9929B0, uint32); + w->var_020 = RCT2_GLOBAL(0x9929BC, uint32); + w->event_handlers = RCT2_GLOBAL(0x9929A4, uint32); + w->pressed_widgets = 0; + RCT2_CALLPROC_X(0x006BED21, 0, 0, 0, 0, (int)w, 0, 0); + window_init_scroll_widgets(w); + RCT2_CALLPROC_X(0x006BEDA3, 0, 0, 0, 0, (int)w, 0, 0); + if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED) { + RCT2_CALLPROC_X(w->event_handlers[1], 0, 0, 0, 10, (int)w, 0, 0); + } +} \ No newline at end of file diff --git a/src/window_staff.c b/src/window_staff.c index 3652084e9d..d6e08f5fd4 100644 --- a/src/window_staff.c +++ b/src/window_staff.c @@ -1,5 +1,5 @@ /***************************************************************************** -* Copyright (c) 2014 Maciek Baron +* Copyright (c) 2014 Maciek Baron, Daniel Tar * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. @@ -21,19 +21,752 @@ #include #include "addresses.h" #include "game.h" +#include "gfx.h" +#include "peep.h" +#include "sprite.h" +#include "string_ids.h" +#include "viewport.h" +#include "widget.h" #include "window.h" enum { - WINDOW_STAFF_LIST_TAB_HANDYMEN, - WINDOW_STAFF_LIST_TAB_MECHANICS, - WINDOW_STAFF_LIST_TAB_SECURITY, - WINDOW_STAFF_LIST_TAB_ENTERTAINERS + WINDOW_STAFF_TAB_HANDYMEN, + WINDOW_STAFF_TAB_MECHANICS, + WINDOW_STAFF_TAB_SECURITY, + WINDOW_STAFF_TAB_ENTERTAINERS } WINDOW_STAFF_LIST_TAB; +static void window_staff_emptysub() { } +static void window_staff_close(); +static void window_staff_mouseup(); +static void window_staff_resize(); +static void window_staff_mousedown(int widgetIndex, rct_window*w, rct_widget* widget); +static void window_staff_dropdown(); +static void window_staff_update(rct_window *w); +static void window_staff_tooldown(); +static void window_staff_toolabort(); +static void window_staff_scrollgetsize(); +static void window_staff_scrollmousedown(); +static void window_staff_scrollmouseover(); +static void window_staff_tooltip(); +static void window_staff_invalidate(); +static void window_staff_paint(); +static void window_staff_scrollpaint(); + +static void* window_staff_events[] = { + window_staff_close, //(void*)0x006BD9B1, + window_staff_mouseup, //(void*)0x006BD94C, + window_staff_resize, //(void*)0x006BDD5D, + window_staff_mousedown, //(void*)0x006BD971, + window_staff_dropdown, //(void*)0x006BD9A6, + window_staff_emptysub, + window_staff_update, // (void*)0x006BDCEA, + window_staff_emptysub, + window_staff_emptysub, + window_staff_emptysub, + (void*)0x006BD990, // window_staff_tooldown + window_staff_emptysub, + window_staff_emptysub, + window_staff_toolabort, // (void*)0x006BD99B, + window_staff_emptysub, + window_staff_scrollgetsize, // (void*)0x006BDBE6, + window_staff_scrollmousedown, // (void*)0x006BDC9A, + window_staff_emptysub, + window_staff_scrollmouseover, // (void*)0x006BDC6B, + window_staff_emptysub, + window_staff_emptysub, + window_staff_emptysub, + window_staff_tooltip, // (void*)0x006BDC90, + window_staff_emptysub, + window_staff_emptysub, + window_staff_invalidate, // (void*)0x006BD477, + window_staff_paint, // (void*)0x006BD533, + window_staff_scrollpaint, // (void*)0x006BD785, +}; + +enum WINDOW_STAFF_LIST_WIDGET_IDX { + WIDX_STAFF_BACKGROUND, // 0,1 + WIDX_STAFF_TITLE, // 1,2 + WIDX_STAFF_CLOSE, // 2,4 + WIDX_STAFF_TAB_CONTENT_PANEL, // 3,8 + WIDX_STAFF_HANDYMEN_TAB, // 4,10 + WIDX_STAFF_MECHANICS_TAB, // 5,20 + WIDX_STAFF_SECURITY_TAB, // 6,40 + WIDX_STAFF_ENTERTAINERS_TAB, // 7,80 + WIDX_STAFF_LIST, // 8,100 + WIDX_STAFF_UNIFORM_COLOR_PICKER, // 9,200 + WIDX_STAFF_HIRE_BUTTON, // A,400 + WIDX_STAFF_SHOW_PATROL_AREA_BUTTON, // B,800 + WIDX_STAFF_MAP, // C,1000 +}; + +static rct_widget window_staff_widgets[] = { + { WWT_FRAME, 0, 0, 319, 0, 269, 0x0FFFFFFFF, STR_NONE }, // 0,1: panel / background + { WWT_CAPTION, 0, 1, 318, 1, 14, STR_STAFF, STR_WINDOW_TITLE_TIP }, // 1,2: title bar + { WWT_CLOSEBOX, 0, 307, 317, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // 2,4: close x button + { WWT_RESIZE, 1, 0, 319, 43, 269, 0x0FFFFFFFF, STR_NONE }, // 3,8: tab content panel + { WWT_TAB, 1, 3, 33, 17, 43, 0x02000144E, STR_STAFF_HANDYMEN_TAB_TIP }, // 4,10: tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x02000144E, STR_STAFF_MECHANICS_TAB_TIP }, // 5,20: tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x02000144E, STR_STAFF_SECURITY_TAB_TIP }, // 6,40: tab 3 + { WWT_TAB, 1, 96, 126, 17, 43, 0x02000144E, STR_STAFF_ENTERTAINERS_TAB_TIP }, // 7,80: tab 4 + { WWT_SCROLL, 1, 3, 316, 72, 266, 3, STR_NONE }, // 8,100: staff list + { WWT_COLORBTN, 1, 130, 141, 58, 69, STR_NONE, STR_STAFF_LIST_COLORBTN }, // 9,200: uniform color picker + { WWT_DROPDOWN_BUTTON, 0, 165, 309, 17, 29, STR_NONE, STR_STAFF_LIST_DROPDOWNBUTTON_TIP }, // 10,400: hire button + { WWT_FLATBTN, 1, 267, 290, 46, 69, 5175, STR_SHOW_PATROL_AREA_TIP }, // 11,800: show staff patrol area + { WWT_FLATBTN, 1, 291, 314, 46, 69, 5192, STR_SHOW_STAFF_ON_MAP_TIP }, // 12,1000: map + { WIDGETS_END }, +}; + +static uint16 _window_staff_selected_type_count = 0; +// TODO: These are still referenced in non-decompiled code +//static int _window_staff_highlighted_index; +//static int _window_staff_selected_tab; /* * rct2: 0x006BD39C **/ -void window_staff_init_vars() { - RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) = WINDOW_STAFF_LIST_TAB_HANDYMEN; +void window_staff_init_vars() +{ + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) = WINDOW_STAFF_TAB_HANDYMEN; +} + +/* +* rct2: 0x006BD3CC +**/ +void window_staff_open() +{ + rct_window* window; + + // Check if window is already open + window = window_bring_to_front_by_id(WC_STAFF_LIST, 0); + if (window != NULL) + return; + + window = window_create_auto_pos(320, 270, (uint32*)window_staff_events, WC_STAFF_LIST, 0x0400); + window->widgets = window_staff_widgets; + window->enabled_widgets = + (1 << WIDX_STAFF_CLOSE) | + (1 << WIDX_STAFF_HANDYMEN_TAB) | + (1 << WIDX_STAFF_MECHANICS_TAB) | + (1 << WIDX_STAFF_SECURITY_TAB) | + (1 << WIDX_STAFF_ENTERTAINERS_TAB) | + (1 << WIDX_STAFF_HIRE_BUTTON) | + (1 << WIDX_STAFF_UNIFORM_COLOR_PICKER) | + (1 << WIDX_STAFF_SHOW_PATROL_AREA_BUTTON) | + (1 << WIDX_STAFF_MAP); + + window_init_scroll_widgets(window); + RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) = -1; + window->list_information_type = 0; + + window_staff_widgets[WIDX_STAFF_UNIFORM_COLOR_PICKER].type = WWT_EMPTY; + window->min_width = 320; + window->min_height = 270; + window->max_width = 500; + window->max_height = 450; + window->flags |= WF_RESIZABLE; + window->colours[0] = 1; + window->colours[1] = 4; + window->colours[2] = 4; +} + +void window_staff_cancel_tools() { + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + 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)) + if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) && w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)) + tool_cancel(); +} + +/* +* rct2: 0x006BD9B1 +**/ +void window_staff_close() { + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + window_staff_cancel_tools(w); +} + +void window_staff_hire_new() { + uint8 bl = 1; + RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_STRING_ID, uint16) = STR_CANT_HIRE_NEW_STAFF; + int eax, ebx, ecx, edx, esi, edi, ebp; + + eax = 0x8000; + ebx = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) << 8 | bl; + esi = 0x1D; + + int result = game_do_command_p(&eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + if (result == 0x80000000) { + rct_window* window = window_find_by_id(WC_STAFF_LIST, 0); + window_invalidate(window); + } else { + window_staff_peep_open(&g_sprite_list[edi].peep); + } +} + +/** +* +* rct2: 0x006BD94C +*/ +static void window_staff_mouseup() +{ + short widgetIndex; + rct_window *w; + + #ifdef _MSC_VER + __asm mov widgetIndex, dx + #else + __asm__("mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex)); + #endif + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + + switch (widgetIndex) { + case WIDX_STAFF_CLOSE: + window_close(w); + break; + case WIDX_STAFF_HIRE_BUTTON: + window_staff_hire_new(); + break; + case WIDX_STAFF_SHOW_PATROL_AREA_BUTTON: + RCT2_CALLPROC_X(0x006BD9FF, 0, 0, 0, widgetIndex, (int)w, 0, 0); + + // TODO: The code below works, but due to some funny things, when clicking again on the show patrol area button to disable the tool, + // the mouseup event is getting called when it should not be + //tool_set(w, WIDX_STAFF_SHOW_PATROL_AREA_BUTTON, 0x0C); + //show_gridlines(); + //RCT2_GLOBAL(0x009DEA50, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) | 0x8000; + //gfx_invalidate_screen(); + break; + case WIDX_STAFF_MAP: + window_map_open(); + break; + } +} + +/** +* +* rct2: 0x006BDD5D +*/ +static void window_staff_resize() +{ + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + + w->min_width = 320; + w->min_height = 270; + if (w->width < w->min_width) { + w->width = w->min_width; + window_invalidate(w); + } + if (w->height < w->min_height) { + w->height = w->min_height; + window_invalidate(w); + } +} + + +/** +* +* rct2: 0x006BD971 +*/ +static void window_staff_mousedown(int widgetIndex, rct_window*w, rct_widget* widget) +{ + short newSelectedTab; + int eax, ebx, ecx, edx; + + switch (widgetIndex) { + case WIDX_STAFF_HANDYMEN_TAB: + case WIDX_STAFF_MECHANICS_TAB: + case WIDX_STAFF_SECURITY_TAB: + case WIDX_STAFF_ENTERTAINERS_TAB: + newSelectedTab = widgetIndex - WIDX_STAFF_HANDYMEN_TAB;; + if (RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) == newSelectedTab) + break; + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) = (uint8)newSelectedTab; + window_invalidate(w); + w->scrolls[0].v_top = 0; + window_staff_cancel_tools(w); + break; + case WIDX_STAFF_UNIFORM_COLOR_PICKER: + eax = (RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)] << 8) + 0x80 + w->colours[1]; + ebx = 0; + ecx = 0; + edx = widgetIndex; + + RCT2_CALLPROC_X(0x006ED43D, eax, &ebx, &ecx, &edx, (int)w, (int)widget, 0xFFFFFFFF); + break; + } + + +} + +/** +* +* rct2: 0x006BD9A6 +*/ +static void window_staff_dropdown() +{ + short widgetIndex, dropdownIndex; + + #ifdef _MSC_VER + __asm mov dropdownIndex, ax + #else + __asm__("mov %[dropdownIndex], ax " : [dropdownIndex] "+m" (dropdownIndex)); + #endif + + #ifdef _MSC_VER + __asm mov widgetIndex, dx + #else + __asm__("mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex)); + #endif + + if (widgetIndex == WIDX_STAFF_UNIFORM_COLOR_PICKER && dropdownIndex != -1) { + game_do_command( + 0, + (RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8) << 8) + 1, + 0, + (dropdownIndex << 8) + 4, + 0x28, + 0, + 0); + } +} + +/** +* +* rct2: 0x006BDCEA +*/ +void window_staff_update(rct_window *w) +{ + int spriteIndex; + rct_peep *peep; + + w->list_information_type++; + if (w->list_information_type >= 24) { + w->list_information_type = 0; + } else { + widget_invalidate(WC_GUEST_LIST, 0, WIDX_STAFF_HANDYMEN_TAB + RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)); + RCT2_GLOBAL(0x009AC861, uint16) |= 2; + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type == PEEP_TYPE_STAFF) { + peep->var_0C &= 0xFDFF; + + if (peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) { + peep->var_0C &= 0x200; + } + } + } + } +} + +/** +* +* rct2: 0x006BD99B +*/ +void window_staff_toolabort() { + short widgetIndex; + rct_window *w; + + #ifdef _MSC_VER + __asm mov widgetIndex, dx + #else + __asm__("mov %[widgetIndex], dx " : [widgetIndex] "+m" (widgetIndex)); + #endif + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + if (widgetIndex == WIDX_STAFF_SHOW_PATROL_AREA_BUTTON) { + hide_gridlines(); + tool_cancel(); + RCT2_GLOBAL(0x009DEA50, sint16) = 0xFFFF; + gfx_invalidate_screen(); + } +} + +/** +* +* rct2: 0x006BDBE6 +*/ +void window_staff_scrollgetsize() { + int spriteIndex; + rct_peep *peep; + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + uint16 staffCount = 0; + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) + staffCount++; + } + + _window_staff_selected_type_count = staffCount; + + if (RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) != -1) { + RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) = -1; + window_invalidate(w); + } + + int scrollHeight = staffCount * 10; + int i = scrollHeight - window_staff_widgets[WIDX_STAFF_LIST].bottom + window_staff_widgets[WIDX_STAFF_LIST].top + 21; + if (i < 0) + i = 0; + if (i < w->scrolls[0].v_top) { + w->scrolls[0].v_top = i; + window_invalidate(w); + } + + #ifdef _MSC_VER + __asm mov ecx, 420 + #else + __asm__("mov ecx, 420 "); + #endif + + #ifdef _MSC_VER + __asm mov edx, scrollHeight + #else + __asm__("mov edx, %[scrollHeight] " : [scrollHeight] "+m" (scrollHeight)); + #endif +} + +/** +* +* rct2: 0x006BDC9A +*/ +void window_staff_scrollmousedown() { + int i, spriteIndex; + short y; + rct_window *w; + rct_peep *peep; + + #ifdef _MSC_VER + __asm mov y, dx + #else + __asm__("mov %[y], dx " : [y] "+m" (y)); + #endif + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + i = y / 10; + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type != PEEP_TYPE_STAFF) + continue; + + if (peep->staff_type != RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8)) + continue; + + if (i == 0) { + window_staff_peep_open(peep); + break; + } + + i--; + } +} + +/** +* +* rct2: 0x006BDC6B +*/ +void window_staff_scrollmouseover() { + int i; + short y; + rct_window *w; + + #ifdef _MSC_VER + __asm mov y, dx + #else + __asm__("mov %[y], dx " : [y] "+m" (y)); + #endif + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + + i = y / 10; + if (i != RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short)) { + RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short) = i; + window_invalidate(w); + } +} + +/** +* +* rct2: 0x006BDC90 +*/ +void window_staff_tooltip() +{ + RCT2_GLOBAL(0x013CE952, uint16) = STR_LIST; +} + +/** +* +* rct2: 0x006BD477 +*/ +void window_staff_invalidate() +{ + rct_window *w; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + int pressed_widgets = w->pressed_widgets & 0xFFFFFF0F; + uint8 tabIndex = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); + uint8 widgetIndex = tabIndex + 4; + + w->pressed_widgets = pressed_widgets | (1 << widgetIndex); + window_staff_widgets[WIDX_STAFF_HIRE_BUTTON].image = STR_HIRE_HANDYMAN + tabIndex; + window_staff_widgets[WIDX_STAFF_UNIFORM_COLOR_PICKER].type = WWT_EMPTY; + + if (tabIndex < 3) { + window_staff_widgets[WIDX_STAFF_UNIFORM_COLOR_PICKER].type = WWT_COLORBTN; + window_staff_widgets[WIDX_STAFF_UNIFORM_COLOR_PICKER].image = + ((uint32)RCT2_ADDRESS(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8)[tabIndex] << 19) + + 0x600013C3; + } + + window_staff_widgets[WIDX_STAFF_BACKGROUND].right = w->width - 1; + window_staff_widgets[WIDX_STAFF_BACKGROUND].bottom = w->height - 1; + window_staff_widgets[WIDX_STAFF_TAB_CONTENT_PANEL].right = w->width - 1; + window_staff_widgets[WIDX_STAFF_TAB_CONTENT_PANEL].bottom = w->height - 1; + window_staff_widgets[WIDX_STAFF_TITLE].right = w->width - 2; + window_staff_widgets[WIDX_STAFF_CLOSE].left = w->width - 2 - 0x0B; + window_staff_widgets[WIDX_STAFF_CLOSE].right = w->width - 2 - 0x0B + 0x0A; + window_staff_widgets[WIDX_STAFF_LIST].right = w->width - 4; + window_staff_widgets[WIDX_STAFF_LIST].bottom = w->height - 0x0F; +} + +/** +* +* rct2: 0x006BD533 +*/ +void window_staff_paint() { + int i, x, y, format; + uint8 selectedTab; + rct_window *w; + rct_drawpixelinfo *dpi; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + #ifdef _MSC_VER + __asm mov dpi, edi + #else + __asm__("mov %[dpi], edi " : [dpi] "+m" (dpi)); + #endif + + // Widgets + window_draw_widgets(w, dpi); + + selectedTab = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); + + // Handymen tab image + i = (selectedTab == 0 ? w->list_information_type & 0x0FFFFFFFC : 0); + i += RCT2_ADDRESS(RCT2_GLOBAL(0x00982710, int), int)[0] + 1; + i |= 0x20000000; + i |= RCT2_GLOBAL(RCT2_ADDRESS_HANDYMAN_COLOUR, uint8) << 19; + gfx_draw_sprite( + dpi, + i, + (window_staff_widgets[WIDX_STAFF_HANDYMEN_TAB].left + window_staff_widgets[WIDX_STAFF_HANDYMEN_TAB].right) / 2 + w->x, + window_staff_widgets[WIDX_STAFF_HANDYMEN_TAB].bottom - 6 + w->y + ); + + // Handymen tab image + i = (selectedTab == 1 ? w->list_information_type & 0x0FFFFFFFC : 0); + i += RCT2_ADDRESS(RCT2_GLOBAL(0x00982718, int), int)[0] + 1; + i |= 0x20000000; + i |= RCT2_GLOBAL(RCT2_ADDRESS_MECHANIC_COLOUR, uint8) << 19; + gfx_draw_sprite( + dpi, + i, + (window_staff_widgets[WIDX_STAFF_MECHANICS_TAB].left + window_staff_widgets[WIDX_STAFF_MECHANICS_TAB].right) / 2 + w->x, + window_staff_widgets[WIDX_STAFF_MECHANICS_TAB].bottom - 6 + w->y + ); + + // Security tab image + i = (selectedTab == 2 ? w->list_information_type & 0x0FFFFFFFC : 0); + i += RCT2_ADDRESS(RCT2_GLOBAL(0x00982720, int), int)[0] + 1; + i |= 0x20000000; + i |= RCT2_GLOBAL(RCT2_ADDRESS_SECURITY_COLOUR, uint8) << 19; + gfx_draw_sprite( + dpi, + i, + (window_staff_widgets[WIDX_STAFF_SECURITY_TAB].left + window_staff_widgets[WIDX_STAFF_SECURITY_TAB].right) / 2 + w->x, + window_staff_widgets[WIDX_STAFF_SECURITY_TAB].bottom - 6 + w->y + ); + + rct_drawpixelinfo* sprite_dpi = clip_drawpixelinfo( + dpi, + window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].left + w->x + 1, + window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].right - window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].left - 1, + window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].top + w->y + 1, + window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].bottom - window_staff_widgets[WIDX_STAFF_ENTERTAINERS_TAB].top - 1 + ); + + + + if (sprite_dpi != NULL) { + // Entertainers tab image + i = (selectedTab == 3 ? w->list_information_type & 0x0FFFFFFFC : 0); + i += RCT2_ADDRESS(RCT2_GLOBAL(0x00982738, int), int)[0] + 1; + gfx_draw_sprite( + sprite_dpi, + i, + 0x0F, + 0x17 + ); + rct2_free(sprite_dpi); + } + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_11)) { + RCT2_GLOBAL(0x013CE952, uint32) = RCT2_ADDRESS(0x00992A00, uint16)[selectedTab]; + gfx_draw_string_left(dpi, 1858, (void*)0x013CE952, 0, w->x + 0xA5, w->y + 0x20); + } + + if (selectedTab < 3) { + gfx_draw_string_left(dpi, STR_UNIFORM_COLOR, w, 0, w->x + 6, window_staff_widgets[WIDX_STAFF_UNIFORM_COLOR_PICKER].top + w->y + 1); + } + + int staffTypeStringId = 1859 + selectedTab; + // If the number of staff for a given type is 1, we use the singular forms of the names + if (_window_staff_selected_type_count == 1) { + staffTypeStringId += 4; + } + + RCT2_GLOBAL(0x013CE952, uint16) = _window_staff_selected_type_count; + RCT2_GLOBAL(0x013CE952 + 2, uint16) = staffTypeStringId; + + gfx_draw_string_left(dpi, STR_STAFF_LIST_COUNTER, (void*)0x013CE952, 0, w->x + 4, window_staff_widgets[WIDX_STAFF_LIST].bottom + w->y + 2); +} + +/** +* +* rct2: 0x006BD785 +*/ +void window_staff_scrollpaint() +{ + int spriteIndex, y, i, staffOrderIcon_x, staffOrders, staffOrderSprite; + uint32 argument_1, argument_2; + uint8 selectedTab; + rct_window *w; + rct_drawpixelinfo *dpi; + rct_peep *peep; + + #ifdef _MSC_VER + __asm mov w, esi + #else + __asm__("mov %[w], esi " : [w] "+m" (w)); + #endif + + #ifdef _MSC_VER + __asm mov dpi, edi + #else + __asm__("mov %[dpi], edi " : [dpi] "+m" (dpi)); + #endif + + gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ((char*)0x0141FC48)[w->colours[1] * 8]); + + y = 0; + i = 0; + selectedTab = RCT2_GLOBAL(RCT2_ADDRESS_WINDOW_STAFF_LIST_SELECTED_TAB, uint8); + FOR_ALL_PEEPS(spriteIndex, peep) { + if (peep->type == PEEP_TYPE_STAFF && peep->staff_type == selectedTab) { + if (y > dpi->y + dpi->height) { + break; + } + + if (y + 11 >= dpi->y) { + int format = 0x4A7; + + if (i == RCT2_GLOBAL(RCT2_ADDRESS_STAFF_HIGHLIGHTED_INDEX, short)) { + gfx_fill_rect(dpi, 0, y, 800, y + 9, 0x2000031); + format = 0x4A9; + } + + RCT2_GLOBAL(0x013CE952, uint16) = peep->name_string_idx; + RCT2_GLOBAL(0x013CE952 + 2, uint32) = peep->id; + gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 0, y - 1, 107); + + get_arguments_from_action(peep, &argument_1, &argument_2); + RCT2_GLOBAL(0x013CE952, uint32) = argument_1; + RCT2_GLOBAL(0x013CE952 + 4, uint32) = argument_2; + gfx_draw_string_left_clipped(dpi, format, (void*)0x013CE952, 0, 175, y - 1, 305); + + // True if a patrol path is set for the worker + if (RCT2_ADDRESS(0x013CA672, uint8)[peep->var_C5] & 2) { + gfx_draw_sprite(dpi, 0x13FD, 110, y - 1); + } + + staffOrderIcon_x = 0x7D; + if (peep->staff_type != 3) { + staffOrders = peep->var_C6; + staffOrderSprite = RCT2_ADDRESS(0x00992A08, uint32)[selectedTab]; + + while (staffOrders != 0) { + if (staffOrders & 1 != 0) { + gfx_draw_sprite(dpi, staffOrderSprite, staffOrderIcon_x, y - 1); + } + staffOrders = staffOrders >> 1; + staffOrderIcon_x += 9; + staffOrderSprite++; + } + } else { + gfx_draw_sprite(dpi, peep->sprite_type - 4 + 0x13FE, staffOrderIcon_x, y - 1); + } + } + + y += 10; + i++; + } + } } \ No newline at end of file