Remove return value from Simulation::Load

Not useful anymore, it can only fail if the GameSave passed in is nullptr, which this commit guards against.

Also make Simulation::Load and Simulation::Save take block-oriented positions and rects.
This commit is contained in:
Tamás Bálint Misius 2023-05-13 13:18:12 +02:00
parent ee87f0a0a7
commit 7ef02a6c0b
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
8 changed files with 94 additions and 138 deletions

View File

@ -44,7 +44,7 @@ int main(int argc, char *argv[])
if (gameSave)
{
sim->Load(gameSave.get(), true);
sim->Load(gameSave.get(), true, { 0, 0 });
//Render save
ren->decorations_enable = true;

View File

@ -242,11 +242,9 @@ void GameController::PlaceSave(ui::Point position)
if (placeSave)
{
HistorySnapshot();
if (!gameModel->GetSimulation()->Load(placeSave, !gameView->ShiftBehaviour(), position.X, position.Y))
{
gameModel->SetPaused(placeSave->paused | gameModel->GetPaused());
Client::Ref().MergeStampAuthorInfo(placeSave->authors);
}
gameModel->GetSimulation()->Load(placeSave, !gameView->ShiftBehaviour(), position);
gameModel->SetPaused(placeSave->paused | gameModel->GetPaused());
Client::Ref().MergeStampAuthorInfo(placeSave->authors);
}
gameModel->SetPlaceSave(nullptr);
}
@ -436,9 +434,20 @@ void GameController::ToolClick(int toolSelection, ui::Point point)
activeTool->Click(sim, cBrush, point);
}
static Rect<int> SaneSaveRect(Vec2<int> point1, Vec2<int> point2)
{
point1 = point1.Clamp(RES.OriginRect());
point2 = point2.Clamp(RES.OriginRect());
auto tlx = std::min(point1.X, point2.X);
auto tly = std::min(point1.Y, point2.Y);
auto brx = std::max(point1.X, point2.X);
auto bry = std::max(point1.Y, point2.Y);
return RectBetween(Vec2{ tlx, tly } / CELL, Vec2{ brx, bry } / CELL);
}
ByteString GameController::StampRegion(ui::Point point1, ui::Point point2)
{
auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y);
auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), SaneSaveRect(point1, point2));
if(newSave)
{
newSave->paused = gameModel->GetPaused();
@ -456,7 +465,7 @@ ByteString GameController::StampRegion(ui::Point point1, ui::Point point2)
void GameController::CopyRegion(ui::Point point1, ui::Point point2)
{
auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), point1.X, point1.Y, point2.X, point2.Y);
auto newSave = gameModel->GetSimulation()->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), SaneSaveRect(point1, point2));
if(newSave)
{
Json::Value clipboardInfo;
@ -1137,7 +1146,7 @@ void GameController::OpenSearch(String searchText)
void GameController::OpenLocalSaveWindow(bool asCurrent)
{
Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour());
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave)
{
new ErrorMessage("Error", "Unable to build save.");
@ -1348,7 +1357,7 @@ void GameController::OpenSaveWindow()
if(gameModel->GetUser().UserID)
{
Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour());
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave)
{
new ErrorMessage("Error", "Unable to build save.");
@ -1390,7 +1399,7 @@ void GameController::SaveAsCurrent()
if(gameModel->GetSave() && gameModel->GetUser().UserID && gameModel->GetUser().Username == gameModel->GetSave()->GetUserName())
{
Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour());
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave)
{
new ErrorMessage("Error", "Unable to build save.");

View File

@ -975,32 +975,30 @@ void GameModel::SetSave(std::unique_ptr<SaveInfo> newSave, bool invertIncludePre
SaveToSimParameters(*saveData);
sim->clear_sim();
ren->ClearAccumulation();
if (!sim->Load(saveData, !invertIncludePressure))
sim->Load(saveData, !invertIncludePressure, { 0, 0 });
// This save was created before logging existed
// Add in the correct info
if (saveData->authors.size() == 0)
{
// This save was created before logging existed
// Add in the correct info
if (saveData->authors.size() == 0)
{
auto gameSave = currentSave->TakeGameSave();
gameSave->authors["type"] = "save";
gameSave->authors["id"] = currentSave->id;
gameSave->authors["username"] = currentSave->userName;
gameSave->authors["title"] = currentSave->name.ToUtf8();
gameSave->authors["description"] = currentSave->Description.ToUtf8();
gameSave->authors["published"] = (int)currentSave->Published;
gameSave->authors["date"] = currentSave->updatedDate;
currentSave->SetGameSave(std::move(gameSave));
}
// This save was probably just created, and we didn't know the ID when creating it
// Update with the proper ID
else if (saveData->authors.get("id", -1) == 0 || saveData->authors.get("id", -1) == -1)
{
auto gameSave = currentSave->TakeGameSave();
gameSave->authors["id"] = currentSave->id;
currentSave->SetGameSave(std::move(gameSave));
}
Client::Ref().OverwriteAuthorInfo(saveData->authors);
auto gameSave = currentSave->TakeGameSave();
gameSave->authors["type"] = "save";
gameSave->authors["id"] = currentSave->id;
gameSave->authors["username"] = currentSave->userName;
gameSave->authors["title"] = currentSave->name.ToUtf8();
gameSave->authors["description"] = currentSave->Description.ToUtf8();
gameSave->authors["published"] = (int)currentSave->Published;
gameSave->authors["date"] = currentSave->updatedDate;
currentSave->SetGameSave(std::move(gameSave));
}
// This save was probably just created, and we didn't know the ID when creating it
// Update with the proper ID
else if (saveData->authors.get("id", -1) == 0 || saveData->authors.get("id", -1) == -1)
{
auto gameSave = currentSave->TakeGameSave();
gameSave->authors["id"] = currentSave->id;
currentSave->SetGameSave(std::move(gameSave));
}
Client::Ref().OverwriteAuthorInfo(saveData->authors);
}
notifySaveChanged();
UpdateQuickOptions();
@ -1028,10 +1026,8 @@ void GameModel::SetSaveFile(std::unique_ptr<SaveFile> newSave, bool invertInclud
SaveToSimParameters(*saveData);
sim->clear_sim();
ren->ClearAccumulation();
if (!sim->Load(saveData, !invertIncludePressure))
{
Client::Ref().OverwriteAuthorInfo(saveData->authors);
}
sim->Load(saveData, !invertIncludePressure, { 0, 0 });
Client::Ref().OverwriteAuthorInfo(saveData->authors);
}
notifySaveChanged();

View File

@ -1199,9 +1199,7 @@ void GameView::OnMouseUp(int x, int y, unsigned button)
{
if (placeSaveThumb && y <= WINDOWH-BARSIZE)
{
auto thumb = selectPoint2 + placeSaveOffset;
thumb = thumb.Clamp(RectBetween(Vec2<int>::Zero, RES - placeSaveThumb->Size()));
c->PlaceSave(thumb);
c->PlaceSave((selectPoint2 / CELL + placeSaveOffset).Clamp((CELLS - placeSaveThumb->Size() / CELL).OriginRect()));
}
}
else
@ -1954,10 +1952,10 @@ void GameView::NotifyTransformedPlaceSaveChanged(GameModel *sender)
placeSaveThumb = SaveRenderer::Ref().Render(sender->GetTransformedPlaceSave(), true, true, sender->GetRenderer());
auto [ quoX, remX ] = floorDiv(placeSaveTranslate.X, CELL);
auto [ quoY, remY ] = floorDiv(placeSaveTranslate.Y, CELL);
placeSaveOffset = Vec2{ quoX, quoY } * CELL;
auto usefulSize = placeSaveThumb->Size();
if (remX) usefulSize.X -= CELL;
if (remY) usefulSize.Y -= CELL;
placeSaveOffset = Vec2{ quoX, quoY };
auto usefulSize = placeSaveThumb->Size() / CELL;
if (remX) usefulSize.X -= 1;
if (remY) usefulSize.Y -= 1;
placeSaveOffset -= usefulSize / 2;
selectMode = PlaceSave;
selectPoint2 = mousePosition;
@ -2174,7 +2172,7 @@ void GameView::OnDraw()
{
if(placeSaveThumb && selectPoint2.X!=-1)
{
auto thumb = selectPoint2 + placeSaveOffset + Vec2(1, 1) * CELL / 2;
auto thumb = selectPoint2 + placeSaveOffset * CELL + Vec2(1, 1) * CELL / 2;
thumb = c->NormaliseBlockCoord(thumb).Clamp(RectBetween(Vec2<int>::Zero, RES - placeSaveThumb->Size()));
auto rect = RectSized(thumb, placeSaveThumb->Size());
ren->BlendImage(placeSaveThumb->Data(), 0x80, rect);

View File

@ -1967,8 +1967,8 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l)
int i = -1;
int pushed = 1;
std::unique_ptr<SaveFile> tempfile;
int x = luaL_optint(l,2,0);
int y = luaL_optint(l,3,0);
int x = luaL_optint(l,2,0) / CELL;
int y = luaL_optint(l,3,0) / CELL;
auto &client = Client::Ref();
if (lua_isstring(l, 1)) //Load from 10 char name, or full filename
{
@ -1984,33 +1984,24 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l)
tempfile = client.GetStamp(stampIDs[i]);
}
if (tempfile)
if (tempfile && tempfile->GetGameSave())
{
if (!luacon_sim->Load(tempfile->GetGameSave(), !luacon_controller->GetView()->ShiftBehaviour(), x, y))
{
//luacon_sim->sys_pause = (tempfile->GetGameSave()->paused | luacon_model->GetPaused())?1:0;
lua_pushinteger(l, 1);
// TODO: maybe do a gameSave->Transform with a new transform argument for the lua function and the "low" [0, CELL) part of x, y
auto gameSave = tempfile->TakeGameSave();
luacon_sim->Load(gameSave.get(), !luacon_controller->GetView()->ShiftBehaviour(), { x, y });
lua_pushinteger(l, 1);
if (tempfile->GetGameSave()->authors.size())
{
auto gameSave = tempfile->TakeGameSave();
gameSave->authors["type"] = "luastamp";
client.MergeStampAuthorInfo(gameSave->authors);
tempfile->SetGameSave(std::move(gameSave));
}
}
else
if (gameSave->authors.size())
{
pushed = 2;
lua_pushnil(l);
tpt_lua_pushString(l, luacon_ci->GetLastError());
gameSave->authors["type"] = "luastamp";
client.MergeStampAuthorInfo(gameSave->authors);
}
}
else
{
pushed = 2;
lua_pushnil(l);
lua_pushliteral(l, "Failed to read file");
tpt_lua_pushString(l, luacon_ci->GetLastError());
}
return pushed;
}

