Add DRC/DRH information

This commit is contained in:
GaryOderNichts 2024-04-02 16:48:37 +02:00
parent 6d5b19a8a6
commit 720ed1bb30
5 changed files with 202 additions and 0 deletions

View File

@ -32,6 +32,12 @@ WiiUIdent currently displays:
- Production Date (MLC only) - Production Date (MLC only)
- Size - Size
- CID/CSD - CID/CSD
- DRC/DRH information
- Running Version
- Active Version
- Board Version
- Region
- Ext IDs
## System Database ## System Database
WiiUIdent comes with an option to optionally upload system information to a database. This allows collecting various statistics about Wii U consoles. WiiUIdent comes with an option to optionally upload system information to a database. This allows collecting various statistics about Wii U consoles.

View File

@ -0,0 +1,170 @@
#include "DRXInfoScreen.hpp"
#include "Utils.hpp"
#include <span>
#include <nsysccr/cdc.h>
#include <nsysccr/cfg.h>
namespace {
bool GetEepromValue(uint32_t offset, std::span<uint8_t> value)
{
uint8_t data[value.size() + 2];
if (CCRCFGGetCachedEeprom(0, offset, data, value.size() + 2) != 0) {
return false;
}
uint16_t crc = (uint16_t) data[value.size() + 1] << 8 | data[value.size()];
if (CCRCDCCalcCRC16(data, value.size()) != crc) {
return false;
}
std::copy(data, data + value.size(), value.begin());
return true;
}
// from gamepad firmare @0x000b2990
const char* kBoardMainVersions[] = {
"DK1",
"DK1 / EP / DK2",
"DP1",
"DP2",
"DK3",
"DK4",
"PreDP3 / DP3",
"DK5",
"DP4",
"DKMP",
"DP5",
"MASS",
"DKMP2",
"DRC-I",
"DKTVMP",
};
// from gamepad firmare @0x000b29cc
const char* kBoardSubVersions[] = {
"DK1 / EP / DK2",
"DP1 / DK3",
"DK4",
"DP3",
"DK5",
"DP4",
"DKMP",
"DP5",
"MASS",
"DKMP2",
"DRC-I",
"DKTVMP"
};
// from gamepad firmare @0x000b29fc
const char* kRegionStrings[] = {
"JAPAN",
"AMERICA",
"EUROPE",
"CHINA",
"SOUTH KOREA",
"TAIWAN",
"AUSTRALIA",
};
}
DRXInfoScreen::DRXInfoScreen()
{
CCRCDCSoftwareVersion softwareVersion;
if (CCRCDCSoftwareGetVersion(CCR_CDC_DESTINATION_DRC0, &softwareVersion) == 0) {
uint32_t v = softwareVersion.runningVersion;
mDRCList.push_back({"Running Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRCList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
v = softwareVersion.activeVersion;
mDRCList.push_back({"Active Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRCList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
} else {
mDRCList.push_back({"CCRCDCSoftwareGetVersion failed", ""});
}
uint8_t boardInfo;
if (GetEepromValue(0x100, std::span(std::addressof(boardInfo), 1))) {
uint8_t mainVersion = boardInfo & 0xf;
uint8_t subVersion = boardInfo >> 4;
mDRCList.push_back({"Board Version:", Utils::sprintf("%d.%d (0x%02x)", mainVersion, subVersion, boardInfo)});
mDRCList.push_back({"", Utils::sprintf("(%s / %s)",
mainVersion < 0xf ? kBoardMainVersions[mainVersion] : "UNKNOWN",
subVersion < 0xc ? kBoardSubVersions[subVersion] : "UNKNOWN")});
} else {
mDRCList.push_back({"GetEepromValue failed", ""});
}
uint8_t region;
if (GetEepromValue(0x103, std::span(std::addressof(region), 1))) {
mDRCList.push_back({"Region:", Utils::sprintf("%s (0x%02x)",
region < 0x7 ? kRegionStrings[region] : "UNKNOWN", region)});
} else {
mDRCList.push_back({"GetRegion failed", ""});
}
if (CCRCDCSoftwareGetVersion(CCR_CDC_DESTINATION_DRH, &softwareVersion) == 0) {
uint32_t v = softwareVersion.runningVersion;
mDRHList.push_back({"Running Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRHList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
v = softwareVersion.activeVersion;
mDRHList.push_back({"Active Version:", Utils::sprintf("%d.%d.%d", v >> 24 & 0xff, v >> 16 & 0xff, v & 0xffff)});
mDRHList.push_back({"", {Utils::sprintf("(0x%08x)", v), true}});
} else {
mDRHList.push_back({"CCRCDCSoftwareGetVersion failed", ""});
}
uint32_t extId;
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, CCR_CDC_EXT_LANGUAGE, &extId) == 0) {
mExtIdList.push_back({"Language:", {Utils::sprintf("0x%08x", extId), true}});
mExtIdList.push_back({"", Utils::sprintf("(version: %04d bank: %02d)", extId >> 8 & 0xffff, extId >> 24)});
} else {
mExtIdList.push_back({"CCRCDCSoftwareGetExtId(CCR_CDC_EXT_LANGUAGE) failed", ""});
}
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, CCR_CDC_EXT_RC_DATABASE, &extId) == 0) {
mExtIdList.push_back({"RC Database:", {Utils::sprintf("0x%08x", extId), true}});
} else {
mExtIdList.push_back({"CCRCDCSoftwareGetExtId(CCR_CDC_EXT_RC_DATABASE) failed", ""});
}
for (int i = CCR_CDC_EXT_UNK2; i <= CCR_CDC_EXT_UNK4; i++) {
if (CCRCDCSoftwareGetExtId(CCR_CDC_DESTINATION_DRC0, (CCRCDCExt) i, &extId) == 0) {
mExtIdList.push_back({Utils::sprintf("ID %d:", i), {Utils::sprintf("0x%08x", extId), true}});
} else {
mExtIdList.push_back({Utils::sprintf("CCRCDCSoftwareGetExtId(%d) failed", i), ""});
}
}
}
DRXInfoScreen::~DRXInfoScreen()
{
}
void DRXInfoScreen::Draw()
{
DrawTopBar("DRC/DRH Information");
int yOff = 128;
yOff = DrawHeader(32, yOff, 896, 0xf11b, "DRC Info");
yOff = DrawList(32, yOff, 896, mDRCList);
yOff = DrawHeader(32, yOff, 896, 0xf0cb, "DRC Ext IDs");
yOff = DrawList(32, yOff, 896, mExtIdList);
yOff = 128;
yOff = DrawHeader(992, yOff, 896, 0xf2db, "DRH Info");
yOff = DrawList(992, yOff, 896, mDRHList);
DrawBottomBar(nullptr, "\ue044 Exit", "\ue001 Back");
}
bool DRXInfoScreen::Update(VPADStatus& input)
{
if (input.trigger & VPAD_BUTTON_B) {
return false;
}
return true;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "Screen.hpp"
class DRXInfoScreen : public Screen
{
public:
DRXInfoScreen();
virtual ~DRXInfoScreen();
void Draw();
bool Update(VPADStatus& input);
private:
ScreenList mDRCList;
ScreenList mExtIdList;
ScreenList mDRHList;
};

View File

@ -1,6 +1,7 @@
#include "MenuScreen.hpp" #include "MenuScreen.hpp"
#include "Gfx.hpp" #include "Gfx.hpp"
#include "AboutScreen.hpp" #include "AboutScreen.hpp"
#include "DRXInfoScreen.hpp"
#include "GeneralScreen.hpp" #include "GeneralScreen.hpp"
#include "StorageScreen.hpp" #include "StorageScreen.hpp"
#include "SubmitScreen.hpp" #include "SubmitScreen.hpp"
@ -11,6 +12,7 @@ MenuScreen::MenuScreen()
: entries({ : entries({
{ MENU_ID_GENERAL, { 0xf085, "General System Information" }}, { MENU_ID_GENERAL, { 0xf085, "General System Information" }},
{ MENU_ID_STORAGE, { 0xf7c2, "Storage Information" }}, { MENU_ID_STORAGE, { 0xf7c2, "Storage Information" }},
{ MENU_ID_DRX, { 0xf11b, "DRC/DRH Information" }},
{ MENU_ID_SUBMIT, { 0xf0ee, "Submit System Information" }}, { MENU_ID_SUBMIT, { 0xf0ee, "Submit System Information" }},
// { MENU_ID_TITLE, { 0xf022, "Title Information" }}, // { MENU_ID_TITLE, { 0xf022, "Title Information" }},
{ MENU_ID_ABOUT, { 0xf05a, "About WiiUIdent" }}, { MENU_ID_ABOUT, { 0xf05a, "About WiiUIdent" }},
@ -76,6 +78,9 @@ bool MenuScreen::Update(VPADStatus& input)
case MENU_ID_STORAGE: case MENU_ID_STORAGE:
subscreen = std::make_unique<StorageScreen>(); subscreen = std::make_unique<StorageScreen>();
break; break;
case MENU_ID_DRX:
subscreen = std::make_unique<DRXInfoScreen>();
break;
case MENU_ID_SUBMIT: case MENU_ID_SUBMIT:
subscreen = std::make_unique<SubmitScreen>(); subscreen = std::make_unique<SubmitScreen>();
break; break;

View File

@ -20,6 +20,7 @@ private:
enum MenuID { enum MenuID {
MENU_ID_GENERAL, MENU_ID_GENERAL,
MENU_ID_STORAGE, MENU_ID_STORAGE,
MENU_ID_DRX,
MENU_ID_SUBMIT, MENU_ID_SUBMIT,
MENU_ID_ABOUT, MENU_ID_ABOUT,