// This method is the same as gfx_draw_string_left_wrapped. // But this adjusts the initial Y coordinate depending of the number of lines. int32_t chat_history_draw_string(rct_drawpixelinfo* dpi, void* args, int32_t x, int32_t y, int32_t width) { int32_t fontSpriteBase, lineHeight, lineY, numLines; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_draw_string(dpi, (char*)"", TEXT_COLOUR_255, dpi->x, dpi->y); char* buffer = gCommonStringFormatBuffer; format_string(buffer, 256, STR_STRING, args); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); lineHeight = font_get_line_height(fontSpriteBase); gCurrentFontFlags = 0; int32_t expectedY = y - (numLines * lineHeight); if (expectedY < 50) { return (numLines * lineHeight); // Skip drawing, return total height. } lineY = y; for (int32_t line = 0; line <= numLines; ++line) { gfx_draw_string(dpi, buffer, TEXT_COLOUR_254, x, lineY - (numLines * lineHeight)); buffer = get_string_end(buffer) + 1; lineY += lineHeight; } return lineY - y; }
// Wrap string without drawing, useful to get the height of a wrapped string. // Almost the same as gfx_draw_string_left_wrapped sint32 chat_string_wrapped_get_height(void *args, sint32 width) { sint32 fontSpriteBase, lineHeight, lineY, numLines; gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; char *buffer = gCommonStringFormatBuffer; format_string(buffer, 256, STR_STRING, args); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); lineHeight = font_get_line_height(fontSpriteBase); gCurrentFontFlags = 0; lineY = 0; for (sint32 line = 0; line <= numLines; ++line) { buffer = get_string_end(buffer) + 1; lineY += lineHeight; } return lineY; }
/** * * 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); } }