示例#1
0
void CG_Credits_Init( LPCSTR psStripReference, vec4_t *pv4Color)
{
	// could make these into parameters later, but for now...
	//
	ghFontHandle = cgs.media.qhFontMedium;
	gfFontScale = 1.0f;

	memcpy(gv4Color,pv4Color,sizeof(gv4Color));	// memcpy so we can poke into alpha channel

	// first, ask the strlen of the final string...
	//	
	int iStrLen = cgi_SP_GetStringTextString( psStripReference, NULL, 0 );
	if (!iStrLen)
	{
#ifndef FINAL_BUILD
		Com_Printf("WARNING: CG_Credits_Init(): invalid text key :'%s'\n", psStripReference);
#endif
		return; 
	}
	//
	// malloc space to hold it...
	//
	char *psMallocText = (char *) cgi_Z_Malloc( iStrLen+1, TAG_TEMP_WORKSPACE );
	//
	// now get the string...
	//	
	iStrLen = cgi_SP_GetStringTextString( psStripReference, psMallocText, iStrLen+1 );
	//ensure we found a match
	if (!iStrLen)
	{
		assert(0);	// should never get here now, but wtf?
		cgi_Z_Free(psMallocText);
#ifndef FINAL_BUILD
		Com_Printf("WARNING: CG_Credits_Init(): invalid text key :'%s'\n", psStripReference);
#endif
		return; 
	}

	// read whole string in and process as cards, lines etc...
	//
	typedef enum
	{
		eNothing = 0,
		eLine,
		eDotEntry,
		eTitle,
		eCard,
		eFinished,
	} Mode_e;
	Mode_e eMode = eNothing;

	qboolean bCardsFinished = qfalse;
	int iLineNumber = 0;
	const char *psTextParse = psMallocText;
	while (*psTextParse != NULL)
	{
		// read a line...
		//	
		char sLine[MAX_LINE_BYTES];
			 sLine[0]='\0';
		qboolean bWasCommand = qtrue;
		while (1)
		{
			qboolean bIsTrailingPunctuation;
			unsigned int uiLetter = cgi_AnyLanguage_ReadCharFromString(&psTextParse, &bIsTrailingPunctuation);

			// concat onto string so far...
			//
			if (uiLetter == 32 && sLine[0] == '\0')
			{
				continue;	// unless it's a space at the start of a line, in which case ignore it.
			}

			if (uiLetter == '\n' || uiLetter == '\0' )
			{
				// have we got a command word?...
				//
				if (!Q_stricmpn(sLine,"(#",2))
				{
					// yep...
					//
					if (!stricmp(sLine, "(#CARD)"))
					{
						if (!bCardsFinished)
						{
							eMode = eCard;
						}
						else
						{
							#ifndef FINAL_BUILD
							Com_Printf( S_COLOR_YELLOW "CG_Credits_Init(): No current support for cards after scroll!\n" );
							#endif
							eMode = eNothing;
						}
						break;
					}
					else
					if (!stricmp(sLine, "(#TITLE)"))
					{
						eMode = eTitle;
						bCardsFinished = qtrue;
						break;
					}
					else
					if (!stricmp(sLine, "(#LINE)"))
					{
						eMode = eLine;
						bCardsFinished = qtrue;
						break;
					}
					else
					if (!stricmp(sLine, "(#DOTENTRY)"))
					{
						eMode = eDotEntry;
						bCardsFinished = qtrue;
						break;
					}
					else
					{
						#ifndef FINAL_BUILD
						Com_Printf( S_COLOR_YELLOW "CG_Credits_Init(): bad keyword \"%s\"!\n", sLine );
						#endif
						eMode = eNothing;
					}
				}
				else
				{
					// I guess not...
					//
					bWasCommand = qfalse;
					break;
				}
			}
			else
			{
				// must be a letter...
				//
				if (uiLetter > 255)
				{
					Q_strcat(sLine, sizeof(sLine), va("%c%c",uiLetter >> 8, uiLetter & 0xFF));
				}
				else
				{
					Q_strcat(sLine, sizeof(sLine), va("%c",uiLetter & 0xFF));
				}
			}
		}
示例#2
0
// display text in a supplied box, start at top left and going down by however many pixels I feel like internally, 
//	return value is NULL if all fitted, else char * of next char to continue from that didn't fit.
//
// (coords are in the usual 640x480 virtual space)...
//
// ( if you get the same char * returned as what you passed in, then none of it fitted at all (box too small) )
//
const char *CG_DisplayBoxedText(int iBoxX, int iBoxY, int iBoxWidth, int iBoxHeight, 
								const char *psText, int iFontHandle, float fScale,
								const vec4_t v4Color)
{
	cgi_R_SetColor( v4Color );

	// Setup a reasonable vertical spacing (taiwanese & japanese need 1.5 fontheight, so use that for all)...
	//
	const int iFontHeight		 = cgi_R_Font_HeightPixels(iFontHandle, fScale);
	const int iFontHeightAdvance = (int) (1.5f * (float) iFontHeight);
	int iYpos = iBoxY;	// start print pos

	// findmeste	// test stuff, remove later
//	psText = "賽卓哥爾博士已經安全了,我也把所有發現報告給「商店」。很不幸地,瑞士警局有些白癡發現了一些狀況,準備在機場逮捕亞歷西•納克瑞得。他偽裝成外交使節,穿過了層層防備。現在他握有人質,並且威脅要散播病毒。根據最搆sCurrentTextReadPos的報告,納克瑞得以及他的黨羽已經完全佔據了機場。我受命來追捕納克瑞得以及救出所有人質。這並不容易。";

	// this could probably be simplified now, but it was converted from something else I didn't originally write, 
	//	and it works anyway so wtf...
	//
	const char *psCurrentTextReadPos = psText;	
	const char *psReadPosAtLineStart = psCurrentTextReadPos;	
	const char *psBestLineBreakSrcPos = psCurrentTextReadPos;
	const char *psLastGood_s;	// needed if we get a full screen of chars with no punctuation or space (see usage notes)
	while( *psCurrentTextReadPos && (iYpos + iFontHeight < (iBoxY + iBoxHeight)) )
	{
		char sLineForDisplay[2048];	// ott

		// construct a line...
		//
		psCurrentTextReadPos = psReadPosAtLineStart;
		sLineForDisplay[0] = '\0';
		while ( *psCurrentTextReadPos )
		{
			psLastGood_s = psCurrentTextReadPos;

			// read letter...
			//
			qboolean bIsTrailingPunctuation;
			unsigned int uiLetter = cgi_AnyLanguage_ReadCharFromString(&psCurrentTextReadPos, &bIsTrailingPunctuation);

			// concat onto string so far...
			//
			if (uiLetter == 32 && sLineForDisplay[0] == '\0')
			{
				psReadPosAtLineStart++;
				continue;	// unless it's a space at the start of a line, in which case ignore it.
			}

			if (uiLetter > 255)
			{
				Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c%c",uiLetter >> 8, uiLetter & 0xFF));
			}
			else
			{
				Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c",uiLetter & 0xFF));
			}

			if (uiLetter == '\n')
			{
				// explicit new line...
				//
				sLineForDisplay[ strlen(sLineForDisplay)-1 ] = '\0';	// kill the CR
				psReadPosAtLineStart = psCurrentTextReadPos;
				psBestLineBreakSrcPos = psCurrentTextReadPos;
				break;	// print this line
			}
			else 
			if ( cgi_R_Font_StrLenPixels(sLineForDisplay, iFontHandle, fScale) >= iBoxWidth )
			{					
				// reached screen edge, so cap off string at bytepos after last good position...
				//
				if (uiLetter > 255 && bIsTrailingPunctuation && !cgi_Language_UsesSpaces())
				{
					// Special case, don't consider line breaking if you're on an asian punctuation char of
					//	a language that doesn't use spaces...
					//
				}
				else
				{
					if (psBestLineBreakSrcPos == psReadPosAtLineStart)
					{
						//  aarrrggh!!!!!   we'll only get here is someone has fed in a (probably) garbage string,
						//		since it doesn't have a single space or punctuation mark right the way across one line
						//		of the screen.  So far, this has only happened in testing when I hardwired a taiwanese 
						//		string into this function while the game was running in english (which should NEVER happen 
						//		normally).  On the other hand I suppose it'psCurrentTextReadPos entirely possible that some taiwanese string 
						//		might have no punctuation at all, so...
						//
						psBestLineBreakSrcPos = psLastGood_s;	// force a break after last good letter
					}

					sLineForDisplay[ psBestLineBreakSrcPos - psReadPosAtLineStart ] = '\0';
					psReadPosAtLineStart = psCurrentTextReadPos = psBestLineBreakSrcPos;
					break;	// print this line
				}
			}

			// record last-good linebreak pos...  (ie if we've just concat'd a punctuation point (western or asian) or space)
			//
			if (bIsTrailingPunctuation || uiLetter == ' ' || (uiLetter > 255 && !cgi_Language_UsesSpaces()))
			{
				psBestLineBreakSrcPos = psCurrentTextReadPos;
			}
		}