Save loading and reloading
This commit is contained in:
parent
9e1be78bc2
commit
d520a70acf
@ -29,6 +29,7 @@
|
||||
|
||||
#define SERVER "powdertoy.co.uk"
|
||||
#define SCRIPTSERVER "powdertoy.co.uk"
|
||||
#define STATICSERVER "static.powdertoy.co.uk"
|
||||
|
||||
#define LOCAL_SAVE_DIR "Saves"
|
||||
|
||||
|
@ -42,7 +42,28 @@ Client::~Client()
|
||||
|
||||
unsigned char * Client::GetSaveData(int saveID, int saveDate, int & dataLength)
|
||||
{
|
||||
lastError = "";
|
||||
int dataStatus;
|
||||
unsigned char * data;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -175,11 +196,12 @@ Save * Client::GetSave(int saveID, int saveDate)
|
||||
Thumbnail * Client::GetPreview(int saveID, int saveDate)
|
||||
{
|
||||
std::stringstream urlStream;
|
||||
urlStream << "http://" << SERVER << "/Get.api?Op=thumblarge&ID=" << saveID;
|
||||
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
||||
if(saveDate)
|
||||
{
|
||||
urlStream << "&Date=" << saveDate;
|
||||
urlStream << "_" << saveDate;
|
||||
}
|
||||
urlStream << "_large.pti";
|
||||
pixel * thumbData;
|
||||
char * data;
|
||||
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)
|
||||
return thumbnailCache[i];
|
||||
}
|
||||
urlStream << "http://" << SERVER << "/Get.api?Op=thumbsmall&ID=" << saveID;
|
||||
urlStream << "http://" << STATICSERVER << "/" << saveID;
|
||||
if(saveDate)
|
||||
{
|
||||
urlStream << "&Date=" << saveDate;
|
||||
urlStream << "_" << saveDate;
|
||||
}
|
||||
urlStream << "_small.pti";
|
||||
idStream << saveID << ":" << saveDate;
|
||||
std::string idString = idStream.str();
|
||||
bool found = false;
|
||||
|
@ -148,7 +148,7 @@ void GameController::DrawPoints(queue<ui::Point*> & pointQueue)
|
||||
|
||||
void GameController::Update()
|
||||
{
|
||||
//gameModel->GetSimulation()->update_particles();
|
||||
gameModel->GetSimulation()->update_particles();
|
||||
if(renderOptions && renderOptions->HasExited)
|
||||
{
|
||||
delete renderOptions;
|
||||
@ -234,7 +234,8 @@ void GameController::ClearSim()
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
Save::~Save()
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void Save::SetName(string 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();
|
||||
|
||||
string userName;
|
||||
string name;
|
||||
|
||||
|
@ -5,16 +5,32 @@
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <bzlib.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)
|
||||
{
|
||||
return 0;
|
||||
return OPSBuildSave(dataLength, 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
|
@ -12,11 +12,11 @@
|
||||
|
||||
class SaveLoader {
|
||||
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 int OPSLoadSave(unsigned char * data, 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);
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
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)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "Elements.h"
|
||||
#include "Misc.h"
|
||||
#include "game/Brush.h"
|
||||
#include "Gravity.h"
|
||||
#include "SimulationData.h"
|
||||
//#include "ElementFunctions.h"
|
||||
|
||||
@ -204,36 +205,36 @@ public:
|
||||
int sandcolour_r;
|
||||
int sandcolour_g;
|
||||
int sandcolour_b; //TODO: Make a single variable
|
||||
//TODO: Inlines for performance
|
||||
|
||||
int Load(unsigned char * data, int dataLength);
|
||||
unsigned char * Save(int & dataLength);
|
||||
int is_blocking(int t, int x, int y);
|
||||
int is_boundary(int pt, int x, int y);
|
||||
int find_next_boundary(int pt, int *x, int *y, int dm, int *em);
|
||||
int pn_junction_sprk(int x, int y, int pt);
|
||||
void photoelectric_effect(int nx, int ny);
|
||||
unsigned direction_to_map(float dx, float dy, int t);
|
||||
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);
|
||||
int eval_move(int pt, int nx, int ny, unsigned *rr);
|
||||
inline int is_blocking(int t, int x, int y);
|
||||
inline int is_boundary(int pt, int x, int y);
|
||||
inline int find_next_boundary(int pt, int *x, int *y, int dm, int *em);
|
||||
inline int pn_junction_sprk(int x, int y, int pt);
|
||||
inline void photoelectric_effect(int nx, int ny);
|
||||
inline unsigned direction_to_map(float dx, float dy, int t);
|
||||
inline int do_move(int i, int x, int y, float nxf, float nyf);
|
||||
inline int try_move(int i, int x, int y, int nx, int ny);
|
||||
inline int eval_move(int pt, int nx, int ny, unsigned *rr);
|
||||
void init_can_move();
|
||||
void create_cherenkov_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_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);
|
||||
void detach(int i);
|
||||
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 void detach(int i);
|
||||
inline void part_change_type(int i, int x, int y, int t);
|
||||
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 get_brush_flags();
|
||||
int create_part(int p, int x, int y, int t);
|
||||
void delete_part(int x, int y, int flags);
|
||||
int is_wire(int x, int y);
|
||||
int is_wire_off(int x, int y);
|
||||
void set_emap(int x, int y);
|
||||
int parts_avg(int ci, int ni, int t);
|
||||
inline int create_part(int p, int x, int y, int t);
|
||||
inline void delete_part(int x, int y, int flags);
|
||||
inline int is_wire(int x, int y);
|
||||
inline int is_wire_off(int x, int y);
|
||||
inline void set_emap(int x, int y);
|
||||
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);
|
||||
int nearest_part(int ci, int t, int max_d);
|
||||
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);
|
||||
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 orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
||||
void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
|
||||
int get_wavelength_bin(int *wm);
|
||||
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 void orbitalparts_get(int block1, int block2, int resblock1[], int resblock2[]);
|
||||
inline void orbitalparts_set(int *block1, int *block2, int resblock1[], int resblock2[]);
|
||||
inline int get_wavelength_bin(int *wm);
|
||||
inline int get_normal(int pt, int x, int y, 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 UpdateParticles();
|
||||
Simulation();
|
||||
|
Reference in New Issue
Block a user