Skip to content

Commit

Permalink
implement m_json wrapper (#1904)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfomin authored Sep 15, 2024
1 parent ad47fe9 commit e5dc326
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 121 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(WOOF_SOURCES
m_fixed.h
m_input.c m_input.h
m_io.c m_io.h
m_json.c m_json.h
mn_font.c mn_font.h
mn_menu.c mn_menu.h
mn_setup.c mn_internal.h
Expand Down
76 changes: 76 additions & 0 deletions src/m_json.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// Copyright(C) 2024 Roman Fomin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

#include "m_json.h"

#include "cjson/cJSON.h"

json_t *JS_Open(const char *data)
{
return cJSON_Parse(data);
}

void JS_Close(json_t *json)
{
cJSON_Delete(json);
}

boolean JS_IsNull(json_t *json)
{
return cJSON_IsNull(json);
}

boolean JS_IsNumber(json_t *json)
{
return cJSON_IsNumber(json);
}

boolean JS_IsString(json_t *json)
{
return cJSON_IsString(json);
}

boolean JS_IsArray(json_t *json)
{
return cJSON_IsArray(json);
}

json_t *JS_GetObject(json_t *json, const char *string)
{
return cJSON_GetObjectItemCaseSensitive(json, string);
}

int JS_GetArraySize(json_t *json)
{
return cJSON_GetArraySize(json);
}

json_t *JS_GetArrayItem(json_t *json, int index)
{
return cJSON_GetArrayItem(json, index);
}

double JS_GetNumber(json_t *json)
{
return json->valuedouble;
}

int JS_GetInteger(json_t *json)
{
return json->valueint;
}

const char *JS_GetString(json_t *json)
{
return json->valuestring;
}
43 changes: 43 additions & 0 deletions src/m_json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Copyright(C) 2024 Roman Fomin
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

#ifndef M_JSON_H
#define M_JSON_H

#include "doomtype.h"

typedef struct cJSON json_t;

json_t *JS_Open(const char *data);
void JS_Close(json_t *json);

json_t *JS_GetObject(json_t *json, const char *string);

boolean JS_IsNull(json_t *json);
boolean JS_IsNumber(json_t *json);
boolean JS_IsString(json_t *json);
boolean JS_IsArray(json_t *json);

double JS_GetNumber(json_t *json);
int JS_GetInteger(json_t *json);
const char *JS_GetString(json_t *json);

int JS_GetArraySize(json_t *json);
json_t *JS_GetArrayItem(json_t *json, int index);

#define JS_ArrayForEach(element, array) \
for (int __index = 0, __size = JS_GetArraySize((array)); \
__index < __size && ((element) = JS_GetArrayItem((array), __index)); \
++__index)

#endif
115 changes: 61 additions & 54 deletions src/r_skydefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,73 +18,80 @@
#include "i_printf.h"
#include "m_array.h"
#include "m_fixed.h"
#include "m_json.h"
#include "m_misc.h"
#include "w_wad.h"

#include "cjson/cJSON.h"

static boolean ParseFire(cJSON *json, fire_t *out)
static boolean ParseFire(json_t *json, fire_t *out)
{
cJSON *updatetime = cJSON_GetObjectItemCaseSensitive(json, "updatetime");
if (!cJSON_IsNumber(updatetime))
json_t *updatetime = JS_GetObject(json, "updatetime");
if (!JS_IsNumber(updatetime))
{
return false;
}
out->updatetime = updatetime->valuedouble * TICRATE;
out->updatetime = JS_GetNumber(updatetime) * TICRATE;

cJSON *palette = cJSON_GetObjectItemCaseSensitive(json, "palette");
if (!cJSON_IsArray(palette))
json_t *palette = JS_GetObject(json, "palette");
if (!JS_IsArray(palette))
{
return false;
}
int size = cJSON_GetArraySize(palette);
int size = JS_GetArraySize(palette);
for (int i = 0; i < size; ++i)
{
cJSON *color = cJSON_GetArrayItem(palette, i);
array_push(out->palette, color->valueint);
json_t *color = JS_GetArrayItem(palette, i);
array_push(out->palette, JS_GetInteger(color));
}

return true;
}

static boolean ParseSkyTex(cJSON *json, skytex_t *out)
static boolean ParseSkyTex(json_t *json, skytex_t *out)
{
cJSON *name = cJSON_GetObjectItemCaseSensitive(json, "name");
if (!cJSON_IsString(name))
json_t *name = JS_GetObject(json, "name");
if (!JS_IsString(name))
{
return false;
}
out->name = M_StringDuplicate(name->valuestring);

cJSON *mid = cJSON_GetObjectItemCaseSensitive(json, "mid");
cJSON *scrollx = cJSON_GetObjectItemCaseSensitive(json, "scrollx");
cJSON *scrolly = cJSON_GetObjectItemCaseSensitive(json, "scrolly");
cJSON *scalex = cJSON_GetObjectItemCaseSensitive(json, "scalex");
cJSON *scaley = cJSON_GetObjectItemCaseSensitive(json, "scaley");
if (!cJSON_IsNumber(mid)
|| !cJSON_IsNumber(scrollx) || !cJSON_IsNumber(scrolly)
|| !cJSON_IsNumber(scalex) || !cJSON_IsNumber(scaley))
out->name = M_StringDuplicate(JS_GetString(name));

json_t *mid = JS_GetObject(json, "mid");
json_t *scrollx = JS_GetObject(json, "scrollx");
json_t *scrolly = JS_GetObject(json, "scrolly");
json_t *scalex = JS_GetObject(json, "scalex");
json_t *scaley = JS_GetObject(json, "scaley");
if (!JS_IsNumber(mid)
|| !JS_IsNumber(scrollx) || !JS_IsNumber(scrolly)
|| !JS_IsNumber(scalex) || !JS_IsNumber(scaley))
{
return false;
}
out->mid = mid->valuedouble;
out->mid = JS_GetNumber(mid);
const double ticratescale = 1.0 / TICRATE;
out->scrollx = (scrollx->valuedouble * ticratescale) * FRACUNIT;
out->scrolly = (scrolly->valuedouble * ticratescale) * FRACUNIT;
out->scalex = scalex->valuedouble * FRACUNIT;
out->scaley = (1.0 / scaley->valuedouble) * FRACUNIT;
out->scrollx = (JS_GetNumber(scrollx) * ticratescale) * FRACUNIT;
out->scrolly = (JS_GetNumber(scrolly) * ticratescale) * FRACUNIT;
out->scalex = JS_GetNumber(scalex) * FRACUNIT;
double value = JS_GetNumber(scaley);
if (value)
{
out->scaley = (1.0 / value) * FRACUNIT;
}
else
{
out->scaley = FRACUNIT;
}

return true;
}

static boolean ParseSky(cJSON *json, sky_t *out)
static boolean ParseSky(json_t *json, sky_t *out)
{
cJSON *type = cJSON_GetObjectItemCaseSensitive(json, "type");
if (!cJSON_IsNumber(type))
json_t *type = JS_GetObject(json, "type");
if (!JS_IsNumber(type))
{
return false;
}
out->type = type->valueint;
out->type = JS_GetInteger(type);

skytex_t background = {0};
if (!ParseSkyTex(json, &background))
Expand All @@ -93,17 +100,17 @@ static boolean ParseSky(cJSON *json, sky_t *out)
}
out->skytex = background;

cJSON *js_fire = cJSON_GetObjectItemCaseSensitive(json, "fire");
json_t *js_fire = JS_GetObject(json, "fire");
fire_t fire = {0};
if (!cJSON_IsNull(js_fire))
if (!JS_IsNull(js_fire))
{
ParseFire(js_fire, &fire);
}
out->fire = fire;

cJSON *js_foreground = cJSON_GetObjectItemCaseSensitive(json, "foregroundtex");
json_t *js_foreground = JS_GetObject(json, "foregroundtex");
skytex_t foreground = {0};
if (!cJSON_IsNull(js_foreground))
if (!JS_IsNull(js_foreground))
{
ParseSkyTex(js_foreground, &foreground);
}
Expand All @@ -112,12 +119,12 @@ static boolean ParseSky(cJSON *json, sky_t *out)
return true;
}

static boolean ParseFlatMap(cJSON *json, flatmap_t *out)
static boolean ParseFlatMap(json_t *json, flatmap_t *out)
{
cJSON *flat = cJSON_GetObjectItemCaseSensitive(json, "flat");
out->flat = M_StringDuplicate(flat->valuestring);
cJSON *sky = cJSON_GetObjectItemCaseSensitive(json, "sky");
out->sky = M_StringDuplicate(sky->valuestring);
json_t *flat = JS_GetObject(json, "flat");
out->flat = M_StringDuplicate(JS_GetString(flat));
json_t *sky = JS_GetObject(json, "sky");
out->sky = M_StringDuplicate(JS_GetString(sky));
return true;
}

Expand All @@ -129,26 +136,26 @@ skydefs_t *R_ParseSkyDefs(void)
return NULL;
}

