minecraft-pi-reborn/media-layer/core/src/screenshot.c

131 lines
3.4 KiB
C
Raw Normal View History

2022-06-11 01:59:57 +00:00
// Config Needs To Load First
#include <libreborn/libreborn.h>
2021-09-12 03:18:12 +00:00
// Screenshot Code Is Useless In Headless Mode
2021-08-27 02:52:18 +00:00
#ifndef MCPI_HEADLESS_MODE
2020-11-24 22:12:23 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
2021-02-09 03:52:39 +00:00
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
2020-11-24 22:12:23 +00:00
#include <FreeImage.h>
#include <GLES/gl.h>
2021-09-12 03:18:12 +00:00
#include <media-layer/core.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
struct stat obj;
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
2021-08-27 02:52:18 +00:00
void media_take_screenshot(char *home) {
// Get Directory
char *screenshots = NULL;
safe_asprintf(&screenshots, "%s/screenshots", home);
// Get Timestamp
2020-11-24 22:12:23 +00:00
time_t rawtime;
struct tm *timeinfo;
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;
char *file = NULL;
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);
file = NULL;
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
2020-11-24 22:12:23 +00:00
unsigned char pixels[size];
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
// Handle Little Endian Systems
2021-06-17 21:32:24 +00:00
#if __BYTE_ORDER == __LITTLE_ENDIAN
2020-11-24 22:12:23 +00:00
// Swap Red And Blue
for (int j = 0; j < width; j++) {
for (int k = 0; k < height; k++) {
int pixel = (k * line_size) + (j * 4);
// Swap
int red = pixels[pixel];
int blue = pixels[pixel + 2];
pixels[pixel] = blue;
pixels[pixel + 2] = red;
}
2020-11-24 22:12:23 +00:00
}
#endif
2021-08-27 02:52:18 +00:00
// Save Image
FIBITMAP *image = FreeImage_ConvertFromRawBits(pixels, width, height, line_size, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0);
2020-11-24 22:12:23 +00:00
if (!FreeImage_Save(FIF_PNG, image, file, 0)) {
INFO("Screenshot Failed: %s", file);
} else {
INFO("Screenshot Saved: %s", file);
}
FreeImage_Unload(image);
2021-08-27 02:52:18 +00:00
// Free
2020-11-24 22:12:23 +00:00
free(file);
free(screenshots);
}
2021-02-09 03:52:39 +00:00
// Init
2020-11-24 22:12:23 +00:00
__attribute__((constructor)) static void init() {
2021-02-09 03:52:39 +00:00
// Init FreeImage
2020-11-24 22:12:23 +00:00
FreeImage_Initialise(0);
2021-06-17 21:32:24 +00:00
}
2022-03-14 23:09:25 +00:00
#else
2021-06-17 21:32:24 +00:00
void media_take_screenshot() {
// NOP
}
2022-03-14 23:09:25 +00:00
#endif