Add temperature scales option
Make the PROP tool default to the current temperature scale Make the PROP tool's temp suffixes work in the console(This is currently blocked by AnyType doing resource management wrong) Signed-off-by: xphere07 <xphere07@outlook.com>
This commit is contained in:
parent
6b133aced6
commit
fe67ec8550
@ -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);
|
||||
|
@ -2285,7 +2285,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)
|
||||
{
|
||||
@ -2315,7 +2316,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;
|
||||
}
|
||||
}
|
||||
@ -2386,7 +2388,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,25 @@ void OptionsView::UpdateAmbientAirTempPreview(float airTemp, bool isValid)
|
||||
ambientAirTempPreview->Appearance.BackgroundHover = ambientAirTempPreview->Appearance.BackgroundInactive;
|
||||
}
|
||||
|
||||
void OptionsView::AmbientAirTempToTextBox(float airTemp)
|
||||
{
|
||||
StringBuilder sb;
|
||||
sb << Format::Precision(2);
|
||||
switch (temperatureScale->GetOption().second)
|
||||
{
|
||||
case 1:
|
||||
sb << (airTemp - 273.15f) << "C";
|
||||
break;
|
||||
case 2:
|
||||
sb << (airTemp - 273.15f) * 1.8f + 32.0f << "F";
|
||||
break;
|
||||
default:
|
||||
sb << airTemp;
|
||||
break;
|
||||
}
|
||||
ambientAirTemp->SetText(sb.Build());
|
||||
}
|
||||
|
||||
void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
{
|
||||
// Parse air temp and determine validity
|
||||
@ -444,8 +477,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)
|
||||
@ -470,10 +502,7 @@ void OptionsView::UpdateAirTemp(String temp, bool isDefocus)
|
||||
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 +517,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
|
||||
{
|
||||
|
Reference in New Issue
Block a user