Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/rcheevos/consoleinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,17 @@ static const rc_memory_region_t _rc_memory_regions_wii[] = {
};
static const rc_memory_regions_t rc_memory_regions_wii = { _rc_memory_regions_wii, 3 };

/* ===== Wii U ===== */
/* https://wiiubrew.org/wiki/Memory_map */
static const rc_memory_region_t _rc_memory_regions_wii_u[] = {
{ 0x00000000U, 0x00FFFFFFU, 0x00000000U, RC_MEMORY_TYPE_UNUSED, "Unused" },
{ 0x01000000U, 0x0FFFFFFFU, 0x01000000U, RC_MEMORY_TYPE_READONLY, "Code / Heap" },
{ 0x10000000U, 0x8FFFFFFFU, 0x10000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "MEM2" },
{ 0x90000000U, 0xF3FFFFFFU, 0x90000000U, RC_MEMORY_TYPE_UNUSED, "Unused" },
{ 0xF4000000U, 0xF5FFFFFFU, 0xF4000000U, RC_MEMORY_TYPE_VIRTUAL_RAM, "MEM1" }
};
static const rc_memory_regions_t rc_memory_regions_wii_u = { _rc_memory_regions_wii_u, 5 };

/* ===== WonderSwan ===== */
/* http://daifukkat.su/docs/wsman/#ovr_memmap */
static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
Expand Down Expand Up @@ -1203,6 +1214,9 @@ const rc_memory_regions_t* rc_console_memory_regions(uint32_t console_id)
case RC_CONSOLE_WII:
return &rc_memory_regions_wii;

case RC_CONSOLE_WII_U:
return &rc_memory_regions_wii_u;

case RC_CONSOLE_WONDERSWAN:
return &rc_memory_regions_wonderswan;

