mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
>>WIP Early<< SDL2 GFX
This commit is contained in:
parent
a02b3e82c3
commit
e34a3f36c7
6
Makefile
6
Makefile
|
|
@ -38,7 +38,7 @@ INCLUDES := inc
|
|||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK
|
||||
APP_VERSION := 05.27.2021
|
||||
APP_VERSION := 06.02.2021
|
||||
ROMFS := romfs
|
||||
ICON := romfs/icon.jpg
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ ICON := romfs/icon.jpg
|
|||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
override CFLAGS += -g -Wall -O2 -ffunction-sections -ffast-math \
|
||||
override CFLAGS += `sdl2-config --cflags` -g -Wall -O2 -ffunction-sections -ffast-math \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
override CFLAGS += $(INCLUDE) -D__SWITCH__ `freetype-config --cflags` `curl-config --cflags`
|
||||
|
|
@ -57,7 +57,7 @@ CXXFLAGS:= $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
|||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `freetype-config --libs` `curl-config --libs` -lpng -ljpeg -lz -lminizip -ljson-c -lnx
|
||||
LIBS := `sdl2-config --libs` `freetype-config --libs` `curl-config --libs` -lsdl2_image -lwebp -lpng -ljpeg -lz -lminizip -ljson-c -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
|
|
|||
12
README.MD
12
README.MD
|
|
@ -89,7 +89,17 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
|
||||
## Building:
|
||||
1. Requires [devkitPro](https://devkitpro.org/) and [libnx](https://github.com/switchbrew/libnx)
|
||||
2. Requires switch-[freetype, libpng, zlib, libjpeg-turbo, curl, and libjson-c]
|
||||
2. Requires switch-
|
||||
* freetype
|
||||
* libpng
|
||||
* zlib
|
||||
* libjpeg-turbo
|
||||
* curl
|
||||
* libjson-c
|
||||
* sdl2
|
||||
* sdl2_image
|
||||
* libwebp
|
||||
|
||||
|
||||
## Credits and Thanks:
|
||||
* [shared-font](https://github.com/switchbrew/switch-portlibs-examples) example by yellows8
|
||||
|
|
|
|||
20
inc/data.h
20
inc/data.h
|
|
@ -12,8 +12,8 @@
|
|||
#define curUser users[data::selUser]
|
||||
#define curData users[data::selUser].titles[data::selData]
|
||||
|
||||
#define BLD_MON 05
|
||||
#define BLD_DAY 27
|
||||
#define BLD_MON 06
|
||||
#define BLD_DAY 02
|
||||
#define BLD_YEAR 2021
|
||||
|
||||
namespace data
|
||||
|
|
@ -76,7 +76,7 @@ namespace data
|
|||
uint32_t getLaunchCount() const { return launchCount; }
|
||||
|
||||
private:
|
||||
tex *icon;
|
||||
SDL_Texture *icon;
|
||||
uint8_t saveDataType;
|
||||
std::string title, titleSafe, author;
|
||||
uint64_t id, saveID;
|
||||
|
|
@ -91,13 +91,13 @@ namespace data
|
|||
public:
|
||||
user() = default;
|
||||
user(const AccountUid& _id, const std::string& _backupName);
|
||||
user(const AccountUid& _id, const std::string& _backupName, tex *img);
|
||||
user(const AccountUid& _id, const std::string& _backupName, SDL_Texture *img);
|
||||
|
||||
//Sets ID
|
||||
void setUID(const AccountUid& _id);
|
||||
|
||||
//Assigns icon
|
||||
void assignIcon(tex *_icn) { userIcon = _icn; }
|
||||
void assignIcon(SDL_Texture *_icn) { userIcon = _icn; }
|
||||
|
||||
//Returns user ID
|
||||
AccountUid getUID() const { return userID; }
|
||||
|
|
@ -111,16 +111,16 @@ namespace data
|
|||
std::vector<titledata> titles;
|
||||
void loadPlayTimes();
|
||||
|
||||
void drawIcon(int x, int y) { texDraw(userIcon, frameBuffer, x, y); }
|
||||
void drawIconHalf(int x, int y) { texDrawSkip(userIcon, frameBuffer, x, y); }
|
||||
void delIcon() { texDestroy(userIcon); }
|
||||
void drawIcon(int x, int y) { gfx::texDraw(userIcon, x, y); }
|
||||
void drawIconHalf(int x, int y) { gfx::texDrawStretch(userIcon, x, y, 128, 128); }
|
||||
void delIcon() { SDL_DestroyTexture(userIcon); }
|
||||
|
||||
private:
|
||||
AccountUid userID;
|
||||
u128 uID128;
|
||||
std::string username, userSafe;
|
||||
//User icon
|
||||
tex* userIcon;
|
||||
SDL_Texture *userIcon;
|
||||
};
|
||||
|
||||
//Adds title to blacklist
|
||||
|
|
@ -130,7 +130,7 @@ namespace data
|
|||
|
||||
//User vector
|
||||
extern std::vector<user> users;
|
||||
extern std::unordered_map<uint64_t, tex *> icons;
|
||||
extern std::unordered_map<uint64_t, SDL_Texture *> icons;
|
||||
|
||||
//Options and info
|
||||
//Restores config to default
|
||||
|
|
|
|||
229
inc/gfx.h
229
inc/gfx.h
|
|
@ -1,200 +1,59 @@
|
|||
#ifndef GFX_H
|
||||
#define GFX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
namespace gfx
|
||||
{
|
||||
#endif
|
||||
extern SDL_Renderer *render;
|
||||
|
||||
//Structs
|
||||
typedef struct
|
||||
{
|
||||
uint8_t r, g, b, a;
|
||||
} clr;
|
||||
void init();
|
||||
void exit();
|
||||
void clear(const SDL_Color *c);
|
||||
void present();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FT_Library lib;
|
||||
FT_Face face[6];
|
||||
FT_Error libRet, faceRet;
|
||||
//Loads to buffer for speed for TTF
|
||||
uint8_t *fntData;
|
||||
bool external;
|
||||
} font;
|
||||
SDL_Texture *loadJPEGMem(const void *jpegData, size_t jpegSize);
|
||||
SDL_Texture *loadImageFile(const char *file);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
unsigned width, height;
|
||||
uint32_t *data;
|
||||
} tex;
|
||||
void drawTextf(int fontSize, int x, int y, const SDL_Color *c, const char *fmt, ...);
|
||||
void drawTextfWrap(int fontSize, int x, int y, int maxWidth, const SDL_Color* c, const char *fmt, ...);
|
||||
size_t getTextWidth(const char *str, int fontSize);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
unsigned width, height;
|
||||
uint8_t *dat;
|
||||
} alphaMask;
|
||||
//Shortcuts for drawing
|
||||
inline void texDraw(SDL_Texture *tex, int x, int y)
|
||||
{
|
||||
int tW = 0, tH = 0;
|
||||
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
|
||||
{
|
||||
SDL_Rect src = {0, 0, tW, tH};
|
||||
SDL_Rect pos = {x, y, tW, tH};
|
||||
SDL_RenderCopy(render, tex, &src, &pos);
|
||||
}
|
||||
}
|
||||
|
||||
//Inits needed graphics stuff
|
||||
bool graphicsInit(int windowWidth, int windowHeight);
|
||||
inline void texDrawStretch(SDL_Texture *tex, int x, int y, int w, int h)
|
||||
{
|
||||
int tW = 0, tH = 0;
|
||||
if(SDL_QueryTexture(tex, NULL, NULL, &tW, &tH) == 0)
|
||||
{
|
||||
SDL_Rect src = {0, 0, tW, tH};
|
||||
SDL_Rect pos = {x, y, w, h};
|
||||
SDL_RenderCopy(render, tex, &src, &pos);
|
||||
}
|
||||
}
|
||||
|
||||
//Exits needed services
|
||||
bool graphicsExit();
|
||||
inline void drawLine(const SDL_Color *c, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
SDL_SetRenderDrawColor(render, c->r, c->g, c->b, c->a);
|
||||
SDL_RenderDrawLine(render, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void gfxBeginFrame();
|
||||
void gfxEndFrame();
|
||||
|
||||
//Creates color from uint32_t
|
||||
inline clr clrCreateU32(uint32_t color)
|
||||
{
|
||||
clr ret;
|
||||
ret.a = color >> 24 & 0xFF;
|
||||
ret.b = color >> 16 & 0xFF;
|
||||
ret.g = color >> 8 & 0xFF;
|
||||
ret.r = color & 0xFF;
|
||||
return ret;
|
||||
inline void drawRect(const SDL_Color *c, int x, int y, int w, int h)
|
||||
{
|
||||
SDL_SetRenderDrawColor(render, c->r, c->g, c->b, c->a);
|
||||
SDL_Rect rect = {x, y, w, h};
|
||||
SDL_RenderFillRect(render, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
//Sets clr to [r], [g], [b], [a]
|
||||
inline clr clrCreateRGBA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a)
|
||||
{
|
||||
clr ret;
|
||||
ret.r = _r;
|
||||
ret.g = _g;
|
||||
ret.b = _b;
|
||||
ret.a = _a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Inverts color
|
||||
inline void clrInvert(clr *c)
|
||||
{
|
||||
c->r = (0xFF - c->r);
|
||||
c->g = (0xFF - c->g);
|
||||
c->b = (0xFF - c->b);
|
||||
}
|
||||
|
||||
//Returns uint32_t color
|
||||
inline uint32_t clrGetColor(const clr c)
|
||||
{
|
||||
return (c.a << 24 | c.b << 16 | c.g << 8 | c.r);
|
||||
}
|
||||
|
||||
//Draws text using f
|
||||
void drawText(const char *str, tex *target, const font *f, int x, int y, int sz, clr c);
|
||||
void drawTextf(tex *target, const font *f, int x, int y, int sz, clr c, const char *fmt, ...);
|
||||
|
||||
//Draws text wrapping lines
|
||||
void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth);
|
||||
void drawTextfWrap(tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth, const char *fmt, ...);
|
||||
|
||||
//Returns text width
|
||||
size_t textGetWidth(const char *str, const font *f, int sz);
|
||||
|
||||
//Draws rectangle at x, y with w, h
|
||||
void drawRect(tex *target, int x, int y, int w, int h, const clr c);
|
||||
|
||||
//Draws rect with alpha.
|
||||
void drawRectAlpha(tex *target, int x, int y, int w, int h, const clr c);
|
||||
|
||||
/*
|
||||
TEX BEGIN
|
||||
*/
|
||||
//Inits empty tex
|
||||
tex *texCreate(int w, int h);
|
||||
|
||||
//Loads PNG from path
|
||||
tex *texLoadPNGFile(const char *path);
|
||||
|
||||
//Loads JPEG from path
|
||||
tex *texLoadJPEGFile(const char *path);
|
||||
|
||||
//Loads jpeg from memory
|
||||
tex *texLoadJPEGMem(const uint8_t *jpegData, size_t jpegSize);
|
||||
|
||||
//Loads image from RGBA - Not meant for large images
|
||||
tex *texLoadRGBA(const char *path);
|
||||
|
||||
//Frees memory used by t
|
||||
void texDestroy(tex *t);
|
||||
|
||||
//Clears tex completely with c
|
||||
void texClearColor(tex *in, const clr c);
|
||||
|
||||
//Draws t at x, y
|
||||
void texDraw(const tex *t, tex *target, int x, int y);
|
||||
|
||||
//Draws without alpha blending, faster
|
||||
void texDrawNoAlpha(const tex *t, tex *target, int x, int y);
|
||||
|
||||
//Draws skipping every other pixel + row
|
||||
void texDrawSkip(const tex *t, tex *target, int x, int y);
|
||||
|
||||
//Same as above, no alpha
|
||||
void texDrawSkipNoAlpha(const tex *t, tex *target, int x, int y);
|
||||
|
||||
//Draw t inverted at x, y
|
||||
void texDrawInvert(const tex *t, tex *target, int x, int y);
|
||||
|
||||
//Replaces old with newColor
|
||||
void texSwapColors(tex *t, const clr old, const clr newColor);
|
||||
|
||||
//Scales tex * scale and writes to out. Can only multiply for now
|
||||
void texScaleToTex(const tex *in, tex *out, int scale);
|
||||
|
||||
//Creates and copies data from another image returns tex
|
||||
tex *texCreateFromPart(const tex *src, int x, int y, int w, int h);
|
||||
|
||||
void texApplyAlphaMask(tex *target, const alphaMask *a);
|
||||
/*
|
||||
TEX END
|
||||
*/
|
||||
|
||||
alphaMask *alphaMaskLoad(unsigned w, unsigned h, const char *file);
|
||||
void alphaMaskDestroy(alphaMask *a);
|
||||
|
||||
//Loads and returns font with Switch shared font loaded
|
||||
font *fontLoadSharedFonts();
|
||||
|
||||
//Loads and returns TTF font.
|
||||
font *fontLoadTTF(const char *path);
|
||||
|
||||
//Frees font
|
||||
void fontDestroy(font *f);
|
||||
|
||||
//returns framebuffer tex pointer
|
||||
extern tex *frameBuffer;
|
||||
|
||||
/*Switch extended button codes:
|
||||
e0e0 = A
|
||||
e0e1 = B
|
||||
e0e2 = X
|
||||
e0e3 = Y
|
||||
e0e4 = L
|
||||
e0e5 = R
|
||||
e0e6 = ZL
|
||||
e0e7 = ZR
|
||||
e0e8 = SL
|
||||
e0e9 = SR
|
||||
e0ea = dpad
|
||||
e0eb = dpad up
|
||||
e0ec = dpad down
|
||||
e0ed = dpad left
|
||||
e0ee = dpad right
|
||||
e0ef = +
|
||||
e0f0 = -
|
||||
|
||||
^^Replace second e with a for different button set. C0 to C9 = analog stick
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GFX_H
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace ui
|
|||
int getSelected() { return selected; }
|
||||
|
||||
//Draws the menu at x and y. rectWidth is the width of the rectangle drawn under the selected
|
||||
void draw(const clr& textClr);
|
||||
void draw(const SDL_Color *textClr);
|
||||
|
||||
//Clears and resets menu
|
||||
void reset();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ namespace ui
|
|||
private:
|
||||
uint64_t max, prog;
|
||||
float width;
|
||||
tex *bg;
|
||||
};
|
||||
|
||||
//General use
|
||||
|
|
@ -32,8 +31,7 @@ namespace ui
|
|||
bool confirm(bool hold, const char *fmt, ...);
|
||||
bool confirmTransfer(const std::string& f, const std::string& t);
|
||||
bool confirmDelete(const std::string& p);
|
||||
void drawTextbox(tex *target, int x, int y, int w, int h);
|
||||
void drawTextboxInvert(tex *target, int x, int y, int w, int h);
|
||||
void drawTextbox(int x, int y, int w, int h);
|
||||
|
||||
//Popup from freebird
|
||||
void showPopup(unsigned frames, const char *fmt, ...);
|
||||
|
|
|
|||
15
inc/ui.h
15
inc/ui.h
|
|
@ -60,20 +60,15 @@ namespace ui
|
|||
txtCont = text that contrasts clearClr
|
||||
txtDiag = text color for dialogs
|
||||
*/
|
||||
extern clr clearClr, txtCont, txtDiag, rectLt, rectSh, tboxClr, sideRect;
|
||||
extern SDL_Color clearClr, txtCont, txtDiag, rectLt, rectSh, tboxClr, sideRect;
|
||||
|
||||
//Textbox graphics
|
||||
extern tex *cornerTopLeft, *cornerTopRight, *cornerBottomLeft, *cornerBottomRight;
|
||||
extern SDL_Texture *cornerTopLeft, *cornerTopRight, *cornerBottomLeft, *cornerBottomRight;
|
||||
//Covers left and right of progress bar to fake being not a rectangle.
|
||||
extern tex *progCovLeft, *progCovRight, *diaBox;
|
||||
extern SDL_Texture *progCovLeft, *progCovRight, *diaBox;
|
||||
|
||||
//Side bar from Freebird. RIP. NEVERMIND
|
||||
extern tex *sideBar;
|
||||
|
||||
extern alphaMask *iconMask;
|
||||
|
||||
//Shared font
|
||||
extern font *shared;
|
||||
//Side bar from Freebird. RIP.
|
||||
extern SDL_Texture *sideBar;
|
||||
|
||||
//Sets colors and loads font for icon creation
|
||||
void initTheme();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace util
|
|||
void replaceButtonsInString(std::string& rep);
|
||||
|
||||
//Creates a basic generic icon for stuff without one
|
||||
tex *createIconGeneric(const char *txt);
|
||||
SDL_Texture *createIconGeneric(const char *txt, int fontSize);
|
||||
|
||||
inline u128 accountUIDToU128(AccountUid uid)
|
||||
{
|
||||
|
|
|
|||
52
src/data.cpp
52
src/data.cpp
|
|
@ -12,7 +12,7 @@
|
|||
#include "util.h"
|
||||
|
||||
//Color for favorite hearts
|
||||
const clr heartColor = clrCreateRGBA(0xFF, 0x44, 0x44, 0xFF);
|
||||
const SDL_Color heartColor = {0xFF, 0x44, 0x44, 0xFF};
|
||||
|
||||
//FsSaveDataSpaceId_All doesn't work for SD
|
||||
static const unsigned saveOrder [] =
|
||||
|
|
@ -39,7 +39,7 @@ static bool sysBCATPushed = false, cachePushed = false, tempPushed = false;
|
|||
static std::vector<uint64_t> blacklist;
|
||||
static std::vector<uint64_t> favorites;
|
||||
static std::unordered_map<uint64_t, std::string> pathDefs;
|
||||
std::unordered_map<uint64_t, tex *> data::icons;
|
||||
std::unordered_map<uint64_t, SDL_Texture *> data::icons;
|
||||
|
||||
//Sorts titles by sortType
|
||||
static struct
|
||||
|
|
@ -113,28 +113,14 @@ static bool isDefined(const uint64_t& id)
|
|||
return false;
|
||||
}
|
||||
|
||||
static tex *createDeviceIcon()
|
||||
static SDL_Texture *createDeviceIcon()
|
||||
{
|
||||
tex *ret = texCreate(256, 256);
|
||||
texClearColor(ret, ui::rectLt);
|
||||
unsigned x = 128 - (textGetWidth("\ue121", ui::shared, 188) / 2);
|
||||
drawText("\ue121", ret, ui::shared, x, 34, 188, ui::txtCont);
|
||||
texApplyAlphaMask(ret, ui::iconMask);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline tex *createFavIcon(const tex *_icn)
|
||||
{
|
||||
tex *ret = texCreate(256, 256);
|
||||
memcpy(ret->data, _icn->data, 256 * 256 * sizeof(uint32_t));
|
||||
drawText("♥", ret, ui::shared, 16, 16, 48, clrCreateU32(0xFF4444FF));
|
||||
return ret;
|
||||
return util::createIconGeneric("\ue121", 192);
|
||||
}
|
||||
|
||||
static inline void loadCreateIcon(const uint64_t& _id, size_t _sz, const NsApplicationControlData *_d)
|
||||
{
|
||||
data::icons[_id] = texLoadJPEGMem(_d->icon, _sz);
|
||||
texApplyAlphaMask(data::icons[_id], ui::iconMask);
|
||||
data::icons[_id] = gfx::loadJPEGMem(_d->icon, _sz);
|
||||
}
|
||||
|
||||
static void loadCreateSystemIcon(const uint64_t& _id)
|
||||
|
|
@ -142,8 +128,7 @@ static void loadCreateSystemIcon(const uint64_t& _id)
|
|||
char tmp[16];
|
||||
sprintf(tmp, "%08X", (uint32_t)_id);
|
||||
|
||||
data::icons[_id] = util::createIconGeneric(tmp);
|
||||
texApplyAlphaMask(data::icons[_id], ui::iconMask);
|
||||
data::icons[_id] = util::createIconGeneric(tmp, 32);
|
||||
}
|
||||
|
||||
static inline std::string getIDStr(const uint64_t& _id)
|
||||
|
|
@ -322,7 +307,7 @@ void data::exit()
|
|||
for(auto& icn : icons)
|
||||
{
|
||||
if(icn.second)
|
||||
texDestroy(icn.second);
|
||||
SDL_DestroyTexture(icn.second);
|
||||
}
|
||||
|
||||
saveFav();
|
||||
|
|
@ -403,22 +388,22 @@ void data::titledata::assignIcon()
|
|||
void data::titledata::drawIcon(bool full, unsigned x, unsigned y)
|
||||
{
|
||||
if(full)
|
||||
texDraw(icon, frameBuffer, x, y);
|
||||
gfx::texDraw(icon, x, y);
|
||||
else
|
||||
texDrawSkip(icon, frameBuffer, x, y);
|
||||
gfx::texDrawStretch(icon, x, y, 128, 128);
|
||||
}
|
||||
|
||||
void data::titledata::drawIconFav(bool full, unsigned x, unsigned y)
|
||||
{
|
||||
if(full)
|
||||
{
|
||||
texDraw(icon, frameBuffer, x, y);
|
||||
drawText("♥", frameBuffer, ui::shared, x + 16, y + 16, 48, heartColor);
|
||||
gfx::texDraw(icon, x, y);
|
||||
gfx::drawTextf(48, x + 16, y + 16, &heartColor, "♥");
|
||||
}
|
||||
else
|
||||
{
|
||||
texDrawSkip(icon, frameBuffer, x, y);
|
||||
drawText("♥", frameBuffer, ui::shared, x + 8, y + 8, 24, heartColor);
|
||||
gfx::texDrawStretch(icon, x, y, 128, 128);
|
||||
gfx::drawTextf(24, x + 8, y + 8, &heartColor, "♥");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +430,7 @@ data::user::user(const AccountUid& _id, const std::string& _backupName)
|
|||
accountProfileGetImageSize(&prof, &jpgSize);
|
||||
uint8_t *jpegData = new uint8_t[jpgSize];
|
||||
accountProfileLoadImage(&prof, jpegData, jpgSize, &jpgSize);
|
||||
userIcon = texLoadJPEGMem(jpegData, jpgSize);
|
||||
userIcon = gfx::loadJPEGMem(jpegData, jpgSize);
|
||||
delete[] jpegData;
|
||||
|
||||
accountProfileClose(&prof);
|
||||
|
|
@ -454,13 +439,12 @@ data::user::user(const AccountUid& _id, const std::string& _backupName)
|
|||
{
|
||||
username = _backupName.empty() ? getIDStr((uint64_t)uID128) : _backupName;
|
||||
userSafe = _backupName.empty() ? getIDStr((uint64_t)uID128) : _backupName;
|
||||
userIcon = util::createIconGeneric(_backupName.c_str());
|
||||
userIcon = util::createIconGeneric(_backupName.c_str(), 32);
|
||||
}
|
||||
texApplyAlphaMask(userIcon, ui::iconMask);
|
||||
titles.reserve(32);
|
||||
}
|
||||
|
||||
data::user::user(const AccountUid& _id, const std::string& _backupName, tex *img) : user(_id, _backupName)
|
||||
data::user::user(const AccountUid& _id, const std::string& _backupName, SDL_Texture *img) : user(_id, _backupName)
|
||||
{
|
||||
delIcon();
|
||||
userIcon = img;
|
||||
|
|
@ -667,6 +651,8 @@ void data::loadDefs()
|
|||
}
|
||||
}
|
||||
|
||||
static const SDL_Color green = {0x00, 0xDD, 0x00, 0xFF};
|
||||
|
||||
void data::dispStats()
|
||||
{
|
||||
//Easiest/laziest way to do this
|
||||
|
|
@ -678,5 +664,5 @@ void data::dispStats()
|
|||
stats += "Safe Title: " + data::curData.getTitleSafe() + "\n";
|
||||
stats += "Icon count: " + std::to_string(icons.size()) + "\n";
|
||||
stats += "Sort Type: " + std::to_string(data::sortType) + "\n";
|
||||
drawText(stats.c_str(), frameBuffer, ui::shared, 2, 2, 16, clrCreateU32(0xFF00DD00));
|
||||
gfx::drawTextf(16, 8, 8, &green, stats.c_str());
|
||||
}
|
||||
|
|
|
|||
25
src/file.cpp
25
src/file.cpp
|
|
@ -22,7 +22,7 @@ static std::string wd;
|
|||
|
||||
static std::vector<std::string> pathFilter;
|
||||
|
||||
static FSFILE *log;
|
||||
static FSFILE *debLog;
|
||||
|
||||
static FsFileSystem sv;
|
||||
|
||||
|
|
@ -379,9 +379,8 @@ void fs::copyFile(const std::string& from, const std::string& to)
|
|||
while(!send->fin)
|
||||
{
|
||||
prog.update(progress);
|
||||
gfxBeginFrame();
|
||||
prog.draw(from, ui::copyHead);
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
copyArgsDestroy(send);
|
||||
|
|
@ -458,9 +457,8 @@ void fs::copyFileCommit(const std::string& from, const std::string& to, const st
|
|||
while(!send->fin)
|
||||
{
|
||||
prog.update(offset);
|
||||
gfxBeginFrame();
|
||||
prog.draw(from, ui::copyHead);
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
copyArgsDestroy(send);
|
||||
|
|
@ -527,9 +525,8 @@ void copyFileToZip(const std::string& from, zipFile *z)
|
|||
while(!send->fin)
|
||||
{
|
||||
prog.update(progress);
|
||||
gfxBeginFrame();
|
||||
prog.draw(from, ui::copyHead);
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
copyArgsDestroy(send);
|
||||
|
|
@ -587,10 +584,8 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
|
|||
done += readIn;
|
||||
fwriteCommit(path, buff, readIn, dev);
|
||||
prog.update(done);
|
||||
|
||||
gfxBeginFrame();
|
||||
prog.draw(filename, ui::copyHead);
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -600,10 +595,8 @@ void fs::copyZipToDir(unzFile *unz, const std::string& to, const std::string& de
|
|||
done += readIn;
|
||||
fwriteCommit(path, buff, readIn, dev);
|
||||
prog.update(done);
|
||||
|
||||
gfxBeginFrame();
|
||||
prog.draw(filename, ui::copyHead);
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
}
|
||||
unzCloseCurrentFile(*unz);
|
||||
|
|
@ -836,7 +829,7 @@ void fs::logOpen()
|
|||
{
|
||||
std::string logPath = wd + "log.txt";
|
||||
remove(logPath.c_str());
|
||||
log = fsfopen(logPath.c_str(), FsOpenMode_Write);
|
||||
debLog = fsfopen(logPath.c_str(), FsOpenMode_Write);
|
||||
}
|
||||
|
||||
void fs::logWrite(const char *fmt, ...)
|
||||
|
|
@ -846,11 +839,11 @@ void fs::logWrite(const char *fmt, ...)
|
|||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
fsfwrite(tmp, 1, strlen(tmp), log);
|
||||
fsfwrite(tmp, 1, strlen(tmp), debLog);
|
||||
}
|
||||
|
||||
void fs::logClose()
|
||||
{
|
||||
fsfclose(log);
|
||||
fsfclose(debLog);
|
||||
}
|
||||
|
||||
|
|
|
|||
957
src/gfx.c
957
src/gfx.c
|
|
@ -1,957 +0,0 @@
|
|||
#include <switch.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <png.h>
|
||||
#include <jpeglib.h>
|
||||
#include <zlib.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
tex *frameBuffer;
|
||||
static clr textClr;
|
||||
|
||||
static NWindow *window;
|
||||
static Framebuffer fb;
|
||||
static bool framestarted = false;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
uint32_t sz;
|
||||
} rgbaHead;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct jpeg_error_mgr mgr;
|
||||
jmp_buf jmpBuffer;
|
||||
} jpegError;
|
||||
|
||||
#pragma GCC optimize ("Ofast")
|
||||
static inline uint32_t blend(const clr px, const clr fb)
|
||||
{
|
||||
uint32_t ret;
|
||||
switch(px.a)
|
||||
{
|
||||
case 0x00:
|
||||
ret = clrGetColor(fb);
|
||||
break;
|
||||
|
||||
case 0xFF:
|
||||
ret = clrGetColor(px);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
uint8_t subAl = 0xFF - px.a;
|
||||
|
||||
uint8_t fR = (px.r * px.a + fb.r * subAl) / 0xFF;
|
||||
uint8_t fG = (px.g * px.a + fb.g * subAl) / 0xFF;
|
||||
uint8_t fB = (px.b * px.a + fb.b * subAl) / 0xFF;
|
||||
ret = (0xFF << 24 | fB << 16 | fG << 8 | fR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline clr smooth(const clr px1, const clr px2)
|
||||
{
|
||||
clr ret;
|
||||
ret.r = (px1.r + px2.r) / 2;
|
||||
ret.g = (px1.g + px2.g) / 2;
|
||||
ret.b = (px1.b + px2.b) / 2;
|
||||
ret.a = (px1.a + px2.a) / 2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t smooth_32t(const clr px1, const clr px2)
|
||||
{
|
||||
uint8_t fR = (px1.r + px2.r) / 2;
|
||||
uint8_t fG = (px1.g + px2.g) / 2;
|
||||
uint8_t fB = (px1.b + px2.b) / 2;
|
||||
uint8_t fA = (px1.a + px2.a) / 2;
|
||||
|
||||
return (fA << 24 | fB << 16 | fG << 8 | fR);
|
||||
}
|
||||
|
||||
static inline bool yCheck(const tex *target, int y)
|
||||
{
|
||||
return y < 0 || y >= target->height;
|
||||
}
|
||||
|
||||
static inline bool xCheck(const tex *target, int x)
|
||||
{
|
||||
return x < 0 || x >= target->width;
|
||||
}
|
||||
|
||||
bool graphicsInit(int windowWidth, int windowHeight)
|
||||
{
|
||||
window = nwindowGetDefault();
|
||||
nwindowSetDimensions(window, windowWidth, windowHeight);
|
||||
|
||||
framebufferCreate(&fb, window, windowWidth, windowHeight, PIXEL_FORMAT_RGBA_8888, 2);
|
||||
framebufferMakeLinear(&fb);
|
||||
plInitialize(PlServiceType_System);
|
||||
|
||||
//Make a fake tex that points to framebuffer
|
||||
frameBuffer = malloc(sizeof(tex));
|
||||
frameBuffer->width = windowWidth;
|
||||
frameBuffer->height = windowHeight;
|
||||
frameBuffer->size = windowWidth * windowHeight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool graphicsExit()
|
||||
{
|
||||
free(frameBuffer);
|
||||
|
||||
plExit();
|
||||
framebufferClose(&fb);
|
||||
nwindowClose(window);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void gfxBeginFrame()
|
||||
{
|
||||
if(!framestarted)
|
||||
{
|
||||
frameBuffer->data = (uint32_t *)framebufferBegin(&fb, NULL);
|
||||
framestarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void gfxEndFrame()
|
||||
{
|
||||
if(framestarted)
|
||||
{
|
||||
framebufferEnd(&fb);
|
||||
framestarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void drawGlyph(const FT_Bitmap *bmp, tex *target, int _x, int _y)
|
||||
{
|
||||
if(bmp->pixel_mode != FT_PIXEL_MODE_GRAY)
|
||||
return;
|
||||
|
||||
clr txClr = textClr, tgtClr;
|
||||
uint8_t *bmpPtr = bmp->buffer;
|
||||
for(int y = _y; y < _y + bmp->rows; y++)
|
||||
{
|
||||
if(yCheck(target, y))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[y * target->width + _x];
|
||||
for(int x = _x; x < _x + bmp->width; x++, bmpPtr++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, x))
|
||||
continue;
|
||||
|
||||
if(*bmpPtr > 0)
|
||||
{
|
||||
txClr.a = *bmpPtr;
|
||||
tgtClr = clrCreateU32(*rowPtr);
|
||||
*rowPtr = blend(txClr, tgtClr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void resizeFont(const font *f, int sz)
|
||||
{
|
||||
if(f->external)
|
||||
FT_Set_Char_Size(f->face[0], 0, sz * 64, 90, 90);
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < 6; i++)
|
||||
FT_Set_Char_Size(f->face[i], 0, sz * 64, 90, 90);
|
||||
}
|
||||
}
|
||||
|
||||
static inline FT_GlyphSlot loadGlyph(const uint32_t c, const font *f, FT_Int32 flags)
|
||||
{
|
||||
if(f->external)
|
||||
{
|
||||
FT_Load_Glyph(f->face[0], FT_Get_Char_Index(f->face[0], c), flags);
|
||||
return f->face[0]->glyph;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
FT_UInt cInd = 0;
|
||||
if( (cInd = FT_Get_Char_Index(f->face[i], c)) != 0 && FT_Load_Glyph(f->face[i], cInd, flags) == 0)
|
||||
return f->face[i]->glyph;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void drawText(const char *str, tex *target, const font *f, int x, int y, int sz, clr c)
|
||||
{
|
||||
int tmpX = x;
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t unitCnt = 0;
|
||||
textClr = c;
|
||||
|
||||
resizeFont(f, sz);
|
||||
|
||||
size_t length = strlen(str);
|
||||
for(unsigned i = 0; i < length; )
|
||||
{
|
||||
unitCnt = decode_utf8(&tmpChr, (const uint8_t *)&str[i]);
|
||||
if(unitCnt <= 0)
|
||||
break;
|
||||
|
||||
i += unitCnt;
|
||||
switch(tmpChr)
|
||||
{
|
||||
case '\n':
|
||||
tmpX = x;
|
||||
y += sz + 8;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if(clrGetColor(textClr) == 0xFFEE9900)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFFEE9900);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if(clrGetColor(textClr) == 0xFF0000FF)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF0000FF);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if(clrGetColor(textClr) == 0xFF00FCF8)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FCF8);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if(clrGetColor(textClr) == 0xFF00FF00)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FF00);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
FT_GlyphSlot slot = loadGlyph(tmpChr, f, FT_LOAD_RENDER);
|
||||
if(slot != NULL)
|
||||
{
|
||||
int drawY = y + (sz - slot->bitmap_top);
|
||||
drawGlyph(&slot->bitmap, target, tmpX + slot->bitmap_left, drawY);
|
||||
|
||||
tmpX += slot->advance.x >> 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawTextf(tex *target, const font *f, int x, int y, int sz, clr c, const char *fmt, ...)
|
||||
{
|
||||
char tmp[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
drawText(tmp, target, f, x, y, sz, c);
|
||||
}
|
||||
|
||||
void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth)
|
||||
{
|
||||
char wordBuf[128];
|
||||
size_t nextbreak = 0;
|
||||
size_t strLength = strlen(str);
|
||||
int tmpX = x;
|
||||
resizeFont(f, sz);
|
||||
textClr = c;
|
||||
|
||||
for(unsigned i = 0; i < strLength; )
|
||||
{
|
||||
nextbreak = strcspn(&str[i], " /_-");
|
||||
|
||||
memset(wordBuf, 0, 128);
|
||||
memcpy(wordBuf, &str[i], nextbreak + 1);
|
||||
|
||||
size_t width = textGetWidth(wordBuf, f, sz);
|
||||
|
||||
if(tmpX + width >= x + maxWidth)
|
||||
{
|
||||
tmpX = x;
|
||||
y += sz + 8;
|
||||
}
|
||||
|
||||
size_t wLength = strlen(wordBuf);
|
||||
uint32_t tmpChr = 0;
|
||||
for(unsigned j = 0; j < wLength; )
|
||||
{
|
||||
ssize_t unitCnt = decode_utf8(&tmpChr, (const uint8_t *)&wordBuf[j]);
|
||||
if(unitCnt <= 0)
|
||||
break;
|
||||
|
||||
j += unitCnt;
|
||||
switch(tmpChr)
|
||||
{
|
||||
case '\n':
|
||||
tmpX = x;
|
||||
y += sz + 8;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if(clrGetColor(textClr) == 0xFFEE9900)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFFEE9900);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if(clrGetColor(textClr) == 0xFF0000FF)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF0000FF);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if(clrGetColor(textClr) == 0xFF00FCF8)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FCF8);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if(clrGetColor(textClr) == 0xFF00FF00)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FF00);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
FT_GlyphSlot slot = loadGlyph(tmpChr, f, FT_LOAD_RENDER);
|
||||
if(slot != NULL)
|
||||
{
|
||||
int drawY = y + (sz - slot->bitmap_top);
|
||||
drawGlyph(&slot->bitmap, target, tmpX + slot->bitmap_left, drawY);
|
||||
|
||||
tmpX += slot->advance.x >> 6;
|
||||
}
|
||||
}
|
||||
i += strlen(wordBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void drawTextfWrap(tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth, const char *fmt, ...)
|
||||
{
|
||||
char tmp[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
drawTextWrap(tmp, target, f, x, y, sz, c, maxWidth);
|
||||
}
|
||||
|
||||
size_t textGetWidth(const char *str, const font *f, int sz)
|
||||
{
|
||||
size_t width = 0;
|
||||
uint32_t untCnt = 0, tmpChr = 0;
|
||||
FT_Error ret = 0;
|
||||
|
||||
resizeFont(f, sz);
|
||||
|
||||
size_t length = strlen(str);
|
||||
for(unsigned i = 0; i < length; )
|
||||
{
|
||||
untCnt = decode_utf8(&tmpChr, (const uint8_t *)&str[i]);
|
||||
i += untCnt;
|
||||
|
||||
//Ignore color changing chars
|
||||
if(tmpChr == '\n' || tmpChr == '#' || tmpChr == '*' || tmpChr == '<' || tmpChr == '>')
|
||||
continue;
|
||||
|
||||
if(untCnt <= 0)
|
||||
break;
|
||||
|
||||
FT_GlyphSlot slot = loadGlyph(tmpChr, f, FT_LOAD_DEFAULT);
|
||||
if(ret)
|
||||
return 0;
|
||||
|
||||
width += slot->advance.x >> 6;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
void drawRect(tex *target, int x, int y, int w, int h, const clr c)
|
||||
{
|
||||
uint32_t clr = clrGetColor(c);
|
||||
|
||||
for(int tY = y; tY < y + h; tY++)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + w; tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
*rowPtr = clr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawRectAlpha(tex *target, int x, int y, int w, int h, const clr c)
|
||||
{
|
||||
for(int tY = y; tY < y + h; tY++)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + w; tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
*rowPtr = blend(c, clrCreateU32(*rowPtr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tex *texCreate(int w, int h)
|
||||
{
|
||||
tex *ret = malloc(sizeof(tex));
|
||||
|
||||
ret->width = w;
|
||||
ret->height = h;
|
||||
|
||||
ret->data = (uint32_t *)malloc(w * h * sizeof(uint32_t));
|
||||
memset(ret->data, 0, w * h * sizeof(uint32_t));
|
||||
ret->size = ret->width * ret->height;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tex *texLoadPNGFile(const char *path)
|
||||
{
|
||||
FILE *pngIn = fopen(path, "rb");
|
||||
if(pngIn != NULL)
|
||||
{
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if(png == 0)
|
||||
return NULL;
|
||||
|
||||
png_infop pngInfo = png_create_info_struct(png);
|
||||
if(pngInfo == 0)
|
||||
return NULL;
|
||||
|
||||
int jmp = setjmp(png_jmpbuf(png));
|
||||
if(jmp)
|
||||
return NULL;
|
||||
|
||||
png_init_io(png, pngIn);
|
||||
png_read_info(png, pngInfo);
|
||||
|
||||
if(png_get_color_type(png, pngInfo) != PNG_COLOR_TYPE_RGBA)
|
||||
{
|
||||
png_destroy_read_struct(&png, &pngInfo, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex *ret = malloc(sizeof(tex));
|
||||
ret->width = png_get_image_width(png, pngInfo);
|
||||
ret->height = png_get_image_height(png, pngInfo);
|
||||
|
||||
ret->data = (uint32_t *)malloc((ret->width * ret->height) * sizeof(uint32_t));
|
||||
ret->size = ret->width * ret->height;
|
||||
|
||||
png_bytep *rows = malloc(sizeof(png_bytep) * ret->height);
|
||||
for(int i = 0; i < ret->height; i++)
|
||||
rows[i] = malloc(png_get_rowbytes(png, pngInfo));
|
||||
|
||||
png_read_image(png, rows);
|
||||
|
||||
uint32_t *dataPtr = &ret->data[0];
|
||||
for(int y = 0; y < ret->height; y++)
|
||||
{
|
||||
uint32_t *rowPtr = (uint32_t *)rows[y];
|
||||
for(int x = 0; x < ret->width; x++)
|
||||
*dataPtr++ = *rowPtr++;
|
||||
}
|
||||
|
||||
for(int i = 0; i < ret->height; i++)
|
||||
free(rows[i]);
|
||||
|
||||
free(rows);
|
||||
|
||||
png_destroy_read_struct(&png, &pngInfo, NULL);
|
||||
fclose(pngIn);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void jpegExit(j_common_ptr ptr)
|
||||
{
|
||||
jpegError *err = (jpegError *)ptr->err;
|
||||
longjmp(err->jmpBuffer, 1);
|
||||
}
|
||||
|
||||
tex *texLoadJPEGFile(const char *path)
|
||||
{
|
||||
FILE *jpegIn = fopen(path, "rb");
|
||||
if(jpegIn)
|
||||
{
|
||||
struct jpeg_decompress_struct jpegInfo;
|
||||
jpegError jpgError;
|
||||
|
||||
jpegInfo.err = jpeg_std_error(&jpgError.mgr);
|
||||
jpgError.mgr.error_exit = jpegExit;
|
||||
if(setjmp(jpgError.jmpBuffer))
|
||||
{
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
fclose(jpegIn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jpeg_create_decompress(&jpegInfo);
|
||||
jpeg_stdio_src(&jpegInfo, jpegIn);
|
||||
jpeg_read_header(&jpegInfo, true);
|
||||
jpegInfo.out_color_space = JCS_RGB;
|
||||
|
||||
tex *ret = malloc(sizeof(tex));
|
||||
|
||||
ret->width = jpegInfo.image_width;
|
||||
ret->height = jpegInfo.image_height;
|
||||
|
||||
ret->data = (uint32_t *)malloc((ret->width * ret->height) * sizeof(uint32_t));
|
||||
ret->size = ret->width * ret->height;
|
||||
|
||||
jpeg_start_decompress(&jpegInfo);
|
||||
|
||||
JSAMPARRAY row = malloc(sizeof(JSAMPROW));
|
||||
for(unsigned i = 0; i < ret->height; i++)
|
||||
row[0] = malloc(sizeof(JSAMPLE) * ret->width * 3);
|
||||
|
||||
uint32_t *dataPtr = &ret->data[0];
|
||||
for(int y = 0; y < ret->height; y++)
|
||||
{
|
||||
jpeg_read_scanlines(&jpegInfo, row, 1);
|
||||
uint8_t *jpegPtr = row[0];
|
||||
for(int x = 0; x < ret->width; x++, jpegPtr += 3)
|
||||
*dataPtr++ = (0xFF << 24 | jpegPtr[2] << 16 | jpegPtr[1] << 8 | jpegPtr[0]);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&jpegInfo);
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
|
||||
free(row[0]);
|
||||
free(row);
|
||||
|
||||
fclose(jpegIn);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex *texLoadJPEGMem(const uint8_t *jpegData, size_t jpegSize)
|
||||
{
|
||||
struct jpeg_decompress_struct jpegInfo;
|
||||
jpegError jpgError;
|
||||
|
||||
jpegInfo.err = jpeg_std_error(&jpgError.mgr);
|
||||
jpgError.mgr.error_exit = jpegExit;
|
||||
if(setjmp(jpgError.jmpBuffer))
|
||||
{
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jpeg_create_decompress(&jpegInfo);
|
||||
jpeg_mem_src(&jpegInfo, jpegData, jpegSize);
|
||||
jpeg_read_header(&jpegInfo, true);
|
||||
jpegInfo.out_color_space = JCS_RGB;
|
||||
|
||||
tex *ret = malloc(sizeof(tex));
|
||||
ret->width = jpegInfo.image_width;
|
||||
ret->height = jpegInfo.image_height;
|
||||
|
||||
ret->data = (uint32_t *)malloc((ret->width * ret->height) * sizeof(uint32_t));
|
||||
ret->size = ret->width * ret->height;
|
||||
|
||||
jpeg_start_decompress(&jpegInfo);
|
||||
|
||||
JSAMPARRAY row = malloc(sizeof(JSAMPROW));
|
||||
for(unsigned i = 0; i < ret->height; i++)
|
||||
row[0] = malloc(sizeof(JSAMPLE) * ret->width * 3);
|
||||
|
||||
uint32_t *dataPtr = &ret->data[0];
|
||||
for(int y = 0; y < ret->height; y++)
|
||||
{
|
||||
jpeg_read_scanlines(&jpegInfo, row, 1);
|
||||
uint8_t *jpegPtr = row[0];
|
||||
for(int x = 0; x < ret->width; x++, jpegPtr += 3)
|
||||
*dataPtr++ = (0xFF << 24 | jpegPtr[2] << 16 | jpegPtr[1] << 8 | jpegPtr[0]);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&jpegInfo);
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
|
||||
free(row[0]);
|
||||
free(row);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tex *texLoadRGBA(const char *path)
|
||||
{
|
||||
tex *ret = malloc(sizeof(tex));
|
||||
FILE *rgb = fopen(path, "rb");
|
||||
|
||||
fseek(rgb, 0, SEEK_END);
|
||||
size_t dataSize = ftell(rgb) - sizeof(rgbaHead);
|
||||
fseek(rgb, 0, SEEK_SET);
|
||||
|
||||
rgbaHead head;
|
||||
fread(&head, sizeof(rgbaHead), 1, rgb);
|
||||
ret->width = head.w;
|
||||
ret->height = head.h;
|
||||
ret->size = head.w * head.h;
|
||||
ret->data = (uint32_t *)malloc((ret->width * ret->height) * sizeof(uint32_t));
|
||||
|
||||
unsigned char *inBuff = malloc(dataSize);
|
||||
fread(inBuff, 1, dataSize, rgb);
|
||||
uLongf destSz = ret->size * 4;
|
||||
uncompress((unsigned char *)ret->data, &destSz, inBuff, dataSize);
|
||||
|
||||
free(inBuff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void texDestroy(tex *t)
|
||||
{
|
||||
if(t->data != NULL)
|
||||
free(t->data);
|
||||
|
||||
if(t != NULL)
|
||||
free(t);
|
||||
}
|
||||
|
||||
void texClearColor(tex *in, const clr c)
|
||||
{
|
||||
uint32_t *dataPtr = &in->data[0];
|
||||
uint32_t color = clrGetColor(c);
|
||||
for(int i = 0; i < in->size; i++)
|
||||
*dataPtr++ = color;
|
||||
}
|
||||
|
||||
void texDraw(const tex *t, tex *target, int x, int y)
|
||||
{
|
||||
if(t != NULL)
|
||||
{
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(int tY = y; tY < y + t->height; tY++)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + t->width; tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
clr dataClr = clrCreateU32(*dataPtr++);
|
||||
clr fbClr = clrCreateU32(*rowPtr);
|
||||
|
||||
*rowPtr = blend(dataClr, fbClr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texDrawNoAlpha(const tex *t, tex *target, int x, int y)
|
||||
{
|
||||
if(t != NULL)
|
||||
{
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(int tY = y; tY < y + t->height; tY++)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + t->width; tX++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
*rowPtr++ = *dataPtr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texDrawSkip(const tex *t, tex *target, int x, int y)
|
||||
{
|
||||
if(t != NULL)
|
||||
{
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(int tY = y; tY < y + (t->height / 2); tY++, dataPtr += t->width)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + (t->width / 2); tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
clr px1 = clrCreateU32(*dataPtr++);
|
||||
clr px2 = clrCreateU32(*dataPtr++);
|
||||
clr fbPx = clrCreateU32(*rowPtr);
|
||||
*rowPtr = blend(smooth(px1, px2), fbPx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texDrawSkipNoAlpha(const tex *t, tex *target, int x, int y)
|
||||
{
|
||||
if(t != NULL)
|
||||
{
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(int tY = y; tY < y + (t->height / 2); tY++, dataPtr += t->width)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + (t->width / 2); tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
clr px1 = clrCreateU32(*dataPtr++);
|
||||
clr px2 = clrCreateU32(*dataPtr++);
|
||||
|
||||
*rowPtr = smooth_32t(px1, px2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texDrawInvert(const tex *t, tex *target, int x, int y)
|
||||
{
|
||||
if(t != NULL)
|
||||
{
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(int tY = y; tY < y + t->height; tY++)
|
||||
{
|
||||
if(yCheck(target, tY))
|
||||
continue;
|
||||
|
||||
uint32_t *rowPtr = &target->data[tY * target->width + x];
|
||||
for(int tX = x; tX < x + t->width; tX++, rowPtr++)
|
||||
{
|
||||
if(xCheck(target, tX))
|
||||
continue;
|
||||
|
||||
clr dataClr = clrCreateU32(*dataPtr++);
|
||||
clrInvert(&dataClr);
|
||||
clr fbClr = clrCreateU32(*rowPtr);
|
||||
|
||||
*rowPtr = blend(dataClr, fbClr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texSwapColors(tex *t, const clr old, const clr newColor)
|
||||
{
|
||||
uint32_t oldClr = clrGetColor(old), newClr = clrGetColor(newColor);
|
||||
|
||||
uint32_t *dataPtr = &t->data[0];
|
||||
for(unsigned i = 0; i < t->size; i++, dataPtr++)
|
||||
{
|
||||
if(*dataPtr == oldClr)
|
||||
*dataPtr = newClr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tex *texCreateFromPart(const tex *src, int x, int y, int w, int h)
|
||||
{
|
||||
tex *ret = texCreate(w, h);
|
||||
|
||||
uint32_t *retPtr = &ret->data[0];
|
||||
for(int tY = y; tY < y + h; tY++)
|
||||
{
|
||||
uint32_t *srcPtr = &src->data[tY * src->width + x];
|
||||
for(int tX = x; tX < x + w; tX++)
|
||||
*retPtr++ = *srcPtr++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void texScaleToTex(const tex *in, tex *out, int scale)
|
||||
{
|
||||
for(int y = 0; y < in->height; y++)
|
||||
{
|
||||
for(int tY = y * scale; tY < (y * scale) + scale; tY++)
|
||||
{
|
||||
uint32_t *inPtr = &in->data[y * in->width];
|
||||
for(int x = 0; x < in->width; x++, inPtr++)
|
||||
{
|
||||
for(int tX = x * scale; tX < (x * scale) + scale; tX++)
|
||||
{
|
||||
out->data[tY * (in->width * scale) + tX] = *inPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void texApplyAlphaMask(tex *target, const alphaMask *a)
|
||||
{
|
||||
if(target->width != a->width || target->height != a->height)
|
||||
return;
|
||||
|
||||
uint32_t *pix = &target->data[0];
|
||||
for(unsigned i = 0; i < target->size; i++, pix++)
|
||||
{
|
||||
clr msk = clrCreateU32(*pix);
|
||||
msk.a = a->dat[i];
|
||||
*pix = clrGetColor(msk);
|
||||
}
|
||||
}
|
||||
|
||||
alphaMask *alphaMaskLoad(unsigned w, unsigned h, const char *file)
|
||||
{
|
||||
FILE *mskIn = fopen(file, "rb");
|
||||
if(!mskIn)
|
||||
return NULL;
|
||||
|
||||
fseek(mskIn, 0, SEEK_END);
|
||||
size_t mskSize = ftell(mskIn);
|
||||
fseek(mskIn, 0, SEEK_SET);
|
||||
|
||||
alphaMask *ret = malloc(sizeof(alphaMask));
|
||||
ret->width = w;
|
||||
ret->height = h;
|
||||
ret->dat = malloc(w * h);
|
||||
|
||||
fread(ret->dat, 1, mskSize, mskIn);
|
||||
fclose(mskIn);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void alphaMaskDestroy(alphaMask *a)
|
||||
{
|
||||
free(a->dat);
|
||||
free(a);
|
||||
}
|
||||
|
||||
font *fontLoadSharedFonts()
|
||||
{
|
||||
font *ret = malloc(sizeof(font));
|
||||
if((ret->libRet = FT_Init_FreeType(&ret->lib)))
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
PlFontData plFont;
|
||||
if(R_FAILED(plGetSharedFontByType(&plFont, i)))
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ret->faceRet = FT_New_Memory_Face(ret->lib, plFont.address, plFont.size, 0, &ret->face[i])))
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret->external = false;
|
||||
ret->fntData = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
font *fontLoadTTF(const char *path)
|
||||
{
|
||||
font *ret = malloc(sizeof(font));
|
||||
if((ret->libRet = FT_Init_FreeType(&ret->lib)))
|
||||
{
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *ttf = fopen(path, "rb");
|
||||
fseek(ttf, 0, SEEK_END);
|
||||
size_t ttfSize = ftell(ttf);
|
||||
fseek(ttf, 0, SEEK_SET);
|
||||
|
||||
ret->fntData = malloc(ttfSize);
|
||||
fread(ret->fntData, 1, ttfSize, ttf);
|
||||
fclose(ttf);
|
||||
|
||||
if((ret->faceRet = FT_New_Memory_Face(ret->lib, ret->fntData, ttfSize, 0, &ret->face[0])))
|
||||
{
|
||||
free(ret->fntData);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->external = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fontDestroy(font *f)
|
||||
{
|
||||
if(f->external && f->faceRet == 0)
|
||||
FT_Done_Face(f->face[0]);
|
||||
else if(!f->external && f->faceRet == 0)
|
||||
{
|
||||
for(int i = 0; i < 6; i++)
|
||||
FT_Done_Face(f->face[i]);
|
||||
}
|
||||
if(f->libRet == 0)
|
||||
FT_Done_FreeType(f->lib);
|
||||
if(f->fntData != NULL)
|
||||
free(f->fntData);
|
||||
|
||||
free(f);
|
||||
}
|
||||
367
src/gfx.cpp
Normal file
367
src/gfx.cpp
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include <switch.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#define VA_SIZE 1024
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
static SDL_Window *wind;
|
||||
SDL_Renderer *gfx::render;
|
||||
|
||||
static FT_Library lib;
|
||||
static FT_Face face[6];
|
||||
static int totalFonts = 0;
|
||||
static bool loaded = false;
|
||||
|
||||
static const SDL_Color *textcol;
|
||||
static SDL_Color red = {0xFF, 0x00, 0x00, 0xFF};
|
||||
static SDL_Color green = {0x00, 0xFF, 0x00, 0xFF};
|
||||
static SDL_Color blue = {0x00, 0x99, 0xEE, 0xFF};
|
||||
static SDL_Color yellow = {0xF8, 0xFC, 0x00, 0xFF};
|
||||
|
||||
static const uint32_t redMask = 0xFF000000;
|
||||
static const uint32_t greenMask = 0x00FF0000;
|
||||
static const uint32_t blueMask = 0x0000FF00;
|
||||
static const uint32_t alphaMask = 0x000000FF;
|
||||
|
||||
static inline bool compClr(const SDL_Color *c1, const SDL_Color *c2)
|
||||
{
|
||||
return (c1->r == c2->r) && (c1->b == c2->b) && (c1->g == c2->g) && (c1->a == c2->a);
|
||||
}
|
||||
|
||||
//Cache glyph textures
|
||||
typedef struct
|
||||
{
|
||||
uint16_t w, h;
|
||||
int advX, top, left;
|
||||
SDL_Texture *tex;
|
||||
} glyphData;
|
||||
|
||||
//<Char, font size>, tex
|
||||
std::map<std::pair<uint32_t, int>, glyphData> glyphCache;
|
||||
|
||||
static bool loadSystemFont()
|
||||
{
|
||||
PlFontData shared[6];
|
||||
uint64_t langCode = 0;
|
||||
|
||||
if(R_FAILED(plInitialize(PlServiceType_System)))
|
||||
return false;
|
||||
|
||||
if(FT_Init_FreeType(&lib))
|
||||
return false;
|
||||
|
||||
if(R_FAILED(setGetLanguageCode(&langCode)))
|
||||
return false;
|
||||
|
||||
|
||||
if(R_FAILED(plGetSharedFont(langCode, shared, 6, &totalFonts)))
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < totalFonts; i++)
|
||||
{
|
||||
if(FT_New_Memory_Face(lib, (FT_Byte *)shared[i].address, shared[i].size, 0, &face[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void freeSystemFont()
|
||||
{
|
||||
if(loaded)
|
||||
{
|
||||
for(int i = 0; i < totalFonts; i++)
|
||||
FT_Done_Face(face[i]);
|
||||
|
||||
FT_Done_FreeType(lib);
|
||||
}
|
||||
|
||||
plExit();
|
||||
}
|
||||
|
||||
void gfx::init()
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
|
||||
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1");
|
||||
|
||||
wind = SDL_CreateWindow("JKSV", 0, 0, 1280, 720, SDL_WINDOW_SHOWN);
|
||||
render = SDL_CreateRenderer(wind, -1, SDL_RENDERER_ACCELERATED);
|
||||
loadSystemFont();
|
||||
}
|
||||
|
||||
void gfx::exit()
|
||||
{
|
||||
IMG_Quit();
|
||||
SDL_Quit();
|
||||
freeSystemFont();
|
||||
|
||||
for(auto c : glyphCache)
|
||||
SDL_DestroyTexture(c.second.tex);
|
||||
}
|
||||
|
||||
void gfx::clear(const SDL_Color *c)
|
||||
{
|
||||
SDL_SetRenderDrawColor(render, c->r, c->g, c->b, c->a);
|
||||
SDL_RenderClear(render);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void resizeFont(int sz)
|
||||
{
|
||||
for(int i = 0; i < totalFonts; i++)
|
||||
FT_Set_Char_Size(face[i], 0, sz * 64, 90, 90);
|
||||
}
|
||||
|
||||
static inline FT_GlyphSlot loadGlyph(const uint32_t c, FT_Int32 flags)
|
||||
{
|
||||
for(int i = 0; i < totalFonts; i++)
|
||||
{
|
||||
FT_UInt cInd = 0;
|
||||
if( (cInd = FT_Get_Char_Index(face[i], c)) != 0 && FT_Load_Glyph(face[i], cInd, flags) == 0)
|
||||
return face[i]->glyph;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static glyphData *getGlyph(uint32_t chr, int size)
|
||||
{
|
||||
//If it's already been loaded and rendered, grab the texture
|
||||
if(glyphCache.find(std::make_pair(chr, size)) != glyphCache.end())
|
||||
return &glyphCache[std::make_pair(chr, size)];
|
||||
|
||||
//Load glyph with Freetype
|
||||
FT_GlyphSlot glyph = loadGlyph(chr, FT_LOAD_RENDER);
|
||||
FT_Bitmap bmp = glyph->bitmap;
|
||||
if(bmp.pixel_mode != FT_PIXEL_MODE_GRAY)
|
||||
return NULL;
|
||||
|
||||
//Convert to SDL_Surface -> Texture
|
||||
SDL_Texture *tex;
|
||||
size_t glyphSize = bmp.rows * bmp.width;
|
||||
uint8_t *bmpPtr = bmp.buffer;
|
||||
uint32_t basePixel = 0xFFFFFF00;
|
||||
uint32_t *tmpBuff = (uint32_t *)malloc(sizeof(uint32_t) * glyphSize);
|
||||
|
||||
//Loop through and fill out buffer
|
||||
for(size_t i = 0; i < glyphSize; i++)
|
||||
tmpBuff[i] = basePixel | *bmpPtr++;
|
||||
|
||||
SDL_Surface *tmpSurf = SDL_CreateRGBSurfaceFrom(tmpBuff, bmp.width, bmp.rows, 32, 4 * bmp.width, redMask, greenMask, blueMask, alphaMask);
|
||||
tex = SDL_CreateTextureFromSurface(gfx::render, tmpSurf);
|
||||
|
||||
SDL_FreeSurface(tmpSurf);
|
||||
free(tmpBuff);
|
||||
|
||||
//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};
|
||||
|
||||
return &glyphCache[std::make_pair(chr, size)];
|
||||
}
|
||||
|
||||
//Takes care of special characters/color switching
|
||||
static inline bool specialChar(const uint32_t *p, const int *fontSize, const SDL_Color *c, const int *baseX, int *modX, int *modY)
|
||||
{
|
||||
//set to false on default
|
||||
bool ret = true;
|
||||
|
||||
switch(*p)
|
||||
{
|
||||
case '\n':
|
||||
*modX = *baseX;
|
||||
*modY += *fontSize + 8;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
if(compClr(textcol, &blue))
|
||||
textcol = c;
|
||||
else
|
||||
textcol = &blue;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if(compClr(textcol, &red))
|
||||
textcol = c;
|
||||
else
|
||||
textcol = &red;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if(compClr(textcol, &yellow))
|
||||
textcol = c;
|
||||
else
|
||||
textcol = &yellow;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if(compClr(textcol, &green))
|
||||
textcol = c;
|
||||
else
|
||||
textcol = &green;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = false;//no special char
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gfx::drawTextf(int fontSize, int x, int y, const SDL_Color *c, const char *fmt, ...)
|
||||
{
|
||||
char tmp[VA_SIZE];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
int tmpX = x;
|
||||
uint32_t point = 0;
|
||||
ssize_t unitCnt = 0;
|
||||
size_t textLength = strlen(tmp);
|
||||
|
||||
resizeFont(fontSize);
|
||||
|
||||
textcol = c;
|
||||
|
||||
for(unsigned i = 0; i < textLength; )
|
||||
{
|
||||
unitCnt = decode_utf8(&point, (const uint8_t *)&tmp[i]);
|
||||
if(unitCnt <= 0)
|
||||
break;
|
||||
|
||||
i += unitCnt;
|
||||
if(specialChar(&point, &fontSize, c, &x, &tmpX, &y))
|
||||
continue;
|
||||
|
||||
glyphData *g = getGlyph(point, fontSize);
|
||||
if(g != NULL)
|
||||
{
|
||||
SDL_Rect src = {0, 0, g->w, g->h};
|
||||
SDL_Rect dst = {tmpX + g->left, y + (fontSize - g->top), g->w, g->h};
|
||||
SDL_SetTextureColorMod(g->tex, c->r, c->g, c->b);
|
||||
SDL_RenderCopy(render, g->tex, &src, &dst);
|
||||
|
||||
tmpX += g->advX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gfx::drawTextfWrap(int fontSize, int x, int y, int maxWidth, const SDL_Color *c, const char *fmt, ...)
|
||||
{
|
||||
char tmp[VA_SIZE], wordBuff[128];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
resizeFont(fontSize);
|
||||
size_t nextBreak = 0, strlength = strlen(tmp);
|
||||
int tmpX = x;
|
||||
|
||||
textcol = c;
|
||||
|
||||
for(unsigned i = 0; i < strlength; )
|
||||
{
|
||||
nextBreak = strcspn(&tmp[i], " /_-");
|
||||
memset(wordBuff, 0, 128);
|
||||
memcpy(wordBuff, &tmp[i], nextBreak + 1);
|
||||
|
||||
size_t width = gfx::getTextWidth(wordBuff, fontSize);
|
||||
|
||||
if(tmpX + width >= x + maxWidth)
|
||||
{
|
||||
tmpX = x;
|
||||
y += fontSize + 8;
|
||||
}
|
||||
|
||||
size_t wordLength = strlen(wordBuff);
|
||||
uint32_t point = 0;
|
||||
for(unsigned j = 0; j < wordLength; )
|
||||
{
|
||||
ssize_t unitCnt = decode_utf8(&point, (const uint8_t *)&wordBuff[j]);
|
||||
if(unitCnt <= 0)
|
||||
break;
|
||||
|
||||
j += unitCnt;
|
||||
|
||||
if(specialChar(&point, &fontSize, c, &x, &tmpX, &y))
|
||||
continue;
|
||||
|
||||
glyphData *g = getGlyph(point, fontSize);
|
||||
if(g != NULL)
|
||||
{
|
||||
SDL_Rect src = {0, 0, g->w, g->h};
|
||||
SDL_Rect dst = {tmpX + g->left, y + (fontSize - g->top), g->w, g->h};
|
||||
SDL_SetTextureColorMod(g->tex, textcol->r, textcol->g, textcol->b);
|
||||
SDL_RenderCopy(render, g->tex, &src, &dst);
|
||||
|
||||
tmpX += g->advX;
|
||||
}
|
||||
}
|
||||
i += wordLength;
|
||||
}
|
||||
}
|
||||
|
||||
size_t gfx::getTextWidth(const char *str, int fontSize)
|
||||
{
|
||||
resizeFont(fontSize);
|
||||
size_t width = 0, strlength = strlen(str);
|
||||
uint32_t unitCnt = 0, point = 0;
|
||||
|
||||
for(unsigned i = 0; i < strlength; )
|
||||
{
|
||||
unitCnt = decode_utf8(&point, (const uint8_t *)&str[i]);
|
||||
if(unitCnt <= 0)
|
||||
break;
|
||||
|
||||
i += unitCnt;
|
||||
|
||||
//Ignore these
|
||||
if(point == '\n')
|
||||
continue;
|
||||
|
||||
glyphData *g = getGlyph(point, fontSize);
|
||||
if(g != NULL)
|
||||
width += g->advX;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ int main(int argc, const char *argv[])
|
|||
{
|
||||
romfsInit();
|
||||
fs::init();
|
||||
graphicsInit(1280, 720);
|
||||
gfx::init();
|
||||
ui::initTheme();
|
||||
ui::showLoadScreen();
|
||||
data::init();
|
||||
|
|
@ -63,16 +63,15 @@ int main(int argc, const char *argv[])
|
|||
else if(down & HidNpadButton_Plus)
|
||||
break;
|
||||
|
||||
gfxBeginFrame();
|
||||
ui::runApp(down, held);
|
||||
|
||||
if(debDataStats)
|
||||
data::dispStats();
|
||||
gfxEndFrame();
|
||||
gfx::present();
|
||||
}
|
||||
|
||||
ui::exit();
|
||||
data::exit();
|
||||
graphicsExit();
|
||||
gfx::exit();
|
||||
fs::exit();
|
||||
}
|
||||
|
|
|
|||
280
src/ui.cpp
280
src/ui.cpp
|
|
@ -26,29 +26,23 @@ ColorSetId ui::thmID;
|
|||
std::string ui::folderMenuInfo;
|
||||
|
||||
//UI colors
|
||||
clr ui::clearClr, ui::txtCont, ui::txtDiag, ui::rectLt, ui::rectSh, ui::tboxClr, divClr;
|
||||
SDL_Color ui::clearClr, ui::txtCont, ui::txtDiag, ui::rectLt, ui::rectSh, ui::tboxClr, divClr;
|
||||
|
||||
//textbox pieces
|
||||
//I was going to flip them when I draw them, but then laziness kicked in.
|
||||
tex *ui::cornerTopLeft, *ui::cornerTopRight, *ui::cornerBottomLeft, *ui::cornerBottomRight;
|
||||
SDL_Texture *ui::cornerTopLeft, *ui::cornerTopRight, *ui::cornerBottomLeft, *ui::cornerBottomRight;
|
||||
|
||||
//Progress bar covers + dialog box predrawn
|
||||
tex *ui::progCovLeft, *ui::progCovRight, *ui::diaBox;
|
||||
SDL_Texture *ui::progCovLeft, *ui::progCovRight, *ui::diaBox;
|
||||
|
||||
//Menu box pieces
|
||||
tex *mnuTopLeft, *mnuTopRight, *mnuBotLeft, *mnuBotRight;
|
||||
SDL_Texture *mnuTopLeft, *mnuTopRight, *mnuBotLeft, *mnuBotRight;
|
||||
|
||||
//Select box + top left icon
|
||||
tex *ui::sideBar;
|
||||
SDL_Texture *ui::sideBar;
|
||||
|
||||
alphaMask *ui::iconMask;
|
||||
|
||||
//Shared font
|
||||
font *ui::shared;
|
||||
|
||||
//Don't waste time drawing top and bottom over and over
|
||||
//guide graphics are to save cpu drawing that over and over with alpha
|
||||
static tex *top, *bot, *usrGuide, *ttlGuide, *fldrGuide, *optGuide;
|
||||
static SDL_Texture *icn;
|
||||
static SDL_Color white = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
|
||||
//X position of help texts. Calculated to make editing quicker/easier
|
||||
static unsigned userHelpX, titleHelpX, folderHelpX, optHelpX;
|
||||
|
|
@ -234,87 +228,69 @@ static void loadTrans()
|
|||
|
||||
void ui::initTheme()
|
||||
{
|
||||
if(fs::fileExists(fs::getWorkDir() + "font.ttf"))
|
||||
shared = fontLoadTTF(std::string(fs::getWorkDir() + "font.ttf").c_str());
|
||||
else
|
||||
shared = fontLoadSharedFonts();
|
||||
|
||||
iconMask = alphaMaskLoad(256, 256, "romfs:/img/icn/icon.msk");
|
||||
|
||||
setsysGetColorSetId(&thmID);
|
||||
|
||||
switch(thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
clearClr = clrCreateU32(0xFFEBEBEB);
|
||||
txtCont = clrCreateU32(0xFF000000);
|
||||
txtDiag = clrCreateU32(0xFFFFFFFF);
|
||||
rectLt = clrCreateU32(0xFFDFDFDF);
|
||||
rectSh = clrCreateU32(0xFFCACACA);
|
||||
tboxClr = clrCreateU32(0xFF505050);
|
||||
divClr = clrCreateU32(0xFF000000);
|
||||
clearClr = {0xEB, 0xEB, 0xEB, 0xFF};
|
||||
txtCont = {0x00, 0x00, 0x00, 0xFF};
|
||||
txtDiag = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
rectLt = {0xDF, 0xDF, 0xDF, 0xFF};
|
||||
rectSh = {0xCA, 0xCA, 0xCA, 0xFF};
|
||||
tboxClr = {0x50, 0x50, 0x50, 0xFF};
|
||||
divClr = {0x00, 0x00, 0x00, 0xFF};
|
||||
break;
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
//jic
|
||||
thmID = ColorSetId_Dark;
|
||||
clearClr = clrCreateU32(0xFF2D2D2D);
|
||||
txtCont = clrCreateU32(0xFFFFFFFF);
|
||||
txtDiag = clrCreateU32(0xFF000000);
|
||||
rectLt = clrCreateU32(0xFF505050);
|
||||
rectSh = clrCreateU32(0xFF202020);
|
||||
tboxClr = clrCreateU32(0xFFEBEBEB);
|
||||
divClr = clrCreateU32(0xFFFFFFFF);
|
||||
|
||||
clearClr = {0x2D, 0x2D, 0x2D, 0xFF};
|
||||
txtCont = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
txtDiag = {0x00, 0x00, 0x00, 0xFF};
|
||||
rectLt = {0x50, 0x50, 0x50, 0xFF};
|
||||
rectSh = {0x20, 0x20, 0x20, 0xFF};
|
||||
tboxClr = {0xEB, 0xEB, 0xEB, 0xFF};
|
||||
divClr = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::init()
|
||||
{
|
||||
tex *icn;
|
||||
char verStr[16];
|
||||
mnuTopLeft = texLoadPNGFile("romfs:/img/fb/menuTopLeft.png");
|
||||
mnuTopRight = texLoadPNGFile("romfs:/img/fb/menuTopRight.png");
|
||||
mnuBotLeft = texLoadPNGFile("romfs:/img/fb/menuBotLeft.png");
|
||||
mnuBotRight = texLoadPNGFile("romfs:/img/fb/menuBotRight.png");
|
||||
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");
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
//Dark corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnDrk.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lLight.png");
|
||||
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/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");
|
||||
break;
|
||||
|
||||
default:
|
||||
//Light corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverLeftLight.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverRightLight.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnLght.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lDark.png");
|
||||
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/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");
|
||||
break;
|
||||
}
|
||||
|
||||
top = texCreate(1280, 88);
|
||||
bot = texCreate(1280, 72);
|
||||
diaBox = texCreate(640, 420);
|
||||
|
||||
//Setup dialog box
|
||||
drawTextbox(diaBox, 0, 0, 640, 420);
|
||||
drawRect(diaBox, 0, 56, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
|
||||
if(ui::textMode && data::skipUser)
|
||||
{
|
||||
ui::textTitlePrep(data::curUser);
|
||||
|
|
@ -339,45 +315,11 @@ void ui::init()
|
|||
util::replaceButtonsInString(ui::optMenuExp[4]);
|
||||
util::replaceButtonsInString(ui::optMenuExp[5]);
|
||||
|
||||
//Setup top and bottom gfx
|
||||
texClearColor(top, clearClr);
|
||||
texDraw(icn, top, 66, 27);
|
||||
drawText("JKSV", top, shared, 130, 38, 24, ui::txtCont);
|
||||
drawRect(top, 30, 87, 1220, 1, ui::txtCont);
|
||||
|
||||
texClearColor(bot, clearClr);
|
||||
drawRect(bot, 30, 0, 1220, 1, ui::txtCont);
|
||||
sprintf(verStr, "v. %02d.%02d.%04d", BLD_MON, BLD_DAY, BLD_YEAR);
|
||||
drawText(verStr, bot, shared, 8, author == "NULL" ? 56 : 38, 12, ui::txtCont);
|
||||
if(author != "NULL")
|
||||
drawText(std::string("Translation: " + author).c_str(), bot, ui::shared, 8, 56, 12, ui::txtCont);
|
||||
|
||||
//Not needed anymore
|
||||
texDestroy(icn);
|
||||
|
||||
//Create graphics to hold guides
|
||||
usrGuide = texCreate(textGetWidth(userHelp.c_str(), ui::shared, 18), 28);
|
||||
ttlGuide = texCreate(textGetWidth(titleHelp.c_str(), ui::shared, 18), 28);
|
||||
fldrGuide = texCreate(textGetWidth(folderHelp.c_str(), ui::shared, 18), 28);
|
||||
optGuide = texCreate(textGetWidth(optHelp.c_str(), ui::shared, 18), 28);
|
||||
|
||||
//Clear with bg color
|
||||
texClearColor(usrGuide, ui::clearClr);
|
||||
texClearColor(ttlGuide, ui::clearClr);
|
||||
texClearColor(fldrGuide, ui::clearClr);
|
||||
texClearColor(optGuide, ui::clearClr);
|
||||
|
||||
//Draw text to them
|
||||
drawText(userHelp.c_str(), usrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(titleHelp.c_str(), ttlGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(folderHelp.c_str(), fldrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(optHelp.c_str(), optGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
|
||||
//Calculate x position of help text
|
||||
userHelpX = 1220 - usrGuide->width;
|
||||
titleHelpX = 1220 - ttlGuide->width;
|
||||
folderHelpX = 1220 - fldrGuide->width;
|
||||
optHelpX = 1220 - optGuide->width;
|
||||
userHelpX = 1220 - gfx::getTextWidth(ui::userHelp.c_str(), 18);
|
||||
titleHelpX = 1220 - gfx::getTextWidth(ui::titleHelp.c_str(), 18);
|
||||
folderHelpX = 1220 - gfx::getTextWidth(ui::folderHelp.c_str(), 18);
|
||||
optHelpX = 1220 - gfx::getTextWidth(ui::optHelp.c_str(), 18);
|
||||
|
||||
//setup pad
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
|
|
@ -390,98 +332,93 @@ void ui::init()
|
|||
|
||||
void ui::exit()
|
||||
{
|
||||
texDestroy(cornerTopLeft);
|
||||
texDestroy(cornerTopRight);
|
||||
texDestroy(cornerBottomLeft);
|
||||
texDestroy(cornerBottomRight);
|
||||
texDestroy(progCovLeft);
|
||||
texDestroy(progCovRight);
|
||||
SDL_DestroyTexture(cornerTopLeft);
|
||||
SDL_DestroyTexture(cornerTopRight);
|
||||
SDL_DestroyTexture(cornerBottomLeft);
|
||||
SDL_DestroyTexture(cornerBottomRight);
|
||||
SDL_DestroyTexture(progCovLeft);
|
||||
SDL_DestroyTexture(progCovRight);
|
||||
|
||||
texDestroy(mnuTopLeft);
|
||||
texDestroy(mnuTopRight);
|
||||
texDestroy(mnuBotLeft);
|
||||
texDestroy(mnuBotRight);
|
||||
SDL_DestroyTexture(mnuTopLeft);
|
||||
SDL_DestroyTexture(mnuTopRight);
|
||||
SDL_DestroyTexture(mnuBotLeft);
|
||||
SDL_DestroyTexture(mnuBotRight);
|
||||
|
||||
texDestroy(usrGuide);
|
||||
texDestroy(ttlGuide);
|
||||
texDestroy(fldrGuide);
|
||||
texDestroy(optGuide);
|
||||
|
||||
texDestroy(top);
|
||||
texDestroy(bot);
|
||||
texDestroy(diaBox);
|
||||
|
||||
alphaMaskDestroy(iconMask);
|
||||
|
||||
fontDestroy(shared);
|
||||
SDL_DestroyTexture(icn);
|
||||
}
|
||||
|
||||
void ui::showLoadScreen()
|
||||
{
|
||||
tex *icn = texLoadJPEGFile("romfs:/icon.jpg");
|
||||
gfxBeginFrame();
|
||||
texClearColor(frameBuffer, clrCreateU32(0xFF2D2D2D));
|
||||
texDrawNoAlpha(icn, frameBuffer, 512, 232);
|
||||
drawText("Loading...", frameBuffer, ui::shared, 1100, 673, 16, clrCreateU32(0xFFFFFFFF));
|
||||
gfxEndFrame();
|
||||
texDestroy(icn);
|
||||
SDL_Texture *icon = gfx::loadImageFile("romfs:/icon.jpg");
|
||||
SDL_SetRenderDrawColor(gfx::render, 0x2D, 0x2D, 0x2D, 0xFF);
|
||||
SDL_RenderClear(gfx::render);
|
||||
gfx::texDraw(icon, 512, 232);
|
||||
gfx::drawTextf(16, 1100, 673, &white, "Loading...");
|
||||
gfx::present();
|
||||
SDL_DestroyTexture(icon);
|
||||
}
|
||||
|
||||
void ui::drawUI()
|
||||
{
|
||||
texClearColor(frameBuffer, clearClr);
|
||||
texDrawNoAlpha(top, frameBuffer, 0, 0);
|
||||
texDrawNoAlpha(bot, frameBuffer, 0, 648);
|
||||
gfx::clear(&ui::clearClr);
|
||||
gfx::texDraw(icn, 66, 27);
|
||||
gfx::drawTextf(24, 130, 38, &ui::txtCont, "JKSV");
|
||||
gfx::drawLine(&divClr, 30, 88, 1250, 88);
|
||||
gfx::drawLine(&divClr, 30, 648, 1250, 648);
|
||||
|
||||
//Version / translation author
|
||||
gfx::drawTextf(12, 8, 700, &ui::txtCont, "v. %02d.%02d.%04d", BLD_MON, BLD_DAY, BLD_YEAR);
|
||||
if(author != "NULL")
|
||||
gfx::drawTextf(12, 8, 682, &ui::txtCont, "Translation: %s", author.c_str());
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
gfx::drawTextf(18, userHelpX, 673, &ui::txtCont, userHelp.c_str());
|
||||
ui::drawUserMenu();
|
||||
break;
|
||||
|
||||
case TTL_SEL:
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
gfx::drawTextf(18, titleHelpX, 673, &ui::txtCont, titleHelp.c_str());
|
||||
ui::drawTitleMenu();
|
||||
break;
|
||||
|
||||
case FLD_SEL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
gfx::drawTextf(18, folderHelpX, 673, &ui::txtCont, folderHelp.c_str());
|
||||
ui::drawFolderMenu();
|
||||
break;
|
||||
|
||||
case TXT_USR:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
gfx::drawTextf(18, userHelpX, 673, &ui::txtCont, userHelp.c_str());
|
||||
ui::drawTextUserMenu();
|
||||
break;
|
||||
|
||||
case TXT_TTL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
gfx::drawTextf(18, titleHelpX, 673, &ui::txtCont, titleHelp.c_str());
|
||||
ui::drawTextTitleMenu();
|
||||
break;
|
||||
|
||||
case TXT_FLD:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
gfx::drawTextf(18, folderHelpX, 673, &ui::txtCont, folderHelp.c_str());
|
||||
ui::drawTextFolderMenu();
|
||||
break;
|
||||
|
||||
case EX_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
ui::drawExMenu();
|
||||
break;
|
||||
|
||||
case OPT_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(optGuide, frameBuffer, optHelpX, 673);
|
||||
gfx::texDraw(sideBar, 0, 89);
|
||||
ui::drawOptMenu();
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
drawRect(frameBuffer, 640, 88, 1, 559, ui::txtCont);
|
||||
gfx::drawRect(&ui::txtCont, 640, 88, 1, 559);
|
||||
drawAdvMode();
|
||||
break;
|
||||
}
|
||||
|
|
@ -489,43 +426,30 @@ void ui::drawUI()
|
|||
|
||||
void ui::drawBoundBox(int x, int y, int w, int h, int clrSh)
|
||||
{
|
||||
clr rectClr = clrCreateRGBA(0x00, 0x88 + clrSh, 0xC5 + (clrSh / 2), 0xFF);
|
||||
SDL_Color rectClr;
|
||||
|
||||
texSwapColors(mnuTopLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuTopRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
if(ui::thmID == ColorSetId_Light)
|
||||
rectClr = {0xFD, 0xFD, 0xFD, 0xFF};
|
||||
else
|
||||
rectClr = {0x21, 0x22, 0x21, 0xFF};
|
||||
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFFFDFDFD));
|
||||
break;
|
||||
gfx::drawRect(&rectClr, x + 4, y + 4, w - 8, h - 8);
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFF212221));
|
||||
break;
|
||||
}
|
||||
rectClr = {0x00, 0x88, 0xC5, 0xFF};
|
||||
|
||||
//top
|
||||
texDraw(mnuTopLeft, frameBuffer, x, y);
|
||||
drawRect(frameBuffer, x + 4, y, w - 8, 4, rectClr);
|
||||
texDraw(mnuTopRight, frameBuffer, (x + w) - 4, y);
|
||||
gfx::texDraw(mnuTopLeft, x, y);
|
||||
gfx::drawRect(&rectClr, x + 4, y, w - 8, 4);
|
||||
gfx::texDraw(mnuTopRight, (x + w) - 4, y);
|
||||
|
||||
//mid
|
||||
drawRect(frameBuffer, x, y + 4, 4, h - 8, rectClr);
|
||||
drawRect(frameBuffer, (x + w) - 4, y + 4, 4, h - 8, rectClr);
|
||||
gfx::drawRect(&rectClr, x, y + 4, 4, h - 8);
|
||||
gfx::drawRect(&rectClr, (x + w) - 4, y + 4, 4, h - 8);
|
||||
|
||||
//bottom
|
||||
texDraw(mnuBotLeft, frameBuffer, x, (y + h) - 4);
|
||||
drawRect(frameBuffer, x + 4, (y + h) - 4, w - 8, 4, rectClr);
|
||||
texDraw(mnuBotRight, frameBuffer, (x + w) - 4, (y + h) - 4);
|
||||
|
||||
texSwapColors(mnuTopLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuTopRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
gfx::texDraw(mnuBotLeft, x, (y + h) - 4);
|
||||
gfx::drawRect(&rectClr, x + 4, (y + h) - 4, w - 8, 4);
|
||||
gfx::texDraw(mnuBotRight, (x + w) - 4, (y + h) - 4);
|
||||
}
|
||||
|
||||
void ui::runApp(const uint64_t& down, const uint64_t& held)
|
||||
|
|
|
|||
|
|
@ -371,11 +371,11 @@ void ui::advModePrep(const std::string& svDev, const FsSaveDataType& _type, bool
|
|||
|
||||
void ui::drawAdvMode()
|
||||
{
|
||||
saveMenu.draw(ui::txtCont);
|
||||
sdMenu.draw(ui::txtCont);
|
||||
saveMenu.draw(&ui::txtCont);
|
||||
sdMenu.draw(&ui::txtCont);
|
||||
|
||||
drawTextWrap(savePath.c_str(), frameBuffer, ui::shared, 30, 654, 14, ui::txtCont, 600);
|
||||
drawTextWrap(sdPath.c_str(), frameBuffer, ui::shared, 640, 654, 14, ui::txtCont, 600);
|
||||
gfx::drawTextfWrap(14, 30, 654, 600, &ui::txtCont, savePath.c_str());
|
||||
gfx::drawTextfWrap(14, 640, 654, 600, &ui::txtCont, sdPath.c_str());
|
||||
|
||||
//draw copy menu if it's supposed to be up
|
||||
if(advMenuCtrl == 2)
|
||||
|
|
@ -385,18 +385,18 @@ void ui::drawAdvMode()
|
|||
case 0:
|
||||
copyMenu.setParams(176, 278, 304);
|
||||
copyMenu.editOpt(0, advMenuStr[0] + "sdmc");
|
||||
ui::drawTextbox(frameBuffer, 168, 236, 320, 268);
|
||||
drawText(dev.c_str(), frameBuffer, ui::shared, 176, 250, 18, ui::txtDiag);
|
||||
ui::drawTextbox(168, 236, 320, 268);
|
||||
gfx::drawTextf(18, 176, 250, &ui::txtDiag, dev.c_str());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
copyMenu.setParams(816, 278, 304);
|
||||
copyMenu.editOpt(0, advMenuStr[0] + dev);
|
||||
ui::drawTextbox(frameBuffer, 808, 236, 320, 268);
|
||||
drawText("SDMC", frameBuffer, ui::shared, 816, 250, 18, ui::txtDiag);
|
||||
ui::drawTextbox(808, 236, 320, 268);
|
||||
gfx::drawTextf(18, 816, 250, &ui::txtDiag, "SDMC");
|
||||
break;
|
||||
}
|
||||
copyMenu.draw(ui::txtDiag);
|
||||
copyMenu.draw(&ui::txtDiag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ void ui::deleteBackup(unsigned ind)
|
|||
void ui::drawFolderMenu()
|
||||
{
|
||||
data::curData.drawIcon(true, 96, 98);
|
||||
drawTextWrap(folderMenuInfo.c_str(), frameBuffer, ui::shared, 60, 370, 16, ui::txtCont, 360);
|
||||
folderMenu.draw(ui::txtCont);
|
||||
gfx::drawTextfWrap(16, 60, 370, 360, &ui::txtCont, folderMenuInfo.c_str());
|
||||
folderMenu.draw(&ui::txtCont);
|
||||
}
|
||||
|
||||
void ui::updateFolderMenu(const uint64_t& down, const uint64_t& held)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@
|
|||
#include "ui.h"
|
||||
#include "miscui.h"
|
||||
|
||||
static const clr menuColorLight = clrCreateU32(0xFFF05032), menuColorDark = clrCreateU32(0xFFC5FF00);
|
||||
static const SDL_Color menuColorLight = {0x32, 0x50, 0xF0, 0xFF};
|
||||
static const SDL_Color menuColorDark = {0x00, 0xFF, 0xC5, 0xFF};
|
||||
|
||||
#define HOLD_FC 10
|
||||
|
||||
void ui::menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned& _rW)
|
||||
{
|
||||
|
|
@ -18,7 +21,7 @@ void ui::menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned&
|
|||
|
||||
void ui::menu::addOpt(const std::string& add)
|
||||
{
|
||||
if(textGetWidth(add.c_str(), ui::shared, 18) < rW - 32 || rW == 0)
|
||||
if(gfx::getTextWidth(add.c_str(), 18) < rW - 32 || rW == 0)
|
||||
opt.push_back(add);
|
||||
else
|
||||
{
|
||||
|
|
@ -30,7 +33,7 @@ void ui::menu::addOpt(const std::string& add)
|
|||
|
||||
tmp += add.substr(i, untCnt);
|
||||
i += untCnt;
|
||||
if(textGetWidth(tmp.c_str(), ui::shared, 18) >= rW - 32)
|
||||
if(gfx::getTextWidth(tmp.c_str(), 18) >= rW - 32)
|
||||
{
|
||||
opt.push_back(tmp);
|
||||
break;
|
||||
|
|
@ -59,7 +62,7 @@ void ui::menu::handleInput(const uint64_t& down, const uint64_t& held)
|
|||
fc = 0;
|
||||
|
||||
int size = opt.size() - 1;
|
||||
if((down & HidNpadButton_Up) || ((held & HidNpadButton_Up) && fc == 10))
|
||||
if((down & HidNpadButton_Up) || ((held & HidNpadButton_Up) && fc == HOLD_FC))
|
||||
{
|
||||
selected--;
|
||||
if(selected < 0)
|
||||
|
|
@ -72,7 +75,7 @@ void ui::menu::handleInput(const uint64_t& down, const uint64_t& held)
|
|||
if((selected - 14) > start)
|
||||
start = selected - 14;
|
||||
}
|
||||
else if((down & HidNpadButton_Down) || ((held & HidNpadButton_Down) && fc == 10))
|
||||
else if((down & HidNpadButton_Down) || ((held & HidNpadButton_Down) && fc == HOLD_FC))
|
||||
{
|
||||
selected++;
|
||||
if(selected > size)
|
||||
|
|
@ -101,7 +104,7 @@ void ui::menu::handleInput(const uint64_t& down, const uint64_t& held)
|
|||
}
|
||||
}
|
||||
|
||||
void ui::menu::draw(const clr& textClr)
|
||||
void ui::menu::draw(const SDL_Color *textClr)
|
||||
{
|
||||
if(opt.size() < 1)
|
||||
return;
|
||||
|
|
@ -129,11 +132,11 @@ void ui::menu::draw(const clr& textClr)
|
|||
{
|
||||
if(i == selected)
|
||||
{
|
||||
drawBoundBox(x, y + ((i - start) * 36), rW, 36, clrSh);
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, ui::thmID == ColorSetId_Light ? menuColorLight : menuColorDark);
|
||||
ui::drawBoundBox(x, y + ((i - start) * 36), rW, 36, clrSh);
|
||||
gfx::drawTextf(18, x + 8, (y + 8) + ((i - start) * 36), ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].c_str());
|
||||
}
|
||||
else
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, textClr);
|
||||
gfx::drawTextf(18, x + 8, (y + 8) + ((i - start) * 36), textClr, opt[i].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,14 @@ static std::string popText;
|
|||
static const char *okt = "OK \ue0e0";
|
||||
static unsigned popY, popX, popWidth, popState, frameCount, frameHold;
|
||||
|
||||
static const SDL_Color divLight = {0x6D, 0x6D, 0x6D, 0xFF};
|
||||
static const SDL_Color divDark = {0xCC, 0xCC, 0xCC, 0xFF};
|
||||
static const SDL_Color shadow = {0x66, 0x66, 0x66, 0xFF};
|
||||
|
||||
static const SDL_Color fillBack = {0x66, 0x66, 0x66, 0xFF};
|
||||
static const SDL_Color fillLight = {0x00, 0xFF, 0xC5, 0xFF};
|
||||
static const SDL_Color fillDark = {0x32, 0x50, 0xF0, 0xFF};
|
||||
|
||||
enum popStates
|
||||
{
|
||||
popRise,
|
||||
|
|
@ -36,33 +44,31 @@ void ui::progBar::update(const uint64_t& _prog)
|
|||
|
||||
void ui::progBar::draw(const std::string& text, const std::string& head)
|
||||
{
|
||||
size_t headWidth = textGetWidth(head.c_str(), ui::shared, 20);
|
||||
size_t headWidth = gfx::getTextWidth(head.c_str(), 20);
|
||||
unsigned headX = (1280 / 2) - (headWidth / 2);
|
||||
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawRect(frameBuffer, 320, 206, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
drawRect(frameBuffer, 352, 530, 576, 12, clrCreateU32(0xFF666666));
|
||||
drawRect(frameBuffer, 352, 530, (unsigned)width, 12, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFFC5FF00) : clrCreateU32(0xFFF05032));
|
||||
texDraw(ui::progCovLeft, frameBuffer, 352, 530);
|
||||
texDraw(ui::progCovRight, frameBuffer, 920, 530);
|
||||
ui::drawTextbox(320, 150, 640, 420);
|
||||
gfx::drawLine(ui::thmID == ColorSetId_Light ? &divLight : &divDark, 320, 206, 959, 206);
|
||||
gfx::drawRect(&fillBack, 352, 530, 576, 12);
|
||||
gfx::drawRect(ui::thmID == ColorSetId_Light ? &fillLight : &fillDark, 352, 530, (int)width, 12);
|
||||
gfx::texDraw(ui::progCovLeft, 352, 530);
|
||||
gfx::texDraw(ui::progCovRight, 920, 530);
|
||||
|
||||
drawText(head.c_str(), frameBuffer, ui::shared, headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(text.c_str(), frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
|
||||
gfx::drawTextf(20, headX, 160, &ui::txtDiag, head.c_str());
|
||||
gfx::drawTextfWrap(16, 352, 230, 576, &ui::txtDiag, text.c_str());
|
||||
}
|
||||
|
||||
void ui::showMessage(const char *head, const char *fmt, ...)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth(head, ui::shared, 20) / 2);
|
||||
unsigned okX = (640 / 2) - (textGetWidth(okt, ui::shared, 20) / 2);
|
||||
unsigned headX = (640 / 2) - (gfx::getTextWidth(head, 20) / 2);
|
||||
unsigned okX = (640 / 2) - (gfx::getTextWidth(okt, 20) / 2);
|
||||
|
||||
while(true)
|
||||
{
|
||||
|
|
@ -71,20 +77,16 @@ void ui::showMessage(const char *head, const char *fmt, ...)
|
|||
if(ui::padKeysDown())
|
||||
break;
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawText(head, frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
drawText(okt, frameBuffer, ui::shared, 320 + okX, 522, 20, ui::txtDiag);
|
||||
gfxEndFrame();
|
||||
ui::drawTextbox(320, 150, 640, 420);
|
||||
gfx::drawTextf(20, 320 + headX, 168, &ui::txtDiag, head);
|
||||
gfx::drawTextfWrap(16, 352, 230, 576, &ui::txtDiag, tmp);
|
||||
gfx::drawTextf(20, 320 + okX, 522, &ui::txtDiag, okt);
|
||||
gfx::present();
|
||||
}
|
||||
}
|
||||
|
||||
bool ui::confirm(bool hold, const char *fmt, ...)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
|
@ -94,11 +96,11 @@ bool ui::confirm(bool hold, const char *fmt, ...)
|
|||
bool ret = false, heldDown = false;
|
||||
unsigned loadFrame = 0, holdCount = 0;
|
||||
uint8_t holdClrDiff = 0;
|
||||
clr holdClr = ui::txtDiag;
|
||||
SDL_Color holdClr = ui::txtDiag;
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth("Confirm", ui::shared, 20) / 2);
|
||||
unsigned yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
unsigned noX = 160 - (textGetWidth(ui::nt.c_str(), ui::shared, 20) / 2);
|
||||
unsigned headX = (640 / 2) - (gfx::getTextWidth("Confirm", 20) / 2);
|
||||
unsigned yesX = 160 - (gfx::getTextWidth(ui::yt.c_str(), 20) / 2);
|
||||
unsigned noX = 160 - (gfx::getTextWidth(ui::nt.c_str(), 20) / 2);
|
||||
|
||||
std::string yesText = yt;
|
||||
|
||||
|
|
@ -134,14 +136,14 @@ bool ui::confirm(bool hold, const char *fmt, ...)
|
|||
yesText = ui::holdingText[2];
|
||||
|
||||
yesText += loadGlyphArray[loadFrame];
|
||||
yesX = 160 - (textGetWidth(yesText.c_str(), ui::shared, 20) / 2);
|
||||
yesX = 160 - (gfx::getTextWidth(yesText.c_str(), 20) / 2);
|
||||
}
|
||||
else if(hold && heldDown)
|
||||
{
|
||||
//Reset everything
|
||||
heldDown= false;
|
||||
holdCount = 0, loadFrame = 0, holdClrDiff = 0;
|
||||
yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
yesX = 160 - (gfx::getTextWidth(ui::yt.c_str(), 20) / 2);
|
||||
yesText = ui::yt;
|
||||
holdClr = ui::txtDiag;
|
||||
}
|
||||
|
|
@ -159,18 +161,17 @@ bool ui::confirm(bool hold, const char *fmt, ...)
|
|||
if(hold && heldDown)
|
||||
{
|
||||
if(ui::thmID == ColorSetId_Light)
|
||||
holdClr = clrCreateRGBA(0xFF, 0xFF - holdClrDiff, 0xFF - holdClrDiff, 0xFF);
|
||||
holdClr = {0xFF, 0xFF - holdClrDiff, 0xFF - holdClrDiff, 0xFF};
|
||||
else
|
||||
holdClr = clrCreateRGBA(0x25 + holdClrDiff, 0x00, 0x00, 0xFF);
|
||||
holdClr = {0x25 + holdClrDiff, 0x00, 0x00, 0xFF};
|
||||
}
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawText(ui::confirmHead.c_str(), frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawText(yesText.c_str(), frameBuffer, ui::shared, 320 + yesX, 522, 20, holdClr);
|
||||
drawText(ui::nt.c_str(), frameBuffer, ui::shared, 640 + noX, 522, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
gfxEndFrame();
|
||||
ui::drawTextbox(320, 150, 640, 420);
|
||||
gfx::drawTextf(20, 320 + headX, 168, &ui::txtDiag, ui::confirmHead.c_str());
|
||||
gfx::drawTextf(20, 320 + yesX, 522, &holdClr, yesText.c_str());
|
||||
gfx::drawTextf(20, 640 + noX, 522, &ui::txtDiag, ui::nt.c_str());
|
||||
gfx::drawTextfWrap(16, 352, 230, 576, &ui::txtDiag, tmp);
|
||||
gfx::present();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -185,24 +186,23 @@ bool ui::confirmDelete(const std::string& p)
|
|||
return confirm(data::holdDel, ui::confDel.c_str(), p.c_str());
|
||||
}
|
||||
|
||||
void ui::drawTextbox(tex *target, int x, int y, int w, int h)
|
||||
void ui::drawTextbox(int x, int y, int w, int h)
|
||||
{
|
||||
//Top
|
||||
texDraw(ui::cornerTopLeft, target, x, y);
|
||||
drawRect(target, x + 32, y, w - 64, 32, ui::tboxClr);
|
||||
texDraw(ui::cornerTopRight, target, (x + w) - 32, y);
|
||||
gfx::texDraw(ui::cornerTopLeft, x, y);
|
||||
gfx::drawRect(&ui::tboxClr, x + 32, y, w - 64, 32);
|
||||
gfx::texDraw(ui::cornerTopRight, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
drawRect(target, x, y + 32, w, h - 64, tboxClr);
|
||||
gfx::drawRect(&ui::tboxClr, x, y + 32, w, h - 64);
|
||||
|
||||
//bottom
|
||||
texDraw(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, tboxClr);
|
||||
texDraw(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
|
||||
gfx::texDraw(ui::cornerBottomLeft, x, (y + h) - 32);
|
||||
gfx::drawRect(&ui::tboxClr, x + 32, (y + h) - 32, w - 64, 32);
|
||||
gfx::texDraw(ui::cornerBottomRight, (x + w) - 32, (y + h) - 32);
|
||||
}
|
||||
|
||||
void ui::drawTextboxInvert(tex *target, int x, int y, int w, int h)
|
||||
/*void ui::drawTextboxInvert(tex *target, int x, int y, int w, int h)
|
||||
{
|
||||
clr temp = ui::tboxClr;
|
||||
clrInvert(&temp);
|
||||
|
|
@ -219,7 +219,7 @@ void ui::drawTextboxInvert(tex *target, int x, int y, int w, int h)
|
|||
texDrawInvert(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, temp);
|
||||
texDrawInvert(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
}
|
||||
}*/
|
||||
|
||||
void ui::showPopup(unsigned frames, const char *fmt, ...)
|
||||
{
|
||||
|
|
@ -231,7 +231,7 @@ void ui::showPopup(unsigned frames, const char *fmt, ...)
|
|||
|
||||
frameCount = 0;
|
||||
frameHold = frames;
|
||||
popWidth = textGetWidth(tmp, ui::shared, 24) + 32;
|
||||
popWidth = gfx::getTextWidth(tmp, 24) + 32;
|
||||
popX = 640 - (popWidth / 2);
|
||||
|
||||
popText = tmp;
|
||||
|
|
@ -267,7 +267,7 @@ void ui::drawPopup(const uint64_t& down)
|
|||
break;
|
||||
}
|
||||
|
||||
drawTextbox(frameBuffer, popX, popY, popWidth, 64);
|
||||
drawText(popText.c_str(), frameBuffer, ui::shared, popX + 16, popY + 20, 24, ui::txtDiag);
|
||||
drawTextbox(popX, popY, popWidth, 64);
|
||||
gfx::drawTextf(24, popX + 16, popY + 20, &ui::txtDiag, popText.c_str());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,15 +63,15 @@ void ui::drawTitleMenu()
|
|||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
unsigned titleWidth = textGetWidth(data::curData.getTitle().c_str(), ui::shared, 18);
|
||||
unsigned titleWidth = gfx::getTextWidth(data::curData.getTitle().c_str(), 18);
|
||||
int rectWidth = titleWidth + 32, rectX = (tX + 64) - (rectWidth / 2);
|
||||
if(rectX < 16)
|
||||
rectX = 16;
|
||||
else if(rectX + rectWidth > 1264)
|
||||
rectX = 1264 - rectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, rectX, y - 50, rectWidth, 38);
|
||||
drawText(data::curData.getTitle().c_str(), frameBuffer, ui::shared, rectX + 16, y - 40, 18, ui::txtDiag);
|
||||
ui::drawTextbox(rectX, y - 50, rectWidth, 38);
|
||||
gfx::drawTextf(18, rectX + 16, y - 40, &ui::txtDiag, data::curData.getTitle().c_str());
|
||||
}
|
||||
if(data::curUser.titles[i].getFav())
|
||||
data::curUser.titles[i].drawIconFav(false, tX, y);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void ui::textUserMenuUpdate(const uint64_t& down, const uint64_t& held)
|
|||
|
||||
void ui::drawTextUserMenu()
|
||||
{
|
||||
userMenu.draw(ui::txtCont);
|
||||
userMenu.draw(&ui::txtCont);
|
||||
}
|
||||
|
||||
void ui::textTitleMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
|
|
@ -151,7 +151,7 @@ void ui::textTitleMenuUpdate(const uint64_t& down, const uint64_t& held)
|
|||
|
||||
void ui::drawTextTitleMenu()
|
||||
{
|
||||
titleMenu.draw(ui::txtCont);
|
||||
titleMenu.draw(&ui::txtCont);
|
||||
}
|
||||
|
||||
void ui::textFolderMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
|
|
@ -200,8 +200,8 @@ void ui::textFolderMenuUpdate(const uint64_t& down, const uint64_t& held)
|
|||
|
||||
void ui::drawTextFolderMenu()
|
||||
{
|
||||
titleMenu.draw(ui::txtCont);
|
||||
folderMenu.draw(ui::txtCont);
|
||||
titleMenu.draw(&ui::txtCont);
|
||||
folderMenu.draw(&ui::txtCont);
|
||||
}
|
||||
|
||||
void ui::exMenuPrep()
|
||||
|
|
@ -346,7 +346,7 @@ void ui::updateExMenu(const uint64_t& down, const uint64_t& held)
|
|||
|
||||
void ui::drawExMenu()
|
||||
{
|
||||
exMenu.draw(ui::txtCont);
|
||||
exMenu.draw(&ui::txtCont);
|
||||
}
|
||||
|
||||
static inline void switchBool(bool& sw)
|
||||
|
|
@ -462,7 +462,7 @@ void ui::updateOptMenu(const uint64_t& down, const uint64_t& held)
|
|||
|
||||
void ui::drawOptMenu()
|
||||
{
|
||||
optMenu.draw(ui::txtCont);
|
||||
drawTextWrap(ui::optMenuExp[optMenu.getSelected()].c_str(), frameBuffer, ui::shared, 466, 98, 18, ui::txtCont, 730);
|
||||
optMenu.draw(&ui::txtCont);
|
||||
gfx::drawTextfWrap(18, 466, 98, 730, &ui::txtCont, ui::optMenuExp[optMenu.getSelected()].c_str());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,15 +49,15 @@ void ui::drawUserMenu()
|
|||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
unsigned userWidth = textGetWidth(data::curUser.getUsername().c_str(), ui::shared, 18);
|
||||
unsigned userWidth = gfx::getTextWidth(data::curUser.getUsername().c_str(), 18);
|
||||
int userRectWidth = userWidth + 32, userRectX = (tX + 64) - (userRectWidth / 2);
|
||||
if(userRectX < 16)
|
||||
userRectX = 16;
|
||||
else if(userRectX + userRectWidth > 1264)
|
||||
userRectX = 1264 - userRectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, userRectX, y - 50, userRectWidth, 38);
|
||||
drawText(data::curUser.getUsername().c_str(), frameBuffer, ui::shared, userRectX + 16, y - 40, 18, ui::txtDiag);
|
||||
drawTextbox(userRectX, y - 50, userRectWidth, 38);
|
||||
gfx::drawTextf(18, userRectX + 16, y - 40, &ui::txtDiag, data::curUser.getUsername().c_str());
|
||||
}
|
||||
data::users[i].drawIconHalf(tX, y);
|
||||
}
|
||||
|
|
|
|||
14
src/util.cpp
14
src/util.cpp
|
|
@ -314,12 +314,16 @@ void util::replaceButtonsInString(std::string& rep)
|
|||
replaceStr(rep, "[-]", "\ue0f0");
|
||||
}
|
||||
|
||||
tex *util::createIconGeneric(const char *txt)
|
||||
SDL_Texture *util::createIconGeneric(const char *txt, int fontSize)
|
||||
{
|
||||
tex *ret = texCreate(256, 256);
|
||||
texClearColor(ret, ui::rectLt);
|
||||
unsigned int x = 128 - (textGetWidth(txt, ui::shared, 32) / 2);
|
||||
drawText(txt, ret, ui::shared, x, 112, 32, ui::txtCont);
|
||||
SDL_Texture *ret = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, 256, 256);
|
||||
SDL_SetRenderTarget(gfx::render, ret);
|
||||
SDL_SetRenderDrawColor(gfx::render, ui::rectLt.r, ui::rectLt.g, ui::rectLt.b, ui::rectLt.a);
|
||||
SDL_RenderClear(gfx::render);
|
||||
unsigned int x = 128 - (gfx::getTextWidth(txt, fontSize) / 2);
|
||||
unsigned int y = 128 - (fontSize / 2);
|
||||
gfx::drawTextf(fontSize, x, y, &ui::txtCont, txt);
|
||||
SDL_SetRenderTarget(gfx::render, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user