Merge pull request #262 from qcz/wip-stafflist

Decompiling the staff window
This commit is contained in:
Ted John 2014-08-05 22:05:54 +01:00
commit 2365563583
14 changed files with 1100 additions and 146 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <string.h>
#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++;
}
}
}