Merge pull request #847 from xphere07/temperaturescales
Add temperature scales option
This commit is contained in:
commit
f1cf0ade70
@ -178,3 +178,57 @@ ByteString format::URLDecode(ByteString source)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void format::RenderTemperature(StringBuilder &sb, float temp, int scale)
|
||||
{
|
||||
switch (scale)
|
||||
{
|
||||
case 1:
|
||||
sb << (temp - 273.15f) << "C";
|
||||
break;
|
||||
case 2:
|
||||
sb << (temp - 273.15f) * 1.8f + 32.0f << "F";
|
||||
break;
|
||||
default:
|
||||
sb << temp << "K";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float format::StringToTemperature(String str, int defaultScale)
|
||||
{
|
||||
auto scale = defaultScale;
|
||||
if (str.size())
|
||||
{
|
||||
if (str.EndsWith("K"))
|
||||
{
|
||||
scale = 0;
|
||||
str = str.SubstrFromEnd(1);
|
||||
}
|
||||
else if (str.EndsWith("C"))
|
||||
{
|
||||
scale = 1;
|
||||
str = str.SubstrFromEnd(1);
|
||||
}
|
||||
else if (str.EndsWith("F"))
|
||||
{
|
||||
scale = 2;
|
||||
str = str.SubstrFromEnd(1);
|
||||
}
|
||||
}
|
||||
if (!str.size())
|
||||
{
|
||||
throw std::out_of_range("empty string");
|
||||
}
|
||||
auto out = str.ToNumber<float>();
|
||||
switch (scale)
|
||||
{
|
||||
case 1:
|
||||
out = out + 273.15;
|
||||
break;
|
||||
case 2:
|
||||
out = (out - 32.0f) / 1.8f + 273.15f;
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
@ -14,4 +14,6 @@ namespace format
|
||||
ByteString UnixtimeToDateMini(time_t unixtime);
|
||||
String CleanString(String dirtyString, bool ascii, bool color, bool newlines, bool numeric = false);
|
||||
std::vector<char> VideoBufferToPPM(const VideoBuffer & vidBuf);
|
||||
void RenderTemperature(StringBuilder &sb, float temp, int scale);
|
||||
float StringToTemperature(String str, int defaultScale);
|
||||
}
|
||||
|
@ -1035,6 +1035,16 @@ bool GameController::GetDebugHUD()
|
||||
return gameView->GetDebugHUD();
|
||||
}
|
||||
|
||||
void GameController::SetTemperatureScale(int temperatureScale)
|
||||
{
|
||||
gameModel->SetTemperatureScale(temperatureScale);
|
||||
}
|
||||
|
||||
int GameController::GetTemperatureScale()
|
||||
{
|
||||
return gameModel->GetTemperatureScale();
|
||||
}
|
||||
|
||||
void GameController::SetActiveColourPreset(int preset)
|
||||
{
|
||||
gameModel->SetActiveColourPreset(preset);
|
||||
|
@ -119,6 +119,8 @@ public:
|
||||
bool GetBrushEnable();
|
||||
void SetDebugHUD(bool hudState);
|
||||
bool GetDebugHUD();
|
||||
void SetTemperatureScale(int temperatureScale);
|
||||
int GetTemperatureScale();
|
||||
void SetDebugFlags(unsigned int flags) { debugFlags = flags; }
|
||||
void SetActiveMenu(int menuID);
|
||||
std::vector<Menu*> GetMenuList();
|
||||
|
@ -154,6 +154,7 @@ GameModel::GameModel():
|
||||
|
||||
mouseClickRequired = Client::Ref().GetPrefBool("MouseClickRequired", false);
|
||||
includePressure = Client::Ref().GetPrefBool("Simulation.IncludePressure", true);
|
||||
temperatureScale = Client::Ref().GetPrefInteger("Renderer.TemperatureScale", 1);
|
||||
|
||||
ClearSimulation();
|
||||
}
|
||||
@ -534,6 +535,11 @@ int GameModel::GetEdgeMode()
|
||||
return this->edgeMode;
|
||||
}
|
||||
|
||||
void GameModel::SetTemperatureScale(int temperatureScale)
|
||||
{
|
||||
this->temperatureScale = temperatureScale;
|
||||
}
|
||||
|
||||
void GameModel::SetAmbientAirTemperature(float ambientAirTemp)
|
||||
{
|
||||
this->ambientAirTemp = ambientAirTemp;
|
||||
|
@ -81,6 +81,7 @@ private:
|
||||
bool mouseClickRequired;
|
||||
bool includePressure;
|
||||
bool perfectCircle = true;
|
||||
int temperatureScale;
|
||||
|
||||
size_t activeColourPreset;
|
||||
std::vector<ui::Colour> colourPresets;
|
||||
@ -123,6 +124,11 @@ public:
|
||||
|
||||
void SetEdgeMode(int edgeMode);
|
||||
int GetEdgeMode();
|
||||
void SetTemperatureScale(int temperatureScale);
|
||||
inline int GetTemperatureScale() const
|
||||
{
|
||||
return temperatureScale;
|
||||
}
|
||||
void SetAmbientAirTemperature(float ambientAirTemp);
|
||||
float GetAmbientAirTemperature();
|
||||
void SetDecoSpace(int decoSpace);
|
||||
|
@ -2305,7 +2305,8 @@ void GameView::OnDraw()
|
||||
else if (ctype)
|
||||
sampleInfo << " (" << ctype << ")";
|
||||
}
|
||||
sampleInfo << ", Temp: " << (sample.particle.temp - 273.15f) << " C";
|
||||
sampleInfo << ", Temp: ";
|
||||
format::RenderTemperature(sampleInfo, sample.particle.temp, c->GetTemperatureScale());
|
||||
sampleInfo << ", Life: " << sample.particle.life;
|
||||
if (sample.particle.type != PT_RFRG && sample.particle.type != PT_RFGL && sample.particle.type != PT_LIFE)
|
||||
{
|
||||
@ -2335,7 +2336,8 @@ void GameView::OnDraw()
|
||||
else
|
||||
{
|
||||
sampleInfo << c->BasicParticleInfo(sample.particle);
|
||||
sampleInfo << ", Temp: " << sample.particle.temp - 273.15f << " C";
|
||||
sampleInfo << ", Temp: ";
|
||||
format::RenderTemperature(sampleInfo, sample.particle.temp, c->GetTemperatureScale());
|
||||
sampleInfo << ", Pressure: " << sample.AirPressure;
|
||||
}
|
||||
}
|
||||
@ -2406,7 +2408,10 @@ void GameView::OnDraw()
|
||||
sampleInfo << ", GX: " << sample.GravityVelocityX << " GY: " << sample.GravityVelocityY;
|
||||
|
||||
if (c->GetAHeatEnable())
|
||||
sampleInfo << ", AHeat: " << sample.AirTemperature - 273.15f << " C";
|
||||
{
|
||||
sampleInfo << ", AHeat: ";
|
||||
format::RenderTemperature(sampleInfo, sample.AirTemperature, c->GetTemperatureScale());
|
||||
}
|
||||
|
||||
textWidth = Graphics::textwidth(sampleInfo.Build());
|
||||
g->fillrect(XRES-20-textWidth, 27, textWidth+8, 14, 0, 0, 0, int(alpha*0.5f));
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "client/Client.h"
|
||||
#include "Menu.h"
|
||||
#include "Format.h"
|
||||
|
||||
#include "gui/game/GameModel.h"
|
||||
#include "gui/Style.h"
|
||||
@ -23,31 +24,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void ParseFloatProperty(String value, float &out)
|
||||
{
|
||||
if (!value.size())
|
||||
{
|
||||
throw std::out_of_range("empty string");
|
||||
}
|
||||
if (value.EndsWith("C"))
|
||||
{
|
||||
float v = value.SubstrFromEnd(1).ToNumber<float>();
|
||||
out = v + 273.15;
|
||||
}
|
||||
else if(value.EndsWith("F"))
|
||||
{
|
||||
float v = value.SubstrFromEnd(1).ToNumber<float>();
|
||||
out = (v-32.0f)*5/9+273.15f;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = value.ToNumber<float>();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
std::cout << "Got float value " << out << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
class PropertyWindow: public ui::Window
|
||||
{
|
||||
public:
|
||||
@ -219,7 +195,7 @@ void PropertyWindow::SetProperty(bool warn)
|
||||
}
|
||||
case StructProperty::Float:
|
||||
{
|
||||
ParseFloatProperty(value, tool->propValue.Float);
|
||||
tool->propValue.Float = format::StringToTemperature(value, tool->gameModel->GetTemperatureScale());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -67,6 +67,11 @@ void OptionsController::SetEdgeMode(int edgeMode)
|
||||
model->SetEdgeMode(edgeMode);
|
||||
}
|
||||
|
||||
void OptionsController::SetTemperatureScale(int temperatureScale)
|
||||
{
|
||||
model->SetTemperatureScale(temperatureScale);
|
||||
}
|
||||
|
||||
void OptionsController::SetFullscreen(bool fullscreen)
|
||||
{
|
||||
model->SetFullscreen(fullscreen);
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
void SetAirMode(int airMode);
|
||||
void SetAmbientAirTemperature(float ambientAirTemp);
|
||||
void SetEdgeMode(int edgeMode);
|
||||
void SetTemperatureScale(int temperatureScale);
|
||||
void SetFullscreen(bool fullscreen);
|
||||
void SetAltFullscreen(bool altFullscreen);
|
||||
void SetForceIntegerScaling(bool forceIntegerScaling);
|
||||
|
@ -90,6 +90,17 @@ void OptionsModel::SetEdgeMode(int edgeMode)
|
||||
notifySettingsChanged();
|
||||
}
|
||||
|
||||
int OptionsModel::GetTemperatureScale()
|
||||
{
|
||||
return gModel->GetTemperatureScale();
|
||||
}
|
||||
void OptionsModel::SetTemperatureScale(int temperatureScale)
|
||||
{
|
||||
Client::Ref().SetPref("Renderer.TemperatureScale", temperatureScale);
|
||||
gModel->SetTemperatureScale(temperatureScale);
|
||||
notifySettingsChanged();
|
||||
}
|
||||
|
||||
float OptionsModel::GetAmbientAirTemperature()
|
||||
{
|
||||
return gModel->GetSimulation()->air->ambientAirTemp;
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
void SetAmbientAirTemperature(float ambientAirTemp);
|
||||
int GetEdgeMode();
|
||||
void SetEdgeMode(int edgeMode);
|
||||
int GetTemperatureScale();
|
||||
void SetTemperatureScale(int temperatureScale);
|
||||
int GetGravityMode();
|
||||
void SetGravityMode(int gravityMode);
|
||||
float GetCustomGravityX();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include "SDLCompat.h"
|
||||
#include "Format.h"
|
||||
|
||||
#include "OptionsController.h"
|
||||
#include "OptionsModel.h"
|
||||
@ -235,6 +236,19 @@ OptionsView::OptionsView():
|
||||
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
scrollPanel->AddChild(tempLabel);
|
||||
|
||||
currentY+=20;
|
||||
temperatureScale = new ui::DropDown(ui::Point(Size.X-95, currentY), ui::Point(80, 16));
|
||||
scrollPanel->AddChild(temperatureScale);
|
||||
temperatureScale->AddOption(std::pair<String, int>("Kelvin", 0));
|
||||
temperatureScale->AddOption(std::pair<String, int>("Celsius", 1));
|
||||
temperatureScale->AddOption(std::pair<String, int>("Fahrenheit", 2));
|
||||
temperatureScale->SetActionCallback({ [this] { c->SetTemperatureScale(temperatureScale->GetOption().second); } });
|
||||
|
||||
tempLabel = new ui::Label(ui::Point(8, currentY), ui::Point(Size.X-96, 16), "Temperature Scale");
|
||||
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
scrollPanel->AddChild(tempLabel);
|
||||
|
||||
currentY+=20;
|
||||
tmpSeparator = new Separator(ui::Point(0, currentY), ui::Point(Size.X, 1));
|
||||
scrollPanel->AddChild(tmpSeparator);
|
||||
@ -437,6 +451,14 @@ void OptionsView::UpdateAmbientAirTempPreview(float airTemp, bool isValid)
|
||||
ambientAirTempPreview->Appearance.BackgroundHover = ambientAirTempPreview->Appearance.BackgroundInactive;
|
||||
}
|
||||
|
||||
void OptionsView::AmbientAirTempToTextBox(float airTemp)
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb << Format::Precision(2);
|
||||
format::RenderTemperature(sb, airTemp, temperatureScale->GetOption().second);
|
||||
ambientAirTemp->SetText(sb.Build());
|
||||
}
|
||||
|
||||
void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
{
|
||||
// Parse air temp and determine validity
|
||||
@ -444,8 +466,7 @@ void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
bool isValid;
|
||||
try
|
||||
{
|
||||
void ParseFloatProperty(String value, float &out);
|
||||
ParseFloatProperty(temp, airTemp);
|
||||
airTemp = format::StringToTemperature(temp, temperatureScale->GetOption().second);
|
||||
isValid = true;
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
@ -467,13 +488,8 @@ void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
airTemp = MIN_TEMP;
|
||||
else if (airTemp > MAX_TEMP)
|
||||
airTemp = MAX_TEMP;
|
||||
else
|
||||
return;
|
||||
|
||||
// Update textbox with the new value
|
||||
StringBuilder sb;
|
||||
sb << Format::Precision(2) << airTemp;
|
||||
ambientAirTemp->SetText(sb.Build());
|
||||
AmbientAirTempToTextBox(airTemp);
|
||||
}
|
||||
// Out of range temperatures are invalid, preview should go away
|
||||
else if (isValid && (airTemp < MIN_TEMP || airTemp > MAX_TEMP))
|
||||
@ -488,20 +504,18 @@ void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
|
||||
void OptionsView::NotifySettingsChanged(OptionsModel * sender)
|
||||
{
|
||||
temperatureScale->SetOption(sender->GetTemperatureScale()); // has to happen before AmbientAirTempToTextBox is called
|
||||
heatSimulation->SetChecked(sender->GetHeatSimulation());
|
||||
ambientHeatSimulation->SetChecked(sender->GetAmbientHeatSimulation());
|
||||
newtonianGravity->SetChecked(sender->GetNewtonianGravity());
|
||||
waterEqualisation->SetChecked(sender->GetWaterEqualisation());
|
||||
airMode->SetOption(sender->GetAirMode());
|
||||
// Initialize air temp and preview only when the options menu is opened, and not when user is actively editing the textbox
|
||||
if (!initializedAirTempPreview)
|
||||
if (!ambientAirTemp->IsFocused())
|
||||
{
|
||||
initializedAirTempPreview = true;
|
||||
float airTemp = sender->GetAmbientAirTemperature();
|
||||
UpdateAmbientAirTempPreview(airTemp, true);
|
||||
StringBuilder sb;
|
||||
sb << Format::Precision(2) << airTemp;
|
||||
ambientAirTemp->SetText(sb.Build());
|
||||
AmbientAirTempToTextBox(airTemp);
|
||||
}
|
||||
gravityMode->SetOption(sender->GetGravityMode());
|
||||
customGravityX = sender->GetCustomGravityX();
|
||||
|
@ -27,6 +27,7 @@ class OptionsView: public ui::Window
|
||||
ui::Button * ambientAirTempPreview;
|
||||
ui::DropDown * gravityMode;
|
||||
ui::DropDown * edgeMode;
|
||||
ui::DropDown * temperatureScale;
|
||||
ui::DropDown * scale;
|
||||
ui::Checkbox * resizable;
|
||||
ui::Checkbox * fullscreen;
|
||||
@ -41,8 +42,8 @@ class OptionsView: public ui::Window
|
||||
ui::Checkbox * perfectCirclePressure;
|
||||
ui::ScrollPanel * scrollPanel;
|
||||
float customGravityX, customGravityY;
|
||||
bool initializedAirTempPreview = false;
|
||||
void UpdateAmbientAirTempPreview(float airTemp, bool isValid);
|
||||
void AmbientAirTempToTextBox(float airTemp);
|
||||
void UpdateAirTemp(String temp, bool isDefocus);
|
||||
public:
|
||||
OptionsView();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Format.h"
|
||||
|
||||
#include "simulation/Simulation.h"
|
||||
#include "simulation/Air.h"
|
||||
@ -271,6 +272,21 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
//Selector
|
||||
int newValue = 0;
|
||||
float newValuef = 0.0f;
|
||||
if (property.Value() == "temp")
|
||||
{
|
||||
// convert non-string temperature values to strings to format::StringToTemperature can take care of them
|
||||
switch (value.GetType())
|
||||
{
|
||||
case TypeNumber:
|
||||
value = StringType(String::Build(((NumberType)value).Value()));
|
||||
break;
|
||||
case TypeFloat:
|
||||
value = StringType(String::Build(((FloatType)value).Value()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (value.GetType() == TypeNumber)
|
||||
{
|
||||
newValuef = float(newValue = ((NumberType)value).Value());
|
||||
@ -283,13 +299,14 @@ AnyType TPTScriptInterface::tptS_set(std::deque<String> * words)
|
||||
{
|
||||
if (property.Value() == "temp")
|
||||
{
|
||||
String newString = ((StringType)value).Value();
|
||||
if (newString.at(newString.length()-1) == 'C')
|
||||
newValuef = atof(newString.SubstrFromEnd(1).ToUtf8().c_str())+273.15;
|
||||
else if (newString.at(newString.length()-1) == 'F')
|
||||
newValuef = (atof(newString.SubstrFromEnd(1).ToUtf8().c_str())-32.0f)*5/9+273.15f;
|
||||
else
|
||||
try
|
||||
{
|
||||
newValuef = format::StringToTemperature(((StringType)value).Value(), c->GetTemperatureScale());
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
throw GeneralException("Invalid value for assignment");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user