2016-07-20 19:42:47 +00:00
|
|
|
#include <3ds.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
|
2016-07-28 19:32:39 +00:00
|
|
|
#include "actu.h"
|
2016-07-27 08:28:48 +00:00
|
|
|
#include "screenshot.h"
|
|
|
|
|
2016-08-24 14:44:20 +00:00
|
|
|
int vaPrint(char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
|
|
int ret = vprintf(format, args);
|
|
|
|
va_end(args);
|
|
|
|
gfxFlushBuffers();
|
|
|
|
gfxSwapBuffers();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
const char * getModel()
|
2016-07-26 01:59:07 +00:00
|
|
|
{
|
2016-07-27 08:28:48 +00:00
|
|
|
const char *models[] =
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
"O3DS",
|
|
|
|
"O3DS XL",
|
|
|
|
"N3DS",
|
|
|
|
"2DS",
|
|
|
|
"N3DS XL",
|
|
|
|
"Unknown"
|
|
|
|
};
|
|
|
|
|
|
|
|
u8 model = 0;
|
|
|
|
CFGU_GetSystemModel(&model);
|
|
|
|
|
|
|
|
if (model < 5)
|
|
|
|
return models[model];
|
|
|
|
else
|
|
|
|
return models[5];
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
const char * getRegion()
|
2016-07-26 01:59:07 +00:00
|
|
|
{
|
2016-07-27 08:28:48 +00:00
|
|
|
const char *regions[] =
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
"JPN",
|
|
|
|
"USA",
|
|
|
|
"EUR",
|
|
|
|
"AUS",
|
|
|
|
"CHN",
|
|
|
|
"KOR",
|
|
|
|
"TWN",
|
|
|
|
"Unknown"
|
|
|
|
};
|
|
|
|
|
|
|
|
u8 region = 0;
|
|
|
|
CFGU_SecureInfoGetRegion(®ion);
|
|
|
|
|
|
|
|
if (region < 7)
|
|
|
|
return regions[region];
|
|
|
|
else
|
|
|
|
return regions[7];
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
const char * getLang()
|
2016-07-26 01:59:07 +00:00
|
|
|
{
|
2016-07-27 08:28:48 +00:00
|
|
|
const char *languages[] =
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
"Japanese",
|
|
|
|
"English",
|
|
|
|
"French",
|
|
|
|
"German",
|
|
|
|
"Italian",
|
|
|
|
"Spanish",
|
|
|
|
"Simplified Chinese",
|
|
|
|
"Korean",
|
|
|
|
"Dutch",
|
|
|
|
"Portugese",
|
|
|
|
"Russian",
|
|
|
|
"Traditional Chinese"
|
|
|
|
};
|
|
|
|
|
|
|
|
u8 language;
|
|
|
|
CFGU_GetSystemLanguage(&language);
|
|
|
|
|
|
|
|
if (language < 11)
|
|
|
|
return languages[language];
|
|
|
|
else
|
|
|
|
return languages[11];
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool detectSD()
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
bool isSD;
|
|
|
|
FSUSER_IsSdmcDetected(&isSD);
|
|
|
|
return isSD;
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
const char * batteryStatus()
|
2016-07-26 01:59:07 +00:00
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
u8 batteryStateBool;
|
|
|
|
PTMU_GetBatteryChargeState(&batteryStateBool);
|
|
|
|
|
|
|
|
if (!batteryStateBool)
|
|
|
|
return "Not charging";
|
|
|
|
else
|
|
|
|
return "Charging";
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char * getMacAddress()
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
u8* macByte = (u8*)0x1FF81060;
|
|
|
|
static char macAddress[18];
|
|
|
|
|
|
|
|
// sprintf automatically zero-terminates the string
|
2016-08-17 15:57:12 +00:00
|
|
|
sprintf(macAddress, "%02X:%02X:%02X:%02X:%02X:%02X", *macByte, *(macByte + 1), *(macByte + 2), *(macByte + 3), *(macByte + 4), *(macByte + 5));
|
2016-07-26 03:20:13 +00:00
|
|
|
|
|
|
|
return macAddress;
|
2016-07-26 01:59:07 +00:00
|
|
|
}
|
|
|
|
|
2016-08-24 14:44:20 +00:00
|
|
|
u32 titleCount(FS_MediaType mediaType)
|
2016-07-20 19:42:47 +00:00
|
|
|
{
|
2016-08-24 14:44:20 +00:00
|
|
|
u32 count = 0;
|
|
|
|
|
|
|
|
AM_GetTitleCount(mediaType, &count);
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2016-07-26 03:20:13 +00:00
|
|
|
gfxInitDefault();
|
|
|
|
cfguInit();
|
|
|
|
fsInit();
|
|
|
|
sdmcInit();
|
|
|
|
ptmuInit();
|
2016-08-24 14:44:20 +00:00
|
|
|
amInit();
|
2016-07-20 19:42:47 +00:00
|
|
|
|
|
|
|
consoleInit(GFX_TOP, NULL);
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
char *str_ver = malloc(255), *str_sysver = malloc(255);
|
|
|
|
u32 os_ver = osGetKernelVersion(), firm_ver = osGetKernelVersion();
|
|
|
|
|
2016-08-24 14:44:20 +00:00
|
|
|
printf("\x1b[32m3DSident 0.4\x1b[0m\n\n");
|
2016-07-26 03:20:13 +00:00
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
snprintf(str_ver, 255, "\x1b[33m*\x1b[0m Kernel version: %lu.%lu-%lu\n\x1b[33m*\x1b[0m FIRM version is %lu.%lu-%lu\n",
|
2016-07-20 19:42:47 +00:00
|
|
|
GET_VERSION_MAJOR(os_ver), GET_VERSION_MINOR(os_ver), GET_VERSION_REVISION(os_ver),
|
|
|
|
GET_VERSION_MAJOR(firm_ver), GET_VERSION_MINOR(firm_ver), GET_VERSION_REVISION(firm_ver));
|
|
|
|
|
|
|
|
printf(str_ver);
|
|
|
|
|
|
|
|
OS_VersionBin *nver = (OS_VersionBin*)malloc(sizeof(OS_VersionBin));
|
|
|
|
OS_VersionBin *cver = (OS_VersionBin*)malloc(sizeof(OS_VersionBin));
|
|
|
|
|
|
|
|
memset(nver, 0, sizeof(OS_VersionBin));
|
|
|
|
memset(cver, 0, sizeof(OS_VersionBin));
|
|
|
|
|
|
|
|
s32 ret = osGetSystemVersionData(nver, cver);
|
|
|
|
if (ret)
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[33m*\x1b[0m osGetSystemVersionData returned 0x%08liX\n\n", ret);
|
2016-07-26 03:20:13 +00:00
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
snprintf(str_sysver, 100, "\x1b[33m*\x1b[0m Current system version: %d.%d.%d-%d\n\n",
|
2016-07-26 03:20:13 +00:00
|
|
|
cver->mainver, cver->minor, cver->build, nver->mainver);
|
2016-07-29 03:25:32 +00:00
|
|
|
if (!ret)
|
|
|
|
printf(str_sysver);
|
2016-07-26 03:20:13 +00:00
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[31m*\x1b[0m Model: %s\n", getModel());
|
|
|
|
printf("\x1b[31m*\x1b[0m Region: %s\n", getRegion());
|
|
|
|
printf("\x1b[31m*\x1b[0m Language: %s\n", getLang());
|
2016-08-17 15:57:12 +00:00
|
|
|
printf("\x1b[31m*\x1b[0m MAC Address: %s\n", getMacAddress());
|
|
|
|
|
2016-08-17 16:14:46 +00:00
|
|
|
u8 buf[16];
|
2016-08-17 15:57:12 +00:00
|
|
|
|
|
|
|
FSUSER_GetSdmcCid(buf, 0x10);
|
|
|
|
printf("\x1b[31m*\x1b[0m SDMC CID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
|
|
|
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
|
|
|
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
|
|
|
buf[12], buf[13], buf[14], buf[15]);
|
|
|
|
|
|
|
|
FSUSER_GetNandCid(buf, 0x10);
|
|
|
|
printf("\x1b[31m*\x1b[0m NAND CID: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n\n",
|
|
|
|
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
|
|
|
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
2016-08-17 16:14:46 +00:00
|
|
|
buf[12], buf[13], buf[14], buf[15]);
|
2016-07-26 03:20:13 +00:00
|
|
|
|
2016-07-28 19:32:39 +00:00
|
|
|
u8 batteryPercent;
|
|
|
|
PTMU_GetBatteryLevel(&batteryPercent);
|
|
|
|
int batt = (u32)batteryPercent * 20;
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[34m*\x1b[0m Battery Status: %s\n", batteryStatus());
|
|
|
|
printf("\x1b[34m*\x1b[0m Battery Percentage: %d%%\n\n", batt);
|
2016-07-28 19:32:39 +00:00
|
|
|
|
|
|
|
u32 nnidNum = 0xFFFFFFFF;
|
|
|
|
|
2016-08-24 14:44:20 +00:00
|
|
|
ret = actInit();
|
|
|
|
/*if (ret)
|
|
|
|
vaPrint("actInit failed! %08x\n", ret);*/
|
|
|
|
ret = ACTU_Initialize(0xB0002C8, 0, 0);
|
|
|
|
/*if (ret)
|
|
|
|
vaPrint("ACTU_Initialize failed! %08x\n", ret);*/
|
|
|
|
ret = ACTU_GetAccountDataBlock(0xFE, 4, 12, &nnidNum);
|
|
|
|
/*if (ret)
|
|
|
|
vaPrint("ACTU_GetAccountDataBlock failed! %08x\n", ret);*/
|
|
|
|
ret = actExit();
|
|
|
|
if (ret)
|
|
|
|
vaPrint("actExit failed! %08x\n", ret);
|
|
|
|
|
|
|
|
if (nnidNum != 0xFFFFFFFF)
|
|
|
|
{
|
|
|
|
vaPrint("\x1b[34m*\x1b[0m NNID Number: %08X\n\n", (int) nnidNum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vaPrint("\x1b[34m*\x1b[0m NNID Number: Error could not retrieve NNID\n\n");
|
|
|
|
}
|
2016-07-28 19:32:39 +00:00
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[32m*\x1b[0m SD Detected: %s\n", detectSD() ? "Yes" : "No");
|
2016-07-28 19:32:39 +00:00
|
|
|
|
|
|
|
FS_ArchiveResource resource = {0};
|
|
|
|
FSUSER_GetArchiveResource(&resource, SYSTEM_MEDIATYPE_SD);
|
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[32m*\x1b[0m SD Size: %.1f MB\n", (((u64) resource.totalClusters * (u64) resource.clusterSize) / 1024.0 / 1024.0));
|
|
|
|
printf("\x1b[32m*\x1b[0m SD Free: %.1f MB\n", ((u64) resource.freeClusters * (u64) resource.clusterSize) / 1024.0 / 1024.0);
|
2016-07-28 19:32:39 +00:00
|
|
|
|
|
|
|
FSUSER_GetArchiveResource(&resource, SYSTEM_MEDIATYPE_CTR_NAND);
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\x1b[32m*\x1b[0m CTR Size: %.1f MB\n", (((u64) resource.totalClusters * (u64) resource.clusterSize) / 1024.0 / 1024.0));
|
|
|
|
printf("\x1b[32m*\x1b[0m CTR Free: %.1f MB\n", ((u64) resource.freeClusters * (u64) resource.clusterSize) / 1024.0 / 1024.0);
|
2016-08-24 14:44:20 +00:00
|
|
|
u32 installedTitles = titleCount(MEDIATYPE_SD);
|
|
|
|
printf("\x1b[32m*\x1b[0m Installed titles: %i\n", (int)installedTitles);
|
2016-07-29 03:25:32 +00:00
|
|
|
|
2016-08-03 08:47:38 +00:00
|
|
|
printf("\n\n\x1b[32m> Press any key to exit =)\x1b[0m\n");
|
2016-08-17 15:57:12 +00:00
|
|
|
|
2016-07-20 19:42:47 +00:00
|
|
|
free(nver);
|
|
|
|
free(cver);
|
|
|
|
free(str_ver);
|
|
|
|
free(str_sysver);
|
|
|
|
|
2016-07-26 03:20:13 +00:00
|
|
|
while (aptMainLoop())
|
|
|
|
{
|
|
|
|
gspWaitForVBlank();
|
|
|
|
hidScanInput();
|
2016-07-27 08:28:48 +00:00
|
|
|
if (hidKeysDown())
|
|
|
|
{
|
|
|
|
captureScreenshot();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
gfxFlushBuffers();
|
2016-07-26 03:20:13 +00:00
|
|
|
gfxSwapBuffers();
|
|
|
|
}
|
|
|
|
|
2016-08-24 14:44:20 +00:00
|
|
|
amExit();
|
2016-07-26 03:20:13 +00:00
|
|
|
ptmuExit();
|
|
|
|
sdmcInit();
|
|
|
|
fsExit();
|
|
|
|
cfguExit();
|
|
|
|
gfxExit();
|
|
|
|
return 0;
|
2016-07-20 19:42:47 +00:00
|
|
|
}
|