Fix TripodCamera
This commit is contained in:
parent
3244b87be0
commit
81f0c6bbc9
@ -16,13 +16,16 @@ target_link_libraries(core dl)
|
|||||||
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp src/server/playerdata.cpp)
|
add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp src/server/playerdata.cpp)
|
||||||
target_link_libraries(server core dl SDL pthread)
|
target_link_libraries(server core dl SDL pthread)
|
||||||
|
|
||||||
|
add_library(screenshot SHARED src/screenshot/screenshot.c)
|
||||||
|
target_link_libraries(screenshot GLESv1_CM freeimage)
|
||||||
|
|
||||||
add_library(extra SHARED src/extra.c src/extra.cpp src/cxx11_util.cpp)
|
add_library(extra SHARED src/extra.c src/extra.cpp src/cxx11_util.cpp)
|
||||||
target_link_libraries(extra core dl server)
|
target_link_libraries(extra core dl server screenshot)
|
||||||
|
|
||||||
find_package(glfw3 3.3 REQUIRED)
|
find_package(glfw3 3.3 REQUIRED)
|
||||||
|
|
||||||
add_library(compat SHARED src/compat.c)
|
add_library(compat SHARED src/compat.c)
|
||||||
target_link_libraries(compat core extra SDL GLESv1_CM GLESv2 X11 dl freeimage glfw Xfixes)
|
target_link_libraries(compat core extra screenshot SDL GLESv1_CM GLESv2 X11 dl glfw Xfixes)
|
||||||
# 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,10 +1,7 @@
|
|||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <FreeImage.h>
|
|
||||||
|
|
||||||
#define GLFW_EXPOSE_NATIVE_X11
|
#define GLFW_EXPOSE_NATIVE_X11
|
||||||
#define GLFW_INCLUDE_ES1
|
#define GLFW_INCLUDE_ES1
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@ -20,6 +17,7 @@
|
|||||||
#include <libcore/libcore.h>
|
#include <libcore/libcore.h>
|
||||||
|
|
||||||
#include "extra.h"
|
#include "extra.h"
|
||||||
|
#include "screenshot/screenshot.h"
|
||||||
|
|
||||||
static GLFWwindow *glfw_window;
|
static GLFWwindow *glfw_window;
|
||||||
static Display *x11_display;
|
static Display *x11_display;
|
||||||
@ -185,8 +183,6 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
|
|||||||
|
|
||||||
// Init GLFW
|
// Init GLFW
|
||||||
HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const char *icon)) {
|
HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const char *icon)) {
|
||||||
FreeImage_Initialise(0);
|
|
||||||
|
|
||||||
// Don't Enable GLFW In Server Mode
|
// Don't Enable GLFW In Server Mode
|
||||||
if (!is_server) {
|
if (!is_server) {
|
||||||
glfwSetErrorCallback(glfw_error);
|
glfwSetErrorCallback(glfw_error);
|
||||||
@ -256,63 +252,6 @@ 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
|
|
||||||
|
|
||||||
// Take Screenshot
|
|
||||||
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 width;
|
|
||||||
int height;
|
|
||||||
glfwGetWindowSize(glfw_window, &width, &height);
|
|
||||||
|
|
||||||
int line_size = width * 3;
|
|
||||||
int size = height * line_size;
|
|
||||||
|
|
||||||
unsigned char pixels[size];
|
|
||||||
glReadPixels(0, 0, width, height, 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, width, height, line_size, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0);
|
|
||||||
if (!FreeImage_Save(FIF_PNG, image, file, 0)) {
|
|
||||||
INFO("Screenshot Failed: %s", file);
|
|
||||||
} else {
|
|
||||||
INFO("Screenshot Saved: %s", file);
|
|
||||||
}
|
|
||||||
FreeImage_Unload(image);
|
|
||||||
|
|
||||||
free(file);
|
|
||||||
free(screenshots);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intercept SDL Events
|
// Intercept SDL Events
|
||||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||||
// Process GLFW Events
|
// Process GLFW Events
|
||||||
@ -339,7 +278,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
|||||||
toggle_fullscreen();
|
toggle_fullscreen();
|
||||||
handled = 1;
|
handled = 1;
|
||||||
} else if (event->key.keysym.sym == SDLK_F2) {
|
} else if (event->key.keysym.sym == SDLK_F2) {
|
||||||
screenshot();
|
take_screenshot();
|
||||||
handled = 1;
|
handled = 1;
|
||||||
} else if (event->key.keysym.sym == SDLK_F1) {
|
} else if (event->key.keysym.sym == SDLK_F1) {
|
||||||
extra_hide_gui();
|
extra_hide_gui();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "extra.h"
|
#include "extra.h"
|
||||||
#include "cxx11_util.h"
|
#include "cxx11_util.h"
|
||||||
|
#include "screenshot/screenshot.h"
|
||||||
|
|
||||||
#include "minecraft.h"
|
#include "minecraft.h"
|
||||||
|
|
||||||
@ -24,6 +25,11 @@ extern "C" {
|
|||||||
return create_cxx11_string(str.c_str());
|
return create_cxx11_string(str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Take Screenshot Using TripodCamera
|
||||||
|
static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) unsigned char *app_platform, __attribute__((unused)) std::string const& param1, __attribute__((unused)) std::string const& param_2) {
|
||||||
|
take_screenshot();
|
||||||
|
}
|
||||||
|
|
||||||
// Open Sign Screen
|
// Open Sign Screen
|
||||||
static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsigned char *sign) {
|
static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsigned char *sign) {
|
||||||
if (*(int *)(sign + 0x18) == 4) {
|
if (*(int *)(sign + 0x18) == 4) {
|
||||||
@ -91,6 +97,7 @@ extern "C" {
|
|||||||
item_instance = (*ItemInstance_damage)(item_instance, *item_dye_powder, 1, i);
|
item_instance = (*ItemInstance_damage)(item_instance, *item_dye_powder, 1, i);
|
||||||
(*FillingContainer_addItem)(filling_container, item_instance);
|
(*FillingContainer_addItem)(filling_container, item_instance);
|
||||||
}
|
}
|
||||||
|
inventory_add_item(filling_container, *item_camera, false);
|
||||||
// Add Tiles
|
// Add Tiles
|
||||||
inventory_add_item(filling_container, *tile_water, true);
|
inventory_add_item(filling_container, *tile_water, true);
|
||||||
inventory_add_item(filling_container, *tile_lava, true);
|
inventory_add_item(filling_container, *tile_lava, true);
|
||||||
@ -160,9 +167,27 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable TripodCameraRenderer
|
||||||
|
static unsigned char *EntityRenderDispatcher_injection(unsigned char *dispatcher) {
|
||||||
|
// Call Original Method
|
||||||
|
(*EntityRenderDispatcher)(dispatcher);
|
||||||
|
|
||||||
|
// Register TripodCameraRenderer
|
||||||
|
unsigned char *renderer = (unsigned char *) ::operator new(0x193);
|
||||||
|
(*TripodCameraRenderer)(renderer);
|
||||||
|
(*EntityRenderDispatcher_assign)(dispatcher, (unsigned char) 0x5, renderer);
|
||||||
|
|
||||||
|
return dispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
__attribute((constructor)) static void init() {
|
__attribute((constructor)) static void init() {
|
||||||
// Implement AppPlatform::readAssetFile So Translations Work
|
// Implement AppPlatform::readAssetFile So Translations Work
|
||||||
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection);
|
||||||
|
// Implement AppPlatform_linux::saveScreenshot So Cameras Work
|
||||||
|
patch_address(AppPlatform_linux_saveScreenshot_vtable_addr, (void *) AppPlatform_linux_saveScreenshot_injection);
|
||||||
|
|
||||||
|
// Enable TripodCameraRenderer
|
||||||
|
overwrite_calls((void *) EntityRenderDispatcher, (void *) EntityRenderDispatcher_injection);
|
||||||
|
|
||||||
if (extra_has_feature("Fix Sign Placement")) {
|
if (extra_has_feature("Fix Sign Placement")) {
|
||||||
// Fix Signs
|
// Fix Signs
|
||||||
|
@ -16,6 +16,7 @@ static unsigned char **item_snowball = (unsigned char **) 0x17bbb0;
|
|||||||
static unsigned char **item_shears = (unsigned char **) 0x17bbf0;
|
static unsigned char **item_shears = (unsigned char **) 0x17bbf0;
|
||||||
static unsigned char **item_egg = (unsigned char **) 0x17bbd0;
|
static unsigned char **item_egg = (unsigned char **) 0x17bbd0;
|
||||||
static unsigned char **item_dye_powder = (unsigned char **) 0x17bbe0;
|
static unsigned char **item_dye_powder = (unsigned char **) 0x17bbe0;
|
||||||
|
static unsigned char **item_camera = (unsigned char **) 0x17bc14;
|
||||||
|
|
||||||
static unsigned char **tile_water = (unsigned char **) 0x181b3c;
|
static unsigned char **tile_water = (unsigned char **) 0x181b3c;
|
||||||
static unsigned char **tile_lava = (unsigned char **) 0x181cc8;
|
static unsigned char **tile_lava = (unsigned char **) 0x181cc8;
|
||||||
@ -246,6 +247,19 @@ static NbtIo_read_t NbtIo_read = (NbtIo_read_t) 0xb98cc;
|
|||||||
typedef void (*Inventory_clearInventoryWithDefault_t)(unsigned char *inventory);
|
typedef void (*Inventory_clearInventoryWithDefault_t)(unsigned char *inventory);
|
||||||
static Inventory_clearInventoryWithDefault_t Inventory_clearInventoryWithDefault = (Inventory_clearInventoryWithDefault_t) 0x8e7c8;
|
static Inventory_clearInventoryWithDefault_t Inventory_clearInventoryWithDefault = (Inventory_clearInventoryWithDefault_t) 0x8e7c8;
|
||||||
|
|
||||||
|
// TripodCameraRenderer
|
||||||
|
|
||||||
|
typedef unsigned char *(*TripodCameraRenderer_t)(unsigned char *renderer);
|
||||||
|
static TripodCameraRenderer_t TripodCameraRenderer = (TripodCameraRenderer_t) 0x6583c;
|
||||||
|
|
||||||
|
// EntityRenderDispatcher
|
||||||
|
|
||||||
|
typedef unsigned char *(*EntityRenderDispatcher_t)(unsigned char *dispatcher);
|
||||||
|
static EntityRenderDispatcher_t EntityRenderDispatcher = (EntityRenderDispatcher_t) 0x6096c;
|
||||||
|
|
||||||
|
typedef void (*EntityRenderDispatcher_assign_t)(unsigned char *dispatcher, unsigned char entity_id, unsigned char *renderer);
|
||||||
|
static EntityRenderDispatcher_assign_t EntityRenderDispatcher_assign = (EntityRenderDispatcher_assign_t) 0x6094c;
|
||||||
|
|
||||||
// Method That Require C++ Types
|
// Method That Require C++ Types
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
@ -255,6 +269,9 @@ static Inventory_clearInventoryWithDefault_t Inventory_clearInventoryWithDefault
|
|||||||
|
|
||||||
// AppPlatform
|
// AppPlatform
|
||||||
|
|
||||||
|
typedef void (*AppPlatform_saveScreenshot_t)(unsigned char *app_platform, std::string const& param1, std::string const& param_2);
|
||||||
|
static void *AppPlatform_linux_saveScreenshot_vtable_addr = (void *) 0x102160;
|
||||||
|
|
||||||
typedef cxx11_string (*AppPlatform_readAssetFile_t)(unsigned char *app_platform, std::string const& path);
|
typedef cxx11_string (*AppPlatform_readAssetFile_t)(unsigned char *app_platform, std::string const& path);
|
||||||
static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_readAssetFile_t) 0x12b10;
|
static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_readAssetFile_t) 0x12b10;
|
||||||
|
|
||||||
|
79
mods/src/screenshot/screenshot.c
Normal file
79
mods/src/screenshot/screenshot.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <FreeImage.h>
|
||||||
|
|
||||||
|
#include <GLES/gl.h>
|
||||||
|
|
||||||
|
#include <libcore/libcore.h>
|
||||||
|
|
||||||
|
#include "screenshot.h"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Take Screenshot
|
||||||
|
void take_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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint viewport[4];
|
||||||
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||||
|
int x = viewport[0];
|
||||||
|
int y = viewport[1];
|
||||||
|
int width = viewport[2];
|
||||||
|
int height = viewport[3];
|
||||||
|
|
||||||
|
int line_size = width * 3;
|
||||||
|
int size = height * line_size;
|
||||||
|
|
||||||
|
unsigned char pixels[size];
|
||||||
|
glReadPixels(x, y, width, height, 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, width, height, line_size, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0);
|
||||||
|
if (!FreeImage_Save(FIF_PNG, image, file, 0)) {
|
||||||
|
INFO("Screenshot Failed: %s", file);
|
||||||
|
} else {
|
||||||
|
INFO("Screenshot Saved: %s", file);
|
||||||
|
}
|
||||||
|
FreeImage_Unload(image);
|
||||||
|
|
||||||
|
free(file);
|
||||||
|
free(screenshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init FreeImage
|
||||||
|
__attribute__((constructor)) static void init() {
|
||||||
|
FreeImage_Initialise(0);
|
||||||
|
}
|
15
mods/src/screenshot/screenshot.h
Normal file
15
mods/src/screenshot/screenshot.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef SCREENSHOT_H
|
||||||
|
|
||||||
|
#define SCREENSHOT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void take_screenshot();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user