|
28 | 28 | #include "zip.h"
|
29 | 29 | #include "unzip.h"
|
30 | 30 |
|
31 |
| -#include "fmem.h" |
| 31 | +#include "SDL3/SDL_surface.h" |
| 32 | +#include <SDL3_image/SDL_image.h> |
32 | 33 |
|
33 | 34 | using namespace RTE;
|
34 | 35 |
|
@@ -150,26 +151,37 @@ bool ActivityMan::SaveCurrentGame(const std::string& fileName) {
|
150 | 151 |
|
151 | 152 | for (const SceneLayerInfo& layerInfo : *sceneLayerInfos)
|
152 | 153 | {
|
153 |
| - // 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 |
154 |
| - fmem memStructure; |
155 |
| - fmem_init(&memStructure); |
| 154 | + // Save png into a memory buffer |
| 155 | + SDL_IOStream* stream = SDL_IOFromDynamicMem(); |
| 156 | + SDL_Surface* image = SDL_CreateSurfaceFrom(layerInfo.bitmap->w, layerInfo.bitmap->h, SDL_PIXELFORMAT_INDEX8, layerInfo.bitmap->dat, layerInfo.bitmap->w); |
156 | 157 |
|
157 |
| - // Save the png to our memory stream |
158 |
| - FILE* stream = fmem_open(&memStructure, "w"); |
159 |
| - save_stream_png(stream, layerInfo.bitmap.get(), palette); |
160 |
| - fflush(stream); |
| 158 | + SDL_Palette* palette = ContentFile::DefaultPaletteToSDL(); |
| 159 | + SDL_SetSurfacePalette(image, palette); |
| 160 | + |
| 161 | + bool result = IMG_SavePNG_IO(image, stream, false); |
| 162 | + SDL_FlushIO(stream); |
| 163 | + |
| 164 | + SDL_DestroyPalette(palette); |
| 165 | + SDL_DestroySurface(image); |
| 166 | + |
| 167 | + if (!result) { |
| 168 | + g_ConsoleMan.PrintString("ERROR: Failed to save scenelayers to PNG!"); |
| 169 | + continue; |
| 170 | + } |
161 | 171 |
|
162 | 172 | // Actually get the memory
|
163 |
| - void* buffer; |
164 |
| - size_t size; |
165 |
| - fmem_mem(&memStructure, &buffer, &size); |
| 173 | + void* buffer = SDL_GetPointerProperty(SDL_GetIOProperties(stream), SDL_PROP_IOSTREAM_DYNAMIC_MEMORY_POINTER, nullptr); |
| 174 | + size_t size = static_cast<size_t>(SDL_GetIOSize(stream)); |
| 175 | + if (!buffer || size < 0) { |
| 176 | + g_ConsoleMan.PrintString("ERROR: Failed to save scenelayers to PNG!"); |
| 177 | + continue; |
| 178 | + } |
166 | 179 |
|
167 | 180 | zipOpenNewFileInZip(zippedSaveFile, ("Save " + layerInfo.name + ".png").c_str(), &zfi, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, defaultCompression);
|
168 | 181 | zipWriteInFileInZip(zippedSaveFile, static_cast<const char*>(buffer), size);
|
169 | 182 | zipCloseFileInZip(zippedSaveFile);
|
170 | 183 |
|
171 |
| - fclose(stream); |
172 |
| - fmem_term(&memStructure); |
| 184 | + SDL_CloseIO(stream); |
173 | 185 | }
|
174 | 186 |
|
175 | 187 | zipClose(zippedSaveFile, fileName.c_str());
|
@@ -219,6 +231,30 @@ bool ActivityMan::LoadAndLaunchGame(const std::string& fileName) {
|
219 | 231 | unzCloseCurrentFile(zippedSaveFile);
|
220 | 232 | };
|
221 | 233 |
|
| 234 | + auto loadMemPngIntoBitmap = [](void* buffer, size_t size) { |
| 235 | + BITMAP* bitmap = nullptr; // just to help the compiler deduce the type, we can't early-return nullptr or it thiks we return std::nullptr_t |
| 236 | + |
| 237 | + SDL_IOStream* stream = SDL_IOFromConstMem(buffer, size); |
| 238 | + SDL_Surface* image = stream ? IMG_LoadPNG_IO(stream) : nullptr; |
| 239 | + if (!image) { |
| 240 | + return bitmap; |
| 241 | + } |
| 242 | + |
| 243 | + SDL_CloseIO(stream); |
| 244 | + |
| 245 | + bitmap = create_bitmap_ex(SDL_BITSPERPIXEL(image->format), image->w, image->h); |
| 246 | + |
| 247 | + // Allegro doesn't align lines, SDL does 4byte alignment |
| 248 | + for (int y = 0; y < image->h; y++) { |
| 249 | + memcpy(bitmap->line[y], |
| 250 | + static_cast<unsigned char*>(image->pixels) + image->pitch * y, |
| 251 | + image->w * SDL_BYTESPERPIXEL(image->format)); |
| 252 | + } |
| 253 | + |
| 254 | + SDL_DestroySurface(image); |
| 255 | + return bitmap; |
| 256 | + }; |
| 257 | + |
222 | 258 | unzipFileIntoBuffer("Save.ini");
|
223 | 259 |
|
224 | 260 | Reader reader(std::make_unique<std::istringstream>(buffer), filePath + "/Save.ini", true, nullptr, false);
|
@@ -253,20 +289,20 @@ bool ActivityMan::LoadAndLaunchGame(const std::string& fileName) {
|
253 | 289 | get_palette(palette);
|
254 | 290 |
|
255 | 291 | unzipFileIntoBuffer("Save Mat.png");
|
256 |
| - ContentFile::ManuallyLoadDataBitmap(filePath + "/Save Mat.png", load_memory_png(buffer, info.uncompressed_size, palette)); |
| 292 | + ContentFile::ManuallyLoadDataBitmap(filePath + "/Save Mat.png", loadMemPngIntoBitmap(buffer, info.uncompressed_size)); |
257 | 293 | free(buffer);
|
258 | 294 |
|
259 | 295 | unzipFileIntoBuffer("Save FG.png");
|
260 |
| - ContentFile::ManuallyLoadDataBitmap(filePath + "/Save FG.png", load_memory_png(buffer, info.uncompressed_size, palette)); |
| 296 | + ContentFile::ManuallyLoadDataBitmap(filePath + "/Save FG.png", loadMemPngIntoBitmap(buffer, info.uncompressed_size)); |
261 | 297 | free(buffer);
|
262 | 298 |
|
263 | 299 | unzipFileIntoBuffer("Save BG.png");
|
264 |
| - ContentFile::ManuallyLoadDataBitmap(filePath + "/Save BG.png", load_memory_png(buffer, info.uncompressed_size, palette)); |
| 300 | + ContentFile::ManuallyLoadDataBitmap(filePath + "/Save BG.png", loadMemPngIntoBitmap(buffer, info.uncompressed_size)); |
265 | 301 | free(buffer);
|
266 | 302 |
|
267 | 303 | for (int i = 0; i < numberOfTeams; ++i) {
|
268 | 304 | unzipFileIntoBuffer(std::format("Save UST%i.png", i));
|
269 |
| - ContentFile::ManuallyLoadDataBitmap(filePath + std::format("/Save UST%i", i), load_memory_png(buffer, info.uncompressed_size, palette)); |
| 305 | + ContentFile::ManuallyLoadDataBitmap(filePath + std::format("/Save UST%i", i), loadMemPngIntoBitmap(buffer, info.uncompressed_size)); |
270 | 306 | free(buffer);
|
271 | 307 | }
|
272 | 308 |
|
|
0 commit comments