mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-11 19:04:05 +02:00
Save loading and reloading
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#define SERVER "powdertoy.co.uk"
|
#define SERVER "powdertoy.co.uk"
|
||||||
#define SCRIPTSERVER "powdertoy.co.uk"
|
#define SCRIPTSERVER "powdertoy.co.uk"
|
||||||
|
#define STATICSERVER "static.powdertoy.co.uk"
|
||||||
|
|
||||||
#define LOCAL_SAVE_DIR "Saves"
|
#define LOCAL_SAVE_DIR "Saves"
|
||||||
|
|
||||||
|
@@ -42,7 +42,28 @@ Client::~Client()
|
|||||||
|
|
||||||
unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength)
|
unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength)
|
||||||
{
|
{
|
||||||
|
lastError = "";
|
||||||
|
int dataStatus;
|
||||||
|
unsigned char * data;
|
||||||
dataLength = 0;
|
dataLength = 0;
|
||||||
|
std::stringstream urlStream;
|
||||||
|
if(saveDate)
|
||||||
|
{
|
||||||
|
urlStream << "http://" << STATICSERVER << "/" << saveID << "_" << saveDate << ".cps";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
urlStream << "http://" << STATICSERVER << "/" << saveID << ".cps";
|
||||||
|
}
|
||||||
|
data = (unsigned char *)http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength);
|
||||||
|
if(data && dataStatus == 200)
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else if(data)
|
||||||
|
{
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,11 +196,12 @@ Save * Client::GetSave(int saveID, int saveDate)
|
|||||||
Thumbnail * Client::GetPreview(int saveID, int saveDate)
|
Thumbnail * Client::GetPreview(int saveID, int saveDate)
|
||||||
{
|
{
|
||||||
std::stringstream urlStream;
|
std::stringstream urlStream;
|
||||||
urlStream << "http://" << SERVER << "/Get.api?Op=thumblarge&ID=" << saveID;
|
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
||||||
if(saveDate)
|
if(saveDate)
|
||||||
{
|
{
|
||||||
urlStream << "&Date=" << saveDate;
|
urlStream << "_" << saveDate;
|
||||||
}
|
}
|
||||||
|
urlStream << "_large.pti";
|
||||||
pixel * thumbData;
|
pixel * thumbData;
|
||||||
char * data;
|
char * data;
|
||||||
int status, data_size, imgw, imgh;
|
int status, data_size, imgw, imgh;
|
||||||
@@ -322,11 +344,12 @@ Thumbnail * Client::GetThumbnail(int saveID, int saveDate)
|
|||||||
if(thumbnailCache[i] && thumbnailCache[i]->ID == saveID && thumbnailCache[i]->Datestamp == saveDate)
|
if(thumbnailCache[i] && thumbnailCache[i]->ID == saveID && thumbnailCache[i]->Datestamp == saveDate)
|
||||||
return thumbnailCache[i];
|
return thumbnailCache[i];
|
||||||
}
|
}
|
||||||
urlStream << "http://" << SERVER << "/Get.api?Op=thumbsmall&ID=" << saveID;
|
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
||||||
if(saveDate)
|
if(saveDate)
|
||||||
{
|
{
|
||||||
urlStream << "&Date=" << saveDate;
|
urlStream << "_" << saveDate;
|
||||||
}
|
}
|
||||||
|
urlStream << "_small.pti";
|
||||||
idStream << saveID << ":" << saveDate;
|
idStream << saveID << ":" << saveDate;
|
||||||
std::string idString = idStream.str();
|
std::string idString = idStream.str();
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@@ -148,7 +148,7 @@ void GameController::DrawPoints(queue<ui::Point*> & pointQueue)
|
|||||||
|
|
||||||
void GameController::Update()
|
void GameController::Update()
|
||||||
{
|
{
|
||||||
//gameModel->GetSimulation()->update_particles();
|
gameModel->GetSimulation()->update_particles();
|
||||||
if(renderOptions && renderOptions->HasExited)
|
if(renderOptions && renderOptions->HasExited)
|
||||||
{
|
{
|
||||||
delete renderOptions;
|
delete renderOptions;
|
||||||
@@ -234,7 +234,8 @@ void GameController::ClearSim()
|
|||||||
|
|
||||||
void GameController::ReloadSim()
|
void GameController::ReloadSim()
|
||||||
{
|
{
|
||||||
//TODO: Implement
|
if(gameModel->GetSave() && gameModel->GetSave()->GetData())
|
||||||
|
gameModel->GetSimulation()->Load(gameModel->GetSave()->GetData(), gameModel->GetSave()->GetDataLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -34,6 +34,14 @@ Save::Save(int _id, int date_, int _votesUp, int _votesDown, string _userName,
|
|||||||
published_), data(NULL) {
|
published_), data(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Save::~Save()
|
||||||
|
{
|
||||||
|
if(data)
|
||||||
|
{
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Save::SetName(string name) {
|
void Save::SetName(string name) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@ public:
|
|||||||
|
|
||||||
Save(int _id, int date_, int _votesUp, int _votesDown, string _userName, string _name, string description_, bool published_);
|
Save(int _id, int date_, int _votesUp, int _votesDown, string _userName, string _name, string description_, bool published_);
|
||||||
|
|
||||||
|
~Save();
|
||||||
|
|
||||||
string userName;
|
string userName;
|
||||||
string name;
|
string name;
|
||||||
|
|
||||||
|
@@ -5,16 +5,32 @@
|
|||||||
* Author: Simon
|
* Author: Simon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <bzlib.h>
|
||||||
#include "SaveLoader.h"
|
#include "SaveLoader.h"
|
||||||
|
|
||||||
int SaveLoader::LoadSave(unsigned char * data, int dataLength, Simulation * sim)
|
//!TODO: enum for LoadSave return
|
||||||
|
|
||||||
|
int SaveLoader::LoadSave(unsigned char * data, int dataLength, Simulation * sim, bool replace, int x, int y)
|
||||||
{
|
{
|
||||||
return 0;
|
unsigned char * saveData = data;
|
||||||
|
if (dataLength<16)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(saveData[0] == 'O' && saveData[1] == 'P' && saveData[2] == 'S')
|
||||||
|
{
|
||||||
|
return OPSLoadSave(data, dataLength, sim);
|
||||||
|
}
|
||||||
|
else if((saveData[0]==0x66 && saveData[1]==0x75 && saveData[2]==0x43) || (saveData[0]==0x50 && saveData[1]==0x53 && saveData[2]==0x76))
|
||||||
|
{
|
||||||
|
return PSVLoadSave(data, dataLength, sim, replace, x, y);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char * SaveLoader::BuildSave(int & dataLength, Simulation * sim)
|
unsigned char * SaveLoader::BuildSave(int & dataLength, Simulation * sim)
|
||||||
{
|
{
|
||||||
return 0;
|
return OPSBuildSave(dataLength, sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SaveLoader::OPSLoadSave(unsigned char * data, int dataLength, Simulation * sim)
|
int SaveLoader::OPSLoadSave(unsigned char * data, int dataLength, Simulation * sim)
|
||||||
@@ -27,9 +43,598 @@ unsigned char * SaveLoader::OPSBuildSave(int & dataLength, Simulation * sim)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SaveLoader::PSVLoadSave(unsigned char * data, int dataLength, Simulation * sim)
|
int SaveLoader::PSVLoadSave(unsigned char * data, int dataLength, Simulation * sim, bool replace, int x0, int y0)
|
||||||
{
|
{
|
||||||
|
unsigned char * d = NULL, * c = data;
|
||||||
|
int q,i,j,k,x,y,p=0,*m=NULL, ver, pty, ty, legacy_beta=0, tempGrav = 0;
|
||||||
|
int bx0=x0/CELL, by0=y0/CELL, bw, bh, w, h;
|
||||||
|
int nf=0, new_format = 0, ttv = 0;
|
||||||
|
Particle *parts = sim->parts;
|
||||||
|
int *fp = (int *)malloc(NPART*sizeof(int));
|
||||||
|
|
||||||
|
//New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures
|
||||||
|
//This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error
|
||||||
|
|
||||||
|
if (dataLength<16)
|
||||||
|
return 1;
|
||||||
|
if (!(c[2]==0x43 && c[1]==0x75 && c[0]==0x66) && !(c[2]==0x76 && c[1]==0x53 && c[0]==0x50))
|
||||||
|
return 1;
|
||||||
|
if (c[2]==0x76 && c[1]==0x53 && c[0]==0x50) {
|
||||||
|
new_format = 1;
|
||||||
|
}
|
||||||
|
if (c[4]>SAVE_VERSION)
|
||||||
|
return 2;
|
||||||
|
ver = c[4];
|
||||||
|
|
||||||
|
if (ver<34)
|
||||||
|
{
|
||||||
|
sim->legacy_enable = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ver>=44) {
|
||||||
|
sim->legacy_enable = c[3]&0x01;
|
||||||
|
if (!sim->sys_pause) {
|
||||||
|
sim->sys_pause = (c[3]>>1)&0x01;
|
||||||
|
}
|
||||||
|
if (ver>=46 && replace) {
|
||||||
|
sim->gravityMode = ((c[3]>>2)&0x03);// | ((c[3]>>2)&0x01);
|
||||||
|
sim->airMode = ((c[3]>>4)&0x07);// | ((c[3]>>4)&0x02) | ((c[3]>>4)&0x01);
|
||||||
|
}
|
||||||
|
if (ver>=49 && replace) {
|
||||||
|
tempGrav = ((c[3]>>7)&0x01);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (c[3]==1||c[3]==0) {
|
||||||
|
sim->legacy_enable = c[3];
|
||||||
|
} else {
|
||||||
|
legacy_beta = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bw = c[6];
|
||||||
|
bh = c[7];
|
||||||
|
if (bx0+bw > XRES/CELL)
|
||||||
|
bx0 = XRES/CELL - bw;
|
||||||
|
if (by0+bh > YRES/CELL)
|
||||||
|
by0 = YRES/CELL - bh;
|
||||||
|
if (bx0 < 0)
|
||||||
|
bx0 = 0;
|
||||||
|
if (by0 < 0)
|
||||||
|
by0 = 0;
|
||||||
|
|
||||||
|
if (c[5]!=CELL || bx0+bw>XRES/CELL || by0+bh>YRES/CELL)
|
||||||
|
return 3;
|
||||||
|
i = (unsigned)c[8];
|
||||||
|
i |= ((unsigned)c[9])<<8;
|
||||||
|
i |= ((unsigned)c[10])<<16;
|
||||||
|
i |= ((unsigned)c[11])<<24;
|
||||||
|
d = (unsigned char *)malloc(i);
|
||||||
|
if (!d)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0))
|
||||||
|
return 1;
|
||||||
|
dataLength = i;
|
||||||
|
|
||||||
|
if (dataLength < bw*bh)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// normalize coordinates
|
||||||
|
x0 = bx0*CELL;
|
||||||
|
y0 = by0*CELL;
|
||||||
|
w = bw *CELL;
|
||||||
|
h = bh *CELL;
|
||||||
|
|
||||||
|
if (replace)
|
||||||
|
{
|
||||||
|
if (ver<46) {
|
||||||
|
sim->gravityMode = 0;
|
||||||
|
sim->airMode = 0;
|
||||||
|
}
|
||||||
|
sim->clear_sim();
|
||||||
|
}
|
||||||
|
sim->parts_lastActiveIndex = NPART-1;
|
||||||
|
m = (int *)calloc(XRES*YRES, sizeof(int));
|
||||||
|
|
||||||
|
// make a catalog of free parts
|
||||||
|
//memset(pmap, 0, sizeof(pmap)); "Using sizeof for array given as function argument returns the size of pointer."
|
||||||
|
memset(sim->pmap, 0, sizeof(unsigned)*(XRES*YRES));
|
||||||
|
for (i=0; i<NPART; i++)
|
||||||
|
if (parts[i].type)
|
||||||
|
{
|
||||||
|
x = (int)(parts[i].x+0.5f);
|
||||||
|
y = (int)(parts[i].y+0.5f);
|
||||||
|
sim->pmap[y][x] = (i<<8)|1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fp[nf++] = i;
|
||||||
|
|
||||||
|
// load the required air state
|
||||||
|
for (y=by0; y<by0+bh; y++)
|
||||||
|
for (x=bx0; x<bx0+bw; x++)
|
||||||
|
{
|
||||||
|
if (d[p])
|
||||||
|
{
|
||||||
|
//In old saves, ignore walls created by sign tool bug
|
||||||
|
//Not ignoring other invalid walls or invalid walls in new saves, so that any other bugs causing them are easier to notice, find and fix
|
||||||
|
if (ver<71 && d[p]==WL_SIGN)
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sim->bmap[y][x] = d[p];
|
||||||
|
if (sim->bmap[y][x]==1)
|
||||||
|
sim->bmap[y][x]=WL_WALL;
|
||||||
|
if (sim->bmap[y][x]==2)
|
||||||
|
sim->bmap[y][x]=WL_DESTROYALL;
|
||||||
|
if (sim->bmap[y][x]==3)
|
||||||
|
sim->bmap[y][x]=WL_ALLOWLIQUID;
|
||||||
|
if (sim->bmap[y][x]==4)
|
||||||
|
sim->bmap[y][x]=WL_FAN;
|
||||||
|
if (sim->bmap[y][x]==5)
|
||||||
|
sim->bmap[y][x]=WL_STREAM;
|
||||||
|
if (sim->bmap[y][x]==6)
|
||||||
|
sim->bmap[y][x]=WL_DETECT;
|
||||||
|
if (sim->bmap[y][x]==7)
|
||||||
|
sim->bmap[y][x]=WL_EWALL;
|
||||||
|
if (sim->bmap[y][x]==8)
|
||||||
|
sim->bmap[y][x]=WL_WALLELEC;
|
||||||
|
if (sim->bmap[y][x]==9)
|
||||||
|
sim->bmap[y][x]=WL_ALLOWAIR;
|
||||||
|
if (sim->bmap[y][x]==10)
|
||||||
|
sim->bmap[y][x]=WL_ALLOWSOLID;
|
||||||
|
if (sim->bmap[y][x]==11)
|
||||||
|
sim->bmap[y][x]=WL_ALLOWALLELEC;
|
||||||
|
if (sim->bmap[y][x]==12)
|
||||||
|
sim->bmap[y][x]=WL_EHOLE;
|
||||||
|
if (sim->bmap[y][x]==13)
|
||||||
|
sim->bmap[y][x]=WL_ALLOWGAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
for (y=by0; y<by0+bh; y++)
|
||||||
|
for (x=bx0; x<bx0+bw; x++)
|
||||||
|
if (d[(y-by0)*bw+(x-bx0)]==4||d[(y-by0)*bw+(x-bx0)]==WL_FAN)
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
sim->fvx[y][x] = (d[p++]-127.0f)/64.0f;
|
||||||
|
}
|
||||||
|
for (y=by0; y<by0+bh; y++)
|
||||||
|
for (x=bx0; x<bx0+bw; x++)
|
||||||
|
if (d[(y-by0)*bw+(x-bx0)]==4||d[(y-by0)*bw+(x-bx0)]==WL_FAN)
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
sim->fvy[y][x] = (d[p++]-127.0f)/64.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the particle map
|
||||||
|
i = 0;
|
||||||
|
pty = p;
|
||||||
|
for (y=y0; y<y0+h; y++)
|
||||||
|
for (x=x0; x<x0+w; x++)
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
j=d[p++];
|
||||||
|
if (j >= PT_NUM) {
|
||||||
|
//TODO: Possibly some server side translation
|
||||||
|
j = PT_DUST;//goto corrupt;
|
||||||
|
}
|
||||||
|
sim->gol[x][y]=0;
|
||||||
|
if (j)
|
||||||
|
{
|
||||||
|
if (sim->pmap[y][x])
|
||||||
|
{
|
||||||
|
k = sim->pmap[y][x]>>8;
|
||||||
|
}
|
||||||
|
else if (i<nf)
|
||||||
|
{
|
||||||
|
k = fp[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m[(x-x0)+(y-y0)*w] = NPART+1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memset(parts+k, 0, sizeof(Particle));
|
||||||
|
parts[k].type = j;
|
||||||
|
if (j == PT_COAL)
|
||||||
|
parts[k].tmp = 50;
|
||||||
|
if (j == PT_FUSE)
|
||||||
|
parts[k].tmp = 50;
|
||||||
|
if (j == PT_PHOT)
|
||||||
|
parts[k].ctype = 0x3fffffff;
|
||||||
|
if (j == PT_SOAP)
|
||||||
|
parts[k].ctype = 0;
|
||||||
|
if (j==PT_BIZR || j==PT_BIZRG || j==PT_BIZRS)
|
||||||
|
parts[k].ctype = 0x47FFFF;
|
||||||
|
parts[k].x = (float)x;
|
||||||
|
parts[k].y = (float)y;
|
||||||
|
m[(x-x0)+(y-y0)*w] = k+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// load particle properties
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
if (p+1 >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
if (i < NPART)
|
||||||
|
{
|
||||||
|
parts[i].vx = (d[p++]-127.0f)/16.0f;
|
||||||
|
parts[i].vy = (d[p++]-127.0f)/16.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=44) {
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
ttv = (d[p++])<<8;
|
||||||
|
ttv |= (d[p++]);
|
||||||
|
parts[i-1].life = ttv;
|
||||||
|
} else {
|
||||||
|
p+=2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
if (i <= NPART)
|
||||||
|
parts[i-1].life = d[p++]*4;
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ver>=44) {
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
ttv = (d[p++])<<8;
|
||||||
|
ttv |= (d[p++]);
|
||||||
|
parts[i-1].tmp = ttv;
|
||||||
|
if (ver<53 && !parts[i-1].tmp)
|
||||||
|
for (q = 1; q<=NGOLALT; q++) {
|
||||||
|
if (parts[i-1].type==sim->goltype[q-1] && sim->grule[q][9]==2)
|
||||||
|
parts[i-1].tmp = sim->grule[q][9]-1;
|
||||||
|
}
|
||||||
|
if (ver>=51 && ver<53 && parts[i-1].type==PT_PBCN)
|
||||||
|
{
|
||||||
|
parts[i-1].tmp2 = parts[i-1].tmp;
|
||||||
|
parts[i-1].tmp = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p+=2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ver>=53) {
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
ty = d[pty+j];
|
||||||
|
if (i && ty==PT_PBCN)
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
if (i <= NPART)
|
||||||
|
parts[i-1].tmp2 = d[p++];
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Read ALPHA component
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=49) {
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
parts[i-1].dcolour = d[p++]<<24;
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Read RED component
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=49) {
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
parts[i-1].dcolour |= d[p++]<<16;
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Read GREEN component
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=49) {
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
parts[i-1].dcolour |= d[p++]<<8;
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Read BLUE component
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=49) {
|
||||||
|
if (p >= dataLength) {
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART) {
|
||||||
|
parts[i-1].dcolour |= d[p++];
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
i = m[j];
|
||||||
|
ty = d[pty+j];
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
if (ver>=34&&legacy_beta==0)
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
{
|
||||||
|
goto corrupt;
|
||||||
|
}
|
||||||
|
if (i <= NPART)
|
||||||
|
{
|
||||||
|
if (ver>=42) {
|
||||||
|
if (new_format) {
|
||||||
|
ttv = (d[p++])<<8;
|
||||||
|
ttv |= (d[p++]);
|
||||||
|
if (parts[i-1].type==PT_PUMP) {
|
||||||
|
parts[i-1].temp = ttv + 0.15;//fix PUMP saved at 0, so that it loads at 0.
|
||||||
|
} else {
|
||||||
|
parts[i-1].temp = ttv;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parts[i-1].temp = (d[p++]*((MAX_TEMP+(-MIN_TEMP))/255))+MIN_TEMP;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parts[i-1].temp = ((d[p++]*((O_MAX_TEMP+(-O_MIN_TEMP))/255))+O_MIN_TEMP)+273;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
if (new_format) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parts[i-1].temp = sim->ptypes[parts[i-1].type].heat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (j=0; j<w*h; j++)
|
||||||
|
{
|
||||||
|
int gnum = 0;
|
||||||
|
i = m[j];
|
||||||
|
ty = d[pty+j];
|
||||||
|
if (i && (ty==PT_CLNE || (ty==PT_PCLN && ver>=43) || (ty==PT_BCLN && ver>=44) || (ty==PT_SPRK && ver>=21) || (ty==PT_LAVA && ver>=34) || (ty==PT_PIPE && ver>=43) || (ty==PT_LIFE && ver>=51) || (ty==PT_PBCN && ver>=52) || (ty==PT_WIRE && ver>=55) || (ty==PT_STOR && ver>=59) || (ty==PT_CONV && ver>=60)))
|
||||||
|
{
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
if (i <= NPART)
|
||||||
|
parts[i-1].ctype = d[p++];
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
//TODO: STKM_init_legs
|
||||||
|
// no more particle properties to load, so we can change type here without messing up loading
|
||||||
|
if (i && i<=NPART)
|
||||||
|
{
|
||||||
|
if ((sim->player.spwn == 1 && ty==PT_STKM) || (sim->player2.spwn == 1 && ty==PT_STKM2))
|
||||||
|
{
|
||||||
|
parts[i-1].type = PT_NONE;
|
||||||
|
}
|
||||||
|
else if (parts[i-1].type == PT_STKM)
|
||||||
|
{
|
||||||
|
//STKM_init_legs(&player, i-1);
|
||||||
|
sim->player.spwn = 1;
|
||||||
|
sim->player.elem = PT_DUST;
|
||||||
|
}
|
||||||
|
else if (parts[i-1].type == PT_STKM2)
|
||||||
|
{
|
||||||
|
//STKM_init_legs(&player2, i-1);
|
||||||
|
sim->player2.spwn = 1;
|
||||||
|
sim->player2.elem = PT_DUST;
|
||||||
|
}
|
||||||
|
else if (parts[i-1].type == PT_FIGH)
|
||||||
|
{
|
||||||
|
unsigned char fcount = 0;
|
||||||
|
while (fcount < 100 && fcount < (sim->fighcount+1) && sim->fighters[fcount].spwn==1) fcount++;
|
||||||
|
if (fcount < 100 && sim->fighters[fcount].spwn==0)
|
||||||
|
{
|
||||||
|
parts[i-1].tmp = fcount;
|
||||||
|
sim->fighters[fcount].spwn = 1;
|
||||||
|
sim->fighters[fcount].elem = PT_DUST;
|
||||||
|
sim->fighcount++;
|
||||||
|
//STKM_init_legs(&(fighters[fcount]), i-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ver<48 && (ty==OLD_PT_WIND || (ty==PT_BRAY&&parts[i-1].life==0)))
|
||||||
|
{
|
||||||
|
// Replace invisible particles with something sensible and add decoration to hide it
|
||||||
|
x = (int)(parts[i-1].x+0.5f);
|
||||||
|
y = (int)(parts[i-1].y+0.5f);
|
||||||
|
parts[i-1].dcolour = 0xFF000000;
|
||||||
|
parts[i-1].type = PT_DMND;
|
||||||
|
}
|
||||||
|
if(ver<51 && ((ty>=78 && ty<=89) || (ty>=134 && ty<=146 && ty!=141))){
|
||||||
|
//Replace old GOL
|
||||||
|
parts[i-1].type = PT_LIFE;
|
||||||
|
for (gnum = 0; gnum<NGOLALT; gnum++){
|
||||||
|
if (ty==sim->goltype[gnum])
|
||||||
|
parts[i-1].ctype = gnum;
|
||||||
|
}
|
||||||
|
ty = PT_LIFE;
|
||||||
|
}
|
||||||
|
if(ver<52 && (ty==PT_CLNE || ty==PT_PCLN || ty==PT_BCLN)){
|
||||||
|
//Replace old GOL ctypes in clone
|
||||||
|
for (gnum = 0; gnum<NGOLALT; gnum++){
|
||||||
|
if (parts[i-1].ctype==sim->goltype[gnum])
|
||||||
|
{
|
||||||
|
parts[i-1].ctype = PT_LIFE;
|
||||||
|
parts[i-1].tmp = gnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ty==PT_LCRY){
|
||||||
|
if(ver<67)
|
||||||
|
{
|
||||||
|
//New LCRY uses TMP not life
|
||||||
|
if(parts[i-1].life>=10)
|
||||||
|
{
|
||||||
|
parts[i-1].life = 10;
|
||||||
|
parts[i-1].tmp2 = 10;
|
||||||
|
parts[i-1].tmp = 3;
|
||||||
|
}
|
||||||
|
else if(parts[i-1].life<=0)
|
||||||
|
{
|
||||||
|
parts[i-1].life = 0;
|
||||||
|
parts[i-1].tmp2 = 0;
|
||||||
|
parts[i-1].tmp = 0;
|
||||||
|
}
|
||||||
|
else if(parts[i-1].life < 10 && parts[i-1].life > 0)
|
||||||
|
{
|
||||||
|
parts[i-1].tmp = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parts[i-1].tmp2 = parts[i-1].life;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sim->ptypes[parts[i-1].type].enabled)
|
||||||
|
parts[i-1].type = PT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef RENDERER
|
||||||
|
//Change the gravity state
|
||||||
|
if(sim->ngrav_enable != tempGrav && replace)
|
||||||
|
{
|
||||||
|
if(tempGrav)
|
||||||
|
sim->grav->start_grav_async();
|
||||||
|
else
|
||||||
|
sim->grav->stop_grav_async();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sim->grav->gravity_mask();
|
||||||
|
|
||||||
|
if (p >= dataLength)
|
||||||
|
goto version1;
|
||||||
|
j = d[p++];
|
||||||
|
for (i=0; i<j; i++)
|
||||||
|
{
|
||||||
|
if (p+6 > dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
for (k=0; k<MAXSIGNS; k++)
|
||||||
|
if (!sim->signs[k].text[0])
|
||||||
|
break;
|
||||||
|
x = d[p++];
|
||||||
|
x |= ((unsigned)d[p++])<<8;
|
||||||
|
if (k<MAXSIGNS)
|
||||||
|
sim->signs[k].x = x+x0;
|
||||||
|
x = d[p++];
|
||||||
|
x |= ((unsigned)d[p++])<<8;
|
||||||
|
if (k<MAXSIGNS)
|
||||||
|
sim->signs[k].y = x+y0;
|
||||||
|
x = d[p++];
|
||||||
|
if (k<MAXSIGNS)
|
||||||
|
sim->signs[k].ju = x;
|
||||||
|
x = d[p++];
|
||||||
|
if (p+x > dataLength)
|
||||||
|
goto corrupt;
|
||||||
|
if (k<MAXSIGNS)
|
||||||
|
{
|
||||||
|
memcpy(sim->signs[k].text, d+p, x);
|
||||||
|
sim->signs[k].text[x] = 0;
|
||||||
|
//clean_text(signs[k].text, 158-14 /* Current max sign length */); //TODO: Text cleanup for signs
|
||||||
|
}
|
||||||
|
p += x;
|
||||||
|
}
|
||||||
|
|
||||||
|
version1:
|
||||||
|
if (m) free(m);
|
||||||
|
if (d) free(d);
|
||||||
|
if (fp) free(fp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
corrupt:
|
||||||
|
if (m) free(m);
|
||||||
|
if (d) free(d);
|
||||||
|
if (fp) free(fp);
|
||||||
|
if (replace)
|
||||||
|
{
|
||||||
|
sim->legacy_enable = 0;
|
||||||
|
sim->clear_sim();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char * PSVBuildSave(int & dataLength, Simulation * sim)
|
unsigned char * PSVBuildSave(int & dataLength, Simulation * sim)
|
||||||
|
@@ -12,11 +12,11 @@
|
|||||||
|
|
||||||
class SaveLoader {
|
class SaveLoader {
|
||||||
public:
|
public:
|
||||||
static int LoadSave(unsigned char * data, int dataLength, Simulation * sim);
|
static int LoadSave(unsigned char * data, int dataLength, Simulation * sim, bool replace, int x, int y);
|
||||||
static unsigned char * BuildSave(int & dataLength, Simulation * sim);
|
static unsigned char * BuildSave(int & dataLength, Simulation * sim);
|
||||||
static int OPSLoadSave(unsigned char * data, int dataLength, Simulation * sim);
|
static int OPSLoadSave(unsigned char * data, int dataLength, Simulation * sim);
|
||||||
static unsigned char * OPSBuildSave(int & dataLength, Simulation * sim);
|
static unsigned char * OPSBuildSave(int & dataLength, Simulation * sim);
|
||||||
static int PSVLoadSave(unsigned char * data, int dataLength, Simulation * sim);
|
static int PSVLoadSave(unsigned char * data, int dataLength, Simulation * sim, bool replace, int x, int y);
|
||||||
static unsigned char * PSVBuildSave(int & dataLength, Simulation * sim);
|
static unsigned char * PSVBuildSave(int & dataLength, Simulation * sim);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
int Simulation::Load(unsigned char * data, int dataLength)
|
int Simulation::Load(unsigned char * data, int dataLength)
|
||||||
{
|
{
|
||||||
return SaveLoader::LoadSave(data, dataLength, this);
|
return SaveLoader::LoadSave(data, dataLength, this, true, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char * Simulation::Save(int & dataLength)
|
unsigned char * Simulation::Save(int & dataLength)
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "Elements.h"
|
#include "Elements.h"
|
||||||
#include "Misc.h"
|
#include "Misc.h"
|
||||||
#include "game/Brush.h"
|
#include "game/Brush.h"
|
||||||
|
#include "Gravity.h"
|
||||||
#include "SimulationData.h"
|
#include "SimulationData.h"
|
||||||
//#include "ElementFunctions.h"
|
//#include "ElementFunctions.h"
|
||||||
|
|
||||||
@@ -204,36 +205,36 @@ public:
|
|||||||
int sandcolour_r;
|
int sandcolour_r;
|
||||||
int sandcolour_g;
|
int sandcolour_g;
|
||||||
int sandcolour_b; //TODO: Make a single variable
|
int sandcolour_b; //TODO: Make a single variable
|
||||||
//TODO: Inlines for performance
|
|
||||||
int Load(unsigned char * data, int dataLength);
|
int Load(unsigned char * data, int dataLength);
|
||||||
unsigned char * Save(int & dataLength);
|
unsigned char * Save(int & dataLength);
|
||||||
int is_blocking(int t, int x, int y);
|
inline int is_blocking(int t, int x, int y);
|
||||||
int is_boundary(int pt, int x, int y);
|
inline int is_boundary(int pt, int x, int y);
|
||||||
int find_next_boundary(int pt, int *x, int *y, int dm, int *em);
|
inline int find_next_boundary(int pt, int *x, int *y, int dm, int *em);
|
||||||
int pn_junction_sprk(int x, int y, int pt);
|
inline int pn_junction_sprk(int x, int y, int pt);
|
||||||
void photoelectric_effect(int nx, int ny);
|
inline void photoelectric_effect(int nx, int ny);
|
||||||
unsigned direction_to_map(float dx, float dy, int t);
|
inline unsigned direction_to_map(float dx, float dy, int t);
|
||||||
int do_move(int i, int x, int y, float nxf, float nyf);
|
inline int do_move(int i, int x, int y, float nxf, float nyf);
|
||||||
int try_move(int i, int x, int y, int nx, int ny);
|
inline int try_move(int i, int x, int y, int nx, int ny);
|
||||||
int eval_move(int pt, int nx, int ny, unsigned *rr);
|
inline int eval_move(int pt, int nx, int ny, unsigned *rr);
|
||||||
void init_can_move();
|
void init_can_move();
|
||||||
void create_cherenkov_photon(int pp);
|
void create_cherenkov_photon(int pp);
|
||||||
void create_gain_photon(int pp);
|
void create_gain_photon(int pp);
|
||||||
void kill_part(int i);
|
inline void kill_part(int i);
|
||||||
int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype);
|
int flood_prop(int x, int y, size_t propoffset, void * propvalue, int proptype);
|
||||||
int flood_prop_2(int x, int y, size_t propoffset, void * propvalue, int proptype, int parttype, char * bitmap);
|
int flood_prop_2(int x, int y, size_t propoffset, void * propvalue, int proptype, int parttype, char * bitmap);
|
||||||
int flood_water(int x, int y, int i, int originaly, int check);
|
int flood_water(int x, int y, int i, int originaly, int check);
|
||||||
void detach(int i);
|
inline void detach(int i);
|
||||||
void part_change_type(int i, int x, int y, int t);
|
inline void part_change_type(int i, int x, int y, int t);
|
||||||
int create_part_add_props(int p, int x, int y, int tv, int rx, int ry);
|
inline int create_part_add_props(int p, int x, int y, int tv, int rx, int ry);
|
||||||
//int InCurrentBrush(int i, int j, int rx, int ry);
|
//int InCurrentBrush(int i, int j, int rx, int ry);
|
||||||
//int get_brush_flags();
|
//int get_brush_flags();
|
||||||
int create_part(int p, int x, int y, int t);
|
inline int create_part(int p, int x, int y, int t);
|
||||||
void delete_part(int x, int y, int flags);
|
inline void delete_part(int x, int y, int flags);
|
||||||
int is_wire(int x, int y);
|
inline int is_wire(int x, int y);
|
||||||
int is_wire_off(int x, int y);
|
inline int is_wire_off(int x, int y);
|
||||||
void set_emap(int x, int y);
|
inline void set_emap(int x, int y);
|
||||||
int parts_avg(int ci, int ni, int t);
|
inline int parts_avg(int ci, int ni, int t);
|
||||||
void create_arc(int sx, int sy, int dx, int dy, int midpoints, int variance, int type, int flags);
|
void create_arc(int sx, int sy, int dx, int dy, int midpoints, int variance, int type, int flags);
|
||||||
int nearest_part(int ci, int t, int max_d);
|
int nearest_part(int ci, int t, int max_d);
|
||||||
void update_particles_i(int start, int inc);
|
void update_particles_i(int start, int inc);
|
||||||
@@ -245,11 +246,11 @@ public:
|
|||||||
int create_parts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
|
int create_parts(int x, int y, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
|
||||||
void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
|
void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c, int flags, Brush * cBrush = NULL);
|
||||||
void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate);
|
void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate);
|
||||||
void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
inline void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
||||||
void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
|
inline void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
|
||||||
int get_wavelength_bin(int *wm);
|
inline int get_wavelength_bin(int *wm);
|
||||||
int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny);
|
inline int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny);
|
||||||
int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny);
|
inline int get_normal_interp(int pt, float x0, float y0, float dx, float dy, float *nx, float *ny);
|
||||||
void clear_sim();
|
void clear_sim();
|
||||||
void UpdateParticles();
|
void UpdateParticles();
|
||||||
Simulation();
|
Simulation();
|
||||||
|
Reference in New Issue
Block a user