mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 11:22:18 -04:00
id24: skies (#1894)
This commit is contained in:
parent
c0d3ae55bf
commit
43fd3869fd
BIN
base/all-all/skytran.lmp
Normal file
BIN
base/all-all/skytran.lmp
Normal file
Binary file not shown.
@ -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
|
||||
|
@ -2414,6 +2414,8 @@ void P_UpdateSpecials (void)
|
||||
|
||||
// [crispy] draw fuzz effect independent of rendering frame rate
|
||||
R_SetFuzzPosTic();
|
||||
|
||||
R_UpdateSky();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -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.
|
||||
|
393
src/r_plane.c
393
src/r_plane.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
149
src/r_sky.c
149
src/r_sky.c
@ -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;
|
||||
|
10
src/r_sky.h
10
src/r_sky.h
@ -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
173
src/r_skydefs.c
Normal 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
68
src/r_skydefs.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user