Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/api/rc_api_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ int rc_api_process_fetch_all_user_progress_server_response(rc_api_fetch_all_user
entry = response->entries;
while (rc_json_get_next_object_field(&iterator, &field))
{
entry->game_id = (uint32_t)strtol(field.name, &end, 10);
entry->game_id = (uint32_t)strtoul(field.name, &end, 10);

field.name = "";
if (!rc_json_get_required_object(entry_fields, sizeof(entry_fields) / sizeof(entry_fields[0]),
Expand Down
2 changes: 1 addition & 1 deletion src/libretro/rc_libretro.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ static void rc_libretro_memory_init_from_memory_map(rc_libretro_memory_regions_t
/* if we need to extract a disconnect bit, the largest block we can read is up to
* the next time that bit flips */
/* https://stackoverflow.com/questions/12247186/find-the-lowest-set-bit */
disconnect_size = (uint32_t)(desc->disconnect & -((int)desc->disconnect));
disconnect_size = (uint32_t)(desc->disconnect & ((size_t)0 - desc->disconnect));
desc_size = disconnect_size - (real_address & (disconnect_size - 1));
}

Expand Down
37 changes: 22 additions & 15 deletions src/runtime/rc_memref.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <stdlib.h> /* malloc/realloc */
#include <string.h> /* memcpy */
#include <math.h> /* INFINITY/NAN */
#include <float.h> /* FLT_RADIX/FLT_MANT_DIG/FLT_MAX_EXP */

#include <stdio.h>

#define MEMREF_PLACEHOLDER_ADDRESS 0xFFFFFFFF

Expand Down Expand Up @@ -344,23 +347,27 @@ static float rc_build_float(uint32_t mantissa_bits, int32_t exponent, int sign)
double dbl = ((double)mantissa) / ((double)implied_bit);

if (exponent > 127) {
/* exponent above 127 is a special number */
if (mantissa_bits == 0) {
/* infinity */
#ifdef INFINITY /* INFINITY and NAN #defines require C99 */
dbl = (double)INFINITY;
#else
dbl = -log(0.0);
#endif
}
else {
/* NaN */
#ifdef NAN
dbl = NAN;
/* An exponent above 127 is a special number: infinity when the mantissa is zero, NaN otherwise. */

#if FLT_RADIX == 2 && FLT_MANT_DIG == 24 && FLT_MAX_EXP == 128

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-ffast_math doesn't prevent defining INFINITY or NAN, so we can't detect when it's being applied. Instead, look for the definition of the deconstruction of a float (which also works in c89) and define the constants ourself, avoiding the real constants which would trigger the compiler warning.

/* The system is IEEE754 capable. Use a memcpy to shuffle an IEEE754 constant into the variable to
* avoid a warning when compiling with -ffast-math. -ffast-math optimizes out special logic for NaN
* and infinity to provide a small performance boost. As such, actually using the values may result
* in undefined behavior - hence the warning. But consumers want to be able to use that flag, so this
* is the easiest way to support it. */
const uint32_t ieee754_inf = 0x7F800000;
const uint32_t ieee754_nan = 0x7FC00000;
float f;
memcpy(&f, (mantissa_bits == 0) ? &ieee754_inf : &ieee754_nan, sizeof(float));
dbl = (double)f;
#elif defined(INFINITY) && defined(NAN)
/* If we're not on an IEEE754 system, rely on the constants provided by the compiler. */
dbl = (double)(mantissa_bits == 0 ? INFINITY : NAN);
#else
dbl = -sqrt(-1);
/* C89 doesn't define INFINITY or NAN. Fallback to FLT_MAX and hope all achievement logic uses full
* range checking as non-float data could appear as >X or <Y whereas NaN would be neither >X nor <Y */
dbl = (double)FLT_MAX;
#endif
}
}
else if (exponent > 0) {
/* exponent from 1 to 127 is a number greater than 1 */
Expand Down
Loading