rem: TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0, TFB_SCREEN_MAIN);
add: STAMP s;  s.origin.x = s.origin.y = 0; s.frame = TextCacheFrame; DrawStamp (&s);
context: add_text (int status, PTEXT pTextIn){	COUNT maxchars, numchars;	TEXT locText;	PTEXT pText;	SIZE leading;	const unsigned char *pStr;	SIZE text_width;	int num_lines = 0;	static COORD last_baseline;	BOOLEAN eol;		BatchGraphics ();	maxchars = (COUNT)~0;	if (status == 1)	{		RECT r;		GetContextClipRect (&r);		if (last_subtitle == pTextIn->pStr)		{			// draws cached subtitle			TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0, TFB_SCREEN_MAIN);			UnbatchGraphics ();			return last_baseline;		}		else		{			// saves background to extra screen			TFB_DrawScreen_Copy (&r, TFB_SCREEN_MAIN, TFB_SCREEN_EXTRA);			// fills screen with transparent color			TFB_DrawScreen_Rect (&r, 0, 0, 128, TFB_SCREEN_MAIN);			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:				SetContextForeGroundColor (						BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));				break;			case -2:				SetContextForeGroundColor (						BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));				break;			case -1:				SetContextForeGroundColor (						BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));				break;		}		maxchars = pTextIn->CharCount;		locText = *pTextIn;		locText.baseline.x -= 8;		locText.CharCount = (COUNT)~0;		locText.pStr = "*";		font_DrawText (&locText);		locText = *pTextIn;		pText = &locText;		pText->baseline.y -= leading;	}	numchars = 0;	pStr = pText->pStr;	if (status > 0 && (CommData.AlienTextTemplate.valign & (				VALIGN_MIDDLE|VALIGN_BOTTOM))) {		num_lines = _count_lines(pText);		if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM)			pText->baseline.y -= (leading * num_lines);		else if (CommData.AlienTextTemplate.valign == 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)		{			if (pText->baseline.y < SIS_SCREEN_HEIGHT)				font_DrawText (pText);			if (status < -4 && pText->baseline.y >= -status - 10)			{				++pStr;				break;			}		}		else		{			SetContextForeGroundColor (CommData.AlienTextBColor);			--pText->baseline.x;			font_DrawText (pText);			++pText->baseline.x;			--pText->baseline.y;			font_DrawText (pText);			++pText->baseline.x;			++pText->baseline.y;			font_DrawText (pText);			--pText->baseline.x;			++pText->baseline.y;			font_DrawText (pText);			SetContextForeGroundColor (CommData.AlienTextFColor);			--pText->baseline.y;			font_DrawText (pText);		}	} while (!eol && maxchars);	pText->pStr = pStr;	if (status == 1)	{		RECT r;		GetContextClipRect (&r);				// copies subtitle to cache		TFB_DrawScreen_CopyToImage (subtitle_cache, &r, TFB_SCREEN_MAIN);		// restores background		TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);		// draws cached subtitle		TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0,				TFB_SCREEN_MAIN);				last_baseline = pText->baseline.y;	}	UnbatchGraphics ();	return (pText->baseline.y);}