game: add graphics mode options

This commit is contained in:
Crypto City 2020-02-05 01:54:56 +00:00
parent 10fa503b7e
commit e41bd2a01e
8 changed files with 240 additions and 2 deletions

View File

@ -5,6 +5,11 @@ WindowInfo
TBLayout: axis: y, distribution-position: "left top", distribution: "gravity"
TBLayout: axis x, distribution-position: "left top", distribution: "gravity", size: "preferred"
TBSelectDropdown: id: "monitor"
TBSelectDropdown: id: "resolution"
TBLayout: axis x, distribution-position: "left top", distribution: "gravity", size: "preferred"
TBClickLabel: text: "Shadows"

2
external/urho3d vendored

@ -1 +1 @@
Subproject commit 886e78817071eef731eee202fdb42e4f135695d3
Subproject commit 13c52fb82cbdb8d14c9b0d72d6fbd9bd69f963e8

View File

@ -470,6 +470,11 @@ void UTBRendererBatcher::HandleScreenMode(StringHash eventType, VariantMap& even
using namespace ScreenMode;
OnResizeWin( eventData[P_WIDTH].GetInt(), eventData[P_HEIGHT].GetInt() );
g_renderer->InvokeContextLost(); // Forget all bitmaps
g_renderer->InvokeContextRestored(); // Reload all bitmaps
UTBRendererBatcher::Singleton().Root().Invalidate();
}
//=============================================================================

View File

