Make a copy of particles before saving them and work off that

This is a minor refactor before the next commit; the significance of that commit would get lost in this noise otherwise.
This commit is contained in:
Tamás Bálint Misius
2025-01-15 19:00:14 +01:00
parent a7d73102d6
commit 2b0ee9392c

View File

@@ -2200,33 +2200,34 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
//Store saved particle index+1 for this partsptr index (0 means not saved) //Store saved particle index+1 for this partsptr index (0 means not saved)
partsSaveIndex[i] = (partsCount++) + 1; partsSaveIndex[i] = (partsCount++) + 1;
paletteSet.insert(particles[i].type); auto part = particles[i];
paletteSet.insert(part.type);
for (auto index : possiblyCarriesType) for (auto index : possiblyCarriesType)
{ {
if (elements[particles[i].type].CarriesTypeIn & (1U << index)) if (elements[part.type].CarriesTypeIn & (1U << index))
{ {
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset); auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&part) + properties[index].Offset);
paletteSet.insert(TYP(*prop)); paletteSet.insert(TYP(*prop));
} }
} }
//Type (required) //Type (required)
partsData[partsDataLen++] = particles[i].type; partsData[partsDataLen++] = part.type;
//Location of the field descriptor //Location of the field descriptor
int fieldDesc3Loc = 0; int fieldDesc3Loc = 0;
int fieldDescLoc = partsDataLen++; int fieldDescLoc = partsDataLen++;
partsDataLen++; partsDataLen++;
auto tmp3 = (unsigned int)(particles[i].tmp3); auto tmp3 = (unsigned int)(part.tmp3);
auto tmp4 = (unsigned int)(particles[i].tmp4); auto tmp4 = (unsigned int)(part.tmp4);
if ((tmp3 || tmp4) && (!PressureInTmp3(particles[i].type) || hasPressure)) if ((tmp3 || tmp4) && (!PressureInTmp3(part.type) || hasPressure))
{ {
fieldDesc |= 1 << 13; fieldDesc |= 1 << 13;
// The tmp3 of PressureInTmp3 elements is okay to truncate because the loading code // The tmp3 of PressureInTmp3 elements is okay to truncate because the loading code
// sign extends it anyway, expecting the value to not be higher in magnitude than // sign extends it anyway, expecting the value to not be higher in magnitude than
// 256 (max pressure value) * 64 (tmp3 multiplicative bias). // 256 (max pressure value) * 64 (tmp3 multiplicative bias).
if (((tmp3 >> 16) || (tmp4 >> 16)) && !PressureInTmp3(particles[i].type)) if (((tmp3 >> 16) || (tmp4 >> 16)) && !PressureInTmp3(part.type))
{ {
fieldDesc |= 1 << 15; fieldDesc |= 1 << 15;
fieldDesc |= 1 << 16; fieldDesc |= 1 << 16;
@@ -2235,24 +2236,24 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
} }
// Extra type byte if necessary // Extra type byte if necessary
if (particles[i].type & 0xFF00) if (part.type & 0xFF00)
{ {
partsData[partsDataLen++] = particles[i].type >> 8; partsData[partsDataLen++] = part.type >> 8;
fieldDesc |= 1 << 14; fieldDesc |= 1 << 14;
RESTRICTVERSION(93, 0); RESTRICTVERSION(93, 0);
} }
//Extra Temperature (2nd byte optional, 1st required), 1 to 2 bytes //Extra Temperature (2nd byte optional, 1st required), 1 to 2 bytes
//Store temperature as an offset of 21C(294.15K) or go into a 16byte int and store the whole thing //Store temperature as an offset of 21C(294.15K) or go into a 16byte int and store the whole thing
if(fabs(particles[i].temp-294.15f)<127) if(fabs(part.temp-294.15f)<127)
{ {
tempTemp = int(floor(particles[i].temp-294.15f+0.5f)); tempTemp = int(floor(part.temp-294.15f+0.5f));
partsData[partsDataLen++] = tempTemp; partsData[partsDataLen++] = tempTemp;
} }
else else
{ {
fieldDesc |= 1; fieldDesc |= 1;
tempTemp = (int)(particles[i].temp+0.5f); tempTemp = (int)(part.temp+0.5f);
partsData[partsDataLen++] = tempTemp; partsData[partsDataLen++] = tempTemp;
partsData[partsDataLen++] = tempTemp >> 8; partsData[partsDataLen++] = tempTemp >> 8;
} }
@@ -2263,9 +2264,9 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
} }
//Life (optional), 1 to 2 bytes //Life (optional), 1 to 2 bytes
if(particles[i].life) if(part.life)
{ {
int life = particles[i].life; int life = part.life;
if (life > 0xFFFF) if (life > 0xFFFF)
life = 0xFFFF; life = 0xFFFF;
else if (life < 0) else if (life < 0)
@@ -2280,76 +2281,76 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
} }
//Tmp (optional), 1, 2, or 4 bytes //Tmp (optional), 1, 2, or 4 bytes
if(particles[i].tmp) if(part.tmp)
{ {
fieldDesc |= 1 << 3; fieldDesc |= 1 << 3;
partsData[partsDataLen++] = particles[i].tmp; partsData[partsDataLen++] = part.tmp;
if(particles[i].tmp & 0xFFFFFF00) if(part.tmp & 0xFFFFFF00)
{ {
fieldDesc |= 1 << 4; fieldDesc |= 1 << 4;
partsData[partsDataLen++] = particles[i].tmp >> 8; partsData[partsDataLen++] = part.tmp >> 8;
if(particles[i].tmp & 0xFFFF0000) if(part.tmp & 0xFFFF0000)
{ {
fieldDesc |= 1 << 12; fieldDesc |= 1 << 12;
partsData[partsDataLen++] = (particles[i].tmp&0xFF000000)>>24; partsData[partsDataLen++] = (part.tmp&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].tmp&0x00FF0000)>>16; partsData[partsDataLen++] = (part.tmp&0x00FF0000)>>16;
} }
} }
} }
//Ctype (optional), 1 or 4 bytes //Ctype (optional), 1 or 4 bytes
if(particles[i].ctype) if(part.ctype)
{ {
fieldDesc |= 1 << 5; fieldDesc |= 1 << 5;
partsData[partsDataLen++] = particles[i].ctype; partsData[partsDataLen++] = part.ctype;
if(particles[i].ctype & 0xFFFFFF00) if(part.ctype & 0xFFFFFF00)
{ {
fieldDesc |= 1 << 9; fieldDesc |= 1 << 9;
partsData[partsDataLen++] = (particles[i].ctype&0xFF000000)>>24; partsData[partsDataLen++] = (part.ctype&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].ctype&0x00FF0000)>>16; partsData[partsDataLen++] = (part.ctype&0x00FF0000)>>16;
partsData[partsDataLen++] = (particles[i].ctype&0x0000FF00)>>8; partsData[partsDataLen++] = (part.ctype&0x0000FF00)>>8;
} }
} }
//Dcolour (optional), 4 bytes //Dcolour (optional), 4 bytes
if(particles[i].dcolour && (particles[i].dcolour & 0xFF000000 || particles[i].type == PT_LIFE)) if(part.dcolour && (part.dcolour & 0xFF000000 || part.type == PT_LIFE))
{ {
fieldDesc |= 1 << 6; fieldDesc |= 1 << 6;
partsData[partsDataLen++] = (particles[i].dcolour&0xFF000000)>>24; partsData[partsDataLen++] = (part.dcolour&0xFF000000)>>24;
partsData[partsDataLen++] = (particles[i].dcolour&0x00FF0000)>>16; partsData[partsDataLen++] = (part.dcolour&0x00FF0000)>>16;
partsData[partsDataLen++] = (particles[i].dcolour&0x0000FF00)>>8; partsData[partsDataLen++] = (part.dcolour&0x0000FF00)>>8;
partsData[partsDataLen++] = (particles[i].dcolour&0x000000FF); partsData[partsDataLen++] = (part.dcolour&0x000000FF);
} }
//VX (optional), 1 byte //VX (optional), 1 byte
if(fabs(particles[i].vx) > 0.001f) if(fabs(part.vx) > 0.001f)
{ {
fieldDesc |= 1 << 7; fieldDesc |= 1 << 7;
vTemp = (int)(particles[i].vx*16.0f+127.5f); vTemp = (int)(part.vx*16.0f+127.5f);
if (vTemp<0) vTemp=0; if (vTemp<0) vTemp=0;
if (vTemp>255) vTemp=255; if (vTemp>255) vTemp=255;
partsData[partsDataLen++] = vTemp; partsData[partsDataLen++] = vTemp;
} }
//VY (optional), 1 byte //VY (optional), 1 byte
if(fabs(particles[i].vy) > 0.001f) if(fabs(part.vy) > 0.001f)
{ {
fieldDesc |= 1 << 8; fieldDesc |= 1 << 8;
vTemp = (int)(particles[i].vy*16.0f+127.5f); vTemp = (int)(part.vy*16.0f+127.5f);
if (vTemp<0) vTemp=0; if (vTemp<0) vTemp=0;
if (vTemp>255) vTemp=255; if (vTemp>255) vTemp=255;
partsData[partsDataLen++] = vTemp; partsData[partsDataLen++] = vTemp;
} }
//Tmp2 (optional), 1 or 2 bytes //Tmp2 (optional), 1 or 2 bytes
if(particles[i].tmp2) if(part.tmp2)
{ {
fieldDesc |= 1 << 10; fieldDesc |= 1 << 10;
partsData[partsDataLen++] = particles[i].tmp2; partsData[partsDataLen++] = part.tmp2;
if(particles[i].tmp2 & 0xFF00) if(part.tmp2 & 0xFF00)
{ {
fieldDesc |= 1 << 11; fieldDesc |= 1 << 11;
partsData[partsDataLen++] = particles[i].tmp2 >> 8; partsData[partsDataLen++] = part.tmp2 >> 8;
} }
} }
@@ -2377,34 +2378,34 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
partsData[fieldDesc3Loc] = fieldDesc>>16; partsData[fieldDesc3Loc] = fieldDesc>>16;
} }
if (particles[i].type == PT_SOAP) if (part.type == PT_SOAP)
soapCount++; soapCount++;
if (particles[i].type == PT_RPEL && particles[i].ctype) if (part.type == PT_RPEL && part.ctype)
{ {
RESTRICTVERSION(91, 4); RESTRICTVERSION(91, 4);
} }
else if (particles[i].type == PT_NWHL && particles[i].tmp) else if (part.type == PT_NWHL && part.tmp)
{ {
RESTRICTVERSION(91, 5); RESTRICTVERSION(91, 5);
} }
if (particles[i].type == PT_HEAC || particles[i].type == PT_SAWD || particles[i].type == PT_POLO if (part.type == PT_HEAC || part.type == PT_SAWD || part.type == PT_POLO
|| particles[i].type == PT_RFRG || particles[i].type == PT_RFGL || particles[i].type == PT_LSNS) || part.type == PT_RFRG || part.type == PT_RFGL || part.type == PT_LSNS)
{ {
RESTRICTVERSION(92, 0); RESTRICTVERSION(92, 0);
} }
else if ((particles[i].type == PT_FRAY || particles[i].type == PT_INVIS) && particles[i].tmp) else if ((part.type == PT_FRAY || part.type == PT_INVIS) && part.tmp)
{ {
RESTRICTVERSION(92, 0); RESTRICTVERSION(92, 0);
} }
else if (particles[i].type == PT_PIPE || particles[i].type == PT_PPIP) else if (part.type == PT_PIPE || part.type == PT_PPIP)
{ {
RESTRICTVERSION(93, 0); RESTRICTVERSION(93, 0);
} }
if (particles[i].type == PT_TSNS || particles[i].type == PT_PSNS if (part.type == PT_TSNS || part.type == PT_PSNS
|| particles[i].type == PT_HSWC || particles[i].type == PT_PUMP) || part.type == PT_HSWC || part.type == PT_PUMP)
{ {
if (particles[i].tmp == 1) if (part.tmp == 1)
{ {
RESTRICTVERSION(93, 0); RESTRICTVERSION(93, 0);
} }
@@ -2413,9 +2414,9 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
{ {
for (auto index : possiblyCarriesType) for (auto index : possiblyCarriesType)
{ {
if (builtinElements[particles[i].type].CarriesTypeIn & (1U << index)) if (builtinElements[part.type].CarriesTypeIn & (1U << index))
{ {
auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&particles[i]) + properties[index].Offset); auto *prop = reinterpret_cast<const int *>(reinterpret_cast<const char *>(&part) + properties[index].Offset);
if (TYP(*prop) > 0xFF) if (TYP(*prop) > 0xFF)
{ {
RESTRICTVERSION(93, 0); RESTRICTVERSION(93, 0);
@@ -2423,45 +2424,45 @@ std::pair<bool, std::vector<char>> GameSave::serialiseOPS() const
} }
} }
} }
if (particles[i].type == PT_LDTC) if (part.type == PT_LDTC)
{ {
RESTRICTVERSION(94, 0); RESTRICTVERSION(94, 0);
} }
if (particles[i].type == PT_TSNS || particles[i].type == PT_PSNS) if (part.type == PT_TSNS || part.type == PT_PSNS)
{ {
if (particles[i].tmp == 2) if (part.tmp == 2)
{ {
RESTRICTVERSION(94, 0); RESTRICTVERSION(94, 0);
} }
} }
if (particles[i].type == PT_LSNS) if (part.type == PT_LSNS)
{ {
if (particles[i].tmp >= 1 || particles[i].tmp <= 3) if (part.tmp >= 1 || part.tmp <= 3)
{ {
RESTRICTVERSION(95, 0); RESTRICTVERSION(95, 0);
} }
} }
if (particles[i].type == PT_LIFE) if (part.type == PT_LIFE)
{ {
RESTRICTVERSION(96, 0); RESTRICTVERSION(96, 0);
} }
if (particles[i].type == PT_GLAS && particles[i].life > 0) if (part.type == PT_GLAS && part.life > 0)
{ {
RESTRICTVERSION(97, 0); RESTRICTVERSION(97, 0);
} }
if (PressureInTmp3(particles[i].type)) if (PressureInTmp3(part.type))
{ {
RESTRICTVERSION(97, 0); RESTRICTVERSION(97, 0);
} }
if (particles[i].type == PT_CONV && particles[i].tmp2 != 0) if (part.type == PT_CONV && part.tmp2 != 0)
{ {
RESTRICTVERSION(97, 0); RESTRICTVERSION(97, 0);
} }
if (particles[i].type == PT_RSST || particles[i].type == PT_RSSS) if (part.type == PT_RSST || part.type == PT_RSSS)
{ {
RESTRICTVERSION(98, 0); RESTRICTVERSION(98, 0);
} }
if (particles[i].type == PT_ETRD && (particles[i].tmp || particles[i].tmp2)) if (part.type == PT_ETRD && (part.tmp || part.tmp2))
{ {
RESTRICTVERSION(98, 0); RESTRICTVERSION(98, 0);
} }