id24: skies (#1894)

This commit is contained in:
Roman Fomin 2024-09-13 18:20:03 +07:00 committed by GitHub
parent c0d3ae55bf
commit 43fd3869fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 655 additions and 148 deletions

BIN
base/all-all/skytran.lmp Normal file

Binary file not shown.

View File

@ -120,6 +120,7 @@ set(WOOF_SOURCES
r_plane.c r_plane.h
r_segs.c r_segs.h
r_sky.c r_sky.h
r_skydefs.c r_skydefs.h
r_state.h
r_swirl.c r_swirl.h
r_things.c r_things.h

View File

@ -2414,6 +2414,8 @@ void P_UpdateSpecials (void)
// [crispy] draw fuzz effect independent of rendering frame rate
R_SetFuzzPosTic();
R_UpdateSky();
}
//////////////////////////////////////////////////////////////////////

View File

@ -52,6 +52,7 @@ extern boolean fuzzcolumn_mode;
void R_SetFuzzColumnMode(void);
void R_DrawSkyColumn(void);
void R_DrawSkyColumnMasked(void);
// Draw with color translation tables, for player sprite rendering,
// Green/Red/Blue/Indigo shirts.

View File

@ -39,6 +39,7 @@
#include "doomstat.h"
#include "doomtype.h"
#include "i_system.h"
#include "m_fixed.h"
#include "r_bmaps.h" // [crispy] R_BrightmapForTexName()
#include "r_data.h"
#include "r_defs.h"
@ -46,11 +47,13 @@
#include "r_main.h"
#include "r_plane.h"
#include "r_sky.h"
#include "r_skydefs.h"
#include "r_state.h"
#include "r_swirl.h" // [crispy] R_DistortedFlat()
#include "tables.h"
#include "v_fmt.h"
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
#define MAXVISPLANES 128 /* must be a power of 2 */
@ -264,19 +267,19 @@ static visplane_t *new_visplane(unsigned hash)
visplane_t *R_DupPlane(const visplane_t *pl, int start, int stop)
{
unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height);
visplane_t *new_pl = new_visplane(hash);
unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height);
visplane_t *new_pl = new_visplane(hash);
new_pl->height = pl->height;
new_pl->picnum = pl->picnum;
new_pl->lightlevel = pl->lightlevel;
new_pl->xoffs = pl->xoffs; // killough 2/28/98
new_pl->yoffs = pl->yoffs;
new_pl->minx = start;
new_pl->maxx = stop;
memset(new_pl->top, UCHAR_MAX, video.width * sizeof(*new_pl->top));
new_pl->height = pl->height;
new_pl->picnum = pl->picnum;
new_pl->lightlevel = pl->lightlevel;
new_pl->xoffs = pl->xoffs; // killough 2/28/98
new_pl->yoffs = pl->yoffs;
new_pl->minx = start;
new_pl->maxx = stop;
memset(new_pl->top, UCHAR_MAX, video.width * sizeof(*new_pl->top));
return new_pl;
return new_pl;
}
//
@ -376,152 +379,260 @@ static void R_MakeSpans(int x, unsigned int t1, unsigned int b1, unsigned int t2
spanstart[b2--] = x;
}
static void DrawSkyFire(visplane_t *pl, fire_t *fire)
{
dc_colormap[0] = dc_colormap[1] = fullcolormap;
dc_texturemid = -28 * FRACUNIT;
dc_iscale = skyiscale;
dc_texheight = FIRE_HEIGHT;
for (int x = pl->minx; x <= pl->maxx; x++)
{
dc_x = x;
dc_yl = pl->top[x];
dc_yh = pl->bottom[x];
if (dc_yl != USHRT_MAX && dc_yl <= dc_yh)
{
dc_source = R_GetFireColumn((viewangle + xtoskyangle[x])
>> ANGLETOSKYSHIFT);
colfunc();
}
}
}
static void DrawSkyTex(visplane_t *pl, skytex_t *skytex)
{
int texture = R_TextureNumForName(skytex->name);
dc_colormap[0] = dc_colormap[1] = fullcolormap;
dc_texturemid = skytex->mid * FRACUNIT;
dc_texheight = textureheight[texture] >> FRACBITS;
dc_iscale = FixedMul(skyiscale, skytex->scaley);
dc_texturemid += skytex->curry;
angle_t an = viewangle + FixedToAngle(skytex->currx);
for (int x = pl->minx; x <= pl->maxx; x++)
{
dc_x = x;
dc_yl = pl->top[x];
dc_yh = pl->bottom[x];
if (dc_yl != USHRT_MAX && dc_yl <= dc_yh)
{
dc_source = R_GetColumnMod2(texture, (an + xtoskyangle[x])
>> ANGLETOSKYSHIFT);
colfunc();
}
}
}
static void DrawSkyDef(visplane_t *pl)
{
if (sky->type == SkyType_Fire)
{
DrawSkyFire(pl, &sky->fire);
return;
}
DrawSkyTex(pl, &sky->skytex);
if (sky->type == SkyType_WithForeground)
{
// Special tranmap to avoid custom render path to render sky
// transparently. See id24 SKYDEFS spec.
tranmap = W_CacheLumpName("SKYTRAN", PU_CACHE);
colfunc = R_DrawTLColumn;
DrawSkyTex(pl, &sky->foreground);
tranmap = main_tranmap;
colfunc = R_DrawColumn;
}
}
static void do_draw_mbf_sky(visplane_t *pl)
{
int texture;
angle_t an, flip;
boolean vertically_scrolling = false;
// killough 10/98: allow skies to come from sidedefs.
// Allows scrolling and/or animated skies, as well as
// arbitrary multiple skies per level without having
// to use info lumps.
an = viewangle;
if (pl->picnum & PL_SKYFLAT)
{
// Sky Linedef
const line_t *l = &lines[pl->picnum & ~PL_SKYFLAT];
// Sky transferred from first sidedef
const side_t *s = *l->sidenum + sides;
if (s->baserowoffset - s->oldrowoffset)
{
vertically_scrolling = true;
}
// Texture comes from upper texture of reference sidedef
texture = texturetranslation[s->toptexture];
// Horizontal offset is turned into an angle offset,
// to allow sky rotation as well as careful positioning.
// However, the offset is scaled very small, so that it
// allows a long-period of sky rotation.
an += s->textureoffset;
// Vertical offset allows careful sky positioning.
dc_texturemid = s->rowoffset - 28 * FRACUNIT;
// We sometimes flip the picture horizontally.
//
// Doom always flipped the picture, so we make it optional,
// to make it easier to use the new feature, while to still
// allow old sky textures to be used.
flip = l->special == 272 ? 0u : ~0u;
}
else // Normal Doom sky, only one allowed per level
{
dc_texturemid = skytexturemid; // Default y-offset
texture = skytexture; // Default texture
flip = 0; // Doom flips it
}
// Sky is always drawn full bright, i.e. colormaps[0] is used.
// Because of this hack, sky is not affected by INVUL inverse mapping.
//
// killough 7/19/98: fix hack to be more realistic:
if (STRICTMODE_COMP(comp_skymap)
|| !(dc_colormap[0] = dc_colormap[1] = fixedcolormap))
{
dc_colormap[0] = dc_colormap[1] = fullcolormap; // killough 3/20/98
}
dc_texheight = textureheight[texture] >> FRACBITS; // killough
dc_iscale = skyiscale;
// [FG] stretch short skies
boolean stretch = (stretchsky && dc_texheight < 200);
if (stretch || !vertically_scrolling)
{
if (stretch)
{
dc_iscale = dc_iscale * dc_texheight / SKYSTRETCH_HEIGHT;
dc_texturemid = dc_texturemid * dc_texheight / SKYSTRETCH_HEIGHT;
}
// Make sure the fade-to-color effect doesn't happen too early
fixed_t diff = dc_texturemid - SCREENHEIGHT / 2 * FRACUNIT;
if (diff < 0)
{
diff += textureheight[texture];
diff %= textureheight[texture];
dc_texturemid = SCREENHEIGHT / 2 * FRACUNIT + diff;
}
dc_skycolor = R_GetSkyColor(texture);
colfunc = R_DrawSkyColumn;
}
// killough 10/98: Use sky scrolling offset, and possibly flip picture
for (int x = pl->minx; x <= pl->maxx; x++)
{
dc_x = x;
dc_yl = pl->top[x];
dc_yh = pl->bottom[x];
if (dc_yl != USHRT_MAX && dc_yl <= dc_yh)
{
dc_source = R_GetColumnMod2(texture, ((an + xtoskyangle[x]) ^ flip)
>> ANGLETOSKYSHIFT);
colfunc();
}
}
colfunc = R_DrawColumn;
}
// New function, by Lee Killough
static void do_draw_plane(visplane_t *pl)
{
register int x;
if (pl->minx <= pl->maxx)
{
if (pl->picnum == skyflatnum || pl->picnum & PL_SKYFLAT) // sky flat
{
int texture;
angle_t an, flip;
boolean vertically_scrolling = false;
boolean stretch;
if (pl->minx > pl->maxx)
{
return;
}
// killough 10/98: allow skies to come from sidedefs.
// Allows scrolling and/or animated skies, as well as
// arbitrary multiple skies per level without having
// to use info lumps.
// sky flat
an = viewangle;
if (pl->picnum == skyflatnum && sky)
{
DrawSkyDef(pl);
return;
}
if (pl->picnum & PL_SKYFLAT)
{
// Sky Linedef
const line_t *l = &lines[pl->picnum & ~PL_SKYFLAT];
if (pl->picnum == skyflatnum || pl->picnum & PL_SKYFLAT)
{
do_draw_mbf_sky(pl);
return;
}
// Sky transferred from first sidedef
const side_t *s = *l->sidenum + sides;
// regular flat
if (s->baserowoffset - s->oldrowoffset)
vertically_scrolling = true;
int stop, light;
boolean swirling = (flattranslation[pl->picnum] == -1);
// Texture comes from upper texture of reference sidedef
texture = texturetranslation[s->toptexture];
// [crispy] add support for SMMU swirling flats
if (swirling)
{
ds_source = R_DistortedFlat(firstflat + pl->picnum);
ds_brightmap = R_BrightmapForFlatNum(pl->picnum);
}
else
{
ds_source = V_CacheFlatNum(
firstflat + flattranslation[pl->picnum], PU_STATIC);
ds_brightmap =
R_BrightmapForFlatNum(flattranslation[pl->picnum]);
}
// Horizontal offset is turned into an angle offset,
// to allow sky rotation as well as careful positioning.
// However, the offset is scaled very small, so that it
// allows a long-period of sky rotation.
xoffs = pl->xoffs; // killough 2/28/98: Add offsets
yoffs = pl->yoffs;
planeheight = abs(pl->height - viewz);
light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
an += s->textureoffset;
if (light >= LIGHTLEVELS)
{
light = LIGHTLEVELS - 1;
}
// Vertical offset allows careful sky positioning.
if (light < 0)
{
light = 0;
}
dc_texturemid = s->rowoffset - 28*FRACUNIT;
stop = pl->maxx + 1;
planezlight = zlight[light];
pl->top[pl->minx - 1] = pl->top[stop] = USHRT_MAX;
// We sometimes flip the picture horizontally.
//
// Doom always flipped the picture, so we make it optional,
// to make it easier to use the new feature, while to still
// allow old sky textures to be used.
for (int x = pl->minx; x <= stop; x++)
{
R_MakeSpans(x, pl->top[x - 1], pl->bottom[x - 1], pl->top[x],
pl->bottom[x]);
}
flip = l->special==272 ? 0u : ~0u;
}
else // Normal Doom sky, only one allowed per level
{
dc_texturemid = skytexturemid; // Default y-offset
texture = skytexture; // Default texture
flip = 0; // Doom flips it
}
// Sky is always drawn full bright, i.e. colormaps[0] is used.
// Because of this hack, sky is not affected by INVUL inverse mapping.
//
// killough 7/19/98: fix hack to be more realistic:
if (STRICTMODE_COMP(comp_skymap) || !(dc_colormap[0] = dc_colormap[1] = fixedcolormap))
dc_colormap[0] = dc_colormap[1] = fullcolormap; // killough 3/20/98
dc_texheight = textureheight[texture]>>FRACBITS; // killough
dc_iscale = skyiscale;
// [FG] stretch short skies
stretch = (stretchsky && dc_texheight < 200);
if (stretch || !vertically_scrolling)
{
fixed_t diff;
if (stretch)
{
dc_iscale = dc_iscale * dc_texheight / SKYSTRETCH_HEIGHT;
dc_texturemid = dc_texturemid * dc_texheight / SKYSTRETCH_HEIGHT;
}
// Make sure the fade-to-color effect doesn't happen too early
diff = dc_texturemid - SCREENHEIGHT / 2 * FRACUNIT;
if (diff < 0)
{
diff += textureheight[texture];
diff %= textureheight[texture];
dc_texturemid = SCREENHEIGHT / 2 * FRACUNIT + diff;
}
dc_skycolor = R_GetSkyColor(texture);
colfunc = R_DrawSkyColumn;
}
// killough 10/98: Use sky scrolling offset, and possibly flip picture
for (x = pl->minx; (dc_x = x) <= pl->maxx; x++)
if ((dc_yl = pl->top[x]) != USHRT_MAX && dc_yl <= (dc_yh = pl->bottom[x]))
{
dc_source = R_GetColumnMod2(texture, ((an + xtoskyangle[x])^flip) >>
ANGLETOSKYSHIFT);
colfunc();
}
colfunc = R_DrawColumn;
}
else // regular flat
{
int stop, light;
boolean swirling = (flattranslation[pl->picnum] == -1);
// [crispy] add support for SMMU swirling flats
if (swirling)
{
ds_source = R_DistortedFlat(firstflat + pl->picnum);
ds_brightmap = R_BrightmapForFlatNum(pl->picnum);
}
else
{
ds_source = V_CacheFlatNum(firstflat + flattranslation[pl->picnum],
PU_STATIC);
ds_brightmap = R_BrightmapForFlatNum(flattranslation[pl->picnum]);
}
xoffs = pl->xoffs; // killough 2/28/98: Add offsets
yoffs = pl->yoffs;
planeheight = abs(pl->height-viewz);
light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
if (light >= LIGHTLEVELS)
light = LIGHTLEVELS-1;
if (light < 0)
light = 0;
stop = pl->maxx + 1;
planezlight = zlight[light];
pl->top[pl->minx-1] = pl->top[stop] = USHRT_MAX;
for (x = pl->minx ; x <= stop ; x++)
R_MakeSpans(x,pl->top[x-1],pl->bottom[x-1],pl->top[x],pl->bottom[x]);
if (!swirling) Z_ChangeTag (ds_source, PU_CACHE);
}
}
if (!swirling)
{
Z_ChangeTag(ds_source, PU_CACHE);
}
}
//

