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>
|
2024-08-25 18:14:30 -04:00
|
|
|
#include <mods/feature/feature.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
|
2024-09-20 21:30:47 -04:00
|
|
|
static int save_png(const char *filename, const unsigned char *pixels, const int line_size, const int width, const 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
|
2024-06-17 18:09:30 -04:00
|
|
|
time_t raw_time;
|
|
|
|
time(&raw_time);
|
2024-08-25 18:14:30 -04:00
|
|
|
const tm *time_info = localtime(&raw_time);
|
2024-06-17 18:09:30 -04:00
|
|
|
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);
|
2024-08-25 18:14:30 -04:00
|
|
|
const int x = viewport[0];
|
|
|
|
const int y = viewport[1];
|
|
|
|
const int width = viewport[2];
|
|
|
|
const int height = viewport[3];
|
2020-11-24 17:12:23 -05:00
|
|
|
|
2021-08-26 22:52:18 -04:00
|
|
|
// Get Line Size
|
2022-05-29 18:44:27 -04:00
|
|
|
int line_size = width * 4;
|
2021-09-15 19:12:03 -04:00
|
|
|
{
|
|
|
|
// 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);
|
2021-09-15 19:12:03 -04:00
|
|
|
}
|
2024-08-25 18:14:30 -04:00
|
|
|
const int size = height * line_size;
|
2020-11-24 17:12:23 -05:00
|
|
|
|
2021-08-26 22:52:18 -04:00
|
|
|
// Read Pixels
|
2023-08-02 01:08:31 -04:00
|
|
|
unsigned char *pixels = (unsigned char *) malloc(size);
|
|
|
|
ALLOC_CHECK(pixels);
|
2022-05-29 18:44:27 -04:00
|
|
|
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-07-10 23:15:58 -04:00
|
|
|
INFO("Screenshot Saved: %s", file.c_str());
|
2024-06-21 01:19:37 -04:00
|
|
|
if (gui) {
|
2024-07-10 23:15:58 -04:00
|
|
|
std::string chat_msg = "Saved screenshot as ";
|
|
|
|
chat_msg += filename;
|
2024-07-15 03:05:05 -04:00
|
|
|
gui->addMessage(chat_msg);
|
2024-06-21 01:19:37 -04:00
|
|
|
}
|
2020-11-24 17:12:23 -05:00
|
|
|
}
|
|
|
|
|
2021-08-26 22:52:18 -04:00
|
|
|
// Free
|
2023-08-02 01:08:31 -04:00
|
|
|
free(pixels);
|
2020-11-24 17:12:23 -05:00
|
|
|
}
|
2024-06-21 01:19:37 -04:00
|
|
|
|
|
|
|
// Init
|
|
|
|
void init_screenshot() {
|
2024-08-25 18:14:30 -04:00
|
|
|
if (feature_has("Screenshot Support", server_disabled)) {
|
|
|
|
// Create Directory
|
|
|
|
get_screenshot_dir();
|
|
|
|
// Take Screenshot On F2
|
2024-09-20 21:30:47 -04:00
|
|
|
misc_run_on_key_press([](Minecraft *mc, const int key) {
|
2024-08-25 18:14:30 -04:00
|
|
|
if (key == MC_KEY_F2) {
|
|
|
|
screenshot_take(&mc->gui);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2024-06-21 01:19:37 -04:00
|
|
|
}
|