View File

@ -36,32 +36,30 @@ std::unique_ptr<VideoBuffer> SaveRenderer::Render(const GameSave *save, bool dec
sim->clear_sim();
if(!sim->Load(save, true))
sim->Load(save, true, { 0, 0 });
ren->decorations_enable = true;
ren->blackDecorations = !decorations;
ren->ClearAccumulation();
ren->clearScreen();
if (fire)
{
ren->decorations_enable = true;
ren->blackDecorations = !decorations;
ren->ClearAccumulation();
ren->clearScreen();
if (fire)
int frame = 15;
while(frame)
{
int frame = 15;
while(frame)
{
frame--;
ren->render_parts();
ren->render_fire();
ren->clearScreen();
}
frame--;
ren->render_parts();
ren->render_fire();
ren->clearScreen();
}
ren->RenderBegin();
ren->RenderEnd();
tempThumb = std::make_unique<VideoBuffer>(save->blockSize * CELL);
tempThumb->BlendImage(ren->Data(), 0xFF, ren->Size().OriginRect());
}
ren->RenderBegin();
ren->RenderEnd();
tempThumb = std::make_unique<VideoBuffer>(save->blockSize * CELL);
tempThumb->BlendImage(ren->Data(), 0xFF, ren->Size().OriginRect());
return tempThumb;
}

