mirror of
https://github.com/BernardoGiordano/Checkpoint
synced 2024-11-28 19:40:18 +00:00
retrieve user icons
This commit is contained in:
parent
c358c577f2
commit
9d98dec931
4 changed files with 145 additions and 27 deletions
|
@ -31,12 +31,26 @@
|
|||
#include <string.h>
|
||||
#include <switch.h>
|
||||
#include <unordered_map>
|
||||
#include "draw.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "nanojpeg.h"
|
||||
}
|
||||
|
||||
#define USER_ICON_SIZE 96
|
||||
|
||||
struct User {
|
||||
std::string name;
|
||||
u8* icon;
|
||||
};
|
||||
|
||||
namespace Account
|
||||
{
|
||||
Result init(void);
|
||||
void exit(void);
|
||||
|
||||
u8* icon(u128 id);
|
||||
std::string username(u128 id);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,5 +82,6 @@ void DrawText(u32 font, u32 x, u32 y, color_t clr, const char* text);
|
|||
void DrawTextTruncate(u32 font, u32 x, u32 y, color_t clr, const char* text, u32 max_width, const char* end_text);
|
||||
void GetTextDimensions(u32 font, const char* text, u32* width_out, u32* height_out);
|
||||
void DrawImage(int x, int y, int width, int height, const u8 *image, ImageMode mode);
|
||||
void downscaleRGBImg(const u8 *image, u8* out, int srcWidth, int srcHeight, int destWidth, int destHeight);
|
||||
|
||||
#endif
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "account.hpp"
|
||||
|
||||
static std::unordered_map<u128, std::string> mUsernames;
|
||||
static std::unordered_map<u128, User> mUsers;
|
||||
|
||||
Result Account::init(void)
|
||||
{
|
||||
|
@ -35,38 +35,77 @@ Result Account::init(void)
|
|||
|
||||
void Account::exit(void)
|
||||
{
|
||||
for (auto& value : mUsers)
|
||||
{
|
||||
free(value.second.icon);
|
||||
}
|
||||
accountExit();
|
||||
}
|
||||
|
||||
static User getUser(u128 id)
|
||||
{
|
||||
User user{ "", NULL };
|
||||
AccountProfile profile;
|
||||
AccountProfileBase profilebase;
|
||||
memset(&profilebase, 0, sizeof(profilebase));
|
||||
|
||||
if (R_SUCCEEDED(accountGetProfile(&profile, id)) &&
|
||||
R_SUCCEEDED(accountProfileGet(&profile, NULL, &profilebase)))
|
||||
{
|
||||
user.name = std::string(profilebase.username, 0x20);
|
||||
|
||||
//load icon
|
||||
u8* buffer;
|
||||
size_t image_size, real_size;
|
||||
if (R_SUCCEEDED(accountProfileGetImageSize(&profile, &image_size)) &&
|
||||
(buffer = (u8*)malloc(image_size)) != NULL &&
|
||||
R_SUCCEEDED(accountProfileLoadImage(&profile, buffer, image_size, &real_size)))
|
||||
{
|
||||
njInit();
|
||||
size_t fullsize = 256*256*3;
|
||||
if (njDecode(buffer, real_size) == NJ_OK &&
|
||||
njGetWidth() == 256 &&
|
||||
njGetHeight() == 256 &&
|
||||
(size_t)njGetImageSize() == fullsize &&
|
||||
njIsColor() == 1)
|
||||
{
|
||||
u8* decoded_buffer = njGetImage();
|
||||
user.icon = (u8*)malloc(USER_ICON_SIZE*USER_ICON_SIZE*3);
|
||||
downscaleRGBImg(decoded_buffer, user.icon, 256, 256, USER_ICON_SIZE, USER_ICON_SIZE);
|
||||
decoded_buffer = NULL;
|
||||
}
|
||||
free(buffer);
|
||||
njDone();
|
||||
}
|
||||
}
|
||||
|
||||
accountProfileClose(&profile);
|
||||
return user;
|
||||
}
|
||||
|
||||
std::string Account::username(u128 id)
|
||||
{
|
||||
std::unordered_map<u128, std::string>::const_iterator got = mUsernames.find(id);
|
||||
if (got == mUsernames.end())
|
||||
std::unordered_map<u128, User>::const_iterator got = mUsers.find(id);
|
||||
if (got == mUsers.end())
|
||||
{
|
||||
// look for a user and add it to the map
|
||||
AccountProfile profile;
|
||||
AccountProfileBase profilebase;
|
||||
char username[0x21] = {0};
|
||||
memset(&profilebase, 0, sizeof(profilebase));
|
||||
|
||||
Result res = accountGetProfile(&profile, id);
|
||||
if (R_FAILED(res))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
res = accountProfileGet(&profile, NULL, &profilebase);
|
||||
if (R_FAILED(res))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
strncpy(username, profilebase.username, sizeof(username) - 1);
|
||||
std::string user = std::string(username);
|
||||
mUsernames.insert({id, user});
|
||||
accountProfileClose(&profile);
|
||||
return user;
|
||||
User user = getUser(id);
|
||||
mUsers.insert({id, user});
|
||||
return user.name;
|
||||
}
|
||||
|
||||
return got->second;
|
||||
return got->second.name;
|
||||
}
|
||||
|
||||
u8* Account::icon(u128 id)
|
||||
{
|
||||
std::unordered_map<u128, User>::const_iterator got = mUsers.find(id);
|
||||
// the null check in the icon is to handle the bad memory issue that isn't yet fixed
|
||||
if (got == mUsers.end() || got->second.icon == NULL)
|
||||
{
|
||||
User user = getUser(id);
|
||||
mUsers.insert({id, user});
|
||||
return user.icon;
|
||||
}
|
||||
|
||||
return got->second.icon;
|
||||
}
|
|
@ -355,4 +355,68 @@ void rectangle(u32 x, u32 y, u32 w, u32 h, color_t color)
|
|||
Draw4PixelsRaw(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void downscaleRGBImg(const u8 *image, u8* out, int srcWidth, int srcHeight, int destWidth, int destHeight)
|
||||
{
|
||||
int tmpx, tmpy;
|
||||
int pos;
|
||||
float sourceX, sourceY;
|
||||
float xScale = (float)srcWidth / (float)destWidth;
|
||||
float yScale = (float)srcHeight / (float)destHeight;
|
||||
int pixelX, pixelY;
|
||||
u8 r1, r2, r3, r4;
|
||||
u8 g1, g2, g3, g4;
|
||||
u8 b1, b2, b3, b4;
|
||||
float fx, fy, fx1, fy1;
|
||||
int w1, w2, w3, w4;
|
||||
|
||||
for (tmpx=0; tmpx<destWidth; tmpx++)
|
||||
{
|
||||
for (tmpy=0; tmpy<destHeight; tmpy++)
|
||||
{
|
||||
sourceX = tmpx * xScale;
|
||||
sourceY = tmpy * yScale;
|
||||
pixelX = (int)sourceX;
|
||||
pixelY = (int)sourceY;
|
||||
|
||||
// get colours from four surrounding pixels
|
||||
pos = ((pixelY + 0) * srcWidth + pixelX + 0) * 3;
|
||||
r1 = image[pos+0];
|
||||
g1 = image[pos+1];
|
||||
b1 = image[pos+2];
|
||||
|
||||
pos = ((pixelY + 0) * srcWidth + pixelX + 1) * 3;
|
||||
r2 = image[pos+0];
|
||||
g2 = image[pos+1];
|
||||
b2 = image[pos+2];
|
||||
|
||||
pos = ((pixelY + 1) * srcWidth + pixelX + 0) * 3;
|
||||
r3 = image[pos+0];
|
||||
g3 = image[pos+1];
|
||||
b3 = image[pos+2];
|
||||
|
||||
pos = ((pixelY + 1) * srcWidth + pixelX + 1) * 3;
|
||||
r4 = image[pos+0];
|
||||
g4 = image[pos+1];
|
||||
b4 = image[pos+2];
|
||||
|
||||
// determine weights
|
||||
fx = sourceX - pixelX;
|
||||
fy = sourceY - pixelY;
|
||||
fx1 = 1.0f - fx;
|
||||
fy1 = 1.0f - fy;
|
||||
|
||||
w1 = (int)(fx1*fy1*256.0);
|
||||
w2 = (int)(fx*fy1*256.0);
|
||||
w3 = (int)(fx1*fy*256.0);
|
||||
w4 = (int)(fx*fy*256.0);
|
||||
|
||||
// set output pixels
|
||||
pos = ((tmpy*destWidth) + tmpx) * 3;
|
||||
out[pos+0] = (u8)((r1 * w1 + r2 * w2 + r3 * w3 + r4 * w4) >> 8);
|
||||
out[pos+1] = (u8)((g1 * w1 + g2 * w2 + g3 * w3 + g4 * w4) >> 8);
|
||||
out[pos+2] = (u8)((b1 * w1 + b2 * w2 + b3 * w3 + b4 * w4) >> 8);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue