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) if (gameSave)
{ {
sim->Load(gameSave.get(), true); sim->Load(gameSave.get(), true, { 0, 0 });
//Render save //Render save
ren->decorations_enable = true; ren->decorations_enable = true;

View File

@ -242,11 +242,9 @@ void GameController::PlaceSave(ui::Point position)
if (placeSave) if (placeSave)
{ {
HistorySnapshot(); HistorySnapshot();
if (!gameModel->GetSimulation()->Load(placeSave, !gameView->ShiftBehaviour(), position.X, position.Y)) gameModel->GetSimulation()->Load(placeSave, !gameView->ShiftBehaviour(), position);
{ gameModel->SetPaused(placeSave->paused | gameModel->GetPaused());
gameModel->SetPaused(placeSave->paused | gameModel->GetPaused()); Client::Ref().MergeStampAuthorInfo(placeSave->authors);
Client::Ref().MergeStampAuthorInfo(placeSave->authors);
}
} }
gameModel->SetPlaceSave(nullptr); gameModel->SetPlaceSave(nullptr);
} }
@ -436,9 +434,20 @@ void GameController::ToolClick(int toolSelection, ui::Point point)
activeTool->Click(sim, cBrush, 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) 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) if(newSave)
{ {
newSave->paused = gameModel->GetPaused(); 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) 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) if(newSave)
{ {
Json::Value clipboardInfo; Json::Value clipboardInfo;
@ -1137,7 +1146,7 @@ void GameController::OpenSearch(String searchText)
void GameController::OpenLocalSaveWindow(bool asCurrent) void GameController::OpenLocalSaveWindow(bool asCurrent)
{ {
Simulation * sim = gameModel->GetSimulation(); Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave) if(!gameSave)
{ {
new ErrorMessage("Error", "Unable to build save."); new ErrorMessage("Error", "Unable to build save.");
@ -1348,7 +1357,7 @@ void GameController::OpenSaveWindow()
if(gameModel->GetUser().UserID) if(gameModel->GetUser().UserID)
{ {
Simulation * sim = gameModel->GetSimulation(); Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave) if(!gameSave)
{ {
new ErrorMessage("Error", "Unable to build save."); 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()) if(gameModel->GetSave() && gameModel->GetUser().UserID && gameModel->GetUser().Username == gameModel->GetSave()->GetUserName())
{ {
Simulation * sim = gameModel->GetSimulation(); Simulation * sim = gameModel->GetSimulation();
auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour()); auto gameSave = sim->Save(gameModel->GetIncludePressure() != gameView->ShiftBehaviour(), CELLS.OriginRect());
if(!gameSave) if(!gameSave)
{ {
new ErrorMessage("Error", "Unable to build save."); 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); SaveToSimParameters(*saveData);
sim->clear_sim(); sim->clear_sim();
ren->ClearAccumulation(); 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 auto gameSave = currentSave->TakeGameSave();
// Add in the correct info gameSave->authors["type"] = "save";
if (saveData->authors.size() == 0) gameSave->authors["id"] = currentSave->id;
{ gameSave->authors["username"] = currentSave->userName;
auto gameSave = currentSave->TakeGameSave(); gameSave->authors["title"] = currentSave->name.ToUtf8();
gameSave->authors["type"] = "save"; gameSave->authors["description"] = currentSave->Description.ToUtf8();
gameSave->authors["id"] = currentSave->id; gameSave->authors["published"] = (int)currentSave->Published;
gameSave->authors["username"] = currentSave->userName; gameSave->authors["date"] = currentSave->updatedDate;
gameSave->authors["title"] = currentSave->name.ToUtf8(); currentSave->SetGameSave(std::move(gameSave));
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);
} }
// 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(); notifySaveChanged();
UpdateQuickOptions(); UpdateQuickOptions();
@ -1028,10 +1026,8 @@ void GameModel::SetSaveFile(std::unique_ptr<SaveFile> newSave, bool invertInclud
SaveToSimParameters(*saveData); SaveToSimParameters(*saveData);
sim->clear_sim(); sim->clear_sim();
ren->ClearAccumulation(); ren->ClearAccumulation();
if (!sim->Load(saveData, !invertIncludePressure)) sim->Load(saveData, !invertIncludePressure, { 0, 0 });
{ Client::Ref().OverwriteAuthorInfo(saveData->authors);
Client::Ref().OverwriteAuthorInfo(saveData->authors);
}
} }
notifySaveChanged(); notifySaveChanged();

View File

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

View File

@ -1967,8 +1967,8 @@ int LuaScriptInterface::simulation_loadStamp(lua_State * l)
int i = -1; int i = -1;
int pushed = 1; int pushed = 1;
std::unique_ptr<SaveFile> tempfile; std::unique_ptr<SaveFile> tempfile;
int x = luaL_optint(l,2,0); int x = luaL_optint(l,2,0) / CELL;
int y = luaL_optint(l,3,0); int y = luaL_optint(l,3,0) / CELL;
auto &client = Client::Ref(); auto &client = Client::Ref();
if (lua_isstring(l, 1)) //Load from 10 char name, or full filename 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]); tempfile = client.GetStamp(stampIDs[i]);
} }
if (tempfile) if (tempfile && tempfile->GetGameSave())
{ {
if (!luacon_sim->Load(tempfile->GetGameSave(), !luacon_controller->GetView()->ShiftBehaviour(), x, y)) // 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->sys_pause = (tempfile->GetGameSave()->paused | luacon_model->GetPaused())?1:0; luacon_sim->Load(gameSave.get(), !luacon_controller->GetView()->ShiftBehaviour(), { x, y });
lua_pushinteger(l, 1); lua_pushinteger(l, 1);
if (tempfile->GetGameSave()->authors.size()) if (gameSave->authors.size())
{
auto gameSave = tempfile->TakeGameSave();
gameSave->authors["type"] = "luastamp";
client.MergeStampAuthorInfo(gameSave->authors);
tempfile->SetGameSave(std::move(gameSave));
}
}
else
{ {
pushed = 2; gameSave->authors["type"] = "luastamp";
lua_pushnil(l); client.MergeStampAuthorInfo(gameSave->authors);
tpt_lua_pushString(l, luacon_ci->GetLastError());
} }
} }
else else
{ {
pushed = 2; pushed = 2;
lua_pushnil(l); lua_pushnil(l);
lua_pushliteral(l, "Failed to read file"); tpt_lua_pushString(l, luacon_ci->GetLastError());
} }
return pushed; return pushed;
} }

View File

@ -36,32 +36,30 @@ std::unique_ptr<VideoBuffer> SaveRenderer::Render(const GameSave *save, bool dec
sim->clear_sim(); 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; int frame = 15;
ren->blackDecorations = !decorations; while(frame)
ren->ClearAccumulation();
ren->clearScreen();
if (fire)
{ {
int frame = 15; frame--;
while(frame) ren->render_parts();
{ ren->render_fire();
frame--; ren->clearScreen();
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; 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_RuleTable[9][9];
extern int Element_LOVE_love[XRES/9][YRES/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)); auto save = std::unique_ptr<GameSave>(new GameSave(*originalSave));
//Align to blockMap auto partP = blockP * CELL;
auto blockP = Vec2{ (fullX + CELL / 2) / CELL, (fullY + CELL / 2) / CELL };
fullX = blockP.X * CELL;
fullY = blockP.Y * CELL;
unsigned int pmapmask = (1<<save->pmapbits)-1; unsigned int pmapmask = (1<<save->pmapbits)-1;
int partMap[PT_NUM]; 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++) for (int n = 0; n < NPART && n < save->particlesCount; n++)
{ {
Particle *tempPart = &save->particles[n]; Particle *tempPart = &save->particles[n];
tempPart->x += (float)fullX; tempPart->x += (float)partP.X;
tempPart->y += (float)fullY; tempPart->y += (float)partP.Y;
int x = int(tempPart->x + 0.5f); int x = int(tempPart->x + 0.5f);
int y = int(tempPart->y + 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]) if (save->signs[i].text[0])
{ {
sign tempSign = save->signs[i]; sign tempSign = save->signs[i];
tempSign.x += fullX; tempSign.x += partP.X;
tempSign.y += fullY; tempSign.y += partP.Y;
signs.push_back(tempSign); signs.push_back(tempSign);
} }
} }
@ -343,38 +333,14 @@ int Simulation::Load(const GameSave * originalSave, bool includePressure, int fu
{ {
air->ApproximateBlockAirMaps(); 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) auto newSave = std::make_unique<GameSave>(blockR.Size());
{
//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 &possiblyCarriesType = Particle::PossiblyCarriesType(); auto &possiblyCarriesType = Particle::PossiblyCarriesType();
auto &properties = Particle::GetProperties(); auto &properties = Particle::GetProperties();
newSave->frameCount = frameCount; newSave->frameCount = frameCount;
@ -392,7 +358,7 @@ std::unique_ptr<GameSave> Simulation::Save(bool includePressure, int fullX, int
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 >= fullX && y >= fullY && x <= fullX2 && y <= fullY2) if (parts[i].type && partR.Contains({ x, y }))
{ {
Particle tempPart = parts[i]; Particle tempPart = parts[i];
tempPart.x -= blockP.X * CELL; 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++) 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]; sign tempSign = signs[i];
tempSign.x -= blockP.X * CELL; tempSign.x -= blockP.X * CELL;

View File

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