static void DogfightFinalScoresDraw(void *data) { UNUSED(data); // This will only draw once const int w = gGraphicsDevice.cachedConfig.Res.x; const int h = gGraphicsDevice.cachedConfig.Res.y; GraphicsBlitBkg(&gGraphicsDevice); // Work out who's the winner, or if it's a tie int maxScore = 0; int playersWithMaxScore = 0; for (int i = 0; i < (int)gPlayerDatas.size; i++) { const PlayerData *p = CArrayGet(&gPlayerDatas, i); if (p->RoundsWon > maxScore) { maxScore = p->RoundsWon; playersWithMaxScore = 1; } else if (p->RoundsWon == maxScore) { playersWithMaxScore++; } } const bool isTie = playersWithMaxScore == (int)gPlayerDatas.size; // Draw players and their names spread evenly around the screen. // If it's a tie, display the message in the centre, // otherwise display the winner just below the winning player #define DRAW_TEXT "It's a draw!" #define WINNER_TEXT "Winner!" CASSERT( gPlayerDatas.size >= 2 && gPlayerDatas.size <= 4, "Unimplemented number of players for dogfight"); for (int i = 0; i < (int)gPlayerDatas.size; i++) { const Vec2i pos = Vec2iNew( w / 4 + (i & 1) * w / 2, gPlayerDatas.size == 2 ? h / 2 : h / 4 + (i / 2) * h / 2); const PlayerData *p = CArrayGet(&gPlayerDatas, i); DisplayCharacterAndName(pos, &p->Char, p->name); ShowPlayerScore(pos, p->RoundsWon); if (!isTie && maxScore == p->RoundsWon) { FontStrMask( WINNER_TEXT, Vec2iNew(pos.x - FontStrW(WINNER_TEXT) / 2, pos.y + 30), colorGreen); } } if (isTie) { FontStrCenter(DRAW_TEXT); } }
void HUDDraw(HUD *hud, const input_device_e pausingDevice) { char s[50]; int flags = 0; const int numPlayersAlive = GetNumPlayers(PLAYER_ALIVE_OR_DYING, false, false); const int numLocalPlayers = GetNumPlayers(PLAYER_ANY, false, true); const int numLocalPlayersAlive = GetNumPlayers(PLAYER_ALIVE_OR_DYING, false, true); Rect2i r; r.Size = Vec2iNew( hud->device->cachedConfig.Res.x, hud->device->cachedConfig.Res.y); if (numLocalPlayersAlive <= 1) { flags = 0; } else if ( ConfigGetEnum(&gConfig, "Interface.Splitscreen") == SPLITSCREEN_NEVER) { flags |= HUDFLAGS_SHARE_SCREEN; } else if (numLocalPlayers == 2) { r.Size.x /= 2; flags |= HUDFLAGS_HALF_SCREEN; } else if (numLocalPlayers == 3 || numLocalPlayers == 4) { r.Size.x /= 2; r.Size.y /= 2; flags |= HUDFLAGS_QUARTER_SCREEN; } else { assert(0 && "not implemented"); } int idx = 0; for (int i = 0; i < (int)gPlayerDatas.size; i++, idx++) { const PlayerData *p = CArrayGet(&gPlayerDatas, i); if (!p->IsLocal) { idx--; continue; } int drawFlags = flags; r.Pos = Vec2iZero(); if (idx & 1) { r.Pos.x = r.Size.x; drawFlags |= HUDFLAGS_PLACE_RIGHT; } if (idx >= 2) { r.Pos.y = r.Size.y; drawFlags |= HUDFLAGS_PLACE_BOTTOM; } TActor *player = NULL; if (IsPlayerAlive(p)) { player = ActorGetByUID(p->ActorUID); } DrawPlayerStatus(hud, p, player, drawFlags, r); DrawScoreUpdate(&hud->scoreUpdates[idx], drawFlags); DrawHealthUpdate(&hud->healthUpdates[idx], drawFlags); DrawAmmoUpdate(&hud->ammoUpdates[idx], drawFlags); } // Only draw radar once if shared if (ConfigGetBool(&gConfig, "Interface.ShowHUDMap") && (flags & HUDFLAGS_SHARE_SCREEN) && IsAutoMapEnabled(gCampaign.Entry.Mode)) { DrawSharedRadar(hud->device, RADAR_SCALE, hud->showExit); } if (numPlayersAlive == 0) { if (AreAllPlayersDeadAndNoLives()) { if (!IsPVP(gCampaign.Entry.Mode)) { FontStrCenter("Game Over!"); } else { FontStrCenter("All Kill!"); } } } else if (hud->mission->state == MISSION_STATE_PICKUP) { int timeLeft = gMission.pickupTime + PICKUP_LIMIT - gMission.time; sprintf(s, "Pickup in %d seconds\n", (timeLeft + (FPS_FRAMELIMIT - 1)) / FPS_FRAMELIMIT); FontStrCenter(s); } if (pausingDevice != INPUT_DEVICE_UNSET) { Vec2i pos = Vec2iScaleDiv(Vec2iMinus( gGraphicsDevice.cachedConfig.Res, FontStrSize("Foo\nPress foo or bar to unpause\nBaz")), 2); const int x = pos.x; FontStr("<Paused>", pos); pos.y += FontH(); pos = FontStr("Press ", pos); color_t c = colorWhite; const char *buttonName = InputGetButtonNameColor(pausingDevice, 0, CMD_ESC, &c); pos = FontStrMask(buttonName, pos, c); FontStr(" again to quit", pos); pos.x = x; pos.y += FontH(); pos = FontStr("Press ", pos); buttonName = InputGetButtonNameColor( pausingDevice, 0, CMD_BUTTON1, &c); pos = FontStrMask(buttonName, pos, c); pos = FontStr(" or ", pos); buttonName = InputGetButtonNameColor( pausingDevice, 0, CMD_BUTTON2, &c); pos = FontStrMask(buttonName, pos, c); FontStr(" to unpause", pos); } if (hud->messageTicks > 0 || hud->messageTicks == -1) { // Draw the message centered, and just below the automap Vec2i pos = Vec2iNew( (hud->device->cachedConfig.Res.x - FontStrW(hud->message)) / 2, AUTOMAP_SIZE + AUTOMAP_PADDING + AUTOMAP_PADDING); FontStrMask(hud->message, pos, colorCyan); } if (ConfigGetBool(&gConfig, "Interface.ShowFPS")) { FPSCounterDraw(&hud->fpsCounter); } if (ConfigGetBool(&gConfig, "Interface.ShowTime")) { WallClockDraw(&hud->clock); } DrawKeycards(hud); // Draw elapsed mission time as MM:SS int missionTimeSeconds = gMission.time / FPS_FRAMELIMIT; sprintf(s, "%d:%02d", missionTimeSeconds / 60, missionTimeSeconds % 60); FontOpts opts = FontOptsNew(); opts.HAlign = ALIGN_CENTER; opts.Area = hud->device->cachedConfig.Res; opts.Pad.y = 5; FontStrOpt(s, Vec2iZero(), opts); if (HasObjectives(gCampaign.Entry.Mode)) { DrawObjectiveCounts(hud); } }