cJSON *json = cJSON_Parse(W_CacheLumpNum(lumpnum, PU_CACHE));
json_t *json = JS_Open(W_CacheLumpNum(lumpnum, PU_CACHE));
if (json == NULL)
{
I_Printf(VB_ERROR, "JSON: Error parsing SKYDEFS");
cJSON_Delete(json);
JS_Close(json);
return NULL;
}

cJSON *data = cJSON_GetObjectItemCaseSensitive(json, "data");
if (!cJSON_IsObject(data))
json_t *data = JS_GetObject(json, "data");
if (JS_IsNull(data))
{
cJSON_Delete(json);
JS_Close(json);
return NULL;
}

skydefs_t *out = calloc(1, sizeof(*out));

cJSON *js_skies = cJSON_GetObjectItemCaseSensitive(data, "skies");
cJSON *js_sky = NULL;
cJSON_ArrayForEach(js_sky, js_skies)
json_t *js_skies = JS_GetObject(data, "skies");
json_t *js_sky = NULL;
JS_ArrayForEach(js_sky, js_skies)
{
sky_t sky = {0};
if (ParseSky(js_sky, &sky))
Expand All @@ -157,9 +164,9 @@ skydefs_t *R_ParseSkyDefs(void)
}
}

cJSON *js_flatmapping = cJSON_GetObjectItemCaseSensitive(data, "flatmapping");
cJSON *js_flatmap = NULL;
cJSON_ArrayForEach(js_flatmap, js_flatmapping)
json_t *js_flatmapping = JS_GetObject(data, "flatmapping");
json_t *js_flatmap = NULL;
JS_ArrayForEach(js_flatmap, js_flatmapping)
{
flatmap_t flatmap = {0};
if (ParseFlatMap(js_flatmap, &flatmap))
Expand All @@ -168,6 +175,6 @@ skydefs_t *R_ParseSkyDefs(void)
}
}

cJSON_Delete(json);
JS_Close(json);
return out;
}
Loading

0 comments on commit e5dc326

Please sign in to comment.