Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Byteandahalf tile render api #514

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions jni/modscript.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 88 additions & 1 deletion jni/modscript_nextgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ static void (*bl_Packet_Packet)(void*);
static void (*bl_ClientSideNetworkHandler_handleMessagePacket_real)(void*, void*, MessagePacket*);
static void** bl_MessagePacket_vtable;

// Custom block renderers
static void (*bl_TileRenderer_tesselateInWorld_real)(void*, Tile*, int, int, int);

static void (*bl_TileRenderer_tesselateBlockInWorld)(void*, Tile*, int, int, int);
static void (*bl_TileRenderer_tesselateCrossInWorld)(void*, Tile*, int, int, int);
static void (*bl_TileRenderer_tesselateTorchInWorld)(void*, Tile*, int, int, int);

static void* bl_TileRenderer_instance;


bool bl_text_parse_color_codes = true;

//custom blocks
Expand Down Expand Up @@ -248,6 +258,33 @@ void bl_RakNetInstance_connect_hook(RakNetInstance* rakNetInstance, char const*
bl_RakNetInstance_connect_real(rakNetInstance, host, port);
}

void bl_TileRenderer_tesselateInWorld_hook(void* tileRenderer, Tile* tile, int x, int y, int z) {
bl_TileRenderer_instance = tileRenderer;

int blockId = tile->id;
if (bl_custom_block_renderShape[blockId] != -1) {
bl_TileRenderer_tesselateInWorld_real(tileRenderer, tile, x, y, z);
return;
}
JNIEnv *env;

int attachStatus = bl_JavaVM->GetEnv((void**) &env, JNI_VERSION_1_2);
if(attachStatus == JNI_EDETACHED) {
bl_JavaVM->AttachCurrentThread(&env, NULL);
}

// Don't allow PREVENT_DEFAULT_STATUS to be invoked, as it would nuke all block rendering in the game
jmethodID mid = env->GetStaticMethodID(bl_scriptmanager_class, "blockRendererCallback", "(IIII)V");

env->CallStaticVoidMethod(bl_scriptmanager_class, mid, blockId, x, y, z);

if(attachStatus == JNI_EDETACHED) {
bl_JavaVM->DetachCurrentThread();
}

bl_TileRenderer_tesselateInWorld_real(tileRenderer, tile, x, y, z);
}

