Skip to content

Commit

Permalink
Screenshotting: Use SDL_RWops throughout
Browse files Browse the repository at this point in the history
Turns out `SDL_RWFromFP` isn't implemented in SDL for mingw.
  • Loading branch information
glebm authored and AJenbo committed Sep 26, 2024
1 parent b78ec23 commit 898cb3a
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 18 deletions.
9 changes: 5 additions & 4 deletions Source/capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
namespace devilution {
namespace {

FILE *CaptureFile(std::string *dstPath)
SDL_RWops *CaptureFile(std::string *dstPath)
{
const char *ext =
#if DEVILUTIONX_SCREENSHOT_FORMAT == DEVILUTIONX_SCREENSHOT_FORMAT_PCX
Expand All @@ -54,7 +54,7 @@ FILE *CaptureFile(std::string *dstPath)
i++;
*dstPath = StrCat(paths::PrefPath(), filename, "-", i, ext);
}
return OpenFile(dstPath->c_str(), "wb");
return SDL_RWFromFile(dstPath->c_str(), "wb");
}

/**
Expand All @@ -79,9 +79,10 @@ void CaptureScreen()
std::string fileName;
const uint32_t startTime = SDL_GetTicks();

FILE *outStream = CaptureFile(&fileName);
SDL_RWops *outStream = CaptureFile(&fileName);
if (outStream == nullptr) {
LogError("Failed to open {} for writing: {}", fileName, std::strerror(errno));
LogError("Failed to open {} for writing: {}", fileName, SDL_GetError());
SDL_ClearError();
return;
}
DrawAndBlit();
Expand Down
20 changes: 11 additions & 9 deletions Source/utils/surface_to_pcx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
namespace devilution {
namespace {

tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, FILE *out)
tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, SDL_RWops *out)
{
if (std::fwrite(ptr, size, 1, out) != 1) {
const char *errorMessage = std::strerror(errno);
if (SDL_RWwrite(out, ptr, size, 1) != 1) {
const char *errorMessage = SDL_GetError();
if (errorMessage == nullptr)
errorMessage = "";
return tl::make_unexpected(std::string("fwrite failed with: ").append(errorMessage));
tl::expected<void, std::string> result = tl::make_unexpected(std::string("write failed with: ").append(errorMessage));
SDL_ClearError();
return result;
}
return {};
}
Expand All @@ -33,7 +35,7 @@ tl::expected<void, std::string> CheckedFWrite(const void *ptr, size_t size, FILE
* @param out File stream to write to
* @return True on success
*/
tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, FILE *out)
tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, SDL_RWops *out)
{
PCXHeader buffer;

Expand All @@ -58,7 +60,7 @@ tl::expected<void, std::string> WritePcxHeader(int16_t width, int16_t height, FI
* @param out File stream for the PCX file.
* @return True if successful, else false
*/
tl::expected<void, std::string> WritePcxPalette(SDL_Color *palette, FILE *out)
tl::expected<void, std::string> WritePcxPalette(SDL_Color *palette, SDL_RWops *out)
{
uint8_t pcxPalette[1 + 256 * 3];

Expand Down Expand Up @@ -121,7 +123,7 @@ uint8_t *WritePcxLine(uint8_t *src, uint8_t *dst, int width)
* @param out File stream for the PCX file.
* @return True if successful, else false
*/
tl::expected<void, std::string> WritePcxPixels(const Surface &buf, FILE *out)
tl::expected<void, std::string> WritePcxPixels(const Surface &buf, SDL_RWops *out)
{
const int width = buf.w();
const std::unique_ptr<uint8_t[]> pBuffer { new uint8_t[static_cast<size_t>(2 * width)] };
Expand All @@ -138,15 +140,15 @@ tl::expected<void, std::string> WritePcxPixels(const Surface &buf, FILE *out)
} // namespace

tl::expected<void, std::string>
WriteSurfaceToFilePcx(const Surface &buf, FILE *outStream)
WriteSurfaceToFilePcx(const Surface &buf, SDL_RWops *outStream)
{
tl::expected<void, std::string> result = WritePcxHeader(buf.w(), buf.h(), outStream);
if (!result.has_value()) return result;
result = WritePcxPixels(buf, outStream);
if (!result.has_value()) return result;
result = WritePcxPalette(buf.surface->format->palette->colors, outStream);
if (!result.has_value()) return result;
std::fclose(outStream);
SDL_RWclose(outStream);
return {};
}

Expand Down
3 changes: 2 additions & 1 deletion Source/utils/surface_to_pcx.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#include <cstdio>
#include <string>

#include <SDL.h>
#include <expected.hpp>

#include "engine/surface.hpp"

namespace devilution {

tl::expected<void, std::string>
WriteSurfaceToFilePcx(const Surface &buf, FILE *outStream);
WriteSurfaceToFilePcx(const Surface &buf, SDL_RWops *outStream);

} // namespace devilution
5 changes: 2 additions & 3 deletions Source/utils/surface_to_png.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ namespace devilution {
extern "C" int IMG_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst);

tl::expected<void, std::string>
WriteSurfaceToFilePng(const Surface &buf, FILE *outStream)
WriteSurfaceToFilePng(const Surface &buf, SDL_RWops *dst)
{
SDL_RWops *rwops = SDL_RWFromFP(outStream, /*autoclose=*/SDL_TRUE);
if (rwops == nullptr || IMG_SavePNG_RW(buf.surface, rwops, /*freedst=*/1) != 0) {
if (IMG_SavePNG_RW(buf.surface, dst, /*freedst=*/1) != 0) {
tl::expected<void, std::string> result = tl::make_unexpected(std::string(SDL_GetError()));
SDL_ClearError();
return result;
Expand Down
8 changes: 7 additions & 1 deletion Source/utils/surface_to_png.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
#include <cstdio>
#include <string>

#include <SDL.h>
#include <expected.hpp>

#include "engine/surface.hpp"

namespace devilution {

/**
* @brief Writes the given surface to `dst` as PNG.
*
* Takes ownership of `dst` and closes it when done.
*/
tl::expected<void, std::string>
WriteSurfaceToFilePng(const Surface &buf, FILE *outStream);
WriteSurfaceToFilePng(const Surface &buf, SDL_RWops *dst);

} // namespace devilution

0 comments on commit 898cb3a

Please sign in to comment.