Add textureMgr class I wrote at work and prepare a little for auto upload option

This commit is contained in:
J-D-K 2023-05-22 17:13:49 -04:00
parent 6f8393483f
commit 85bca2d66e
11 changed files with 189 additions and 82 deletions

View File

@ -32,9 +32,9 @@ include $(DEVKITPRO)/libnx/switch_rules
#---------------------------------------------------------------------------------
TARGET := JKSV
BUILD := build
SOURCES := src src/ui src/fs
SOURCES := src src/ui src/fs src/gfx
DATA := data
INCLUDES := inc inc/ui inc/fs
INCLUDES := inc inc/ui inc/fs inc/gfx
EXEFS_SRC := exefs_src
APP_TITLE := JKSV
APP_AUTHOR := JK

View File

@ -1,18 +1,17 @@
#pragma once
#include <SDL.h>
#include "textureMgr.h"
namespace gfx
{
extern SDL_Renderer *render;
extern gfx::textureMgr *texMgr;
void init();
void exit();
void present();
SDL_Texture *loadJPEGMem(const void *jpegData, size_t jpegSize);
SDL_Texture *loadImageFile(const char *file);
void drawTextf(SDL_Texture *target, int fontSize, int x, int y, const SDL_Color *c, const char *fmt, ...);
void drawTextfWrap(SDL_Texture *target, int fontSize, int x, int y, int maxWidth, const SDL_Color* c, const char *fmt, ...);
size_t getTextWidth(const char *str, int fontSize);

32
inc/gfx/textureMgr.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <vector>
#include <SDL2/SDL.h>
/*Texture manager class
Keeps pointers to ALL textures so it is not possible to forget to free them. Also keeps code a little easier to read. A little.*/
typedef enum
{
IMG_FMT_PNG,
IMG_FMT_JPG,
IMG_FMT_BMP
} imgTypes;
namespace gfx
{
class textureMgr
{
public:
textureMgr() = default;
~textureMgr();
void textureAdd(SDL_Texture *_tex);
SDL_Texture *textureCreate(int _w, int _h);
SDL_Texture *textureLoadFromFile(const char *_path);
SDL_Texture *textureLoadFromMem(imgTypes _type, const void *_dat, size_t _datSize);
private:
std::vector<SDL_Texture *> textures;
};
}

View File

@ -155,6 +155,7 @@ void cfg::resetConfig()
cfg::config["autoName"] = false;
cfg::sortType = cfg::ALPHA;
ui::animScale = 3.0f;
cfg::config["autoUpload"] = false;
}
static inline bool textToBool(const std::string& _txt)
@ -437,6 +438,10 @@ void cfg::loadConfig()
cfg::driveRefreshToken = cfgRead.getNextValueStr();
break;
case 20:
cfg::config["autoUpload"] = textToBool(cfgRead.getNextValueStr());
break;
default:
break;
}
@ -474,6 +479,7 @@ void cfg::saveConfig()
fprintf(cfgOut, "enableTrashBin = %s\n", boolToText(cfg::config["trashBin"]).c_str());
fprintf(cfgOut, "titleSortType = %s\n", sortTypeText().c_str());
fprintf(cfgOut, "animationScale = %f\n", ui::animScale);
fprintf(cfgOut, "autoUpload = %s\n", boolToText(cfg::config["autoUpload"]).c_str());
if(!cfg::driveRefreshToken.empty())
fprintf(cfgOut, "driveRefreshToken = %s\n", cfg::driveRefreshToken.c_str());

View File

@ -130,7 +130,7 @@ static inline void addTitleToList(const uint64_t& tid)
if(cfg::isFavorite(tid))
data::titles[tid].fav = true;
data::titles[tid].icon = gfx::loadJPEGMem(ctrlData->icon, iconSize);
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, ctrlData->icon, iconSize);
if(!data::titles[tid].icon)
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
}
@ -215,7 +215,7 @@ static void importSVIs()
data::titles[tid].fav = true;
if(!data::titles[tid].icon && iconSize > 0)
data::titles[tid].icon = gfx::loadJPEGMem(iconBuffer, iconSize);
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, iconBuffer, iconSize);
else if(!data::titles[tid].icon && iconSize == 0)
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
}
@ -450,7 +450,7 @@ data::user::user(const AccountUid& _id, const std::string& _backupName, const st
accountProfileGetImageSize(&prof, &jpgSize);
uint8_t *jpegData = new uint8_t[jpgSize];
accountProfileLoadImage(&prof, jpegData, jpgSize, &jpgSize);
userIcon = gfx::loadJPEGMem(jpegData, jpgSize);
userIcon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, jpegData, jpgSize);
delete[] jpegData;
accountProfileClose(&prof);

