diff --git a/docs/content/annotated_banner.png b/docs/content/annotated_banner.png
new file mode 100644
index 00000000..554326f0
Binary files /dev/null and b/docs/content/annotated_banner.png differ
diff --git a/docs/general_config.md b/docs/general_config.md
index ec70add1..75850916 100644
--- a/docs/general_config.md
+++ b/docs/general_config.md
@@ -295,22 +295,33 @@ The user can specify one or more questions using the `questions` array, as demon
Each question in the array is then asked of the user (via an independent time-sequenced dialog box) before being recorded to the output log. Note that `MultipleChoise` and `Rating` questions include a confirmation button that must be pressed to confirm the selection before proceeding.
## HUD settings
-| Parameter Name |Units | Description |
-|-----------------------|-------|------------------------------------------------------------------------------------|
-|`showHUD` |`bool` | The master control for whether or not HUD elements are displayed (score banner, player health bar, and ammo indicator) |
-|`showBanner` |`bool` | Whether or not the score banner is displayed (currently w/ time remaining, percent of session complete, and score) |
-|`bannerLargeFontSize` |pt | The "large" font for the percent complete in the banner
-|`bannerSmallFontSize` |pt | The "small" font for the time remaining and score
-|`hudFont` |file | The font to use (as a `.fnt` file) for the HUD (for available fonts check `%g3d%/data10/common/font` or `%g3d%/G3D10/ data-files/font`). We suggest using a fixed width font (such as `console.fnt`) for HUD elements|
+| Parameter Name |Units | Description |
+|-----------------------|-----------|-----------------------------------------------------------------------------------------------------------------------|
+|`showHUD` |`bool` | The master control for whether or not HUD elements are displayed (score banner, player health bar, and ammo indicator)|
+|`showBanner` |`bool` | Whether or not the score banner is displayed (currently w/ time remaining, percent of session complete, and score) an annotated banner image is provided below for reference. |
+|`bannerTimerMode` |`String` | The mode in which to show time in the banner (can be `"remaining"`, `"elapsed"`, or `"none"`) |
+|`bannerShowProgress` |`bool` | Whether to show the session progress in the banner |
+|`bannerShowScore` |`bool` | Whether to show the session score in the banner |
+|`bannerLargeFontSize` |pt | The "large" font for the percent complete in the banner |
+|`bannerSmallFontSize` |pt | The "small" font for the time remaining and score |
+|`hudFont` |file | The font to use (as a `.fnt` file) for the HUD (for available fonts check `%g3d%/data10/common/font` or `%g3d%/G3D10/ data-files/font`). We suggest using a fixed width font (such as `console.fnt`) for HUD elements|
```
"showHUD": false, // Show the player HUD (banner, ammo, health bar)
"showBanner": false, // Control the banner at the top of the screen (shows time, score, and session % complete)
+"bannerTimerMode": "remaining", // Show remaining time in trial in timer on banner
+"bannerShowProgress": true, // Show the session progress percentage in the banner
+"bannerShowScore": true, // Show the session score in the banner
"bannerLargeFontSize": 30.0, // Large font size to use in the banner (% complete)
"bannerSmallFontSize": 14.0, // Small font size to use in the banner (time remaining and score)
"hudFont": "console.fnt", // Font to use for the HUD (fixed with highly suggested!)
```
+#### Annotated Banner
+The image below provides an example of the banner with the timer, progress, and score annotated with an overlay.
+
+
+
### Player Health Bar
| Parameter Name |Units | Description |
|-------------------------------|---------------|------------------------------------------------------------------------------------|
diff --git a/source/FPSciGraphics.cpp b/source/FPSciGraphics.cpp
index 6daab841..2151b592 100644
--- a/source/FPSciGraphics.cpp
+++ b/source/FPSciGraphics.cpp
@@ -506,19 +506,43 @@ void FPSciApp::drawHUD(RenderDevice *rd, Vector2 resolution) {
Draw::rect2D((scoreBannerTexture->rect2DBounds() * scale - scoreBannerTexture->vector2Bounds() * scale / 2.0f) * 0.8f + hudCenter, rd, Color3::white(), scoreBannerTexture);
// Create strings for time remaining, progress in sessions, and score
- float remainingTime = sess->getRemainingTrialTime();
- float printTime = remainingTime > 0 ? remainingTime : 0.0f;
- String time_string = format("%0.2f", printTime);
+ float time;
+ if (sessConfig->hud.bannerTimerMode == "remaining") {
+ time = sess->getRemainingTrialTime();
+ if (time < 0.f) time = 0.f;
+ }
+ else if (sessConfig->hud.bannerTimerMode == "elapsed") {
+ time = sess->getElapsedTrialTime();
+ }
+ String time_string = time < 10000.f ? format("%0.1f", time) : "---"; // Only allow up to 3 digit time strings
+
float prog = sess->getProgress();
String prog_string = "";
if (!isnan(prog)) {
- prog_string = format("%d", (int)(100.0f*prog)) + "%";
+ prog_string = format("%d", (int)G3D::round(100.0f*prog)) + "%";
}
- String score_string = format("%d", (int)(10 * sess->getScore()));
- hudFont->draw2D(rd, time_string, hudCenter - Vector2(80, 0) * scale.x, scale.x * sessConfig->hud.bannerSmallFontSize, Color3::white(), Color4::clear(), GFont::XALIGN_RIGHT, GFont::YALIGN_CENTER);
- hudFont->draw2D(rd, prog_string, hudCenter + Vector2(0, -1), scale.x * sessConfig->hud.bannerLargeFontSize, Color3::white(), Color4::clear(), GFont::XALIGN_CENTER, GFont::YALIGN_CENTER);
- hudFont->draw2D(rd, score_string, hudCenter + Vector2(125, 0) * scale, scale.x * sessConfig->hud.bannerSmallFontSize, Color3::white(), Color4::clear(), GFont::XALIGN_RIGHT, GFont::YALIGN_CENTER);
+ const double score = sess->getScore();
+ String score_string;
+ if (score < 1e3) {
+ score_string = format("%d", (int)G3D::round(score));
+ }
+ else if (score > 1e3 && score < 1e6) {
+ score_string = format("%dk", (int)G3D::round(score / 1e3));
+ }
+ else if (score > 1e6 && score < 1e9) {
+ score_string = format("%dM", (int)G3D::round(score / 1e6));
+ }
+ else if (score > 1e9) {
+ score_string = format("%dB", (int)G3D::round(score / 1e9));
+ }
+
+ if (sessConfig->hud.bannerTimerMode != "none" && sess->inTask()) {
+ hudFont->draw2D(rd, time_string, hudCenter - Vector2(80, 0) * scale.x, scale.x * sessConfig->hud.bannerSmallFontSize,
+ Color3::white(), Color4::clear(), GFont::XALIGN_RIGHT, GFont::YALIGN_CENTER);
+ }
+ if(sessConfig->hud.bannerShowProgress) hudFont->draw2D(rd, prog_string, hudCenter + Vector2(0, -1), scale.x * sessConfig->hud.bannerLargeFontSize, Color3::white(), Color4::clear(), GFont::XALIGN_CENTER, GFont::YALIGN_CENTER);
+ if(sessConfig->hud.bannerShowScore) hudFont->draw2D(rd, score_string, hudCenter + Vector2(125, 0) * scale, scale.x * sessConfig->hud.bannerSmallFontSize, Color3::white(), Color4::clear(), GFont::XALIGN_RIGHT, GFont::YALIGN_CENTER);
}
// Draw any static HUD elements
diff --git a/source/FpsConfig.cpp b/source/FpsConfig.cpp
index dfc01d84..3b48a962 100644
--- a/source/FpsConfig.cpp
+++ b/source/FpsConfig.cpp
@@ -246,6 +246,20 @@ void HudConfig::load(AnyTableReader reader, int settingsVersion) {
case 1:
reader.getIfPresent("showHUD", enable);
reader.getIfPresent("showBanner", showBanner);
+ if (reader.getIfPresent("bannerTimerMode", bannerTimerMode)) {
+ bannerTimerMode = toLower(bannerTimerMode);
+ const Array validTimeModes = { "none", "elapsed", "remaining" };
+ if (!validTimeModes.contains(bannerTimerMode)) {
+ String errString = format("\"bannerShowTime\" value \"%s\" is invalid, must be specified as one of the valid modes (", bannerTimerMode);
+ for (String validTimeMode : validTimeModes) {
+ errString += "\"" + validTimeMode + "\", ";
+ }
+ errString = errString.substr(0, errString.length() - 2) + ")!";
+ throw errString.c_str();
+ }
+ }
+ reader.getIfPresent("bannerShowProgress", bannerShowProgress);
+ reader.getIfPresent("bannerShowScore", bannerShowScore);
reader.getIfPresent("hudFont", hudFont);
reader.getIfPresent("showPlayerHealthBar", showPlayerHealthBar);
reader.getIfPresent("playerHealthBarSize", playerHealthBarSize);
@@ -277,6 +291,9 @@ Any HudConfig::addToAny(Any a, bool forceAll) const {
HudConfig def;
if (forceAll || def.enable != enable) a["showHUD"] = enable;
if (forceAll || def.showBanner != showBanner) a["showBanner"] = showBanner;
+ if (forceAll || def.bannerTimerMode != bannerTimerMode) a["bannerTimerMode"] = bannerTimerMode;
+ if (forceAll || def.bannerShowProgress != bannerShowProgress) a["bannerShowProgress"] = bannerShowProgress;
+ if (forceAll || def.bannerShowScore != bannerShowScore) a["bannerShowScore"] = bannerShowScore;
if (forceAll || def.hudFont != hudFont) a["hudFont"] = hudFont;
if (forceAll || def.showPlayerHealthBar != showPlayerHealthBar) a["showPlayerHealthBar"] = showPlayerHealthBar;
if (forceAll || def.playerHealthBarSize != playerHealthBarSize) a["playerHealthBarSize"] = playerHealthBarSize;
diff --git a/source/FpsConfig.h b/source/FpsConfig.h
index 9bb1bd6d..57196b69 100644
--- a/source/FpsConfig.h
+++ b/source/FpsConfig.h
@@ -89,6 +89,9 @@ class HudConfig {
// HUD parameters
bool enable = false; ///< Master control for all HUD elements
bool showBanner = false; ///< Show the banner display
+ String bannerTimerMode = "remaining"; ///< Time to show in the banner ("remaining", "elapsed", or "none")
+ bool bannerShowProgress = true; ///< Show progress in banner?
+ bool bannerShowScore = true; ///< Show score in banner?
float bannerVertVisible = 0.41f; ///< Vertical banner visibility
float bannerLargeFontSize = 30.0f; ///< Banner percent complete font size
float bannerSmallFontSize = 14.0f; ///< Banner detail font size
diff --git a/source/Session.cpp b/source/Session.cpp
index 140e8e5a..dde9dca9 100644
--- a/source/Session.cpp
+++ b/source/Session.cpp
@@ -574,6 +574,14 @@ void Session::accumulateFrameInfo(RealTime t, float sdt, float idt) {
}
}
+bool Session::inTask() {
+ return currentState == PresentationState::trialTask;
+}
+
+float Session::getElapsedTrialTime() {
+ return m_timer.getTime();
+}
+
float Session::getRemainingTrialTime() {
if (isNull(m_config)) return 10.0;
return m_config->timing.maxTrialDuration - m_timer.getTime();
@@ -591,8 +599,8 @@ float Session::getProgress() {
return fnan();
}
-int Session::getScore() {
- return (int)(10.0 * m_totalRemainingTime);
+double Session::getScore() {
+ return 100.0 * m_totalRemainingTime;
}
String Session::formatCommand(const String& input) {
diff --git a/source/Session.h b/source/Session.h
index be263e89..7793e83b 100644
--- a/source/Session.h
+++ b/source/Session.h
@@ -403,9 +403,11 @@ class Session : public ReferenceCountedObject {
/** clear all targets (used when clearing remaining targets at the end of a trial) */
void clearTargets();
+ bool inTask();
+ float getElapsedTrialTime();
float getRemainingTrialTime();
float getProgress();
- int getScore();
+ double getScore();
String getFeedbackMessage();
/** queues action with given name to insert into database when trial completes