Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
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);
	}
}