From fb71817c33b3f83e5637a2ca9a5b8a2a6f8db0d8 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 8 Feb 2019 20:13:25 +0100 Subject: [PATCH] Implementation of the ConvertImageToTexture function --- src/myutils/texture_utils.cpp | 105 ++++++++++++++++++++++++++++++++++ src/myutils/texture_utils.h | 31 ++++++++++ src/utils.cpp | 6 +- 3 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/myutils/texture_utils.cpp create mode 100644 src/myutils/texture_utils.h diff --git a/src/myutils/texture_utils.cpp b/src/myutils/texture_utils.cpp new file mode 100644 index 0000000..c5248e9 --- /dev/null +++ b/src/myutils/texture_utils.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** + * Copyright (C) 2018 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include +#include "texture_utils.h" +#include +#include +#include +#include +#include "mem_utils.h" + +void gdImageToUnormR8G8B8A8(gdImagePtr gdImg, u32 *imgBuffer, u32 width, u32 height, u32 pitch){ + for(u32 y = 0; y < height; ++y) + { + for(u32 x = 0; x < width; ++x) + { + u32 pixel = gdImageGetPixel(gdImg, x, y); + + u8 a = 254 - 2*((u8)gdImageAlpha(gdImg, pixel)); + if(a == 254) a++; + + u8 r = gdImageRed(gdImg, pixel); + u8 g = gdImageGreen(gdImg, pixel); + u8 b = gdImageBlue(gdImg, pixel); + + imgBuffer[y * pitch + x] = (r << 24) | (g << 16) | (b << 8) | (a); + } + } +} + +bool TextureUtils::convertImageToTexture(const uint8_t *img, int32_t imgSize, void * _texture){ + if(!img || (imgSize < 8) || _texture == NULL){ + return false; + } + GX2Texture * texture = (GX2Texture *) _texture; + + gdImagePtr gdImg = 0; + + if (img[0] == 0xFF && img[1] == 0xD8) { + //! not needed for now therefore comment out to safe ELF size + //! if needed uncomment, adds 200 kb to the ELF size + // IMAGE_JPEG + gdImg = gdImageCreateFromJpegPtr(imgSize, (uint8_t*) img); + } else if (img[0] == 'B' && img[1] == 'M') { + // IMAGE_BMP + //gdImg = gdImageCreateFromBmpPtr(imgSize, (uint8_t*) img); + } else if (img[0] == 0x89 && img[1] == 'P' && img[2] == 'N' && img[3] == 'G') { + // IMAGE_PNG + gdImg = gdImageCreateFromPngPtr(imgSize, (uint8_t*) img); + } + //!This must be last since it can also intefere with outher formats + else if(img[0] == 0x00) { + // Try loading TGA image + //gdImg = gdImageCreateFromTgaPtr(imgSize, (uint8_t*) img); + } + + if(gdImg == 0){ + return false; + } + + uint32_t width = (gdImageSX(gdImg)); + uint32_t height = (gdImageSY(gdImg)); + + //! Initialize texture + GX2InitTexture(texture, width, height, 1, 0, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GX2_SURFACE_DIM_2D, GX2_TILE_MODE_LINEAR_ALIGNED); + + //! if this fails something went horribly wrong + if(texture->surface.image_size == 0) { + gdImageDestroy(gdImg); + return false; + } + + texture->surface.image_data = MemoryUtils::alloc(texture->surface.image_size, texture->surface.align); + + //! check if memory is available for image + if(!texture->surface.image_data) { + gdImageDestroy(gdImg); + return false; + } + + //! set mip map data pointer + texture->surface.mip_data = NULL; + + gdImageToUnormR8G8B8A8(gdImg, (uint32_t*)texture->surface.image_data, texture->surface.width, texture->surface.height, texture->surface.pitch); + + //! free memory of image as its not needed anymore + gdImageDestroy(gdImg); + + //! invalidate the memory + GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, texture->surface.image_data, texture->surface.image_size); + return true; +} diff --git a/src/myutils/texture_utils.h b/src/myutils/texture_utils.h new file mode 100644 index 0000000..7545ed9 --- /dev/null +++ b/src/myutils/texture_utils.h @@ -0,0 +1,31 @@ +/**************************************************************************** + * Copyright (C) 2018 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef __TEXTURE_UTILS_UTILS_H_ +#define __TEXTURE_UTILS_UTILS_H_ +#include +#include + +class TextureUtils { +public: + static bool convertImageToTexture(const uint8_t *img, int32_t imgSize, void * texture); + +private: + TextureUtils() {} + ~TextureUtils() {} + +}; +#endif diff --git a/src/utils.cpp b/src/utils.cpp index 76cedca..b2008f9 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -15,6 +15,7 @@ #include "common/retain_vars.h" #include "myutils/overlay_helper.h" #include "myutils/mem_utils.h" +#include "myutils/texture_utils.h" #include "kernel/syscalls.h" void CallHook(wups_loader_hook_type_t hook_type) { @@ -67,6 +68,7 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) } else if(hook_type == WUPS_LOADER_HOOK_INIT_OVERLAY) { wups_loader_init_overlay_args_t args; args.overlayfunction_ptr = &overlay_helper; + args.textureconvertfunction_ptr = &TextureUtils::convertImageToTexture; ((void (*)(wups_loader_init_overlay_args_t))((uint32_t*)func_ptr) )(args); } else if(hook_type == WUPS_LOADER_HOOK_INIT_PLUGIN) { ((void (*)(void))((uint32_t*)func_ptr) )(); @@ -113,12 +115,12 @@ void CallHookEx(wups_loader_hook_type_t hook_type, int32_t plugin_index_needed) ((void (*)(wups_loader_init_kernel_args_t))((uint32_t*)func_ptr) )(args); plugin_data->kernel_init_done = true; } - } else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM){ + } else if(hook_type == WUPS_LOADER_HOOK_INIT_VID_MEM){ wups_loader_init_vid_mem_args_t args; args.vid_mem_alloc_ptr = &MemoryUtils::alloc; args.vid_mem_free_ptr = &MemoryUtils::free; ((void (*)(wups_loader_init_vid_mem_args_t))((uint32_t*)func_ptr) )(args); - }else { + } else { DEBUG_FUNCTION_LINE("ERROR: HOOK TYPE WAS NOT IMPLEMENTED %08X \n",hook_type); } } else {