Load save data when showing the save preview

This commit is contained in:
Simon Robertshaw 2012-06-08 22:04:14 +01:00
parent 1dadb11fc2
commit 0ee1e1875d
12 changed files with 238 additions and 117 deletions

View File

@ -22,13 +22,13 @@ gravityMode(save.gravityMode),
airMode(save.airMode), airMode(save.airMode),
signs(save.signs) signs(save.signs)
{ {
setSize(save.width, save.height); setSize(save.blockWidth, save.blockHeight);
particlesCount = save.particlesCount; particlesCount = save.particlesCount;
copy(save.particles, save.particles+NPART, particles); copy(save.particles, save.particles+NPART, particles);
copy(save.blockMapPtr, save.blockMapPtr+((height/CELL)*(width/CELL)), blockMapPtr); copy(save.blockMapPtr, save.blockMapPtr+(blockHeight*blockWidth), blockMapPtr);
copy(save.fanVelXPtr, save.fanVelXPtr+((height/CELL)*(width/CELL)), fanVelXPtr); copy(save.fanVelXPtr, save.fanVelXPtr+(blockHeight*blockWidth), fanVelXPtr);
copy(save.fanVelYPtr, save.fanVelYPtr+((height/CELL)*(width/CELL)), fanVelYPtr); copy(save.fanVelYPtr, save.fanVelYPtr+(blockHeight*blockWidth), fanVelYPtr);
} }
GameSave::GameSave(int width, int height) GameSave::GameSave(int width, int height)
@ -38,10 +38,29 @@ GameSave::GameSave(int width, int height)
GameSave::GameSave(char * data, int dataSize) GameSave::GameSave(char * data, int dataSize)
{ {
width, height = 0; blockWidth, blockHeight = 0;
blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL; blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL;
try { try {
if(dataSize > 0)
{
if(data[0] == 0x50 || data[0] == 0x66)
{
readPSv(data, dataSize); readPSv(data, dataSize);
}
else if(data[0] == 'O')
{
readOPS(data, dataSize);
}
else
{
std::cerr << "Got Magic number '" << data[0] << "'" << std::endl;
throw ParseException(ParseException::Corrupt, "Invalid save format");
}
}
else
{
throw ParseException(ParseException::Corrupt, "No data");
}
} catch (ParseException& e) { } catch (ParseException& e) {
this->~GameSave(); //Free any allocated memory this->~GameSave(); //Free any allocated memory
throw; throw;
@ -50,26 +69,29 @@ GameSave::GameSave(char * data, int dataSize)
void GameSave::setSize(int newWidth, int newHeight) void GameSave::setSize(int newWidth, int newHeight)
{ {
this->width = (newWidth/CELL)*CELL;
this->height = (newHeight/CELL)*CELL; std::cout << "GameSave::setSize(" << newWidth << ", " << newHeight << ")";
this->blockWidth = newWidth;
this->blockHeight = newHeight;
particlesCount = 0; particlesCount = 0;
particles = new Particle[NPART]; particles = new Particle[NPART];
blockMap = new unsigned char*[height/CELL]; blockMap = new unsigned char*[blockHeight];
blockMapPtr = new unsigned char[(height/CELL)*(width/CELL)]; blockMapPtr = new unsigned char[blockHeight*blockWidth];
fill(blockMapPtr, blockMapPtr+((height/CELL)*(width/CELL)), 0); fill(blockMapPtr, blockMapPtr+(blockHeight*blockWidth), 0);
for(int y = 0; y < height/CELL; y++) for(int y = 0; y < blockHeight; y++)
blockMap[y] = &blockMapPtr[y*(width/CELL)]; blockMap[y] = &blockMapPtr[y*blockWidth];
fanVelXPtr = new float[(height/CELL)*(width/CELL)]; fanVelXPtr = new float[(blockHeight)*(blockWidth)];
fill(fanVelXPtr, fanVelXPtr+((height/CELL)*(width/CELL)), 0); fill(fanVelXPtr, fanVelXPtr+((blockHeight)*(blockWidth)), 0);
fanVelX = new float*[height/CELL]; fanVelX = new float*[blockHeight];
for(int y = 0; y < height/CELL; y++) for(int y = 0; y < blockHeight; y++)
fanVelX[y] = &fanVelXPtr[y*(width/CELL)]; fanVelX[y] = &fanVelXPtr[y*(blockWidth)];
fanVelYPtr = new float[(height/CELL)*(width/CELL)]; fanVelYPtr = new float[(blockHeight)*(blockWidth)];
fill(fanVelYPtr, fanVelYPtr+((height/CELL)*(width/CELL)), 0); fill(fanVelYPtr, fanVelYPtr+((blockHeight)*(blockWidth)), 0);
fanVelY = new float*[height/CELL]; fanVelY = new float*[blockHeight];
for(int y = 0; y < height/CELL; y++) for(int y = 0; y < blockHeight; y++)
fanVelY[y] = &fanVelYPtr[y*(width/CELL)]; fanVelY[y] = &fanVelYPtr[y*blockWidth];
} }
char * GameSave::Serialise(int & dataSize) char * GameSave::Serialise(int & dataSize)
@ -116,7 +138,7 @@ void GameSave::readOPS(char * data, int dataLength)
if(blockX+blockW > XRES/CELL || blockY+blockH > YRES/CELL) if(blockX+blockW > XRES/CELL || blockY+blockH > YRES/CELL)
throw ParseException(ParseException::InvalidDimensions, "Save too large"); throw ParseException(ParseException::InvalidDimensions, "Save too large");
setSize(fullW, fullH); setSize(blockW, blockH);
bsonDataLen = ((unsigned)inputData[8]); bsonDataLen = ((unsigned)inputData[8]);
bsonDataLen |= ((unsigned)inputData[9]) << 8; bsonDataLen |= ((unsigned)inputData[9]) << 8;
@ -373,7 +395,7 @@ void GameSave::readOPS(char * data, int dataLength)
y = saved_y + fullY; y = saved_y + fullY;
fieldDescriptor = partsData[i+1]; fieldDescriptor = partsData[i+1];
fieldDescriptor |= partsData[i+2] << 8; fieldDescriptor |= partsData[i+2] << 8;
if(x >= XRES || x < 0 || y >= YRES || y < 0) if(x >= fullW || x < 0 || y >= fullH || y < 0)
{ {
fprintf(stderr, "Out of range [%d]: %d %d, [%d, %d], [%d, %d]\n", i, x, y, (unsigned)partsData[i+1], (unsigned)partsData[i+2], (unsigned)partsData[i+3], (unsigned)partsData[i+4]); fprintf(stderr, "Out of range [%d]: %d %d, [%d, %d], [%d, %d]\n", i, x, y, (unsigned)partsData[i+1], (unsigned)partsData[i+2], (unsigned)partsData[i+3], (unsigned)partsData[i+4]);
goto fail; goto fail;
@ -618,7 +640,7 @@ void GameSave::readPSv(char * data, int dataLength)
if (!d) if (!d)
throw ParseException(ParseException::Corrupt, "Cannot allocate memory"); throw ParseException(ParseException::Corrupt, "Cannot allocate memory");
setSize(bw*CELL, bh*CELL); setSize(bw, bh);
if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0)) if (BZ2_bzBuffToBuffDecompress((char *)d, (unsigned *)&i, (char *)(c+12), dataLength-12, 0, 0))
throw ParseException(ParseException::Corrupt, "Cannot decompress"); throw ParseException(ParseException::Corrupt, "Cannot decompress");
@ -1122,8 +1144,8 @@ char * GameSave::serialiseOPS(int & dataLength)
fullY = blockY*CELL; fullY = blockY*CELL;
//Original size + offset of original corner from snapped corner, rounded up by adding CELL-1 //Original size + offset of original corner from snapped corner, rounded up by adding CELL-1
blockW = (width-fullX+CELL-1)/CELL; blockW = blockWidth;//(blockWidth-fullX+CELL-1)/CELL;
blockH = (height-fullY+CELL-1)/CELL; blockH = blockHeight;//(blockHeight-fullY+CELL-1)/CELL;
fullW = blockW*CELL; fullW = blockW*CELL;
fullH = blockH*CELL; fullH = blockH*CELL;
@ -1438,7 +1460,7 @@ fin:
GameSave::~GameSave() GameSave::~GameSave()
{ {
if(width && height) if(blockWidth && blockHeight)
{ {
if(particles) if(particles)
{ {

View File

@ -34,7 +34,7 @@ class GameSave
{ {
public: public:
int width, height; int blockWidth, blockHeight;
//Simulation data //Simulation data
//int ** particleMap; //int ** particleMap;

View File

@ -99,5 +99,7 @@ GameSave * SaveInfo::GetGameSave()
void SaveInfo::SetGameSave(GameSave * saveGame) void SaveInfo::SetGameSave(GameSave * saveGame)
{ {
if(gameSave)
delete gameSave;
gameSave = saveGame; gameSave = saveGame;
} }

View File

@ -234,6 +234,11 @@ ui::Point GameController::PointTranslate(ui::Point point)
return point; return point;
} }
ui::Point GameController::NormaliseBlockCoord(ui::Point point)
{
return (point/CELL)*CELL;
}
void GameController::DrawRect(int toolSelection, ui::Point point1, ui::Point point2) void GameController::DrawRect(int toolSelection, ui::Point point1, ui::Point point2)
{ {
Simulation * sim = gameModel->GetSimulation(); Simulation * sim = gameModel->GetSimulation();

View File

@ -94,6 +94,7 @@ public:
void ShowConsole(); void ShowConsole();
void FrameStep(); void FrameStep();
ui::Point PointTranslate(ui::Point point); ui::Point PointTranslate(ui::Point point);
ui::Point NormaliseBlockCoord(ui::Point point);
std::string ElementResolve(int type); std::string ElementResolve(int type);
}; };

View File

@ -898,17 +898,19 @@ void GameView::OnDraw()
int thumbX = selectPoint2.X - (tempThumb->Size.X/2); int thumbX = selectPoint2.X - (tempThumb->Size.X/2);
int thumbY = selectPoint2.Y - (tempThumb->Size.Y/2); int thumbY = selectPoint2.Y - (tempThumb->Size.Y/2);
if(thumbX<0) ui::Point thumbPos = c->NormaliseBlockCoord(ui::Point(thumbX, thumbY));
thumbX = 0;
if(thumbX+(tempThumb->Size.X)>=XRES)
thumbX = XRES-tempThumb->Size.X;
if(thumbY<0) if(thumbPos.X<0)
thumbY = 0; thumbPos.X = 0;
if(thumbY+(tempThumb->Size.Y)>=YRES) if(thumbPos.X+(tempThumb->Size.X)>=XRES)
thumbY = YRES-tempThumb->Size.Y; thumbPos.X = XRES-tempThumb->Size.X;
g->draw_image(tempThumb->Data, thumbX, thumbY, tempThumb->Size.X, tempThumb->Size.Y, 128); if(thumbPos.Y<0)
thumbPos.Y = 0;
if(thumbPos.Y+(tempThumb->Size.Y)>=YRES)
thumbPos.Y = YRES-tempThumb->Size.Y;
g->draw_image(tempThumb->Data, thumbPos.X, thumbPos.Y, tempThumb->Size.X, tempThumb->Size.Y, 128);
} }
} }
else else

View File

@ -11,11 +11,10 @@
PreviewModel::PreviewModel(): PreviewModel::PreviewModel():
save(NULL), save(NULL),
savePreview(NULL),
saveComments(NULL), saveComments(NULL),
doOpen(false), doOpen(false),
updateSavePreviewWorking(false), updateSaveDataWorking(false),
updateSavePreviewFinished(false), updateSaveDataFinished(false),
updateSaveInfoWorking(false), updateSaveInfoWorking(false),
updateSaveInfoFinished(false), updateSaveInfoFinished(false),
updateSaveCommentsWorking(false), updateSaveCommentsWorking(false),
@ -30,9 +29,9 @@ void * PreviewModel::updateSaveInfoTHelper(void * obj)
return ((PreviewModel*)obj)->updateSaveInfoT(); return ((PreviewModel*)obj)->updateSaveInfoT();
} }
void * PreviewModel::updateSavePreviewTHelper(void * obj) void * PreviewModel::updateSaveDataTHelper(void * obj)
{ {
return ((PreviewModel*)obj)->updateSavePreviewT(); return ((PreviewModel*)obj)->updateSaveDataT();
} }
void * PreviewModel::updateSaveCommentsTHelper(void * obj) void * PreviewModel::updateSaveCommentsTHelper(void * obj)
@ -47,11 +46,14 @@ void * PreviewModel::updateSaveInfoT()
return tempSave; return tempSave;
} }
void * PreviewModel::updateSavePreviewT() void * PreviewModel::updateSaveDataT()
{ {
Thumbnail * tempThumb = Client::Ref().GetPreview(tSaveID, tSaveDate); int tempDataSize;
updateSavePreviewFinished = true; unsigned char * tempData = Client::Ref().GetSaveData(tSaveID, tSaveDate, tempDataSize);
return tempThumb; saveDataBuffer.clear();
saveDataBuffer.insert(saveDataBuffer.begin(), tempData, tempData+tempDataSize);
updateSaveDataFinished = true;
return NULL;
} }
void * PreviewModel::updateSaveCommentsT() void * PreviewModel::updateSaveCommentsT()
@ -81,11 +83,7 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
delete save; delete save;
save = NULL; save = NULL;
} }
if(savePreview) saveDataBuffer.clear();
{
delete savePreview;
savePreview = NULL;
}
if(saveComments) if(saveComments)
{ {
for(int i = 0; i < saveComments->size(); i++) for(int i = 0; i < saveComments->size(); i++)
@ -93,15 +91,14 @@ void PreviewModel::UpdateSave(int saveID, int saveDate)
delete saveComments; delete saveComments;
saveComments = NULL; saveComments = NULL;
} }
notifyPreviewChanged();
notifySaveChanged(); notifySaveChanged();
notifySaveCommentsChanged(); notifySaveCommentsChanged();
if(!updateSavePreviewWorking) if(!updateSaveDataWorking)
{ {
updateSavePreviewWorking = true; updateSaveDataWorking = true;
updateSavePreviewFinished = false; updateSaveDataFinished = false;
pthread_create(&updateSavePreviewThread, 0, &PreviewModel::updateSavePreviewTHelper, this); pthread_create(&updateSaveDataThread, 0, &PreviewModel::updateSaveDataTHelper, this);
} }
if(!updateSaveInfoWorking) if(!updateSaveInfoWorking)
@ -129,11 +126,6 @@ bool PreviewModel::GetDoOpen()
return doOpen; return doOpen;
} }
Thumbnail * PreviewModel::GetPreview()
{
return savePreview;
}
SaveInfo * PreviewModel::GetSave() SaveInfo * PreviewModel::GetSave()
{ {
return save; return save;
@ -144,14 +136,6 @@ std::vector<SaveComment*> * PreviewModel::GetComments()
return saveComments; return saveComments;
} }
void PreviewModel::notifyPreviewChanged()
{
for(int i = 0; i < observers.size(); i++)
{
observers[i]->NotifyPreviewChanged(this);
}
}
void PreviewModel::notifySaveChanged() void PreviewModel::notifySaveChanged()
{ {
for(int i = 0; i < observers.size(); i++) for(int i = 0; i < observers.size(); i++)
@ -170,24 +154,30 @@ void PreviewModel::notifySaveCommentsChanged()
void PreviewModel::AddObserver(PreviewView * observer) { void PreviewModel::AddObserver(PreviewView * observer) {
observers.push_back(observer); observers.push_back(observer);
observer->NotifyPreviewChanged(this);
observer->NotifySaveChanged(this); observer->NotifySaveChanged(this);
} }
void PreviewModel::Update() void PreviewModel::Update()
{ {
if(updateSavePreviewWorking) if(updateSaveDataWorking)
{ {
if(updateSavePreviewFinished) if(updateSaveDataFinished)
{ {
if(savePreview) updateSaveDataWorking = false;
pthread_join(updateSaveDataThread, NULL);
if(updateSaveInfoFinished && save)
{ {
delete savePreview; try
savePreview = NULL; {
save->SetGameSave(new GameSave(&saveDataBuffer[0], saveDataBuffer.size()));
}
catch(ParseException &e)
{
throw PreviewModelException("Save file corrupt or from newer version");
}
notifySaveChanged();
} }
updateSavePreviewWorking = false;
pthread_join(updateSavePreviewThread, (void**)(&savePreview));
notifyPreviewChanged();
} }
} }
@ -202,6 +192,17 @@ void PreviewModel::Update()
} }
updateSaveInfoWorking = false; updateSaveInfoWorking = false;
pthread_join(updateSaveInfoThread, (void**)(&save)); pthread_join(updateSaveInfoThread, (void**)(&save));
if(updateSaveDataFinished && save)
{
try
{
save->SetGameSave(new GameSave(&saveDataBuffer[0], saveDataBuffer.size()));
}
catch(ParseException &e)
{
throw PreviewModelException("Save file corrupt or from newer version");
}
}
notifySaveChanged(); notifySaveChanged();
if(!save) if(!save)
throw PreviewModelException("Unable to load save"); throw PreviewModelException("Unable to load save");
@ -229,7 +230,5 @@ void PreviewModel::Update()
PreviewModel::~PreviewModel() { PreviewModel::~PreviewModel() {
if(save) if(save)
delete save; delete save;
if(savePreview)
delete savePreview;
} }

View File

@ -9,6 +9,7 @@
#define PREVIEWMODEL_H_ #define PREVIEWMODEL_H_
#include <vector> #include <vector>
#include <iostream>
#include <pthread.h> #include <pthread.h>
#include "PreviewView.h" #include "PreviewView.h"
#include "client/SaveInfo.h" #include "client/SaveInfo.h"
@ -17,14 +18,19 @@
using namespace std; using namespace std;
struct SaveData
{
unsigned char * data;
int length;
};
class PreviewView; class PreviewView;
class PreviewModel { class PreviewModel {
bool doOpen; bool doOpen;
vector<PreviewView*> observers; vector<PreviewView*> observers;
SaveInfo * save; SaveInfo * save;
Thumbnail * savePreview; vector<char> saveDataBuffer;
std::vector<SaveComment*> * saveComments; std::vector<SaveComment*> * saveComments;
void notifyPreviewChanged();
void notifySaveChanged(); void notifySaveChanged();
void notifySaveCommentsChanged(); void notifySaveCommentsChanged();
@ -32,11 +38,11 @@ class PreviewModel {
int tSaveID; int tSaveID;
int tSaveDate; int tSaveDate;
bool updateSavePreviewWorking; bool updateSaveDataWorking;
volatile bool updateSavePreviewFinished; volatile bool updateSaveDataFinished;
pthread_t updateSavePreviewThread; pthread_t updateSaveDataThread;
static void * updateSavePreviewTHelper(void * obj); static void * updateSaveDataTHelper(void * obj);
void * updateSavePreviewT(); void * updateSaveDataT();
bool updateSaveInfoWorking; bool updateSaveInfoWorking;
volatile bool updateSaveInfoFinished; volatile bool updateSaveInfoFinished;
@ -51,7 +57,6 @@ class PreviewModel {
void * updateSaveCommentsT(); void * updateSaveCommentsT();
public: public:
PreviewModel(); PreviewModel();
Thumbnail * GetPreview();
SaveInfo * GetSave(); SaveInfo * GetSave();
std::vector<SaveComment*> * GetComments(); std::vector<SaveComment*> * GetComments();
void AddObserver(PreviewView * observer); void AddObserver(PreviewView * observer);

View File

@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "PreviewView.h" #include "PreviewView.h"
#include "dialogues/TextPrompt.h" #include "dialogues/TextPrompt.h"
#include "simulation/SaveRenderer.h"
#include "interface/Point.h" #include "interface/Point.h"
#include "interface/Window.h" #include "interface/Window.h"
#include "search/Thumbnail.h" #include "search/Thumbnail.h"
@ -163,6 +164,9 @@ void PreviewView::OnMouseDown(int x, int y, unsigned button)
void PreviewView::NotifySaveChanged(PreviewModel * sender) void PreviewView::NotifySaveChanged(PreviewModel * sender)
{ {
SaveInfo * save = sender->GetSave(); SaveInfo * save = sender->GetSave();
if(savePreview)
delete savePreview;
savePreview = NULL;
if(save) if(save)
{ {
votesUp = save->votesUp; votesUp = save->votesUp;
@ -174,6 +178,24 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
favButton->Enabled = false; favButton->Enabled = false;
else else
favButton->Enabled = true; favButton->Enabled = true;
if(save->GetGameSave())
{
savePreview = SaveRenderer::Ref().Render(save->GetGameSave());
if(savePreview && savePreview->Data && !(savePreview->Size.X == XRES/2 && savePreview->Size.Y == YRES/2))
{
int newSizeX, newSizeY;
pixel * oldData = savePreview->Data;
float factorX = ((float)XRES/2)/((float)savePreview->Size.X);
float factorY = ((float)YRES/2)/((float)savePreview->Size.Y);
float scaleFactor = factorY < factorX ? factorY : factorX;
savePreview->Data = Graphics::resample_img(oldData, savePreview->Size.X, savePreview->Size.Y, savePreview->Size.X*scaleFactor, savePreview->Size.Y*scaleFactor);
free(oldData);
savePreview->Size.X *= scaleFactor;
savePreview->Size.Y *= scaleFactor;
}
}
} }
else else
{ {
@ -230,9 +252,9 @@ void PreviewView::NotifyCommentsChanged(PreviewModel * sender)
} }
} }
void PreviewView::NotifyPreviewChanged(PreviewModel * sender) /*void PreviewView::NotifyPreviewChanged(PreviewModel * sender)
{ {
savePreview = sender->GetPreview(); savePreview = sender->GetGameSave();
if(savePreview && savePreview->Data && !(savePreview->Size.X == XRES/2 && savePreview->Size.Y == YRES/2)) if(savePreview && savePreview->Data && !(savePreview->Size.X == XRES/2 && savePreview->Size.Y == YRES/2))
{ {
int newSizeX, newSizeY; int newSizeX, newSizeY;
@ -243,7 +265,7 @@ void PreviewView::NotifyPreviewChanged(PreviewModel * sender)
savePreview->Size.X *= scaleFactor; savePreview->Size.X *= scaleFactor;
savePreview->Size.Y *= scaleFactor; savePreview->Size.Y *= scaleFactor;
} }
} }*/
PreviewView::~PreviewView() { PreviewView::~PreviewView() {
} }

View File

@ -36,7 +36,6 @@ class PreviewView: public ui::Window {
public: public:
void AttachController(PreviewController * controller) { c = controller;} void AttachController(PreviewController * controller) { c = controller;}
PreviewView(); PreviewView();
void NotifyPreviewChanged(PreviewModel * sender);
void NotifySaveChanged(PreviewModel * sender); void NotifySaveChanged(PreviewModel * sender);
void NotifyCommentsChanged(PreviewModel * sender); void NotifyCommentsChanged(PreviewModel * sender);
virtual void OnDraw(); virtual void OnDraw();

View File

@ -22,8 +22,8 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
{ {
Thumbnail * tempThumb = NULL; Thumbnail * tempThumb = NULL;
int width, height; int width, height;
width = save->width/CELL; width = save->blockWidth;
height = save->height/CELL; height = save->blockHeight;
pixel * pData = NULL; pixel * pData = NULL;
pixel * dst; pixel * dst;

View File

@ -17,31 +17,48 @@ int Simulation::Load(GameSave * save)
return Load(0, 0, save); return Load(0, 0, save);
} }
int Simulation::Load(int x, int y, GameSave * save) int Simulation::Load(int fullX, int fullY, GameSave * save)
{ {
for(int i = 0; i < NPART && i < save->particlesCount; i++) int blockX, blockY;
if(!save) return 0;
//Align to blockMap
blockX = fullX/CELL;
blockY = fullY/CELL;
fullX = blockX*CELL;
fullY = blockY*CELL;
int i;
for(int n = 0; n < NPART && n < save->particlesCount; n++)
{ {
parts[i] = save->particles[i]; if (pfree == -1)
parts[i].x += (float)x; break;
parts[i].y += (float)y; i = pfree;
pfree = parts[i].life;
if (i>parts_lastActiveIndex) parts_lastActiveIndex = i;
parts[i] = save->particles[n];
parts[i].x += (float)fullX;
parts[i].y += (float)fullY;
} }
parts_lastActiveIndex = NPART-1; parts_lastActiveIndex = NPART-1;
for(int i = 0; i < save->signs.size() && signs.size() < MAXSIGNS; i++) for(int i = 0; i < save->signs.size() && signs.size() < MAXSIGNS; i++)
{ {
sign tempSign = save->signs[i]; sign tempSign = save->signs[i];
tempSign.x += x; tempSign.x += fullX;
tempSign.y += y; tempSign.y += fullY;
signs.push_back(tempSign); signs.push_back(tempSign);
} }
for(int blockX = 0; blockX < save->width/CELL; blockX++) for(int saveBlockX = 0; saveBlockX < save->blockWidth/CELL; saveBlockX++)
{ {
for(int blockY = 0; blockY < save->height/CELL; blockY++) for(int saveBlockY = 0; saveBlockY < save->blockHeight/CELL; saveBlockY++)
{ {
if(save->blockMap[blockY][blockX]) if(save->blockMap[saveBlockY][saveBlockX])
{ {
bmap[blockY+(y/CELL)][blockX+(x/CELL)] = save->blockMap[blockY][blockX]; bmap[saveBlockY+blockY][saveBlockX+blockX] = save->blockMap[saveBlockY][saveBlockX];
fvx[blockY+(y/CELL)][blockX+(x/CELL)] = save->fanVelX[blockY][blockX]; fvx[saveBlockY+blockY][saveBlockX+blockX] = save->fanVelX[saveBlockY][saveBlockX];
fvy[blockY+(y/CELL)][blockX+(x/CELL)] = save->fanVelY[blockY][blockX]; fvy[saveBlockY+blockY][saveBlockX+blockX] = save->fanVelY[saveBlockY][saveBlockX];
} }
} }
} }
@ -53,35 +70,82 @@ GameSave * Simulation::Save()
return Save(0, 0, XRES, YRES); return Save(0, 0, XRES, YRES);
} }
GameSave * Simulation::Save(int x1, int y1, int x2, int y2) GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2)
{ {
GameSave * newSave = new GameSave(abs(x2-x1), abs(y2-y1)); int blockX, blockY, blockX2, blockY2, fullW, fullH, blockW, blockH;
//Normalise incoming coords
int swapTemp;
if(fullY>fullY2)
{
swapTemp = fullY;
fullY = fullY2;
fullY2 = swapTemp;
}
if(fullX>fullX2)
{
swapTemp = fullX;
fullX = fullX2;
fullX2 = swapTemp;
}
//Align coords to blockMap
blockX = fullX/CELL;
blockY = fullY/CELL;
blockX2 = fullX2/CELL;
blockY2 = fullY2/CELL;
fullX = blockX*CELL;
fullY = blockY*CELL;
fullX2 = blockX2*CELL;
fullY2 = blockY2*CELL;
blockW = blockX2-blockX;
blockH = blockY2-blockY;
fullW = fullX2-fullX;
fullH = fullY2-fullY;
GameSave * newSave = new GameSave(blockW, blockH);
for(int i = 0; i < NPART; i++) for(int i = 0; i < NPART; i++)
{ {
int x, y; int x, y;
x = int(parts[i].x + 0.5f); x = int(parts[i].x + 0.5f);
y = int(parts[i].y + 0.5f); y = int(parts[i].y + 0.5f);
if(parts[i].type && x >= x1 && y >= y1 && x < x2 && y < y2) if(parts[i].type && x >= fullX && y >= fullY && x < fullX2 && y < fullY2)
{ {
Particle tempPart = parts[i]; Particle tempPart = parts[i];
tempPart.x -= x1; tempPart.x -= fullX;
tempPart.y -= y1; tempPart.y -= fullY;
*newSave << tempPart; *newSave << tempPart;
} }
} }
for(int i = 0; i < MAXSIGNS && i < signs.size(); i++) for(int i = 0; i < MAXSIGNS && i < signs.size(); i++)
{ {
if(signs[i].text.length() && signs[i].x >= x1 && signs[i].y >= y1 && signs[i].x < x2 && signs[i].y < y2) if(signs[i].text.length() && signs[i].x >= fullX && signs[i].y >= fullY && signs[i].x < fullX2 && signs[i].y < fullY2)
{ {
sign tempSign = signs[i]; sign tempSign = signs[i];
tempSign.x -= x1; tempSign.x -= fullX;
tempSign.y -= y1; tempSign.y -= fullY;
*newSave << tempSign; *newSave << tempSign;
} }
} }
for(int saveBlockX = 0; saveBlockX < newSave->blockWidth; saveBlockX++)
{
for(int saveBlockY = 0; saveBlockY < newSave->blockHeight; saveBlockY++)
{
if(bmap[saveBlockY+blockY][saveBlockX+blockX])
{
newSave->blockMap[saveBlockY][saveBlockX] = bmap[saveBlockY+blockY][saveBlockX+blockX];
newSave->fanVelX[saveBlockY][saveBlockX] = fvx[saveBlockY+blockY][saveBlockX+blockX];
newSave->fanVelY[saveBlockY][saveBlockX] = fvy[saveBlockY+blockY][saveBlockX+blockX];
}
}
}
return newSave; return newSave;
} }