diff --git a/source/core/screen.c b/source/core/screen.c index 1235dbf..2cf31fd 100644 --- a/source/core/screen.c +++ b/source/core/screen.c @@ -12,7 +12,7 @@ #include "default_shbin.h" -GX_TRANSFER_FORMAT gpu_to_gx_format[13] = { +static GX_TRANSFER_FORMAT gpu_to_gx_format[13] = { GX_TRANSFER_FMT_RGBA8, GX_TRANSFER_FMT_RGB8, GX_TRANSFER_FMT_RGB5A1, @@ -28,8 +28,6 @@ GX_TRANSFER_FORMAT gpu_to_gx_format[13] = { GX_TRANSFER_FMT_RGBA8 // Unsupported }; -static u32 color_config[NUM_COLORS] = {0xFF000000}; - static bool c3d_initialized; static bool shader_initialized; @@ -41,19 +39,19 @@ static C3D_RenderTarget* target_bottom; static C3D_Mtx projection_top; static C3D_Mtx projection_bottom; -static struct { - bool initialized; - C3D_Tex tex; - u32 width; - u32 height; - u32 pow2Width; - u32 pow2Height; -} textures[MAX_TEXTURES]; - static C3D_Tex* glyph_sheets; static u8 base_alpha = 0xFF; +static u32 color_config[MAX_COLORS] = {0xFF000000}; + +static struct { + bool allocated; + C3D_Tex tex; + u32 width; + u32 height; +} textures[MAX_TEXTURES]; + static FILE* screen_open_resource(const char* path) { u32 realPathSize = strlen(path) + 17; char realPath[realPathSize]; @@ -70,6 +68,32 @@ static FILE* screen_open_resource(const char* path) { } } +static void screen_set_blend(u32 color, bool rgb, bool alpha) { + C3D_TexEnv* env = C3D_GetTexEnv(0); + if(env == NULL) { + util_panic("Failed to retrieve combiner settings."); + return; + } + + if(rgb) { + C3D_TexEnvSrc(env, C3D_RGB, GPU_CONSTANT, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); + } else { + C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); + } + + if(alpha) { + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); + } else { + C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); + C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); + } + + C3D_TexEnvColor(env, color); +} + void screen_init() { if(!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE * 4)) { util_panic("Failed to initialize the GPU."); @@ -78,25 +102,28 @@ void screen_init() { c3d_initialized = true; - target_top = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + u32 displayFlags = GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO); + + target_top = C3D_RenderTargetCreate(TOP_SCREEN_HEIGHT, TOP_SCREEN_WIDTH, GPU_RB_RGB8, 0); if(target_top == NULL) { util_panic("Failed to initialize the top screen target."); return; } - u32 displayFlags = GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO); - - C3D_RenderTargetSetClear(target_top, C3D_CLEAR_ALL, 0, 0); C3D_RenderTargetSetOutput(target_top, GFX_TOP, GFX_LEFT, displayFlags); + C3D_RenderTargetSetClear(target_top, C3D_CLEAR_ALL, 0, 0); - target_bottom = C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + target_bottom = C3D_RenderTargetCreate(BOTTOM_SCREEN_HEIGHT, BOTTOM_SCREEN_WIDTH, GPU_RB_RGB8, 0); if(target_bottom == NULL) { util_panic("Failed to initialize the bottom screen target."); return; } - C3D_RenderTargetSetClear(target_bottom, C3D_CLEAR_ALL, 0, 0); C3D_RenderTargetSetOutput(target_bottom, GFX_BOTTOM, GFX_LEFT, displayFlags); + C3D_RenderTargetSetClear(target_bottom, C3D_CLEAR_ALL, 0, 0); + + Mtx_OrthoTilt(&projection_top, 0.0, TOP_SCREEN_WIDTH, TOP_SCREEN_HEIGHT, 0.0, 0.0, 1.0, true); + Mtx_OrthoTilt(&projection_bottom, 0.0, BOTTOM_SCREEN_WIDTH, BOTTOM_SCREEN_HEIGHT, 0.0, 0.0, 1.0, true); dvlb = DVLB_ParseFile((u32*) default_shbin, default_shbin_len); if(dvlb == NULL) { @@ -130,20 +157,9 @@ void screen_init() { AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); AttrInfo_AddLoader(attrInfo, 1, GPU_FLOAT, 2); - C3D_TexEnv* env = C3D_GetTexEnv(0); - if(env == NULL) { - util_panic("Failed to retrieve combiner settings."); - return; - } - - C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvOp(env, C3D_Both, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR); - C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); - C3D_DepthTest(true, GPU_GEQUAL, GPU_WRITE_ALL); - Mtx_OrthoTilt(&projection_top, 0.0, 400.0, 240.0, 0.0, 0.0, 1.0, true); - Mtx_OrthoTilt(&projection_bottom, 0.0, 320.0, 240.0, 0.0, 0.0, 1.0, true); + screen_set_blend(0, false, false); Result fontMapRes = fontEnsureMapped(); if(R_FAILED(fontMapRes)) { @@ -308,6 +324,25 @@ static u32 screen_next_pow_2(u32 i) { return i; } +u32 screen_allocate_free_texture() { + u32 id = 0; + for(u32 i = 1; i < MAX_TEXTURES; i++) { + if(!textures[i].allocated) { + textures[i].allocated = true; + + id = i; + break; + } + } + + if(id == 0) { + util_panic("Out of free textures."); + return 0; + } + + return id; +} + void screen_load_texture(u32 id, void* data, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter) { if(id >= MAX_TEXTURES) { util_panic("Attempted to load buffer to invalid texture ID \"%lu\".", id); @@ -345,49 +380,33 @@ void screen_load_texture(u32 id, void* data, u32 size, u32 width, u32 height, GP } } - textures[id].initialized = true; - textures[id].width = width; - textures[id].height = height; - textures[id].pow2Width = pow2Width; - textures[id].pow2Height = pow2Height; + if(textures[id].tex.data != NULL && (textures[id].tex.size != size || textures[id].tex.width != pow2Width || textures[id].tex.height != pow2Height || textures[id].tex.fmt != format)) { + C3D_TexDelete(&textures[id].tex); + } - if(!C3D_TexInit(&textures[id].tex, (int) pow2Width, (int) pow2Height, format)) { - util_panic("Failed to initialize texture."); + if(textures[id].tex.data == NULL && !C3D_TexInit(&textures[id].tex, (int) pow2Width, (int) pow2Height, format)) { + util_panic("Failed to initialize texture with ID \"%lu\".", id); return; } C3D_TexSetFilter(&textures[id].tex, linearFilter ? GPU_LINEAR : GPU_NEAREST, GPU_NEAREST); - Result flushRes = GSPGPU_FlushDataCache(pow2Tex, pow2Width * pow2Height * 4); + Result flushRes = GSPGPU_FlushDataCache(pow2Tex, pow2Width * pow2Height * pixelSize); if(R_FAILED(flushRes)) { - util_panic("Failed to flush texture buffer: 0x%08lX", flushRes); + util_panic("Failed to flush buffer for texture ID \"%lu\": 0x%08lX", id, flushRes); return; } C3D_SafeDisplayTransfer((u32*) pow2Tex, GX_BUFFER_DIM(pow2Width, pow2Height), (u32*) textures[id].tex.data, GX_BUFFER_DIM(pow2Width, pow2Height), GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT((u32) gpu_to_gx_format[format]) | GX_TRANSFER_OUT_FORMAT((u32) gpu_to_gx_format[format]) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)); gspWaitForPPF(); + textures[id].allocated = true; + textures[id].width = width; + textures[id].height = height; + linearFree(pow2Tex); } -u32 screen_load_texture_auto(void* tiledData, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter) { - int id = -1; - for(int i = TEXTURE_AUTO_START; i < MAX_TEXTURES; i++) { - if(!textures[i].initialized) { - id = i; - break; - } - } - - if(id == -1) { - util_panic("Attempted to load auto texture from buffer without free textures."); - return 0; - } - - screen_load_texture((u32) id, tiledData, size, width, height, format, linearFilter); - return (u32) id; -} - void screen_load_texture_file(u32 id, const char* path, bool linearFilter) { if(id >= MAX_TEXTURES) { util_panic("Attempted to load path \"%s\" to invalid texture ID \"%lu\".", path, id); @@ -432,24 +451,6 @@ void screen_load_texture_file(u32 id, const char* path, bool linearFilter) { free(image); } -u32 screen_load_texture_file_auto(const char* path, bool linearFilter) { - int id = -1; - for(int i = TEXTURE_AUTO_START; i < MAX_TEXTURES; i++) { - if(!textures[i].initialized) { - id = i; - break; - } - } - - if(id == -1) { - util_panic("Attempted to load auto texture from path \"%s\" without free textures.", path); - return 0; - } - - screen_load_texture_file((u32) id, path, linearFilter); - return (u32) id; -} - static u32 screen_tiled_texture_index(u32 x, u32 y, u32 w, u32 h) { return (((y >> 3) * (w >> 3) + (x >> 3)) << 6) + ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3)); } @@ -460,7 +461,7 @@ void screen_load_texture_tiled(u32 id, void* tiledData, u32 size, u32 width, u32 return; } - u8* untiledData = (u8*) calloc(1, size); + u8* untiledData = (u8*) calloc(size, sizeof(u8)); if(untiledData == NULL) { util_panic("Failed to allocate buffer for texture untiling."); return; @@ -484,43 +485,21 @@ void screen_load_texture_tiled(u32 id, void* tiledData, u32 size, u32 width, u32 free(untiledData); } -u32 screen_load_texture_tiled_auto(void* tiledData, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter) { - int id = -1; - for(int i = TEXTURE_AUTO_START; i < MAX_TEXTURES; i++) { - if(!textures[i].initialized) { - id = i; - break; - } - } - - if(id == -1) { - util_panic("Attempted to load auto texture from tiled data without free textures."); - return 0; - } - - screen_load_texture_tiled((u32) id, tiledData, size, width, height, format, linearFilter); - return (u32) id; -} - void screen_unload_texture(u32 id) { if(id >= MAX_TEXTURES) { util_panic("Attempted to unload invalid texture ID \"%lu\".", id); return; } - if(textures[id].initialized) { - C3D_TexDelete(&textures[id].tex); + C3D_TexDelete(&textures[id].tex); - textures[id].initialized = false; - textures[id].width = 0; - textures[id].height = 0; - textures[id].pow2Width = 0; - textures[id].pow2Height = 0; - } + textures[id].allocated = false; + textures[id].width = 0; + textures[id].height = 0; } void screen_get_texture_size(u32* width, u32* height, u32 id) { - if(id >= MAX_TEXTURES || !textures[id].initialized) { + if(id >= MAX_TEXTURES) { util_panic("Attempted to get size of invalid texture ID \"%lu\".", id); return; } @@ -534,56 +513,6 @@ void screen_get_texture_size(u32* width, u32* height, u32 id) { } } -void screen_begin_frame() { - if(!C3D_FrameBegin(C3D_FRAME_SYNCDRAW)) { - util_panic("Failed to begin frame."); - return; - } -} - -void screen_end_frame() { - C3D_FrameEnd(0); -} - -void screen_select(gfxScreen_t screen) { - if(!C3D_FrameDrawOn(screen == GFX_TOP ? target_top : target_bottom)) { - util_panic("Failed to select render target."); - return; - } - - C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, shaderInstanceGetUniformLocation(program.vertexShader, "projection"), screen == GFX_TOP ? &projection_top : &projection_bottom); -} - -void screen_set_scissor(bool enabled, u32 x, u32 y, u32 width, u32 height) { - C3D_SetScissor(enabled ? GPU_SCISSOR_NORMAL : GPU_SCISSOR_DISABLE, 240 - (y + height), x, 240 - y, x + width); -} - -static void screen_set_blend(u32 color, bool rgb, bool alpha) { - C3D_TexEnv* env = C3D_GetTexEnv(0); - if(env == NULL) { - util_panic("Failed to retrieve combiner settings."); - return; - } - - if(rgb) { - C3D_TexEnvSrc(env, C3D_RGB, GPU_CONSTANT, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); - } else { - C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE); - } - - if(alpha) { - C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE); - } else { - C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR); - C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE); - } - - C3D_TexEnvColor(env, color); -} - static void screen_draw_quad(float x1, float y1, float x2, float y2, float tx1, float ty1, float tx2, float ty2) { C3D_ImmDrawBegin(GPU_TRIANGLES); @@ -608,18 +537,42 @@ static void screen_draw_quad(float x1, float y1, float x2, float y2, float tx1, C3D_ImmDrawEnd(); } +void screen_begin_frame() { + if(!C3D_FrameBegin(C3D_FRAME_SYNCDRAW)) { + util_panic("Failed to begin frame."); + return; + } +} + +void screen_end_frame() { + C3D_FrameEnd(0); +} + +void screen_select(gfxScreen_t screen) { + if(!C3D_FrameDrawOn(screen == GFX_TOP ? target_top : target_bottom)) { + util_panic("Failed to select render target."); + return; + } + + C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, shaderInstanceGetUniformLocation(program.vertexShader, "projection"), screen == GFX_TOP ? &projection_top : &projection_bottom); +} + void screen_draw_texture(u32 id, float x, float y, float width, float height) { - if(id >= MAX_TEXTURES || !textures[id].initialized) { + if(id >= MAX_TEXTURES) { util_panic("Attempted to draw invalid texture ID \"%lu\".", id); return; } + if(textures[id].tex.data == NULL) { + return; + } + if(base_alpha != 0xFF) { screen_set_blend(base_alpha << 24, false, true); } C3D_TexBind(0, &textures[id].tex); - screen_draw_quad(x, y, x + width, y + height, 0, 0, (float) textures[id].width / (float) textures[id].pow2Width, (float) textures[id].height / (float) textures[id].pow2Height); + screen_draw_quad(x, y, x + width, y + height, 0, 0, (float) textures[id].width / (float) textures[id].tex.width, (float) textures[id].height / (float) textures[id].tex.height); if(base_alpha != 0xFF) { screen_set_blend(0, false, false); @@ -627,17 +580,21 @@ void screen_draw_texture(u32 id, float x, float y, float width, float height) { } void screen_draw_texture_crop(u32 id, float x, float y, float width, float height) { - if(id >= MAX_TEXTURES || !textures[id].initialized) { + if(id >= MAX_TEXTURES) { util_panic("Attempted to draw invalid texture ID \"%lu\".", id); return; } + if(textures[id].tex.data == NULL) { + return; + } + if(base_alpha != 0xFF) { screen_set_blend(base_alpha << 24, false, true); } C3D_TexBind(0, &textures[id].tex); - screen_draw_quad(x, y, x + width, y + height, 0, 0, width / (float) textures[id].pow2Width, height / (float) textures[id].pow2Height); + screen_draw_quad(x, y, x + width, y + height, 0, 0, width / (float) textures[id].tex.width, height / (float) textures[id].tex.height); if(base_alpha != 0xFF) { screen_set_blend(0, false, false); @@ -715,6 +672,11 @@ static void screen_draw_string_internal(const char* text, float x, float y, floa return; } + if(colorId >= MAX_COLORS) { + util_panic("Attempted to draw string with invalid color ID \"%lu\".", colorId); + return; + } + u32 blendColor = color_config[colorId]; if(base_alpha != 0xFF) { float alpha1 = ((blendColor >> 24) & 0xFF) / 255.0f; diff --git a/source/core/screen.h b/source/core/screen.h index 9b65bd7..e21b5df 100644 --- a/source/core/screen.h +++ b/source/core/screen.h @@ -40,9 +40,7 @@ #define TEXTURE_WIFI_2 30 #define TEXTURE_WIFI_3 31 -#define TEXTURE_AUTO_START 32 - -#define NUM_COLORS 13 +#define MAX_COLORS 13 #define COLOR_TEXT 0 #define COLOR_NAND 1 @@ -61,18 +59,16 @@ void screen_init(); void screen_exit(); void screen_set_base_alpha(u8 alpha); +u32 screen_allocate_free_texture(); void screen_load_texture(u32 id, void* data, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); -u32 screen_load_texture_auto(void* data, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); void screen_load_texture_file(u32 id, const char* path, bool linearFilter); -u32 screen_load_texture_file_auto(const char* path, bool linearFilter); void screen_load_texture_tiled(u32 id, void* tiledData, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); -u32 screen_load_texture_tiled_auto(void* tiledData, u32 size, u32 width, u32 height, GPU_TEXCOLOR format, bool linearFilter); +void screen_load_texture_screenshot(u32 id, gfxScreen_t screen); void screen_unload_texture(u32 id); void screen_get_texture_size(u32* width, u32* height, u32 id); void screen_begin_frame(); void screen_end_frame(); void screen_select(gfxScreen_t screen); -void screen_set_scissor(bool enabled, u32 x, u32 y, u32 width, u32 height); void screen_draw_texture(u32 id, float x, float y, float width, float height); void screen_draw_texture_crop(u32 id, float x, float y, float width, float height); float screen_get_font_height(float scaleY); diff --git a/source/main.c b/source/main.c index 2eef5a6..3d7ceca 100644 --- a/source/main.c +++ b/source/main.c @@ -61,20 +61,20 @@ static bool attempt_patch_pid() { return backdoor_ran; } -static void (*exitFuncs[16])()= {NULL}; -static u32 exitFuncCount = 0; +static void (*exit_funcs[16])()= {NULL}; +static u32 exit_func_count = 0; static void* soc_buffer = NULL; void cleanup_services() { - for(u32 i = 0; i < exitFuncCount; i++) { - if(exitFuncs[i] != NULL) { - exitFuncs[i](); - exitFuncs[i] = NULL; + for(u32 i = 0; i < exit_func_count; i++) { + if(exit_funcs[i] != NULL) { + exit_funcs[i](); + exit_funcs[i] = NULL; } } - exitFuncCount = 0; + exit_func_count = 0; if(soc_buffer != NULL) { free(soc_buffer); @@ -82,7 +82,7 @@ void cleanup_services() { } } -#define INIT_SERVICE(initStatement, exitFunc) (R_SUCCEEDED(res = (initStatement)) && (exitFuncs[exitFuncCount++] = (exitFunc))) +#define INIT_SERVICE(initStatement, exitFunc) (R_SUCCEEDED(res = (initStatement)) && (exit_funcs[exit_func_count++] = (exitFunc))) Result init_services() { Result res = 0; @@ -125,7 +125,7 @@ void init() { if(R_FAILED(init_services())) { if(!attempt_patch_pid()) { - util_panic("Kernel backdoor not installed.\nPlease run a kernel exploit and try again.\n"); + util_panic("Kernel backdoor not installed.\nPlease run a kernel exploit and try again."); return; } diff --git a/source/ui/list.c b/source/ui/list.c index 1f475e9..d69c218 100644 --- a/source/ui/list.c +++ b/source/ui/list.c @@ -236,8 +236,7 @@ static void list_draw_bottom(ui_view* view, void* data, float x1, float y1, floa if(item == listData->selectedItem) { u32 selectionOverlayWidth = 0; - u32 selectionOverlayHeight = 0; - screen_get_texture_size(&selectionOverlayWidth, &selectionOverlayHeight, TEXTURE_SELECTION_OVERLAY); + screen_get_texture_size(&selectionOverlayWidth, NULL, TEXTURE_SELECTION_OVERLAY); screen_draw_texture(TEXTURE_SELECTION_OVERLAY, (x1 + x2 - selectionOverlayWidth) / 2, y, selectionOverlayWidth, fontHeight); } } diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index cce5e27..e3cfed6 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -139,7 +139,10 @@ static Result action_install_cias_open_dst(void* data, u32 index, void* initialR } // Deleting FBI before it reinstalls itself causes issues. - if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { + u64 currTitleId = 0; + FS_MediaType currMediaType = MEDIATYPE_NAND; + + if(envIsHomebrew() || R_FAILED(APT_GetAppletInfo((NS_APPID) envGetAptAppId(), &currTitleId, (u8*) &currMediaType, NULL, NULL, NULL)) || titleId != currTitleId || dest != currMediaType) { AM_DeleteTitle(dest, titleId); AM_DeleteTicket(titleId); diff --git a/source/ui/section/action/urlinstall.c b/source/ui/section/action/urlinstall.c index a7e8984..8322ed6 100644 --- a/source/ui/section/action/urlinstall.c +++ b/source/ui/section/action/urlinstall.c @@ -140,7 +140,10 @@ static Result action_url_install_open_dst(void* data, u32 index, void* initialRe } // Deleting FBI before it reinstalls itself causes issues. - if(((titleId >> 8) & 0xFFFFF) != 0xF8001) { + u64 currTitleId = 0; + FS_MediaType currMediaType = MEDIATYPE_NAND; + + if(envIsHomebrew() || R_FAILED(APT_GetAppletInfo((NS_APPID) envGetAptAppId(), &currTitleId, (u8*) &currMediaType, NULL, NULL, NULL)) || titleId != currTitleId || dest != currMediaType) { AM_DeleteTitle(dest, titleId); AM_DeleteTicket(titleId); diff --git a/source/ui/section/remoteinstall.c b/source/ui/section/remoteinstall.c index 596a577..be5dd03 100644 --- a/source/ui/section/remoteinstall.c +++ b/source/ui/section/remoteinstall.c @@ -333,18 +333,13 @@ static void remoteinstall_qr_update(ui_view* view, void* data, float* progress, return; } - if(installData->tex != 0) { - screen_unload_texture(installData->tex); - installData->tex = 0; - } - int w = 0; int h = 0; uint8_t* qrBuf = quirc_begin(installData->qrContext, &w, &h); svcWaitSynchronization(installData->captureInfo.mutex, U64_MAX); - installData->tex = screen_load_texture_auto(installData->captureInfo.buffer, QR_IMAGE_WIDTH * QR_IMAGE_HEIGHT * sizeof(u16), QR_IMAGE_WIDTH, QR_IMAGE_HEIGHT, GPU_RGB565, false); + screen_load_texture(installData->tex, installData->captureInfo.buffer, QR_IMAGE_WIDTH * QR_IMAGE_HEIGHT * sizeof(u16), QR_IMAGE_WIDTH, QR_IMAGE_HEIGHT, GPU_RGB565, false); for(int x = 0; x < w; x++) { for(int y = 0; y < h; y++) { @@ -418,6 +413,8 @@ void remoteinstall_scan_qr_code() { return; } + data->tex = screen_allocate_free_texture(); + info_display("QR Code Install", "B: Return", false, data, remoteinstall_qr_update, remoteinstall_qr_draw_top); } diff --git a/source/ui/section/task/listextsavedata.c b/source/ui/section/task/listextsavedata.c index b13c2fa..4418a9a 100644 --- a/source/ui/section/task/listextsavedata.c +++ b/source/ui/section/task/listextsavedata.c @@ -62,7 +62,8 @@ static Result task_populate_ext_save_data_from(populate_ext_save_data_data* data utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(extSaveDataInfo->meta.longDescription) - 1); utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(extSaveDataInfo->meta.publisher) - 1); extSaveDataInfo->meta.region = smdh->region; - extSaveDataInfo->meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); + extSaveDataInfo->meta.texture = screen_allocate_free_texture(); + screen_load_texture_tiled(extSaveDataInfo->meta.texture, smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); } } diff --git a/source/ui/section/task/listfiles.c b/source/ui/section/task/listfiles.c index 3835076..32bcba1 100644 --- a/source/ui/section/task/listfiles.c +++ b/source/ui/section/task/listfiles.c @@ -84,7 +84,8 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(fileInfo->ciaInfo.meta.longDescription) - 1); utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(fileInfo->ciaInfo.meta.publisher) - 1); fileInfo->ciaInfo.meta.region = smdh->region; - fileInfo->ciaInfo.meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); + fileInfo->ciaInfo.meta.texture = screen_allocate_free_texture(); + screen_load_texture_tiled(fileInfo->ciaInfo.meta.texture, smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); } } diff --git a/source/ui/section/task/listtitledb.c b/source/ui/section/task/listtitledb.c index 1556892..1138045 100644 --- a/source/ui/section/task/listtitledb.c +++ b/source/ui/section/task/listtitledb.c @@ -176,7 +176,8 @@ static void task_populate_titledb_thread(void* arg) { } } - titledbInfo->meta.texture = screen_load_texture_auto(image, (u32) (width * height * 4), (u32) width, (u32) height, GPU_RGBA8, false); + titledbInfo->meta.texture = screen_allocate_free_texture(); + screen_load_texture(titledbInfo->meta.texture, image, (u32) (width * height * 4), (u32) width, (u32) height, GPU_RGBA8, false); free(image); } diff --git a/source/ui/section/task/listtitles.c b/source/ui/section/task/listtitles.c index 8fbbc12..cf0e60d 100644 --- a/source/ui/section/task/listtitles.c +++ b/source/ui/section/task/listtitles.c @@ -51,7 +51,8 @@ static Result task_populate_titles_add_ctr(populate_titles_data* data, FS_MediaT utf16_to_utf8((uint8_t*) titleInfo->meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(titleInfo->meta.longDescription) - 1); utf16_to_utf8((uint8_t*) titleInfo->meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(titleInfo->meta.publisher) - 1); titleInfo->meta.region = smdh->region; - titleInfo->meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); + titleInfo->meta.texture = screen_allocate_free_texture(); + screen_load_texture_tiled(titleInfo->meta.texture, smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false); } } @@ -193,7 +194,8 @@ static Result task_populate_titles_add_twl(populate_titles_data* data, FS_MediaT titleInfo->meta.region = 0; } - titleInfo->meta.texture = screen_load_texture_auto(icon, sizeof(icon), 32, 32, GPU_RGBA5551, false); + titleInfo->meta.texture = screen_allocate_free_texture(); + screen_load_texture(titleInfo->meta.texture, icon, sizeof(icon), 32, 32, GPU_RGBA5551, false); } free(bnr); diff --git a/source/ui/section/task/task.c b/source/ui/section/task/task.c index bf907e6..e397cec 100644 --- a/source/ui/section/task/task.c +++ b/source/ui/section/task/task.c @@ -33,14 +33,14 @@ void task_init() { Result res = 0; if(R_FAILED(res = svcCreateEvent(&task_pause_event, RESET_STICKY))) { - util_panic("Failed to create task awake event: 0x%08lX", res); + util_panic("Failed to create task pause event: 0x%08lX", res); return; } if(R_FAILED(res = svcCreateEvent(&task_suspend_event, RESET_STICKY))) { svcCloseHandle(task_pause_event); - util_panic("Failed to create task awake event: 0x%08lX", res); + util_panic("Failed to create task suspend event: 0x%08lX", res); return; } diff --git a/source/ui/ui.c b/source/ui/ui.c index 27132ad..8cd63b6 100644 --- a/source/ui/ui.c +++ b/source/ui/ui.c @@ -21,7 +21,7 @@ static u64 ui_free_space_last_update = 0; static char ui_free_space_buffer[128]; static u64 ui_fade_begin_time = 0; -static u8 ui_fade_in_alpha = 0; +static u8 ui_fade_alpha = 0; void ui_init() { if(ui_stack_mutex == 0) { @@ -108,6 +108,8 @@ void ui_pop() { } static void ui_draw_top(ui_view* ui) { + screen_select(GFX_TOP); + u32 topScreenBgWidth = 0; u32 topScreenBgHeight = 0; screen_get_texture_size(&topScreenBgWidth, &topScreenBgHeight, TEXTURE_TOP_SCREEN_BG); @@ -128,7 +130,6 @@ static void ui_draw_top(ui_view* ui) { u32 topScreenBottomBarShadowHeight = 0; screen_get_texture_size(&topScreenBottomBarShadowWidth, &topScreenBottomBarShadowHeight, TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW); - screen_select(GFX_TOP); screen_draw_texture(TEXTURE_TOP_SCREEN_BG, (TOP_SCREEN_WIDTH - topScreenBgWidth) / 2, (TOP_SCREEN_HEIGHT - topScreenBgHeight) / 2, topScreenBgWidth, topScreenBgHeight); if(ui->drawTop != NULL) { @@ -145,7 +146,7 @@ static void ui_draw_top(ui_view* ui) { screen_draw_texture(TEXTURE_TOP_SCREEN_BOTTOM_BAR, topScreenBottomBarX, topScreenBottomBarY, topScreenBottomBarWidth, topScreenBottomBarHeight); screen_draw_texture(TEXTURE_TOP_SCREEN_BOTTOM_BAR_SHADOW, topScreenBottomBarX, topScreenBottomBarY - topScreenBottomBarShadowHeight, topScreenBottomBarShadowWidth, topScreenBottomBarShadowHeight); - screen_set_base_alpha(ui_fade_in_alpha); + screen_set_base_alpha(ui_fade_alpha); char verText[64]; snprintf(verText, 64, "Ver. %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO); @@ -259,6 +260,8 @@ static void ui_draw_top(ui_view* ui) { } static void ui_draw_bottom(ui_view* ui) { + screen_select(GFX_BOTTOM); + u32 bottomScreenBgWidth = 0; u32 bottomScreenBgHeight = 0; screen_get_texture_size(&bottomScreenBgWidth, &bottomScreenBgHeight, TEXTURE_BOTTOM_SCREEN_BG); @@ -279,10 +282,9 @@ static void ui_draw_bottom(ui_view* ui) { u32 bottomScreenBottomBarShadowHeight = 0; screen_get_texture_size(&bottomScreenBottomBarShadowWidth, &bottomScreenBottomBarShadowHeight, TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW); - screen_select(GFX_BOTTOM); screen_draw_texture(TEXTURE_BOTTOM_SCREEN_BG, (BOTTOM_SCREEN_WIDTH - bottomScreenBgWidth) / 2, (BOTTOM_SCREEN_HEIGHT - bottomScreenBgHeight) / 2, bottomScreenBgWidth, bottomScreenBgHeight); - screen_set_base_alpha(ui_fade_in_alpha); + screen_set_base_alpha(ui_fade_alpha); if(ui->drawBottom != NULL) { ui->drawBottom(ui, ui->data, 0, bottomScreenTopBarHeight, BOTTOM_SCREEN_WIDTH, BOTTOM_SCREEN_HEIGHT - bottomScreenBottomBarHeight); @@ -300,7 +302,7 @@ static void ui_draw_bottom(ui_view* ui) { screen_draw_texture(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR, bottomScreenBottomBarX, bottomScreenBottomBarY, bottomScreenBottomBarWidth, bottomScreenBottomBarHeight); screen_draw_texture(TEXTURE_BOTTOM_SCREEN_BOTTOM_BAR_SHADOW, bottomScreenBottomBarX, bottomScreenBottomBarY - bottomScreenBottomBarShadowHeight, bottomScreenBottomBarShadowWidth, bottomScreenBottomBarShadowHeight); - screen_set_base_alpha(ui_fade_in_alpha); + screen_set_base_alpha(ui_fade_alpha); if(ui->name != NULL) { float nameWidth; @@ -335,6 +337,13 @@ bool ui_update() { ui->update(ui, ui->data, 0, bottomScreenTopBarHeight, BOTTOM_SCREEN_WIDTH, BOTTOM_SCREEN_HEIGHT - bottomScreenBottomBarHeight); } + u64 time = osGetTime(); + if(!envIsHomebrew() && time - ui_fade_begin_time < 500) { + ui_fade_alpha = (u8) (((time - ui_fade_begin_time) / 500.0f) * 0xFF); + } else { + ui_fade_alpha = 0xFF; + } + ui = ui_top(); if(ui != NULL) { screen_begin_frame(); @@ -343,13 +352,6 @@ bool ui_update() { screen_end_frame(); } - u64 time = osGetTime(); - if(!envIsHomebrew() && time - ui_fade_begin_time < 500) { - ui_fade_in_alpha = (u8) (((time - ui_fade_begin_time) / 500.0f) * 0xFF); - } else { - ui_fade_in_alpha = 0xFF; - } - return ui != NULL; }