Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screenshotting: Use SDL_RWops throughout #7435

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading