Add Screenshot Support VIA F2
This commit is contained in:
parent
b4d4c6e584
commit
7f1506ee2b
@ -2,10 +2,10 @@ FROM arm64v8/debian:bullseye
|
|||||||
|
|
||||||
RUN dpkg --add-architecture armhf
|
RUN dpkg --add-architecture armhf
|
||||||
|
|
||||||
RUN apt-get update
|
RUN \
|
||||||
RUN apt-get upgrade -y
|
apt-get update && \
|
||||||
|
apt-get upgrade -y && \
|
||||||
RUN apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf build-essential zlib1g-dev:armhf git cmake curl gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gdb
|
apt-get install -y libglvnd-dev:armhf libsdl1.2-dev:armhf libx11-dev:armhf build-essential zlib1g-dev:armhf git cmake curl gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libfreeimage-dev:armhf
|
||||||
|
|
||||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so
|
RUN ln -s /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2 /usr/lib/libGLESv2.so
|
||||||
RUN ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1 /usr/lib/libEGL.so
|
RUN ln -s /usr/lib/arm-linux-gnueabihf/libEGL.so.1 /usr/lib/libEGL.so
|
||||||
|
@ -102,6 +102,12 @@ static void load(char **ld_path, char **ld_preload, char *folder) {
|
|||||||
int main(__attribute__((unused)) int argc, char *argv[]) {
|
int main(__attribute__((unused)) int argc, char *argv[]) {
|
||||||
fprintf(stderr, "Configuring Game...\n");
|
fprintf(stderr, "Configuring Game...\n");
|
||||||
|
|
||||||
|
// Create Screenshots Folder
|
||||||
|
char *screenshots_cmd = NULL;
|
||||||
|
asprintf(&screenshots_cmd, "mkdir -p %s/.minecraft/screenshots", getenv("HOME"));
|
||||||
|
system(screenshots_cmd);
|
||||||
|
free(screenshots_cmd);
|
||||||
|
|
||||||
char *ld_path = NULL;
|
char *ld_path = NULL;
|
||||||
|
|
||||||
// Start Configuring LD_LIBRARY_PATH
|
// Start Configuring LD_LIBRARY_PATH
|
||||||
|
@ -15,7 +15,7 @@ add_library(extra SHARED src/extra.c src/extra.cpp)
|
|||||||
target_link_libraries(extra core dl)
|
target_link_libraries(extra core dl)
|
||||||
|
|
||||||
add_library(compat SHARED src/compat.c)
|
add_library(compat SHARED src/compat.c)
|
||||||
target_link_libraries(compat core extra SDL EGL GLESv1_CM GLESv2 X11 dl)
|
target_link_libraries(compat core extra SDL EGL GLESv1_CM GLESv2 X11 dl freeimage)
|
||||||
# Force GLESv1 Link
|
# Force GLESv1 Link
|
||||||
target_link_options(compat PRIVATE "-Wl,--no-as-needed")
|
target_link_options(compat PRIVATE "-Wl,--no-as-needed")
|
||||||
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <FreeImage.h>
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
#include <SDL/SDL_syswm.h>
|
#include <SDL/SDL_syswm.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
@ -88,7 +93,7 @@ HOOK(eglTerminate, EGLBoolean, (__attribute__((unused)) EGLDisplay display)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handled In SDL_WM_SetCaption
|
// Handled In SDL_WM_SetCaption
|
||||||
HOOK(SDL_SetVideoMode, SDL_Surface *, (__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) Uint32 flags)) {
|
HOOK(SDL_SetVideoMode, SDL_Surface *, (__attribute__((unused)) int width, __attribute__((unused)) int height, __attribute__((unused)) int bpp, __attribute__((unused)) uint32_t flags)) {
|
||||||
// Return Value Is Only Used For A NULL-Check
|
// Return Value Is Only Used For A NULL-Check
|
||||||
return (SDL_Surface *) 1;
|
return (SDL_Surface *) 1;
|
||||||
}
|
}
|
||||||
@ -106,13 +111,17 @@ EGLint const set_attrib_list[] = {
|
|||||||
#define WINDOW_VIDEO_FLAGS SDL_RESIZABLE
|
#define WINDOW_VIDEO_FLAGS SDL_RESIZABLE
|
||||||
#define FULLSCREEN_VIDEO_FLAGS SDL_FULLSCREEN
|
#define FULLSCREEN_VIDEO_FLAGS SDL_FULLSCREEN
|
||||||
|
|
||||||
|
#define BPP 32
|
||||||
|
|
||||||
// Init EGL
|
// Init EGL
|
||||||
HOOK(SDL_WM_SetCaption, void, (const char *title, const char *icon)) {
|
HOOK(SDL_WM_SetCaption, void, (const char *title, const char *icon)) {
|
||||||
// Enable Unicode
|
// Enable Unicode
|
||||||
SDL_EnableUNICODE(SDL_ENABLE);
|
SDL_EnableUNICODE(SDL_ENABLE);
|
||||||
|
|
||||||
|
FreeImage_Initialise(0);
|
||||||
|
|
||||||
ensure_SDL_SetVideoMode();
|
ensure_SDL_SetVideoMode();
|
||||||
sdl_surface = (*real_SDL_SetVideoMode)(848, 480, 32, WINDOW_VIDEO_FLAGS);
|
sdl_surface = (*real_SDL_SetVideoMode)(848, 480, BPP, WINDOW_VIDEO_FLAGS);
|
||||||
|
|
||||||
ensure_SDL_WM_SetCaption();
|
ensure_SDL_WM_SetCaption();
|
||||||
(*real_SDL_WM_SetCaption)(title, icon);
|
(*real_SDL_WM_SetCaption)(title, icon);
|
||||||
@ -149,10 +158,10 @@ HOOK(eglSwapBuffers, EGLBoolean, (__attribute__((unused)) EGLDisplay display, __
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void resize(int width, int height, int fullscreen) {
|
static void resize(int width, int height, int fullscreen) {
|
||||||
Uint32 flags = fullscreen ? FULLSCREEN_VIDEO_FLAGS : WINDOW_VIDEO_FLAGS;
|
uint32_t flags = fullscreen ? FULLSCREEN_VIDEO_FLAGS : WINDOW_VIDEO_FLAGS;
|
||||||
|
|
||||||
ensure_SDL_SetVideoMode();
|
ensure_SDL_SetVideoMode();
|
||||||
sdl_surface = (*real_SDL_SetVideoMode)(width, height, 32, flags);
|
sdl_surface = (*real_SDL_SetVideoMode)(width, height, BPP, flags);
|
||||||
|
|
||||||
// OpenGL state modification for resizing
|
// OpenGL state modification for resizing
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
@ -199,13 +208,65 @@ static void toggle_fullscreen() {
|
|||||||
is_fullscreen = !is_fullscreen;
|
is_fullscreen = !is_fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 4 (Year + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Terminator)
|
||||||
|
#define TIME_SIZE 20
|
||||||
|
|
||||||
|
static void screenshot() {
|
||||||
|
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);
|
||||||
|
|
||||||
|
char *screenshots = NULL;
|
||||||
|
asprintf(&screenshots, "%s/.minecraft/screenshots", getenv("HOME"));
|
||||||
|
|
||||||
|
int num = 1;
|
||||||
|
char *file = NULL;
|
||||||
|
asprintf(&file, "%s/%s.png", screenshots, time);
|
||||||
|
while (access(file, F_OK) != -1) {
|
||||||
|
asprintf(&file, "%s/%s-%i.png", screenshots, time, num);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int line_size = sdl_surface->w * 3;
|
||||||
|
int size = sdl_surface->h * line_size;
|
||||||
|
|
||||||
|
unsigned char pixels[size];
|
||||||
|
glReadPixels(0, 0, sdl_surface->w, sdl_surface->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||||
|
// Swap Red And Blue
|
||||||
|
for (int i = 0; i < (size / 3); i++) {
|
||||||
|
int pixel = i * 3;
|
||||||
|
int red = pixels[pixel];
|
||||||
|
int blue = pixels[pixel + 2];
|
||||||
|
pixels[pixel] = blue;
|
||||||
|
pixels[pixel + 2] = red;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FIBITMAP *image = FreeImage_ConvertFromRawBits(pixels, sdl_surface->w, sdl_surface->h, line_size, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0);
|
||||||
|
if (!FreeImage_Save(FIF_PNG, image, file, 0)) {
|
||||||
|
fprintf(stderr, "Screenshot Failed: %s\n", file);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Screenshot Saved: %s\n", file);
|
||||||
|
}
|
||||||
|
FreeImage_Unload(image);
|
||||||
|
|
||||||
|
free(file);
|
||||||
|
free(screenshots);
|
||||||
|
}
|
||||||
|
|
||||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||||
// Poll Events
|
// Poll Events
|
||||||
ensure_SDL_PollEvent();
|
ensure_SDL_PollEvent();
|
||||||
int ret = (*real_SDL_PollEvent)(event);
|
int ret = (*real_SDL_PollEvent)(event);
|
||||||
|
|
||||||
// Resize EGL
|
// Resize EGL
|
||||||
if (event != NULL) {
|
if (event != NULL && ret == 1) {
|
||||||
int handled = 0;
|
int handled = 0;
|
||||||
|
|
||||||
if (event->type == SDL_VIDEORESIZE) {
|
if (event->type == SDL_VIDEORESIZE) {
|
||||||
@ -215,6 +276,9 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
|||||||
if (event->key.keysym.sym == SDLK_F11) {
|
if (event->key.keysym.sym == SDLK_F11) {
|
||||||
toggle_fullscreen();
|
toggle_fullscreen();
|
||||||
handled = 1;
|
handled = 1;
|
||||||
|
} else if (event->key.keysym.sym == SDLK_F2) {
|
||||||
|
screenshot();
|
||||||
|
handled = 1;
|
||||||
} else {
|
} else {
|
||||||
key_press((char) event->key.keysym.unicode);
|
key_press((char) event->key.keysym.unicode);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ void revert_overwrite(void *start, void *original) {
|
|||||||
// Insert Original Value
|
// Insert Original Value
|
||||||
_patch(NULL, -1, start, original);
|
_patch(NULL, -1, start, original);
|
||||||
_patch(NULL, -1, start + 4, original + 4);
|
_patch(NULL, -1, start + 4, original + 4);
|
||||||
|
|
||||||
// Complete Memory Swap
|
// Complete Memory Swap
|
||||||
memcpy(original, temp, ORIGINAL_SIZE);
|
memcpy(original, temp, ORIGINAL_SIZE);
|
||||||
free(temp);
|
free(temp);
|
||||||
|
@ -202,4 +202,8 @@ __attribute__((constructor)) static void init() {
|
|||||||
unsigned char autojump_patch[4] = {0x00, 0x30, 0xa0, 0xe3};
|
unsigned char autojump_patch[4] = {0x00, 0x30, 0xa0, 0xe3};
|
||||||
patch((void *) 0x44b90, autojump_patch);
|
patch((void *) 0x44b90, autojump_patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix Segmentation Fault
|
||||||
|
unsigned char segfault_patch[4] = {0x03, 0x00, 0x00, 0xea};
|
||||||
|
patch((void *) 0x4a630, segfault_patch);
|
||||||
}
|
}
|
||||||
|
@ -40,16 +40,9 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> input;
|
std::vector<char> input;
|
||||||
int count = 0;
|
|
||||||
void key_press(char key) {
|
void key_press(char key) {
|
||||||
if (is_valid_key(key)) {
|
if (is_valid_key(key)) {
|
||||||
// Keys Are Sent Twice
|
input.push_back(key);
|
||||||
if (count > 0) {
|
|
||||||
count = 0;
|
|
||||||
} else {
|
|
||||||
input.push_back(key);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void clear_input() {
|
void clear_input() {
|
||||||
|
Loading…
Reference in New Issue
Block a user