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:
xphere07 2022-12-27 22:07:52 +09:00
parent 6b133aced6
commit fe67ec8550
No known key found for this signature in database
GPG Key ID: AE1AD11DF516617D
15 changed files with 172 additions and 47 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

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

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

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
{