Expand Down
4 changes: 4 additions & 0 deletions src/rhash/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,9 @@ static int rc_hash_from_file(char hash[33], uint32_t console_id, const rc_hash_i
#ifndef RC_HASH_NO_ROM
case RC_CONSOLE_NINTENDO_64:
return rc_hash_n64(hash, iterator);

case RC_CONSOLE_WII_U:
return rc_hash_wiiu_rpx(hash, iterator);
#endif

#ifndef RC_HASH_NO_ENCRYPTED
Expand Down Expand Up @@ -1239,6 +1242,7 @@ static const rc_hash_iterator_ext_handler_entry_t rc_hash_iterator_ext_handlers[
{ "pzx", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM },
{ "ri", rc_hash_initialize_iterator_single, RC_CONSOLE_MSX },
{ "rom", rc_hash_initialize_iterator_rom, 0 },
{ "rpx", rc_hash_initialize_iterator_single, RC_CONSOLE_WII_U },
{ "sap", rc_hash_initialize_iterator_single, RC_CONSOLE_THOMSONTO8 }, /* disk */
{ "scl", rc_hash_initialize_iterator_single, RC_CONSOLE_ZX_SPECTRUM },
{ "sfc", rc_hash_initialize_iterator_single, RC_CONSOLE_SUPER_NINTENDO },
Expand Down
34 changes: 34 additions & 0 deletions src/rhash/hash_rom.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,37 @@ int rc_hash_snes(char hash[33], const rc_hash_iterator_t* iterator)

return rc_hash_iterator_buffer(hash, iterator);
}

int rc_hash_wiiu_rpx(char hash[33], const rc_hash_iterator_t* iterator)
{
uint8_t buffer[52];
void* file_handle;

file_handle = rc_file_open(iterator, iterator->path);
if (!file_handle)
return rc_hash_iterator_error(iterator, "Could not open file");

if (rc_file_read(iterator, file_handle, buffer, sizeof(buffer)) != sizeof(buffer)) {
rc_file_close(iterator, file_handle);
return rc_hash_iterator_error(iterator, "Could not read header");
}

rc_file_close(iterator, file_handle);

/* Magic Number: 0x7F 'E' 'L' 'F' */
if (buffer[0] != 0x7F || buffer[1] != 'E' || buffer[2] != 'L' || buffer[3] != 'F') {
return rc_hash_iterator_error(iterator, "Not a valid Wii U RPX file");
}

/* Endianness: 0x02 = Big Endian */
if (buffer[5] != 0x02) {
return rc_hash_iterator_error(iterator, "Not a valid Wii U RPX file");
}

/* Machine Architecture: 0x14 = PowerPC */
if (buffer[18] != 0x14) {
return rc_hash_iterator_error(iterator, "Not a valid Wii U RPX file");
}

return rc_hash_whole_file(hash, iterator);
}
1 change: 1 addition & 0 deletions src/rhash/rc_hash_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ int rc_hash_buffered_file(char hash[33], uint32_t console_id, const rc_hash_iter
int rc_hash_pce(char hash[33], const rc_hash_iterator_t* iterator);
int rc_hash_scv(char hash[33], const rc_hash_iterator_t* iterator);
int rc_hash_snes(char hash[33], const rc_hash_iterator_t* iterator);
int rc_hash_wiiu_rpx(char hash[33], const rc_hash_iterator_t* iterator);
#endif

#ifndef RC_HASH_NO_DISC
Expand Down
1 change: 1 addition & 0 deletions test/rcheevos/test_consoleinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ void test_consoleinfo(void) {
TEST_PARAMS3(test_memory, RC_CONSOLE_UZEBOX, 0x001000, 0x001000);
TEST_PARAMS3(test_memory, RC_CONSOLE_WASM4, 0x010000, 0x010000);
TEST_PARAMS3(test_memory, RC_CONSOLE_WII, 0x14000000, 0x05800000);
TEST_PARAMS3(test_memory, RC_CONSOLE_WII_U, 0xF6000000, 0x91000000);
TEST_PARAMS3(test_memory, RC_CONSOLE_WONDERSWAN, 0x090000, 0x090000);
TEST_PARAMS3(test_memory, RC_CONSOLE_VECTREX, 0x000400, 0x000400);
TEST_PARAMS3(test_memory, RC_CONSOLE_VIRTUAL_BOY, 0x020000, 0x020000);
Expand Down
68 changes: 68 additions & 0 deletions test/rhash/test_hash_rom.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,70 @@ static void test_hash_scv_cart()

/* ========================================================================= */

static void test_hash_wiiu_rpx()
{
size_t image_size = 1024 * 1024;
uint8_t* image = generate_generic_file(image_size);
char hash_file[33], hash_iterator[33];

/* Found with TDD */
const char* expected_md5 = "2c0b393597ad45952138f79c7180fc88";

image[0] = 0x7F;
image[1] = 'E';
image[2] = 'L';
image[3] = 'F';
image[5] = 0x02; /* Big Endian */
image[18] = 0x14; /* PowerPC */

mock_file(0, "game.rpx", image, image_size);

/* Test file hash */
int result_file = rc_hash_generate_from_file(hash_file, RC_CONSOLE_WII_U, "game.rpx");

/* Test file identification from iterator */
int result_iterator;
struct rc_hash_iterator iterator;

rc_hash_initialize_iterator(&iterator, "game.rpx", NULL, 0);
result_iterator = rc_hash_iterate(hash_iterator, &iterator);
rc_hash_destroy_iterator(&iterator);

/* Cleanup */
free(image);

/* Validation */
ASSERT_NUM_EQUALS(result_file, 1);
ASSERT_STR_EQUALS(hash_file, expected_md5);

ASSERT_NUM_EQUALS(result_iterator, 1);
ASSERT_STR_EQUALS(hash_iterator, expected_md5);
}

static void test_hash_wiiu_rpx_invalid()
{
size_t image_size = 1024;
uint8_t* image = generate_generic_file(image_size);
char hash_file[33];

/* "Corrupted" header */
image[0] = 0x7F;
image[1] = 'E';
image[2] = 'L';
image[3] = 'X';
image[5] = 0x02;
image[18] = 0x14;

mock_file(0, "bad.rpx", image, image_size);

int result_file = rc_hash_generate_from_file(hash_file, RC_CONSOLE_WII_U, "bad.rpx");
free(image);

ASSERT_NUM_EQUALS(result_file, 0);
}

/* ========================================================================= */

void test_hash_rom(void) {
TEST_SUITE_BEGIN();

Expand Down Expand Up @@ -891,6 +955,10 @@ void test_hash_rom(void) {
/* WASM-4 */
TEST_PARAMS4(test_hash_full_file, RC_CONSOLE_WASM4, "test.wasm", 33454, "bce38bb5f05622fc7e0e56757059d180");

/* Wii U */
TEST(test_hash_wiiu_rpx);
TEST(test_hash_wiiu_rpx_invalid);

/* WonderSwan */
TEST_PARAMS4(test_hash_full_file, RC_CONSOLE_WONDERSWAN, "test.ws", 524288, "68f0f13b598e0b66461bc578375c3888");
TEST_PARAMS4(test_hash_full_file, RC_CONSOLE_WONDERSWAN, "test.wsc", 4194304, "a247ec8a8c42e18fcb80702dfadac14b");
Expand Down