View File

@ -13,6 +13,7 @@
static SDL_Window *wind;
SDL_Renderer *gfx::render;
gfx::textureMgr *gfx::texMgr;
static FT_Library lib;
static FT_Face face[6];
@ -102,6 +103,8 @@ void gfx::init()
SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
gfx::texMgr = new gfx::textureMgr;
loadSystemFont();
}
@ -110,9 +113,7 @@ void gfx::exit()
IMG_Quit();
SDL_Quit();
freeSystemFont();
for(auto c : glyphCache)
SDL_DestroyTexture(c.second.tex);
delete gfx::texMgr;
}
void gfx::present()
@ -120,37 +121,6 @@ void gfx::present()
SDL_RenderPresent(render);
}
SDL_Texture *gfx::loadJPEGMem(const void *jpegData, size_t jpegsize)
{
SDL_Texture *ret = NULL;
SDL_RWops *jpeg = SDL_RWFromConstMem(jpegData, jpegsize);
SDL_Surface *tmpSurf = IMG_LoadJPG_RW(jpeg);
if(tmpSurf)
{
ret = SDL_CreateTextureFromSurface(render, tmpSurf);
SDL_FreeSurface(tmpSurf);
}
SDL_RWclose(jpeg);
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
return ret;
}
SDL_Texture *gfx::loadImageFile(const char *file)
{
SDL_Texture *ret = NULL;
SDL_Surface *tmpSurf = IMG_Load(file);
if(tmpSurf)
{
ret = SDL_CreateTextureFromSurface(render, tmpSurf);
SDL_FreeSurface(tmpSurf);
}
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
return ret;
}
static inline void resizeFont(int sz)
{
for(int i = 0; i < totalFonts; i++)
@ -197,6 +167,9 @@ static glyphData *getGlyph(uint32_t chr, int size)
SDL_FreeSurface(tmpSurf);
free(tmpBuff);
//Add it to texture manager so textures are freed on exit
gfx::texMgr->textureAdd(tex);
//Add it to cache map
glyphCache[std::make_pair(chr, size)] = {(uint16_t)bmp.width, (uint16_t)bmp.rows, (int)glyph->advance.x >> 6, glyph->bitmap_top, glyph->bitmap_left, tex};

108
src/gfx/textureMgr.cpp Normal file
View File

@ -0,0 +1,108 @@
#include <vector>
#include <SDL2/SDL.h>
#include <SDL_image.h>
#include "gfx.h"
gfx::textureMgr::~textureMgr()
{
for(auto tex : textures)
SDL_DestroyTexture(tex);
}
void gfx::textureMgr::textureAdd(SDL_Texture *_tex)
{
textures.push_back(_tex);
}
SDL_Texture *gfx::textureMgr::textureCreate(int _w, int _h)
{
SDL_Texture *ret = NULL;
ret = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, _w, _h);
if(ret)
textures.push_back(ret);
return ret;
}
SDL_Texture *gfx::textureMgr::textureLoadFromFile(const char *_path)
{
SDL_Texture *ret = NULL;
SDL_Surface *tmp = IMG_Load(_path);
if(tmp)
{
ret = SDL_CreateTextureFromSurface(gfx::render, tmp);
textures.push_back(ret);
SDL_FreeSurface(tmp);
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
}
return ret;
}
static SDL_Texture *loadPNGMem(const void *_dat, size_t _datSize)
{
SDL_Texture *ret = NULL;
SDL_RWops *pngData = SDL_RWFromConstMem(_dat, _datSize);
SDL_Surface *tmp = IMG_LoadPNG_RW(pngData);
if(tmp)
{
ret = SDL_CreateTextureFromSurface(gfx::render, tmp);
SDL_FreeSurface(tmp);
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
}
SDL_RWclose(pngData);
return ret;
}
static SDL_Texture *loadJPEGMem(const void *_dat, size_t _datSize)
{
SDL_Texture *ret = NULL;
SDL_RWops *jpegData = SDL_RWFromConstMem(_dat, _datSize);
SDL_Surface *tmp = IMG_LoadJPG_RW(jpegData);
if(tmp)
{
ret = SDL_CreateTextureFromSurface(gfx::render, tmp);
SDL_FreeSurface(tmp);
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
}
SDL_RWclose(jpegData);
return ret;
}
static SDL_Texture *loadBMPMem(const void *_dat, size_t _datSize)
{
SDL_Texture *ret = NULL;
SDL_RWops *bmpData = SDL_RWFromConstMem(_dat, _datSize);
SDL_Surface *tmp = IMG_LoadBMP_RW(bmpData);
if(tmp)
{
ret = SDL_CreateTextureFromSurface(gfx::render, tmp);
SDL_FreeSurface(tmp);
SDL_SetTextureBlendMode(ret, SDL_BLENDMODE_BLEND);
}
SDL_RWclose(bmpData);
return ret;
}
SDL_Texture *gfx::textureMgr::textureLoadFromMem(imgTypes _type, const void *_dat, size_t _datSize)
{
SDL_Texture *ret = NULL;
switch (_type)
{
case IMG_FMT_PNG:
ret = loadPNGMem(_dat, _datSize);
break;
case IMG_FMT_JPG:
ret = loadJPEGMem(_dat, _datSize);
break;
case IMG_FMT_BMP:
ret = loadBMPMem(_dat, _datSize);
break;
}
if(ret)
textures.push_back(ret);
return ret;
}

