/**
 *
 *  rct2: 0x00671060
 */
static void window_editor_scenario_options_park_dropdown(rct_window *w, int widgetIndex, int dropdownIndex)
{
	if (widgetIndex == WIDX_PAY_FOR_PARK_OR_RIDES_DROPDOWN && dropdownIndex != -1) {
		if(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) {
			if (dropdownIndex == 0) {
				if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY)) {
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY;
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = MONEY(0, 00);
				}
			} else {
				if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY) {
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) = MONEY(10, 00);
				}
			}
		}
		else {
			if (dropdownIndex == 0) {
				if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY)) {
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY;
				}
			} else {
				if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_FREE_ENTRY) {
					RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
				}
			}
			window_invalidate_by_class(WC_PARK_INFORMATION);
			window_invalidate_by_class(WC_RIDE);
		}
		window_invalidate(w);
	}
}
Beispiel #2
0
/**
 *
 *  rct2: 0x0066E377
 */
void news_item_close_current()
{
    sint32 i;
    NewsItem *newsItems = gNewsItems;

    // Check if there is a current message
    if (news_item_is_queue_empty())
        return;

    // Find an available history news item slot for current message
    i = news_item_get_new_history_slot();

    // Set the history news item slot to the current news item
    newsItems[i] = newsItems[0];

    // Set the end of the end of the history list
    if (i < MAX_NEWS_ITEMS - 1)
        newsItems[i + 1].Type = NEWS_ITEM_NULL;

    // Invalidate the news window
    window_invalidate_by_class(WC_RECENT_NEWS);

    // Dequeue the current news item, shift news up
    for (i = 0; i < 10; i++)
        newsItems[i] = newsItems[i + 1];
    newsItems[10].Type = NEWS_ITEM_NULL;

    // Invalidate current news item bar
    window_game_bottom_toolbar_invalidate_news_item();
}
Beispiel #3
0
/**
 * 
 *  rct2: 0x0066A348
 */
int park_calculate_size()
{
	int tiles, x, y;
	rct_map_element *mapElement;

	tiles = 0;
	for (y = 0; y < 256; y++) {
		for (x = 0; x < 256; x++) {
			mapElement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[y * 256 + x];
			while (mapElement->type & MAP_ELEMENT_TYPE_MASK) {
				mapElement++;
			}

			if (mapElement->properties.surface.ownership & 0x30)
				tiles++;
		}
	}

	if (tiles != RCT2_GLOBAL(RCT2_ADDRESS_PARK_SIZE, sint16)) {
		RCT2_GLOBAL(RCT2_ADDRESS_PARK_SIZE, sint16) = tiles;
		window_invalidate_by_class(WC_PARK_INFORMATION);
	}
	
	return tiles;
}
Beispiel #4
0
/**
 *
 *  rct2: 0x0069E73C
 */
void game_command_start_campaign(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp)
{
	int type = *edx & 0xFF;
	int rideOrItem = (*edx >> 8) & 0xFF;
	int numWeeks = (*ebx >> 8) & 0xFF;

	if (type < 0 || type >= countof(AdvertisingCampaignPricePerWeek))
	{
		log_warning("Invalid game command, type = %d", type);
		*ebx = MONEY32_UNDEFINED;
		return;
	}

	RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_MARKETING * 4;
	if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) {
		RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 3048;
		*ebx = MONEY32_UNDEFINED;
		return;
	}

	if (*ebx & GAME_COMMAND_FLAG_APPLY) {
		gMarketingCampaignDaysLeft[type] = numWeeks | CAMPAIGN_ACTIVE_FLAG;
		gMarketingCampaignRideIndex[type] = rideOrItem;

		window_invalidate_by_class(WC_FINANCES);
	}

	*ebx = numWeeks * AdvertisingCampaignPricePerWeek[type];
}
Beispiel #5
0
/**
 *
 *  rct2: 0x0066DF17
 */
static void window_save_prompt_close(rct_window *w)
{
	// Unpause the game
	RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) &= ~2;
	audio_unpause_sounds();
	window_invalidate_by_class(WC_TOP_TOOLBAR);
}
Beispiel #6
0
/**
 *
 *  rct2: 0x0066DF17
 */
static void window_save_prompt_close(rct_window *w)
{
	// Unpause the game
	gGamePaused &= ~GAME_PAUSED_MODAL;
	audio_unpause_sounds();
	window_invalidate_by_class(WC_TOP_TOOLBAR);
}
Beispiel #7
0
/**
 * Pay an amount of money.
 * rct2: 0x069C674
 * @param amount (eax)
 * @param type passed via global var 0x0141F56C, our type is that var/4.
 **/
