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)
|
||||
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)
|
||||
target_link_libraries(extra core dl server)
|
||||
target_link_libraries(extra core dl server screenshot)
|
||||
|
||||
find_package(glfw3 3.3 REQUIRED)
|
||||
|
||||
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
|
||||
target_link_options(compat PRIVATE "-Wl,--no-as-needed")
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <FreeImage.h>
|
||||
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#define GLFW_INCLUDE_ES1
|
||||
#include <GLFW/glfw3.h>
|
||||
@ -20,6 +17,7 @@
|
||||
#include <libcore/libcore.h>
|
||||
|
||||
#include "extra.h"
|
||||
#include "screenshot/screenshot.h"
|
||||
|
||||
static GLFWwindow *glfw_window;
|
||||
static Display *x11_display;
|
||||
@ -185,8 +183,6 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
|
||||
|
||||
// Init GLFW
|
||||
HOOK(SDL_WM_SetCaption, void, (const char *title, __attribute__((unused)) const char *icon)) {
|
||||
FreeImage_Initialise(0);
|
||||
|
||||
// Don't Enable GLFW In Server Mode
|
||||
if (!is_server) {
|
||||
glfwSetErrorCallback(glfw_error);
|
||||
@ -256,63 +252,6 @@ static void toggle_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
|
||||
HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||
// Process GLFW Events
|
||||
@ -339,7 +278,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
|
||||
toggle_fullscreen();
|
||||
handled = 1;
|
||||
} else if (event->key.keysym.sym == SDLK_F2) {
|
||||
screenshot();
|
||||
take_screenshot();
|
||||
handled = 1;
|
||||
} else if (event->key.keysym.sym == SDLK_F1) {
|
||||
extra_hide_gui();
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "extra.h"
|
||||
#include "cxx11_util.h"
|
||||
#include "screenshot/screenshot.h"
|
||||
|
||||
#include "minecraft.h"
|
||||
|
||||
@ -24,6 +25,11 @@ extern "C" {
|
||||
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
|
||||
static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsigned char *sign) {
|
||||
if (*(int *)(sign + 0x18) == 4) {
|
||||
@ -91,6 +97,7 @@ extern "C" {
|
||||
item_instance = (*ItemInstance_damage)(item_instance, *item_dye_powder, 1, i);
|
||||
(*FillingContainer_addItem)(filling_container, item_instance);
|
||||
}
|
||||
inventory_add_item(filling_container, *item_camera, false);
|
||||
// Add Tiles
|
||||
inventory_add_item(filling_container, *tile_water, 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() {
|
||||
// Implement AppPlatform::readAssetFile So Translations Work
|
||||
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")) {
|
||||
// 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_egg = (unsigned char **) 0x17bbd0;
|
||||
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_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);
|
||||
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
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -255,6 +269,9 @@ static Inventory_clearInventoryWithDefault_t Inventory_clearInventoryWithDefault
|
||||
|
||||
// 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);
|
||||
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