minecraft-pi-reborn/mods/src/screenshot/screenshot.cpp

107 lines
2.9 KiB
C++
Raw Normal View History

2024-04-02 23:22:01 +00:00
#include <cstdlib>
#include <cstdio>
2020-11-24 22:12:23 +00:00
#include <unistd.h>
2024-04-02 23:22:01 +00:00
#include <ctime>
#include <cstring>
#include <cerrno>
2021-02-09 03:52:39 +00:00
#include <sys/stat.h>
2020-11-24 22:12:23 +00:00
2023-11-11 05:44:26 +00:00
#include "stb_image.h"
#include "stb_image_write.h"
2020-11-24 22:12:23 +00:00
2022-07-13 20:46:33 +00:00
#include <libreborn/libreborn.h>
2020-11-24 22:12:23 +00:00
#include <GLES/gl.h>
2022-07-13 20:46:33 +00:00
#include <mods/screenshot/screenshot.h>
2020-11-24 22:12:23 +00:00
2021-08-27 02:52:18 +00:00
// Ensure Screenshots Folder Exists
static void ensure_screenshots_folder(char *screenshots) {
// Check Screenshots Folder
2024-04-02 23:22:01 +00:00
struct stat obj = {};
2021-08-27 02:52:18 +00:00
if (stat(screenshots, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
// Create Screenshots Folder
int ret = mkdir(screenshots, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
ERR("Error Creating Directory: %s: %s", screenshots, strerror(errno));
}
}
}
2021-02-09 03:52:39 +00:00
// 4 (Year) + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Null Terminator)
2020-11-24 22:12:23 +00:00
#define TIME_SIZE 20
// Take Screenshot
2022-06-14 00:49:09 +00:00
static int save_png(const char *filename, unsigned char *pixels, int line_size, int width, int height) {
2023-11-11 05:44:26 +00:00
// Setup
stbi_flip_vertically_on_write(1);
2022-06-14 00:49:09 +00:00
2023-11-11 05:44:26 +00:00
// Write Image
return !stbi_write_png(filename, width, height, 4, pixels, line_size);
2022-06-14 00:49:09 +00:00
}
2022-07-13 20:46:33 +00:00
void screenshot_take(char *home) {
2021-08-27 02:52:18 +00:00
// Get Directory
2024-04-02 23:22:01 +00:00
char *screenshots = nullptr;
2021-08-27 02:52:18 +00:00
safe_asprintf(&screenshots, "%s/screenshots", home);
// Get Timestamp
2020-11-24 22:12:23 +00:00
time_t rawtime;
2024-04-02 23:22:01 +00:00
tm *timeinfo = {};
2020-11-24 22:12:23 +00:00
time(&rawtime);
timeinfo = localtime(&rawtime);
char time[TIME_SIZE];
strftime(time, TIME_SIZE, "%Y-%m-%d_%H.%M.%S", timeinfo);
2021-08-27 02:52:18 +00:00
// Ensure Screenshots Folder Exists
ensure_screenshots_folder(screenshots);
2020-11-24 22:12:23 +00:00
2021-08-27 02:52:18 +00:00
// Prevent Overwriting Screenshots
2020-11-24 22:12:23 +00:00
int num = 1;
2024-04-02 23:22:01 +00:00
char *file = nullptr;
2021-06-17 21:32:24 +00:00
safe_asprintf(&file, "%s/%s.png", screenshots, time);
2020-11-24 22:12:23 +00:00
while (access(file, F_OK) != -1) {
2021-06-17 21:32:24 +00:00
free(file);
2024-04-02 23:22:01 +00:00
file = nullptr;
2021-06-17 21:32:24 +00:00
safe_asprintf(&file, "%s/%s-%i.png", screenshots, time, num);
2020-11-24 22:12:23 +00:00
num++;
}
2021-08-27 02:52:18 +00:00
// Get Image Size
2020-11-24 22:12:23 +00: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-27 02:52:18 +00: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 22:12:23 +00:00
int size = height * line_size;
2021-08-27 02:52:18 +00: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 22:12:23 +00:00
2021-08-27 02:52:18 +00:00
// Save Image
2022-06-14 00:49:09 +00:00
if (save_png(file, pixels, line_size, width, height)) {
2022-07-09 02:40:56 +00:00
WARN("Screenshot Failed: %s", file);
2020-11-24 22:12:23 +00:00
} else {
INFO("Screenshot Saved: %s", file);
}
2021-08-27 02:52:18 +00:00
// Free
2020-11-24 22:12:23 +00:00
free(file);
free(screenshots);
free(pixels);
2020-11-24 22:12:23 +00:00
}