void finance_payment(money32 amount, rct_expenditure_type type)
{
	money32 cur_money = DECRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32));
	money32 new_money = cur_money - amount;

	//overflow check
	RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, sint32) = ENCRYPT_MONEY(new_money);
	RCT2_ADDRESS(RCT2_ADDRESS_EXPENDITURE_TABLE, money32)[type] -= amount;
	if (RCT2_ADDRESS(0x00988E60, uint32)[type] & 1)
		RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_EXPENDITURE, money32) -= amount; // Cumulative amount of money spent this day
	

	RCT2_GLOBAL(0x009A9804, uint32) |= 1; // money dirty flag
	window_invalidate_by_class(WC_FINANCES);
	window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
}
/**
 *
 *  rct2: 0x0067049D
 */
static void window_editor_scenario_options_financial_mouseup(rct_window *w, int widgetIndex)
{
	switch (widgetIndex) {
	case WIDX_CLOSE:
		window_close(w);
		break;
	case WIDX_TAB_1:
	case WIDX_TAB_2:
	case WIDX_TAB_3:
		window_editor_scenario_options_set_page(w, widgetIndex - WIDX_TAB_1);
		break;
	case WIDX_NO_MONEY:
		if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) {
			RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) ^= PARK_FLAGS_NO_MONEY_SCENARIO;
		} else {
			RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) ^= PARK_FLAGS_NO_MONEY;
			// Invalidate all windows that have anything to do with finance
			window_invalidate_by_class(WC_RIDE);
			window_invalidate_by_class(WC_PEEP);
			window_invalidate_by_class(WC_PARK_INFORMATION);
			window_invalidate_by_class(WC_FINANCES);
			window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
			window_invalidate_by_class(WC_TOP_TOOLBAR);
		}
		window_invalidate(w);
		break;
	case WIDX_FORBID_MARKETING:
		RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) ^= PARK_FLAGS_FORBID_MARKETING_CAMPAIGN;
		window_invalidate(w);
		break;
	}
}
/**
 *
 *  rct2: 0x006C825F
 */
static void window_maze_construction_entrance_tooldown(sint32 x, sint32 y, rct_window* w){
    ride_construction_invalidate_current_track();

    map_invalidate_selection_rect();

    gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;
    gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;

    sint32 direction = 0;
    ride_get_entrance_or_exit_position_from_screen_position(x, y, &x, &y, &direction);

    if (gRideEntranceExitPlaceDirection == 0xFF)
        return;

    uint8 rideIndex = gRideEntranceExitPlaceRideIndex;
    uint8 entranceExitType = gRideEntranceExitPlaceType;
    if (entranceExitType == ENTRANCE_TYPE_RIDE_ENTRANCE) {
        gGameCommandErrorTitle = STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION;
    } else {
        gGameCommandErrorTitle = STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION;
    }

    money32 cost = game_do_command(
        x,
        GAME_COMMAND_FLAG_APPLY | ((direction ^ 2) << 8),
        y,
        rideIndex | (entranceExitType << 8),
        GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT,
        gRideEntranceExitPlaceStationIndex,
        0);

    if (cost == MONEY32_UNDEFINED)
        return;

    audio_play_sound_at_location(
        SOUND_PLACE_ITEM,
        gCommandPosition.x,
        gCommandPosition.y,
        gCommandPosition.z);

    rct_ride* ride = get_ride(rideIndex);
    if (ride_are_all_possible_entrances_and_exits_built(ride)){
        tool_cancel();
        if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK))
            window_close(w);
    }
    else{
        gRideEntranceExitPlaceType = entranceExitType ^ 1;
        window_invalidate_by_class(WC_RIDE_CONSTRUCTION);
        gCurrentToolWidget.widget_index = entranceExitType ? WIDX_MAZE_ENTRANCE : WIDX_MAZE_EXIT;
    }
}
/**
 * 
 *  rct2: 0x006E3E91
 */
void keyboard_shortcut_set(int key)
{
	int i;

	// Unmap shortcut that already uses this key
	for (i = 0; i < 32; i++) {
		if (key == gShortcutKeys[i]) {
			gShortcutKeys[i] = 0xFFFF;
			break;
		}
	}

	// Map shortcut to this key
	gShortcutKeys[RCT2_GLOBAL(0x009DE511, uint8)] = key;
	window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
	window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST);
	config_save();
}
/**
 *
 *  rct2: 0x00685412
 */
static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, int32_t y)
{
    rct_research_item* researchItem;

    // Skip always researched items, so that the dragged item gets placed underneath them
    do
    {
        researchItem = get_research_item_at(x, y);
        y += LIST_ROW_HEIGHT;
    } while (researchItem != nullptr && researchItem->rawValue >= 0 && research_item_is_always_researched(researchItem));

    if (researchItem != nullptr)
        move_research_item(researchItem);

    window_close(w);
    _editorInventionsListDraggedItem = nullptr;
    window_invalidate_by_class(WC_EDITOR_INVENTION_LIST);
}
Beispiel #12
0
/**
 * Update status of marketing campaigns and send produce a news item when they have finished.
 *  rct2: 0x0069E0C1
 */
