Esempio n. 1
0
/* _count_lines - sees how many lines a given input string would take to
 * display given the line wrapping information
 */
static int
_count_lines (TEXT *pText)
{
	SIZE text_width;
	const char *pStr;
	int numLines = 0;
	BOOLEAN eol;

	text_width = CommData.AlienTextWidth;
	SetContextFont (CommData.AlienFont);

	pStr = pText->pStr;
	do
	{
		++numLines;
		pText->pStr = pStr;
		eol = getLineWithinWidth (pText, &pStr, text_width, (COUNT)~0);
	} while (!eol);
	pText->pStr = pStr;

	return numLines;
}
Esempio n. 2
0
static BOOLEAN
DoConvSummary (SUMMARY_STATE *pSS)
{
#define DELTA_Y_SUMMARY RES_SCALE(8) // JMS_GFX
	//#define MAX_SUMM_ROWS ((SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT) / DELTA_Y_SUMMARY
#define MAX_SUMM_ROWS (SLIDER_Y	/ DELTA_Y_SUMMARY) - 1 // JMS_GFX

	if (!pSS->Initialized)
	{
		pSS->PrintNext = TRUE;
		pSS->NextSub = GetFirstTrackSubtitle ();
		pSS->LeftOver = NULL;
		pSS->InputFunc = DoConvSummary;
		pSS->Initialized = TRUE;
		DoInput (pSS, FALSE);
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE; // bail out
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT]
			|| PulsedInputState.menu[KEY_MENU_CANCEL]
			|| PulsedInputState.menu[KEY_MENU_RIGHT])
	{
		if (pSS->NextSub)
		{	// we want the next page
			pSS->PrintNext = TRUE;
		}
		else
		{	// no more, we are done
			return FALSE;
		}
	}
	else if (pSS->PrintNext)
	{	// print the next page
		RECT r;
		TEXT t;
		int row;

		r.corner.x = 0;
		r.corner.y = 0;
		r.extent.width = SIS_SCREEN_WIDTH;
		r.extent.height = SLIDER_Y; //SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT + RES_SCALE(2) + 16 * RESOLUTION_FACTOR; // JMS_GFX

		SetContext (AnimContext);
		SetContextForeGroundColor (COMM_HISTORY_BACKGROUND_COLOR);
		DrawFilledRectangle (&r);

		SetContextForeGroundColor (COMM_HISTORY_TEXT_COLOR);

		r.extent.width -= 2 + 2;
		t.baseline.x = RES_SCALE(2); // JMS_GFX
		t.align = ALIGN_LEFT;
		t.baseline.y = DELTA_Y_SUMMARY;
		SetContextFont (TinyFont);

		for (row = 0; row < MAX_SUMM_ROWS && pSS->NextSub;
				++row, pSS->NextSub = GetNextTrackSubtitle (pSS->NextSub))
		{
			const char *next = NULL;

			if (pSS->LeftOver)
			{	// some text left from last subtitle
				t.pStr = pSS->LeftOver;
				pSS->LeftOver = NULL;
			}
			else
			{
				t.pStr = GetTrackSubtitleText (pSS->NextSub);
				if (!t.pStr)
					continue;
			}

			t.CharCount = (COUNT)~0;
			for ( ; row < MAX_SUMM_ROWS && !getLineWithinWidth (&t, &next, r.extent.width, (COUNT)~0); ++row) {
				if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz
					UNICODE my_copy[128];
					strcpy(my_copy, t.pStr);
					remove_char_from_string(my_copy, '$');
					t.pStr = my_copy;
					font_DrawText(&t);
				} else { // Normal mode
					font_DrawText(&t);
				}
				t.baseline.y += DELTA_Y_SUMMARY;
				t.pStr = next;
				t.CharCount = (COUNT)~0;
			}

			if (row >= MAX_SUMM_ROWS)
			{	// no more space on screen, but some text left over
				// from the current subtitle
				pSS->LeftOver = next;
				break;
			}
		
			// this subtitle fit completely
			if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz
				UNICODE my_copy[128];
				strcpy(my_copy, t.pStr);
				remove_char_from_string(my_copy, '$');
				t.pStr = my_copy;
				font_DrawText(&t);
			} else { // Normal mode
				font_DrawText(&t);
			}
			t.baseline.y += DELTA_Y_SUMMARY;
		}

		if (row >= MAX_SUMM_ROWS && (pSS->NextSub || pSS->LeftOver))
		{	// draw *MORE*
			TEXT mt;
			UNICODE buffer[128];

			mt.baseline.x = SIS_SCREEN_WIDTH >> 1;
			mt.baseline.y = t.baseline.y;
			mt.align = ALIGN_CENTER;
			snprintf (buffer, sizeof (buffer), "%s%s%s", // "MORE"
					STR_MIDDLE_DOT, GAME_STRING (FEEDBACK_STRING_BASE + 1),
					STR_MIDDLE_DOT);

			if (CommData.AlienConv == ORZ_CONVERSATION) { // MB: nasty hack: remove '$'s from conversation for Orz
				remove_char_from_string(buffer, '$');
			}

			mt.pStr = buffer;
			SetContextForeGroundColor (COMM_MORE_TEXT_COLOR);
			font_DrawText (&mt);
		}
