Exemple #1
0
/*
 * 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;
	}
}