void marketing_update()
{
    for (sint32 campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++)
    {
        if (gCheatsNeverendingMarketing)
            continue;

        sint32 active = (gMarketingCampaignDaysLeft[campaign] & CAMPAIGN_ACTIVE_FLAG) != 0;
        if (gMarketingCampaignDaysLeft[campaign] == 0)
            continue;

        window_invalidate_by_class(WC_FINANCES);

        // High bit marks the campaign as inactive, on first check the campaign is set active
        // this makes campaigns run a full x weeks even when started in the middle of a week
        gMarketingCampaignDaysLeft[campaign] &= ~CAMPAIGN_ACTIVE_FLAG;
        if (active)
            continue;

        if (--gMarketingCampaignDaysLeft[campaign] != 0)
            continue;

        sint32 campaignItem = gMarketingCampaignRideIndex[campaign];

        // This sets the string parameters for the marketing types that have an argument.
        if (campaign == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign == ADVERTISING_CAMPAIGN_RIDE)
        {
            Ride * ride = get_ride(campaignItem);
            set_format_arg(0, rct_string_id, ride->name);
            set_format_arg(2, uint32, ride->name_arguments);
        }
        else if (campaign == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE)
        {
            set_format_arg(0, rct_string_id, ShopItemStringIds[campaignItem].plural);
        }

        if (gConfigNotifications.park_marketing_campaign_finished)
        {
            news_item_add_to_queue(NEWS_ITEM_MONEY, MarketingCampaignNames[campaign][2], 0);
        }
    }
}
Beispiel #13
0
/**
 *
 *  rct2: 0x0066A348
 */
sint32 park_calculate_size()
{
    sint32 tiles;
    tile_element_iterator it;

    tiles = 0;
    tile_element_iterator_begin(&it);
    do {
        if (tile_element_get_type(it.element) == TILE_ELEMENT_TYPE_SURFACE) {
            if (it.element->properties.surface.ownership & (OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED | OWNERSHIP_OWNED)) {
                tiles++;
            }
        }
    } while (tile_element_iterator_next(&it));

    if (tiles != gParkSize) {
        gParkSize = tiles;
        window_invalidate_by_class(WC_PARK_INFORMATION);
    }

    return tiles;
}
Beispiel #14
0
/**
 * Update status of marketing campaigns and send produce a news item when they have finished.
 *  rct2: 0x0069E0C1
 */
void marketing_update()
{
	for (int campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) {
		if (gCheatsNeverendingMarketing)
			continue;

		int active = (gMarketingCampaignDaysLeft[campaign] & CAMPAIGN_ACTIVE_FLAG) != 0;
		if (gMarketingCampaignDaysLeft[campaign] == 0)
			continue;

		window_invalidate_by_class(WC_FINANCES);

		// High bit marks the campaign as inactive, on first check the campaign is set active
		// this makes campaigns run a full x weeks even when started in the middle of a week
		gMarketingCampaignDaysLeft[campaign] &= ~CAMPAIGN_ACTIVE_FLAG;
		if (active)
			continue;

		if (--gMarketingCampaignDaysLeft[campaign] != 0)
			continue;

		int campaignItem = gMarketingCampaignRideIndex[campaign];

		// This sets the string parameters for the marketing types that have an argument.
		if (campaign == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign == ADVERTISING_CAMPAIGN_RIDE) {
			rct_ride* ride = get_ride(campaignItem);
			RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = ride->name;
			RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint32) = ride->name_arguments;
		} else if (campaign == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) {
			RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = ShopItemStringIds[campaignItem].plural;
		}

		if (gConfigNotifications.park_marketing_campaign_finished) {
			news_item_add_to_queue(NEWS_ITEM_MONEY, STR_MARKETING_FINISHED_BASE + campaign, 0);
		}
	}
}
/**
 *
 *  rct2: 0x006704C8
 */
