Merge pull request #847 from xphere07/temperaturescales

Add temperature scales option
This commit is contained in:
jacob1 2022-12-27 11:59:16 -05:00 committed by GitHub
commit f1cf0ade70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 161 additions and 49 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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:

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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
{