View File

@ -102,10 +102,10 @@ void ui::initTheme()
void ui::init()
{
mnuTopLeft = gfx::loadImageFile("romfs:/img/fb/menuTopLeft.png");
mnuTopRight = gfx::loadImageFile("romfs:/img/fb/menuTopRight.png");
mnuBotLeft = gfx::loadImageFile("romfs:/img/fb/menuBotLeft.png");
mnuBotRight = gfx::loadImageFile("romfs:/img/fb/menuBotRight.png");
mnuTopLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/menuTopLeft.png");
mnuTopRight = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/menuTopRight.png");
mnuBotLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/menuBotLeft.png");
mnuBotRight = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/menuBotRight.png");
corePanel = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET | SDL_TEXTUREACCESS_STATIC, 1220, 559);
SDL_SetTextureBlendMode(corePanel, SDL_BLENDMODE_BLEND);
@ -114,26 +114,26 @@ void ui::init()
{
case ColorSetId_Light:
//Dark corners
cornerTopLeft = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerTopLeft.png");
cornerTopRight = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerTopRight.png");
cornerBottomLeft = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerBotLeft.png");
cornerBottomRight = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerBotRight.png");
progCovLeft = gfx::loadImageFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png");
progCovRight = gfx::loadImageFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png");
icn = gfx::loadImageFile("romfs:/img/icn/icnDrk.png");
sideBar = gfx::loadImageFile("romfs:/img/fb/lLight.png");
cornerTopLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/tboxCornerTopLeft.png");
cornerTopRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/tboxCornerTopRight.png");
cornerBottomLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/tboxCornerBotLeft.png");
cornerBottomRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/tboxCornerBotRight.png");
progCovLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png");
progCovRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png");
icn = gfx::texMgr->textureLoadFromFile("romfs:/img/icn/icnDrk.png");
sideBar = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/lLight.png");
break;
default:
//Light corners
cornerTopLeft = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png");
cornerTopRight = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerTopRight.png");
cornerBottomLeft = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png");
cornerBottomRight = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerBotRight.png");
progCovLeft = gfx::loadImageFile("romfs:/img/tboxLght/progBarCoverLeftLight.png");
progCovRight = gfx::loadImageFile("romfs:/img/tboxLght/progBarCoverRightLight.png");
icn = gfx::loadImageFile("romfs:/img/icn/icnLght.png");
sideBar = gfx::loadImageFile("romfs:/img/fb/lDark.png");
cornerTopLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png");
cornerTopRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/tboxCornerTopRight.png");
cornerBottomLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png");
cornerBottomRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxDrk/tboxCornerBotRight.png");
progCovLeft = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/progBarCoverLeftLight.png");
progCovRight = gfx::texMgr->textureLoadFromFile("romfs:/img/tboxLght/progBarCoverRightLight.png");
icn = gfx::texMgr->textureLoadFromFile("romfs:/img/icn/icnLght.png");
sideBar = gfx::texMgr->textureLoadFromFile("romfs:/img/fb/lDark.png");
break;
}
@ -166,22 +166,6 @@ void ui::exit()
delete popMessages;
delete threadMngr;
SDL_DestroyTexture(cornerTopLeft);
SDL_DestroyTexture(cornerTopRight);
SDL_DestroyTexture(cornerBottomLeft);
SDL_DestroyTexture(cornerBottomRight);
SDL_DestroyTexture(progCovLeft);
SDL_DestroyTexture(progCovRight);
SDL_DestroyTexture(mnuTopLeft);
SDL_DestroyTexture(mnuTopRight);
SDL_DestroyTexture(mnuBotLeft);
SDL_DestroyTexture(mnuBotRight);
SDL_DestroyTexture(corePanel);
SDL_DestroyTexture(icn);
}
int ui::registerPanel(slideOutPanel *sop)
@ -197,12 +181,11 @@ threadInfo *ui::newThread(ThreadFunc func, void *args, funcPtr _drawFunc)
void ui::showLoadScreen()
{
SDL_Texture *icon = gfx::loadImageFile("romfs:/icon.png");
SDL_Texture *icon = gfx::texMgr->textureLoadFromFile("romfs:/icon.png");
gfx::clearTarget(NULL, &ui::clearClr);
gfx::texDraw(NULL, icon, 512, 232);
gfx::drawTextf(NULL, 16, 1100, 673, &ui::txtCont, ui::getUICString("loadingStartPage", 0));
gfx::present();
SDL_DestroyTexture(icon);
}
void ui::drawUI()