static void window_editor_scenario_options_financial_mousedown(int widgetIndex, rct_window *w, rct_widget *widget)
{
	switch (widgetIndex) {
	case WIDX_INITIAL_CASH_INCREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) < MONEY(1000000,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) += MONEY(500,00);
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, money32) = ENCRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3248, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_INITIAL_CASH_DECREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) > MONEY(0,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) -= MONEY(500,00);
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONEY_ENCRYPTED, money32) = ENCRYPT_MONEY(RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3249, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_INITIAL_LOAN_INCREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) < MONEY(5000000,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) += MONEY(1000,00);
			RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = max(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3250, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_INITIAL_LOAN_DECREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) > MONEY(0,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) -= MONEY(1000,00);
			RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = max(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3251, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_MAXIMUM_LOAN_INCREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) < MONEY(5000000,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) += MONEY(1000,00);
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = min(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3252, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_MAXIMUM_LOAN_DECREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) > MONEY(0,00)) {
			RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) -= MONEY(1000,00);
			RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = min(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32), RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32));
			finance_update_loan_hash();
		} else {
			window_error_open(3253, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_INTEREST_RATE_INCREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) < 80) {
			if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) < 0) {
				RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) = 0;
			} else {
				RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32)++;
			}
		} else {
			window_error_open(3254, STR_NONE);
		}
		window_invalidate(w);
		break;
	case WIDX_INTEREST_RATE_DECREASE:
		if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) > 0) {
			if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) > 80) {
				RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32) = 80;
			} else {
				RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, money32)--;
			}
		} else {
			window_error_open(3255, STR_NONE);
		}
		window_invalidate(w);
		break;
	}

	if(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) == SCREEN_FLAGS_PLAYING) {
		window_invalidate_by_class(WC_FINANCES);
		window_invalidate_by_class(WC_BOTTOM_TOOLBAR);
	}
}
Beispiel #16
0
/**
 *
 *  rct2: 0x0066DCBE
 */
void window_save_prompt_open()
{
	sint32 width, height;
	rct_string_id stringId;
	rct_window* window;
	uint8 prompt_mode;
	rct_widget *widgets;
	uint64 enabled_widgets;

	prompt_mode = gSavePromptMode;
	if (prompt_mode == PM_QUIT)
		prompt_mode = PM_SAVE_BEFORE_QUIT;

	// do not show save prompt if we're in the title demo and click on load game
	if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) {
		game_load_or_quit_no_save_prompt();
		return;
	}

	if (!gConfigGeneral.confirmation_prompt) {
		/* game_load_or_quit_no_save_prompt() will exec requested task and close this window
		* immediately again.
		* TODO restructure these functions when we're sure game_load_or_quit_no_save_prompt()
		* and game_load_or_quit() are not called by the original binary anymore.
		*/

		if (gScreenAge < 3840) {
			game_load_or_quit_no_save_prompt();
			return;
		}
	}

	// Check if window is already open
	window = window_bring_to_front_by_class(WC_SAVE_PROMPT);
	if (window){
		window_close(window);
	}

	if (gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) {
		widgets = window_quit_prompt_widgets;
		enabled_widgets =
			(1 << WQIDX_CLOSE) |
			(1 << WQIDX_OK) |
			(1 << WQIDX_CANCEL);
		width = 177;
		height = 34;
	} else {
		widgets = window_save_prompt_widgets;
		enabled_widgets =
			(1 << WIDX_CLOSE) |
			(1 << WIDX_SAVE) |
			(1 << WIDX_DONT_SAVE) |
			(1 << WIDX_CANCEL);
		width = 260;
		height = 50;
	}

	if (prompt_mode >= countof(window_save_prompt_labels)) {
		log_warning("Invalid save prompt mode %u", prompt_mode);
		return;
	}
	window = window_create_centred(
		width,
		height,
		&window_save_prompt_events,
		WC_SAVE_PROMPT,
		WF_TRANSPARENT | WF_STICK_TO_FRONT
	);

	window->widgets = widgets;
	window->enabled_widgets = enabled_widgets;
	window_init_scroll_widgets(window);

	// Pause the game
	gGamePaused |= GAME_PAUSED_MODAL;
	audio_pause_sounds();
	window_invalidate_by_class(WC_TOP_TOOLBAR);

	stringId = window_save_prompt_labels[prompt_mode][0];
	if (stringId == STR_LOAD_GAME_PROMPT_TITLE && gScreenFlags & 2)
		stringId = STR_LOAD_LANDSCAPE_PROMPT_TITLE;
	if (stringId == STR_QUIT_GAME_PROMPT_TITLE && gScreenFlags & 2)
		stringId = STR_QUIT_SCENARIO_EDITOR;
	window_save_prompt_widgets[WIDX_TITLE].text = stringId;
	window_save_prompt_widgets[WIDX_LABEL].text = window_save_prompt_labels[prompt_mode][1];
}
Beispiel #17
0
static void research_invalidate_related_windows()
{
    window_invalidate_by_class(WC_CONSTRUCT_RIDE);
    window_invalidate_by_class(WC_RESEARCH);
}
Beispiel #18
0
/**
 *
 *  rct2: 0x0066DCBE
 */