@ -74,6 +74,8 @@ const float TOUCH_SENSITIVITY = 2.0f;
#define DEFAULT_TIME_OF_DAY -1.0f
#define CONFIG_SHOW_FLAGS "show-flags"
#define DEFAULT_SHOW_FLAGS true
#define CONFIG_GRAPHICS_MODE "graphics-mode"
#define DEFAULT_GRAPHICS_MODE String("")
enum SelectionMode
{
@ -172,6 +174,7 @@ public:
void HandleResized(StringHash eventType, VariantMap& eventData);
void HandleEnableShadows(StringHash eventType, VariantMap& eventData);
void HandleEnableClouds(StringHash eventType, VariantMap& eventData);
void HandleGraphicsMode(StringHash eventType, VariantMap& eventData);
void HandleEnableHorizon(StringHash eventType, VariantMap& eventData);
void HandleEnableDynamicSky(StringHash eventType, VariantMap& eventData);
void HandleTimeOfDay(StringHash eventType, VariantMap& eventData);
@ -225,6 +228,7 @@ private:
std::vector<std::pair<std::shared_ptr<tb::TBBitmap>, unsigned int>> LoadImage(const String &filename);
void EnableShadows(bool enable);
void EnableClouds(bool enable);
bool SetGraphicsMode(int monitor, int width, int height, int refresh_rate);
void EnableHorizon(bool enable);
void EnableDynamicSky(bool enable);
void ShowFlags(bool enable);
@ -430,6 +434,19 @@ void CryptoCityUrho3D::Setup(void)
void CryptoCityUrho3D::Start()
{
String mode = GetConfigValue(CONFIG_GRAPHICS_MODE, DEFAULT_GRAPHICS_MODE);
int monitor = -1, width = -1, height = -1, refresh_rate = -1;
sscanf(mode.CString(), "%d:%dx%d@%d", &monitor, &width, &height, &refresh_rate);
if (!SetGraphicsMode(monitor, width, height, refresh_rate))
{
if (!SetGraphicsMode(0, 640, 480, 60))
{
fprintf(stderr, "Failed to set graphics mode\n");
engine_->Exit();
}
}
if (GetPlatform() == "Android" || GetPlatform() == "iOS")
// On mobile platform, enable touch by adding a screen joystick
InitTouchInput();
@ -669,6 +686,7 @@ void CryptoCityUrho3D::SetupUI()
SubscribeToEvent(ui, E_CRYPTOCITY_RESEARCH, URHO3D_HANDLER(CryptoCityUrho3D, HandleResearch));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_SHADOWS, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableShadows));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_CLOUDS, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableClouds));
SubscribeToEvent(ui, E_CRYPTOCITY_GRAPHICS_MODE, URHO3D_HANDLER(CryptoCityUrho3D, HandleGraphicsMode));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_HORIZON, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableHorizon));
SubscribeToEvent(ui, E_CRYPTOCITY_ENABLE_DYNAMIC_SKY, URHO3D_HANDLER(CryptoCityUrho3D, HandleEnableDynamicSky));
SubscribeToEvent(ui, E_CRYPTOCITY_TIME_OF_DAY, URHO3D_HANDLER(CryptoCityUrho3D, HandleTimeOfDay));
@ -987,6 +1005,18 @@ void CryptoCityUrho3D::ShowFlags(bool enable)
cityMesh->setDisplayMode(enable ? DisplayModeShowFlags : DisplayModeNormal);
}
bool CryptoCityUrho3D::SetGraphicsMode(int monitor, int width, int height, int refresh_rate)
{
Graphics *graphics = GetSubsystem<Graphics>();
const bool highDPI = true;
const bool vsync = true;
const bool triple_buffer = true;
const bool multi_sample = true;
printf("Setting graphics mode: %dx%d, %s\n",
width, height, monitor < 0 ? "windowed" : ("fullscreen on monitor " + std::to_string(monitor + 1) + " at " + std::to_string(refresh_rate) + " Hz").c_str());
return graphics->SetMode(width, height, monitor >= 0, false, monitor < 0, highDPI, vsync, triple_buffer, multi_sample, monitor, refresh_rate);
}
void CryptoCityUrho3D::CreateScene()
{
if (!scene_)
@ -2391,6 +2421,7 @@ template<> bool GetJSONValue(const JSONValue &field, bool &value) { if (!field.I
template<> bool GetJSONValue(const JSONValue &field, int &value) { if (!field.IsNumber()) return false; value = field.GetInt(); return true; }
template<> bool GetJSONValue(const JSONValue &field, unsigned &value) { if (!field.IsNumber()) return false; value = field.GetUInt(); return true; }
template<> bool GetJSONValue(const JSONValue &field, float &value) { if (!field.IsNumber()) return false; value = field.GetFloat(); return true; }
template<> bool GetJSONValue(const JSONValue &field, String &value) { if (!field.IsString()) return false; value = field.GetString(); return true; }
template<typename T>
T CryptoCityUrho3D::GetConfigValue(const char *key, const T &default_value) const
@ -2486,6 +2517,35 @@ void CryptoCityUrho3D::HandleShowFlags(StringHash eventType, VariantMap& eventDa
eventData[ShowFlags::P_SHOW] = GetConfigValue(CONFIG_SHOW_FLAGS, DEFAULT_SHOW_FLAGS);
}
void CryptoCityUrho3D::HandleGraphicsMode(StringHash eventType, VariantMap& eventData)
{
if (eventData.Contains(GraphicsMode::P_MONITOR))
{
char s[256];
const int monitor = eventData[GraphicsMode::P_MONITOR].GetInt();
const int width = eventData[GraphicsMode::P_WIDTH].GetInt();
const int height = eventData[GraphicsMode::P_HEIGHT].GetInt();
const int refresh_rate = eventData[GraphicsMode::P_REFRESH_RATE].GetInt();
eventData[GraphicsMode::P_SUCCESS] = false;
if (SetGraphicsMode(monitor, width, height, refresh_rate))
{
snprintf(s, sizeof(s), "%d:%dx%d@%d", monitor, width, height, refresh_rate);
SetConfigValue(CONFIG_GRAPHICS_MODE, String(s));
eventData[GraphicsMode::P_SUCCESS] = true;
}
}
else
{
String mode = GetConfigValue(CONFIG_GRAPHICS_MODE, DEFAULT_GRAPHICS_MODE);
int monitor = -1, width = -1, height = -1, refresh_rate = -1;
sscanf(mode.CString(), "%d:%dx%d@%d", &monitor, &width, &height, &refresh_rate);
eventData[GraphicsMode::P_MONITOR] = monitor;
eventData[GraphicsMode::P_WIDTH] = width;
eventData[GraphicsMode::P_HEIGHT] = height;
eventData[GraphicsMode::P_REFRESH_RATE] = refresh_rate;
}
}
void CryptoCityUrho3D::HandleResearch(StringHash eventType, VariantMap& eventData)
{
cryptonote::cc_command_research_t cmd;
@ -3379,6 +3439,11 @@ void CryptoCityUrho3D::HandleResized(StringHash eventType, VariantMap& eventData
const int width = eventData[Resized::P_WIDTH].GetInt();
const int height = eventData[Resized::P_HEIGHT].GetInt();
g_renderer->InvokeContextLost(); // Forget all bitmaps
g_renderer->InvokeContextRestored(); // Reload all bitmaps
UTBRendererBatcher::Singleton().Root().Invalidate();
RenderPath *effectRenderPath = viewport->GetRenderPath();
if (effectRenderPath)
effectRenderPath->SetShaderParameter("BlurHInvSize", Vector2(1.0f/(float)width, 1.0f/(float)height));

View File

@ -12,14 +12,18 @@
#include <tb/tb_font_renderer.h>
#include "cc/cc_config.h"
#include "cc/cc.h"
#include "UTBRendererBatcher.h"
#include "ui-options.h"
using namespace Urho3D;
using namespace tb;
UIOptionsDialog::UIOptionsDialog(Context *ctx):
UITBWindow(ctx, "cc/options.tb.txt")
UITBWindow(ctx, "cc/options.tb.txt"),
initializing_resolution_list(false)
{
monitorWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("monitor"));
resolutionWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("resolution"));
shadowsWidget = GetWidgetByIDAndType<TBCheckBox>(TBIDC("shadows"));
cloudsWidget = GetWidgetByIDAndType<TBCheckBox>(TBIDC("clouds"));
horizonWidget = GetWidgetByIDAndType<TBCheckBox>(TBIDC("horizon"));
@ -31,12 +35,17 @@ UIOptionsDialog::UIOptionsDialog(Context *ctx):
fontSizeWidget = GetWidgetByIDAndType<TBSelectDropdown>(TBIDC("font-size"));
showFlagsWidget = GetWidgetByIDAndType<TBCheckBox>(TBIDC("show-hide-flags"));
monitorWidget->SetSource(&monitor_source);
resolutionWidget->SetSource(&resolution_source);
SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UIOptionsDialog, HandleTBMessage));
SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UIOptionsDialog, HandleClose));
}
UIOptionsDialog::~UIOptionsDialog()
{
monitorWidget->SetSource(NULL);
resolutionWidget->SetSource(NULL);
}
void UIOptionsDialog::RegisterObject(Context* context)
@ -44,9 +53,87 @@ void UIOptionsDialog::RegisterObject(Context* context)
context->RegisterFactory<UIOptionsDialog>();
}
void UIOptionsDialog::FillMonitors()
{
Graphics* graphics = GetSubsystem<Graphics>();
monitor_source.DeleteAllItems();
int sel = -1;
const int cur = graphics->GetCurrentMonitor();
const int count = graphics->GetMonitorCount();
monitor_source.AddItem(new TBGenericStringItem("Windowed"));
for (int i = 0; i < count; ++i)
{
char s[256];
snprintf(s, sizeof(s), "Fullscreen, monitor #%d", i + 1);
monitor_source.AddItem(new TBGenericStringItem(s));
if (i == cur)
sel = i;
}
if (sel >= 0)
monitorWidget->SetValue(sel);
}
void UIOptionsDialog::FillResolutionForMonitor(int monitor)
{
Graphics* graphics = GetSubsystem<Graphics>();
char s[256];
resolution_source.DeleteAllItems();
if (monitor == 0)
{
IntVector2 mode = graphics->GetDesktopResolution(0);
snprintf(s, sizeof(s), "%d x %d", mode.x_, mode.y_);
resolution_source.AddItem(new TBGenericStringItem(s));
}
else
{
const PODVector<IntVector3> resolutions = graphics->GetResolutions(monitor - 1);
const int count = resolutions.Size();
for (int i = 0; i < count; ++i)
{
snprintf(s, sizeof(s), "%d x %d, %d Hz", resolutions[i].x_, resolutions[i].y_, resolutions[i].z_);
resolution_source.AddItem(new TBGenericStringItem(s));
}
}
}
int UIOptionsDialog::GetResolutionIndexFor(int monitor, int width, int height, int refresh_rate) const
{
if (monitor == 0)
return 0;
Graphics* graphics = GetSubsystem<Graphics>();
const PODVector<IntVector3> resolutions = graphics->GetResolutions(monitor);
const int count = resolutions.Size();
int idx = -1;
for (int i = 0; i < count; ++i)
{
if (resolutions[i].x_ != width)
continue;
if (resolutions[i].y_ != height)
continue;
if (resolutions[i].z_ != refresh_rate)
continue;
idx = i;
}
return idx;
}
void UIOptionsDialog::Configure()
{
VariantMap newEventData;
FillMonitors();
newEventData = {};
SendEvent(E_OPTIONS_GRAPHICS_MODE, newEventData);
monitorWidget->SetValue(newEventData[OptionsGraphicsMode::P_MONITOR].GetInt() + 1);
FillResolutionForMonitor(newEventData[OptionsGraphicsMode::P_MONITOR].GetInt());
current_monitor = newEventData[OptionsGraphicsMode::P_MONITOR].GetInt();
current_width = newEventData[OptionsGraphicsMode::P_WIDTH].GetInt();
current_height = newEventData[OptionsGraphicsMode::P_HEIGHT].GetInt();
current_refresh_rate = newEventData[OptionsGraphicsMode::P_REFRESH_RATE].GetInt();
resolutionWidget->SetValue(GetResolutionIndexFor(current_monitor, current_width, current_height, current_refresh_rate));
newEventData = {};
SendEvent(E_OPTIONS_ENABLE_SHADOWS, newEventData);
shadowsWidget->SetValue(newEventData[OptionsEnableShadows::P_ENABLE].GetBool());
@ -76,6 +163,53 @@ void UIOptionsDialog::Configure()
showFlagsWidget->SetValue(newEventData[OptionsShowFlags::P_SHOW].GetBool());
}
void UIOptionsDialog::HandleMonitorChanged(StringHash eventType, VariantMap& eventData)
{
FillResolutionForMonitor(monitorWidget->GetValue());
initializing_resolution_list = true;
if (monitorWidget->GetValue() == current_monitor + 1)
resolutionWidget->SetValue(GetResolutionIndexFor(current_monitor, current_width, current_height, current_refresh_rate));
else
resolutionWidget->SetValue(-1);
initializing_resolution_list = false;
}
void UIOptionsDialog::HandleResolutionChanged(StringHash eventType, VariantMap& eventData)
{
if (initializing_resolution_list)
return;
int sel = resolutionWidget->GetValue();
if (sel < 0)
return;
const int monitor = monitorWidget->GetValue() - 1;
const TBGenericStringItem *item = resolution_source.GetItem(sel);
int width = -1, height = -1, refresh_rate = -1;
if (monitor < 0)
{
sscanf(item->str.CStr(), "%d x %d", &width, &height);
}
else
{
sscanf(item->str.CStr(), "%d x %d, %d Hz", &width, &height, &refresh_rate);
}
VariantMap newEventData;
newEventData[OptionsGraphicsMode::P_MONITOR] = monitor;
newEventData[OptionsGraphicsMode::P_WIDTH] = width;
newEventData[OptionsGraphicsMode::P_HEIGHT] = height;
newEventData[OptionsGraphicsMode::P_REFRESH_RATE] = refresh_rate;
newEventData[OptionsGraphicsMode::P_SUCCESS] = false;
SendEvent(E_OPTIONS_GRAPHICS_MODE, newEventData);
if (newEventData[OptionsGraphicsMode::P_SUCCESS].GetBool())
{
current_monitor = monitor;
current_width = width;
current_height = height;
current_refresh_rate = refresh_rate;
}
}
void UIOptionsDialog::HandleShadowsChanged(StringHash eventType, VariantMap& eventData)
{
VariantMap newEventData;
@ -123,6 +257,7 @@ void UIOptionsDialog::HandleIncTimeOfDay(StringHash eventType, VariantMap& event
if (v > timeOfDayWidget->GetMaxValue())
v = timeOfDayWidget->GetMaxValue();
timeOfDayWidget->SetValue(v);
UTBRendererBatcher::Singleton().Root().Invalidate();
}
void UIOptionsDialog::HandleDecTimeOfDay(StringHash eventType, VariantMap& eventData)
@ -132,6 +267,7 @@ void UIOptionsDialog::HandleDecTimeOfDay(StringHash eventType, VariantMap& event
if (v < 0.0f)
v = 0.0f;
timeOfDayWidget->SetValue(v);
UTBRendererBatcher::Singleton().Root().Invalidate();
}
void UIOptionsDialog::HandleFontSizeChanged(StringHash eventType, VariantMap& eventData)
@ -196,6 +332,8 @@ void UIOptionsDialog::HandleTBMessage(StringHash eventType, VariantMap& eventDat
CONNECT("time-of-day", HandleTimeOfDayChanged);
CONNECT("font-size", HandleFontSizeChanged);
CONNECT("show-hide-flags", HandleShowFlagsChanged);
CONNECT("monitor", HandleMonitorChanged);
CONNECT("resolution", HandleResolutionChanged);
}
#undef CONNECT

View File

@ -6,6 +6,7 @@
#include <Urho3D/Container/Str.h>
#include <Urho3D/Container/Ptr.h>
#include <Urho3D/Math/StringHash.h>
#include <tb/tb_select_item.h>
#include "cc/cc_config.h"
#include "ui-tb-window.h"
@ -24,6 +25,7 @@ namespace tb
URHO3D_EVENT(E_OPTIONS_OKAYED, OptionsOkayed) { }
URHO3D_EVENT(E_OPTIONS_CANCELLED, OptionsCancelled) {}
URHO3D_EVENT(E_OPTIONS_GRAPHICS_MODE, OptionsGraphicsMode) { URHO3D_PARAM(P_MONITOR, Monitor); URHO3D_PARAM(P_WIDTH, Width); URHO3D_PARAM(P_HEIGHT, Height); URHO3D_PARAM(P_REFRESH_RATE, RefreshRate); URHO3D_PARAM(P_SUCCESS, Success); }
URHO3D_EVENT(E_OPTIONS_ENABLE_SHADOWS, OptionsEnableShadows) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_OPTIONS_ENABLE_CLOUDS, OptionsEnableClouds) { URHO3D_PARAM(P_ENABLE, Enable); }
URHO3D_EVENT(E_OPTIONS_ENABLE_HORIZON, OptionsEnableHorizon) { URHO3D_PARAM(P_ENABLE, Enable); }
@ -46,6 +48,8 @@ public:
private:
void HandleClose(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleMonitorChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleResolutionChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleShadowsChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleCloudsChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleHorizonChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
@ -58,6 +62,13 @@ private:
void HandleTBMessage(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
private:
void FillMonitors();
void FillResolutionForMonitor(int monitor);
int GetResolutionIndexFor(int monitor, int width, int height, int refresh_rate) const;
private:
tb::TBSelectDropdown *monitorWidget;
tb::TBSelectDropdown *resolutionWidget;
tb::TBCheckBox *shadowsWidget;
tb::TBCheckBox *cloudsWidget;
tb::TBCheckBox *horizonWidget;
@ -68,6 +79,15 @@ private:
tb::TBButton *decTimeOfDayWidget;
tb::TBSelectDropdown *fontSizeWidget;
tb::TBCheckBox *showFlagsWidget;
tb::TBGenericStringItemSource monitor_source;
tb::TBGenericStringItemSource resolution_source;
int current_monitor;
int current_width;
int current_height;
int current_refresh_rate;
bool initializing_resolution_list;
};
#endif

View File

@ -765,6 +765,9 @@ void UIUrho3D::HandleOptions(StringHash eventType, VariantMap& eventData)
SubscribeToEvent(optionsDialog, E_OPTIONS_CANCELLED, [this](StringHash eventType, VariantMap& eventData) {
optionsDialog = NULL;
});
SubscribeToEvent(optionsDialog, E_OPTIONS_GRAPHICS_MODE, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_GRAPHICS_MODE, eventData);
});
SubscribeToEvent(optionsDialog, E_OPTIONS_ENABLE_SHADOWS, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_ENABLE_SHADOWS, eventData);
});

