From 55ed83ddb842cb2a6c9d9d9dd5979bcaed7e4aaf Mon Sep 17 00:00:00 2001 From: PeachyPeach <72323920+PeachyPeachSM64@users.noreply.github.com> Date: Thu, 3 Nov 2022 03:45:20 +0100 Subject: [PATCH] djui_hud_render_texture_tile[_interpolated]; increased GFX pool and main memory pool (#211) djui_hud_render_texture_tile: allows user to draw a part of a texture instead of the whole texture (tilesets) increased GFX pool size from 512kB to 4MB increased main memory pool size from ~11MB to 32MB --- autogen/convert_functions.py | 2 +- autogen/lua_definitions/manual.lua | 32 ++++++++ src/game/memory.h | 4 +- src/pc/djui/djui_gfx.c | 21 ++++++ src/pc/djui/djui_gfx.h | 1 + src/pc/djui/djui_hud_utils.c | 51 +++++++++++++ src/pc/djui/djui_hud_utils.h | 3 + src/pc/lua/smlua_functions.c | 116 +++++++++++++++++++++++++++++ 8 files changed, 227 insertions(+), 3 deletions(-) diff --git a/autogen/convert_functions.py b/autogen/convert_functions.py index af75cee40..6da7ba4ec 100644 --- a/autogen/convert_functions.py +++ b/autogen/convert_functions.py @@ -95,7 +95,7 @@ override_disallowed_functions = { "src/game/camera.h": [ "update_camera", "init_camera", "stub_camera", "^reset_camera", "move_point_along_spline" ], "src/game/behavior_actions.h": [ "bhv_dust_smoke_loop", "bhv_init_room" ], "src/pc/lua/utils/smlua_audio_utils.h": [ "smlua_audio_utils_override", "audio_custom_shutdown"], - "src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw" ], + "src/pc/djui/djui_hud_utils.h": [ "djui_hud_render_texture", "djui_hud_render_texture_raw", "djui_hud_render_texture_tile", "djui_hud_render_texture_tile_raw" ], "src/pc/lua/utils/smlua_level_utils.h": [ "smlua_level_util_reset" ], } diff --git a/autogen/lua_definitions/manual.lua b/autogen/lua_definitions/manual.lua index 9effb01fb..4e585906b 100644 --- a/autogen/lua_definitions/manual.lua +++ b/autogen/lua_definitions/manual.lua @@ -166,6 +166,20 @@ function djui_hud_render_texture(texInfo, x, y, scaleW, scaleH) -- ... end +--- @param texInfo TextureInfo +--- @param x number +--- @param y number +--- @param scaleW number +--- @param scaleH number +--- @param tileX number +--- @param tileY number +--- @param tileW number +--- @param tileH number +--- @return nil +function djui_hud_render_texture_tile(texInfo, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH) + -- ... +end + --- @param texInfo TextureInfo --- @param prevX number --- @param prevY number @@ -179,3 +193,21 @@ end function djui_hud_render_texture_interpolated(texInfo, prevX, prevY, prevScaleW, prevScaleH, x, y, scaleW, scaleH) -- ... end + +--- @param texInfo TextureInfo +--- @param prevX number +--- @param prevY number +--- @param prevScaleW number +--- @param prevScaleH number +--- @param x number +--- @param y number +--- @param scaleW number +--- @param scaleH number +--- @param tileX number +--- @param tileY number +--- @param tileW number +--- @param tileH number +--- @return nil +function djui_hud_render_texture_tile_interpolated(texInfo, prevX, prevY, prevScaleW, prevScaleH, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH) + -- ... +end diff --git a/src/game/memory.h b/src/game/memory.h index a1eba8a72..4579c18c7 100644 --- a/src/game/memory.h +++ b/src/game/memory.h @@ -8,8 +8,8 @@ #define MEMORY_POOL_LEFT 0 #define MEMORY_POOL_RIGHT 1 -#define GFX_POOL_SIZE (512 * 1024) -#define DEFAULT_POOL_SIZE (0x165000 * 8) +#define GFX_POOL_SIZE 0x400000 // 4MB (Vanilla: 512kB) +#define DEFAULT_POOL_SIZE 0x2000000 // 32MB (Vanilla: ~11MB) struct AllocOnlyPool { diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c index 2bece2f09..49f68b852 100644 --- a/src/pc/djui/djui_gfx.c +++ b/src/pc/djui/djui_gfx.c @@ -82,6 +82,27 @@ void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize) { gSPDisplayList(gDisplayListHead++, dl_djui_image); } +void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { + Vtx *vtx = alloc_display_list(sizeof(Vtx) * 4); + vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[1] = (Vtx) {{{ 1, -1, 0 }, 0, { ((tileX + tileW) * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[2] = (Vtx) {{{ 1, 0, 0 }, 0, { ((tileX + tileW) * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize); + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); + gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_FADEA); + gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetTextureFilter(gDisplayListHead++, G_TF_POINT); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPLoadTextureBlock(gDisplayListHead++, NULL, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); + *(gDisplayListHead++) = (Gfx) gsSPExecuteDjui(G_TEXOVERRIDE_DJUI); + gSPVertex(gDisplayListHead++, vtx, 4, 0); + *(gDisplayListHead++) = (Gfx) gsSPExecuteDjui(G_TEXCLIP_DJUI); + gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0); + gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF); + gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); +} + ///////////////////////////////////////////// void djui_gfx_position_translate(f32* x, f32* y) { diff --git a/src/pc/djui/djui_gfx.h b/src/pc/djui/djui_gfx.h index 5801260ce..4777e5b5d 100644 --- a/src/pc/djui/djui_gfx.h +++ b/src/pc/djui/djui_gfx.h @@ -12,6 +12,7 @@ extern const Gfx dl_djui_img_end[]; f32 djui_gfx_get_scale(void); void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize); +void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH); void djui_gfx_position_translate(f32* x, f32* y); void djui_gfx_scale_translate(f32* width, f32* height); diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index f599d4db6..ea830d63b 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -265,10 +265,39 @@ void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } +void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { + gDjuiHudUtilsZ += 0.01f; + scaleW *= (f32) tileW / (f32) width; + scaleH *= (f32) tileH / (f32) height; + + // translate position + f32 translatedX = x; + f32 translatedY = y; + djui_hud_position_translate(&translatedX, &translatedY); + create_dl_translation_matrix(DJUI_MTX_PUSH, translatedX, translatedY, gDjuiHudUtilsZ); + + // translate scale + f32 translatedW = scaleW; + f32 translatedH = scaleH; + djui_hud_size_translate(&translatedW); + djui_hud_size_translate(&translatedH); + create_dl_scale_matrix(DJUI_MTX_NOPUSH, width * translatedW, height * translatedH, 1.0f); + + // render + djui_gfx_render_texture_tile(texture, width, height, bitSize, tileX, tileY, tileW, tileH); + + // pop + gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); +} + void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH) { djui_hud_render_texture_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, x, y, scaleW, scaleH); } +void djui_hud_render_texture_tile(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { + djui_hud_render_texture_tile_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH); +} + void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH) { Gfx* savedHeadPos = gDisplayListHead; f32 savedZ = gDjuiHudUtilsZ; @@ -291,6 +320,28 @@ void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX interp->z = savedZ; } +void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { + Gfx* savedHeadPos = gDisplayListHead; + f32 savedZ = gDjuiHudUtilsZ; + + djui_hud_render_texture_tile_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, prevX, prevY, prevScaleW, prevScaleH, tileX, tileY, tileW, tileH); + + if (sInterpHudCount >= MAX_INTERP_HUD) { return; } + struct InterpHud* interp = &sInterpHuds[sInterpHudCount++]; + interp->headPos = savedHeadPos; + interp->prevX = prevX; + interp->prevY = prevY; + interp->prevScaleW = prevScaleW; + interp->prevScaleH = prevScaleH; + interp->x = x; + interp->y = y; + interp->scaleW = scaleW; + interp->scaleH = scaleH; + interp->width = texInfo->width; + interp->height = texInfo->height; + interp->z = savedZ; +} + void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height) { gDjuiHudUtilsZ += 0.01f; diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index a6487777b..b4443d00f 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -50,7 +50,10 @@ f32 djui_hud_measure_text(const char* message); void djui_hud_print_text(const char* message, float x, float y, float scale); void djui_hud_render_texture(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH); void djui_hud_render_texture_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH); +void djui_hud_render_texture_tile(struct TextureInfo* texInfo, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); +void djui_hud_render_texture_tile_raw(const u8* texture, u32 bitSize, u32 width, u32 height, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); void djui_hud_render_texture_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH); +void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 prevX, f32 prevY, f32 prevScaleW, f32 prevScaleH, f32 x, f32 y, f32 scaleW, f32 scaleH, u32 tileX, u32 tileY, u32 tileW, u32 tileH); void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height); void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height); diff --git a/src/pc/lua/smlua_functions.c b/src/pc/lua/smlua_functions.c index 32a455f66..130899f85 100644 --- a/src/pc/lua/smlua_functions.c +++ b/src/pc/lua/smlua_functions.c @@ -292,6 +292,59 @@ int smlua_func_djui_hud_render_texture(lua_State* L) { return 1; } +int smlua_func_djui_hud_render_texture_tile(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 9)) { return 0; } + + struct TextureInfo tmpTexInfo = { 0 }; + struct TextureInfo* texInfo = &tmpTexInfo; + + if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) { + texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; } + } else { + int top = lua_gettop(L); + lua_pushvalue(L, 1); + + lua_pushstring(L, "texture"); + lua_gettable(L, top+1); + tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P); + lua_pop(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; } + + tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; } + + tmpTexInfo.width = smlua_get_integer_field(top+1, "width"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; } + + tmpTexInfo.height = smlua_get_integer_field(top+1, "height"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; } + + lua_settop(L, top); + } + + f32 x = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; } + f32 y = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; } + f32 scaleW = smlua_to_number(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; } + f32 scaleH = smlua_to_number(L, 5); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; } + f32 tileX = smlua_to_number(L, 6); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; } + f32 tileY = smlua_to_number(L, 7); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; } + f32 tileW = smlua_to_number(L, 8); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; } + f32 tileH = smlua_to_number(L, 9); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 9"); return 0; } + + djui_hud_render_texture_tile_raw(texInfo->texture, texInfo->bitSize, texInfo->width, texInfo->height, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH); + + return 1; +} + int smlua_func_djui_hud_render_texture_interpolated(lua_State* L) { if(!smlua_functions_valid_param_count(L, 9)) { return 0; } @@ -345,6 +398,67 @@ int smlua_func_djui_hud_render_texture_interpolated(lua_State* L) { return 1; } +int smlua_func_djui_hud_render_texture_tile_interpolated(lua_State* L) { + if(!smlua_functions_valid_param_count(L, 13)) { return 0; } + + struct TextureInfo tmpTexInfo = { 0 }; + struct TextureInfo* texInfo = &tmpTexInfo; + + if (smlua_is_cobject(L, 1, LOT_TEXTUREINFO)) { + texInfo = (struct TextureInfo*)smlua_to_cobject(L, 1, LOT_TEXTUREINFO); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1"); return 0; } + } else { + int top = lua_gettop(L); + lua_pushvalue(L, 1); + + lua_pushstring(L, "texture"); + lua_gettable(L, top+1); + tmpTexInfo.texture = smlua_to_cpointer(L, lua_gettop(L), LVT_U8_P); + lua_pop(L, 1); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'texture' field"); return 0; } + + tmpTexInfo.bitSize = smlua_get_integer_field(top+1, "bitSize"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'bitSize' field"); return 0; } + + tmpTexInfo.width = smlua_get_integer_field(top+1, "width"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'width' field"); return 0; } + + tmpTexInfo.height = smlua_get_integer_field(top+1, "height"); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 1's 'height' field"); return 0; } + + lua_settop(L, top); + } + + f32 prevX = smlua_to_number(L, 2); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 2"); return 0; } + f32 prevY = smlua_to_number(L, 3); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 3"); return 0; } + f32 prevScaleW = smlua_to_number(L, 4); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 4"); return 0; } + f32 prevScaleH = smlua_to_number(L, 5); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 5"); return 0; } + f32 x = smlua_to_number(L, 6); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 6"); return 0; } + f32 y = smlua_to_number(L, 7); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 7"); return 0; } + f32 scaleW = smlua_to_number(L, 8); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 8"); return 0; } + f32 scaleH = smlua_to_number(L, 9); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 9"); return 0; } + f32 tileX = smlua_to_number(L, 10); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 10"); return 0; } + f32 tileY = smlua_to_number(L, 11); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 11"); return 0; } + f32 tileW = smlua_to_number(L, 12); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 12"); return 0; } + f32 tileH = smlua_to_number(L, 13); + if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter 13"); return 0; } + + djui_hud_render_texture_tile_interpolated(texInfo, prevX, prevY, prevScaleW, prevScaleH, x, y, scaleW, scaleH, tileX, tileY, tileW, tileH); + + return 1; +} + ////////// // bind // ////////// @@ -365,5 +479,7 @@ void smlua_bind_functions(void) { smlua_bind_function(L, "network_send_to", smlua_func_network_send_to); smlua_bind_function(L, "get_texture_info", smlua_func_get_texture_info); smlua_bind_function(L, "djui_hud_render_texture", smlua_func_djui_hud_render_texture); + smlua_bind_function(L, "djui_hud_render_texture_tile", smlua_func_djui_hud_render_texture_tile); smlua_bind_function(L, "djui_hud_render_texture_interpolated", smlua_func_djui_hud_render_texture_interpolated); + smlua_bind_function(L, "djui_hud_render_texture_tile_interpolated", smlua_func_djui_hud_render_texture_tile_interpolated); }