mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-04-25 10:56:36 +08:00
List DS cartridges.
This commit is contained in:
parent
78b85d0bf0
commit
56b0879f8f
@ -4,6 +4,7 @@
|
|||||||
#include "../../error.h"
|
#include "../../error.h"
|
||||||
#include "../../progressbar.h"
|
#include "../../progressbar.h"
|
||||||
#include "../../prompt.h"
|
#include "../../prompt.h"
|
||||||
|
#include "../task/task.h"
|
||||||
|
|
||||||
static void action_launch_title_update(ui_view* view, void* data, float* progress, char* progressText) {
|
static void action_launch_title_update(ui_view* view, void* data, float* progress, char* progressText) {
|
||||||
title_info* info = (title_info*) data;
|
title_info* info = (title_info*) data;
|
||||||
@ -11,10 +12,11 @@ static void action_launch_title_update(ui_view* view, void* data, float* progres
|
|||||||
u8 buf0[0x300];
|
u8 buf0[0x300];
|
||||||
u8 buf1[0x20];
|
u8 buf1[0x20];
|
||||||
|
|
||||||
|
Result res = 0;
|
||||||
|
|
||||||
aptOpenSession();
|
aptOpenSession();
|
||||||
|
|
||||||
Result res = APT_PrepareToDoAppJump(0, info->titleId, info->mediaType);
|
if(R_SUCCEEDED(res = APT_PrepareToDoAppJump(0, info->titleId, info->mediaType))) {
|
||||||
if(R_SUCCEEDED(res)) {
|
|
||||||
res = APT_DoAppJump(0x300, 0x20, buf0, buf1);
|
res = APT_DoAppJump(0x300, 0x20, buf0, buf1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,164 +23,242 @@ typedef struct {
|
|||||||
static Result task_populate_titles_from(populate_titles_data* data, FS_MediaType mediaType, bool useDSiWare) {
|
static Result task_populate_titles_from(populate_titles_data* data, FS_MediaType mediaType, bool useDSiWare) {
|
||||||
bool inserted;
|
bool inserted;
|
||||||
FS_CardType type;
|
FS_CardType type;
|
||||||
if(mediaType == MEDIATYPE_GAME_CARD && ((R_FAILED(FSUSER_CardSlotIsInserted(&inserted)) || !inserted) || (R_FAILED(FSUSER_GetCardType(&type)) || type != CARD_CTR))) {
|
if(mediaType == MEDIATYPE_GAME_CARD && (R_FAILED(FSUSER_CardSlotIsInserted(&inserted)) || !inserted || R_FAILED(FSUSER_GetCardType(&type)))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result res = 0;
|
Result res = 0;
|
||||||
|
|
||||||
u32 titleCount = 0;
|
if(mediaType != MEDIATYPE_GAME_CARD || type == CARD_CTR) {
|
||||||
if(R_SUCCEEDED(res = AM_GetTitleCount(mediaType, &titleCount))) {
|
u32 titleCount = 0;
|
||||||
u64* titleIds = (u64*) calloc(titleCount, sizeof(u64));
|
if(R_SUCCEEDED(res = AM_GetTitleCount(mediaType, &titleCount))) {
|
||||||
if(titleIds != NULL) {
|
u64* titleIds = (u64*) calloc(titleCount, sizeof(u64));
|
||||||
if(R_SUCCEEDED(res = AM_GetTitleList(&titleCount, mediaType, titleCount, titleIds))) {
|
if(titleIds != NULL) {
|
||||||
qsort(titleIds, titleCount, sizeof(u64), util_compare_u64);
|
if(R_SUCCEEDED(res = AM_GetTitleList(&titleCount, mediaType, titleCount, titleIds))) {
|
||||||
|
qsort(titleIds, titleCount, sizeof(u64), util_compare_u64);
|
||||||
|
|
||||||
AM_TitleEntry* titleInfos = (AM_TitleEntry*) calloc(titleCount, sizeof(AM_TitleEntry));
|
AM_TitleEntry* titleInfos = (AM_TitleEntry*) calloc(titleCount, sizeof(AM_TitleEntry));
|
||||||
if(titleInfos != NULL) {
|
if(titleInfos != NULL) {
|
||||||
if(R_SUCCEEDED(res = AM_GetTitleInfo(mediaType, titleCount, titleIds, titleInfos))) {
|
if(R_SUCCEEDED(res = AM_GetTitleInfo(mediaType, titleCount, titleIds, titleInfos))) {
|
||||||
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
||||||
BNR* bnr = (BNR*) calloc(1, sizeof(BNR));
|
BNR* bnr = (BNR*) calloc(1, sizeof(BNR));
|
||||||
for(u32 i = 0; i < titleCount && i < data->max; i++) {
|
for(u32 i = 0; i < titleCount && i < data->max; i++) {
|
||||||
if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) {
|
if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0;
|
|
||||||
if(dsiWare != useDSiWare) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
title_info* titleInfo = (title_info*) calloc(1, sizeof(title_info));
|
|
||||||
if(titleInfo != NULL) {
|
|
||||||
titleInfo->mediaType = mediaType;
|
|
||||||
titleInfo->titleId = titleIds[i];
|
|
||||||
AM_GetTitleProductCode(mediaType, titleIds[i], titleInfo->productCode);
|
|
||||||
titleInfo->version = titleInfos[i].version;
|
|
||||||
titleInfo->installedSize = titleInfos[i].size;
|
|
||||||
titleInfo->hasSmdh = false;
|
|
||||||
|
|
||||||
list_item* item = &data->items[*data->count];
|
|
||||||
|
|
||||||
if(dsiWare) {
|
|
||||||
if(R_SUCCEEDED(FSUSER_GetLegacyBannerData(mediaType, titleIds[i], (u8*) bnr))) {
|
|
||||||
titleInfo->hasSmdh = true;
|
|
||||||
|
|
||||||
u8 systemLanguage = CFG_LANGUAGE_EN;
|
|
||||||
CFGU_GetSystemLanguage(&systemLanguage);
|
|
||||||
|
|
||||||
char title[0x100] = {'\0'};
|
|
||||||
utf16_to_utf8((uint8_t*) title, bnr->titles[systemLanguage], 0x100);
|
|
||||||
|
|
||||||
char* nameEnd = strchr(title, '\n');
|
|
||||||
if(nameEnd == NULL) {
|
|
||||||
nameEnd = title + strlen(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(item->name, title, nameEnd - title);
|
|
||||||
|
|
||||||
strncpy(titleInfo->smdhInfo.shortDescription, title, nameEnd - title);
|
|
||||||
strncpy(titleInfo->smdhInfo.longDescription, nameEnd + 1, strlen(title) - (nameEnd - title) - 1);
|
|
||||||
|
|
||||||
u8 icon[32 * 32 * 2];
|
|
||||||
for(u32 x = 0; x < 32; x++) {
|
|
||||||
for(u32 y = 0; y < 32; y++) {
|
|
||||||
u32 srcPos = (((y >> 3) * 4 + (x >> 3)) * 8 + (y & 7)) * 4 + ((x & 7) >> 1);
|
|
||||||
u32 srcShift = (x & 1) * 4;
|
|
||||||
u16 srcPx = bnr->mainIconPalette[(bnr->mainIconBitmap[srcPos] >> srcShift) & 0xF];
|
|
||||||
|
|
||||||
u8 r = (u8) (srcPx & 0x1F);
|
|
||||||
u8 g = (u8) ((srcPx >> 5) & 0x1F);
|
|
||||||
u8 b = (u8) ((srcPx >> 10) & 0x1F);
|
|
||||||
|
|
||||||
u16 reversedPx = (u16) ((r << 11) | (g << 6) | (b << 1) | 1);
|
|
||||||
|
|
||||||
u32 dstPos = (y * 32 + x) * 2;
|
|
||||||
icon[dstPos + 0] = (u8) (reversedPx & 0xFF);
|
|
||||||
icon[dstPos + 1] = (u8) ((reversedPx >> 8) & 0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
titleInfo->smdhInfo.texture = screen_load_texture_auto(icon, sizeof(icon), 32, 32, GPU_RGBA5551, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
static const u32 filePathData[] = {0x00000000, 0x00000000, 0x00000002, 0x6E6F6369, 0x00000000};
|
|
||||||
static const FS_Path filePath = (FS_Path) {PATH_BINARY, 0x14, (u8*) filePathData};
|
|
||||||
u32 archivePath[] = {(u32) (titleIds[i] & 0xFFFFFFFF), (u32) ((titleIds[i] >> 32) & 0xFFFFFFFF), mediaType, 0x00000000};
|
|
||||||
FS_Archive archive = {ARCHIVE_SAVEDATA_AND_CONTENT, (FS_Path) {PATH_BINARY, 0x10, (u8*) archivePath}};
|
|
||||||
Handle fileHandle;
|
|
||||||
if(R_SUCCEEDED(FSUSER_OpenFileDirectly(&fileHandle, archive, filePath, FS_OPEN_READ, 0))) {
|
|
||||||
u32 bytesRead;
|
|
||||||
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 0, smdh, sizeof(SMDH))) && bytesRead == sizeof(SMDH)) {
|
|
||||||
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
|
||||||
u8 systemLanguage = CFG_LANGUAGE_EN;
|
|
||||||
CFGU_GetSystemLanguage(&systemLanguage);
|
|
||||||
|
|
||||||
utf16_to_utf8((uint8_t*) item->name, smdh->titles[systemLanguage].shortDescription, NAME_MAX);
|
|
||||||
|
|
||||||
titleInfo->hasSmdh = true;
|
|
||||||
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(titleInfo->smdhInfo.shortDescription));
|
|
||||||
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(titleInfo->smdhInfo.longDescription));
|
|
||||||
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.publisher, smdh->titles[systemLanguage].publisher, sizeof(titleInfo->smdhInfo.publisher));
|
|
||||||
titleInfo->smdhInfo.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FSFILE_Close(fileHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty = strlen(item->name) == 0;
|
bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0;
|
||||||
if(!empty) {
|
if(dsiWare != useDSiWare) {
|
||||||
empty = true;
|
continue;
|
||||||
|
|
||||||
char* curr = item->name;
|
|
||||||
while(*curr) {
|
|
||||||
if(*curr != ' ') {
|
|
||||||
empty = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
curr++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(empty) {
|
title_info* titleInfo = (title_info*) calloc(1, sizeof(title_info));
|
||||||
snprintf(item->name, NAME_MAX, "%016llX", titleIds[i]);
|
if(titleInfo != NULL) {
|
||||||
}
|
titleInfo->mediaType = mediaType;
|
||||||
|
titleInfo->titleId = titleIds[i];
|
||||||
|
AM_GetTitleProductCode(mediaType, titleIds[i], titleInfo->productCode);
|
||||||
|
titleInfo->version = titleInfos[i].version;
|
||||||
|
titleInfo->installedSize = titleInfos[i].size;
|
||||||
|
titleInfo->twl = dsiWare;
|
||||||
|
titleInfo->hasSmdh = false;
|
||||||
|
|
||||||
|
list_item* item = &data->items[*data->count];
|
||||||
|
|
||||||
if(mediaType == MEDIATYPE_NAND) {
|
|
||||||
if(dsiWare) {
|
if(dsiWare) {
|
||||||
item->rgba = 0xFF82004B;
|
if(R_SUCCEEDED(FSUSER_GetLegacyBannerData(mediaType, titleIds[i], (u8*) bnr))) {
|
||||||
|
titleInfo->hasSmdh = true;
|
||||||
|
|
||||||
|
u8 systemLanguage = CFG_LANGUAGE_EN;
|
||||||
|
CFGU_GetSystemLanguage(&systemLanguage);
|
||||||
|
|
||||||
|
char title[0x100] = {'\0'};
|
||||||
|
utf16_to_utf8((uint8_t*) title, bnr->titles[systemLanguage], 0x100);
|
||||||
|
|
||||||
|
char* nameEnd = strchr(title, '\n');
|
||||||
|
if(nameEnd != NULL) {
|
||||||
|
char* curr = NULL;
|
||||||
|
while((curr = strchr(nameEnd + 1, '\n')) != NULL) {
|
||||||
|
*nameEnd = ' ';
|
||||||
|
nameEnd = curr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nameEnd = title + strlen(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(item->name, title, nameEnd - title);
|
||||||
|
|
||||||
|
strncpy(titleInfo->smdhInfo.shortDescription, title, nameEnd - title);
|
||||||
|
strncpy(titleInfo->smdhInfo.longDescription, nameEnd + 1, strlen(title) - (nameEnd - title) - 1);
|
||||||
|
|
||||||
|
u8 icon[32 * 32 * 2];
|
||||||
|
for(u32 x = 0; x < 32; x++) {
|
||||||
|
for(u32 y = 0; y < 32; y++) {
|
||||||
|
u32 srcPos = (((y >> 3) * 4 + (x >> 3)) * 8 + (y & 7)) * 4 + ((x & 7) >> 1);
|
||||||
|
u32 srcShift = (x & 1) * 4;
|
||||||
|
u16 srcPx = bnr->mainIconPalette[(bnr->mainIconBitmap[srcPos] >> srcShift) & 0xF];
|
||||||
|
|
||||||
|
u8 r = (u8) (srcPx & 0x1F);
|
||||||
|
u8 g = (u8) ((srcPx >> 5) & 0x1F);
|
||||||
|
u8 b = (u8) ((srcPx >> 10) & 0x1F);
|
||||||
|
|
||||||
|
u16 reversedPx = (u16) ((r << 11) | (g << 6) | (b << 1) | 1);
|
||||||
|
|
||||||
|
u32 dstPos = (y * 32 + x) * 2;
|
||||||
|
icon[dstPos + 0] = (u8) (reversedPx & 0xFF);
|
||||||
|
icon[dstPos + 1] = (u8) ((reversedPx >> 8) & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
titleInfo->smdhInfo.texture = screen_load_texture_auto(icon, sizeof(icon), 32, 32, GPU_RGBA5551, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
item->rgba = 0xFF0000FF;
|
static const u32 filePathData[] = {0x00000000, 0x00000000, 0x00000002, 0x6E6F6369, 0x00000000};
|
||||||
|
static const FS_Path filePath = (FS_Path) {PATH_BINARY, 0x14, (u8*) filePathData};
|
||||||
|
u32 archivePath[] = {(u32) (titleIds[i] & 0xFFFFFFFF), (u32) ((titleIds[i] >> 32) & 0xFFFFFFFF), mediaType, 0x00000000};
|
||||||
|
FS_Archive archive = {ARCHIVE_SAVEDATA_AND_CONTENT, (FS_Path) {PATH_BINARY, 0x10, (u8*) archivePath}};
|
||||||
|
Handle fileHandle;
|
||||||
|
if(R_SUCCEEDED(FSUSER_OpenFileDirectly(&fileHandle, archive, filePath, FS_OPEN_READ, 0))) {
|
||||||
|
u32 bytesRead;
|
||||||
|
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 0, smdh, sizeof(SMDH))) && bytesRead == sizeof(SMDH)) {
|
||||||
|
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
||||||
|
u8 systemLanguage = CFG_LANGUAGE_EN;
|
||||||
|
CFGU_GetSystemLanguage(&systemLanguage);
|
||||||
|
|
||||||
|
utf16_to_utf8((uint8_t*) item->name, smdh->titles[systemLanguage].shortDescription, NAME_MAX);
|
||||||
|
|
||||||
|
titleInfo->hasSmdh = true;
|
||||||
|
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(titleInfo->smdhInfo.shortDescription));
|
||||||
|
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(titleInfo->smdhInfo.longDescription));
|
||||||
|
utf16_to_utf8((uint8_t*) titleInfo->smdhInfo.publisher, smdh->titles[systemLanguage].publisher, sizeof(titleInfo->smdhInfo.publisher));
|
||||||
|
titleInfo->smdhInfo.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FSFILE_Close(fileHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(mediaType == MEDIATYPE_SD) {
|
|
||||||
item->rgba = 0xFF00FF00;
|
bool empty = strlen(item->name) == 0;
|
||||||
} else if(mediaType == MEDIATYPE_GAME_CARD) {
|
if(!empty) {
|
||||||
item->rgba = 0xFFFF0000;
|
empty = true;
|
||||||
|
|
||||||
|
char* curr = item->name;
|
||||||
|
while(*curr) {
|
||||||
|
if(*curr != ' ') {
|
||||||
|
empty = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
curr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty) {
|
||||||
|
snprintf(item->name, NAME_MAX, "%016llX", titleIds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mediaType == MEDIATYPE_NAND) {
|
||||||
|
if(dsiWare) {
|
||||||
|
item->rgba = 0xFF82004B;
|
||||||
|
} else {
|
||||||
|
item->rgba = 0xFF0000FF;
|
||||||
|
}
|
||||||
|
} else if(mediaType == MEDIATYPE_SD) {
|
||||||
|
item->rgba = 0xFF00FF00;
|
||||||
|
} else if(mediaType == MEDIATYPE_GAME_CARD) {
|
||||||
|
item->rgba = 0xFFFF0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
item->data = titleInfo;
|
||||||
|
|
||||||
|
(*data->count)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
item->data = titleInfo;
|
|
||||||
|
|
||||||
(*data->count)++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(smdh);
|
||||||
|
free(bnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(smdh);
|
free(titleInfos);
|
||||||
free(bnr);
|
} else {
|
||||||
|
res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(titleInfos);
|
|
||||||
} else {
|
|
||||||
res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(titleIds);
|
free(titleIds);
|
||||||
} else {
|
} else {
|
||||||
res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY);
|
res = MAKERESULT(RL_PERMANENT, RS_INVALIDSTATE, 254, RD_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
u8* header = (u8*) calloc(1, 0x3B4);
|
||||||
|
BNR* bnr = (BNR*) calloc(1, sizeof(BNR));
|
||||||
|
|
||||||
|
if(R_SUCCEEDED(res = FSUSER_GetLegacyRomHeader(MEDIATYPE_GAME_CARD, 0, header)) && R_SUCCEEDED(res = FSUSER_GetLegacyBannerData(MEDIATYPE_GAME_CARD, 0, (u8*) bnr))) {
|
||||||
|
title_info* titleInfo = (title_info*) calloc(1, sizeof(title_info));
|
||||||
|
if(titleInfo != NULL) {
|
||||||
|
titleInfo->mediaType = MEDIATYPE_GAME_CARD;
|
||||||
|
titleInfo->titleId = *(u64*) &header[0x230];
|
||||||
|
memcpy(titleInfo->productCode, header, 0x00C);
|
||||||
|
titleInfo->version = header[0x01E];
|
||||||
|
titleInfo->installedSize = *(u32*) &header[0x080];
|
||||||
|
titleInfo->twl = true;
|
||||||
|
titleInfo->hasSmdh = true;
|
||||||
|
|
||||||
|
list_item* item = &data->items[*data->count];
|
||||||
|
|
||||||
|
u8 systemLanguage = CFG_LANGUAGE_EN;
|
||||||
|
CFGU_GetSystemLanguage(&systemLanguage);
|
||||||
|
|
||||||
|
char title[0x100] = {'\0'};
|
||||||
|
utf16_to_utf8((uint8_t*) title, bnr->titles[systemLanguage], 0x100);
|
||||||
|
|
||||||
|
char* nameEnd = strchr(title, '\n');
|
||||||
|
if(nameEnd != NULL) {
|
||||||
|
char* curr = NULL;
|
||||||
|
while((curr = strchr(nameEnd + 1, '\n')) != NULL) {
|
||||||
|
*nameEnd = ' ';
|
||||||
|
nameEnd = curr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nameEnd = title + strlen(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(item->name, title, nameEnd - title);
|
||||||
|
|
||||||
|
strncpy(titleInfo->smdhInfo.shortDescription, title, nameEnd - title);
|
||||||
|
strncpy(titleInfo->smdhInfo.longDescription, nameEnd + 1, strlen(title) - (nameEnd - title) - 1);
|
||||||
|
|
||||||
|
u8 icon[32 * 32 * 2];
|
||||||
|
for(u32 x = 0; x < 32; x++) {
|
||||||
|
for(u32 y = 0; y < 32; y++) {
|
||||||
|
u32 srcPos = (((y >> 3) * 4 + (x >> 3)) * 8 + (y & 7)) * 4 + ((x & 7) >> 1);
|
||||||
|
u32 srcShift = (x & 1) * 4;
|
||||||
|
u16 srcPx = bnr->mainIconPalette[(bnr->mainIconBitmap[srcPos] >> srcShift) & 0xF];
|
||||||
|
|
||||||
|
u8 r = (u8) (srcPx & 0x1F);
|
||||||
|
u8 g = (u8) ((srcPx >> 5) & 0x1F);
|
||||||
|
u8 b = (u8) ((srcPx >> 10) & 0x1F);
|
||||||
|
|
||||||
|
u16 reversedPx = (u16) ((r << 11) | (g << 6) | (b << 1) | 1);
|
||||||
|
|
||||||
|
u32 dstPos = (y * 32 + x) * 2;
|
||||||
|
icon[dstPos + 0] = (u8) (reversedPx & 0xFF);
|
||||||
|
icon[dstPos + 1] = (u8) ((reversedPx >> 8) & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
titleInfo->smdhInfo.texture = screen_load_texture_auto(icon, sizeof(icon), 32, 32, GPU_RGBA5551, false);
|
||||||
|
|
||||||
|
item->rgba = 0xFFFF0000;
|
||||||
|
item->data = titleInfo;
|
||||||
|
|
||||||
|
(*data->count)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(header);
|
||||||
|
free(bnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -37,6 +37,7 @@ typedef struct {
|
|||||||
char productCode[0x10];
|
char productCode[0x10];
|
||||||
u16 version;
|
u16 version;
|
||||||
u64 installedSize;
|
u64 installedSize;
|
||||||
|
bool twl;
|
||||||
bool hasSmdh;
|
bool hasSmdh;
|
||||||
smdh_info smdhInfo;
|
smdh_info smdhInfo;
|
||||||
} title_info;
|
} title_info;
|
||||||
|
@ -43,6 +43,13 @@ static list_item dsiware_titles_action_items[DSIWARE_TITLES_ACTION_COUNT] = {
|
|||||||
{"Delete Title", 0xFF000000, action_delete_title},
|
{"Delete Title", 0xFF000000, action_delete_title},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DSIWARE_CARD_TITLES_ACTION_COUNT 1
|
||||||
|
|
||||||
|
static u32 dsiware_card_titles_action_count = DSIWARE_CARD_TITLES_ACTION_COUNT;
|
||||||
|
static list_item dsiware_card_titles_action_items[DSIWARE_CARD_TITLES_ACTION_COUNT] = {
|
||||||
|
{"Launch Title", 0xFF000000, action_launch_title},
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
title_info* info;
|
title_info* info;
|
||||||
bool* populated;
|
bool* populated;
|
||||||
@ -77,12 +84,17 @@ static void titles_action_update(ui_view* view, void* data, list_item** items, u
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(actionData->info->mediaType == MEDIATYPE_GAME_CARD) {
|
if(actionData->info->mediaType == MEDIATYPE_GAME_CARD && actionData->info->twl) {
|
||||||
|
if(*itemCount != &dsiware_card_titles_action_count || *items != dsiware_card_titles_action_items) {
|
||||||
|
*itemCount = &dsiware_card_titles_action_count;
|
||||||
|
*items = dsiware_card_titles_action_items;
|
||||||
|
}
|
||||||
|
} else if(actionData->info->mediaType == MEDIATYPE_GAME_CARD) {
|
||||||
if(*itemCount != &card_titles_action_count || *items != card_titles_action_items) {
|
if(*itemCount != &card_titles_action_count || *items != card_titles_action_items) {
|
||||||
*itemCount = &card_titles_action_count;
|
*itemCount = &card_titles_action_count;
|
||||||
*items = card_titles_action_items;
|
*items = card_titles_action_items;
|
||||||
}
|
}
|
||||||
} else if(((actionData->info->titleId >> 32) & 0x8000) != 0) {
|
} else if(actionData->info->twl) {
|
||||||
if(*itemCount != &dsiware_titles_action_count || *items != dsiware_titles_action_items) {
|
if(*itemCount != &dsiware_titles_action_count || *items != dsiware_titles_action_items) {
|
||||||
*itemCount = &dsiware_titles_action_count;
|
*itemCount = &dsiware_titles_action_count;
|
||||||
*items = dsiware_titles_action_items;
|
*items = dsiware_titles_action_items;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user