Esempio n. 3
0
// status == -1: draw highlighted player dialog option
// status == -2: draw non-highlighted player dialog option
// status == -4: use current context, and baseline from pTextIn
// status ==  1:  draw alien speech; subtitle cache is used
static COORD
add_text (int status, TEXT *pTextIn)
{
	COUNT maxchars, numchars;
	TEXT locText;
	TEXT *pText;
	SIZE leading;
	const char *pStr;
	SIZE text_width;
	int num_lines = 0;
	static COORD last_baseline;
	BOOLEAN eol;
	CONTEXT OldContext = NULL;
	COUNT computerOn = 0;
	
	BatchGraphics ();

	maxchars = (COUNT)~0;
	if (status == 1)
	{
		if (last_subtitle == pTextIn->pStr)
		{
			// draws cached subtitle
			STAMP s;

			s.origin.x = 0;
			s.origin.y = 0;
			s.frame = TextCacheFrame;
			DrawStamp (&s);
			UnbatchGraphics ();
			return last_baseline;
		}
		else
		{
			// draw to subtitle cache; prepare first
			OldContext = SetContext (TextCacheContext);
			ClearDrawable ();

			last_subtitle = pTextIn->pStr;
		}

		text_width = CommData.AlienTextWidth;
		SetContextFont (CommData.AlienFont);
		GetContextFontLeading (&leading);

		pText = pTextIn;
	}
	else if (GetContextFontLeading (&leading), status <= -4)
	{
		text_width = (SIZE) (SIS_SCREEN_WIDTH - RES_SCALE(8) - (TEXT_X_OFFS << 2)); // JMS_GFX

		pText = pTextIn;
	}
	else
	{
		text_width = (SIZE) (SIS_SCREEN_WIDTH - RES_SCALE(8) - (TEXT_X_OFFS << 2)); // JMS_GFX

		switch (status)
		{
			case -3:
				// Unknown. Never reached; color matches the background color.
				SetContextForeGroundColor (
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
				break;
			case -2:
				// Not highlighted dialog options.
				SetContextForeGroundColor (COMM_PLAYER_TEXT_NORMAL_COLOR);
				break;
			case -1:
				// Currently highlighted dialog option.
				SetContextForeGroundColor (COMM_PLAYER_TEXT_HIGHLIGHT_COLOR);
				break;
		}

		maxchars = pTextIn->CharCount;
		locText = *pTextIn;
		locText.baseline.x -= RES_SCALE(8) - 4 * RESOLUTION_FACTOR; // JMS_GFX
		locText.CharCount = (COUNT)~0;
		locText.pStr = STR_BULLET;
		font_DrawText (&locText);

		locText = *pTextIn;
		pText = &locText;
		pText->baseline.y -= leading;
	}

	numchars = 0;
	pStr = pText->pStr;

	if (status > 0 && (CommData.AlienTextValign &
			(VALIGN_MIDDLE | VALIGN_BOTTOM)))
	{
		num_lines = _count_lines(pText);
		if (CommData.AlienTextValign == VALIGN_BOTTOM)
			pText->baseline.y -= (leading * num_lines);
		else if (CommData.AlienTextValign == VALIGN_MIDDLE)
			pText->baseline.y -= ((leading * num_lines) / 2);
		if (pText->baseline.y < 0)
			pText->baseline.y = 0;
	}

	do
	{
		pText->pStr = pStr;
		pText->baseline.y += leading;

		eol = getLineWithinWidth (pText, &pStr, text_width, maxchars);

		maxchars -= pText->CharCount;
		if (maxchars != 0)
			--maxchars;
		numchars += pText->CharCount;
		
		if (status <= 0)
		{
			// Player dialog option or (status == -4) other non-alien
			// text.
			if (pText->baseline.y < SIS_SCREEN_HEIGHT)
				font_DrawText (pText);

			if (status < -4 && pText->baseline.y >= -status - 10)
			{
				// Never actually reached. Status is never <-4.
				++pStr;
				break;
			}
		}
		else
		{
			// Alien speech
			if (CommData.AlienConv == ORZ_CONVERSATION)
			{
				// BW : special case for the Orz conversations
				// the character $ is recycled as a marker to
				// switch from and to computer font
				
				const char *ptr;
				RECT rect;
				COORD baselinex = pText->baseline.x;
				COORD width = 0;
				COUNT remChars = pText->CharCount;
			        // Remaining chars until end of line within width
				const char *bakptr;
				COUNT bakChars = remChars;
				COUNT bakcompOn = computerOn;
				FONT bakFont = SetContextFont(ComputerFont);
				
				SetContextFont(bakFont);
				ptr = pText->pStr;
				bakptr = ptr;
				
				// We need to manually center the line because
				// the computer font is larger than the Orzfont
				
				// This loop computes the width of the line
				while (remChars > 0)
					{
						while ((*ptr != '$') && remChars > 0)
							{
								getCharFromString (&ptr);
								remChars--;
							}
						
						pText->CharCount -= remChars;
						TextRect (pText, &rect, NULL);
						
						width += rect.extent.width;
						
						if (*ptr == '$')
							{
								getCharFromString (&ptr);
								remChars--;
								computerOn = 1 - computerOn;
								if (computerOn)
									SetContextFont (ComputerFont);
								else
									SetContextFont (CommData.AlienFont);
							}
						pText->CharCount = remChars;
						pText->pStr = ptr;
					}

				// This to simulate a centered line
				pText->baseline.x = baselinex - (width >> 1);
				pText->align = ALIGN_LEFT;
				
				// Put everything back in place for the
				// actual display 
				remChars = bakChars;
				pText->CharCount = bakChars;
				ptr = bakptr;
				pText->pStr = bakptr;
				computerOn = bakcompOn;
				SetContextFont(bakFont);
				
				// This loop is used to look up for $
				while (remChars > 0)
					{
						while ((*ptr != '$') && remChars > 0)
							{
								getCharFromString (&ptr);
								remChars--;
							}
						
						pText->CharCount -= remChars;
						TextRect (pText, &rect, NULL);
						
						font_DrawTracedText (pText,
								     CommData.AlienTextFColor, CommData.AlienTextBColor);
						
						pText->baseline.x += rect.extent.width;
						
						if (*ptr == '$')
							{
								getCharFromString (&ptr);
								remChars--;
								computerOn = 1 - computerOn;
								if (computerOn)
									SetContextFont (ComputerFont);
								else
									SetContextFont (CommData.AlienFont);
							}
						pText->CharCount = remChars;
						pText->pStr = ptr;
					}
				pText->baseline.x = baselinex;
				pText->align = ALIGN_CENTER;
			}
			else
			{
				// Normal case : other races than Orz
				font_DrawTracedText (pText, CommData.AlienTextFColor, CommData.AlienTextBColor);
			}
		}
	} while (!eol && maxchars);
	pText->pStr = pStr;

	if (status == 1)
	{
		STAMP s;
		
		// We were drawing to cache -- flush to screen
		SetContext (OldContext);
		s.origin.x = s.origin.y = 0;
		s.frame = TextCacheFrame;
		DrawStamp (&s);
		
		last_baseline = pText->baseline.y;
	}

	UnbatchGraphics ();
	return (pText->baseline.y);
}
Esempio n. 4
0
// status == -1: draw highlighted player dialog option
// status == -2: draw non-highlighted player dialog option
// status == -4: use current context, and baseline from pTextIn
// status ==  1:  draw alien speech; subtitle cache is used
static COORD
add_text (int status, TEXT *pTextIn)
{
	COUNT maxchars, numchars;
	TEXT locText;
	TEXT *pText;
	SIZE leading;
	const char *pStr;
	SIZE text_width;
	int num_lines = 0;
	static COORD last_baseline;
	BOOLEAN eol;
	CONTEXT OldContext = NULL;
	
	BatchGraphics ();

	maxchars = (COUNT)~0;
	if (status == 1)
	{
		if (last_subtitle == pTextIn->pStr)
		{
			// draws cached subtitle
			STAMP s;

			s.origin.x = 0;
			s.origin.y = 0;
			s.frame = TextCacheFrame;
			DrawStamp (&s);
			UnbatchGraphics ();
			return last_baseline;
		}
		else
		{
			// draw to subtitle cache; prepare first
			OldContext = SetContext (TextCacheContext);
			ClearDrawable ();

			last_subtitle = pTextIn->pStr;
		}

		text_width = CommData.AlienTextWidth;
		SetContextFont (CommData.AlienFont);
		GetContextFontLeading (&leading);

		pText = pTextIn;
	}
	else if (GetContextFontLeading (&leading), status <= -4)
	{
		text_width = (SIZE) (SIS_SCREEN_WIDTH - 8 - (TEXT_X_OFFS << 2));

		pText = pTextIn;
	}
	else
	{
		text_width = (SIZE) (SIS_SCREEN_WIDTH - 8 - (TEXT_X_OFFS << 2));

		switch (status)
		{
			case -3:
				// Unknown. Never reached; color matches the background color.
				SetContextForeGroundColor (
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
				break;
			case -2:
				// Not highlighted dialog options.
				SetContextForeGroundColor (COMM_PLAYER_TEXT_NORMAL_COLOR);
				break;
			case -1:
				// Currently highlighted dialog option.
				SetContextForeGroundColor (COMM_PLAYER_TEXT_HIGHLIGHT_COLOR);
				break;
		}

		maxchars = pTextIn->CharCount;
		locText = *pTextIn;
		locText.baseline.x -= 8;
		locText.CharCount = (COUNT)~0;
		locText.pStr = STR_BULLET;
		font_DrawText (&locText);

		locText = *pTextIn;
		pText = &locText;
		pText->baseline.y -= leading;
	}

	numchars = 0;
	pStr = pText->pStr;

	if (status > 0 && (CommData.AlienTextValign &
			(VALIGN_MIDDLE | VALIGN_BOTTOM)))
	{
		num_lines = _count_lines(pText);
		if (CommData.AlienTextValign == VALIGN_BOTTOM)
			pText->baseline.y -= (leading * num_lines);
		else if (CommData.AlienTextValign == VALIGN_MIDDLE)
			pText->baseline.y -= ((leading * num_lines) / 2);
		if (pText->baseline.y < 0)
			pText->baseline.y = 0;
	}

	do
	{
		pText->pStr = pStr;
		pText->baseline.y += leading;

		eol = getLineWithinWidth (pText, &pStr, text_width, maxchars);

		maxchars -= pText->CharCount;
		if (maxchars != 0)
			--maxchars;
		numchars += pText->CharCount;
		
		if (status <= 0)
		{
			// Player dialog option or (status == -4) other non-alien
			// text.
			if (pText->baseline.y < SIS_SCREEN_HEIGHT)
				font_DrawText (pText);

			if (status < -4 && pText->baseline.y >= -status - 10)
			{
				// Never actually reached. Status is never <-4.
				++pStr;
				break;
			}
		}
		else
		{
			// Alien speech
			font_DrawTracedText (pText,
					CommData.AlienTextFColor, CommData.AlienTextBColor);
		}
	} while (!eol && maxchars);
	pText->pStr = pStr;

	if (status == 1)
	{
		STAMP s;
		
		// We were drawing to cache -- flush to screen
		SetContext (OldContext);
		s.origin.x = s.origin.y = 0;
		s.frame = TextCacheFrame;
		DrawStamp (&s);
		
		last_baseline = pText->baseline.y;
	}

	UnbatchGraphics ();
	return (pText->baseline.y);
}