mirror of
https://github.com/BernardoGiordano/Checkpoint
synced 2025-02-17 15:58:24 +00:00
Load DS icons (#251)
* Start loading DS icon * Cart is never cached * Handle positioning and fix log * Center icon on the bottom screen as well * allocate dsIcon in main thread * fix ds icons
This commit is contained in:
parent
31e9f6ba8a
commit
d5c5949f65
7 changed files with 74 additions and 21 deletions
|
@ -2,5 +2,4 @@
|
|||
checkbox.png
|
||||
checkpoint.png
|
||||
noicon.png
|
||||
twlcart.png
|
||||
star.png
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 265 B |
|
@ -47,7 +47,6 @@ namespace Gui {
|
|||
void drawPulsingOutline(u32 x, u32 y, u16 w, u16 h, u8 size, u32 color);
|
||||
void drawOutline(u32 x, u32 y, u16 w, u16 h, u8 size, u32 color);
|
||||
|
||||
C2D_Image TWLIcon(void);
|
||||
C2D_Image noIcon(void);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ extern "C" {
|
|||
|
||||
class Title {
|
||||
public:
|
||||
~Title(void);
|
||||
|
||||
bool accessibleSave(void);
|
||||
bool accessibleExtdata(void);
|
||||
FS_CardType cardType(void);
|
||||
|
|
|
@ -112,7 +112,13 @@ void MainScreen::drawTop(void) const
|
|||
C2D_DrawText(&timeText, C2D_WithColor, 4.0f, 3.0f, 0.5f, 0.45f, 0.45f, COLOR_GREY_LIGHT);
|
||||
|
||||
for (size_t k = hid.page() * entries; k < hid.page() * entries + max; k++) {
|
||||
C2D_DrawImageAt(icon(k), selectorX(k) + 1, selectorY(k) + 1, 0.5f, NULL, 1.0f, 1.0f);
|
||||
C2D_Image titleIcon = icon(k);
|
||||
if (titleIcon.subtex->width == 48) {
|
||||
C2D_DrawImageAt(titleIcon, selectorX(k) + 1, selectorY(k) + 1, 0.5f, NULL, 1.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
C2D_DrawImageAt(titleIcon, selectorX(k) + 9, selectorY(k) + 9, 0.5f, NULL, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (getTitleCount() > 0) {
|
||||
|
@ -224,7 +230,12 @@ void MainScreen::drawBottom(void) const
|
|||
C2D_DrawText(&media, C2D_WithColor, 75, 47 + longDescHeight, 0.5f, 0.5f, 0.5f, COLOR_WHITE);
|
||||
|
||||
C2D_DrawRectSolid(260, 27, 0.5f, 52, 52, COLOR_BLACK);
|
||||
C2D_DrawImageAt(title.icon(), 262, 29, 0.5f, NULL, 1.0f, 1.0f);
|
||||
if (title.icon().subtex->width == 48) {
|
||||
C2D_DrawImageAt(title.icon(), 262, 29, 0.5f, NULL, 1.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
C2D_DrawImageAt(title.icon(), 262 + 8, 29 + 8, 0.5f, NULL, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
C2D_DrawRectSolid(4, 100, 0.5f, 312, 114, COLOR_GREY_DARK);
|
||||
directoryList->draw(g_bottomScrollEnabled);
|
||||
|
|
|
@ -26,11 +26,6 @@
|
|||
|
||||
#include "gui.hpp"
|
||||
|
||||
C2D_Image Gui::TWLIcon(void)
|
||||
{
|
||||
return C2D_SpriteSheetGetImage(spritesheet, sprites_twlcart_idx);
|
||||
}
|
||||
|
||||
C2D_Image Gui::noIcon(void)
|
||||
{
|
||||
return C2D_SpriteSheetGetImage(spritesheet, sprites_noicon_idx);
|
||||
|
|
|
@ -35,6 +35,49 @@ static std::vector<Title> titleExtdatas;
|
|||
static void exportTitleListCache(std::vector<Title>& list, const std::u16string& path);
|
||||
static void importTitleListCache(void);
|
||||
|
||||
static constexpr Tex3DS_SubTexture dsIconSubt3x = {32, 32, 0.0f, 1.0f, 1.0f, 0.0f};
|
||||
static C2D_Image dsIcon = {nullptr, &dsIconSubt3x};
|
||||
|
||||
static void loadDSIcon(u8* banner)
|
||||
{
|
||||
static constexpr int WIDTH_POW2 = 32;
|
||||
static constexpr int HEIGHT_POW2 = 32;
|
||||
if (!dsIcon.tex) {
|
||||
dsIcon.tex = new C3D_Tex;
|
||||
C3D_TexInit(dsIcon.tex, WIDTH_POW2, HEIGHT_POW2, GPU_RGB565);
|
||||
}
|
||||
|
||||
struct bannerData {
|
||||
u16 version;
|
||||
u16 crc;
|
||||
u8 reserved[28];
|
||||
u8 data[512];
|
||||
u16 palette[16];
|
||||
};
|
||||
bannerData* iconData = (bannerData*)banner;
|
||||
|
||||
u16* output = (u16*)dsIcon.tex->data;
|
||||
for (size_t x = 0; x < 32; x++) {
|
||||
for (size_t y = 0; y < 32; y++) {
|
||||
u32 srcOff = (((y >> 3) * 4 + (x >> 3)) * 8 + (y & 7)) * 4 + ((x & 7) >> 1);
|
||||
u32 srcShift = (x & 1) * 4;
|
||||
|
||||
u16 pIndex = (iconData->data[srcOff] >> srcShift) & 0xF;
|
||||
u16 color = 0xFFFF;
|
||||
if (pIndex != 0) {
|
||||
u16 r = iconData->palette[pIndex] & 0x1F;
|
||||
u16 g = (iconData->palette[pIndex] >> 5) & 0x1F;
|
||||
u16 b = (iconData->palette[pIndex] >> 10) & 0x1F;
|
||||
color = (r << 11) | (g << 6) | (g >> 4) | (b);
|
||||
}
|
||||
|
||||
u32 dst = ((((y >> 3) * (32 >> 3) + (x >> 3)) << 6) +
|
||||
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3)));
|
||||
output[dst] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Title::load(void)
|
||||
{
|
||||
mId = 0xFFFFFFFFFFFFFFFF;
|
||||
|
@ -45,7 +88,6 @@ void Title::load(void)
|
|||
mLongDescription = StringUtils::UTF8toUTF16("");
|
||||
mSavePath = StringUtils::UTF8toUTF16("");
|
||||
mExtdataPath = StringUtils::UTF8toUTF16("");
|
||||
mIcon = Gui::noIcon();
|
||||
mAccessibleSave = false;
|
||||
mAccessibleExtdata = false;
|
||||
mSaves.clear();
|
||||
|
@ -65,7 +107,6 @@ void Title::load(u64 id, u8* _productCode, bool accessibleSave, bool accessibleE
|
|||
mMedia = media;
|
||||
mCard = cardType;
|
||||
mCardType = card;
|
||||
mIcon = Gui::noIcon();
|
||||
|
||||
memcpy(productCode, _productCode, 16);
|
||||
}
|
||||
|
@ -147,15 +188,19 @@ bool Title::load(u64 _id, FS_MediaType _media, FS_CardType _card)
|
|||
_cardTitle[13] = '\0';
|
||||
_gameCode[5] = '\0';
|
||||
|
||||
delete[] headerData;
|
||||
headerData = new u8[0x23C0];
|
||||
FSUSER_GetLegacyBannerData(mMedia, 0LL, headerData);
|
||||
loadDSIcon(headerData);
|
||||
mIcon = dsIcon;
|
||||
delete[] headerData;
|
||||
|
||||
res = SPIGetCardType(&mCardType, (_gameCode[0] == 'I') ? 1 : 0);
|
||||
if (R_FAILED(res)) {
|
||||
delete[] headerData;
|
||||
Logger::getInstance().log(Logger::ERROR, "Failed get SPI Card Type with result 0x%08lX.", res);
|
||||
return false;
|
||||
}
|
||||
|
||||
delete[] headerData;
|
||||
|
||||
mShortDescription = StringUtils::removeForbiddenCharacters(StringUtils::UTF8toUTF16(_cardTitle));
|
||||
mLongDescription = mShortDescription;
|
||||
mSavePath = StringUtils::UTF8toUTF16("/3ds/Checkpoint/saves/") + StringUtils::UTF8toUTF16(_gameCode) + StringUtils::UTF8toUTF16(" ") +
|
||||
|
@ -171,17 +216,17 @@ bool Title::load(u64 _id, FS_MediaType _media, FS_CardType _card)
|
|||
res = io::createDirectory(Archive::sdmc(), mSavePath);
|
||||
if (R_FAILED(res)) {
|
||||
loadTitle = false;
|
||||
Logger::getInstance().log(Logger::ERROR, "Failed to create backup with result 0x%08lX.", res);
|
||||
Logger::getInstance().log(Logger::ERROR, "Failed to create backup directory with result 0x%08lX.", res);
|
||||
}
|
||||
}
|
||||
|
||||
mIcon = Gui::TWLIcon();
|
||||
}
|
||||
|
||||
refreshDirectories();
|
||||
return loadTitle;
|
||||
}
|
||||
|
||||
Title::~Title(void) {}
|
||||
|
||||
bool Title::accessibleSave(void)
|
||||
{
|
||||
return mAccessibleSave;
|
||||
|
@ -446,8 +491,8 @@ static bool validId(u64 id)
|
|||
|
||||
void loadTitles(bool forceRefresh)
|
||||
{
|
||||
std::u16string savecachePath = StringUtils::UTF8toUTF16("/3ds/Checkpoint/fullsavecache");
|
||||
std::u16string extdatacachePath = StringUtils::UTF8toUTF16("/3ds/Checkpoint/fullextdatacache");
|
||||
static const std::u16string savecachePath = StringUtils::UTF8toUTF16("/3ds/Checkpoint/fullsavecache");
|
||||
static const std::u16string extdatacachePath = StringUtils::UTF8toUTF16("/3ds/Checkpoint/fullextdatacache");
|
||||
|
||||
// on refreshing
|
||||
titleSaves.clear();
|
||||
|
@ -814,7 +859,8 @@ static void importTitleListCache(void)
|
|||
title.setIcon(smallIcon);
|
||||
}
|
||||
else {
|
||||
title.setIcon(Gui::TWLIcon());
|
||||
// this cannot happen
|
||||
title.setIcon(Gui::noIcon());
|
||||
}
|
||||
|
||||
titleSaves.at(i) = title;
|
||||
|
@ -860,7 +906,8 @@ static void importTitleListCache(void)
|
|||
title.setIcon(smallIcon);
|
||||
}
|
||||
else {
|
||||
title.setIcon(Gui::TWLIcon());
|
||||
// this cannot happen
|
||||
title.setIcon(Gui::noIcon());
|
||||
}
|
||||
|
||||
titleExtdatas.at(i) = title;
|
||||
|
|
Loading…
Add table
Reference in a new issue