void bl_Font_drawSlow_hook(Font* font, char const* text, int length, float xOffset, float yOffset, int color, bool isShadow) {
if (bl_text_parse_color_codes) {
char const* currentTextBegin = text; //the current coloured section
Expand Down Expand Up @@ -520,6 +557,19 @@ JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeCl
env->ReleaseStringUTFChars(text, utfChars);
}

JNIEXPORT int JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeGetBlockRenderShape
(JNIEnv *env, jclass clazz, jint blockId) {
Tile* tile = bl_Tile_tiles[blockId];
if(tile == NULL) return 0;

return bl_CustomBlock_getRenderShapeHook(tile);
}

JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeSetBlockRenderShape
(JNIEnv *env, jclass clazz, jint blockId, jint renderType) {
bl_custom_block_renderShape[blockId] = renderType;
}

Item* bl_constructItem(int id) {
Item* retval = (Item*) ::operator new((std::size_t) 72);
bl_Item_Item(retval, id - 0x100);
Expand Down Expand Up @@ -965,7 +1015,7 @@ JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeAd
JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeAddFurnaceRecipe
(JNIEnv *env, jclass clazz, jint inputId, jint outputId, jint outputDamage) {
ItemInstance outputStack;
bl_setItemInstance(&outputStack, outputId, 1, outputDamage); // Should this be null? You don't need count, not sure how to omit it completely
bl_setItemInstance(&outputStack, outputId, 1, outputDamage);
FurnaceRecipes* recipes = bl_FurnaceRecipes_getInstance();
bl_FurnaceRecipes_addFurnaceRecipe(recipes, inputId, outputStack);
}
Expand Down Expand Up @@ -1118,6 +1168,31 @@ JNIEXPORT jlongArray JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_na
return uuidArray;
}

// Custom block renderers
JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeRenderStandardBlock
(JNIEnv *env, jclass clazz, jint blockId, jint x, jint y, jint z) {
Tile* tile = bl_Tile_tiles[blockId];
if(tile == NULL) return;

bl_TileRenderer_tesselateBlockInWorld(bl_TileRenderer_instance, tile, x, y, z);
}

JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeRenderCrossBlock
(JNIEnv *env, jclass clazz, jint blockId, jint x, jint y, jint z) {
Tile* tile = bl_Tile_tiles[blockId];
if(tile == NULL) return;

bl_TileRenderer_tesselateCrossInWorld(bl_TileRenderer_instance, tile, x, y, z);
}

JNIEXPORT void JNICALL Java_net_zhuoweizhang_mcpelauncher_ScriptManager_nativeRenderTorchBlock
(JNIEnv *env, jclass clazz, jint blockId, jint x, jint y, jint z) {
Tile* tile = bl_Tile_tiles[blockId];
if(tile == NULL) return;

bl_TileRenderer_tesselateTorchInWorld(bl_TileRenderer_instance, tile, x, y, z);
}

void bl_cppNewLevelInit() {
bl_entityUUIDMap.clear();
}
Expand Down Expand Up @@ -1181,6 +1256,18 @@ void bl_setuphooks_cppside() {
dlsym(RTLD_DEFAULT, "_ZNK4Tile16getDescriptionIdEv");

bl_initCustomBlockVtable();

// This method switches out the Tile* render type and calls into the render type's respective tesselator
void* bl_TileRenderer_tesselateInWorld = dlsym(RTLD_DEFAULT, "_ZN12TileRenderer16tesselateInWorldEP4Tileiii");
mcpelauncher_hook(bl_TileRenderer_tesselateInWorld, (void*) &bl_TileRenderer_tesselateInWorld_hook, (void**) &bl_TileRenderer_tesselateInWorld_real);

// To render a standard block into the world; Use Tile::setShape to change the size and shape of it
bl_TileRenderer_tesselateBlockInWorld = (void (*)(void*, Tile*, int, int, int)) dlsym(RTLD_DEFAULT, "_ZN12TileRenderer21tesselateBlockInWorldEP4Tileiii");
// To render a cross block into the world; Use the tesselator to render a vertexUV into the location, in a cross shape
bl_TileRenderer_tesselateCrossInWorld = (void (*)(void*, Tile*, int, int, int)) dlsym(RTLD_DEFAULT, "_ZN12TileRenderer21tesselateCrossInWorldEP4Tileiii");
// To render a torch into the world at the given location. I think I can hook the angled torch renderer to make a torch at an angle
// That's an experiment for later.
bl_TileRenderer_tesselateTorchInWorld = (void (*)(void*, Tile*, int, int, int)) dlsym(RTLD_DEFAULT, "_ZN12TileRenderer21tesselateTorchInWorldEP4Tileiii");

bl_I18n_strings = (std::map <std::string, std::string> *) dlsym(RTLD_DEFAULT, "_ZN4I18n8_stringsE");
bl_Item_setIcon = (void (*)(Item*, std::string const&, int)) dlsym(mcpelibhandle, "_ZN4Item7setIconERKSsi");
Expand Down
54 changes: 54 additions & 0 deletions src/net/zhuoweizhang/mcpelauncher/ScriptManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ public static void initJustLoadedScript(Context ctx, Script script, String sourc
classConstantsToJSObject(ItemCategory.class));
ScriptableObject.defineClass(scope, NativeBlockApi.class);
ScriptableObject.defineClass(scope, NativeServerApi.class);
ScriptableObject.defineClass(scope, NativeBlockRendererApi.class);
RendererManager.defineClasses(scope);
} catch (Exception e) {
e.printStackTrace();
Expand Down Expand Up @@ -297,6 +298,10 @@ public static void leaveGameCallback(boolean thatboolean) {
public static void attackCallback(int attacker, int victim) {
callScriptMethod("attackHook", attacker, victim);
}

public static void blockRendererCallback(int blockId, int x, int y, int z) {
callScriptMethod("renderBlockHook", blockId, x, y, z);
}

public static void tickCallback() {
callScriptMethod("modTick");
Expand Down Expand Up @@ -665,6 +670,7 @@ public static String getAllApiMethodsDescriptions() {
appendApiMethods(builder, NativeItemApi.class, "Item");
appendApiMethods(builder, NativeBlockApi.class, "Block");
appendApiMethods(builder, NativeServerApi.class, "Server");
appendApiMethods(builder, NativeBlockRendererApi.class, "BlockRenderer");
return builder.toString();

}
Expand Down Expand Up @@ -1211,6 +1217,18 @@ public static native void nativeAddItemFurnace(int x, int y, int z, int slot, in

public static native void nativeSetItemMaxDamage(int id, int maxDamage);

public static native int nativeGetBlockRenderShape(int blockId);

public static native void nativeSetBlockRenderShape(int blockId, int renderType);

// Custom block renderers
public static native void nativeRenderStandardBlock(int blockId, int x, int y, int z);

public static native void nativeRenderCrossBlock(int blockId, int x, int y, int z);

public static native void nativeRenderTorchBlock(int blockId, int x, int y, int z);


// setup
public static native void nativeSetupHooks(int versionCode);

Expand Down Expand Up @@ -1497,6 +1515,7 @@ public static int spawnMob(double x, double y, double z, int typeId, String tex)
return entityId;
}


@JSStaticFunction
public static String getSignText(int x, int y, int z, int line) {
if (line < 0 || line >= 4)
Expand Down Expand Up @@ -2205,6 +2224,16 @@ public static void setDestroyTime(int blockId, double time) {
nativeBlockSetDestroyTime(blockId, (float) time);
}

@JSStaticFunction
public static int getRenderType(int blockId) {
return nativeGetBlockRenderShape(blockId);
}

@JSStaticFunction
public static void setRenderType(int blockId, int renderType) {
nativeSetBlockRenderShape(blockId, renderType);
}

@JSStaticFunction
public static void setExplosionResistance(int blockId, double resist) {
nativeBlockSetExplosionResistance(blockId, (float) resist);
Expand Down Expand Up @@ -2317,6 +2346,31 @@ public String getClassName() {
return "Gui";
}
}

private static class NativeBlockRendererApi extends ScriptableObject {
public NativeBlockRendererApi() {
}

@JSStaticFunction
public static void renderBlock(int blockId, int x, int y, int z) {
nativeRenderStandardBlock(blockId, x, y, z);
}

@JSStaticFunction
public static void renderCross(int blockId, int x, int y, int z) {
nativeRenderCrossBlock(blockId, x, y, z);
}

@JSStaticFunction
public static void renderTorch(int blockId, int x, int y, int z) {
nativeRenderTorchBlock(blockId, x, y, z);
}

@Override
public String getClassName() {
return "BlockRenderer";
}
}

private static class SelectLevelRequest {
public String dir;
Expand Down