void window_save_prompt_open()
{
	int stringId, width, height;
	rct_window* window;
	unsigned short prompt_mode;
	rct_widget *widgets;
	uint64 enabled_widgets;

	prompt_mode = RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16);
	if (prompt_mode == PM_QUIT)
		prompt_mode = PM_SAVE_BEFORE_QUIT;

	// do not show save prompt if we're in the title demo and click on load game
	if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO) {
		game_load_or_quit_no_save_prompt();
		return;
	}

	if (!gConfigGeneral.confirmation_prompt) {
		/* game_load_or_quit_no_save_prompt() will exec requested task and close this window
		* immediately again.
		* TODO restructure these functions when we're sure game_load_or_quit_no_save_prompt()
		* and game_load_or_quit() are not called by the original binary anymore.
		*/

		if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 0) {
			if (RCT2_GLOBAL(RCT2_ADDRESS_ON_TUTORIAL, uint8) != 1) {
				RCT2_CALLPROC_EBPSAFE(0x0066EE54);
				game_load_or_quit_no_save_prompt();
				return;
			}
			else {
				tutorial_stop();
				game_load_or_quit_no_save_prompt();
				return;
			}
		}

		if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_AGE, uint16) < 3840) {
			game_load_or_quit_no_save_prompt();
			return;
		}
	}

	// Check if window is already open
	window = window_bring_to_front_by_class(WC_SAVE_PROMPT);
	if (window){
		window_close(window);
	}

	if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) {
		widgets = window_quit_prompt_widgets;
		enabled_widgets =
			(1 << WQIDX_CLOSE) |
			(1 << WQIDX_OK) |
			(1 << WQIDX_CANCEL);
		width = 177;
		height = 34;
	} else {
		widgets = window_save_prompt_widgets;
		enabled_widgets =
			(1 << WIDX_CLOSE) |
			(1 << WIDX_SAVE) |
			(1 << WIDX_DONT_SAVE) |
			(1 << WIDX_CANCEL);
		width = 260;
		height = 50;
	}

	window = window_create_centred(
		width,
		height,
		&window_save_prompt_events,
		WC_SAVE_PROMPT,
		WF_TRANSPARENT | WF_STICK_TO_FRONT
	);

	window->widgets = widgets;
	window->enabled_widgets = enabled_widgets;
	window_init_scroll_widgets(window);

	// Pause the game
	RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) |= 2;
	audio_pause_sounds();
	window_invalidate_by_class(WC_TOP_TOOLBAR);

	stringId = prompt_mode + STR_LOAD_GAME_PROMPT_TITLE;
	if (stringId == STR_LOAD_GAME_PROMPT_TITLE && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
		stringId = STR_LOAD_LANDSCAPE_PROMPT_TITLE;
	if (stringId == STR_QUIT_GAME_PROMPT_TITLE && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)
		stringId = STR_QUIT_SCENARIO_EDITOR;
	window_save_prompt_widgets[WIDX_TITLE].image = stringId;
	window_save_prompt_widgets[WIDX_LABEL].image = prompt_mode + STR_SAVE_BEFORE_LOADING;
}
Beispiel #19
0
void input_handle_keyboard(bool isTitle)
{
    if (gOpenRCT2Headless)
    {
        return;
    }

    if (!gConsoleOpen)
    {
        if (!isTitle)
        {
            // Handle mouse scrolling
            if (input_get_state() == INPUT_STATE_NORMAL && gConfigGeneral.edge_scrolling)
            {
                if (!(gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_SHIFT_Z | PLACE_OBJECT_MODIFIER_COPY_Z)))
                {
                    game_handle_edge_scroll();
                }
            }
        }

        // Handle modifier keys and key scrolling
        gInputPlaceObjectModifier = PLACE_OBJECT_MODIFIER_NONE;
        const uint8 * keysState   = context_get_keys_state();
        if (keysState[SDL_SCANCODE_LSHIFT] || keysState[SDL_SCANCODE_RSHIFT])
        {
            gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_SHIFT_Z;
        }
        if (keysState[SDL_SCANCODE_LCTRL] || keysState[SDL_SCANCODE_RCTRL])
        {
            gInputPlaceObjectModifier |= PLACE_OBJECT_MODIFIER_COPY_Z;
        }
        if (keysState[SDL_SCANCODE_LALT] || keysState[SDL_SCANCODE_RALT])
        {
            gInputPlaceObjectModifier |= 4;
        }
#ifdef __MACOSX__
        if (keysState[SDL_SCANCODE_LGUI] || keysState[SDL_SCANCODE_RGUI])
        {
            gInputPlaceObjectModifier |= 8;
        }
#endif
        if (!isTitle)
        {
            game_handle_key_scroll();
        }
    }

    if (gConfigGeneral.use_virtual_floor)
    {
        if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z))
            virtual_floor_enable();
        else
            virtual_floor_disable();
    }

    // Handle key input
    sint32 key;
    while (!gOpenRCT2Headless && (key = get_next_key()) != 0)
    {
        if (key == 255)
            continue;

        // Reserve backtick for console
        if (key == SDL_SCANCODE_GRAVE)
        {
            if ((gConfigGeneral.debugging_tools && !context_is_input_active()) || gConsoleOpen)
            {
                window_cancel_textbox();
                console_toggle();
            }
            continue;
        }
        else if (gConsoleOpen)
        {
            input_handle_console(key);
            continue;
        }
        else if (!isTitle && gChatOpen)
        {
            input_handle_chat(key);
            continue;
        }

        key |= gInputPlaceObjectModifier << 8;

        rct_window * w = window_find_by_class(WC_TEXTINPUT);
        if (w != nullptr)
        {
            char keychar = input_scancode_to_rct_keycode(key & 0xFF);
            window_text_input_key(w, keychar);
        }
        else if (!gUsingWidgetTextBox)
        {
            w = window_find_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
            if (w != nullptr)
            {
                keyboard_shortcuts_set(key);
                window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
                window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST);
            }
            else
            {
                keyboard_shortcut_handle(key);
            }
        }
    }
}
Beispiel #20
0
/**
 *
 *  rct2: 0x006E8DA7
 */
