/* * AddNewLineAroundCurrent - put a new line on either side of the current line */ void AddNewLineAroundCurrent( char *data, int copylen, insert_dir dir ) { bool wasnull; /* * if inserting into a null fcb, clean it up */ FetchFcb( CurrentFcb ); wasnull = CurrentFcb->nullfcb; if( wasnull ) { MemFree( CurrentFcb->lines.head ); CurrentFcb->lines.head = CurrentFcb->lines.tail = NULL; CurrentFcb->nullfcb = FALSE; CurrentFcb->byte_cnt = 0; CurrentFcb->end_line = 0; } /* * add the line */ InsertNewLine( CurrentLine, &CurrentFcb->lines, data, copylen,dir ); CurrentFcb->byte_cnt += copylen + 1; CurrentFcb->end_line += 1; /* * update line info */ if( wasnull ) { CurrentLine = CurrentFcb->lines.head; SetCurrentLineNumber( 1 ); } else { if( dir == INSERT_BEFORE ) { SetCurrentLineNumber( CurrentPos.line + 1 ); } UpdateLineNumbers( 1L, CurrentFcb->next ); } CheckCurrentFcbCapacity(); } /* AddNewLineAroundCurrent */
void Window_Message::UpdateMessage() { // Message Box Show Message rendering loop // Contains at what frame the sleep is over static int sleep_until = -1; if (sleep_until > -1) { if (Graphics::GetFrameCount() >= sleep_until) { // Sleep over sleep_until = -1; } else { return; } } bool instant_speed = false; int loop_count = 0; int loop_max = speed_table[speed_modifier] == 0 ? 2 : 1; while (instant_speed || loop_count < loop_max) { // It's assumed that speed_modifier is between 0 and 20 ++speed_frame_counter; if (speed_table[speed_modifier] != 0 && speed_table[speed_modifier] != speed_frame_counter) { break; } speed_frame_counter = 0; ++loop_count; if (text_index == end) { FinishMessageProcessing(); break; } else if (line_count == 4) { pause = true; new_page_after_pause = true; break; } if (*text_index == '\n') { instant_speed = false; InsertNewLine(); if (pause) { break; } } else if (*text_index == '\f') { instant_speed = false; ++text_index; if (*text_index == '\n') { ++text_index; } if (text_index != end) { pause = true; new_page_after_pause = true; } break; } else if (*text_index == '\\' && std::distance(text_index, end) > 1) { // Special message codes ++text_index; std::string command_result; switch (tolower(*text_index)) { case 'c': case 'n': case 's': case 'v': // These commands support indirect access via \v[] command_result = ParseCommandCode(); contents->TextDraw(contents_x, contents_y, text_color, command_result); contents_x += contents->GetFont()->GetSize(command_result).width; break; case '\\': // Show Backslash contents->TextDraw(contents_x, contents_y, text_color, std::string("\\")); contents_x += contents->GetFont()->GetSize("\\").width; break; case '_': // Insert half size space contents_x += contents->GetFont()->GetSize(" ").width / 2; break; case '$': // Show Gold Window gold_window->SetY(y == 0 ? 240 - 32 : 0); gold_window->Refresh(); gold_window->SetOpenAnimation(5); gold_window->SetVisible(true); break; case '!': // Text pause pause = true; break; case '^': // Force message close // The close happens at the end of the message, not where // the ^ is encoutered kill_message = true; break; case '>': // Instant speed start instant_speed = true; break; case '<': // Instant speed stop instant_speed = false; break; case '.': // 1/4 second sleep sleep_until = Graphics::GetFrameCount() + 60 / 4; ++text_index; return; break; case '|': // Second sleep sleep_until = Graphics::GetFrameCount() + 60; ++text_index; return; break; default:; } } else if (*text_index == '$' && std::distance(text_index, end) > 1 && std::isalpha(*boost::next(text_index))) { // ExFont contents->TextDraw(contents_x, contents_y, text_color, std::string(text_index.base(), boost::next(text_index, 2).base())); contents_x += 12; ++text_index; } else { std::string const glyph(text_index.base(), boost::next(text_index).base()); contents->TextDraw(contents_x, contents_y, text_color, glyph); contents_x += contents->GetFont()->GetSize(glyph).width; } ++text_index; } loop_count = 0; }
void Window_Message::UpdateMessage() { // Message Box Show Message rendering loop // Contains at what frame the sleep is over static int sleep_until = -1; bool instant_speed = false; if (Player::debug_flag && Input::IsPressed(Input::SHIFT)) { sleep_until = -1; instant_speed = true; } if (sleep_until > -1) { if (Player::GetFrames() >= sleep_until) { // Sleep over sleep_until = -1; } else { return; } } int loop_count = 0; int loop_max = speed_table[speed_modifier] == 0 ? 2 : 1; while (instant_speed || loop_count < loop_max) { if (!instant_speed) { // It's assumed that speed_modifier is between 0 and 20 ++speed_frame_counter; if (speed_table[speed_modifier] != 0 && speed_table[speed_modifier] != speed_frame_counter) { break; } speed_frame_counter = 0; } ++loop_count; if (text_index == end) { FinishMessageProcessing(); break; } else if (line_count == 4) { pause = true; new_page_after_pause = true; break; } else if (pause) { break; } if (*text_index == '\n') { if (instant_speed) { // instant_speed stops at the end of the line, unless // there's a /> at the beginning of the next line if (std::distance(text_index, end) > 2 && *(text_index + 1) == escape_char && *(text_index + 2) == '>') { text_index += 2; } else { instant_speed = false; } } InsertNewLine(); } else if (*text_index == '\f') { instant_speed = false; ++text_index; if (*text_index == '\n') { ++text_index; } if (text_index != end) { pause = true; new_page_after_pause = true; } break; } else if (*text_index == escape_char && std::distance(text_index, end) > 1) { // Special message codes ++text_index; int parameter; bool is_valid; switch (tolower(*text_index)) { case 'c': // Color parameter = ParseParameter(is_valid); text_color = parameter > 19 ? 0 : parameter; break; case 's': // Speed modifier parameter = ParseParameter(is_valid); speed_modifier = max(0, min(parameter, 20)); break; case '_': // Insert half size space contents_x += contents->GetFont()->GetSize(" ").width / 2; break; case '$': // Show Gold Window ShowGoldWindow(); break; case '!': // Text pause pause = true; break; case '^': // Force message close // The close happens at the end of the message, not where // the ^ is encountered kill_message = true; break; case '>': // Instant speed start instant_speed = true; break; case '<': // Instant speed stop instant_speed = false; break; case '.': // 1/4 second sleep if (instant_speed) break; sleep_until = Player::GetFrames() + 60 / 4; ++text_index; return; case '|': // Second sleep if (instant_speed) break; sleep_until = Player::GetFrames() + 60; ++text_index; return; case '\n': case '\f': // \ followed by linebreak, don't skip them --text_index; break; default: if (*text_index == escape_char) { // Show Escape Symbol contents->TextDraw(contents_x, contents_y, text_color, Player::escape_symbol); contents_x += contents->GetFont()->GetSize(Player::escape_symbol).width; } } } else if (*text_index == '$' && std::distance(text_index, end) > 1 && std::isalpha(*std::next(text_index))) { // ExFont std::string const glyph(Utils::EncodeUTF(std::u32string(text_index, std::next(text_index, 2)))); contents->TextDraw(contents_x, contents_y, text_color, glyph); contents_x += 12; ++loop_count; ++text_index; } else { std::string const glyph(Utils::EncodeUTF(std::u32string(text_index, std::next(text_index)))); contents->TextDraw(contents_x, contents_y, text_color, glyph); int glyph_width = contents->GetFont()->GetSize(glyph).width; // Show full-width characters twice as slow as half-width characters if (glyph_width >= 12) loop_count++; contents_x += glyph_width; } ++text_index; } }