mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-30 13:10:55 +00:00
add r_patch.c
This commit is contained in:
parent
1a44159ce9
commit
a22af36305
18 changed files with 1380 additions and 1288 deletions
|
@ -123,6 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
||||||
r_sky.c
|
r_sky.c
|
||||||
r_splats.c
|
r_splats.c
|
||||||
r_things.c
|
r_things.c
|
||||||
|
r_patch.c
|
||||||
r_portal.c
|
r_portal.c
|
||||||
|
|
||||||
r_bsp.h
|
r_bsp.h
|
||||||
|
@ -137,6 +138,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
||||||
r_splats.h
|
r_splats.h
|
||||||
r_state.h
|
r_state.h
|
||||||
r_things.h
|
r_things.h
|
||||||
|
r_patch.h
|
||||||
r_portal.h
|
r_portal.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -470,6 +470,7 @@ OBJS:=$(i_main_o) \
|
||||||
$(OBJDIR)/r_sky.o \
|
$(OBJDIR)/r_sky.o \
|
||||||
$(OBJDIR)/r_splats.o \
|
$(OBJDIR)/r_splats.o \
|
||||||
$(OBJDIR)/r_things.o \
|
$(OBJDIR)/r_things.o \
|
||||||
|
$(OBJDIR)/r_patch.o \
|
||||||
$(OBJDIR)/r_portal.o \
|
$(OBJDIR)/r_portal.o \
|
||||||
$(OBJDIR)/screen.o \
|
$(OBJDIR)/screen.o \
|
||||||
$(OBJDIR)/v_video.o \
|
$(OBJDIR)/v_video.o \
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
#include "r_data.h"
|
#include "r_data.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
|
#include "r_patch.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../z_zone.h"
|
#include "../z_zone.h"
|
||||||
#include "../v_video.h"
|
#include "../v_video.h"
|
||||||
#include "../r_draw.h"
|
#include "../r_draw.h"
|
||||||
|
#include "../r_patch.h"
|
||||||
#include "../p_setup.h"
|
#include "../p_setup.h"
|
||||||
|
|
||||||
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
|
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
#include "../p_setup.h"
|
#include "../p_setup.h"
|
||||||
#include "../r_local.h"
|
#include "../r_local.h"
|
||||||
|
#include "../r_patch.h"
|
||||||
#include "../r_bsp.h"
|
#include "../r_bsp.h"
|
||||||
#include "../d_clisrv.h"
|
#include "../d_clisrv.h"
|
||||||
#include "../w_wad.h"
|
#include "../w_wad.h"
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "r_data.h"
|
#include "r_data.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
|
#include "r_patch.h"
|
||||||
#include "r_sky.h"
|
#include "r_sky.h"
|
||||||
#include "r_draw.h"
|
#include "r_draw.h"
|
||||||
|
|
||||||
|
|
746
src/r_data.c
746
src/r_data.c
|
@ -9,7 +9,7 @@
|
||||||
// See the 'LICENSE' file for more details.
|
// See the 'LICENSE' file for more details.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/// \file r_data.c
|
/// \file r_data.c
|
||||||
/// \brief Preparation of data for rendering,generation of lookups, caching, retrieval by name
|
/// \brief Preparation of data for rendering, generation of lookups, caching, retrieval by name
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "g_game.h"
|
#include "g_game.h"
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
#include "m_misc.h"
|
#include "m_misc.h"
|
||||||
#include "r_data.h"
|
#include "r_data.h"
|
||||||
|
#include "r_patch.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
#include "p_setup.h" // levelflats
|
#include "p_setup.h" // levelflats
|
||||||
|
@ -41,28 +42,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PNG
|
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#ifndef _LARGEFILE64_SOURCE
|
|
||||||
#define _LARGEFILE64_SOURCE
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _LFS64_LARGEFILE
|
|
||||||
#define _LFS64_LARGEFILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _FILE_OFFSET_BITS
|
|
||||||
#define _FILE_OFFSET_BITS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "png.h"
|
|
||||||
#ifndef PNG_READ_SUPPORTED
|
|
||||||
#undef HAVE_PNG
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Texture definition.
|
// Texture definition.
|
||||||
// Each texture is composed of one or more patches,
|
// Each texture is composed of one or more patches,
|
||||||
|
@ -2519,724 +2498,3 @@ void R_PrecacheLevel(void)
|
||||||
"texturememory: %s k\n"
|
"texturememory: %s k\n"
|
||||||
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
|
"spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// R_CheckIfPatch
|
|
||||||
//
|
|
||||||
// Returns true if the lump is a valid patch.
|
|
||||||
//
|
|
||||||
boolean R_CheckIfPatch(lumpnum_t lump)
|
|
||||||
{
|
|
||||||
size_t size;
|
|
||||||
INT16 width, height;
|
|
||||||
patch_t *patch;
|
|
||||||
boolean result;
|
|
||||||
|
|
||||||
size = W_LumpLength(lump);
|
|
||||||
|
|
||||||
// minimum length of a valid Doom patch
|
|
||||||
if (size < 13)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC);
|
|
||||||
|
|
||||||
width = SHORT(patch->width);
|
|
||||||
height = SHORT(patch->height);
|
|
||||||
|
|
||||||
result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4));
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
// The dimensions seem like they might be valid for a patch, so
|
|
||||||
// check the column directory for extra security. All columns
|
|
||||||
// must begin after the column directory, and none of them must
|
|
||||||
// point past the end of the patch.
|
|
||||||
INT16 x;
|
|
||||||
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
UINT32 ofs = LONG(patch->columnofs[x]);
|
|
||||||
|
|
||||||
// Need one byte for an empty column (but there's patches that don't know that!)
|
|
||||||
if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size)
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_TextureToFlat
|
|
||||||
//
|
|
||||||
// Convert a texture to a flat.
|
|
||||||
//
|
|
||||||
void R_TextureToFlat(size_t tex, UINT8 *flat)
|
|
||||||
{
|
|
||||||
texture_t *texture = textures[tex];
|
|
||||||
|
|
||||||
fixed_t col, ofs;
|
|
||||||
column_t *column;
|
|
||||||
UINT8 *desttop, *dest, *deststop;
|
|
||||||
UINT8 *source;
|
|
||||||
|
|
||||||
// yea
|
|
||||||
R_CheckTextureCache(tex);
|
|
||||||
|
|
||||||
desttop = flat;
|
|
||||||
deststop = desttop + (texture->width * texture->height);
|
|
||||||
|
|
||||||
for (col = 0; col < texture->width; col++, desttop++)
|
|
||||||
{
|
|
||||||
// no post_t info
|
|
||||||
if (!texture->holes)
|
|
||||||
{
|
|
||||||
column = (column_t *)(R_GetColumn(tex, col));
|
|
||||||
source = (UINT8 *)(column);
|
|
||||||
dest = desttop;
|
|
||||||
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
|
|
||||||
{
|
|
||||||
if (source[ofs] != TRANSPARENTPIXEL)
|
|
||||||
*dest = source[ofs];
|
|
||||||
dest += texture->width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
|
||||||
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
|
|
||||||
while (column->topdelta != 0xff)
|
|
||||||
{
|
|
||||||
topdelta = column->topdelta;
|
|
||||||
if (topdelta <= prevdelta)
|
|
||||||
topdelta += prevdelta;
|
|
||||||
prevdelta = topdelta;
|
|
||||||
|
|
||||||
dest = desttop + (topdelta * texture->width);
|
|
||||||
source = (UINT8 *)column + 3;
|
|
||||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
|
||||||
{
|
|
||||||
if (source[ofs] != TRANSPARENTPIXEL)
|
|
||||||
*dest = source[ofs];
|
|
||||||
dest += texture->width;
|
|
||||||
}
|
|
||||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_PatchToFlat
|
|
||||||
//
|
|
||||||
// Convert a patch to a flat.
|
|
||||||
//
|
|
||||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat)
|
|
||||||
{
|
|
||||||
fixed_t col, ofs;
|
|
||||||
column_t *column;
|
|
||||||
UINT8 *desttop, *dest, *deststop;
|
|
||||||
UINT8 *source;
|
|
||||||
|
|
||||||
desttop = flat;
|
|
||||||
deststop = desttop + (SHORT(patch->width) * SHORT(patch->height));
|
|
||||||
|
|
||||||
for (col = 0; col < SHORT(patch->width); col++, desttop++)
|
|
||||||
{
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col]));
|
|
||||||
|
|
||||||
while (column->topdelta != 0xff)
|
|
||||||
{
|
|
||||||
topdelta = column->topdelta;
|
|
||||||
if (topdelta <= prevdelta)
|
|
||||||
topdelta += prevdelta;
|
|
||||||
prevdelta = topdelta;
|
|
||||||
|
|
||||||
dest = desttop + (topdelta * SHORT(patch->width));
|
|
||||||
source = (UINT8 *)(column) + 3;
|
|
||||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
|
||||||
{
|
|
||||||
*dest = source[ofs];
|
|
||||||
dest += SHORT(patch->width);
|
|
||||||
}
|
|
||||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_PatchToFlat_16bpp
|
|
||||||
//
|
|
||||||
// Convert a patch to a 16-bit flat.
|
|
||||||
//
|
|
||||||
void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip)
|
|
||||||
{
|
|
||||||
fixed_t col, ofs;
|
|
||||||
column_t *column;
|
|
||||||
UINT16 *desttop, *dest, *deststop;
|
|
||||||
UINT8 *source;
|
|
||||||
|
|
||||||
desttop = raw;
|
|
||||||
deststop = desttop + (SHORT(patch->width) * SHORT(patch->height));
|
|
||||||
|
|
||||||
for (col = 0; col < SHORT(patch->width); col++, desttop++)
|
|
||||||
{
|
|
||||||
INT32 topdelta, prevdelta = -1;
|
|
||||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-col) : col]));
|
|
||||||
while (column->topdelta != 0xff)
|
|
||||||
{
|
|
||||||
topdelta = column->topdelta;
|
|
||||||
if (topdelta <= prevdelta)
|
|
||||||
topdelta += prevdelta;
|
|
||||||
prevdelta = topdelta;
|
|
||||||
dest = desttop + (topdelta * SHORT(patch->width));
|
|
||||||
source = (UINT8 *)(column) + 3;
|
|
||||||
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
|
|
||||||
{
|
|
||||||
*dest = source[ofs];
|
|
||||||
dest += SHORT(patch->width);
|
|
||||||
}
|
|
||||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_FlatToPatch
|
|
||||||
//
|
|
||||||
// Convert a flat to a patch.
|
|
||||||
//
|
|
||||||
static unsigned char imgbuf[1<<26];
|
|
||||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency)
|
|
||||||
{
|
|
||||||
UINT32 x, y;
|
|
||||||
UINT8 *img;
|
|
||||||
UINT8 *imgptr = imgbuf;
|
|
||||||
UINT8 *colpointers, *startofspan;
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
// Write image size and offset
|
|
||||||
WRITEINT16(imgptr, width);
|
|
||||||
WRITEINT16(imgptr, height);
|
|
||||||
WRITEINT16(imgptr, leftoffset);
|
|
||||||
WRITEINT16(imgptr, topoffset);
|
|
||||||
|
|
||||||
// Leave placeholder to column pointers
|
|
||||||
colpointers = imgptr;
|
|
||||||
imgptr += width*4;
|
|
||||||
|
|
||||||
// Write columns
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
int lastStartY = 0;
|
|
||||||
int spanSize = 0;
|
|
||||||
startofspan = NULL;
|
|
||||||
|
|
||||||
// Write column pointer
|
|
||||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
|
||||||
|
|
||||||
// Write pixels
|
|
||||||
for (y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
UINT8 paletteIndex = raw[((y * width) + x)];
|
|
||||||
boolean opaque = transparency ? (paletteIndex != TRANSPARENTPIXEL) : true;
|
|
||||||
|
|
||||||
// End span if we have a transparent pixel
|
|
||||||
if (!opaque)
|
|
||||||
{
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
startofspan = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start new column if we need to
|
|
||||||
if (!startofspan || spanSize == 255)
|
|
||||||
{
|
|
||||||
int writeY = y;
|
|
||||||
|
|
||||||
// If we reached the span size limit, finish the previous span
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
|
|
||||||
if (y > 254)
|
|
||||||
{
|
|
||||||
// Make sure we're aligned to 254
|
|
||||||
if (lastStartY < 254)
|
|
||||||
{
|
|
||||||
WRITEUINT8(imgptr, 254);
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
imgptr += 2;
|
|
||||||
lastStartY = 254;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write stopgap empty spans if needed
|
|
||||||
writeY = y - lastStartY;
|
|
||||||
|
|
||||||
while (writeY > 254)
|
|
||||||
{
|
|
||||||
WRITEUINT8(imgptr, 254);
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
imgptr += 2;
|
|
||||||
writeY -= 254;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startofspan = imgptr;
|
|
||||||
WRITEUINT8(imgptr, writeY);
|
|
||||||
imgptr += 2;
|
|
||||||
spanSize = 0;
|
|
||||||
|
|
||||||
lastStartY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the pixel
|
|
||||||
WRITEUINT8(imgptr, paletteIndex);
|
|
||||||
spanSize++;
|
|
||||||
startofspan[1] = spanSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
|
|
||||||
WRITEUINT8(imgptr, 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = imgptr-imgbuf;
|
|
||||||
img = Z_Malloc(size, PU_STATIC, NULL);
|
|
||||||
memcpy(img, imgbuf, size);
|
|
||||||
|
|
||||||
Z_Free(raw);
|
|
||||||
|
|
||||||
if (destsize != NULL)
|
|
||||||
*destsize = size;
|
|
||||||
return (patch_t *)img;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_FlatToPatch_16bpp
|
|
||||||
//
|
|
||||||
// Convert a 16-bit flat to a patch.
|
|
||||||
//
|
|
||||||
patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size)
|
|
||||||
{
|
|
||||||
UINT32 x, y;
|
|
||||||
UINT8 *img;
|
|
||||||
UINT8 *imgptr = imgbuf;
|
|
||||||
UINT8 *colpointers, *startofspan;
|
|
||||||
|
|
||||||
if (!raw)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// Write image size and offset
|
|
||||||
WRITEINT16(imgptr, width);
|
|
||||||
WRITEINT16(imgptr, height);
|
|
||||||
// no offsets
|
|
||||||
WRITEINT16(imgptr, 0);
|
|
||||||
WRITEINT16(imgptr, 0);
|
|
||||||
|
|
||||||
// Leave placeholder to column pointers
|
|
||||||
colpointers = imgptr;
|
|
||||||
imgptr += width*4;
|
|
||||||
|
|
||||||
// Write columns
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
int lastStartY = 0;
|
|
||||||
int spanSize = 0;
|
|
||||||
startofspan = NULL;
|
|
||||||
|
|
||||||
// Write column pointer
|
|
||||||
WRITEINT32(colpointers, imgptr - imgbuf);
|
|
||||||
|
|
||||||
// Write pixels
|
|
||||||
for (y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
UINT16 pixel = raw[((y * width) + x)];
|
|
||||||
UINT8 paletteIndex = (pixel & 0xFF);
|
|
||||||
UINT8 opaque = (pixel != 0xFF00); // If 1, we have a pixel
|
|
||||||
|
|
||||||
// End span if we have a transparent pixel
|
|
||||||
if (!opaque)
|
|
||||||
{
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
startofspan = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start new column if we need to
|
|
||||||
if (!startofspan || spanSize == 255)
|
|
||||||
{
|
|
||||||
int writeY = y;
|
|
||||||
|
|
||||||
// If we reached the span size limit, finish the previous span
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
|
|
||||||
if (y > 254)
|
|
||||||
{
|
|
||||||
// Make sure we're aligned to 254
|
|
||||||
if (lastStartY < 254)
|
|
||||||
{
|
|
||||||
WRITEUINT8(imgptr, 254);
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
imgptr += 2;
|
|
||||||
lastStartY = 254;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write stopgap empty spans if needed
|
|
||||||
writeY = y - lastStartY;
|
|
||||||
|
|
||||||
while (writeY > 254)
|
|
||||||
{
|
|
||||||
WRITEUINT8(imgptr, 254);
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
imgptr += 2;
|
|
||||||
writeY -= 254;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startofspan = imgptr;
|
|
||||||
WRITEUINT8(imgptr, writeY);
|
|
||||||
imgptr += 2;
|
|
||||||
spanSize = 0;
|
|
||||||
|
|
||||||
lastStartY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the pixel
|
|
||||||
WRITEUINT8(imgptr, paletteIndex);
|
|
||||||
spanSize++;
|
|
||||||
startofspan[1] = spanSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startofspan)
|
|
||||||
WRITEUINT8(imgptr, 0);
|
|
||||||
|
|
||||||
WRITEUINT8(imgptr, 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = imgptr-imgbuf;
|
|
||||||
img = Z_Malloc(*size, PU_STATIC, NULL);
|
|
||||||
memcpy(img, imgbuf, *size);
|
|
||||||
return (patch_t *)img;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NO_PNG_LUMPS
|
|
||||||
//
|
|
||||||
// R_IsLumpPNG
|
|
||||||
//
|
|
||||||
// Returns true if the lump is a valid PNG.
|
|
||||||
//
|
|
||||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s)
|
|
||||||
{
|
|
||||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
|
||||||
return false;
|
|
||||||
// Check for PNG file signature using memcmp
|
|
||||||
// As it may be faster on CPUs with slow unaligned memory access
|
|
||||||
// Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
|
||||||
return (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_PNG
|
|
||||||
|
|
||||||
#if PNG_LIBPNG_VER_DLLNUM < 14
|
|
||||||
typedef PNG_CONST png_byte *png_const_bytep;
|
|
||||||
#endif
|
|
||||||
typedef struct {
|
|
||||||
png_const_bytep buffer;
|
|
||||||
png_uint_32 bufsize;
|
|
||||||
png_uint_32 current_pos;
|
|
||||||
} png_io_t;
|
|
||||||
|
|
||||||
static void PNG_IOReader(png_structp png_ptr, png_bytep data, png_size_t length)
|
|
||||||
{
|
|
||||||
png_io_t *f = png_get_io_ptr(png_ptr);
|
|
||||||
if (length > (f->bufsize - f->current_pos))
|
|
||||||
png_error(png_ptr, "PNG_IOReader: buffer overrun");
|
|
||||||
memcpy(data, f->buffer + f->current_pos, length);
|
|
||||||
f->current_pos += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char name[4];
|
|
||||||
void *data;
|
|
||||||
size_t size;
|
|
||||||
} png_chunk_t;
|
|
||||||
|
|
||||||
static png_byte *chunkname = NULL;
|
|
||||||
static png_chunk_t chunk;
|
|
||||||
|
|
||||||
static int PNG_ChunkReader(png_structp png_ptr, png_unknown_chunkp chonk)
|
|
||||||
{
|
|
||||||
(void)png_ptr;
|
|
||||||
if (!memcmp(chonk->name, chunkname, 4))
|
|
||||||
{
|
|
||||||
memcpy(chunk.name, chonk->name, 4);
|
|
||||||
chunk.size = chonk->size;
|
|
||||||
chunk.data = Z_Malloc(chunk.size, PU_STATIC, NULL);
|
|
||||||
memcpy(chunk.data, chonk->data, chunk.size);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PNG_error(png_structp PNG, png_const_charp pngtext)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "libpng error at %p: %s", PNG, pngtext);
|
|
||||||
//I_Error("libpng error at %p: %s", PNG, pngtext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PNG_warn(png_structp PNG, png_const_charp pngtext)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static png_bytep *PNG_Read(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
|
|
||||||
{
|
|
||||||
png_structp png_ptr;
|
|
||||||
png_infop png_info_ptr;
|
|
||||||
png_uint_32 width, height;
|
|
||||||
int bit_depth, color_type;
|
|
||||||
png_uint_32 y;
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
jmp_buf jmpbuf;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_io_t png_io;
|
|
||||||
png_bytep *row_pointers;
|
|
||||||
|
|
||||||
png_byte grAb_chunk[5] = {'g', 'r', 'A', 'b', (png_byte)'\0'};
|
|
||||||
png_voidp *user_chunk_ptr;
|
|
||||||
|
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
|
|
||||||
if (!png_ptr)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
png_info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
if (!png_info_ptr)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "PNG_Load: Error on allocate for libpng\n");
|
|
||||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
if (setjmp(jmpbuf))
|
|
||||||
#else
|
|
||||||
if (setjmp(png_jmpbuf(png_ptr)))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
//CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename);
|
|
||||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// set our own read_function
|
|
||||||
png_io.buffer = (png_const_bytep)png;
|
|
||||||
png_io.bufsize = size;
|
|
||||||
png_io.current_pos = 0;
|
|
||||||
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
|
|
||||||
|
|
||||||
memset(&chunk, 0x00, sizeof(png_chunk_t));
|
|
||||||
chunkname = grAb_chunk; // I want to read a grAb chunk
|
|
||||||
|
|
||||||
user_chunk_ptr = png_get_user_chunk_ptr(png_ptr);
|
|
||||||
png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr, PNG_ChunkReader);
|
|
||||||
png_set_keep_unknown_chunks(png_ptr, 2, chunkname, 1);
|
|
||||||
|
|
||||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
|
||||||
png_set_user_limits(png_ptr, 2048, 2048);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_read_info(png_ptr, png_info_ptr);
|
|
||||||
png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (bit_depth == 16)
|
|
||||||
png_set_strip_16(png_ptr);
|
|
||||||
|
|
||||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
||||||
png_set_gray_to_rgb(png_ptr);
|
|
||||||
else if (color_type == PNG_COLOR_TYPE_PALETTE)
|
|
||||||
png_set_palette_to_rgb(png_ptr);
|
|
||||||
|
|
||||||
if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_tRNS))
|
|
||||||
png_set_tRNS_to_alpha(png_ptr);
|
|
||||||
else if (color_type != PNG_COLOR_TYPE_RGB_ALPHA && color_type != PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
||||||
{
|
|
||||||
#if PNG_LIBPNG_VER < 10207
|
|
||||||
png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER);
|
|
||||||
#else
|
|
||||||
png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
png_read_update_info(png_ptr, png_info_ptr);
|
|
||||||
|
|
||||||
// Read the image
|
|
||||||
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
|
|
||||||
for (y = 0; y < height; y++)
|
|
||||||
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, png_info_ptr));
|
|
||||||
png_read_image(png_ptr, row_pointers);
|
|
||||||
|
|
||||||
// Read grAB chunk
|
|
||||||
if ((topoffset || leftoffset) && (chunk.data != NULL))
|
|
||||||
{
|
|
||||||
INT32 *offsets = (INT32 *)chunk.data;
|
|
||||||
// read left offset
|
|
||||||
if (leftoffset != NULL)
|
|
||||||
*leftoffset = (INT16)BIGENDIAN_LONG(*offsets);
|
|
||||||
offsets++;
|
|
||||||
// read top offset
|
|
||||||
if (topoffset != NULL)
|
|
||||||
*topoffset = (INT16)BIGENDIAN_LONG(*offsets);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bye
|
|
||||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
|
||||||
if (chunk.data)
|
|
||||||
Z_Free(chunk.data);
|
|
||||||
|
|
||||||
*w = (INT32)width;
|
|
||||||
*h = (INT32)height;
|
|
||||||
return row_pointers;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a PNG to a raw image.
|
|
||||||
static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size)
|
|
||||||
{
|
|
||||||
UINT8 *flat;
|
|
||||||
png_uint_32 x, y;
|
|
||||||
png_bytep *row_pointers = PNG_Read(png, w, h, topoffset, leftoffset, size);
|
|
||||||
png_uint_32 width = *w, height = *h;
|
|
||||||
|
|
||||||
if (!row_pointers)
|
|
||||||
I_Error("PNG_RawConvert: conversion failed");
|
|
||||||
|
|
||||||
// Convert the image to 8bpp
|
|
||||||
flat = Z_Malloc(width * height, PU_LEVEL, NULL);
|
|
||||||
memset(flat, TRANSPARENTPIXEL, width * height);
|
|
||||||
for (y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
png_bytep row = row_pointers[y];
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
png_bytep px = &(row[x * 4]);
|
|
||||||
if ((UINT8)px[3])
|
|
||||||
flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(row_pointers);
|
|
||||||
|
|
||||||
return flat;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_PNGToFlat
|
|
||||||
//
|
|
||||||
// Convert a PNG to a flat.
|
|
||||||
//
|
|
||||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size)
|
|
||||||
{
|
|
||||||
return PNG_RawConvert(png, width, height, NULL, NULL, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_PNGToPatch
|
|
||||||
//
|
|
||||||
// Convert a PNG to a patch.
|
|
||||||
//
|
|
||||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency)
|
|
||||||
{
|
|
||||||
UINT16 width, height;
|
|
||||||
INT16 topoffset = 0, leftoffset = 0;
|
|
||||||
UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size);
|
|
||||||
|
|
||||||
if (!raw)
|
|
||||||
I_Error("R_PNGToPatch: conversion failed");
|
|
||||||
|
|
||||||
return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size)
|
|
||||||
{
|
|
||||||
png_structp png_ptr;
|
|
||||||
png_infop png_info_ptr;
|
|
||||||
png_uint_32 w, h;
|
|
||||||
int bit_depth, color_type;
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
jmp_buf jmpbuf;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_io_t png_io;
|
|
||||||
|
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
|
||||||
PNG_error, PNG_warn);
|
|
||||||
if (!png_ptr)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
png_info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
if (!png_info_ptr)
|
|
||||||
{
|
|
||||||
CONS_Debug(DBG_RENDER, "PNG_Load: Error on allocate for libpng\n");
|
|
||||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
if (setjmp(jmpbuf))
|
|
||||||
#else
|
|
||||||
if (setjmp(png_jmpbuf(png_ptr)))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
//CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename);
|
|
||||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#ifdef USE_FAR_KEYWORD
|
|
||||||
png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// set our own read_function
|
|
||||||
png_io.buffer = (png_bytep)png;
|
|
||||||
png_io.bufsize = size;
|
|
||||||
png_io.current_pos = 0;
|
|
||||||
png_set_read_fn(png_ptr, &png_io, PNG_IOReader);
|
|
||||||
|
|
||||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
|
||||||
png_set_user_limits(png_ptr, 2048, 2048);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_read_info(png_ptr, png_info_ptr);
|
|
||||||
|
|
||||||
png_get_IHDR(png_ptr, png_info_ptr, &w, &h, &bit_depth, &color_type,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
|
|
||||||
// okay done. stop.
|
|
||||||
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
|
|
||||||
|
|
||||||
*width = (INT32)w;
|
|
||||||
*height = (INT32)h;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
18
src/r_data.h
18
src/r_data.h
|
@ -159,24 +159,6 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
||||||
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
||||||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||||
|
|
||||||
boolean R_CheckIfPatch(lumpnum_t lump);
|
|
||||||
void R_TextureToFlat(size_t tex, UINT8 *flat);
|
|
||||||
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
|
||||||
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
|
|
||||||
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip);
|
|
||||||
patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_PNG_LUMPS
|
|
||||||
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
|
|
||||||
|
|
||||||
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size);
|
|
||||||
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
|
|
||||||
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern INT32 numtextures;
|
extern INT32 numtextures;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
15
src/r_defs.h
15
src/r_defs.h
|
@ -732,7 +732,7 @@ typedef struct
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Rotated sprite 0-360
|
// rotsprite
|
||||||
#ifdef ROTSPRITE
|
#ifdef ROTSPRITE
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -742,21 +742,8 @@ typedef struct
|
||||||
aatree_t *hardware_patch[8];
|
aatree_t *hardware_patch[8];
|
||||||
#endif
|
#endif
|
||||||
} rotsprite_t;
|
} rotsprite_t;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
INT32 x, y;
|
|
||||||
} spriteframepivot_t;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
spriteframepivot_t pivot[64];
|
|
||||||
#endif
|
|
||||||
boolean available;
|
|
||||||
} spriteinfo_t;
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SRF_SINGLE = 0, // 0-angle for all rotations
|
SRF_SINGLE = 0, // 0-angle for all rotations
|
||||||
|
|
1280
src/r_patch.c
Normal file
1280
src/r_patch.c
Normal file
File diff suppressed because it is too large
Load diff
66
src/r_patch.h
Normal file
66
src/r_patch.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// SONIC ROBO BLAST 2
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
|
// Copyright (C) 1999-2018 by Sonic Team Junior.
|
||||||
|
//
|
||||||
|
// This program is free software distributed under the
|
||||||
|
// terms of the GNU General Public License, version 2.
|
||||||
|
// See the 'LICENSE' file for more details.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/// \file r_patch.h
|
||||||
|
/// \brief Patch generation.
|
||||||
|
|
||||||
|
#ifndef __R_PATCH__
|
||||||
|
#define __R_PATCH__
|
||||||
|
|
||||||
|
#include "r_defs.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
|
||||||
|
// structs
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
INT32 x, y;
|
||||||
|
} spriteframepivot_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
spriteframepivot_t pivot[64];
|
||||||
|
#endif
|
||||||
|
boolean available;
|
||||||
|
} spriteinfo_t;
|
||||||
|
|
||||||
|
extern spriteinfo_t spriteinfo[NUMSPRITES];
|
||||||
|
|
||||||
|
// patches, flats, textures...
|
||||||
|
boolean R_CheckIfPatch(lumpnum_t lump);
|
||||||
|
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
|
||||||
|
|
||||||
|
void R_TextureToFlat(size_t tex, UINT8 *flat);
|
||||||
|
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
|
||||||
|
void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip);
|
||||||
|
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
|
||||||
|
patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size);
|
||||||
|
|
||||||
|
// png
|
||||||
|
#ifndef NO_PNG_LUMPS
|
||||||
|
UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size);
|
||||||
|
patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency);
|
||||||
|
boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// spriteinfo
|
||||||
|
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
|
||||||
|
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
|
||||||
|
|
||||||
|
// rotsprite
|
||||||
|
#ifdef ROTSPRITE
|
||||||
|
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
|
||||||
|
extern fixed_t cosang2rad[ROTANGLES];
|
||||||
|
extern fixed_t sinang2rad[ROTANGLES];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __R_PATCH__
|
484
src/r_things.c
484
src/r_things.c
|
@ -24,6 +24,7 @@
|
||||||
#include "i_video.h" // rendermode
|
#include "i_video.h" // rendermode
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
|
#include "r_patch.h"
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "p_tick.h"
|
#include "p_tick.h"
|
||||||
|
@ -74,11 +75,6 @@ INT16 screenheightarray[MAXVIDWIDTH];
|
||||||
|
|
||||||
spriteinfo_t spriteinfo[NUMSPRITES];
|
spriteinfo_t spriteinfo[NUMSPRITES];
|
||||||
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
static fixed_t cosang2rad[ROTANGLES];
|
|
||||||
static fixed_t sinang2rad[ROTANGLES];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// INITIALIZATION FUNCTIONS
|
// INITIALIZATION FUNCTIONS
|
||||||
//
|
//
|
||||||
|
@ -219,199 +215,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ROTSPRITE
|
#ifdef ROTSPRITE
|
||||||
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip)
|
|
||||||
{
|
|
||||||
UINT32 i;
|
|
||||||
INT32 angle;
|
|
||||||
patch_t *patch;
|
|
||||||
patch_t *newpatch;
|
|
||||||
UINT16 *rawsrc, *rawdst;
|
|
||||||
size_t size, size2;
|
|
||||||
INT32 bflip = ((flip != 0x00) ? -1 : 1);
|
|
||||||
|
|
||||||
#define SPRITE_XCENTER (width / 2)
|
|
||||||
#define SPRITE_YCENTER (height / 2)
|
|
||||||
#define ROTSPRITE_XCENTER (newwidth / 2)
|
|
||||||
#define ROTSPRITE_YCENTER (newheight / 2)
|
|
||||||
|
|
||||||
if (!sprframe->rotsprite.cached[rot])
|
|
||||||
{
|
|
||||||
INT32 dx,dy;
|
|
||||||
INT32 px,py;
|
|
||||||
INT32 width,height;
|
|
||||||
fixed_t ca, sa;
|
|
||||||
lumpnum_t lump = sprframe->lumppat[rot];
|
|
||||||
|
|
||||||
if (lump == LUMPERROR)
|
|
||||||
return;
|
|
||||||
// Because there's something wrong with SPR_DFLM, I guess
|
|
||||||
if (!R_CheckIfPatch(lump))
|
|
||||||
return;
|
|
||||||
|
|
||||||
patch = (patch_t *)W_CachePatchNum(lump, PU_STATIC);
|
|
||||||
width = patch->width;
|
|
||||||
height = patch->height;
|
|
||||||
|
|
||||||
// rotation pivot
|
|
||||||
px = SPRITE_XCENTER;
|
|
||||||
py = SPRITE_YCENTER;
|
|
||||||
|
|
||||||
// get correct sprite info for sprite
|
|
||||||
if (sprinfo == NULL)
|
|
||||||
sprinfo = &spriteinfo[sprnum];
|
|
||||||
if (sprinfo->available)
|
|
||||||
{
|
|
||||||
px = sprinfo->pivot[frame].x;
|
|
||||||
py = sprinfo->pivot[frame].y;
|
|
||||||
}
|
|
||||||
if (flip)
|
|
||||||
px = width - px;
|
|
||||||
|
|
||||||
// Draw the sprite to a temporary buffer.
|
|
||||||
size = (width*height);
|
|
||||||
rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL);
|
|
||||||
|
|
||||||
// can't memset here
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
rawsrc[i] = 0xFF00;
|
|
||||||
|
|
||||||
R_PatchToFlat_16bpp(patch, rawsrc, (flip != 0x00));
|
|
||||||
|
|
||||||
// Don't cache angle = 0, that would be stoopid
|
|
||||||
for (angle = 1; angle < ROTANGLES; angle++)
|
|
||||||
{
|
|
||||||
INT32 newwidth, newheight;
|
|
||||||
|
|
||||||
ca = cosang2rad[angle];
|
|
||||||
sa = sinang2rad[angle];
|
|
||||||
|
|
||||||
// Find the dimensions of the rotated patch.
|
|
||||||
{
|
|
||||||
INT32 w1 = abs(FixedMul(width << FRACBITS, ca) - FixedMul(height << FRACBITS, sa));
|
|
||||||
INT32 w2 = abs(FixedMul(-(width << FRACBITS), ca) - FixedMul(height << FRACBITS, sa));
|
|
||||||
INT32 h1 = abs(FixedMul(width << FRACBITS, sa) + FixedMul(height << FRACBITS, ca));
|
|
||||||
INT32 h2 = abs(FixedMul(-(width << FRACBITS), sa) + FixedMul(height << FRACBITS, ca));
|
|
||||||
w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2)));
|
|
||||||
w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2)));
|
|
||||||
h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2)));
|
|
||||||
h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2)));
|
|
||||||
newwidth = max(width, max(w1, w2));
|
|
||||||
newheight = max(height, max(h1, h2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// check boundaries
|
|
||||||
{
|
|
||||||
fixed_t top[2][2];
|
|
||||||
fixed_t bottom[2][2];
|
|
||||||
|
|
||||||
top[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS);
|
|
||||||
top[0][1] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS);
|
|
||||||
top[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS);
|
|
||||||
top[1][1] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS);
|
|
||||||
|
|
||||||
bottom[0][0] = FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS);
|
|
||||||
bottom[0][1] = -FixedMul((-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS);
|
|
||||||
bottom[1][0] = FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, ca) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, sa) + (px << FRACBITS);
|
|
||||||
bottom[1][1] = -FixedMul((newwidth-ROTSPRITE_XCENTER) << FRACBITS, sa) + FixedMul((newheight-ROTSPRITE_YCENTER) << FRACBITS, ca) + (py << FRACBITS);
|
|
||||||
|
|
||||||
top[0][0] >>= FRACBITS;
|
|
||||||
top[0][1] >>= FRACBITS;
|
|
||||||
top[1][0] >>= FRACBITS;
|
|
||||||
top[1][1] >>= FRACBITS;
|
|
||||||
|
|
||||||
bottom[0][0] >>= FRACBITS;
|
|
||||||
bottom[0][1] >>= FRACBITS;
|
|
||||||
bottom[1][0] >>= FRACBITS;
|
|
||||||
bottom[1][1] >>= FRACBITS;
|
|
||||||
|
|
||||||
#define BOUNDARYWCHECK(b) (b[0] < 0 || b[0] >= width)
|
|
||||||
#define BOUNDARYHCHECK(b) (b[1] < 0 || b[1] >= height)
|
|
||||||
#define BOUNDARYADJUST(x) x *= 2
|
|
||||||
// top left/right
|
|
||||||
if (BOUNDARYWCHECK(top[0]) || BOUNDARYWCHECK(top[1]))
|
|
||||||
BOUNDARYADJUST(newwidth);
|
|
||||||
// bottom left/right
|
|
||||||
else if (BOUNDARYWCHECK(bottom[0]) || BOUNDARYWCHECK(bottom[1]))
|
|
||||||
BOUNDARYADJUST(newwidth);
|
|
||||||
// top left/right
|
|
||||||
if (BOUNDARYHCHECK(top[0]) || BOUNDARYHCHECK(top[1]))
|
|
||||||
BOUNDARYADJUST(newheight);
|
|
||||||
// bottom left/right
|
|
||||||
else if (BOUNDARYHCHECK(bottom[0]) || BOUNDARYHCHECK(bottom[1]))
|
|
||||||
BOUNDARYADJUST(newheight);
|
|
||||||
#undef BOUNDARYWCHECK
|
|
||||||
#undef BOUNDARYHCHECK
|
|
||||||
#undef BOUNDARYADJUST
|
|
||||||
}
|
|
||||||
|
|
||||||
size2 = (newwidth * newheight);
|
|
||||||
if (!size2)
|
|
||||||
size2 = size;
|
|
||||||
|
|
||||||
rawdst = Z_Malloc(size2 * sizeof(UINT16), PU_STATIC, NULL);
|
|
||||||
|
|
||||||
// can't memset here
|
|
||||||
for (i = 0; i < size2; i++)
|
|
||||||
rawdst[i] = 0xFF00;
|
|
||||||
|
|
||||||
// Draw the rotated sprite to a temporary buffer.
|
|
||||||
for (dy = 0; dy < newheight; dy++)
|
|
||||||
{
|
|
||||||
for (dx = 0; dx < newwidth; dx++)
|
|
||||||
{
|
|
||||||
INT32 x = (dx-ROTSPRITE_XCENTER) << FRACBITS;
|
|
||||||
INT32 y = (dy-ROTSPRITE_YCENTER) << FRACBITS;
|
|
||||||
INT32 sx = FixedMul(x, ca) + FixedMul(y, sa) + (px << FRACBITS);
|
|
||||||
INT32 sy = -FixedMul(x, sa) + FixedMul(y, ca) + (py << FRACBITS);
|
|
||||||
sx >>= FRACBITS;
|
|
||||||
sy >>= FRACBITS;
|
|
||||||
if (sx >= 0 && sy >= 0 && sx < width && sy < height)
|
|
||||||
rawdst[(dy*newwidth)+dx] = rawsrc[(sy*width)+sx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// make patch
|
|
||||||
newpatch = R_FlatToPatch_16bpp(rawdst, newwidth, newheight, &size);
|
|
||||||
newpatch->leftoffset = (newpatch->width / 2) - ((SPRITE_XCENTER - patch->leftoffset) * bflip);
|
|
||||||
newpatch->topoffset = (newpatch->height / 2) - (SPRITE_YCENTER - patch->topoffset);
|
|
||||||
newpatch->leftoffset += (SPRITE_XCENTER - px);
|
|
||||||
newpatch->topoffset += (SPRITE_YCENTER - py);
|
|
||||||
|
|
||||||
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
|
|
||||||
if (rendermode != render_none) // not for psprite
|
|
||||||
newpatch->topoffset += 4;
|
|
||||||
|
|
||||||
// P_PrecacheLevel
|
|
||||||
if (devparm) spritememory += size;
|
|
||||||
|
|
||||||
#ifdef HWRENDER
|
|
||||||
if (rendermode == render_opengl)
|
|
||||||
{
|
|
||||||
GLPatch_t *grPatch = HWR_GetCachedGLRotSprite(sprframe->rotsprite.hardware_patch[rot], angle, newpatch);
|
|
||||||
HWR_MakePatch(newpatch, grPatch, &grPatch->mipmap, false);
|
|
||||||
sprframe->rotsprite.patch[rot][angle] = (patch_t *)grPatch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // HWRENDER
|
|
||||||
sprframe->rotsprite.patch[rot][angle] = newpatch;
|
|
||||||
|
|
||||||
// free rotated image data
|
|
||||||
Z_Free(rawdst);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This rotation is cached now
|
|
||||||
sprframe->rotsprite.cached[rot] = true;
|
|
||||||
|
|
||||||
// free image data
|
|
||||||
Z_Free(rawsrc);
|
|
||||||
Z_Free(patch);
|
|
||||||
}
|
|
||||||
#undef SPRITE_XCENTER
|
|
||||||
#undef SPRITE_YCENTER
|
|
||||||
#undef ROTSPRITE_XCENTER
|
|
||||||
#undef ROTSPRITE_YCENTER
|
|
||||||
}
|
|
||||||
|
|
||||||
static void R_FreeRotSprite(spritedef_t *spritedef)
|
static void R_FreeRotSprite(spritedef_t *spritedef)
|
||||||
{
|
{
|
||||||
UINT8 frame;
|
UINT8 frame;
|
||||||
|
@ -3637,288 +3440,3 @@ next_token:
|
||||||
|
|
||||||
#undef HUDNAMEWRITE
|
#undef HUDNAMEWRITE
|
||||||
#undef SYMBOLCONVERT
|
#undef SYMBOLCONVERT
|
||||||
|
|
||||||
// pain
|
|
||||||
static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
|
|
||||||
{
|
|
||||||
char *sprinfoToken;
|
|
||||||
size_t sprinfoTokenLength;
|
|
||||||
char *frameChar;
|
|
||||||
UINT8 frameFrame;
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
INT16 frameXPivot = 0;
|
|
||||||
INT16 frameYPivot = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Sprite identifier
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite frame should be");
|
|
||||||
}
|
|
||||||
sprinfoTokenLength = strlen(sprinfoToken);
|
|
||||||
if (sprinfoTokenLength != 1)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Invalid frame \"%s\"",sprinfoToken);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
frameChar = sprinfoToken;
|
|
||||||
|
|
||||||
frameFrame = R_Char2Frame(frameChar[0]);
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
|
|
||||||
// Left Curly Brace
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Missing sprite info");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (strcmp(sprinfoToken,"{")==0)
|
|
||||||
{
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info should be");
|
|
||||||
}
|
|
||||||
while (strcmp(sprinfoToken,"}")!=0)
|
|
||||||
{
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
if (stricmp(sprinfoToken, "XPIVOT")==0)
|
|
||||||
{
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
frameXPivot = atoi(sprinfoToken);
|
|
||||||
}
|
|
||||||
else if (stricmp(sprinfoToken, "YPIVOT")==0)
|
|
||||||
{
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
frameYPivot = atoi(sprinfoToken);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace should be");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set fields
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
info->pivot[frameFrame].x = frameXPivot;
|
|
||||||
info->pivot[frameFrame].y = frameYPivot;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void R_ParseSpriteInfo(boolean spr2)
|
|
||||||
{
|
|
||||||
spriteinfo_t *info;
|
|
||||||
char *sprinfoToken;
|
|
||||||
size_t sprinfoTokenLength;
|
|
||||||
char newSpriteName[5]; // no longer dynamically allocated
|
|
||||||
spritenum_t sprnum = NUMSPRITES;
|
|
||||||
playersprite_t spr2num = NUMPLAYERSPRITES;
|
|
||||||
INT32 i;
|
|
||||||
INT32 skinnumbers[MAXSKINS];
|
|
||||||
INT32 foundskins = 0;
|
|
||||||
|
|
||||||
// Sprite name
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite name should be");
|
|
||||||
}
|
|
||||||
sprinfoTokenLength = strlen(sprinfoToken);
|
|
||||||
if (sprinfoTokenLength != 4)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Sprite name \"%s\" isn't 4 characters long",sprinfoToken);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(&newSpriteName, 0, 5);
|
|
||||||
M_Memcpy(newSpriteName, sprinfoToken, sprinfoTokenLength);
|
|
||||||
// ^^ we've confirmed that the token is == 4 characters so it will never overflow a 5 byte char buffer
|
|
||||||
strupr(newSpriteName); // Just do this now so we don't have to worry about it
|
|
||||||
}
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
|
|
||||||
if (!spr2)
|
|
||||||
{
|
|
||||||
for (i = 0; i <= NUMSPRITES; i++)
|
|
||||||
{
|
|
||||||
if (i == NUMSPRITES)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unknown sprite name \"%s\"", newSpriteName);
|
|
||||||
if (!memcmp(newSpriteName,sprnames[i],4))
|
|
||||||
{
|
|
||||||
sprnum = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i <= NUMPLAYERSPRITES; i++)
|
|
||||||
{
|
|
||||||
if (i == NUMPLAYERSPRITES)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unknown sprite2 name \"%s\"", newSpriteName);
|
|
||||||
if (!memcmp(newSpriteName,spr2names[i],4))
|
|
||||||
{
|
|
||||||
spr2num = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate a spriteinfo
|
|
||||||
info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
|
|
||||||
info->available = true;
|
|
||||||
|
|
||||||
// Left Curly Brace
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where open curly brace for sprite \"%s\" should be",newSpriteName);
|
|
||||||
}
|
|
||||||
if (strcmp(sprinfoToken,"{")==0)
|
|
||||||
{
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where definition for sprite \"%s\" should be",newSpriteName);
|
|
||||||
}
|
|
||||||
while (strcmp(sprinfoToken,"}")!=0)
|
|
||||||
{
|
|
||||||
if (stricmp(sprinfoToken, "SKIN")==0)
|
|
||||||
{
|
|
||||||
INT32 skinnum;
|
|
||||||
char *skinName = NULL;
|
|
||||||
if (!spr2)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: \"SKIN\" token found outside of a sprite2 definition");
|
|
||||||
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
|
|
||||||
// Skin name
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where skin frame should be");
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy skin name yada yada
|
|
||||||
sprinfoTokenLength = strlen(sprinfoToken);
|
|
||||||
skinName = (char *)Z_Malloc((sprinfoTokenLength+1)*sizeof(char),PU_STATIC,NULL);
|
|
||||||
M_Memcpy(skinName,sprinfoToken,sprinfoTokenLength*sizeof(char));
|
|
||||||
skinName[sprinfoTokenLength] = '\0';
|
|
||||||
strlwr(skinName);
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
|
|
||||||
skinnum = R_SkinAvailable(skinName);
|
|
||||||
if (skinnum == -1)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unknown skin \"%s\"", skinName);
|
|
||||||
|
|
||||||
skinnumbers[foundskins] = skinnum;
|
|
||||||
foundskins++;
|
|
||||||
}
|
|
||||||
else if (stricmp(sprinfoToken, "FRAME")==0)
|
|
||||||
{
|
|
||||||
R_ParseSpriteInfoFrame(info);
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
if (spr2)
|
|
||||||
{
|
|
||||||
if (!foundskins)
|
|
||||||
I_Error("Error parsing SPRTINFO lump: No skins specified in this sprite2 definition");
|
|
||||||
for (i = 0; i < foundskins; i++)
|
|
||||||
{
|
|
||||||
skin_t *skin = &skins[skinnumbers[i]];
|
|
||||||
spriteinfo_t *sprinfo = skin->sprinfo;
|
|
||||||
M_Memcpy(&sprinfo[spr2num], info, sizeof(spriteinfo_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
M_Memcpy(&spriteinfo[sprnum], info, sizeof(spriteinfo_t));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\" in sprite %s",sprinfoToken,newSpriteName);
|
|
||||||
}
|
|
||||||
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
if (sprinfoToken == NULL)
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unexpected end of file where sprite info or right curly brace for sprite \"%s\" should be",newSpriteName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Expected \"{\" for sprite \"%s\", got \"%s\"",newSpriteName,sprinfoToken);
|
|
||||||
}
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
Z_Free(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is all just copy-pasted from R_ParseTEXTURESLump
|
|
||||||
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum)
|
|
||||||
{
|
|
||||||
char *sprinfoLump;
|
|
||||||
size_t sprinfoLumpLength;
|
|
||||||
char *sprinfoText;
|
|
||||||
char *sprinfoToken;
|
|
||||||
|
|
||||||
// Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll
|
|
||||||
// need to make a space of memory where I can ensure that it will terminate
|
|
||||||
// correctly. Start by loading the relevant data from the WAD.
|
|
||||||
sprinfoLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC);
|
|
||||||
// If that didn't exist, we have nothing to do here.
|
|
||||||
if (sprinfoLump == NULL) return;
|
|
||||||
// If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly.
|
|
||||||
sprinfoLumpLength = W_LumpLengthPwad(wadNum, lumpNum);
|
|
||||||
sprinfoText = (char *)Z_Malloc((sprinfoLumpLength+1)*sizeof(char),PU_STATIC,NULL);
|
|
||||||
// Now move the contents of the lump into this new location.
|
|
||||||
memmove(sprinfoText,sprinfoLump,sprinfoLumpLength);
|
|
||||||
// Make damn well sure the last character in our new memory location is \0.
|
|
||||||
sprinfoText[sprinfoLumpLength] = '\0';
|
|
||||||
// Finally, free up the memory from the first data load, because we really
|
|
||||||
// don't need it.
|
|
||||||
Z_Free(sprinfoLump);
|
|
||||||
|
|
||||||
sprinfoToken = M_GetToken(sprinfoText);
|
|
||||||
while (sprinfoToken != NULL)
|
|
||||||
{
|
|
||||||
if (!stricmp(sprinfoToken, "SPRITE") || !stricmp(sprinfoToken, "SPRITE2"))
|
|
||||||
{
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
R_ParseSpriteInfo(!stricmp(sprinfoToken, "SPRITE2"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
I_Error("Error parsing SPRTINFO lump: Unknown keyword \"%s\"", sprinfoToken);
|
|
||||||
sprinfoToken = M_GetToken(NULL);
|
|
||||||
}
|
|
||||||
Z_Free(sprinfoToken);
|
|
||||||
Z_Free((void *)sprinfoText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps)
|
|
||||||
{
|
|
||||||
lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo;
|
|
||||||
UINT16 i;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
for (i = 0; i < numlumps; i++, lumpinfo++)
|
|
||||||
{
|
|
||||||
name = lumpinfo->name;
|
|
||||||
// load SPRTINFO lumps
|
|
||||||
if (!stricmp(name, "SPRTINFO"))
|
|
||||||
R_ParseSPRTINFOLump(wadnum, i);
|
|
||||||
// load SPR_ lumps (as DEHACKED lump)
|
|
||||||
else if (!memcmp(name, "SPR_", 4))
|
|
||||||
DEH_LoadDehackedLumpPwad(wadnum, i, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
#include "r_plane.h"
|
#include "r_plane.h"
|
||||||
|
#include "r_patch.h"
|
||||||
#include "r_portal.h"
|
#include "r_portal.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
@ -52,10 +53,6 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
|
||||||
// (only sprites from namelist are added or replaced)
|
// (only sprites from namelist are added or replaced)
|
||||||
void R_AddSpriteDefs(UINT16 wadnum);
|
void R_AddSpriteDefs(UINT16 wadnum);
|
||||||
|
|
||||||
#ifdef ROTSPRITE
|
|
||||||
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//SoM: 6/5/2000: Light sprites correctly!
|
//SoM: 6/5/2000: Light sprites correctly!
|
||||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||||
void R_InitSprites(void);
|
void R_InitSprites(void);
|
||||||
|
@ -212,8 +209,6 @@ typedef struct vissprite_s
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
} vissprite_t;
|
} vissprite_t;
|
||||||
|
|
||||||
extern spriteinfo_t spriteinfo[NUMSPRITES];
|
|
||||||
|
|
||||||
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
||||||
// middle texture. This is used for sorting with sprites.
|
// middle texture. This is used for sorting with sprites.
|
||||||
typedef struct drawnode_s
|
typedef struct drawnode_s
|
||||||
|
@ -240,9 +235,6 @@ INT32 R_SkinAvailable(const char *name);
|
||||||
void R_PatchSkins(UINT16 wadnum);
|
void R_PatchSkins(UINT16 wadnum);
|
||||||
void R_AddSkins(UINT16 wadnum);
|
void R_AddSkins(UINT16 wadnum);
|
||||||
|
|
||||||
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
|
|
||||||
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
|
|
||||||
|
|
||||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);
|
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);
|
||||||
|
|
||||||
void R_InitDrawNodes(void);
|
void R_InitDrawNodes(void);
|
||||||
|
|
|
@ -277,6 +277,7 @@
|
||||||
<ClInclude Include="..\r_local.h" />
|
<ClInclude Include="..\r_local.h" />
|
||||||
<ClInclude Include="..\r_main.h" />
|
<ClInclude Include="..\r_main.h" />
|
||||||
<ClInclude Include="..\r_plane.h" />
|
<ClInclude Include="..\r_plane.h" />
|
||||||
|
<ClInclude Include="..\r_patch.h" />
|
||||||
<ClInclude Include="..\r_portal.h" />
|
<ClInclude Include="..\r_portal.h" />
|
||||||
<ClInclude Include="..\r_segs.h" />
|
<ClInclude Include="..\r_segs.h" />
|
||||||
<ClInclude Include="..\r_sky.h" />
|
<ClInclude Include="..\r_sky.h" />
|
||||||
|
@ -431,6 +432,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\r_main.c" />
|
<ClCompile Include="..\r_main.c" />
|
||||||
<ClCompile Include="..\r_plane.c" />
|
<ClCompile Include="..\r_plane.c" />
|
||||||
|
<ClCompile Include="..\r_patch.c" />
|
||||||
<ClCompile Include="..\r_portal.c" />
|
<ClCompile Include="..\r_portal.c" />
|
||||||
<ClCompile Include="..\r_segs.c" />
|
<ClCompile Include="..\r_segs.c" />
|
||||||
<ClCompile Include="..\r_sky.c" />
|
<ClCompile Include="..\r_sky.c" />
|
||||||
|
@ -482,4 +484,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -453,6 +453,9 @@
|
||||||
<ClInclude Include="..\hardware\hw_clip.h">
|
<ClInclude Include="..\hardware\hw_clip.h">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\r_patch.h">
|
||||||
|
<Filter>R_Rend</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\r_portal.h">
|
<ClInclude Include="..\r_portal.h">
|
||||||
<Filter>R_Rend</Filter>
|
<Filter>R_Rend</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -898,6 +901,9 @@
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\apng.c" />
|
<ClCompile Include="..\apng.c" />
|
||||||
|
<ClCompile Include="..\r_patch.c">
|
||||||
|
<Filter>R_Rend</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\r_portal.c">
|
<ClCompile Include="..\r_portal.c">
|
||||||
<Filter>R_Rend</Filter>
|
<Filter>R_Rend</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -907,4 +913,4 @@
|
||||||
<Filter>SDLApp</Filter>
|
<Filter>SDLApp</Filter>
|
||||||
</Image>
|
</Image>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
18
src/w_wad.c
18
src/w_wad.c
|
@ -1183,21 +1183,6 @@ void zerr(int ret)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NO_PNG_LUMPS
|
|
||||||
static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l)
|
|
||||||
{
|
|
||||||
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
|
||||||
return;
|
|
||||||
// Check for PNG file signature using memcmp
|
|
||||||
// As it may be faster on CPUs with slow unaligned memory access
|
|
||||||
// Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
|
||||||
if (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
|
|
||||||
{
|
|
||||||
I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .PNG - please convert to either Doom or Flat (raw) image format.", l, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Reads bytes from the head of a lump.
|
/** Reads bytes from the head of a lump.
|
||||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||||
*
|
*
|
||||||
|
@ -1240,7 +1225,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
#ifdef NO_PNG_LUMPS
|
#ifdef NO_PNG_LUMPS
|
||||||
{
|
{
|
||||||
size_t bytesread = fread(dest, 1, size, handle);
|
size_t bytesread = fread(dest, 1, size, handle);
|
||||||
ErrorIfPNG(dest, bytesread, wadfiles[wad]->filename, l->name2);
|
if (R_IsLumpPNG((UINT8 *)dest, bytesread))
|
||||||
|
I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", l->name2, wadfiles[wad]->filename);
|
||||||
return bytesread;
|
return bytesread;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -293,6 +293,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\r_main.c" />
|
<ClCompile Include="..\r_main.c" />
|
||||||
<ClCompile Include="..\r_plane.c" />
|
<ClCompile Include="..\r_plane.c" />
|
||||||
|
<ClCompile Include="..\r_patch.c" />
|
||||||
<ClCompile Include="..\r_portal.c" />
|
<ClCompile Include="..\r_portal.c" />
|
||||||
<ClCompile Include="..\r_segs.c" />
|
<ClCompile Include="..\r_segs.c" />
|
||||||
<ClCompile Include="..\r_sky.c" />
|
<ClCompile Include="..\r_sky.c" />
|
||||||
|
@ -444,6 +445,7 @@
|
||||||
<ClInclude Include="..\r_local.h" />
|
<ClInclude Include="..\r_local.h" />
|
||||||
<ClInclude Include="..\r_main.h" />
|
<ClInclude Include="..\r_main.h" />
|
||||||
<ClInclude Include="..\r_plane.h" />
|
<ClInclude Include="..\r_plane.h" />
|
||||||
|
<ClInclude Include="..\r_patch.h" />
|
||||||
<ClInclude Include="..\r_portal.h" />
|
<ClInclude Include="..\r_portal.h" />
|
||||||
<ClInclude Include="..\r_segs.h" />
|
<ClInclude Include="..\r_segs.h" />
|
||||||
<ClInclude Include="..\r_sky.h" />
|
<ClInclude Include="..\r_sky.h" />
|
||||||
|
@ -497,4 +499,4 @@
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -457,6 +457,9 @@
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\apng.c" />
|
<ClCompile Include="..\apng.c" />
|
||||||
|
<ClCompile Include="..\r_patch.c">
|
||||||
|
<Filter>R_Rend</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\r_portal.c">
|
<ClCompile Include="..\r_portal.c">
|
||||||
<Filter>R_Rend</Filter>
|
<Filter>R_Rend</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -862,6 +865,9 @@
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\apng.h" />
|
<ClInclude Include="..\apng.h" />
|
||||||
|
<ClInclude Include="..\r_patch.h">
|
||||||
|
<Filter>R_Rend</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\r_portal.h">
|
<ClInclude Include="..\r_portal.h">
|
||||||
<Filter>R_Rend</Filter>
|
<Filter>R_Rend</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -895,4 +901,4 @@
|
||||||
<Filter>A_Asm</Filter>
|
<Filter>A_Asm</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in a new issue