119 lines
3.0 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>
2024-06-21 01:19:37 -04:00
#include <symbols/minecraft.h>
2022-07-13 16:46:33 -04:00
#include <mods/screenshot/screenshot.h>
2024-06-21 01:19:37 -04:00
#include <mods/home/home.h>
#include <mods/misc/misc.h>
#include <mods/input/input.h>
#include <mods/init/init.h>
2020-11-24 17:12:23 -05:00
2021-08-26 22:52:18 -04:00
// Ensure Screenshots Folder Exists
2024-06-21 01:19:37 -04:00
static std::string get_screenshot_dir() {
std::string dir = std::string(home_get()) + "/screenshots";
ensure_directory(dir.c_str());
return dir;
}
static std::string get_screenshot(const std::string &filename) {
return get_screenshot_dir() + '/' + filename;
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-21 01:19:37 -04:00
void screenshot_take(Gui *gui) {
2024-06-15 08:52:15 -04:00
// Check
if (reborn_is_headless()) {
IMPOSSIBLE();
}
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
// Prevent Overwriting Screenshots
2024-06-21 01:19:37 -04:00
int num = 0;
std::string filename;
do {
filename = std::string(time);
if (num > 0) {
filename += '-' + std::to_string(num);
}
filename += ".png";
2020-11-24 17:12:23 -05:00
num++;
2024-06-21 01:19:37 -04:00
} while (access(get_screenshot(filename).c_str(), F_OK) != -1);
const std::string file = get_screenshot(filename);
2020-11-24 17:12:23 -05:00
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
2024-07-05 02:33:29 -04:00
line_size = ALIGN_UP(line_size, alignment);
}
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-21 01:19:37 -04:00
std::string msg = "Screenshot Saved: ";
INFO("%s%s", msg.c_str(), file.c_str());
if (gui) {
msg += filename;
gui->addMessage(&msg);
}
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
}
2024-06-21 01:19:37 -04:00
// Init
void init_screenshot() {
// Create Directory
get_screenshot_dir();
// Take Screenshot On F2
misc_run_on_key_press([](Minecraft *mc, int key) {
if (key == MC_KEY_F2) {
screenshot_take(&mc->gui);
return true;
} else {
return false;
}
});
}