mirror of
https://github.com/libretro/RetroArch
synced 2025-02-13 21:40:27 +00:00
support for hashing buffered NDS ROMs (#13365)
This commit is contained in:
parent
45f2f74d45
commit
cd50a51f3e
167
deps/rcheevos/src/rhash/hash.c
vendored
167
deps/rcheevos/src/rhash/hash.c
vendored
@ -711,86 +711,7 @@ static void rc_hash_n64_to_z64(uint8_t* buffer, const uint8_t* stop)
|
||||
}
|
||||
}
|
||||
|
||||
static int rc_hash_n64(char hash[33], const uint8_t* buffer, size_t buffer_size)
|
||||
{
|
||||
uint8_t* swapbuffer;
|
||||
uint8_t* stop;
|
||||
const size_t swapbuffer_size = 65536;
|
||||
md5_state_t md5;
|
||||
size_t remaining;
|
||||
int is_v64;
|
||||
|
||||
if (buffer[0] == 0x80) /* z64 format (big endian [native]) */
|
||||
{
|
||||
return rc_hash_buffer(hash, buffer, buffer_size);
|
||||
}
|
||||
else if (buffer[0] == 0x37) /* v64 format (byteswapped) */
|
||||
{
|
||||
rc_hash_verbose("converting v64 to z64");
|
||||
is_v64 = 1;
|
||||
}
|
||||
else if (buffer[0] == 0x40) /* n64 format (little endian) */
|
||||
{
|
||||
rc_hash_verbose("converting n64 to z64");
|
||||
is_v64 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc_hash_verbose("Not a Nintendo 64 ROM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
swapbuffer = (uint8_t*)malloc(swapbuffer_size);
|
||||
if (!swapbuffer)
|
||||
return rc_hash_error("Could not allocate temporary buffer");
|
||||
stop = swapbuffer + swapbuffer_size;
|
||||
|
||||
md5_init(&md5);
|
||||
|
||||
if (buffer_size > MAX_BUFFER_SIZE)
|
||||
remaining = MAX_BUFFER_SIZE;
|
||||
else
|
||||
remaining = (size_t)buffer_size;
|
||||
|
||||
if (verbose_message_callback)
|
||||
{
|
||||
char message[64];
|
||||
snprintf(message, sizeof(message), "Hashing %u bytes", (unsigned)remaining);
|
||||
verbose_message_callback(message);
|
||||
}
|
||||
|
||||
while (remaining >= swapbuffer_size)
|
||||
{
|
||||
memcpy(swapbuffer, buffer, swapbuffer_size);
|
||||
|
||||
if (is_v64)
|
||||
rc_hash_v64_to_z64(swapbuffer, stop);
|
||||
else
|
||||
rc_hash_n64_to_z64(swapbuffer, stop);
|
||||
|
||||
md5_append(&md5, swapbuffer, (int)swapbuffer_size);
|
||||
buffer += swapbuffer_size;
|
||||
remaining -= swapbuffer_size;
|
||||
}
|
||||
|
||||
if (remaining > 0)
|
||||
{
|
||||
memcpy(swapbuffer, buffer, remaining);
|
||||
|
||||
stop = swapbuffer + remaining;
|
||||
if (is_v64)
|
||||
rc_hash_v64_to_z64(swapbuffer, stop);
|
||||
else
|
||||
rc_hash_n64_to_z64(swapbuffer, stop);
|
||||
|
||||
md5_append(&md5, swapbuffer, (int)remaining);
|
||||
}
|
||||
|
||||
free(swapbuffer);
|
||||
return rc_hash_finalize(&md5, hash);
|
||||
}
|
||||
|
||||
static int rc_hash_n64_file(char hash[33], const char* path)
|
||||
static int rc_hash_n64(char hash[33], const char* path)
|
||||
{
|
||||
uint8_t* buffer;
|
||||
uint8_t* stop;
|
||||
@ -1547,6 +1468,83 @@ static int rc_hash_snes(char hash[33], const uint8_t* buffer, size_t buffer_size
|
||||
return rc_hash_buffer(hash, buffer, buffer_size);
|
||||
}
|
||||
|
||||
struct rc_buffered_file
|
||||
{
|
||||
const uint8_t* read_ptr;
|
||||
const uint8_t* data;
|
||||
size_t data_size;
|
||||
};
|
||||
|
||||
static struct rc_buffered_file rc_buffered_file;
|
||||
|
||||
static void* rc_file_open_buffered_file(const char* path)
|
||||
{
|
||||
struct rc_buffered_file* handle = (struct rc_buffered_file*)malloc(sizeof(struct rc_buffered_file));
|
||||
memcpy(handle, &rc_buffered_file, sizeof(rc_buffered_file));
|
||||
return handle;
|
||||
}
|
||||
|
||||
void rc_file_seek_buffered_file(void* file_handle, int64_t offset, int origin)
|
||||
{
|
||||
struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle;
|
||||
switch (origin)
|
||||
{
|
||||
case SEEK_SET: buffered_file->read_ptr = buffered_file->data + offset; break;
|
||||
case SEEK_CUR: buffered_file->read_ptr += offset; break;
|
||||
case SEEK_END: buffered_file->read_ptr = buffered_file->data + buffered_file->data_size - offset; break;
|
||||
}
|
||||
|
||||
if (buffered_file->read_ptr < buffered_file->data)
|
||||
buffered_file->read_ptr = buffered_file->data;
|
||||
else if (buffered_file->read_ptr > buffered_file->data + buffered_file->data_size)
|
||||
buffered_file->read_ptr = buffered_file->data + buffered_file->data_size;
|
||||
}
|
||||
|
||||
int64_t rc_file_tell_buffered_file(void* file_handle)
|
||||
{
|
||||
struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle;
|
||||
return (buffered_file->read_ptr - buffered_file->data);
|
||||
}
|
||||
|
||||
size_t rc_file_read_buffered_file(void* file_handle, void* buffer, size_t requested_bytes)
|
||||
{
|
||||
struct rc_buffered_file* buffered_file = (struct rc_buffered_file*)file_handle;
|
||||
const int64_t remaining = buffered_file->data_size - (buffered_file->read_ptr - buffered_file->data);
|
||||
if ((int)requested_bytes > remaining)
|
||||
requested_bytes = (int)remaining;
|
||||
|
||||
memcpy(buffer, buffered_file->read_ptr, requested_bytes);
|
||||
buffered_file->read_ptr += requested_bytes;
|
||||
return requested_bytes;
|
||||
}
|
||||
|
||||
void rc_file_close_buffered_file(void* file_handle)
|
||||
{
|
||||
free(file_handle);
|
||||
}
|
||||
|
||||
static int rc_hash_file_from_buffer(char hash[33], int console_id, const uint8_t* buffer, size_t buffer_size)
|
||||
{
|
||||
struct rc_hash_filereader filereader_funcs_old;
|
||||
int result;
|
||||
|
||||
memcpy(&filereader_funcs_old, &filereader_funcs, sizeof(filereader_funcs));
|
||||
|
||||
filereader_funcs.open = rc_file_open_buffered_file;
|
||||
filereader_funcs.close = rc_file_close_buffered_file;
|
||||
filereader_funcs.read = rc_file_read_buffered_file;
|
||||
filereader_funcs.seek = rc_file_seek_buffered_file;
|
||||
filereader_funcs.tell = rc_file_tell_buffered_file;
|
||||
|
||||
rc_buffered_file.data = rc_buffered_file.read_ptr = buffer;
|
||||
rc_buffered_file.data_size = buffer_size;
|
||||
|
||||
result = rc_hash_generate_from_file(hash, console_id, "[buffered file]");
|
||||
|
||||
memcpy(&filereader_funcs, &filereader_funcs_old, sizeof(filereader_funcs));
|
||||
return result;
|
||||
}
|
||||
|
||||
int rc_hash_generate_from_buffer(char hash[33], int console_id, const uint8_t* buffer, size_t buffer_size)
|
||||
{
|
||||
switch (console_id)
|
||||
@ -1593,14 +1591,15 @@ int rc_hash_generate_from_buffer(char hash[33], int console_id, const uint8_t* b
|
||||
case RC_CONSOLE_NINTENDO:
|
||||
return rc_hash_nes(hash, buffer, buffer_size);
|
||||
|
||||
case RC_CONSOLE_NINTENDO_64:
|
||||
return rc_hash_n64(hash, buffer, buffer_size);
|
||||
|
||||
case RC_CONSOLE_PC_ENGINE: /* NOTE: does not support PCEngine CD */
|
||||
return rc_hash_pce(hash, buffer, buffer_size);
|
||||
|
||||
case RC_CONSOLE_SUPER_NINTENDO:
|
||||
return rc_hash_snes(hash, buffer, buffer_size);
|
||||
|
||||
case RC_CONSOLE_NINTENDO_64:
|
||||
case RC_CONSOLE_NINTENDO_DS:
|
||||
return rc_hash_file_from_buffer(hash, console_id, buffer, buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1892,7 +1891,7 @@ int rc_hash_generate_from_file(char hash[33], int console_id, const char* path)
|
||||
return rc_hash_arcade(hash, path);
|
||||
|
||||
case RC_CONSOLE_NINTENDO_64:
|
||||
return rc_hash_n64_file(hash, path);
|
||||
return rc_hash_n64(hash, path);
|
||||
|
||||
case RC_CONSOLE_NINTENDO_DS:
|
||||
return rc_hash_nintendo_ds(hash, path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user