View File

@ -184,7 +184,7 @@ static void fldFuncDownload_t(void *a)
dlFile.path = targetPath;
dlFile.size = in->size;
dlFile.o = &cpy->offset;
fs::gDrive->downloadFile(in->id, &dlFile);
//fclose(dlFile.f);

View File

@ -227,6 +227,10 @@ static void toggleOpt(void *a)
if(ui::animScale > 8)
ui::animScale = 1;
break;
case 21:
toggleBool(cfg::config["autoUpload"]);
break;
}
}
@ -251,6 +255,7 @@ static void updateMenuText()
char tmp[16];
sprintf(tmp, "%.1f", ui::animScale);
ui::settMenu->editOpt(20, NULL, ui::getUIString(settMenuStr, 20) + std::string(tmp));
ui::settMenu->editOpt(21, NULL, ui::getUIString(settMenuStr, 21) + getBoolText(cfg::config["autoUpload"]));
}
void ui::settInit()
@ -267,7 +272,7 @@ void ui::settInit()
optHelpX = 1220 - gfx::getTextWidth(ui::getUICString("helpSettings", 0), 18);
for(unsigned i = 0; i < 21; i++)
for(unsigned i = 0; i < 22; i++)
{
ui::settMenu->addOpt(NULL, ui::getUIString("settingsMenu", i));
ui::settMenu->optAddButtonEvent(i, HidNpadButton_A, toggleOpt, NULL);

View File

@ -203,6 +203,7 @@ void ui::initStrings()
addUIString("settingsMenu", 18, "Enable Trash Bin: ");
addUIString("settingsMenu", 19, "Title Sorting Type: ");
addUIString("settingsMenu", 20, "Animation Scale: ");
addUIString("settingsMenu", 21, "Auto-upload to Drive: ");
//Main menu
addUIString("mainMenuSettings", 0, "Settings");