void set(uint color) { r = AS_C32P(RGBA_RED(color)); g = AS_C32P(RGBA_GREEN(color)); b = AS_C32P(RGBA_BLUE(color)); a = AS_C32P(RGBA_ALPHA(color)); }
CBitmap *CreateStringBitmap ( const char *s, int nKey, uint nKeyColor, int *nTabs, int bCentered, int nMaxWidth, int bForce) { int origColor = CCanvas::Current ()->FontColor (0).index;//to allow easy reseting to default string color with colored strings -MPM int i, x, y, hx, hy, w, h, aw, cw, spacing, nTab, nChars, bHotKey; CBitmap *bmP, *bmfP; tRgbaColorb hc, kc, *pc; ubyte *pf; CPalette *palP = NULL; tRgbColorb *colorP; ubyte c; const char *textP, *text_ptr1, *nextRowP; int letter; CFont* fontP = fontManager.Current (); #if 0 if (!(bForce || (gameOpts->menus.nStyle && gameOpts->menus.bFastMenus))) return NULL; #endif fontP->StringSizeTabbed (s, w, h, aw, nTabs, nMaxWidth); if (!(w && h)) return NULL; if (bForce >= 0) { for (i = 1; i < w; i <<= 2) ; w = i; for (i = 1; i < h; i <<= 2) ; h = i; } if (!(bmP = CBitmap::Create (0, w, h, 4))) return NULL; if (!bmP->Buffer ()) { delete bmP; return NULL; } bmP->SetName ("String Bitmap"); bmP->Clear (); bmP->AddFlags (BM_FLAG_TRANSPARENT); nextRowP = s; y = 0; nTab = 0; nChars = 0; while (nextRowP) { text_ptr1 = nextRowP; nextRowP = NULL; textP = text_ptr1; #if 0 # if DBG if (bCentered) x = (w - fontManager.Current ()->GetLineWidth (textP)) / 2; else x = 0; # else x = bCentered ? (w - fontManager.Current ()->GetLineWidth (textP)) / 2 : 0; # endif #else x = 0; #endif while ((c = *textP)) { if (c == '\n') { nextRowP = textP + 1; y += fontP->Height () + 2; nTab = 0; break; } if (c == '\t') { textP++; if (nTabs && (nTab < 6)) { int w, h, aw; fontManager.Current ()->StringSize (textP, w, h, aw); x = LHX (nTabs [nTab++]); if (!gameStates.multi.bSurfingNet) x += nMaxWidth - w; for (i = 1; i < w; i <<= 2) ; w = i; for (i = 1; i < h; i <<= 2) ; h = i; } continue; } letter = c - fontP->MinChar (); fontP->GetCharWidth (c, textP [1], cw, spacing); if (c <= 0x06) { //not in font, draw as space textP = ScanEmbeddedColors (c, textP, origColor, 128, 2); continue; } if (!fontManager.Current ()->InFont (letter)) { x += spacing; textP++; continue; } if ((bHotKey = ((nKey < 0) && isalnum (c)) || (nKey && ((int) c == nKey)))) nKey = 0; bmfP = (bHotKey && (fontManager.Current () != SMALL_FONT)) ? SELECTED_FONT->Bitmaps () + letter : fontP->Bitmaps () + letter; palP = bmfP->Parent () ? bmfP->Parent ()->Palette () : bmfP->Palette (); nChars++; i = nKeyColor * 3; kc.red = RGBA_RED (nKeyColor); kc.green = RGBA_GREEN (nKeyColor); kc.blue = RGBA_BLUE (nKeyColor); kc.alpha = 255; if (fontP->Flags () & FT_COLOR) { for (hy = 0; hy < bmfP->Height (); hy++) { pc = reinterpret_cast<tRgbaColorb*> (bmP->Buffer ()) + (y + hy) * w + x; pf = bmfP->Buffer () + hy * bmfP->RowSize (); for (hx = bmfP->Width (); hx; hx--, pc++, pf++) if ((c = *pf) != TRANSPARENCY_COLOR) { colorP = palP->Color () + c; pc->red = colorP->red * 4; pc->green = colorP->green * 4; pc->blue = colorP->blue * 4; pc->alpha = 255; } #if DBG else c = c; #endif } } else { if (CCanvas::Current ()->FontColor (0).index < 0) memset (&hc, 0xff, sizeof (hc)); else { if (CCanvas::Current ()->FontColor (0).rgb) { hc = CCanvas::Current ()->FontColor (0).color; } else { colorP = palP->Color () + CCanvas::Current ()->FontColor (0).index; hc.red = colorP->red * 4; hc.green = colorP->green * 4; hc.blue = colorP->blue * 4; } hc.alpha = 255; } for (hy = 0; hy < bmfP->Height (); hy++) { pc = reinterpret_cast<tRgbaColorb*> (bmP->Buffer ()) + (y + hy) * w + x; pf = bmfP->Buffer () + hy * bmfP->RowSize (); for (hx = bmfP->Width (); hx; hx--, pc++, pf++) if (*pf != TRANSPARENCY_COLOR) *pc = bHotKey ? kc : hc; } } x += spacing; textP++; } } bmP->SetPalette (palP); bmP->SetTranspType (-1); return bmP; }
//------------------------------------------------------------------------------ // Call to flash a message on the HUD. Returns true if message drawn. // (pszMsg might not be drawn if previous pszMsg was same) int HUDInitMessageVA (ubyte nType, char * format, va_list args) { tHUDMessage *pMsgs = gameData.hud.msgs + (gameOpts->render.cockpit.bSplitHUDMsgs ? nType : 0); int temp; char *pszMsg = NULL, *pszLastMsg = NULL; char con_message [HUD_MESSAGE_LENGTH + 3]; if (!gameOpts->render.cockpit.bHUDMsgs) return 0; nModexHUDMsgs = 2; if ((pMsgs->nLast < 0) || (pMsgs->nLast >= HUD_MAX_MSGS)) Int3 (); // Get Rob!! pszMsg = pMsgs->szMsgs [pMsgs->nLast]; vsprintf (pszMsg, format, args); /* Produce a colorised version and send it to the console */ con_message [0] = CC_COLOR; if (pMsgs->nColor != -1) { con_message [1] = (char) RGBA_RED (pMsgs->nColor) / 2 + 128; con_message [2] = (char) RGBA_GREEN (pMsgs->nColor) / 2 + 128; con_message [3] = (char) RGBA_BLUE (pMsgs->nColor) / 2 + 128; } else if (nType) { con_message [1] = (char) (127 + 128); con_message [2] = (char) (95 + 128); con_message [3] = (char) (0 + 128); } else { con_message [1] = (char) (0 + 128); con_message [3] = (char) (0 + 128); con_message [2] = (char) (63 + 128); } con_message [4] = '\0'; strcat (con_message, pszMsg); #if TRACE con_printf (CON_NORMAL, "%s\n", con_message); #endif // Added by Leighton if (IsMultiGame) { if (gameOpts->multi.bNoRedundancy && !strnicmp ("You already", pszMsg, 11)) return 0; if (!gameData.hud.bPlayerMessage && FindArg ("-PlayerMessages")) return 0; } if (pMsgs->nMessages > 1) { pszLastMsg = pMsgs->szMsgs [((pMsgs->nLast - 1) ? pMsgs->nLast : HUD_MAX_MSGS) - 2]; if (pszLastMsg && (!strcmp (pszLastMsg, pszMsg))) { pMsgs->xTimer = F1_0 * 3; // 1 second per 5 characters return 0; // ignore since it is the same as the last one } } if (pMsgs->nMessages > 0) pszLastMsg = pMsgs->szMsgs [(pMsgs->nLast ? pMsgs->nLast : HUD_MAX_MSGS) - 1]; temp = (pMsgs->nLast + 1) % HUD_MAX_MSGS; if (temp == pMsgs->nFirst) { // If too many messages, remove oldest pszMsg to make room pMsgs->nFirst = (pMsgs->nFirst + 1) % HUD_MAX_MSGS; pMsgs->nMessages--; } if (pszLastMsg && (!strcmp (pszLastMsg, pszMsg))) { pMsgs->xTimer = F1_0 * 3; // 1 second per 5 characters return 0; // ignore since it is the same as the last one } pMsgs->nLast = temp; // Check if memory has been overwritten at this point. if (strlen (pszMsg) >= HUD_MESSAGE_LENGTH) Error ( "Your message to HUD is too long. Limit is %i characters.\n", HUD_MESSAGE_LENGTH); #ifdef NEWDEMO if (gameData.demo.nState == ND_STATE_RECORDING) NDRecordHUDMessage ( pszMsg); #endif pMsgs->xTimer = F1_0*3; // 1 second per 5 characters pMsgs->nMessages++; return 1; }