28
28
#include " zip.h"
29
29
#include " unzip.h"
30
30
31
+ #include " fmem.h"
32
+
31
33
using namespace RTE ;
32
34
33
35
ActivityMan::ActivityMan () {
@@ -109,13 +111,6 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
109
111
modifiableScene->GetTerrain ()->SetPresetName (fileName);
110
112
modifiableScene->GetTerrain ()->MigrateToModule (g_PresetMan.GetModuleID (c_UserScriptedSavesModuleName));
111
113
112
- // Create zip sav file
113
- zipFile zippedSaveFile = zipOpen ((g_PresetMan.GetFullModulePath (c_UserScriptedSavesModuleName) + " /" + fileName + " .ccsave" ).c_str (), APPEND_STATUS_CREATE);
114
- if (!zippedSaveFile) {
115
- g_ConsoleMan.PrintString (" ERROR: Couldn't create zip save file!" );
116
- return false ;
117
- }
118
-
119
114
std::unique_ptr<std::stringstream> iniStream = std::make_unique<std::stringstream>();
120
115
121
116
// Block the main thread for a bit to let the Writer access the relevant data.
@@ -137,9 +132,11 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
137
132
writer->NewPropertyWithValue (" Scene" , modifiableScene.get ());
138
133
139
134
// Get BITMAPS so save into our zip
140
- std::vector<SceneLayerInfo> sceneLayerInfos = scene->GetCopiedSceneLayerBitmaps ();
135
+ // I tired std::moving this into the function directly but threadpool really doesn't like that
136
+ std::vector<SceneLayerInfo>* sceneLayerInfos = new std::vector<SceneLayerInfo>();
137
+ *sceneLayerInfos = std::move (scene->GetCopiedSceneLayerBitmaps ());
141
138
142
- auto saveWriterData = [& ](Writer* writerToSave, std::vector<SceneLayerInfo>&& sceneLayerInfos ) {
139
+ auto saveWriterData = [fileName, sceneLayerInfos ](Writer* writerToSave) {
143
140
std::stringstream* stream = static_cast <std::stringstream*>(writerToSave->GetStream ());
144
141
stream->flush ();
145
142
@@ -148,6 +145,13 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
148
145
149
146
zip_fileinfo zfi = {0 };
150
147
148
+ // Create zip sav file
149
+ zipFile zippedSaveFile = zipOpen ((g_PresetMan.GetFullModulePath (c_UserScriptedSavesModuleName) + " /" + fileName + " .ccsave" ).c_str (), APPEND_STATUS_CREATE);
150
+ if (!zippedSaveFile) {
151
+ g_ConsoleMan.PrintString (" ERROR: Couldn't create zip save file!" );
152
+ return ;
153
+ }
154
+
151
155
const int defaultCompression = 6 ;
152
156
zipOpenNewFileInZip (zippedSaveFile, (fileName + " .ini" ).c_str (), &zfi, nullptr , 0 , nullptr , 0 , nullptr , Z_DEFLATED, defaultCompression);
153
157
zipWriteInFileInZip (zippedSaveFile, streamAsString.data (), streamAsString.size ());
@@ -156,22 +160,38 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
156
160
PALETTE palette;
157
161
get_palette (palette);
158
162
159
- for (const SceneLayerInfo& layerInfo : sceneLayerInfos)
163
+ for (const SceneLayerInfo& layerInfo : * sceneLayerInfos)
160
164
{
161
- // Allego lacks the fucking ability to save/load png from a byte stream
162
- // AAAAAAAAAAAAAAAAAAAAAAAAAAA
163
- // zipOpenNewFileInZip(zippedSaveFile, (fileName + " " + layerInfo.name + ".png").c_str(), &zfi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, defaultCompression);
164
- // zipWriteInFileInZip(zippedSaveFile, streamAsString.data(), streamAsString.size());
165
- // zipCloseFileInZip(zippedSaveFile);
165
+ // A bit of a finicky workaround, but to save a png to memory we create a memory stream and send that into allegro to save into
166
+ fmem memStructure;
167
+ fmem_init (&memStructure);
168
+
169
+ // Save the png to our memory stream
170
+ FILE* stream = fmem_open (&memStructure, " w" );
171
+ save_stream_png (stream, layerInfo.bitmap .get (), palette);
172
+ fflush (stream);
173
+
174
+ // Actually get the memory
175
+ void * buffer;
176
+ size_t size;
177
+ fmem_mem (&memStructure, &buffer, &size);
178
+
179
+ zipOpenNewFileInZip (zippedSaveFile, (fileName + " " + layerInfo.name + " .png" ).c_str (), &zfi, nullptr , 0 , nullptr , 0 , nullptr , Z_DEFLATED, defaultCompression);
180
+ zipWriteInFileInZip (zippedSaveFile, static_cast <const char *>(buffer), size);
181
+ zipCloseFileInZip (zippedSaveFile);
182
+
183
+ fclose (stream);
184
+ fmem_term (&memStructure);
166
185
}
167
186
168
187
zipClose (zippedSaveFile, fileName.c_str ());
169
188
170
189
delete writerToSave;
190
+ delete sceneLayerInfos;
171
191
};
172
192
173
193
// For some reason I can't std::move a unique ptr in, so just releasing and deleting manually...
174
- m_SaveGameTask.push_back (g_ThreadMan.GetBackgroundThreadPool ().submit (saveWriterData, writer.release (), std::move (sceneLayerInfos) ));
194
+ m_SaveGameTask.push_back (g_ThreadMan.GetBackgroundThreadPool ().submit (saveWriterData, writer.release ()));
175
195
176
196
// We didn't transfer ownership, so we must be very careful that sceneAltered's deletion doesn't touch the stuff we got from MovableMan.
177
197
modifiableScene->ClearPlacedObjectSet (Scene::PlacedObjectSets::PLACEONLOAD, false );
0 commit comments