From 0ee1e1875d00876b946f358308f39dc33ef96ea4 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Fri, 8 Jun 2012 22:04:14 +0100 Subject: [PATCH] Load save data when showing the save preview --- src/client/GameSave.cpp | 80 +++++++++++++++--------- src/client/GameSave.h | 2 +- src/client/SaveInfo.cpp | 2 + src/game/GameController.cpp | 5 ++ src/game/GameController.h | 1 + src/game/GameView.cpp | 20 +++--- src/preview/PreviewModel.cpp | 85 +++++++++++++------------ src/preview/PreviewModel.h | 21 ++++--- src/preview/PreviewView.cpp | 28 ++++++++- src/preview/PreviewView.h | 1 - src/simulation/SaveRenderer.cpp | 4 +- src/simulation/Simulation.cpp | 106 +++++++++++++++++++++++++------- 12 files changed, 238 insertions(+), 117 deletions(-) diff --git a/src/client/GameSave.cpp b/src/client/GameSave.cpp index 8ad03a262..3bf0df181 100644 --- a/src/client/GameSave.cpp +++ b/src/client/GameSave.cpp @@ -22,13 +22,13 @@ gravityMode(save.gravityMode), airMode(save.airMode), signs(save.signs) { - setSize(save.width, save.height); + setSize(save.blockWidth, save.blockHeight); particlesCount = save.particlesCount; copy(save.particles, save.particles+NPART, particles); - copy(save.blockMapPtr, save.blockMapPtr+((height/CELL)*(width/CELL)), blockMapPtr); - copy(save.fanVelXPtr, save.fanVelXPtr+((height/CELL)*(width/CELL)), fanVelXPtr); - copy(save.fanVelYPtr, save.fanVelYPtr+((height/CELL)*(width/CELL)), fanVelYPtr); + copy(save.blockMapPtr, save.blockMapPtr+(blockHeight*blockWidth), blockMapPtr); + copy(save.fanVelXPtr, save.fanVelXPtr+(blockHeight*blockWidth), fanVelXPtr); + copy(save.fanVelYPtr, save.fanVelYPtr+(blockHeight*blockWidth), fanVelYPtr); } GameSave::GameSave(int width, int height) @@ -38,10 +38,29 @@ GameSave::GameSave(int width, int height) GameSave::GameSave(char * data, int dataSize) { - width, height = 0; + blockWidth, blockHeight = 0; blockMap, blockMapPtr, fanVelX, fanVelXPtr, fanVelY, fanVelYPtr, particles = NULL; try { - readPSv(data, dataSize); + if(dataSize > 0) + { + if(data[0] == 0x50 || data[0] == 0x66) + { + 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) { this->~GameSave(); //Free any allocated memory throw; @@ -50,26 +69,29 @@ GameSave::GameSave(char * data, int dataSize) 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; particles = new Particle[NPART]; - blockMap = new unsigned char*[height/CELL]; - blockMapPtr = new unsigned char[(height/CELL)*(width/CELL)]; - fill(blockMapPtr, blockMapPtr+((height/CELL)*(width/CELL)), 0); - for(int y = 0; y < height/CELL; y++) - blockMap[y] = &blockMapPtr[y*(width/CELL)]; - fanVelXPtr = new float[(height/CELL)*(width/CELL)]; - fill(fanVelXPtr, fanVelXPtr+((height/CELL)*(width/CELL)), 0); - fanVelX = new float*[height/CELL]; - for(int y = 0; y < height/CELL; y++) - fanVelX[y] = &fanVelXPtr[y*(width/CELL)]; - fanVelYPtr = new float[(height/CELL)*(width/CELL)]; - fill(fanVelYPtr, fanVelYPtr+((height/CELL)*(width/CELL)), 0); - fanVelY = new float*[height/CELL]; - for(int y = 0; y < height/CELL; y++) - fanVelY[y] = &fanVelYPtr[y*(width/CELL)]; + blockMap = new unsigned char*[blockHeight]; + blockMapPtr = new unsigned char[blockHeight*blockWidth]; + fill(blockMapPtr, blockMapPtr+(blockHeight*blockWidth), 0); + for(int y = 0; y < blockHeight; y++) + blockMap[y] = &blockMapPtr[y*blockWidth]; + fanVelXPtr = new float[(blockHeight)*(blockWidth)]; + fill(fanVelXPtr, fanVelXPtr+((blockHeight)*(blockWidth)), 0); + fanVelX = new float*[blockHeight]; + for(int y = 0; y < blockHeight; y++) + fanVelX[y] = &fanVelXPtr[y*(blockWidth)]; + fanVelYPtr = new float[(blockHeight)*(blockWidth)]; + fill(fanVelYPtr, fanVelYPtr+((blockHeight)*(blockWidth)), 0); + fanVelY = new float*[blockHeight]; + for(int y = 0; y < blockHeight; y++) + fanVelY[y] = &fanVelYPtr[y*blockWidth]; } 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) throw ParseException(ParseException::InvalidDimensions, "Save too large"); - setSize(fullW, fullH); + setSize(blockW, blockH); bsonDataLen = ((unsigned)inputData[8]); bsonDataLen |= ((unsigned)inputData[9]) << 8; @@ -373,7 +395,7 @@ void GameSave::readOPS(char * data, int dataLength) y = saved_y + fullY; fieldDescriptor = partsData[i+1]; 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]); goto fail; @@ -618,7 +640,7 @@ void GameSave::readPSv(char * data, int dataLength) if (!d) 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)) throw ParseException(ParseException::Corrupt, "Cannot decompress"); @@ -1122,8 +1144,8 @@ char * GameSave::serialiseOPS(int & dataLength) fullY = blockY*CELL; //Original size + offset of original corner from snapped corner, rounded up by adding CELL-1 - blockW = (width-fullX+CELL-1)/CELL; - blockH = (height-fullY+CELL-1)/CELL; + blockW = blockWidth;//(blockWidth-fullX+CELL-1)/CELL; + blockH = blockHeight;//(blockHeight-fullY+CELL-1)/CELL; fullW = blockW*CELL; fullH = blockH*CELL; @@ -1438,7 +1460,7 @@ fin: GameSave::~GameSave() { - if(width && height) + if(blockWidth && blockHeight) { if(particles) { diff --git a/src/client/GameSave.h b/src/client/GameSave.h index 283ed4e42..ffb7c6d2e 100644 --- a/src/client/GameSave.h +++ b/src/client/GameSave.h @@ -34,7 +34,7 @@ class GameSave { public: - int width, height; + int blockWidth, blockHeight; //Simulation data //int ** particleMap; diff --git a/src/client/SaveInfo.cpp b/src/client/SaveInfo.cpp index 4e096efb3..bfacd7da3 100644 --- a/src/client/SaveInfo.cpp +++ b/src/client/SaveInfo.cpp @@ -99,5 +99,7 @@ GameSave * SaveInfo::GetGameSave() void SaveInfo::SetGameSave(GameSave * saveGame) { + if(gameSave) + delete gameSave; gameSave = saveGame; } diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index 01cf1dec8..e0e86736b 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -234,6 +234,11 @@ ui::Point GameController::PointTranslate(ui::Point 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) { Simulation * sim = gameModel->GetSimulation(); diff --git a/src/game/GameController.h b/src/game/GameController.h index 25705bce7..f2d05b99d 100644 --- a/src/game/GameController.h +++ b/src/game/GameController.h @@ -94,6 +94,7 @@ public: void ShowConsole(); void FrameStep(); ui::Point PointTranslate(ui::Point point); + ui::Point NormaliseBlockCoord(ui::Point point); std::string ElementResolve(int type); }; diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index adc5883f4..89d9fac19 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -898,17 +898,19 @@ void GameView::OnDraw() int thumbX = selectPoint2.X - (tempThumb->Size.X/2); int thumbY = selectPoint2.Y - (tempThumb->Size.Y/2); - if(thumbX<0) - thumbX = 0; - if(thumbX+(tempThumb->Size.X)>=XRES) - thumbX = XRES-tempThumb->Size.X; + ui::Point thumbPos = c->NormaliseBlockCoord(ui::Point(thumbX, thumbY)); - if(thumbY<0) - thumbY = 0; - if(thumbY+(tempThumb->Size.Y)>=YRES) - thumbY = YRES-tempThumb->Size.Y; + if(thumbPos.X<0) + thumbPos.X = 0; + if(thumbPos.X+(tempThumb->Size.X)>=XRES) + 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 diff --git a/src/preview/PreviewModel.cpp b/src/preview/PreviewModel.cpp index de6c6e8b6..f923ceb72 100644 --- a/src/preview/PreviewModel.cpp +++ b/src/preview/PreviewModel.cpp @@ -11,11 +11,10 @@ PreviewModel::PreviewModel(): save(NULL), - savePreview(NULL), saveComments(NULL), doOpen(false), - updateSavePreviewWorking(false), - updateSavePreviewFinished(false), + updateSaveDataWorking(false), + updateSaveDataFinished(false), updateSaveInfoWorking(false), updateSaveInfoFinished(false), updateSaveCommentsWorking(false), @@ -30,9 +29,9 @@ void * PreviewModel::updateSaveInfoTHelper(void * obj) 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) @@ -47,11 +46,14 @@ void * PreviewModel::updateSaveInfoT() return tempSave; } -void * PreviewModel::updateSavePreviewT() +void * PreviewModel::updateSaveDataT() { - Thumbnail * tempThumb = Client::Ref().GetPreview(tSaveID, tSaveDate); - updateSavePreviewFinished = true; - return tempThumb; + int tempDataSize; + unsigned char * tempData = Client::Ref().GetSaveData(tSaveID, tSaveDate, tempDataSize); + saveDataBuffer.clear(); + saveDataBuffer.insert(saveDataBuffer.begin(), tempData, tempData+tempDataSize); + updateSaveDataFinished = true; + return NULL; } void * PreviewModel::updateSaveCommentsT() @@ -81,11 +83,7 @@ void PreviewModel::UpdateSave(int saveID, int saveDate) delete save; save = NULL; } - if(savePreview) - { - delete savePreview; - savePreview = NULL; - } + saveDataBuffer.clear(); if(saveComments) { for(int i = 0; i < saveComments->size(); i++) @@ -93,15 +91,14 @@ void PreviewModel::UpdateSave(int saveID, int saveDate) delete saveComments; saveComments = NULL; } - notifyPreviewChanged(); notifySaveChanged(); notifySaveCommentsChanged(); - if(!updateSavePreviewWorking) + if(!updateSaveDataWorking) { - updateSavePreviewWorking = true; - updateSavePreviewFinished = false; - pthread_create(&updateSavePreviewThread, 0, &PreviewModel::updateSavePreviewTHelper, this); + updateSaveDataWorking = true; + updateSaveDataFinished = false; + pthread_create(&updateSaveDataThread, 0, &PreviewModel::updateSaveDataTHelper, this); } if(!updateSaveInfoWorking) @@ -129,11 +126,6 @@ bool PreviewModel::GetDoOpen() return doOpen; } -Thumbnail * PreviewModel::GetPreview() -{ - return savePreview; -} - SaveInfo * PreviewModel::GetSave() { return save; @@ -144,14 +136,6 @@ std::vector * PreviewModel::GetComments() return saveComments; } -void PreviewModel::notifyPreviewChanged() -{ - for(int i = 0; i < observers.size(); i++) - { - observers[i]->NotifyPreviewChanged(this); - } -} - void PreviewModel::notifySaveChanged() { for(int i = 0; i < observers.size(); i++) @@ -170,24 +154,30 @@ void PreviewModel::notifySaveCommentsChanged() void PreviewModel::AddObserver(PreviewView * observer) { observers.push_back(observer); - observer->NotifyPreviewChanged(this); observer->NotifySaveChanged(this); } void PreviewModel::Update() { - if(updateSavePreviewWorking) + if(updateSaveDataWorking) { - if(updateSavePreviewFinished) + if(updateSaveDataFinished) { - if(savePreview) + updateSaveDataWorking = false; + pthread_join(updateSaveDataThread, NULL); + + if(updateSaveInfoFinished && save) { - delete savePreview; - savePreview = NULL; + try + { + 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; 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(); if(!save) throw PreviewModelException("Unable to load save"); @@ -229,7 +230,5 @@ void PreviewModel::Update() PreviewModel::~PreviewModel() { if(save) delete save; - if(savePreview) - delete savePreview; } diff --git a/src/preview/PreviewModel.h b/src/preview/PreviewModel.h index af94af3f9..5a0fd536b 100644 --- a/src/preview/PreviewModel.h +++ b/src/preview/PreviewModel.h @@ -9,6 +9,7 @@ #define PREVIEWMODEL_H_ #include +#include #include #include "PreviewView.h" #include "client/SaveInfo.h" @@ -17,14 +18,19 @@ using namespace std; +struct SaveData +{ + unsigned char * data; + int length; +}; + class PreviewView; class PreviewModel { bool doOpen; vector observers; SaveInfo * save; - Thumbnail * savePreview; + vector saveDataBuffer; std::vector * saveComments; - void notifyPreviewChanged(); void notifySaveChanged(); void notifySaveCommentsChanged(); @@ -32,11 +38,11 @@ class PreviewModel { int tSaveID; int tSaveDate; - bool updateSavePreviewWorking; - volatile bool updateSavePreviewFinished; - pthread_t updateSavePreviewThread; - static void * updateSavePreviewTHelper(void * obj); - void * updateSavePreviewT(); + bool updateSaveDataWorking; + volatile bool updateSaveDataFinished; + pthread_t updateSaveDataThread; + static void * updateSaveDataTHelper(void * obj); + void * updateSaveDataT(); bool updateSaveInfoWorking; volatile bool updateSaveInfoFinished; @@ -51,7 +57,6 @@ class PreviewModel { void * updateSaveCommentsT(); public: PreviewModel(); - Thumbnail * GetPreview(); SaveInfo * GetSave(); std::vector * GetComments(); void AddObserver(PreviewView * observer); diff --git a/src/preview/PreviewView.cpp b/src/preview/PreviewView.cpp index 4e0716bbd..5e1470e3f 100644 --- a/src/preview/PreviewView.cpp +++ b/src/preview/PreviewView.cpp @@ -8,6 +8,7 @@ #include #include "PreviewView.h" #include "dialogues/TextPrompt.h" +#include "simulation/SaveRenderer.h" #include "interface/Point.h" #include "interface/Window.h" #include "search/Thumbnail.h" @@ -163,6 +164,9 @@ void PreviewView::OnMouseDown(int x, int y, unsigned button) void PreviewView::NotifySaveChanged(PreviewModel * sender) { SaveInfo * save = sender->GetSave(); + if(savePreview) + delete savePreview; + savePreview = NULL; if(save) { votesUp = save->votesUp; @@ -174,6 +178,24 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender) favButton->Enabled = false; else 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 { @@ -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)) { int newSizeX, newSizeY; @@ -243,7 +265,7 @@ void PreviewView::NotifyPreviewChanged(PreviewModel * sender) savePreview->Size.X *= scaleFactor; savePreview->Size.Y *= scaleFactor; } -} +}*/ PreviewView::~PreviewView() { } diff --git a/src/preview/PreviewView.h b/src/preview/PreviewView.h index ca2e01b1a..a0e7c2071 100644 --- a/src/preview/PreviewView.h +++ b/src/preview/PreviewView.h @@ -36,7 +36,6 @@ class PreviewView: public ui::Window { public: void AttachController(PreviewController * controller) { c = controller;} PreviewView(); - void NotifyPreviewChanged(PreviewModel * sender); void NotifySaveChanged(PreviewModel * sender); void NotifyCommentsChanged(PreviewModel * sender); virtual void OnDraw(); diff --git a/src/simulation/SaveRenderer.cpp b/src/simulation/SaveRenderer.cpp index 1837156fd..50df27854 100644 --- a/src/simulation/SaveRenderer.cpp +++ b/src/simulation/SaveRenderer.cpp @@ -22,8 +22,8 @@ Thumbnail * SaveRenderer::Render(GameSave * save) { Thumbnail * tempThumb = NULL; int width, height; - width = save->width/CELL; - height = save->height/CELL; + width = save->blockWidth; + height = save->blockHeight; pixel * pData = NULL; pixel * dst; diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 063b880f6..5f8e963d8 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -17,31 +17,48 @@ int Simulation::Load(GameSave * 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]; - parts[i].x += (float)x; - parts[i].y += (float)y; + if (pfree == -1) + break; + 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; for(int i = 0; i < save->signs.size() && signs.size() < MAXSIGNS; i++) { sign tempSign = save->signs[i]; - tempSign.x += x; - tempSign.y += y; + tempSign.x += fullX; + tempSign.y += fullY; 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]; - fvx[blockY+(y/CELL)][blockX+(x/CELL)] = save->fanVelX[blockY][blockX]; - fvy[blockY+(y/CELL)][blockX+(x/CELL)] = save->fanVelY[blockY][blockX]; + bmap[saveBlockY+blockY][saveBlockX+blockX] = save->blockMap[saveBlockY][saveBlockX]; + fvx[saveBlockY+blockY][saveBlockX+blockX] = save->fanVelX[saveBlockY][saveBlockX]; + fvy[saveBlockY+blockY][saveBlockX+blockX] = save->fanVelY[saveBlockY][saveBlockX]; } } } @@ -53,35 +70,82 @@ GameSave * Simulation::Save() 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++) { int x, y; x = int(parts[i].x + 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]; - tempPart.x -= x1; - tempPart.y -= y1; + tempPart.x -= fullX; + tempPart.y -= fullY; *newSave << tempPart; } } 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]; - tempSign.x -= x1; - tempSign.y -= y1; + tempSign.x -= fullX; + tempSign.y -= fullY; *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; }