void input_state_widget_pressed(sint32 x, sint32 y, sint32 state, rct_widgetindex widgetIndex, rct_window *w, rct_widget *widget)
{
	rct_windowclass cursor_w_class;
	rct_windownumber cursor_w_number;
	cursor_w_class = gPressedWidget.window_classification;
	cursor_w_number = gPressedWidget.window_number;
	rct_widgetindex cursor_widgetIndex = gPressedWidget.widget_index;

	rct_window *cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
	if (cursor_w == NULL) {
		_inputState = INPUT_STATE_RESET;
		return;
	}

	switch (state) {
	case MOUSE_STATE_RELEASED:
		if (!w || cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
			break;

		if (w->disabled_widgets & (1ULL << widgetIndex))
			break;

		if (_clickRepeatTicks != 0) {
			_clickRepeatTicks++;

			// Handle click repeat
			if (_clickRepeatTicks >= 16 && (_clickRepeatTicks & 3) != 0) {
				if (w->hold_down_widgets & (1ULL << widgetIndex)) {
					window_event_mouse_down_call(w, widgetIndex);
				}
			}
		}

		if (_inputFlags & INPUT_FLAG_WIDGET_PRESSED) {
			if (_inputState == INPUT_STATE_DROPDOWN_ACTIVE) {
				gDropdownHighlightedIndex = gDropdownDefaultIndex;
				window_invalidate_by_class(WC_DROPDOWN);
			}
			return;
		}

		_inputFlags |= INPUT_FLAG_WIDGET_PRESSED;
		widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
		return;
	case MOUSE_STATE_LEFT_RELEASE:
	case MOUSE_STATE_RIGHT_PRESS:
		if (_inputState == INPUT_STATE_DROPDOWN_ACTIVE) {
			if (w) {
				sint32 dropdown_index = 0;

				if (w->classification == WC_DROPDOWN) {
					dropdown_index = dropdown_index_from_point(x, y, w);
					if (dropdown_index == -1) {
						goto dropdown_cleanup;
					}

					if (dropdown_index < 64 && gDropdownItemsDisabled & (1ULL << dropdown_index)) {
						goto dropdown_cleanup;
					}

					if (gDropdownItemsFormat[dropdown_index] == 0) {
						goto dropdown_cleanup;
					}
				}
				else {
					if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
						goto dropdown_cleanup;
					dropdown_index = -1;
					if (_inputFlags & INPUT_FLAG_DROPDOWN_STAY_OPEN){
						if (!(_inputFlags & INPUT_FLAG_DROPDOWN_MOUSE_UP)){
							_inputFlags |= INPUT_FLAG_DROPDOWN_MOUSE_UP;
							return;
						}
					}
				}

				window_close_by_class(WC_DROPDOWN);
				cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
				if (_inputFlags & INPUT_FLAG_WIDGET_PRESSED) {
					_inputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
					widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
				}

				_inputState = INPUT_STATE_NORMAL;
				gTooltipTimeout = 0;
				gTooltipWidget.widget_index = cursor_widgetIndex;
				gTooltipWidget.window_classification = cursor_w_class;
				gTooltipWidget.window_number = cursor_w_number;

				if (dropdown_index == -1) {
					if (!dropdown_is_disabled(gDropdownDefaultIndex)) {
						dropdown_index = gDropdownDefaultIndex;
					}
				}
				window_event_dropdown_call(cursor_w, cursor_widgetIndex, dropdown_index);
			}
		dropdown_cleanup:
			window_close_by_class(WC_DROPDOWN);
		}
		if (state == MOUSE_STATE_RIGHT_PRESS) {
			return;
		}

		_inputState = INPUT_STATE_NORMAL;
		gTooltipTimeout = 0;
		gTooltipWidget.widget_index = cursor_widgetIndex;

		if (!w)
			break;

		if (!widget)
			break;

		sint32 mid_point_x = (widget->left + widget->right) / 2 + w->x;
		audio_play_sound_panned(5, mid_point_x, 0, 0, 0);
		if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
			break;

		if (w->disabled_widgets & (1ULL << widgetIndex))
			break;

		widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
		window_event_mouse_up_call(w, widgetIndex);
	default:
		return;
	}

	_clickRepeatTicks = 0;
	if (_inputState != INPUT_STATE_DROPDOWN_ACTIVE){
		// Hold down widget and drag outside of area??
		if (_inputFlags & INPUT_FLAG_WIDGET_PRESSED){
			_inputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
			widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
		}
		return;
	}

	gDropdownHighlightedIndex = -1;
	window_invalidate_by_class(WC_DROPDOWN);
	if (w == NULL) {
		return;
	}

	if (w->classification == WC_DROPDOWN){
		sint32 dropdown_index = dropdown_index_from_point(x, y, w);
		if (dropdown_index == -1) {
			return;
		}

		if (gDropdownIsColour && gDropdownLastColourHover != dropdown_index) {
			gDropdownLastColourHover = dropdown_index;
			window_tooltip_close();

			static const rct_string_id colourTooltips[] = {
				STR_COLOUR_BLACK_TIP,
				STR_COLOUR_GREY_TIP,
				STR_COLOUR_WHITE_TIP,
				STR_COLOUR_DARK_PURPLE_TIP,
				STR_COLOUR_LIGHT_PURPLE_TIP,
				STR_COLOUR_BRIGHT_PURPLE_TIP,
				STR_COLOUR_DARK_BLUE_TIP,
				STR_COLOUR_LIGHT_BLUE_TIP,
				STR_COLOUR_ICY_BLUE_TIP,
				STR_COLOUR_TEAL_TIP,
				STR_COLOUR_AQUAMARINE_TIP,
				STR_COLOUR_SATURATED_GREEN_TIP,
				STR_COLOUR_DARK_GREEN_TIP,
				STR_COLOUR_MOSS_GREEN_TIP,
				STR_COLOUR_BRIGHT_GREEN_TIP,
				STR_COLOUR_OLIVE_GREEN_TIP,
				STR_COLOUR_DARK_OLIVE_GREEN_TIP,
				STR_COLOUR_BRIGHT_YELLOW_TIP,
				STR_COLOUR_YELLOW_TIP,
				STR_COLOUR_DARK_YELLOW_TIP,
				STR_COLOUR_LIGHT_ORANGE_TIP,
				STR_COLOUR_DARK_ORANGE_TIP,
				STR_COLOUR_LIGHT_BROWN_TIP,
				STR_COLOUR_SATURATED_BROWN_TIP,
				STR_COLOUR_DARK_BROWN_TIP,
				STR_COLOUR_SALMON_PINK_TIP,
				STR_COLOUR_BORDEAUX_RED_TIP,
				STR_COLOUR_SATURATED_RED_TIP,
				STR_COLOUR_BRIGHT_RED_TIP,
				STR_COLOUR_DARK_PINK_TIP,
				STR_COLOUR_BRIGHT_PINK_TIP,
				STR_COLOUR_LIGHT_PINK_TIP,
			};

			window_tooltip_show(colourTooltips[dropdown_index], x, y);
		}

		if (dropdown_index < 64 && gDropdownItemsDisabled & (1ULL << dropdown_index)) {
			return;
		}

		if (gDropdownItemsFormat[dropdown_index] == 0) {
			return;
		}

		gDropdownHighlightedIndex = dropdown_index;
		window_invalidate_by_class(WC_DROPDOWN);
	} else {
		gDropdownLastColourHover = -1;
		window_tooltip_close();
	}
}
Beispiel #21
0
/**
 *
 *  rct2: 0x006E8DA7
 */
void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_window *w, rct_widget *widget)
{
	RCT2_GLOBAL(0x1420054, uint16) = x;
	RCT2_GLOBAL(0x1420056, uint16) = y;

	rct_windowclass cursor_w_class;
	rct_windownumber cursor_w_number;
	cursor_w_class = gPressedWidget.window_classification;
	cursor_w_number = gPressedWidget.window_number;
	int cursor_widgetIndex = gPressedWidget.widget_index;

	rct_window *cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
	if (cursor_w == NULL) {
		gInputState = INPUT_STATE_RESET;
		return;
	}

	switch (state) {
	case MOUSE_STATE_RELEASED:
		if (!w || cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
			break;

		if (w->disabled_widgets & (1ULL << widgetIndex))
			break;

		if (RCT2_GLOBAL(0x009DE528, uint16) != 0)
			RCT2_GLOBAL(0x009DE528, uint16)++;

		if (w->hold_down_widgets & (1ULL << widgetIndex) &&
			RCT2_GLOBAL(0x009DE528, uint16) >= 16 &&
			!(RCT2_GLOBAL(0x009DE528, uint16) & 3)
			) {
			window_event_mouse_down_call(w, widgetIndex);
		}

		if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED) {
			if (gInputState == INPUT_STATE_DROPDOWN_ACTIVE) {
				gDropdownHighlightedIndex = gDropdownDefaultIndex;
				window_invalidate_by_class(WC_DROPDOWN);
			}
			return;
		}

		gInputFlags |= INPUT_FLAG_WIDGET_PRESSED;
		widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
		return;
	case MOUSE_STATE_LEFT_RELEASE:
	case MOUSE_STATE_RIGHT_PRESS:
		if (gInputState == INPUT_STATE_DROPDOWN_ACTIVE) {
			if (w) {
				int dropdown_index = 0;

				if (w->classification == WC_DROPDOWN) {
					dropdown_index = dropdown_index_from_point(x, y, w);
					if (dropdown_index == -1) {
						goto dropdown_cleanup;
					}

					if (dropdown_index < 64 && gDropdownItemsDisabled & (1ULL << dropdown_index)) {
						goto dropdown_cleanup;
					}

					if (gDropdownItemsFormat[dropdown_index] == 0) {
						goto dropdown_cleanup;
					}
				}
				else {
					if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
						goto dropdown_cleanup;
					dropdown_index = -1;
					if (gInputFlags & INPUT_FLAG_DROPDOWN_STAY_OPEN){
						if (!(gInputFlags & INPUT_FLAG_DROPDOWN_MOUSE_UP)){
							gInputFlags |= INPUT_FLAG_DROPDOWN_MOUSE_UP;
							return;
						}
					}
				}

				window_close_by_class(WC_DROPDOWN);
				cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
				if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED) {
					gInputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
					widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
				}

				gInputState = INPUT_STATE_NORMAL;
				gTooltipTimeout = 0;
				gTooltipWidget.widget_index = cursor_widgetIndex;
				gTooltipWidget.window_classification = cursor_w_class;
				gTooltipWidget.window_number = cursor_w_number;

				if (dropdown_index == -1) {
					if (!dropdown_is_disabled(gDropdownDefaultIndex)) {
						dropdown_index = gDropdownDefaultIndex;
					}
				}
				window_event_dropdown_call(cursor_w, cursor_widgetIndex, dropdown_index);
			}
		dropdown_cleanup:
			window_close_by_class(WC_DROPDOWN);
		}
		if (state == MOUSE_STATE_RIGHT_PRESS) {
			return;
		}

		gInputState = INPUT_STATE_NORMAL;
		gTooltipTimeout = 0;
		gTooltipWidget.widget_index = cursor_widgetIndex;

		if (!w)
			break;

		if (!widget)
			break;

		int mid_point_x = (widget->left + widget->right) / 2 + w->x;
		audio_play_sound_panned(5, mid_point_x, 0, 0, 0);
		if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
			break;

		if (w->disabled_widgets & (1ULL << widgetIndex))
			break;

		widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
		window_event_mouse_up_call(w, widgetIndex);
	default:
		return;
	}

	RCT2_GLOBAL(0x009DE528, uint16) = 0;
	if (gInputState != INPUT_STATE_DROPDOWN_ACTIVE){
		// Hold down widget and drag outside of area??
		if (gInputFlags & INPUT_FLAG_WIDGET_PRESSED){
			gInputFlags &= ~INPUT_FLAG_WIDGET_PRESSED;
			widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
		}
		return;
	}

	gDropdownHighlightedIndex = -1;
	window_invalidate_by_class(WC_DROPDOWN);
	if (w == NULL) {
		return;
	}

	if (w->classification == WC_DROPDOWN){
		int dropdown_index = dropdown_index_from_point(x, y, w);
		if (dropdown_index == -1) {
			return;
		}

		if (gDropdownIsColour && gDropdownLastColourHover != dropdown_index) {
			gDropdownLastColourHover = dropdown_index;
			window_tooltip_close();
			window_tooltip_show(STR_COLOUR_NAMES_START + dropdown_index, x, y);
		}

		if (dropdown_index < 64 && gDropdownItemsDisabled & (1ULL << dropdown_index)) {
			return;
		}

		if (gDropdownItemsFormat[dropdown_index] == 0) {
			return;
		}

		gDropdownHighlightedIndex = dropdown_index;
		window_invalidate_by_class(WC_DROPDOWN);
	} else {
		gDropdownLastColourHover = -1;
		window_tooltip_close();
	}
}