// 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); }
// 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); }