Save ambient heat temperature and add it to options

This commit is contained in:
Tamás Bálint Misius 2021-06-04 22:39:07 +02:00
parent 7cfc5aa9f6
commit ffe730c615
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
15 changed files with 191 additions and 25 deletions

View File

@ -26,6 +26,7 @@ GameSave::GameSave(GameSave & save):
paused(save.paused),
gravityMode(save.gravityMode),
airMode(save.airMode),
ambientAirTemp(save.ambientAirTemp),
edgeMode(save.edgeMode),
signs(save.signs),
stkm(save.stkm),
@ -173,6 +174,7 @@ void GameSave::InitVars()
paused = false;
gravityMode = 0;
airMode = 0;
ambientAirTemp = R_TEMP + 273.15f;
edgeMode = 0;
translated.x = translated.y = 0;
pmapbits = 8; // default to 8 bits for older saves
@ -571,6 +573,21 @@ void GameSave::CheckBsonFieldInt(bson_iterator iter, const char *field, int *set
}
}
void GameSave::CheckBsonFieldFloat(bson_iterator iter, const char *field, float *setting)
{
if (!strcmp(bson_iterator_key(&iter), field))
{
if (bson_iterator_type(&iter) == BSON_DOUBLE)
{
*setting = float(bson_iterator_int(&iter));
}
else
{
fprintf(stderr, "Wrong type for %s\n", bson_iterator_key(&iter));
}
}
}
void GameSave::readOPS(char * data, int dataLength)
{
unsigned char *inputData = (unsigned char*)data, *bsonData = NULL, *partsData = NULL, *partsPosData = NULL, *fanData = NULL, *wallData = NULL, *soapLinkData = NULL;
@ -668,6 +685,7 @@ void GameSave::readOPS(char * data, int dataLength)
CheckBsonFieldBool(iter, "paused", &paused);
CheckBsonFieldInt(iter, "gravityMode", &gravityMode);
CheckBsonFieldInt(iter, "airMode", &airMode);
CheckBsonFieldFloat(iter, "ambientAirTemp", &ambientAirTemp);
CheckBsonFieldInt(iter, "edgeMode", &edgeMode);
CheckBsonFieldInt(iter, "pmapbits", &pmapbits);
if (!strcmp(bson_iterator_key(&iter), "signs"))
@ -2550,6 +2568,7 @@ char * GameSave::serialiseOPS(unsigned int & dataLength)
bson_append_bool(&b, "paused", paused);
bson_append_int(&b, "gravityMode", gravityMode);
bson_append_int(&b, "airMode", airMode);
bson_append_double(&b, "ambientAirTemp", double(ambientAirTemp));
bson_append_int(&b, "edgeMode", edgeMode);
if (stkm.hasData())

View File

@ -96,6 +96,7 @@ public:
bool paused;
int gravityMode;
int airMode;
float ambientAirTemp;
int edgeMode;
//Signs
@ -149,6 +150,7 @@ private:
void CheckBsonFieldUser(bson_iterator iter, const char *field, unsigned char **data, unsigned int *fieldLen);
void CheckBsonFieldBool(bson_iterator iter, const char *field, bool *flag);
void CheckBsonFieldInt(bson_iterator iter, const char *field, int *setting);
void CheckBsonFieldFloat(bson_iterator iter, const char *field, float *setting);
template <typename T> T ** Allocate2DArray(int blockWidth, int blockHeight, T defaultVal);
template <typename T> void Deallocate2DArray(T ***array, int blockHeight);
void dealloc();

View File

@ -2368,6 +2368,14 @@ void Renderer::draw_grav()
}
}
int HeatToColour(float temp)
{
constexpr float min_temp = MIN_TEMP;
constexpr float max_temp = MAX_TEMP;
int caddress = int(restrict_flt((temp - min_temp) / (max_temp - min_temp) * 1024, 0, 1023)) * 3;
return PIXRGB((int)(color_data[caddress]*0.7f), (int)(color_data[caddress+1]*0.7f), (int)(color_data[caddress+2]*0.7f));
}
void Renderer::draw_air()
{
if(!sim->aheat_enable && (display_mode & DISPLAY_AIRH))
@ -2399,10 +2407,7 @@ void Renderer::draw_air()
}
else if (display_mode & DISPLAY_AIRH)
{
constexpr float min_temp = MIN_TEMP;
constexpr float max_temp = MAX_TEMP;
int caddress = int(restrict_flt((hv[y][x] - min_temp) / (max_temp - min_temp) * 1024, 0, 1023)) * 3;
c = PIXRGB((int)(color_data[caddress]*0.7f), (int)(color_data[caddress+1]*0.7f), (int)(color_data[caddress+2]*0.7f));
c = HeatToColour(hv[y][x]);
//c = PIXRGB(clamp_flt(fabsf(vx[y][x]), 0.0f, 8.0f),//vx adds red
// clamp_flt(hv[y][x], 0.0f, 1600.0f),//heat adds green
// clamp_flt(fabsf(vy[y][x]), 0.0f, 8.0f));//vy adds blue

View File

@ -50,6 +50,7 @@ GameModel::GameModel():
colourSelector(false),
colour(255, 0, 0, 255),
edgeMode(0),
ambientAirTemp(R_TEMP + 273.15f),
decoSpace(0)
{
sim = new Simulation();
@ -95,6 +96,15 @@ GameModel::GameModel():
//Load config into simulation
edgeMode = Client::Ref().GetPrefInteger("Simulation.EdgeMode", 0);
sim->SetEdgeMode(edgeMode);
ambientAirTemp = R_TEMP + 273.15;
{
auto temp = Client::Ref().GetPrefNumber("Simulation.AmbientAirTemp", ambientAirTemp);
if (MIN_TEMP <= temp && MAX_TEMP >= temp)
{
ambientAirTemp = temp;
}
}
sim->air->ambientAirTemp = ambientAirTemp;
decoSpace = Client::Ref().GetPrefInteger("Simulation.DecoSpace", 0);
sim->SetDecoSpace(decoSpace);
int ngrav_enable = Client::Ref().GetPrefInteger("Simulation.NewtonianGravity", 0);
@ -140,6 +150,8 @@ GameModel::GameModel():
mouseClickRequired = Client::Ref().GetPrefBool("MouseClickRequired", false);
includePressure = Client::Ref().GetPrefBool("Simulation.IncludePressure", true);
ClearSimulation();
}
GameModel::~GameModel()
@ -519,6 +531,17 @@ int GameModel::GetEdgeMode()
return this->edgeMode;
}
void GameModel::SetAmbientAirTemperature(float ambientAirTemp)
{
this->ambientAirTemp = ambientAirTemp;
sim->air->ambientAirTemp = ambientAirTemp;
}
float GameModel::GetAmbientAirTemperature()
{
return this->ambientAirTemp;
}
void GameModel::SetDecoSpace(int decoSpace)
{
sim->SetDecoSpace(decoSpace);
@ -735,6 +758,7 @@ void GameModel::SetSave(SaveInfo * newSave, bool invertIncludePressure)
SetPaused(saveData->paused | GetPaused());
sim->gravityMode = saveData->gravityMode;
sim->air->airMode = saveData->airMode;
sim->air->ambientAirTemp = saveData->ambientAirTemp;
sim->edgeMode = saveData->edgeMode;
sim->legacy_enable = saveData->legacyEnable;
sim->water_equal_test = saveData->waterEEnabled;
@ -796,6 +820,7 @@ void GameModel::SetSaveFile(SaveFile * newSave, bool invertIncludePressure)
SetPaused(saveData->paused | GetPaused());
sim->gravityMode = saveData->gravityMode;
sim->air->airMode = saveData->airMode;
sim->air->ambientAirTemp = saveData->ambientAirTemp;
sim->edgeMode = saveData->edgeMode;
sim->legacy_enable = saveData->legacyEnable;
sim->water_equal_test = saveData->waterEEnabled;
@ -1111,6 +1136,7 @@ void GameModel::ClearSimulation()
sim->legacy_enable = false;
sim->water_equal_test = false;
sim->SetEdgeMode(edgeMode);
sim->air->ambientAirTemp = ambientAirTemp;
sim->clear_sim();
ren->ClearAccumulation();

View File

@ -78,6 +78,7 @@ private:
ui::Colour colour;
int edgeMode;
float ambientAirTemp;
int decoSpace;
String infoTip;
@ -112,6 +113,8 @@ public:
void SetEdgeMode(int edgeMode);
int GetEdgeMode();
void SetAmbientAirTemperature(float edgeMode);
float GetAmbientAirTemperature();
void SetDecoSpace(int decoSpace);
int GetDecoSpace();

View File

@ -23,6 +23,27 @@
#include <iostream>
void ParseFloatProperty(String value, float &out)
{
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:
@ -189,23 +210,7 @@ void PropertyWindow::SetProperty()
}
case StructProperty::Float:
{
if (value.EndsWith("C"))
{
float v = value.SubstrFromEnd(1).ToNumber<float>();
tool->propValue.Float = v + 273.15;
}
else if(value.EndsWith("F"))
{
float v = value.SubstrFromEnd(1).ToNumber<float>();
tool->propValue.Float = (v-32.0f)*5/9+273.15f;
}
else
{
tool->propValue.Float = value.ToNumber<float>();
}
#ifdef DEBUG
std::cout << "Got float value " << tool->propValue.Float << std::endl;
#endif
ParseFloatProperty(value, tool->propValue.Float);
}
break;
default:

View File

@ -47,6 +47,11 @@ void OptionsController::SetAirMode(int airMode)
model->SetAirMode(airMode);
}
void OptionsController::SetAmbientAirTemperature(float ambientAirTemp)
{
model->SetAmbientAirTemperature(ambientAirTemp);
}
void OptionsController::SetEdgeMode(int edgeMode)
{
model->SetEdgeMode(edgeMode);

View File

@ -22,6 +22,7 @@ public:
void SetWaterEqualisation(bool state);
void SetGravityMode(int gravityMode);
void SetAirMode(int airMode);
void SetAmbientAirTemperature(float ambientAirTemp);
void SetEdgeMode(int edgeMode);
void SetFullscreen(bool fullscreen);
void SetAltFullscreen(bool altFullscreen);

View File

@ -90,6 +90,17 @@ void OptionsModel::SetEdgeMode(int edgeMode)
notifySettingsChanged();
}
float OptionsModel::GetAmbientAirTemperature()
{
return gModel->GetSimulation()->air->ambientAirTemp;
}
void OptionsModel::SetAmbientAirTemperature(float ambientAirTemp)
{
Client::Ref().SetPref("Simulation.AmbientAirTemp", ambientAirTemp);
gModel->SetAmbientAirTemperature(ambientAirTemp);
notifySettingsChanged();
}
int OptionsModel::GetGravityMode()
{
return sim->gravityMode;

View File

@ -28,6 +28,8 @@ public:
void SetShowAvatars(bool state);
int GetAirMode();
void SetAirMode(int airMode);
float GetAmbientAirTemperature();
void SetAmbientAirTemperature(float ambientAirTemp);
int GetEdgeMode();
void SetEdgeMode(int edgeMode);
int GetGravityMode();

View File

@ -1,5 +1,6 @@
#include "OptionsView.h"
#include "simulation/ElementDefs.h"
#include "OptionsController.h"
#include "OptionsModel.h"
@ -20,11 +21,14 @@
#include "gui/interface/DropDown.h"
#include "gui/interface/Engine.h"
#include "gui/interface/Checkbox.h"
#include "gui/interface/Textbox.h"
#include "graphics/Graphics.h"
OptionsView::OptionsView():
ui::Window(ui::Point(-1, -1), ui::Point(320, 340)){
ui::Window(ui::Point(-1, -1), ui::Point(320, 340)),
ambientAirTempPreviewValid(false)
{
auto autowidth = [this](ui::Component *c) {
c->Size.X = Size.X - c->Position.X - 12;
@ -119,6 +123,41 @@ OptionsView::OptionsView():
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
scrollPanel->AddChild(tempLabel);
currentY+=20;
ambientAirTemp = new ui::Textbox(ui::Point(Size.X-95, currentY), ui::Point(60, 16));
ambientAirTemp->SetActionCallback({ [this] {
float temp;
try
{
void ParseFloatProperty(String value, float &out);
ParseFloatProperty(ambientAirTemp->GetText(), temp);
ambientAirTempPreviewValid = true;
}
catch (const std::exception &ex)
{
ambientAirTempPreviewValid = false;
}
if (!(MIN_TEMP <= temp && MAX_TEMP >= temp))
{
ambientAirTempPreviewValid = false;
}
if (ambientAirTempPreviewValid)
{
ambientAirTempPreviewValue = temp;
c->SetAmbientAirTemperature(ambientAirTempPreviewValue);
}
UpdateAmbientAirTempPreview();
} });
scrollPanel->AddChild(ambientAirTemp);
ambientAirTempPreview = new ui::Button(ui::Point(Size.X-31, currentY), ui::Point(16, 16), "", "Preview");
scrollPanel->AddChild(ambientAirTempPreview);
tempLabel = new ui::Label(ui::Point(8, currentY), ui::Point(Size.X-96, 16), "Ambient Air Temperature");
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
scrollPanel->AddChild(tempLabel);
currentY+=20;
gravityMode = new ui::DropDown(ui::Point(Size.X-95, currentY), ui::Point(80, 16));
scrollPanel->AddChild(gravityMode);
@ -330,6 +369,23 @@ OptionsView::OptionsView():
scrollPanel->InnerSize = ui::Point(Size.X, currentY);
}
void OptionsView::UpdateAmbientAirTempPreview()
{
if (ambientAirTempPreviewValid)
{
int HeatToColour(float temp);
int c = HeatToColour(ambientAirTempPreviewValue);
ambientAirTempPreview->Appearance.BackgroundInactive = ui::Colour(PIXR(c), PIXG(c), PIXB(c));
ambientAirTempPreview->SetText("");
}
else
{
ambientAirTempPreview->Appearance.BackgroundInactive = ui::Colour(0, 0, 0);
ambientAirTempPreview->SetText("?");
}
ambientAirTempPreview->Appearance.BackgroundHover = ambientAirTempPreview->Appearance.BackgroundInactive;
}
void OptionsView::NotifySettingsChanged(OptionsModel * sender)
{
heatSimulation->SetChecked(sender->GetHeatSimulation());
@ -337,6 +393,30 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
newtonianGravity->SetChecked(sender->GetNewtonianGravity());
waterEqualisation->SetChecked(sender->GetWaterEqualisation());
airMode->SetOption(sender->GetAirMode());
if (!ambientAirTempPreviewValid)
{
// * ambientAirTempPreviewValid is initially false (see constructor). Thus, when
// NotifySettingsChanged is first called when the view is registered as an
// observer, this block executes. Once this happens, NotifySettingsChanged is
// only ever called when some setting is changed by the user in OptionsView.
// This means either a change that doesn't involve the ambientAirTemp Textbox,
// or one that does involve it. The latter case can only happen if the action
// callback of the Textbox called OptionsController::SetAmbientAirTemperature,
// which in turn implies that ambientAirTempPreviewValid is already true.
// * What this all boils down to is that this block is only ever run on two
// occasions: when OptionsView is initialized and when the user decides to
// cancel changing the ambient temperature via the ambientAirTemp Textbox,
// and hasn't yet succeeded. What we want to avoid is SetText being called
// on the Textbox while the user is actively editing its contents, so this
// works out perfectly.
// * Rather twisted. I blame the MVC pattern TPT uses. -- LBPHacker
ambientAirTempPreviewValid = true;
ambientAirTempPreviewValue = sender->GetAmbientAirTemperature();
UpdateAmbientAirTempPreview();
StringBuilder sb;
sb << Format::Precision(2) << ambientAirTempPreviewValue;
ambientAirTemp->SetText(sb.Build());
}
gravityMode->SetOption(sender->GetGravityMode());
decoSpace->SetOption(sender->GetDecoSpace());
edgeMode->SetOption(sender->GetEdgeMode());

View File

@ -8,7 +8,8 @@ namespace ui
{
class Checkbox;
class DropDown;
class DropDown;
class Textbox;
class Button;
}
class OptionsModel;
@ -21,6 +22,8 @@ class OptionsView: public ui::Window
ui::Checkbox * newtonianGravity;
ui::Checkbox * waterEqualisation;
ui::DropDown * airMode;
ui::Textbox * ambientAirTemp;
ui::Button * ambientAirTempPreview;
ui::DropDown * gravityMode;
ui::DropDown * edgeMode;
ui::DropDown * scale;
@ -36,6 +39,9 @@ class OptionsView: public ui::Window
ui::Checkbox * includePressure;
ui::Checkbox * perfectCirclePressure;
ui::ScrollPanel * scrollPanel;
bool ambientAirTempPreviewValid;
float ambientAirTempPreviewValue;
void UpdateAmbientAirTempPreview();
public:
OptionsView();
void NotifySettingsChanged(OptionsModel * sender);

View File

@ -1935,7 +1935,7 @@ int LuaScriptInterface::simulation_ambientAirTemp(lua_State * l)
return 1;
}
float ambientAirTemp = luaL_optnumber(l, 1, 295.15f);
luacon_sim->air->ambientAirTemp = ambientAirTemp;
luacon_model->SetAmbientAirTemperature(ambientAirTemp);
return 0;
}

View File

@ -385,7 +385,7 @@ void Air::RecalculateBlockAirMaps()
Air::Air(Simulation & simulation):
sim(simulation),
airMode(0),
ambientAirTemp(295.15f)
ambientAirTemp(R_TEMP + 273.15f)
{
//Simulation should do this.
make_kernel();

View File

@ -551,6 +551,7 @@ void Simulation::SaveSimOptions(GameSave * gameSave)
return;
gameSave->gravityMode = gravityMode;
gameSave->airMode = air->airMode;
gameSave->ambientAirTemp = air->ambientAirTemp;
gameSave->edgeMode = edgeMode;
gameSave->legacyEnable = legacy_enable;
gameSave->waterEEnabled = water_equal_test;