View File

@ -22,11 +22,16 @@
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include "doomtype.h"
#include "i_video.h"
#include "m_array.h"
#include "m_fixed.h"
#include "m_random.h"
#include "r_data.h"
#include "r_sky.h"
#include "r_skydefs.h"
#include "r_state.h" // [FG] textureheight[]
#include "w_wad.h"
#include "z_zone.h"
@ -42,13 +47,153 @@ int skyflatnum;
int skytexture = -1; // [crispy] initialize
int skytexturemid;
sky_t *sky = NULL;
// PSX fire sky, description: https://fabiensanglard.net/doom_fire_psx/
static byte fire_indices[FIRE_WIDTH * FIRE_HEIGHT];
static byte fire_pixels[FIRE_WIDTH * FIRE_HEIGHT];
static void PrepareFirePixels(fire_t *fire)
{
byte *rover = fire_pixels;
for (int x = 0; x < FIRE_WIDTH; x++)
{
byte *src = fire_indices + x;
for (int y = 0; y < FIRE_HEIGHT; y++)
{
*rover++ = fire->palette[*src];
src += FIRE_WIDTH;
}
}
}
static void SpreadFire(void)
{
for (int x = 0; x < FIRE_WIDTH; ++x)
{
for (int y = 1; y < FIRE_HEIGHT; ++y)
{
int src = y * FIRE_WIDTH + x;
int index = fire_indices[src];
if (!index)
{
fire_indices[src - FIRE_WIDTH] = 0;
}
else
{
int rand_index = M_Random() & 3;
int dst = src - rand_index + 1;
fire_indices[dst - FIRE_WIDTH] = index - (rand_index & 1);
}
}
}
}
static void SetupFire(fire_t *fire)
{
memset(fire_indices, 0, FIRE_WIDTH * FIRE_HEIGHT);
int last = array_size(fire->palette) - 1;
for (int i = 0; i < FIRE_WIDTH; ++i)
{
fire_indices[(FIRE_HEIGHT - 1) * FIRE_WIDTH + i] = last;
}
for (int i = 0; i < 64; ++i)
{
SpreadFire();
}
PrepareFirePixels(fire);
}
byte *R_GetFireColumn(int col)
{
while (col < 0)
{
col += FIRE_WIDTH;
}
col %= FIRE_WIDTH;
return &fire_pixels[col * FIRE_HEIGHT];
}
static void InitSky(void)
{
static skydefs_t *skydefs;
static boolean run_once = true;
if (run_once)
{
skydefs = R_ParseSkyDefs();
run_once = false;
}
if (!skydefs)
{
return;
}
array_foreach(sky, skydefs->skies)
{
if (skytexture == R_CheckTextureNumForName(sky->skytex.name))
{
if (sky->type == SkyType_Fire)
{
SetupFire(&sky->fire);
}
return;
}
}
sky = NULL;
}
void R_UpdateSky(void)
{
if (!sky)
{
return;
}
if (sky->type == SkyType_Fire)
{
fire_t *fire = &sky->fire;
if (fire->tics_left == 0)
{
SpreadFire();
PrepareFirePixels(fire);
fire->tics_left = fire->updatetime;
}
fire->tics_left--;
return;
}
skytex_t *background = &sky->skytex;
background->currx += background->scrollx;
background->curry += background->scrolly;
if (sky->type == SkyType_WithForeground)
{
skytex_t *foreground = &sky->foreground;
foreground->currx += foreground->scrollx;
foreground->curry += foreground->scrolly;
}
}
//
// R_InitSkyMap
// Called whenever the view size changes.
//
void R_InitSkyMap (void)
{
int skyheight;
InitSky();
// [crispy] initialize
if (skytexture == -1)
@ -58,7 +203,7 @@ void R_InitSkyMap (void)
R_GetSkyColor(skytexture);
// [FG] stretch short skies
skyheight = textureheight[skytexture]>>FRACBITS;
int skyheight = textureheight[skytexture] >> FRACBITS;
if (stretchsky && skyheight < 200)
skytexturemid = -28*FRACUNIT;

View File

@ -21,6 +21,7 @@
#define __R_SKY__
#include "doomtype.h"
#include "r_skydefs.h"
// SKY, store the number for name.
#define SKYFLATNAME "F_SKY1"
@ -38,11 +39,20 @@ extern boolean linearsky;
extern int skytexture;
extern int skytexturemid;
extern sky_t *sky;
// Called whenever the view size changes.
void R_InitSkyMap(void);
byte R_GetSkyColor(int texturenum);
void R_UpdateSky(void);
#define FIRE_WIDTH 128
#define FIRE_HEIGHT 256
byte *R_GetFireColumn(int col);
#endif
//----------------------------------------------------------------------------

173
src/r_skydefs.c Normal file
View File

@ -0,0 +1,173 @@
//
// 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 "r_skydefs.h"
#include "doomdef.h"
#include "doomtype.h"
#include "i_printf.h"
#include "m_array.h"
#include "m_fixed.h"
#include "m_misc.h"
#include "w_wad.h"
#include "cjson/cJSON.h"
static boolean ParseFire(cJSON *json, fire_t *out)
{
cJSON *updatetime = cJSON_GetObjectItemCaseSensitive(json, "updatetime");
if (!cJSON_IsNumber(updatetime))
{
return false;
}
out->updatetime = updatetime->valuedouble * TICRATE;
cJSON *palette = cJSON_GetObjectItemCaseSensitive(json, "palette");
if (!cJSON_IsArray(palette))
{
return false;
}
int size = cJSON_GetArraySize(palette);
for (int i = 0; i < size; ++i)
{
cJSON *color = cJSON_GetArrayItem(palette, i);
array_push(out->palette, color->valueint);
}
return true;
}
static boolean ParseSkyTex(cJSON *json, skytex_t *out)
{
cJSON *name = cJSON_GetObjectItemCaseSensitive(json, "name");
if (!cJSON_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))
{
return false;
}
out->mid = mid->valuedouble;
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;
return true;
}
static boolean ParseSky(cJSON *json, sky_t *out)
{
cJSON *type = cJSON_GetObjectItemCaseSensitive(json, "type");
if (!cJSON_IsNumber(type))
{
return false;
}
out->type = type->valueint;
skytex_t background = {0};
if (!ParseSkyTex(json, &background))
{
return false;
}
out->skytex = background;
cJSON *js_fire = cJSON_GetObjectItemCaseSensitive(json, "fire");
fire_t fire = {0};
if (!cJSON_IsNull(js_fire))
{
ParseFire(js_fire, &fire);
}
out->fire = fire;
cJSON *js_foreground = cJSON_GetObjectItemCaseSensitive(json, "foregroundtex");
skytex_t foreground = {0};
if (!cJSON_IsNull(js_foreground))
{
ParseSkyTex(js_foreground, &foreground);
}
out->foreground = foreground;
return true;
}
static boolean ParseFlatMap(cJSON *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);
return true;
}
skydefs_t *R_ParseSkyDefs(void)
{
int lumpnum = W_CheckNumForName("SKYDEFS");
if (lumpnum < 0)
{
return NULL;
}
cJSON *json = cJSON_Parse(W_CacheLumpNum(lumpnum, PU_CACHE));
if (json == NULL)
{
I_Printf(VB_ERROR, "JSON: Error parsing SKYDEFS");
cJSON_Delete(json);
return NULL;
}
cJSON *data = cJSON_GetObjectItemCaseSensitive(json, "data");
if (!cJSON_IsObject(data))
{
cJSON_Delete(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)
{
sky_t sky = {0};
if (ParseSky(js_sky, &sky))
{
array_push(out->skies, sky);
}
}
cJSON *js_flatmapping = cJSON_GetObjectItemCaseSensitive(data, "flatmapping");
cJSON *js_flatmap = NULL;
cJSON_ArrayForEach(js_flatmap, js_flatmapping)
{
flatmap_t flatmap = {0};
if (ParseFlatMap(js_flatmap, &flatmap))
{
array_push(out->flatmapping, flatmap);
}
}
cJSON_Delete(json);
return out;
}

68
src/r_skydefs.h Normal file
View File

@ -0,0 +1,68 @@
//
// 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 R_SKYDEFS_H
#define R_SKYDEFS_H
#include "doomtype.h"
#include "m_fixed.h"
typedef enum
{
SkyType_Normal,
SkyType_Fire,
SkyType_WithForeground,
} skytype_t;
typedef struct fire_s
{
byte *palette;
int updatetime;
int tics_left;
} fire_t;
typedef struct
{
const char *name;
double mid;
fixed_t scrollx;
fixed_t currx;
fixed_t scrolly;
fixed_t curry;
fixed_t scalex;
fixed_t scaley;
} skytex_t;
typedef struct sky_s
{
skytype_t type;
skytex_t skytex;
fire_t fire;
skytex_t foreground;
} sky_t;
typedef struct
{
const char *flat;
const char *sky;
} flatmap_t;
typedef struct
{
sky_t *skies;
flatmap_t *flatmapping;
} skydefs_t;
skydefs_t *R_ParseSkyDefs(void);
#endif

View File

@ -155,11 +155,7 @@ interlevel_t *WI_ParseInterlevel(const char *lumpname)
cJSON *json = cJSON_Parse(W_CacheLumpName(lumpname, PU_CACHE));
if (json == NULL)
{
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL)
{
I_Printf(VB_ERROR, "Error parsing %s", lumpname);
}
I_Printf(VB_ERROR, "Error parsing %s", lumpname);
cJSON_Delete(json);
return NULL;
}