void window_tooltip_show(rct_string_id id, int x, int y) { rct_window *w; int width, height; w = window_find_by_class(WC_ERROR); if (w != NULL) return; RCT2_GLOBAL(0x0142006C, sint32) = -1; char* buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); format_string(buffer, id, (void*)0x013CE952); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM; int tooltip_text_width; tooltip_text_width = gfx_get_string_width_new_lined(buffer); buffer = RCT2_ADDRESS(RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER, char); tooltip_text_width = min(tooltip_text_width, 196); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = FONT_SPRITE_BASE_MEDIUM; int numLines, fontSpriteBase; tooltip_text_width = gfx_wrap_string(buffer, tooltip_text_width + 1, &numLines, &fontSpriteBase); RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_TEXT_HEIGHT, sint16) = numLines; width = tooltip_text_width + 3; height = ((numLines + 1) * font_get_line_height(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16))) + 4; window_tooltip_widgets[WIDX_BACKGROUND].right = width; window_tooltip_widgets[WIDX_BACKGROUND].bottom = height; memcpy(gTooltip_text_buffer, buffer, 512); x = clamp(0, x - (width / 2), RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) - width); int max_y = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - height; y += 26; // Normally, we'd display the tooltip 26 lower if (y > max_y) // If y is too large, the tooltip could be forced below the cursor if we'd just clamped y, // so we'll subtract a bit more y -= height + 40; y = clamp(22, y, max_y); w = window_create( x, y, width, height, &window_tooltip_events, WC_TOOLTIP, WF_TRANSPARENT | WF_STICK_TO_FRONT ); w->widgets = window_tooltip_widgets; RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, uint16) = 0; }
void window_tooltip_show(rct_string_id id, int32_t x, int32_t y) { rct_window* w; int32_t width, height; w = window_find_by_class(WC_ERROR); if (w != nullptr) return; char* buffer = gCommonStringFormatBuffer; format_string(buffer, sizeof(gCommonStringFormatBuffer), id, gCommonFormatArgs); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; int32_t tooltip_text_width; tooltip_text_width = gfx_get_string_width_new_lined(buffer); buffer = gCommonStringFormatBuffer; tooltip_text_width = std::min(tooltip_text_width, 196); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; int32_t numLines, fontSpriteBase; tooltip_text_width = gfx_wrap_string(buffer, tooltip_text_width + 1, &numLines, &fontSpriteBase); _tooltipNumLines = numLines; width = tooltip_text_width + 3; height = ((numLines + 1) * font_get_line_height(gCurrentFontSpriteBase)) + 4; window_tooltip_widgets[WIDX_BACKGROUND].right = width; window_tooltip_widgets[WIDX_BACKGROUND].bottom = height; std::memcpy(_tooltipText, buffer, sizeof(_tooltipText)); int32_t screenWidth = context_get_width(); int32_t screenHeight = context_get_height(); x = std::clamp(x - (width / 2), 0, screenWidth - width); // TODO The cursor size will be relative to the window DPI. // The amount to offset the y should be adjusted. int32_t max_y = screenHeight - height; y += 26; // Normally, we'd display the tooltip 26 lower if (y > max_y) // If y is too large, the tooltip could be forced below the cursor if we'd just clamped y, // so we'll subtract a bit more y -= height + 40; y = std::clamp(y, 22, max_y); w = window_create(x, y, width, height, &window_tooltip_events, WC_TOOLTIP, WF_TRANSPARENT | WF_STICK_TO_FRONT); w->widgets = window_tooltip_widgets; reset_tooltip_not_shown(); }
/** * * rct2: 0x0066792F * * bx: title * dx: message */ void window_error_open(rct_string_id title, rct_string_id message) { utf8 *dst; char *args; int numLines, fontHeight, x, y, width, height, maxY; rct_window *w; window_close_by_class(WC_ERROR); dst = _window_error_text; args = (char*)0x0013CE952; // Format the title dst = utf8_write_codepoint(dst, FORMAT_BLACK); if (title != (rct_string_id)STR_NONE) { format_string(dst, title, args); dst = get_string_end(dst); } // Format the message if (message != (rct_string_id)STR_NONE) { dst = utf8_write_codepoint(dst, FORMAT_NEWLINE); format_string(dst, message, args); dst = get_string_end(dst); } log_verbose("show error, %s", _window_error_text + 1); // Check if there is any text to display if (dst == _window_error_text + 1) return; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; width = gfx_get_string_width_new_lined(_window_error_text); width = min(196, width); RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; gfx_wrap_string(_window_error_text, width + 1, &numLines, &fontHeight); _window_error_num_lines = numLines; width = width + 3; height = (numLines + 1) * 10 + 4; window_error_widgets[WIDX_BACKGROUND].right = width; window_error_widgets[WIDX_BACKGROUND].bottom = height; x = RCT2_GLOBAL(0x0142406C, sint32) - (width / 2); x = clamp(0, x, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16)); y = RCT2_GLOBAL(0x01424070, sint32) + 26; y = max(22, y); maxY = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) - height; if (y > maxY) { y = y - height - 40; y = min(y, maxY); } w = window_create(x, y, width, height, &window_error_events, WC_ERROR, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_RESIZABLE); w->widgets = window_error_widgets; w->error.var_480 = 0; if (!(RCT2_GLOBAL(0x009A8C29, uint8) & 1)) sound_play_panned(SOUND_ERROR, 0, w->x + (w->width / 2), 0, 0); }
/** * * rct2: 0x0066792F * * bx: title * dx: message */ void window_error_open(rct_string_id title, rct_string_id message) { utf8 *dst; sint32 numLines, fontHeight, x, y, width, height, maxY; rct_window *w; window_close_by_class(WC_ERROR); dst = _window_error_text; // Format the title dst = utf8_write_codepoint(dst, FORMAT_BLACK); if (title != STR_NONE) { format_string(dst, 512 - (dst - _window_error_text), title, gCommonFormatArgs); dst = get_string_end(dst); } // Format the message if (message != STR_NONE) { dst = utf8_write_codepoint(dst, FORMAT_NEWLINE); format_string(dst, 512 - (dst - _window_error_text), message, gCommonFormatArgs); dst = get_string_end(dst); } log_verbose("show error, %s", _window_error_text + 1); // Check if there is any text to display if (dst == _window_error_text + 1) return; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; width = gfx_get_string_width_new_lined(_window_error_text); width = min(196, width); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(_window_error_text, width + 1, &numLines, &fontHeight); _window_error_num_lines = numLines; width = width + 3; height = (numLines + 1) * 10 + 4; window_error_widgets[WIDX_BACKGROUND].right = width; window_error_widgets[WIDX_BACKGROUND].bottom = height; x = gCursorState.x - (width / 2); x = clamp(0, x, gScreenWidth); y = gCursorState.y + 26; y = max(22, y); maxY = gScreenHeight - height; if (y > maxY) { y = y - height - 40; y = min(y, maxY); } w = window_create(x, y, width, height, &window_error_events, WC_ERROR, WF_STICK_TO_FRONT | WF_TRANSPARENT | WF_RESIZABLE); w->widgets = window_error_widgets; w->error.var_480 = 0; if (!gDisableErrorWindowSound) { audio_play_sound_panned(SOUND_ERROR, 0, w->x + (w->width / 2), 0, 0); } }