mirror of
https://github.com/libretro/RetroArch
synced 2025-03-26 20:37:10 +00:00
Updated rcheevos to 7.0.0
This commit is contained in:
parent
613a3e8479
commit
720ecaff17
deps/rcheevos
4
deps/rcheevos/CHANGELOG.md
vendored
4
deps/rcheevos/CHANGELOG.md
vendored
@ -1,3 +1,7 @@
|
||||
# v7.0.0
|
||||
|
||||
* Removed **rjson**
|
||||
|
||||
# v6.5.0
|
||||
|
||||
* Added a schema for errors returned by the server
|
||||
|
48
deps/rcheevos/README.md
vendored
48
deps/rcheevos/README.md
vendored
@ -465,54 +465,6 @@ void rc_format_value(char* buffer, int size, unsigned value, int format);
|
||||
|
||||
`buffer` receives `value` formatted according to `format`. No more than `size` characters will be written to `buffer`. 32 characters are enough to hold any valid value with any format.
|
||||
|
||||
# **rjson**
|
||||
|
||||
**rjson** provides parsing of RetroAchievements JSON files, and provides the results in strongly typed C structures instead of returning a generic dictionary and forcing the caller to check for values and extracting them.
|
||||
|
||||
Similarly to **rcheevos**, **rjson** does *not* allocate any memory. The caller must use the functions that compute the size needed to parse a given JSON, allocate the necessary memory, and call another function that does the parsing.
|
||||
|
||||
## API
|
||||
|
||||
### Return values
|
||||
|
||||
The functions that compute the memory needed for a given JSON return a positive value, which is the number of bytes needed. Errors are negative values taken from the following enumeration:
|
||||
|
||||
```c
|
||||
enum {
|
||||
RC_JSON_OK = 0,
|
||||
RC_JSON_OBJECT_EXPECTED = -1,
|
||||
RC_JSON_UNKOWN_RECORD = -2,
|
||||
RC_JSON_EOF_EXPECTED = -3,
|
||||
RC_JSON_MISSING_KEY = -4,
|
||||
RC_JSON_UNTERMINATED_KEY = -5,
|
||||
RC_JSON_MISSING_VALUE = -6,
|
||||
RC_JSON_UNTERMINATED_OBJECT = -7,
|
||||
RC_JSON_INVALID_VALUE = -8,
|
||||
RC_JSON_UNTERMINATED_STRING = -9,
|
||||
RC_JSON_UNTERMINATED_ARRAY = -10,
|
||||
RC_JSON_INVALID_ESCAPE = -11
|
||||
};
|
||||
```
|
||||
|
||||
### Supported schemas
|
||||
|
||||
**rjson** supports the following JSON schemas. Please see `rjson.h` for the definition of the C structures:
|
||||
|
||||
* `rc_json_gameid_t`: The game identifier returned by the server, given its hash.
|
||||
* `rc_json_login_t`: The login token for the user, given their user name and password.
|
||||
* `rc_json_patch_t`: The information about a game, given its identifier. It includes arrays with the achievements and leaderboards for the game.
|
||||
* `rc_json_unlocks_t`: The list of achievements already awarded for the player, given the game identifier. Used to avoid the emulator awarding achievements more than once.
|
||||
* `rc_json_error_t`: Error messages returned by the server.
|
||||
|
||||
For each schema there are two functions, for example:
|
||||
|
||||
```c
|
||||
int rc_json_get_patch_size(const char* json);
|
||||
const rc_json_patch_t* rc_json_parse_patch(void* buffer, const char* json);
|
||||
```
|
||||
|
||||
`rc_json_get_patch_size` returns the number of bytes needed to parse the given JSON as a `rc_json_patch_t`. `rc_json_parse_patch` parses the given JSON into the given `buffer`, returning a pointer that is used to access the decoded information.
|
||||
|
||||
# **rurl**
|
||||
|
||||
**rurl** builds URLs to access many RetroAchievements web services. Its purpose it to just to free the developer from having to URL-encode parameters and build correct URL that are valid for the server.
|
||||
|
131
deps/rcheevos/include/rjson.h
vendored
131
deps/rcheevos/include/rjson.h
vendored
@ -1,131 +0,0 @@
|
||||
#ifndef RJSON_H
|
||||
#define RJSON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
RC_JSON_OK = 0,
|
||||
RC_JSON_OBJECT_EXPECTED = -1,
|
||||
RC_JSON_UNKOWN_RECORD = -2,
|
||||
RC_JSON_EOF_EXPECTED = -3,
|
||||
RC_JSON_MISSING_KEY = -4,
|
||||
RC_JSON_UNTERMINATED_KEY = -5,
|
||||
RC_JSON_MISSING_VALUE = -6,
|
||||
RC_JSON_UNTERMINATED_OBJECT = -7,
|
||||
RC_JSON_INVALID_VALUE = -8,
|
||||
RC_JSON_UNTERMINATED_STRING = -9,
|
||||
RC_JSON_UNTERMINATED_ARRAY = -10,
|
||||
RC_JSON_INVALID_ESCAPE = -11
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned int gameid;
|
||||
char success;
|
||||
}
|
||||
rc_json_gameid_t;
|
||||
|
||||
int rc_json_get_gameid_size(const char* json);
|
||||
const rc_json_gameid_t* rc_json_parse_gameid(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
const char* token;
|
||||
const char* user;
|
||||
unsigned int score;
|
||||
unsigned int messages;
|
||||
char success;
|
||||
}
|
||||
rc_json_login_t;
|
||||
|
||||
int rc_json_get_login_size(const char* json);
|
||||
const rc_json_login_t* rc_json_parse_login(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
unsigned long long created;
|
||||
unsigned long long modified;
|
||||
const char* author;
|
||||
const char* badge;
|
||||
const char* description;
|
||||
const char* memaddr;
|
||||
const char* title;
|
||||
unsigned int flags;
|
||||
unsigned int points;
|
||||
unsigned int id;
|
||||
}
|
||||
rc_json_cheevo_t;
|
||||
|
||||
int rc_json_get_cheevo_size(const char* json);
|
||||
const rc_json_cheevo_t* rc_json_parse_cheevo(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
const char* description;
|
||||
const char* title;
|
||||
const char* format;
|
||||
const char* mem;
|
||||
unsigned int id;
|
||||
}
|
||||
rc_json_lboard_t;
|
||||
|
||||
int rc_json_get_lboard_size(const char* json);
|
||||
const rc_json_lboard_t* rc_json_parse_lboard(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
const rc_json_lboard_t* lboards; int lboards_count;
|
||||
const char* genre;
|
||||
const char* developer;
|
||||
const char* publisher;
|
||||
const char* released;
|
||||
const char** presence;
|
||||
const char* console;
|
||||
const rc_json_cheevo_t* cheevos; int cheevos_count;
|
||||
const char* image_boxart;
|
||||
const char* image_title;
|
||||
const char* image_icon;
|
||||
const char* title;
|
||||
const char* image_ingame;
|
||||
unsigned int consoleid;
|
||||
unsigned int id;
|
||||
unsigned int flags;
|
||||
unsigned int topicid;
|
||||
char is_final;
|
||||
}
|
||||
rc_json_patchdata_t;
|
||||
|
||||
int rc_json_get_patchdata_size(const char* json);
|
||||
const rc_json_patchdata_t* rc_json_parse_patchdata(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
rc_json_patchdata_t patchdata;
|
||||
char success;
|
||||
}
|
||||
rc_json_patch_t;
|
||||
|
||||
int rc_json_get_patch_size(const char* json);
|
||||
const rc_json_patch_t* rc_json_parse_patch(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
const unsigned int* ids; int ids_count;
|
||||
unsigned int gameid;
|
||||
char success;
|
||||
char hardcore;
|
||||
}
|
||||
rc_json_unlocks_t;
|
||||
|
||||
int rc_json_get_unlocks_size(const char* json);
|
||||
const rc_json_unlocks_t* rc_json_parse_unlocks(void* buffer, const char* json);
|
||||
|
||||
typedef struct {
|
||||
const char* error;
|
||||
char success;
|
||||
}
|
||||
rc_json_error_t;
|
||||
|
||||
int rc_json_get_error_size(const char* json);
|
||||
const rc_json_error_t* rc_json_parse_error(void* buffer, const char* json);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RJSON_H */
|
750
deps/rcheevos/src/rjson/dejson.c
vendored
750
deps/rcheevos/src/rjson/dejson.c
vendored
@ -1,750 +0,0 @@
|
||||
#include "rjson.h"
|
||||
#include "dejson.h"
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* json;
|
||||
uintptr_t buffer;
|
||||
int counting;
|
||||
jmp_buf rollback;
|
||||
}
|
||||
rc_json_state_t;
|
||||
|
||||
static void* rc_json_alloc(rc_json_state_t* state, size_t size, size_t alignment) {
|
||||
state->buffer = (state->buffer + alignment - 1) & ~(alignment - 1);
|
||||
void* ptr = (void*)state->buffer;
|
||||
state->buffer += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void rc_json_skip_spaces(rc_json_state_t* state) {
|
||||
if (isspace(*state->json)) {
|
||||
do {
|
||||
state->json++;
|
||||
}
|
||||
while (isspace(*state->json));
|
||||
}
|
||||
}
|
||||
|
||||
static size_t rc_json_skip_string(rc_json_state_t*);
|
||||
static void rc_json_skip_value(rc_json_state_t*);
|
||||
|
||||
static void rc_json_skip_object(rc_json_state_t* state) {
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
while (*state->json != '}') {
|
||||
rc_json_skip_string(state);
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
if (*state->json != ':') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
rc_json_skip_value(state);
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
if (*state->json != ',') {
|
||||
break;
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
}
|
||||
|
||||
if (*state->json != '}') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
}
|
||||
|
||||
static size_t rc_json_skip_array(rc_json_state_t* state) {
|
||||
size_t count = 0;
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
while (*state->json != ']') {
|
||||
rc_json_skip_value(state);
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
count++;
|
||||
|
||||
if (*state->json != ',') {
|
||||
break;
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
}
|
||||
|
||||
if (*state->json != ']') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static void rc_json_skip_number(rc_json_state_t* state) {
|
||||
errno = 0;
|
||||
|
||||
char* end;
|
||||
double result = strtod((const char*)state->json, &end);
|
||||
|
||||
if ((result == 0.0 && end == (const char*)state->json) || errno == ERANGE) {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json = (uint8_t*)end;
|
||||
}
|
||||
|
||||
static void rc_json_skip_boolean(rc_json_state_t* state) {
|
||||
const uint8_t* json = state->json;
|
||||
|
||||
if (json[0] == 't' && json[1] == 'r' && json[2] == 'u' && json[3] == 'e' && !isalpha(json[4])) {
|
||||
state->json += 4;
|
||||
}
|
||||
else if (json[0] == 'f' && json[1] == 'a' && json[2] == 'l' && json[3] == 's' && json[4] == 'e' && !isalpha(json[5])) {
|
||||
state->json += 5;
|
||||
}
|
||||
else {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t rc_json_skip_string(rc_json_state_t* state) {
|
||||
const uint8_t* aux = state->json + 1;
|
||||
size_t length = 0;
|
||||
|
||||
if (*aux !='"') {
|
||||
do {
|
||||
length++;
|
||||
|
||||
if (*aux++ == '\\') {
|
||||
char digits[5];
|
||||
uint32_t utf32;
|
||||
|
||||
switch (*aux++) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
case 'b':
|
||||
case 'f':
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (!isxdigit(aux[0] || !isxdigit(aux[1]) || !isxdigit(aux[2]) || !isxdigit(aux[3]))) {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_ESCAPE);
|
||||
}
|
||||
|
||||
digits[0] = aux[0];
|
||||
digits[1] = aux[1];
|
||||
digits[2] = aux[2];
|
||||
digits[3] = aux[3];
|
||||
digits[4] = 0;
|
||||
aux += 4;
|
||||
|
||||
utf32 = strtoul(digits, NULL, 16);
|
||||
|
||||
if (utf32 < 0x80U) {
|
||||
length += 0;
|
||||
}
|
||||
else if (utf32 < 0x800U) {
|
||||
length += 1;
|
||||
}
|
||||
else if (utf32 < 0x10000U) {
|
||||
length += 2;
|
||||
}
|
||||
else if (utf32 < 0x200000U) {
|
||||
length += 3;
|
||||
}
|
||||
else {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_ESCAPE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
longjmp(state->rollback, RC_JSON_INVALID_ESCAPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (*aux != '"');
|
||||
}
|
||||
|
||||
state->json = aux + 1;
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
static void rc_json_skip_null(rc_json_state_t* state) {
|
||||
const uint8_t* json = state->json;
|
||||
|
||||
if (json[0] == 'n' && json[1] == 'u' && json[2] == 'l' && json[3] == 'l' && !isalpha(json[4])) {
|
||||
state->json += 4;
|
||||
}
|
||||
else {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_json_skip_value(rc_json_state_t* state) {
|
||||
switch (*state->json) {
|
||||
case '{':
|
||||
rc_json_skip_object(state);
|
||||
break;
|
||||
|
||||
case '[':
|
||||
rc_json_skip_array(state);
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
rc_json_skip_number(state);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'f':
|
||||
rc_json_skip_boolean(state);
|
||||
break;
|
||||
|
||||
case '"':
|
||||
rc_json_skip_string(state);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
rc_json_skip_null(state);
|
||||
break;
|
||||
|
||||
default:
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
rc_json_skip_spaces(state);
|
||||
}
|
||||
|
||||
static int64_t rc_json_get_int64(rc_json_state_t* state, int64_t min, int64_t max) {
|
||||
errno = 0;
|
||||
|
||||
char* end;
|
||||
long long result = strtoll((const char*)state->json, &end, 10);
|
||||
|
||||
if ((result == 0 && end == (const char*)state->json) || errno == ERANGE || result < min || result > max) {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json = (uint8_t*)end;
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint64_t rc_json_get_uint64(rc_json_state_t* state, uint64_t max) {
|
||||
errno = 0;
|
||||
|
||||
char* end;
|
||||
unsigned long long result = strtoull((char*)state->json, &end, 10);
|
||||
|
||||
if ((result == 0 && end == (const char*)state->json) || errno == ERANGE || result > max) {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json = (uint8_t*)end;
|
||||
return result;
|
||||
}
|
||||
|
||||
static double rc_json_get_double(rc_json_state_t* state, double min, double max) {
|
||||
errno = 0;
|
||||
|
||||
char* end;
|
||||
double result = strtod((const char*)state->json, &end);
|
||||
|
||||
if ((result == 0.0 && end == (const char*)state->json) || errno == ERANGE || result < min || result > max) {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
state->json = (uint8_t*)end;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void rc_json_parse_char(rc_json_state_t* state, void* data) {
|
||||
*(char*)data = rc_json_get_int64(state, CHAR_MIN, CHAR_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uchar(rc_json_state_t* state, void* data) {
|
||||
*(unsigned char*)data = rc_json_get_uint64(state, UCHAR_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_short(rc_json_state_t* state, void* data) {
|
||||
*(short*)data = rc_json_get_int64(state, SHRT_MIN, SHRT_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_ushort(rc_json_state_t* state, void* data) {
|
||||
*(unsigned short*)data = rc_json_get_uint64(state, USHRT_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_int(rc_json_state_t* state, void* data) {
|
||||
*(int*)data = rc_json_get_int64(state, INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uint(rc_json_state_t* state, void* data) {
|
||||
*(unsigned int*)data = rc_json_get_uint64(state, UINT_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_long(rc_json_state_t* state, void* data) {
|
||||
*(long*)data = rc_json_get_int64(state, LONG_MIN, LONG_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_ulong(rc_json_state_t* state, void* data) {
|
||||
*(unsigned long*)data = rc_json_get_uint64(state, ULONG_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_longlong(rc_json_state_t* state, void* data) {
|
||||
*(unsigned long*)data = rc_json_get_int64(state, LLONG_MIN, LLONG_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_ulonglong(rc_json_state_t* state, void* data) {
|
||||
*(unsigned long*)data = rc_json_get_uint64(state, ULLONG_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_int8(rc_json_state_t* state, void* data) {
|
||||
*(int8_t*)data = rc_json_get_int64(state, INT8_MIN, INT8_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_int16(rc_json_state_t* state, void* data) {
|
||||
*(int16_t*)data = rc_json_get_int64(state, INT16_MIN, INT16_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_int32(rc_json_state_t* state, void* data) {
|
||||
*(int32_t*)data = rc_json_get_int64(state, INT32_MIN, INT32_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_int64(rc_json_state_t* state, void* data) {
|
||||
*(int64_t*)data = rc_json_get_int64(state, INT64_MIN, INT64_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uint8(rc_json_state_t* state, void* data) {
|
||||
*(uint8_t*)data = rc_json_get_uint64(state, UINT8_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uint16(rc_json_state_t* state, void* data) {
|
||||
*(uint16_t*)data = rc_json_get_uint64(state, UINT16_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uint32(rc_json_state_t* state, void* data) {
|
||||
*(uint32_t*)data = rc_json_get_uint64(state, UINT32_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_uint64(rc_json_state_t* state, void* data) {
|
||||
*(uint64_t*)data = rc_json_get_uint64(state, UINT64_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_float(rc_json_state_t* state, void* data) {
|
||||
*(float*)data = rc_json_get_double(state, FLT_MIN, FLT_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_double(rc_json_state_t* state, void* data) {
|
||||
*(double*)data = rc_json_get_double(state, DBL_MIN, DBL_MAX);
|
||||
}
|
||||
|
||||
static void rc_json_parse_boolean(rc_json_state_t* state, void* data) {
|
||||
const uint8_t* json = state->json;
|
||||
|
||||
if (json[0] == 't' && json[1] == 'r' && json[2] == 'u' && json[3] == 'e' && !isalpha(json[4])) {
|
||||
*(char*)data = 1;
|
||||
state->json += 4;
|
||||
}
|
||||
else if (json[0] == 'f' && json[1] == 'a' && json[2] == 'l' && json[3] == 's' && json[4] == 'e' && !isalpha(json[5])) {
|
||||
*(char*)data = 0;
|
||||
state->json += 5;
|
||||
}
|
||||
else {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_json_parse_string(rc_json_state_t* state, void* data) {
|
||||
const uint8_t* aux = state->json;
|
||||
size_t length = rc_json_skip_string(state);
|
||||
uint8_t* str = (uint8_t*)rc_json_alloc(state, length + 1, RC_JSON_ALIGNOF(char));
|
||||
|
||||
if (state->counting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*aux++ != '"') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
*(char**)data = (char*)str;
|
||||
|
||||
if (*aux !='"') {
|
||||
do {
|
||||
if (*aux == '\\') {
|
||||
char digits[5];
|
||||
uint32_t utf32;
|
||||
|
||||
aux++;
|
||||
|
||||
switch (*aux++) {
|
||||
case '"': *str++ = '"'; break;
|
||||
case '\\': *str++ = '\\'; break;
|
||||
case '/': *str++ = '/'; break;
|
||||
case 'b': *str++ = '\b'; break;
|
||||
case 'f': *str++ = '\f'; break;
|
||||
case 'n': *str++ = '\n'; break;
|
||||
case 'r': *str++ = '\r'; break;
|
||||
case 't': *str++ = '\t'; break;
|
||||
|
||||
case 'u':
|
||||
digits[0] = aux[0];
|
||||
digits[1] = aux[1];
|
||||
digits[2] = aux[2];
|
||||
digits[3] = aux[3];
|
||||
digits[4] = 0;
|
||||
aux += 4;
|
||||
|
||||
utf32 = strtoul(digits, NULL, 16);
|
||||
|
||||
if (utf32 < 0x80) {
|
||||
*str++ = utf32;
|
||||
}
|
||||
else if (utf32 < 0x800) {
|
||||
str[0] = 0xc0 | (utf32 >> 6);
|
||||
str[1] = 0x80 | (utf32 & 0x3f);
|
||||
str += 2;
|
||||
}
|
||||
else if (utf32 < 0x10000) {
|
||||
str[0] = 0xe0 | (utf32 >> 12);
|
||||
str[1] = 0x80 | ((utf32 >> 6) & 0x3f);
|
||||
str[2] = 0x80 | (utf32 & 0x3f);
|
||||
str += 3;
|
||||
}
|
||||
else {
|
||||
str[0] = 0xf0 | (utf32 >> 18);
|
||||
str[1] = 0x80 | ((utf32 >> 12) & 0x3f);
|
||||
str[2] = 0x80 | ((utf32 >> 6) & 0x3f);
|
||||
str[3] = 0x80 | (utf32 & 0x3f);
|
||||
str += 4;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
longjmp(state->rollback, RC_JSON_INVALID_ESCAPE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
*str++ = *aux++;
|
||||
}
|
||||
}
|
||||
while (*aux != '"');
|
||||
}
|
||||
|
||||
*str = 0;
|
||||
}
|
||||
|
||||
typedef void (*rc_json_parser_t)(rc_json_state_t*, void*);
|
||||
|
||||
static const rc_json_parser_t rc_json_parsers[] = {
|
||||
rc_json_parse_char, rc_json_parse_uchar, rc_json_parse_short, rc_json_parse_ushort,
|
||||
rc_json_parse_int, rc_json_parse_uint, rc_json_parse_long, rc_json_parse_ulong,
|
||||
rc_json_parse_longlong, rc_json_parse_ulonglong,
|
||||
rc_json_parse_int8, rc_json_parse_int16, rc_json_parse_int32, rc_json_parse_int64,
|
||||
rc_json_parse_uint8, rc_json_parse_uint16, rc_json_parse_uint32, rc_json_parse_uint64,
|
||||
rc_json_parse_float, rc_json_parse_double, rc_json_parse_boolean, rc_json_parse_string
|
||||
};
|
||||
|
||||
static void rc_json_parse_value(rc_json_state_t*, void*, const rc_json_field_meta_t*);
|
||||
static void rc_json_parse_object(rc_json_state_t*, void*, const rc_json_struct_meta_t*);
|
||||
|
||||
static void rc_json_parse_array(rc_json_state_t* state, void* value, size_t element_size, size_t element_alignment, const rc_json_field_meta_t* field) {
|
||||
if (*state->json != '[') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
const uint8_t* save = state->json;
|
||||
size_t count = rc_json_skip_array(state);
|
||||
state->json = save + 1;
|
||||
|
||||
uint8_t* elements = (uint8_t*)rc_json_alloc(state, element_size * count, element_alignment);
|
||||
|
||||
if (!state->counting) {
|
||||
struct {
|
||||
void* elements;
|
||||
int count;
|
||||
}
|
||||
*array = value;
|
||||
|
||||
array->elements = elements;
|
||||
array->count = count;
|
||||
}
|
||||
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
rc_json_field_meta_t field_scalar = *field;
|
||||
field_scalar.flags &= ~RC_JSON_FLAG_ARRAY;
|
||||
|
||||
while (*state->json != ']') {
|
||||
rc_json_parse_value(state, (void*)elements, &field_scalar);
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
elements += element_size;
|
||||
|
||||
if (*state->json != ',') {
|
||||
break;
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
}
|
||||
|
||||
if (*state->json != ']') {
|
||||
longjmp(state->rollback, RC_JSON_UNTERMINATED_ARRAY);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
}
|
||||
|
||||
const rc_json_struct_meta_t* rc_json_resolve_struct(uint32_t hash);
|
||||
|
||||
static void rc_json_parse_value(rc_json_state_t* state, void* value, const rc_json_field_meta_t* field) {
|
||||
#define RC_JSON_TYPE_INFO(t) sizeof(t), RC_JSON_ALIGNOF(t)
|
||||
|
||||
static const size_t rc_json_type_info[] = {
|
||||
RC_JSON_TYPE_INFO(char), RC_JSON_TYPE_INFO(unsigned char), RC_JSON_TYPE_INFO(short), RC_JSON_TYPE_INFO(unsigned short),
|
||||
RC_JSON_TYPE_INFO(int), RC_JSON_TYPE_INFO(unsigned int), RC_JSON_TYPE_INFO(long), RC_JSON_TYPE_INFO(unsigned long),
|
||||
RC_JSON_TYPE_INFO(long long), RC_JSON_TYPE_INFO(unsigned long long),
|
||||
RC_JSON_TYPE_INFO(int8_t), RC_JSON_TYPE_INFO(int16_t), RC_JSON_TYPE_INFO(int32_t), RC_JSON_TYPE_INFO(int64_t),
|
||||
RC_JSON_TYPE_INFO(uint8_t), RC_JSON_TYPE_INFO(uint16_t), RC_JSON_TYPE_INFO(uint32_t), RC_JSON_TYPE_INFO(uint64_t),
|
||||
RC_JSON_TYPE_INFO(float), RC_JSON_TYPE_INFO(double), RC_JSON_TYPE_INFO(char), RC_JSON_TYPE_INFO(const char*)
|
||||
};
|
||||
|
||||
const rc_json_struct_meta_t* meta = NULL;
|
||||
|
||||
if ((field->flags & (RC_JSON_FLAG_ARRAY | RC_JSON_FLAG_POINTER)) == 0) {
|
||||
if (field->type != RC_JSON_TYPE_RECORD) {
|
||||
char dummy[64];
|
||||
|
||||
if (state->counting) {
|
||||
value = (void*)dummy;
|
||||
}
|
||||
|
||||
rc_json_parsers[field->type](state, value);
|
||||
}
|
||||
else {
|
||||
meta = rc_json_resolve_struct(field->type_hash);
|
||||
|
||||
if (meta == NULL) {
|
||||
longjmp(state->rollback, RC_JSON_UNKOWN_RECORD);
|
||||
}
|
||||
|
||||
rc_json_parse_object(state, value, meta);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size, alignment;
|
||||
|
||||
if (field->type != RC_JSON_TYPE_RECORD) {
|
||||
unsigned ndx = field->type * 2;
|
||||
size = rc_json_type_info[ndx];
|
||||
alignment = rc_json_type_info[ndx + 1];
|
||||
}
|
||||
else { /* field->type == RC_JSON_TYPE_RECORD */
|
||||
meta = rc_json_resolve_struct(field->type_hash);
|
||||
|
||||
if (meta == NULL) {
|
||||
longjmp(state->rollback, RC_JSON_UNKOWN_RECORD);
|
||||
}
|
||||
|
||||
size = meta->size;
|
||||
alignment = meta->alignment;
|
||||
}
|
||||
|
||||
if ((field->flags & RC_JSON_FLAG_ARRAY) != 0) {
|
||||
rc_json_parse_array(state, value, size, alignment, field);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* json = state->json;
|
||||
|
||||
if (json[0] == 'n' && json[1] == 'u' && json[2] == 'l' && json[3] == 'l' && !isalpha(json[4])) {
|
||||
if (!state->counting) {
|
||||
*(void**)value = NULL;
|
||||
}
|
||||
|
||||
state->json += 4;
|
||||
return;
|
||||
}
|
||||
|
||||
void* pointer = rc_json_alloc(state, size, alignment);
|
||||
|
||||
if (!state->counting) {
|
||||
*(void**)value = pointer;
|
||||
}
|
||||
|
||||
value = pointer;
|
||||
|
||||
if (field->type != RC_JSON_TYPE_RECORD) {
|
||||
rc_json_parsers[field->type](state, value);
|
||||
}
|
||||
else {
|
||||
rc_json_parse_object(state, value, meta);
|
||||
}
|
||||
}
|
||||
|
||||
static void rc_json_parse_object(rc_json_state_t* state, void* record, const rc_json_struct_meta_t* meta) {
|
||||
if (*state->json != '{') {
|
||||
longjmp(state->rollback, RC_JSON_INVALID_VALUE);
|
||||
}
|
||||
|
||||
if (!state->counting) {
|
||||
memset((void*)record, 0, meta->size);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
while (*state->json != '}') {
|
||||
if (*state->json != '"') {
|
||||
longjmp(state->rollback, RC_JSON_MISSING_KEY);
|
||||
}
|
||||
|
||||
const char* key = (const char*)++state->json;
|
||||
const char* quote = key;
|
||||
|
||||
for (;;) {
|
||||
quote = strchr(quote, '"');
|
||||
|
||||
if (!quote) {
|
||||
longjmp(state->rollback, RC_JSON_UNTERMINATED_KEY);
|
||||
}
|
||||
|
||||
if (quote[-1] != '\\') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
state->json = (const uint8_t*)quote + 1;
|
||||
uint32_t hash = rc_json_hash((const uint8_t*)key, quote - key);
|
||||
|
||||
unsigned i;
|
||||
const rc_json_field_meta_t* field;
|
||||
|
||||
for (i = 0, field = meta->fields; i < meta->num_fields; i++, field++) {
|
||||
if (field->name_hash == hash) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
if (*state->json != ':') {
|
||||
longjmp(state->rollback, RC_JSON_MISSING_VALUE);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
if (i != meta->num_fields) {
|
||||
rc_json_parse_value(state, (void*)((uint8_t*)record + field->offset), field);
|
||||
}
|
||||
else {
|
||||
rc_json_skip_value(state);
|
||||
}
|
||||
|
||||
rc_json_skip_spaces(state);
|
||||
|
||||
if (*state->json != ',') {
|
||||
break;
|
||||
}
|
||||
|
||||
state->json++;
|
||||
rc_json_skip_spaces(state);
|
||||
}
|
||||
|
||||
if (*state->json != '}') {
|
||||
longjmp(state->rollback, RC_JSON_UNTERMINATED_OBJECT);
|
||||
}
|
||||
|
||||
state->json++;
|
||||
}
|
||||
|
||||
static int rc_json_execute(void* buffer, uint32_t hash, const uint8_t* json, int counting) {
|
||||
const rc_json_struct_meta_t* meta = rc_json_resolve_struct(hash);
|
||||
|
||||
if (!meta) {
|
||||
return RC_JSON_UNKOWN_RECORD;
|
||||
}
|
||||
|
||||
rc_json_state_t state;
|
||||
int res;
|
||||
|
||||
if ((res = setjmp(state.rollback)) != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
state.json = json;
|
||||
state.buffer = counting ? 0 : (uintptr_t)*(void**)buffer;
|
||||
state.counting = counting;
|
||||
|
||||
if (!counting) {
|
||||
*(void**)buffer = rc_json_alloc(&state, meta->size, meta->alignment);
|
||||
}
|
||||
|
||||
rc_json_skip_spaces(&state);
|
||||
rc_json_parse_object(&state, *(void**)buffer, meta);
|
||||
rc_json_skip_spaces(&state);
|
||||
|
||||
if (counting) {
|
||||
*(size_t*)buffer = state.buffer;
|
||||
}
|
||||
|
||||
return *state.json == 0 ? RC_JSON_OK : RC_JSON_EOF_EXPECTED;
|
||||
}
|
||||
|
||||
void* rc_json_deserialize(void* buffer, uint32_t hash, const uint8_t* json) {
|
||||
void** record = &buffer;
|
||||
int res = rc_json_execute(record, hash, json, 0);
|
||||
return res == RC_JSON_OK ? *record : NULL;
|
||||
}
|
||||
|
||||
int rc_json_get_size(size_t* size, uint32_t hash, const uint8_t* json) {
|
||||
return rc_json_execute((void*)size, hash, json, 1);
|
||||
}
|
||||
|
||||
uint32_t rc_json_hash(const uint8_t* str, size_t length) {
|
||||
typedef char unsigned_must_have_32_bits_minimum[sizeof(unsigned) >= 4 ? 1 : -1];
|
||||
|
||||
uint32_t hash = 5381;
|
||||
|
||||
if (length != 0) {
|
||||
do {
|
||||
hash = hash * 33 + *str++;
|
||||
}
|
||||
while (--length != 0);
|
||||
}
|
||||
|
||||
return hash & 0xffffffffU;
|
||||
}
|
71
deps/rcheevos/src/rjson/dejson.h
vendored
71
deps/rcheevos/src/rjson/dejson.h
vendored
@ -1,71 +0,0 @@
|
||||
#ifndef DEJSON_H
|
||||
#define DEJSON_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RC_JSON_OFFSETOF(s, f) ((size_t)(&((s*)0)->f))
|
||||
#define RC_JSON_ALIGNOF(t) RC_JSON_OFFSETOF(struct{char c; t d;}, d)
|
||||
|
||||
enum {
|
||||
RC_JSON_TYPE_CHAR,
|
||||
RC_JSON_TYPE_UCHAR,
|
||||
RC_JSON_TYPE_SHORT,
|
||||
RC_JSON_TYPE_USHORT,
|
||||
RC_JSON_TYPE_INT,
|
||||
RC_JSON_TYPE_UINT,
|
||||
RC_JSON_TYPE_LONG,
|
||||
RC_JSON_TYPE_LONGLONG,
|
||||
RC_JSON_TYPE_ULONG,
|
||||
RC_JSON_TYPE_ULONGLONG,
|
||||
RC_JSON_TYPE_INT8,
|
||||
RC_JSON_TYPE_INT16,
|
||||
RC_JSON_TYPE_INT32,
|
||||
RC_JSON_TYPE_INT64,
|
||||
RC_JSON_TYPE_UINT8,
|
||||
RC_JSON_TYPE_UINT16,
|
||||
RC_JSON_TYPE_UINT32,
|
||||
RC_JSON_TYPE_UINT64,
|
||||
RC_JSON_TYPE_FLOAT,
|
||||
RC_JSON_TYPE_DOUBLE,
|
||||
RC_JSON_TYPE_BOOL,
|
||||
RC_JSON_TYPE_STRING,
|
||||
RC_JSON_TYPE_RECORD
|
||||
};
|
||||
|
||||
enum {
|
||||
RC_JSON_FLAG_ARRAY = 1 << 0,
|
||||
RC_JSON_FLAG_POINTER = 1 << 1
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t name_hash;
|
||||
uint32_t type_hash;
|
||||
uint16_t offset;
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
}
|
||||
rc_json_field_meta_t;
|
||||
|
||||
typedef struct {
|
||||
const rc_json_field_meta_t* fields;
|
||||
uint32_t name_hash;
|
||||
uint32_t size;
|
||||
uint16_t alignment;
|
||||
uint16_t num_fields;
|
||||
}
|
||||
rc_json_struct_meta_t;
|
||||
|
||||
void* rc_json_deserialize(void* buffer, uint32_t hash, const uint8_t* json);
|
||||
int rc_json_get_size(size_t* size, uint32_t hash, const uint8_t* json);
|
||||
uint32_t rc_json_hash(const uint8_t* str, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DEJSON_H */
|
609
deps/rcheevos/src/rjson/schema.c
vendored
609
deps/rcheevos/src/rjson/schema.c
vendored
@ -1,609 +0,0 @@
|
||||
#include "rjson.h"
|
||||
#include "dejson.h"
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_gameid[] = {
|
||||
{
|
||||
/* Metadata for field unsigned int gameid;. */
|
||||
/* name_hash */ 0xb4960eecU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_gameid_t, gameid),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char success;. */
|
||||
/* name_hash */ 0x110461deU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_gameid_t, success),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_gameid = {
|
||||
/* fields */ rc_json_field_meta_gameid,
|
||||
/* name_hash */ 0xb4960eecU,
|
||||
/* size */ sizeof(rc_json_gameid_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_gameid_t),
|
||||
/* num_fields */ 2
|
||||
};
|
||||
|
||||
int rc_json_get_gameid_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0xb4960eecU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_gameid_t* rc_json_parse_gameid(void* buffer, const char* json) {
|
||||
return (const rc_json_gameid_t*)rc_json_deserialize(buffer, 0xb4960eecU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_login[] = {
|
||||
{
|
||||
/* Metadata for field const char* token;. */
|
||||
/* name_hash */ 0x0e2dbd26U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_login_t, token),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* user;. */
|
||||
/* name_hash */ 0x7c8da264U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_login_t, user),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int score;. */
|
||||
/* name_hash */ 0x0e1522c1U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_login_t, score),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int messages;. */
|
||||
/* name_hash */ 0xfed3807dU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_login_t, messages),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char success;. */
|
||||
/* name_hash */ 0x110461deU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_login_t, success),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_login = {
|
||||
/* fields */ rc_json_field_meta_login,
|
||||
/* name_hash */ 0x0d9ce89eU,
|
||||
/* size */ sizeof(rc_json_login_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_login_t),
|
||||
/* num_fields */ 5
|
||||
};
|
||||
|
||||
int rc_json_get_login_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0x0d9ce89eU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_login_t* rc_json_parse_login(void* buffer, const char* json) {
|
||||
return (const rc_json_login_t*)rc_json_deserialize(buffer, 0x0d9ce89eU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_cheevo[] = {
|
||||
{
|
||||
/* Metadata for field unsigned long long created;. */
|
||||
/* name_hash */ 0x3a84721dU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, created),
|
||||
/* type */ RC_JSON_TYPE_ULONGLONG,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned long long modified;. */
|
||||
/* name_hash */ 0xdcea4fe6U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, modified),
|
||||
/* type */ RC_JSON_TYPE_ULONGLONG,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* author;. */
|
||||
/* name_hash */ 0xa804edb8U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, author),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* badge;. */
|
||||
/* name_hash */ 0x887685d9U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, badge),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* description;. */
|
||||
/* name_hash */ 0xe61a1f69U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, description),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* memaddr;. */
|
||||
/* name_hash */ 0x1e76b53fU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, memaddr),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* title;. */
|
||||
/* name_hash */ 0x0e2a9a07U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, title),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int flags;. */
|
||||
/* name_hash */ 0x0d2e96b2U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, flags),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int points;. */
|
||||
/* name_hash */ 0xca8fce22U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, points),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int id;. */
|
||||
/* name_hash */ 0x005973f2U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_cheevo_t, id),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_cheevo = {
|
||||
/* fields */ rc_json_field_meta_cheevo,
|
||||
/* name_hash */ 0x0af404aeU,
|
||||
/* size */ sizeof(rc_json_cheevo_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_cheevo_t),
|
||||
/* num_fields */ 10
|
||||
};
|
||||
|
||||
int rc_json_get_cheevo_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0x0af404aeU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_cheevo_t* rc_json_parse_cheevo(void* buffer, const char* json) {
|
||||
return (const rc_json_cheevo_t*)rc_json_deserialize(buffer, 0x0af404aeU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_lboard[] = {
|
||||
{
|
||||
/* Metadata for field const char* description;. */
|
||||
/* name_hash */ 0xe61a1f69U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_lboard_t, description),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* title;. */
|
||||
/* name_hash */ 0x0e2a9a07U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_lboard_t, title),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* format;. */
|
||||
/* name_hash */ 0xb341208eU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_lboard_t, format),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* mem;. */
|
||||
/* name_hash */ 0x0b8807e4U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_lboard_t, mem),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int id;. */
|
||||
/* name_hash */ 0x005973f2U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_lboard_t, id),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_lboard = {
|
||||
/* fields */ rc_json_field_meta_lboard,
|
||||
/* name_hash */ 0xf7cacd7aU,
|
||||
/* size */ sizeof(rc_json_lboard_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_lboard_t),
|
||||
/* num_fields */ 5
|
||||
};
|
||||
|
||||
int rc_json_get_lboard_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0xf7cacd7aU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_lboard_t* rc_json_parse_lboard(void* buffer, const char* json) {
|
||||
return (const rc_json_lboard_t*)rc_json_deserialize(buffer, 0xf7cacd7aU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_patchdata[] = {
|
||||
{
|
||||
/* Metadata for field const rc_json_lboard_t* lboards; int lboards_count;. */
|
||||
/* name_hash */ 0xf1247d2dU,
|
||||
/* type_hash */ 0xf7cacd7aU,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, lboards),
|
||||
/* type */ RC_JSON_TYPE_RECORD,
|
||||
/* flags */ RC_JSON_FLAG_ARRAY
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* genre;. */
|
||||
/* name_hash */ 0x0d3d1136U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, genre),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* developer;. */
|
||||
/* name_hash */ 0x87f5b28bU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, developer),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* publisher;. */
|
||||
/* name_hash */ 0xce7b6ff3U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, publisher),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* released;. */
|
||||
/* name_hash */ 0x8acb686aU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, released),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char** presence;. */
|
||||
/* name_hash */ 0xf18dd230U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, presence),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ RC_JSON_FLAG_POINTER
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* console;. */
|
||||
/* name_hash */ 0x260aebd9U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, console),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const rc_json_cheevo_t* cheevos; int cheevos_count;. */
|
||||
/* name_hash */ 0x69749ae1U,
|
||||
/* type_hash */ 0x0af404aeU,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, cheevos),
|
||||
/* type */ RC_JSON_TYPE_RECORD,
|
||||
/* flags */ RC_JSON_FLAG_ARRAY
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* image_boxart;. */
|
||||
/* name_hash */ 0xddc6bd18U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, image_boxart),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* image_title;. */
|
||||
/* name_hash */ 0x65121b6aU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, image_title),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* image_icon;. */
|
||||
/* name_hash */ 0xe4022c11U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, image_icon),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* title;. */
|
||||
/* name_hash */ 0x0e2a9a07U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, title),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field const char* image_ingame;. */
|
||||
/* name_hash */ 0xedfff5f9U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, image_ingame),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int consoleid;. */
|
||||
/* name_hash */ 0x071656e5U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, consoleid),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int id;. */
|
||||
/* name_hash */ 0x005973f2U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, id),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int flags;. */
|
||||
/* name_hash */ 0x0d2e96b2U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, flags),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int topicid;. */
|
||||
/* name_hash */ 0x7d2b565aU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, topicid),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char is_final;. */
|
||||
/* name_hash */ 0x088a58abU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patchdata_t, is_final),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_patchdata = {
|
||||
/* fields */ rc_json_field_meta_patchdata,
|
||||
/* name_hash */ 0xadc4ac0fU,
|
||||
/* size */ sizeof(rc_json_patchdata_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_patchdata_t),
|
||||
/* num_fields */ 18
|
||||
};
|
||||
|
||||
int rc_json_get_patchdata_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0xadc4ac0fU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_patchdata_t* rc_json_parse_patchdata(void* buffer, const char* json) {
|
||||
return (const rc_json_patchdata_t*)rc_json_deserialize(buffer, 0xadc4ac0fU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_patch[] = {
|
||||
{
|
||||
/* Metadata for field rc_json_patchdata_t patchdata;. */
|
||||
/* name_hash */ 0xadc4ac0fU,
|
||||
/* type_hash */ 0xadc4ac0fU,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patch_t, patchdata),
|
||||
/* type */ RC_JSON_TYPE_RECORD,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char success;. */
|
||||
/* name_hash */ 0x110461deU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_patch_t, success),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_patch = {
|
||||
/* fields */ rc_json_field_meta_patch,
|
||||
/* name_hash */ 0x0dddd3d5U,
|
||||
/* size */ sizeof(rc_json_patch_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_patch_t),
|
||||
/* num_fields */ 2
|
||||
};
|
||||
|
||||
int rc_json_get_patch_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0x0dddd3d5U, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_patch_t* rc_json_parse_patch(void* buffer, const char* json) {
|
||||
return (const rc_json_patch_t*)rc_json_deserialize(buffer, 0x0dddd3d5U, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_unlocks[] = {
|
||||
{
|
||||
/* Metadata for field const unsigned int* ids; int ids_count;. */
|
||||
/* name_hash */ 0xc5e91303U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_unlocks_t, ids),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ RC_JSON_FLAG_ARRAY
|
||||
},
|
||||
{
|
||||
/* Metadata for field unsigned int gameid;. */
|
||||
/* name_hash */ 0xb4960eecU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_unlocks_t, gameid),
|
||||
/* type */ RC_JSON_TYPE_UINT,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char success;. */
|
||||
/* name_hash */ 0x110461deU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_unlocks_t, success),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char hardcore;. */
|
||||
/* name_hash */ 0xc1b80672U,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_unlocks_t, hardcore),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_unlocks = {
|
||||
/* fields */ rc_json_field_meta_unlocks,
|
||||
/* name_hash */ 0x9b4e2684U,
|
||||
/* size */ sizeof(rc_json_unlocks_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_unlocks_t),
|
||||
/* num_fields */ 4
|
||||
};
|
||||
|
||||
int rc_json_get_unlocks_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0x9b4e2684U, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_unlocks_t* rc_json_parse_unlocks(void* buffer, const char* json) {
|
||||
return (const rc_json_unlocks_t*)rc_json_deserialize(buffer, 0x9b4e2684U, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
static const rc_json_field_meta_t rc_json_field_meta_error[] = {
|
||||
{
|
||||
/* Metadata for field const char* error;. */
|
||||
/* name_hash */ 0x0d2011cfU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_error_t, error),
|
||||
/* type */ RC_JSON_TYPE_STRING,
|
||||
/* flags */ 0
|
||||
},
|
||||
{
|
||||
/* Metadata for field char success;. */
|
||||
/* name_hash */ 0x110461deU,
|
||||
/* type_hash */ 0x00000000U,
|
||||
/* offset */ RC_JSON_OFFSETOF(rc_json_error_t, success),
|
||||
/* type */ RC_JSON_TYPE_BOOL,
|
||||
/* flags */ 0
|
||||
},
|
||||
};
|
||||
|
||||
static const rc_json_struct_meta_t rc_json_struct_meta_error = {
|
||||
/* fields */ rc_json_field_meta_error,
|
||||
/* name_hash */ 0x0d2011cfU,
|
||||
/* size */ sizeof(rc_json_error_t),
|
||||
/* alignment */ RC_JSON_ALIGNOF(rc_json_error_t),
|
||||
/* num_fields */ 2
|
||||
};
|
||||
|
||||
int rc_json_get_error_size(const char* json) {
|
||||
size_t size;
|
||||
int res = rc_json_get_size(&size, 0x0d2011cfU, (const uint8_t*)json);
|
||||
|
||||
if (res == RC_JSON_OK) {
|
||||
res = (int)size;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const rc_json_error_t* rc_json_parse_error(void* buffer, const char* json) {
|
||||
return (const rc_json_error_t*)rc_json_deserialize(buffer, 0x0d2011cfU, (const uint8_t*)json);
|
||||
}
|
||||
|
||||
const rc_json_struct_meta_t* rc_json_resolve_struct(unsigned hash) {
|
||||
|
||||
switch (hash) {
|
||||
case 0xb4960eecU: return &rc_json_struct_meta_gameid;
|
||||
case 0x0d9ce89eU: return &rc_json_struct_meta_login;
|
||||
case 0x0af404aeU: return &rc_json_struct_meta_cheevo;
|
||||
case 0xf7cacd7aU: return &rc_json_struct_meta_lboard;
|
||||
case 0xadc4ac0fU: return &rc_json_struct_meta_patchdata;
|
||||
case 0x0dddd3d5U: return &rc_json_struct_meta_patch;
|
||||
case 0x9b4e2684U: return &rc_json_struct_meta_unlocks;
|
||||
case 0x0d2011cfU: return &rc_json_struct_meta_error;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
82
deps/rcheevos/src/rjson/schema.dej
vendored
82
deps/rcheevos/src/rjson/schema.dej
vendored
@ -1,82 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct gameid/GameID {
|
||||
bool success/Success;
|
||||
unsigned gameid/GameID;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct login/Login {
|
||||
bool success/Success;
|
||||
string user/User;
|
||||
string token/Token;
|
||||
unsigned score/Score;
|
||||
unsigned messages/Messages;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct cheevo/Achievement {
|
||||
unsigned id/ID;
|
||||
string memaddr/MemAddr;
|
||||
string title/Title;
|
||||
string description/Description;
|
||||
unsigned points/Points;
|
||||
string author/Author;
|
||||
string badge/BadgeName;
|
||||
unsigned flags/Flags;
|
||||
|
||||
unsigned long long modified/Modified;
|
||||
unsigned long long created/Created;
|
||||
};
|
||||
|
||||
struct lboard/Leaderboard {
|
||||
unsigned id/ID;
|
||||
string mem/Mem;
|
||||
string format/Format;
|
||||
string title/Title;
|
||||
string description/Description;
|
||||
};
|
||||
|
||||
struct patchdata/PatchData {
|
||||
unsigned id/ID;
|
||||
string title/Title;
|
||||
unsigned consoleid/ConsoleID;
|
||||
unsigned topicid/ForumTopicID;
|
||||
unsigned flags/Flags;
|
||||
string image_icon/ImageIcon;
|
||||
string image_title/ImageTitle;
|
||||
string image_ingame/ImageIngame;
|
||||
string image_boxart/ImageBoxArt;
|
||||
string publisher/Publisher;
|
||||
string developer/Developer;
|
||||
string genre/Genre;
|
||||
string released/Released;
|
||||
bool is_final/IsFinal;
|
||||
string console/ConsoleName;
|
||||
string* presence/RichPresencePatch;
|
||||
cheevo cheevos/Achievements[];
|
||||
lboard lboards/Leaderboards[];
|
||||
};
|
||||
|
||||
struct patch/Patch {
|
||||
bool success/Success;
|
||||
patchdata patchdata/PatchData;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct unlocks/Unlocks {
|
||||
bool success/Success;
|
||||
unsigned ids/UserUnlocks[];
|
||||
unsigned gameid/GameID;
|
||||
bool hardcore/HardcoreMode;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
struct error/Error {
|
||||
bool success/Success;
|
||||
string error/Error;
|
||||
};
|
2
deps/rcheevos/test/Makefile
vendored
2
deps/rcheevos/test/Makefile
vendored
@ -1,12 +1,10 @@
|
||||
RC_SRC=../src/rcheevos
|
||||
RC_JSON_SRC=../src/rjson
|
||||
RC_URL_SRC=../src/rurl
|
||||
LUA_SRC=lua/src
|
||||
|
||||
OBJ=$(RC_SRC)/trigger.o $(RC_SRC)/condset.o $(RC_SRC)/condition.o $(RC_SRC)/operand.o \
|
||||
$(RC_SRC)/term.o $(RC_SRC)/expression.o $(RC_SRC)/value.o $(RC_SRC)/lboard.o \
|
||||
$(RC_SRC)/alloc.o $(RC_SRC)/format.o \
|
||||
$(RC_JSON_SRC)/dejson.o $(RC_JSON_SRC)/schema.o \
|
||||
$(RC_URL_SRC)/url.o \
|
||||
$(LUA_SRC)/lapi.o $(LUA_SRC)/lcode.o $(LUA_SRC)/lctype.o $(LUA_SRC)/ldebug.o \
|
||||
$(LUA_SRC)/ldo.o $(LUA_SRC)/ldump.o $(LUA_SRC)/lfunc.o $(LUA_SRC)/lgc.o $(LUA_SRC)/llex.o \
|
||||
|
80
deps/rcheevos/test/test.c
vendored
80
deps/rcheevos/test/test.c
vendored
@ -1,5 +1,4 @@
|
||||
#include "internal.h"
|
||||
#include "rjson.h"
|
||||
#include "rurl.h"
|
||||
|
||||
#include "smw_snes.h"
|
||||
@ -2091,84 +2090,6 @@ static void test_lua(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_json(void) {
|
||||
{
|
||||
/*------------------------------------------------------------------------
|
||||
TestJson
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
char json[65536];
|
||||
char buffer[65536];
|
||||
int res;
|
||||
const rc_json_patch_t* patch;
|
||||
|
||||
memcpy(json, smw_snes_json, smw_snes_json_len);
|
||||
json[smw_snes_json_len] = 0;
|
||||
|
||||
res = rc_json_get_patch_size(json);
|
||||
assert(res >= 0);
|
||||
patch = rc_json_parse_patch(buffer, json);
|
||||
|
||||
assert(patch->success);
|
||||
assert(patch->patchdata.id == 228);
|
||||
assert(!strcmp(patch->patchdata.title, "Super Mario World"));
|
||||
assert(patch->patchdata.consoleid == 3);
|
||||
assert(patch->patchdata.topicid == 135);
|
||||
assert(patch->patchdata.flags == 0);
|
||||
assert(!strcmp(patch->patchdata.image_icon, "/Images/006972.png"));
|
||||
assert(!strcmp(patch->patchdata.image_title, "/Images/000021.png"));
|
||||
assert(!strcmp(patch->patchdata.image_ingame, "/Images/000022.png"));
|
||||
assert(!strcmp(patch->patchdata.image_boxart, "/Images/000138.png"));
|
||||
assert(!strcmp(patch->patchdata.publisher, "Nintendo"));
|
||||
assert(!strcmp(patch->patchdata.developer, "Nintendo EAD"));
|
||||
assert(!strcmp(patch->patchdata.genre, "Platforming"));
|
||||
assert(!strcmp(patch->patchdata.released, "JP 1990 , NA 1991 Europe 1992"));
|
||||
assert(patch->patchdata.is_final == 0);
|
||||
assert(!strcmp(patch->patchdata.console, "SNES"));
|
||||
assert(patch->patchdata.presence != NULL);
|
||||
assert(!strcmp(*patch->patchdata.presence, "Lookup:LevelName\r\n0x0=Title Screen\r\n0x14=Yellow Switch Palace\r\n0x28=Yoshi's House\r\n0x29=Yoshi's Island 1\r\n0x2a=Yoshi's Island 2\r\n0x27=Yoshi's Island 3\r\n0x26=Yoshi's Island 4\r\n0x25=#1 Iggy's Castle\r\n0x15=Donut Plains 1\r\n0x9=Donut Plains 2\r\n0x8=Green Switch Palace\r\n0x4=Donut Ghost House\r\n0x3=Top Secret Area\r\n0x5=Donut Plains 3\r\n0x6=Donut Plains 4\r\n0x7=#2 Morton's Castle\r\n0xa=Donut Secret 1\r\n0x13=Donut Secret House\r\n0x2f=Donut Secret 2\r\n0x3e=Vanilla Dome 1\r\n0x3c=Vanilla Dome 2\r\n0x3f=Red Switch Palace\r\n0x2b=Vanilla Ghost House\r\n0x2e=Vanilla Dome 3\r\n0x3d=Vanilla Dome 4\r\n0x40=#3 Lemmy's Castle\r\n0x2d=Vanilla Secret 1\r\n0x1=Vanilla Secret 2\r\n0x2=Vanilla Secret 3\r\n0xb=Vanilla Fortress\r\n0xc=Butter Bridge 1\r\n0xd=Butter Bridge 2\r\n0xe=#4 Ludwig's Castle\r\n0xf=Cheese Bridge Area\r\n0x10=Cookie Mountain\r\n0x11=Soda Lake\r\n0x41=Forest Ghost House\r\n0x42=Forest of Illusion 1\r\n0x43=Forest of Illusion 4\r\n0x44=Forest of Illusion 2\r\n0x45=Blue Switch Palace\r\n0x46=Forest Secret Area\r\n0x47=Forest of Illusion 3\r\n0x1f=Forest Fortress\r\n0x20=#5 Roy's Castle\r\n0x21=Choco-Ghost House\r\n0x22=Chocolate Island 1\r\n0x23=Chocolate Island 3\r\n0x24=Chocolate Island 2\r\n0x1b=Chocolate Fortress\r\n0x1d=Chocolate Island 4\r\n0x1c=Chocolate Island 5\r\n0x1a=#6 Wendy's Castle\r\n0x18=Sunken Ghost Ship\r\n0x3b=Chocolate Secret\r\n0x3a=Valley of Bowser 1\r\n0x39=Valley of Bowser 2\r\n0x38=Valley Ghost House\r\n0x37=Valley of Bowser 3\r\n0x33=Valley of Bowser 4\r\n0x34=#7 Larry's Castle\r\n0x35=Valley Fortress\r\n0x31=Front Door\r\n0x32=Back Door\r\n0x58=Star World 1\r\n0x54=Star World 2\r\n0x56=Star World 3\r\n0x59=Star World 4\r\n0x5a=Star World 5\r\n0x4e=Gnarly\r\n0x4f=Tubular\r\n0x50=Way Cool\r\n0x51=Awesome\r\n0x4c=Groovy\r\n0x4b=Mondo\r\n0x4a=Outrageous\r\n0x49=Funky\r\n\r\nFormat:Lives\r\nFormatType=VALUE\r\n\r\nDisplay:\r\n@LevelName(0xh0013bf), @Lives(0xh0dbe_v+1) lives"));
|
||||
assert(patch->patchdata.cheevos_count == 53);
|
||||
assert(patch->patchdata.lboards_count == 0);
|
||||
|
||||
assert(patch->patchdata.cheevos[0].id == 4874);
|
||||
assert(!strcmp(patch->patchdata.cheevos[0].memaddr, "0xH000019=2"));
|
||||
assert(!strcmp(patch->patchdata.cheevos[0].title, "I Believe I Can Fly"));
|
||||
assert(!strcmp(patch->patchdata.cheevos[0].description, "Collect a feather"));
|
||||
assert(patch->patchdata.cheevos[0].points == 2);
|
||||
assert(!strcmp(patch->patchdata.cheevos[0].author, "UNHchabo"));
|
||||
assert(patch->patchdata.cheevos[0].modified == 1452548368ULL);
|
||||
assert(patch->patchdata.cheevos[0].created == 1391908064ULL);
|
||||
assert(!strcmp(patch->patchdata.cheevos[0].badge, "05506"));
|
||||
assert(patch->patchdata.cheevos[0].flags == 3);
|
||||
|
||||
assert(patch->patchdata.cheevos[52].id == 29667);
|
||||
assert(!strcmp(patch->patchdata.cheevos[52].memaddr, "0xR001ff5=1_0xH0013bf=58"));
|
||||
assert(!strcmp(patch->patchdata.cheevos[52].title, "Under A Koopa Moon"));
|
||||
assert(!strcmp(patch->patchdata.cheevos[52].description, "Collect the 3-Up Moon in the Valley of Bowser"));
|
||||
assert(patch->patchdata.cheevos[52].points == 2);
|
||||
assert(!strcmp(patch->patchdata.cheevos[52].author, "Dexterspet"));
|
||||
assert(patch->patchdata.cheevos[52].modified == 1445783716ULL);
|
||||
assert(patch->patchdata.cheevos[52].created == 1445754036ULL);
|
||||
assert(!strcmp(patch->patchdata.cheevos[52].badge, "30351"));
|
||||
assert(patch->patchdata.cheevos[52].flags == 3);
|
||||
|
||||
memcpy(json, galaga_nes_json, galaga_nes_json_len);
|
||||
json[galaga_nes_json_len] = 0;
|
||||
|
||||
res = rc_json_get_patch_size(json);
|
||||
assert(res >= 0);
|
||||
patch = rc_json_parse_patch(buffer, json);
|
||||
|
||||
assert(patch->patchdata.lboards_count == 1);
|
||||
|
||||
assert(patch->patchdata.lboards[0].id == 310);
|
||||
assert(!strcmp(patch->patchdata.lboards[0].mem, "STA:0xh0482=1::CAN:0xh0470=0_0xh0471=0::SUB:0xh0485=0_d0xh007a=0_0xh007a=1::VAL:0xh00e5*10_0xh00e4*100_0xh00e3*1000_0xh00e2*10000_0xh00e1*100000_0xh00e0*1000000"));
|
||||
assert(!strcmp(patch->patchdata.lboards[0].format, "SCORE"));
|
||||
assert(!strcmp(patch->patchdata.lboards[0].title, "Hi-Score"));
|
||||
assert(!strcmp(patch->patchdata.lboards[0].description, "Get the highest score possible."));
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test_operand();
|
||||
test_condition();
|
||||
@ -2177,7 +2098,6 @@ int main(void) {
|
||||
test_value();
|
||||
test_lboard();
|
||||
test_lua();
|
||||
test_json();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user