View File

@ -19,21 +19,11 @@ extern int Element_LOLZ_lolz[XRES/9][YRES/9];
extern int Element_LOVE_RuleTable[9][9];
extern int Element_LOVE_love[XRES/9][YRES/9];
int Simulation::Load(const GameSave * save, bool includePressure)
void Simulation::Load(const GameSave *originalSave, bool includePressure, Vec2<int> blockP)
{
return Load(save, includePressure, 0, 0);
}
int Simulation::Load(const GameSave * originalSave, bool includePressure, int fullX, int fullY)
{
if (!originalSave)
return 1;
auto save = std::unique_ptr<GameSave>(new GameSave(*originalSave));
//Align to blockMap
auto blockP = Vec2{ (fullX + CELL / 2) / CELL, (fullY + CELL / 2) / CELL };
fullX = blockP.X * CELL;
fullY = blockP.Y * CELL;
auto partP = blockP * CELL;
unsigned int pmapmask = (1<<save->pmapbits)-1;
int partMap[PT_NUM];
@ -71,8 +61,8 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
for (int n = 0; n < NPART && n < save->particlesCount; n++)
{
Particle *tempPart = &save->particles[n];
tempPart->x += (float)fullX;
tempPart->y += (float)fullY;
tempPart->x += (float)partP.X;
tempPart->y += (float)partP.Y;
int x = int(tempPart->x + 0.5f);
int y = int(tempPart->y + 0.5f);
@ -307,8 +297,8 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
if (save->signs[i].text[0])
{
sign tempSign = save->signs[i];
tempSign.x += fullX;
tempSign.y += fullY;
tempSign.x += partP.X;
tempSign.y += partP.Y;
signs.push_back(tempSign);
}
}
@ -343,38 +333,14 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
{
air->ApproximateBlockAirMaps();
}
return 0;
}
std::unique_ptr<GameSave> Simulation::Save(bool includePressure)
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, Rect<int> blockR)
{
return Save(includePressure, 0, 0, XRES-1, YRES-1);
}
auto blockP = blockR.TopLeft;
auto partR = RectSized(blockR.TopLeft * CELL, blockR.Size() * CELL);
std::unique_ptr<GameSave> Simulation::Save(bool includePressure, int fullX, int fullY, int fullX2, int fullY2)
{
//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
auto blockP = Vec2{ fullX / CELL, fullY / CELL };
auto blockP2 = Vec2{ (fullX2 + CELL) / CELL, (fullY2 + CELL) / CELL };
auto blockS = blockP2 - blockP;
auto newSave = std::make_unique<GameSave>(blockS);
auto newSave = std::make_unique<GameSave>(blockR.Size());
auto &possiblyCarriesType = Particle::PossiblyCarriesType();
auto &properties = Particle::GetProperties();
newSave->frameCount = frameCount;
@ -392,7 +358,7 @@ std::unique_ptr<GameSave> Simulation::Save(bool includePressure, int fullX, int
int x, y;
x = int(parts[i].x + 0.5f);
y = int(parts[i].y + 0.5f);
if (parts[i].type && x >= fullX && y >= fullY && x <= fullX2 && y <= fullY2)
if (parts[i].type && partR.Contains({ x, y }))
{
Particle tempPart = parts[i];
tempPart.x -= blockP.X * CELL;
@ -456,7 +422,7 @@ std::unique_ptr<GameSave> Simulation::Save(bool includePressure, int fullX, int
for (size_t i = 0; i < MAXSIGNS && i < signs.size(); i++)
{
if(signs[i].text.length() && signs[i].x >= fullX && signs[i].y >= fullY && signs[i].x <= fullX2 && signs[i].y <= fullY2)
if (signs[i].text.length() && partR.Contains({ signs[i].x, signs[i].y }))
{
sign tempSign = signs[i];
tempSign.x -= blockP.X * CELL;

View File

@ -121,10 +121,8 @@ public:
uint64_t frameCount;
bool ensureDeterminism;
int Load(const GameSave * save, bool includePressure);
int Load(const GameSave * save, bool includePressure, int x, int y);
std::unique_ptr<GameSave> Save(bool includePressure);
std::unique_ptr<GameSave> Save(bool includePressure, int x1, int y1, int x2, int y2);
void Load(const GameSave *save, bool includePressure, Vec2<int> blockP);
std::unique_ptr<GameSave> Save(bool includePressure, Rect<int> blockR);
void SaveSimOptions(GameSave &gameSave);
SimulationSample GetSample(int x, int y);