94 lines
2.4 KiB
C++
Raw Normal View History

2024-04-02 19:22:01 -04:00
#include <cstdlib>
#include <cstdio>
2020-11-24 17:12:23 -05:00
#include <unistd.h>
2024-04-02 19:22:01 -04:00
#include <ctime>
#include <cstring>
#include <cerrno>
2021-02-08 22:52:39 -05:00
#include <sys/stat.h>
2020-11-24 17:12:23 -05:00
2023-11-11 00:44:26 -05:00
#include "stb_image.h"
#include "stb_image_write.h"
2020-11-24 17:12:23 -05:00
2022-07-13 16:46:33 -04:00
#include <libreborn/libreborn.h>
2020-11-24 17:12:23 -05:00
#include <GLES/gl.h>
2022-07-13 16:46:33 -04:00
#include <mods/screenshot/screenshot.h>
2020-11-24 17:12:23 -05:00
2021-08-26 22:52:18 -04:00
// Ensure Screenshots Folder Exists
2024-06-16 00:47:36 -04:00
static void ensure_screenshots_folder(const char *screenshots) {
2021-08-26 22:52:18 -04:00
// Check Screenshots Folder
ensure_directory(screenshots);
2021-08-26 22:52:18 -04:00
}
2020-11-24 17:12:23 -05:00
// Take Screenshot
2022-06-13 20:49:09 -04:00
static int save_png(const char *filename, unsigned char *pixels, int line_size, int width, int height) {
2023-11-11 00:44:26 -05:00
// Setup
stbi_flip_vertically_on_write(1);
2022-06-13 20:49:09 -04:00
2023-11-11 00:44:26 -05:00
// Write Image
return !stbi_write_png(filename, width, height, 4, pixels, line_size);
2022-06-13 20:49:09 -04:00
}
2024-06-15 08:52:15 -04:00
void screenshot_take(const char *home) {
// Check
if (reborn_is_headless()) {
IMPOSSIBLE();
}
2021-08-26 22:52:18 -04:00
// Get Directory
2024-06-16 00:47:36 -04:00
const std::string screenshots = std::string(home) + "/screenshots";
2021-08-26 22:52:18 -04:00
// Get Timestamp
time_t raw_time;
time(&raw_time);
tm *time_info = localtime(&raw_time);
char time[512];
strftime(time, 512, "%Y-%m-%d_%H.%M.%S", time_info);
2020-11-24 17:12:23 -05:00
2021-08-26 22:52:18 -04:00
// Ensure Screenshots Folder Exists
2024-06-16 00:47:36 -04:00
ensure_screenshots_folder(screenshots.c_str());
2020-11-24 17:12:23 -05:00
2021-08-26 22:52:18 -04:00
// Prevent Overwriting Screenshots
2020-11-24 17:12:23 -05:00
int num = 1;
2024-06-16 00:47:36 -04:00
std::string file = screenshots + '/' + time + ".png";
while (access(file.c_str(), F_OK) != -1) {
file = screenshots + '/' + time + '-' + std::to_string(num) + ".png";
2020-11-24 17:12:23 -05:00
num++;
}
2021-08-26 22:52:18 -04:00
// Get Image Size
2020-11-24 17:12:23 -05:00
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
int x = viewport[0];
int y = viewport[1];
int width = viewport[2];
int height = viewport[3];
2021-08-26 22:52:18 -04:00
// Get Line Size
int line_size = width * 4;
{
// Handle Alignment
int alignment;
glGetIntegerv(GL_PACK_ALIGNMENT, &alignment);
// Round
int diff = line_size % alignment;
if (diff > 0) {
line_size = line_size + (alignment - diff);
}
}
2020-11-24 17:12:23 -05:00
int size = height * line_size;
2021-08-26 22:52:18 -04:00
// Read Pixels
unsigned char *pixels = (unsigned char *) malloc(size);
ALLOC_CHECK(pixels);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
2020-11-24 17:12:23 -05:00
2021-08-26 22:52:18 -04:00
// Save Image
2024-06-16 00:47:36 -04:00
if (save_png(file.c_str(), pixels, line_size, width, height)) {
WARN("Screenshot Failed: %s", file.c_str());
2020-11-24 17:12:23 -05:00
} else {
2024-06-16 00:47:36 -04:00
INFO("Screenshot Saved: %s", file.c_str());
2020-11-24 17:12:23 -05:00
}
2021-08-26 22:52:18 -04:00
// Free
free(pixels);
2020-11-24 17:12:23 -05:00
}