View File

@ -92,6 +92,7 @@ URHO3D_EVENT(E_CRYPTOCITY_GIVE_ITEMS, GiveItems) { URHO3D_PARAM(P_RECIPIENT, Rec
URHO3D_EVENT(E_CRYPTOCITY_GIVE_MONEY, GiveMoney) { URHO3D_PARAM(P_RECIPIENT, Recipient); URHO3D_PARAM(P_AMOUNT, Amount); /* uint64_t */ }
URHO3D_EVENT(E_CRYPTOCITY_EXIT, Exit) { }
URHO3D_EVENT(E_CRYPTOCITY_CAMERA_TYPE, CameraType) { URHO3D_PARAM(P_TYPE, Type); }
URHO3D_EVENT(E_CRYPTOCITY_GRAPHICS_MODE, GraphicsMode) { URHO3D_PARAM(P_MONITOR, Monitor); URHO3D_PARAM(P_WIDTH, Width); URHO3D_PARAM(P_HEIGHT, Height); URHO3D_PARAM(P_REFRESH_RATE, RefreshRate); URHO3D_PARAM(P_SUCCESS, Success); }
class UIUrho3D: public Urho3D::UIElement
{
@ -155,6 +156,7 @@ private:
void HandleTravelToCity(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleLeaderboards(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleCameraType(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleGraphicsMode(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void NotifyEditMode(EditMode mode);