diff --git a/src/files.cpp b/src/files.cpp index 0b72032361..6bf38274b9 100644 --- a/src/files.cpp +++ b/src/files.cpp @@ -600,3 +600,58 @@ char *MemoryArrayReader::Gets(char *strbuf, int len) { return GetsFromBuffer((char*)&buf[0], strbuf, len); } + +//========================================================================== +// +// FileWriter (the motivation here is to have a buffer writing subclass) +// +//========================================================================== + +bool FileWriter::OpenDirect(const char *filename) +{ + File = fopen(filename, "wb"); + return (File != NULL); +} + +FileWriter *FileWriter::Open(const char *filename) +{ + FileWriter *fwrit = new FileWriter(); + if (fwrit->OpenDirect(filename)) + { + return fwrit; + } + delete fwrit; + return NULL; +} + +size_t FileWriter::Write(const void *buffer, size_t len) +{ + if (File != NULL) + { + return fwrite(buffer, 1, len, File); + } + else + { + return 0; + } +} + + +size_t FileWriter::Printf(const char *fmt, ...) +{ + va_list ap; + FString out; + + va_start(ap, fmt); + out.VFormat(fmt, ap); + va_end(ap); + return Write(out.GetChars(), out.Len()); +} + +size_t BufferWriter::Write(const void *buffer, size_t len) +{ + unsigned int ofs = mBuffer.Reserve((unsigned)len); + memcpy(&mBuffer[ofs], buffer, len); + return len; +} + diff --git a/src/files.h b/src/files.h index 5889eb6fe7..4c12550c80 100644 --- a/src/files.h +++ b/src/files.h @@ -356,4 +356,46 @@ protected: }; +class FileWriter +{ +protected: + bool OpenDirect(const char *filename); + + FileWriter() + { + File = NULL; + } +public: + virtual ~FileWriter() + { + if (File != NULL) fclose(File); + } + + static FileWriter *Open(const char *filename); + + virtual size_t Write(const void *buffer, size_t len); + size_t Printf(const char *fmt, ...); + +protected: + + FILE *File; + +protected: + bool CloseOnDestruct; +}; + +class BufferWriter : public FileWriter +{ +protected: + TArray mBuffer; +public: + + BufferWriter() {} + virtual size_t Write(const void *buffer, size_t len) override; + TArray *GetBuffer() { return &mBuffer; } +}; + + + + #endif diff --git a/src/g_game.cpp b/src/g_game.cpp index 73293a15e9..a221d3a5a8 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1828,6 +1828,7 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn) void G_DoLoadGame () { +#if 0 // SAVEGAME char sigcheck[20]; char *text = NULL; char *map; @@ -1981,6 +1982,7 @@ void G_DoLoadGame () // amount of memory in use, so bring it down now by starting a // collection. GC::StartCollection(); +#endif } @@ -2102,6 +2104,7 @@ void G_DoAutoSave () static void PutSaveWads (FILE *file) { +#if 0 // SAVEGAME const char *name; // Name of IWAD @@ -2114,10 +2117,12 @@ static void PutSaveWads (FILE *file) name = Wads.GetWadName (Wads.GetLumpFile (level.lumpnum)); M_AppendPNGText (file, "Map WAD", name); } +#endif } static void PutSaveComment (FILE *file) { +#if 0 // SAVEGAME char comment[256]; const char *readableTime; WORD len; @@ -2147,9 +2152,10 @@ static void PutSaveComment (FILE *file) // Write out the comment M_AppendPNGText (file, "Comment", comment); +#endif } -static void PutSavePic (FILE *file, int width, int height) +static void PutSavePic (FileWriter *file, int width, int height) { if (width <= 0 || height <= 0 || !storesavepic) { @@ -2194,6 +2200,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio } SaveVersion = SAVEVER; +#if 0 // SAVEGAME PutSavePic (stdfile, SAVEPICWIDTH, SAVEPICHEIGHT); mysnprintf(buf, countof(buf), GAMENAME " %s", GetVersionString()); M_AppendPNGText (stdfile, "Software", buf); @@ -2249,7 +2256,9 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio } fclose(stdfile); } - if (success) +#endif + bool success = true; + if (success) { if (longsavemessages) Printf ("%s (%s)\n", GStrings("GGSAVED"), filename.GetChars()); else Printf ("%s\n", GStrings("GGSAVED")); diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 87f61f2539..a37c320946 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -449,10 +449,15 @@ struct pcx_t }; +inline void putc(char chr, FileWriter *file) +{ + file->Write(&chr, 1); +} + // // WritePCXfile // -void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette, +void WritePCXfile (FileWriter *file, const BYTE *buffer, const PalEntry *palette, ESSType color_type, int width, int height, int pitch) { BYTE temprow[MAXWIDTH * 3]; @@ -480,7 +485,7 @@ void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette, pcx.palette_type = 1; // not a grey scale memset (pcx.filler, 0, sizeof(pcx.filler)); - fwrite (&pcx, 128, 1, file); + file->Write(&pcx, 128); bytes_per_row_minus_one = ((color_type == SS_PAL) ? width : width * 3) - 1; @@ -593,7 +598,7 @@ void WritePCXfile (FILE *file, const BYTE *buffer, const PalEntry *palette, // // WritePNGfile // -void WritePNGfile (FILE *file, const BYTE *buffer, const PalEntry *palette, +void WritePNGfile (FileWriter *file, const BYTE *buffer, const PalEntry *palette, ESSType color_type, int width, int height, int pitch) { char software[100]; @@ -655,7 +660,7 @@ static bool FindFreeName (FString &fullname, const char *extension) void M_ScreenShot (const char *filename) { - FILE *file; + FileWriter *file; FString autoname; bool writepcx = (stricmp (screenshot_type, "pcx") == 0); // PNG is the default @@ -709,7 +714,7 @@ void M_ScreenShot (const char *filename) { screen->GetFlashedPalette(palette); } - file = fopen (autoname, "wb"); + file = FileWriter::Open(autoname); if (file == NULL) { Printf ("Could not open %s\n", autoname.GetChars()); @@ -726,7 +731,7 @@ void M_ScreenShot (const char *filename) WritePNGfile(file, buffer, palette, color_type, screen->GetWidth(), screen->GetHeight(), pitch); } - fclose(file); + delete file; screen->ReleaseScreenshotBuffer(); if (!screenshot_quiet) diff --git a/src/m_png.cpp b/src/m_png.cpp index 22a9a657d1..35cd8587e7 100644 --- a/src/m_png.cpp +++ b/src/m_png.cpp @@ -101,7 +101,7 @@ PNGHandle::~PNGHandle () static inline void MakeChunk (void *where, DWORD type, size_t len); static inline void StuffPalette (const PalEntry *from, BYTE *to); -static bool WriteIDAT (FILE *file, const BYTE *data, int len); +static bool WriteIDAT (FileWriter *file, const BYTE *data, int len); static void UnfilterRow (int width, BYTE *dest, BYTE *stream, BYTE *prev, int bpp); static void UnpackPixels (int width, int bytesPerRow, int bitdepth, const BYTE *rowin, BYTE *rowout, bool grayscale); @@ -131,7 +131,7 @@ CVAR(Float, png_gamma, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // //========================================================================== -bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette, +bool M_CreatePNG (FileWriter *file, const BYTE *buffer, const PalEntry *palette, ESSType color_type, int width, int height, int pitch) { BYTE work[8 + // signature @@ -171,7 +171,7 @@ bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette, work_len = sizeof(work) - (12+256*3); } - if (fwrite (work, 1, work_len, file) != work_len) + if (file->Write (work, work_len) != work_len) return false; return M_SaveBitmap (buffer, color_type, width, height, pitch, file); @@ -185,7 +185,7 @@ bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *palette, // //========================================================================== -bool M_CreateDummyPNG (FILE *file) +bool M_CreateDummyPNG (FileWriter *file) { static const BYTE dummyPNG[] = { @@ -195,7 +195,7 @@ bool M_CreateDummyPNG (FILE *file) 0,0,0,10,'I','D','A','T', 104,222,99,96,0,0,0,2,0,1,0x9f,0x65,0x0e,0x18 }; - return fwrite (dummyPNG, 1, sizeof(dummyPNG), file) == sizeof(dummyPNG); + return file->Write (dummyPNG, sizeof(dummyPNG)) == sizeof(dummyPNG); } @@ -207,10 +207,10 @@ bool M_CreateDummyPNG (FILE *file) // //========================================================================== -bool M_FinishPNG (FILE *file) +bool M_FinishPNG (FileWriter *file) { static const BYTE iend[12] = { 0,0,0,0,73,69,78,68,174,66,96,130 }; - return fwrite (iend, 1, 12, file) == 12; + return file->Write (iend, 12) == 12; } //========================================================================== @@ -221,13 +221,13 @@ bool M_FinishPNG (FILE *file) // //========================================================================== -bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD len) +bool M_AppendPNGChunk (FileWriter *file, DWORD chunkID, const BYTE *chunkData, DWORD len) { DWORD head[2] = { BigLong((unsigned int)len), chunkID }; DWORD crc; - if (fwrite (head, 1, 8, file) == 8 && - (len == 0 || fwrite (chunkData, 1, len, file) == len)) + if (file->Write (head, 8) == 8 && + (len == 0 || file->Write (chunkData, len) == len)) { crc = CalcCRC32 ((BYTE *)&head[1], 4); if (len != 0) @@ -235,7 +235,7 @@ bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD l crc = AddCRC32 (crc, chunkData, len); } crc = BigLong((unsigned int)crc); - return fwrite (&crc, 1, 4, file) == 4; + return file->Write (&crc, 4) == 4; } return false; } @@ -248,7 +248,7 @@ bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD l // //========================================================================== -bool M_AppendPNGText (FILE *file, const char *keyword, const char *text) +bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text) { struct { DWORD len, id; char key[80]; } head; int len = (int)strlen (text); @@ -261,8 +261,8 @@ bool M_AppendPNGText (FILE *file, const char *keyword, const char *text) strncpy (head.key, keyword, keylen); head.key[keylen] = 0; - if ((int)fwrite (&head, 1, keylen + 9, file) == keylen + 9 && - (int)fwrite (text, 1, len, file) == len) + if ((int)file->Write (&head, keylen + 9) == keylen + 9 && + (int)file->Write (text, len) == len) { crc = CalcCRC32 ((BYTE *)&head+4, keylen + 5); if (len != 0) @@ -270,7 +270,7 @@ bool M_AppendPNGText (FILE *file, const char *keyword, const char *text) crc = AddCRC32 (crc, (BYTE *)text, len); } crc = BigLong((unsigned int)crc); - return fwrite (&crc, 1, 4, file) == 4; + return file->Write (&crc, 4) == 4; } return false; } @@ -900,7 +900,7 @@ static int SelectFilter(Byte row[5][1 + MAXWIDTH*3], Byte prior[MAXWIDTH*3], int // //========================================================================== -bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FILE *file) +bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FileWriter *file) { #if USE_FILTER_HEURISTIC Byte prior[MAXWIDTH*3]; @@ -1040,7 +1040,7 @@ bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, i // //========================================================================== -static bool WriteIDAT (FILE *file, const BYTE *data, int len) +static bool WriteIDAT (FileWriter *file, const BYTE *data, int len) { DWORD foo[2], crc; @@ -1049,9 +1049,9 @@ static bool WriteIDAT (FILE *file, const BYTE *data, int len) crc = CalcCRC32 ((BYTE *)&foo[1], 4); crc = BigLong ((unsigned int)AddCRC32 (crc, data, len)); - if (fwrite (foo, 1, 8, file) != 8 || - fwrite (data, 1, len, file) != (size_t)len || - fwrite (&crc, 1, 4, file) != 4) + if (file->Write (foo, 8) != 8 || + file->Write (data, len) != (size_t)len || + file->Write (&crc, 4) != 4) { return false; } diff --git a/src/m_png.h b/src/m_png.h index 6434031d28..ef25d70d43 100644 --- a/src/m_png.h +++ b/src/m_png.h @@ -36,6 +36,7 @@ #include #include "doomtype.h" #include "v_video.h" +#include "files.h" // PNG Writing -------------------------------------------------------------- @@ -43,22 +44,22 @@ // The passed file should be a newly created file. // This function writes the PNG signature and the IHDR, gAMA, PLTE, and IDAT // chunks. -bool M_CreatePNG (FILE *file, const BYTE *buffer, const PalEntry *pal, +bool M_CreatePNG (FileWriter *file, const BYTE *buffer, const PalEntry *pal, ESSType color_type, int width, int height, int pitch); // Creates a grayscale 1x1 PNG file. Used for savegames without savepics. -bool M_CreateDummyPNG (FILE *file); +bool M_CreateDummyPNG (FileWriter *file); // Appends any chunk to a PNG file started with M_CreatePNG. -bool M_AppendPNGChunk (FILE *file, DWORD chunkID, const BYTE *chunkData, DWORD len); +bool M_AppendPNGChunk (FileWriter *file, DWORD chunkID, const BYTE *chunkData, DWORD len); // Adds a tEXt chunk to a PNG file started with M_CreatePNG. -bool M_AppendPNGText (FILE *file, const char *keyword, const char *text); +bool M_AppendPNGText (FileWriter *file, const char *keyword, const char *text); // Appends the IEND chunk to a PNG file. -bool M_FinishPNG (FILE *file); +bool M_FinishPNG (FileWriter *file); -bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FILE *file); +bool M_SaveBitmap(const BYTE *from, ESSType color_type, int width, int height, int pitch, FileWriter *file); // PNG Reading -------------------------------------------------------------- diff --git a/src/r_renderer.h b/src/r_renderer.h index c5385aadcd..4236993d63 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -11,6 +11,7 @@ class AActor; class player_t; struct sector_t; class FCanvasTexture; +class FileWriter; struct FRenderer { @@ -37,7 +38,7 @@ struct FRenderer virtual void RemapVoxels() {} // renders view to a savegame picture - virtual void WriteSavePic (player_t *player, FILE *file, int width, int height) = 0; + virtual void WriteSavePic (player_t *player, FileWriter *file, int width, int height) = 0; // draws player sprites with hardware acceleration (only useful for software rendering) virtual void DrawRemainingPlayerSprites() {} diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index ccf12e7ed5..3c33134301 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -179,7 +179,7 @@ void FSoftwareRenderer::RemapVoxels() // //=========================================================================== -void FSoftwareRenderer::WriteSavePic (player_t *player, FILE *file, int width, int height) +void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { DCanvas *pic = new DSimpleCanvas (width, height); PalEntry palette[256]; diff --git a/src/r_swrenderer.h b/src/r_swrenderer.h index 2856d9586a..f9d5609a0d 100644 --- a/src/r_swrenderer.h +++ b/src/r_swrenderer.h @@ -6,35 +6,35 @@ struct FSoftwareRenderer : public FRenderer { // Can be overridden so that the colormaps for sector color/fade won't be built. - virtual bool UsesColormap() const; + virtual bool UsesColormap() const override; // precache one texture void PrecacheTexture(FTexture *tex, int cache); - virtual void Precache(BYTE *texhitlist, TMap &actorhitlist); + virtual void Precache(BYTE *texhitlist, TMap &actorhitlist) override; // render 3D view - virtual void RenderView(player_t *player); + virtual void RenderView(player_t *player) override; // Remap voxel palette - virtual void RemapVoxels(); + virtual void RemapVoxels() override; // renders view to a savegame picture - virtual void WriteSavePic (player_t *player, FILE *file, int width, int height); + virtual void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override; // draws player sprites with hardware acceleration (only useful for software rendering) - virtual void DrawRemainingPlayerSprites(); + virtual void DrawRemainingPlayerSprites() override; - virtual int GetMaxViewPitch(bool down); + virtual int GetMaxViewPitch(bool down) override; - void OnModeSet (); - void ErrorCleanup (); - void ClearBuffer(int color); - void Init(); - void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio); - void SetupFrame(player_t *player); - void CopyStackedViewParameters(); - void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov); - sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back); + void OnModeSet () override; + void ErrorCleanup () override; + void ClearBuffer(int color) override; + void Init() override; + void SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight, float trueratio) override; + void SetupFrame(player_t *player) override; + void CopyStackedViewParameters() override; + void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) override; + sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) override; };