mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch 'rotsprite_i' into 'master'
Sprite rotation (resolves #183) Closes #183 See merge request STJr/SRB2Internal!430
This commit is contained in:
commit
3352f914d7
37 changed files with 2752 additions and 896 deletions
|
@ -123,6 +123,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_sky.c
|
||||
r_splats.c
|
||||
r_things.c
|
||||
r_patch.c
|
||||
r_portal.c
|
||||
|
||||
r_bsp.h
|
||||
|
@ -137,6 +138,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_splats.h
|
||||
r_state.h
|
||||
r_things.h
|
||||
r_patch.h
|
||||
r_portal.h
|
||||
)
|
||||
|
||||
|
|
|
@ -471,6 +471,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/r_sky.o \
|
||||
$(OBJDIR)/r_splats.o \
|
||||
$(OBJDIR)/r_things.o \
|
||||
$(OBJDIR)/r_patch.o \
|
||||
$(OBJDIR)/r_portal.o \
|
||||
$(OBJDIR)/screen.o \
|
||||
$(OBJDIR)/v_video.o \
|
||||
|
|
|
@ -791,7 +791,7 @@ static void resynch_read_player(resynch_pak *rsp)
|
|||
players[i].mo->scalespeed = LONG(rsp->scalespeed);
|
||||
|
||||
// And finally, SET THE MOBJ SKIN damn it.
|
||||
if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NGT0].numframes == 0))
|
||||
if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NFLY].numframes == 0))
|
||||
{
|
||||
players[i].mo->skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
players[i].mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; // this will be corrected by thinker to super flash
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef enum
|
|||
SF_DASHMODE = 1<<11, // Sonic Advance 2 style top speed increase?
|
||||
SF_FASTEDGE = 1<<12, // Faster edge teeter?
|
||||
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
|
||||
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
|
||||
// free up to and including 1<<31
|
||||
} skinflags_t;
|
||||
|
||||
|
|
295
src/dehacked.c
295
src/dehacked.c
|
@ -29,6 +29,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "r_data.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_sky.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
|
@ -803,50 +804,251 @@ static void readlight(MYFILE *f, INT32 num)
|
|||
|
||||
Z_Free(s);
|
||||
}
|
||||
#endif // HWRENDER
|
||||
|
||||
static void readspritelight(MYFILE *f, INT32 num)
|
||||
static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word, *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
char *lastline;
|
||||
|
||||
do
|
||||
{
|
||||
lastline = f->curpos;
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
value = searchvalue(s);
|
||||
// Set / reset word
|
||||
word = s;
|
||||
while ((*word == '\t') || (*word == ' '))
|
||||
word++;
|
||||
|
||||
word = strtok(s, " ");
|
||||
if (word)
|
||||
strupr(word);
|
||||
else
|
||||
break;
|
||||
|
||||
if (fastcmp(word, "LIGHTTYPE"))
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
{
|
||||
INT32 oldvar;
|
||||
for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++)
|
||||
;
|
||||
t_lspr[num] = &lspr[value];
|
||||
*(tmp-1) = '\0';
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
}
|
||||
else
|
||||
deh_warning("Sprite %d: unknown word '%s'", num, word);
|
||||
{
|
||||
// Get the part before the " "
|
||||
tmp = strchr(s, ' ');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
// Now get the part after
|
||||
tmp++;
|
||||
word2 = tmp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
strupr(word);
|
||||
value = atoi(word2); // used for numerical settings
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (fastcmp(word, "XPIVOT"))
|
||||
sprinfo->pivot[frame].x = value;
|
||||
else if (fastcmp(word, "YPIVOT"))
|
||||
sprinfo->pivot[frame].y = value;
|
||||
else if (fastcmp(word, "ROTAXIS"))
|
||||
sprinfo->pivot[frame].rotaxis = value;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
f->curpos = lastline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word, *word2;
|
||||
char *tmp;
|
||||
INT32 value;
|
||||
char *lastline;
|
||||
INT32 skinnumbers[MAXSKINS];
|
||||
INT32 foundskins = 0;
|
||||
|
||||
// allocate a spriteinfo
|
||||
spriteinfo_t *info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
|
||||
info->available = true;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if ((sprites != NULL) && (!sprite2))
|
||||
R_FreeSingleRotSprite(&sprites[num]);
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
lastline = f->curpos;
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
// Set / reset word
|
||||
word = s;
|
||||
while ((*word == '\t') || (*word == ' '))
|
||||
word++;
|
||||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
{
|
||||
*(tmp-1) = '\0';
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the part before the " "
|
||||
tmp = strchr(s, ' ');
|
||||
if (tmp)
|
||||
{
|
||||
*tmp = '\0';
|
||||
// Now get the part after
|
||||
tmp++;
|
||||
word2 = tmp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
strupr(word);
|
||||
value = atoi(word2); // used for numerical settings
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (fastcmp(word, "LIGHTTYPE"))
|
||||
{
|
||||
if (sprite2)
|
||||
deh_warning("Sprite2 %s: invalid word '%s'", spr2names[num], word);
|
||||
else
|
||||
{
|
||||
INT32 oldvar;
|
||||
for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++)
|
||||
;
|
||||
t_lspr[num] = &lspr[value];
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (fastcmp(word, "SKIN"))
|
||||
{
|
||||
INT32 skinnum = -1;
|
||||
if (!sprite2)
|
||||
{
|
||||
deh_warning("Sprite %s: %s keyword found outside of SPRITE2INFO block, ignoring", spr2names[num], word);
|
||||
continue;
|
||||
}
|
||||
|
||||
// make lowercase
|
||||
strlwr(word2);
|
||||
skinnum = R_SkinAvailable(word2);
|
||||
if (skinnum == -1)
|
||||
{
|
||||
deh_warning("Sprite2 %s: unknown skin %s", spr2names[num], word2);
|
||||
break;
|
||||
}
|
||||
|
||||
skinnumbers[foundskins] = skinnum;
|
||||
foundskins++;
|
||||
}
|
||||
else if (fastcmp(word, "DEFAULT"))
|
||||
{
|
||||
if (!sprite2)
|
||||
{
|
||||
deh_warning("Sprite %s: %s keyword found outside of SPRITE2INFO block, ignoring", spr2names[num], word);
|
||||
continue;
|
||||
}
|
||||
if (num < (INT32)free_spr2 && num >= (INT32)SPR2_FIRSTFREESLOT)
|
||||
spr2defaults[num] = get_number(word2);
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite2 %s: out of range (%d - %d), ignoring", spr2names[num], SPR2_FIRSTFREESLOT, free_spr2-1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "FRAME"))
|
||||
{
|
||||
UINT8 frame = R_Char2Frame(word2[0]);
|
||||
// frame number too high
|
||||
if (frame >= 64)
|
||||
{
|
||||
if (sprite2)
|
||||
deh_warning("Sprite2 %s: invalid frame %s", spr2names[num], word2);
|
||||
else
|
||||
deh_warning("Sprite %s: invalid frame %s", sprnames[num], word2);
|
||||
break;
|
||||
}
|
||||
|
||||
// read sprite frame and store it in the spriteinfo_t struct
|
||||
readspriteframe(f, info, frame);
|
||||
if (sprite2)
|
||||
{
|
||||
INT32 i;
|
||||
if (!foundskins)
|
||||
{
|
||||
deh_warning("Sprite2 %s: no skins specified", spr2names[num]);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < foundskins; i++)
|
||||
{
|
||||
size_t skinnum = skinnumbers[i];
|
||||
skin_t *skin = &skins[skinnum];
|
||||
spriteinfo_t *sprinfo = skin->sprinfo;
|
||||
#ifdef ROTSPRITE
|
||||
R_FreeSkinRotSprite(skinnum);
|
||||
#endif
|
||||
M_Memcpy(&sprinfo[num], info, sizeof(spriteinfo_t));
|
||||
}
|
||||
}
|
||||
else
|
||||
M_Memcpy(&spriteinfo[num], info, sizeof(spriteinfo_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
//deh_warning("Sprite %s: unknown word '%s'", sprnames[num], word);
|
||||
f->curpos = lastline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!myfeof(f)); // finish when the line is empty
|
||||
|
||||
Z_Free(s);
|
||||
Z_Free(info);
|
||||
}
|
||||
#endif // HWRENDER
|
||||
|
||||
static void readsprite2(MYFILE *f, INT32 num)
|
||||
{
|
||||
|
@ -2447,6 +2649,11 @@ static actionpointer_t actionpointers[] =
|
|||
{{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"},
|
||||
{{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"},
|
||||
{{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"},
|
||||
#ifdef ROTSPRITE
|
||||
{{A_RollAngle}, "A_ROLLANGLE"},
|
||||
{{A_ChangeRollAngleRelative},"A_CHANGEROLLANGLERELATIVE"},
|
||||
{{A_ChangeRollAngleAbsolute},"A_CHANGEROLLANGLEABSOLUTE"},
|
||||
#endif
|
||||
{{A_PlaySound}, "A_PLAYSOUND"},
|
||||
{{A_FindTarget}, "A_FINDTARGET"},
|
||||
{{A_FindTracer}, "A_FINDTRACER"},
|
||||
|
@ -4081,19 +4288,31 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "SPRITE"))
|
||||
#endif
|
||||
else if (fastcmp(word, "SPRITE") || fastcmp(word, "SPRITEINFO"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_sprite(word2); // find a sprite by name
|
||||
if (i < NUMSPRITES && i > 0)
|
||||
readspritelight(f, i);
|
||||
readspriteinfo(f, i, false);
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (fastcmp(word, "SPRITE2INFO"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_sprite2(word2); // find a sprite by name
|
||||
if (i < NUMPLAYERSPRITES && i >= 0)
|
||||
readspriteinfo(f, i, true);
|
||||
else
|
||||
{
|
||||
deh_warning("Sprite2 number %d out of range (0 - %d)", i, NUMPLAYERSPRITES-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "LEVEL"))
|
||||
{
|
||||
// Support using the actual map name,
|
||||
|
@ -4425,40 +4644,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
|
|||
"S_PLAY_NIGHTS_TRANS4",
|
||||
"S_PLAY_NIGHTS_TRANS5",
|
||||
"S_PLAY_NIGHTS_TRANS6",
|
||||
|
||||
"S_PLAY_NIGHTS_STAND",
|
||||
"S_PLAY_NIGHTS_FLOAT",
|
||||
"S_PLAY_NIGHTS_FLY",
|
||||
"S_PLAY_NIGHTS_DRILL",
|
||||
"S_PLAY_NIGHTS_STUN",
|
||||
"S_PLAY_NIGHTS_PULL",
|
||||
"S_PLAY_NIGHTS_ATTACK",
|
||||
|
||||
"S_PLAY_NIGHTS_FLY0",
|
||||
"S_PLAY_NIGHTS_DRILL0",
|
||||
"S_PLAY_NIGHTS_FLY1",
|
||||
"S_PLAY_NIGHTS_DRILL1",
|
||||
"S_PLAY_NIGHTS_FLY2",
|
||||
"S_PLAY_NIGHTS_DRILL2",
|
||||
"S_PLAY_NIGHTS_FLY3",
|
||||
"S_PLAY_NIGHTS_DRILL3",
|
||||
"S_PLAY_NIGHTS_FLY4",
|
||||
"S_PLAY_NIGHTS_DRILL4",
|
||||
"S_PLAY_NIGHTS_FLY5",
|
||||
"S_PLAY_NIGHTS_DRILL5",
|
||||
"S_PLAY_NIGHTS_FLY6",
|
||||
"S_PLAY_NIGHTS_DRILL6",
|
||||
"S_PLAY_NIGHTS_FLY7",
|
||||
"S_PLAY_NIGHTS_DRILL7",
|
||||
"S_PLAY_NIGHTS_FLY8",
|
||||
"S_PLAY_NIGHTS_DRILL8",
|
||||
"S_PLAY_NIGHTS_FLY9",
|
||||
"S_PLAY_NIGHTS_DRILL9",
|
||||
"S_PLAY_NIGHTS_FLYA",
|
||||
"S_PLAY_NIGHTS_DRILLA",
|
||||
"S_PLAY_NIGHTS_FLYB",
|
||||
"S_PLAY_NIGHTS_DRILLB",
|
||||
"S_PLAY_NIGHTS_FLYC",
|
||||
"S_PLAY_NIGHTS_DRILLC",
|
||||
|
||||
// c:
|
||||
"S_TAILSOVERLAY_STAND",
|
||||
"S_TAILSOVERLAY_0DEGREES",
|
||||
|
@ -8902,6 +9095,7 @@ struct {
|
|||
{"SF_DASHMODE",SF_DASHMODE},
|
||||
{"SF_FASTEDGE",SF_FASTEDGE},
|
||||
{"SF_MULTIABILITY",SF_MULTIABILITY},
|
||||
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
|
||||
|
||||
// Character abilities!
|
||||
// Primary
|
||||
|
@ -9158,6 +9352,13 @@ struct {
|
|||
{"DI_SOUTHEAST",DI_SOUTHEAST},
|
||||
{"NUMDIRS",NUMDIRS},
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
// Sprite rotation axis (rotaxis_t)
|
||||
{"ROTAXIS_X",ROTAXIS_X},
|
||||
{"ROTAXIS_Y",ROTAXIS_Y},
|
||||
{"ROTAXIS_Z",ROTAXIS_Z},
|
||||
#endif
|
||||
|
||||
// Buttons (ticcmd_t)
|
||||
{"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits.
|
||||
{"BT_WEAPONNEXT",BT_WEAPONNEXT},
|
||||
|
|
|
@ -489,6 +489,8 @@ extern INT32 cv_debug;
|
|||
// Misc stuff for later...
|
||||
// =======================
|
||||
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180)
|
||||
|
||||
// Modifier key variables, accessible anywhere
|
||||
extern UINT8 shiftdown, ctrldown, altdown;
|
||||
extern boolean capslock;
|
||||
|
@ -621,6 +623,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
|
|||
/// SRB2CB itself ported this from PrBoom+
|
||||
#define NEWCLIP
|
||||
|
||||
/// Sprite rotation
|
||||
#define ROTSPRITE
|
||||
#define ROTANGLES 24 // Needs to be a divisor of 360 (45, 60, 90, 120...)
|
||||
#define ROTANGDIFF (360 / ROTANGLES)
|
||||
|
||||
#ifndef HAVE_PNG
|
||||
#define NO_PNG_LUMPS
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../z_zone.h"
|
||||
#include "../v_video.h"
|
||||
#include "../r_draw.h"
|
||||
#include "../r_patch.h"
|
||||
#include "../p_setup.h"
|
||||
|
||||
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
|
||||
|
@ -1002,10 +1003,14 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
|
|||
{
|
||||
if (!grmip->downloaded && !grmip->grInfo.data)
|
||||
{
|
||||
patch_t *patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
patch_t *patch = gpatch->rawpatch;
|
||||
if (!patch)
|
||||
patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
HWR_MakePatch(patch, gpatch, grmip, true);
|
||||
|
||||
Z_Free(patch);
|
||||
// You can't free rawpatch for some reason?
|
||||
if (!gpatch->rawpatch)
|
||||
Z_Free(patch);
|
||||
}
|
||||
|
||||
HWD.pfnSetTexture(grmip);
|
||||
|
@ -1024,12 +1029,16 @@ void HWR_GetPatch(GLPatch_t *gpatch)
|
|||
{
|
||||
// load the software patch, PU_STATIC or the Z_Malloc for hardware patch will
|
||||
// flush the software patch before the conversion! oh yeah I suffered
|
||||
patch_t *ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
patch_t *ptr = gpatch->rawpatch;
|
||||
if (!ptr)
|
||||
ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
|
||||
HWR_MakePatch(ptr, gpatch, gpatch->mipmap, true);
|
||||
|
||||
// this is inefficient.. but the hardware patch in heap is purgeable so it should
|
||||
// not fragment memory, and besides the REAL cache here is the hardware memory
|
||||
Z_Free(ptr);
|
||||
// You can't free rawpatch for some reason?
|
||||
if (!gpatch->rawpatch)
|
||||
Z_Free(ptr);
|
||||
}
|
||||
|
||||
HWD.pfnSetTexture(gpatch->mipmap);
|
||||
|
@ -1265,6 +1274,23 @@ GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum)
|
|||
return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
|
||||
}
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch)
|
||||
{
|
||||
GLPatch_t *grpatch;
|
||||
|
||||
if (!(grpatch = M_AATreeGet(hwrcache, rollangle)))
|
||||
{
|
||||
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
|
||||
grpatch->rawpatch = rawpatch;
|
||||
grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
|
||||
M_AATreeSet(hwrcache, rollangle, grpatch);
|
||||
}
|
||||
|
||||
return grpatch;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Need to do this because they aren't powers of 2
|
||||
static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight,
|
||||
lumpnum_t fademasklumpnum, UINT16 fmwidth, UINT16 fmheight)
|
||||
|
|
|
@ -83,7 +83,8 @@ struct GLPatch_s
|
|||
float max_s,max_t;
|
||||
UINT16 wadnum; // the software patch lump num for when the hardware patch
|
||||
UINT16 lumpnum; // was flushed, and we need to re-create it
|
||||
GLMipmap_t *mipmap;
|
||||
void *rawpatch; // :^)
|
||||
GLMipmap_t *mipmap;
|
||||
} ATTRPACK;
|
||||
typedef struct GLPatch_s GLPatch_t;
|
||||
|
||||
|
|
|
@ -115,6 +115,13 @@ typedef struct
|
|||
FLOAT fovxangle, fovyangle;
|
||||
UINT8 splitscreen;
|
||||
boolean flip; // screenflip
|
||||
#ifdef ROTSPRITE
|
||||
boolean roll;
|
||||
SINT8 rollflip;
|
||||
FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ
|
||||
UINT8 rotaxis;
|
||||
FLOAT centerx, centery;
|
||||
#endif
|
||||
#ifdef USE_FTRANSFORM_MIRROR
|
||||
boolean mirror; // SRB2Kart: Encore Mode
|
||||
#endif
|
||||
|
|
|
@ -73,7 +73,8 @@ typedef struct gr_vissprite_s
|
|||
struct gr_vissprite_s *next;
|
||||
float x1, x2;
|
||||
float tz, ty;
|
||||
lumpnum_t patchlumpnum;
|
||||
//lumpnum_t patchlumpnum;
|
||||
GLPatch_t *gpatch;
|
||||
boolean flip;
|
||||
UINT8 translucency; //alpha level 0-255
|
||||
mobj_t *mobj;
|
||||
|
@ -111,6 +112,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum);
|
|||
void HWR_SetPalette(RGBA_t *palette);
|
||||
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
|
||||
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
|
||||
#ifdef ROTSPRITE
|
||||
GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch);
|
||||
#endif
|
||||
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
|
||||
|
||||
// --------
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../p_local.h"
|
||||
#include "../p_setup.h"
|
||||
#include "../r_local.h"
|
||||
#include "../r_patch.h"
|
||||
#include "../r_bsp.h"
|
||||
#include "../d_clisrv.h"
|
||||
#include "../w_wad.h"
|
||||
|
@ -4378,7 +4379,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
if (hires)
|
||||
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale);
|
||||
|
||||
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
|
||||
// cache the patch in the graphics card memory
|
||||
//12/12/99: Hurdler: same comment as above (for md2)
|
||||
|
@ -4734,7 +4735,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
|||
// sure to do it the right way. So actually, we keep normal sprite
|
||||
// in memory and we add the md2 model if it exists for that sprite
|
||||
|
||||
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY ||
|
||||
|
@ -4879,7 +4880,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
|||
return;
|
||||
|
||||
// cache sprite graphics
|
||||
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
|
||||
// create the sprite billboard
|
||||
//
|
||||
|
@ -5522,6 +5523,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
float gz, gzt;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
spriteinfo_t *sprinfo;
|
||||
size_t lumpoff;
|
||||
unsigned rot;
|
||||
UINT8 flip;
|
||||
|
@ -5533,10 +5535,22 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
|
||||
float z1, z2;
|
||||
|
||||
fixed_t spr_width, spr_height;
|
||||
fixed_t spr_offset, spr_topoffset;
|
||||
#ifdef ROTSPRITE
|
||||
patch_t *rotsprite = NULL;
|
||||
angle_t arollangle;
|
||||
UINT32 rollangle;
|
||||
#endif
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
else
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
arollangle = thing->rollangle;
|
||||
rollangle = AngleFixed(arollangle)>>FRACBITS;
|
||||
#endif
|
||||
this_scale = FIXED_TO_FLOAT(thing->scale);
|
||||
|
||||
// transform the origin point
|
||||
tr_x = FIXED_TO_FLOAT(thing->x) - gr_viewx;
|
||||
|
@ -5563,9 +5577,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
//Fab : 02-08-98: 'skin' override spritedef currently used for skin
|
||||
if (thing->skin && thing->sprite == SPR_PLAY)
|
||||
{
|
||||
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
|
||||
sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2];
|
||||
}
|
||||
else
|
||||
{
|
||||
sprdef = &sprites[thing->sprite];
|
||||
sprinfo = NULL;
|
||||
}
|
||||
|
||||
if (rot >= sprdef->numframes)
|
||||
{
|
||||
|
@ -5574,6 +5594,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
thing->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->frame = states[S_UNKNOWN].frame;
|
||||
sprdef = &sprites[thing->sprite];
|
||||
sprinfo = NULL;
|
||||
rot = thing->frame&FF_FRAMEMASK;
|
||||
thing->state->sprite = thing->sprite;
|
||||
thing->state->frame = thing->frame;
|
||||
|
@ -5629,6 +5650,30 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
|
||||
|
||||
spr_width = spritecachedinfo[lumpoff].width;
|
||||
spr_height = spritecachedinfo[lumpoff].height;
|
||||
spr_offset = spritecachedinfo[lumpoff].offset;
|
||||
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (rollangle > 0)
|
||||
{
|
||||
if (!sprframe->rotsprite.cached[rot])
|
||||
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||
rollangle /= ROTANGDIFF;
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
if (rotsprite != NULL)
|
||||
{
|
||||
spr_width = rotsprite->width << FRACBITS;
|
||||
spr_height = rotsprite->height << FRACBITS;
|
||||
spr_offset = rotsprite->leftoffset << FRACBITS;
|
||||
spr_topoffset = rotsprite->topoffset << FRACBITS;
|
||||
// flip -> rotate, not rotate -> flip
|
||||
flip = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
|
||||
|
@ -5642,13 +5687,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (flip)
|
||||
{
|
||||
x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale);
|
||||
x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale);
|
||||
x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale);
|
||||
x2 = (FIXED_TO_FLOAT(spr_offset) * this_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].offset) * this_scale);
|
||||
x2 = (FIXED_TO_FLOAT(spritecachedinfo[lumpoff].width - spritecachedinfo[lumpoff].offset) * this_scale);
|
||||
x1 = (FIXED_TO_FLOAT(spr_offset) * this_scale);
|
||||
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale);
|
||||
}
|
||||
|
||||
// test if too close
|
||||
|
@ -5670,13 +5715,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (vflip)
|
||||
{
|
||||
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gzt = gz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
|
||||
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spr_topoffset) * this_scale;
|
||||
gzt = gz + FIXED_TO_FLOAT(spr_height) * this_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset) * this_scale;
|
||||
gz = gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height) * this_scale;
|
||||
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spr_topoffset) * this_scale;
|
||||
gz = gzt - FIXED_TO_FLOAT(spr_height) * this_scale;
|
||||
}
|
||||
|
||||
if (thing->subsector->sector->cullheight)
|
||||
|
@ -5716,7 +5761,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->x2 = x2;
|
||||
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
|
||||
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
|
||||
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
//vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
#ifdef ROTSPRITE
|
||||
if (rotsprite)
|
||||
vis->gpatch = (GLPatch_t *)rotsprite;
|
||||
else
|
||||
#endif
|
||||
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
|
||||
vis->flip = flip;
|
||||
vis->mobj = thing;
|
||||
vis->z1 = z1;
|
||||
|
@ -5851,7 +5902,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->z2 = z2;
|
||||
vis->tz = tz;
|
||||
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
|
||||
vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
//vis->patchlumpnum = sprframe->lumppat[rot];
|
||||
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
|
||||
vis->flip = flip;
|
||||
vis->mobj = (mobj_t *)thing;
|
||||
|
||||
|
|
|
@ -961,6 +961,10 @@ void HWR_DrawModel(gr_vissprite_t *spr)
|
|||
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP));
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
#ifdef ROTSPRITE
|
||||
spriteinfo_t *sprinfo;
|
||||
angle_t ang;
|
||||
#endif
|
||||
INT32 mod;
|
||||
float finalscale;
|
||||
|
||||
|
@ -984,9 +988,17 @@ void HWR_DrawModel(gr_vissprite_t *spr)
|
|||
{
|
||||
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
|
||||
md2->skin = (skin_t*)spr->mobj->skin-skins;
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
md2 = &md2_models[spr->mobj->sprite];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &spriteinfo[spr->mobj->sprite];
|
||||
#endif
|
||||
}
|
||||
|
||||
if (md2->error)
|
||||
return; // we already failed loading this before :(
|
||||
|
@ -1065,7 +1077,7 @@ void HWR_DrawModel(gr_vissprite_t *spr)
|
|||
else
|
||||
{
|
||||
// Sprite
|
||||
gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
gpatch = spr->gpatch; //W_CachePatchNum(spr->patchlumpnum, PU_CACHE);
|
||||
HWR_GetMappedPatch(gpatch, spr->colormap);
|
||||
}
|
||||
|
||||
|
@ -1172,7 +1184,36 @@ void HWR_DrawModel(gr_vissprite_t *spr)
|
|||
const fixed_t anglef = AngleFixed((R_PointToAngle(spr->mobj->x, spr->mobj->y))-ANGLE_180);
|
||||
p.angley = FIXED_TO_FLOAT(anglef);
|
||||
}
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
p.rollangle = 0.0f;
|
||||
p.rollflip = 0;
|
||||
p.rotaxis = 0;
|
||||
if (spr->mobj->rollangle)
|
||||
{
|
||||
fixed_t anglef = AngleFixed(spr->mobj->rollangle);
|
||||
p.rollangle = FIXED_TO_FLOAT(anglef);
|
||||
p.roll = true;
|
||||
|
||||
// rotation pivot
|
||||
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
|
||||
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
|
||||
|
||||
// rotation axis
|
||||
if (sprinfo->available)
|
||||
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
|
||||
|
||||
// for NiGHTS specifically but should work everywhere else
|
||||
ang = R_PointToAngle (spr->mobj->x, spr->mobj->y) - (spr->mobj->player ? spr->mobj->player->drawangle : spr->mobj->angle);
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
p.rollflip = 1;
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
p.rollflip = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
p.anglex = 0.0f;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
// Slope rotation from Kart
|
||||
p.anglez = 0.0f;
|
||||
|
|
|
@ -2059,11 +2059,27 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
|||
pglTranslatef(pos->x, pos->z, pos->y);
|
||||
if (flipped)
|
||||
scaley = -scaley;
|
||||
|
||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
|
||||
#endif
|
||||
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
|
||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (pos->roll)
|
||||
{
|
||||
float roll = (1.0f * pos->rollflip);
|
||||
pglTranslatef(pos->centerx, pos->centery, 0);
|
||||
if (pos->rotaxis == 2) // Z
|
||||
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
|
||||
else if (pos->rotaxis == 1) // Y
|
||||
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
|
||||
else // X
|
||||
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
|
||||
pglTranslatef(-pos->centerx, -pos->centery, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
pglScalef(scalex, scaley, scalez);
|
||||
|
||||
|
|
96
src/info.c
96
src/info.c
|
@ -553,38 +553,12 @@ char spr2names[NUMPLAYERSPRITES][5] =
|
|||
|
||||
"NSTD",
|
||||
"NFLT",
|
||||
"NFLY",
|
||||
"NDRL",
|
||||
"NSTN",
|
||||
"NPUL",
|
||||
"NATK",
|
||||
|
||||
"NGT0",
|
||||
"NGT1",
|
||||
"NGT2",
|
||||
"NGT3",
|
||||
"NGT4",
|
||||
"NGT5",
|
||||
"NGT6",
|
||||
"NGT7",
|
||||
"NGT8",
|
||||
"NGT9",
|
||||
"NGTA",
|
||||
"NGTB",
|
||||
"NGTC",
|
||||
|
||||
"DRL0",
|
||||
"DRL1",
|
||||
"DRL2",
|
||||
"DRL3",
|
||||
"DRL4",
|
||||
"DRL5",
|
||||
"DRL6",
|
||||
"DRL7",
|
||||
"DRL8",
|
||||
"DRL9",
|
||||
"DRLA",
|
||||
"DRLB",
|
||||
"DRLC",
|
||||
|
||||
"TAL0",
|
||||
"TAL1",
|
||||
"TAL2",
|
||||
|
@ -656,38 +630,12 @@ playersprite_t spr2defaults[NUMPLAYERSPRITES] = {
|
|||
|
||||
FF_SPR2SUPER|SPR2_STND, // SPR2_NSTD,
|
||||
FF_SPR2SUPER|SPR2_FLT , // SPR2_NFLT,
|
||||
0, // SPR2_NFLY, (will never be referenced unless skin 0 lacks this)
|
||||
SPR2_NFLY, // SPR2_NDRL,
|
||||
FF_SPR2SUPER|SPR2_STUN, // SPR2_NSTN,
|
||||
SPR2_NSTN, // SPR2_NPUL,
|
||||
FF_SPR2SUPER|SPR2_ROLL, // SPR2_NATK,
|
||||
|
||||
0, // SPR2_NGT0, (will never be referenced unless skin 0 lacks this)
|
||||
SPR2_NGT0, // SPR2_NGT1,
|
||||
SPR2_NGT1, // SPR2_NGT2,
|
||||
SPR2_NGT2, // SPR2_NGT3,
|
||||
SPR2_NGT3, // SPR2_NGT4,
|
||||
SPR2_NGT4, // SPR2_NGT5,
|
||||
SPR2_NGT5, // SPR2_NGT6,
|
||||
SPR2_NGT0, // SPR2_NGT7,
|
||||
SPR2_NGT7, // SPR2_NGT8,
|
||||
SPR2_NGT8, // SPR2_NGT9,
|
||||
SPR2_NGT9, // SPR2_NGTA,
|
||||
SPR2_NGTA, // SPR2_NGTB,
|
||||
SPR2_NGTB, // SPR2_NGTC,
|
||||
|
||||
SPR2_NGT0, // SPR2_DRL0,
|
||||
SPR2_NGT1, // SPR2_DRL1,
|
||||
SPR2_NGT2, // SPR2_DRL2,
|
||||
SPR2_NGT3, // SPR2_DRL3,
|
||||
SPR2_NGT4, // SPR2_DRL4,
|
||||
SPR2_NGT5, // SPR2_DRL5,
|
||||
SPR2_NGT6, // SPR2_DRL6,
|
||||
SPR2_NGT7, // SPR2_DRL7,
|
||||
SPR2_NGT8, // SPR2_DRL8,
|
||||
SPR2_NGT9, // SPR2_DRL9,
|
||||
SPR2_NGTA, // SPR2_DRLA,
|
||||
SPR2_NGTB, // SPR2_DRLB,
|
||||
SPR2_NGTC, // SPR2_DRLC,
|
||||
|
||||
0, // SPR2_TAL0, (this will look mighty stupid but oh well)
|
||||
SPR2_TAL0, // SPR2_TAL1,
|
||||
SPR2_TAL1, // SPR2_TAL2,
|
||||
|
@ -818,41 +766,15 @@ state_t states[NUMSTATES] =
|
|||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
|
||||
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 21, {A_FadeOverlay}, 2, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS5
|
||||
|
||||
// NiGHTS Player, stand, float, pain, pull and attack
|
||||
// NiGHTS Player
|
||||
{SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
|
||||
{SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT
|
||||
{SPR_PLAY, SPR2_NFLY, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY}, // S_PLAY_NIGHTS_FLY
|
||||
{SPR_PLAY, SPR2_NDRL, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL}, // S_PLAY_NIGHTS_DRILL
|
||||
{SPR_PLAY, SPR2_NSTN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_STUN}, // S_PLAY_NIGHTS_STUN
|
||||
{SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL
|
||||
{SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK
|
||||
|
||||
// NiGHTS Player, flying and drilling
|
||||
{SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0
|
||||
{SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0
|
||||
{SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1
|
||||
{SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1
|
||||
{SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2
|
||||
{SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2
|
||||
{SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3
|
||||
{SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3
|
||||
{SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4
|
||||
{SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4
|
||||
{SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5
|
||||
{SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5
|
||||
{SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6
|
||||
{SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6
|
||||
{SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7
|
||||
{SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7
|
||||
{SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8
|
||||
{SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8
|
||||
{SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9
|
||||
{SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9
|
||||
{SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA
|
||||
{SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA
|
||||
{SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB
|
||||
{SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB
|
||||
{SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC
|
||||
{SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC
|
||||
|
||||
// c:
|
||||
{SPR_PLAY, SPR2_TAL0|FF_SPR2MIDSTART, 5, {NULL}, 0, 0, S_TAILSOVERLAY_STAND}, // S_TAILSOVERLAY_STAND
|
||||
{SPR_PLAY, SPR2_TAL1|FF_SPR2MIDSTART, 35, {NULL}, 0, 0, S_TAILSOVERLAY_0DEGREES}, // S_TAILSOVERLAY_0DEGREES
|
||||
|
@ -2408,7 +2330,11 @@ state_t states[NUMSTATES] =
|
|||
{SPR_BARX, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL5}, // S_TNTBARREL_EXPL4
|
||||
{SPR_BARX, 3|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_TNTBARREL_EXPL6}, // S_TNTBARREL_EXPL5
|
||||
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_NULL}, // S_TNTBARREL_EXPL6
|
||||
#ifndef ROTSPRITE
|
||||
{SPR_BARR, 1|FF_ANIMATE, -1, {NULL}, 7, 2, S_NULL}, // S_TNTBARREL_FLYING
|
||||
#else
|
||||
{SPR_BARR, 1, 1, {A_RollAngle}, 14, 0, S_TNTBARREL_FLYING}, // S_TNTBARREL_FLYING
|
||||
#endif
|
||||
|
||||
// TNT proximity shell
|
||||
{SPR_REMT, 0, 10, {A_Look}, 33554433, 0, S_PROXIMITY_TNT}, // S_PROXIMITY_TNT
|
||||
|
|
67
src/info.h
67
src/info.h
|
@ -155,6 +155,11 @@ void A_SpawnObjectAbsolute();
|
|||
void A_SpawnObjectRelative();
|
||||
void A_ChangeAngleRelative();
|
||||
void A_ChangeAngleAbsolute();
|
||||
#ifdef ROTSPRITE
|
||||
void A_RollAngle();
|
||||
void A_ChangeRollAngleRelative();
|
||||
void A_ChangeRollAngleAbsolute();
|
||||
#endif
|
||||
void A_PlaySound();
|
||||
void A_FindTarget();
|
||||
void A_FindTracer();
|
||||
|
@ -817,40 +822,12 @@ typedef enum playersprite
|
|||
|
||||
SPR2_NSTD, // NiGHTS stand
|
||||
SPR2_NFLT, // NiGHTS float
|
||||
SPR2_NFLY, // NiGHTS fly
|
||||
SPR2_NDRL, // NiGHTS drill
|
||||
SPR2_NSTN, // NiGHTS stun
|
||||
SPR2_NPUL, // NiGHTS pull
|
||||
SPR2_NATK, // NiGHTS attack
|
||||
|
||||
// NiGHTS flight
|
||||
SPR2_NGT0,
|
||||
SPR2_NGT1,
|
||||
SPR2_NGT2,
|
||||
SPR2_NGT3,
|
||||
SPR2_NGT4,
|
||||
SPR2_NGT5,
|
||||
SPR2_NGT6,
|
||||
SPR2_NGT7,
|
||||
SPR2_NGT8,
|
||||
SPR2_NGT9,
|
||||
SPR2_NGTA,
|
||||
SPR2_NGTB,
|
||||
SPR2_NGTC,
|
||||
|
||||
// NiGHTS drill
|
||||
SPR2_DRL0,
|
||||
SPR2_DRL1,
|
||||
SPR2_DRL2,
|
||||
SPR2_DRL3,
|
||||
SPR2_DRL4,
|
||||
SPR2_DRL5,
|
||||
SPR2_DRL6,
|
||||
SPR2_DRL7,
|
||||
SPR2_DRL8,
|
||||
SPR2_DRL9,
|
||||
SPR2_DRLA,
|
||||
SPR2_DRLB,
|
||||
SPR2_DRLC,
|
||||
|
||||
// c:
|
||||
SPR2_TAL0,
|
||||
SPR2_TAL1,
|
||||
|
@ -984,40 +961,14 @@ typedef enum state
|
|||
S_PLAY_NIGHTS_TRANS4,
|
||||
S_PLAY_NIGHTS_TRANS5,
|
||||
S_PLAY_NIGHTS_TRANS6,
|
||||
|
||||
S_PLAY_NIGHTS_STAND,
|
||||
S_PLAY_NIGHTS_FLOAT,
|
||||
S_PLAY_NIGHTS_FLY,
|
||||
S_PLAY_NIGHTS_DRILL,
|
||||
S_PLAY_NIGHTS_STUN,
|
||||
S_PLAY_NIGHTS_PULL,
|
||||
S_PLAY_NIGHTS_ATTACK,
|
||||
|
||||
S_PLAY_NIGHTS_FLY0,
|
||||
S_PLAY_NIGHTS_DRILL0,
|
||||
S_PLAY_NIGHTS_FLY1,
|
||||
S_PLAY_NIGHTS_DRILL1,
|
||||
S_PLAY_NIGHTS_FLY2,
|
||||
S_PLAY_NIGHTS_DRILL2,
|
||||
S_PLAY_NIGHTS_FLY3,
|
||||
S_PLAY_NIGHTS_DRILL3,
|
||||
S_PLAY_NIGHTS_FLY4,
|
||||
S_PLAY_NIGHTS_DRILL4,
|
||||
S_PLAY_NIGHTS_FLY5,
|
||||
S_PLAY_NIGHTS_DRILL5,
|
||||
S_PLAY_NIGHTS_FLY6,
|
||||
S_PLAY_NIGHTS_DRILL6,
|
||||
S_PLAY_NIGHTS_FLY7,
|
||||
S_PLAY_NIGHTS_DRILL7,
|
||||
S_PLAY_NIGHTS_FLY8,
|
||||
S_PLAY_NIGHTS_DRILL8,
|
||||
S_PLAY_NIGHTS_FLY9,
|
||||
S_PLAY_NIGHTS_DRILL9,
|
||||
S_PLAY_NIGHTS_FLYA,
|
||||
S_PLAY_NIGHTS_DRILLA,
|
||||
S_PLAY_NIGHTS_FLYB,
|
||||
S_PLAY_NIGHTS_DRILLB,
|
||||
S_PLAY_NIGHTS_FLYC,
|
||||
S_PLAY_NIGHTS_DRILLC,
|
||||
|
||||
// c:
|
||||
S_TAILSOVERLAY_STAND,
|
||||
S_TAILSOVERLAY_0DEGREES,
|
||||
|
|
|
@ -143,6 +143,11 @@ static const struct {
|
|||
{META_STATE, "state_t"},
|
||||
{META_MOBJINFO, "mobjinfo_t"},
|
||||
{META_SFXINFO, "sfxinfo_t"},
|
||||
{META_SPRITEINFO, "spriteinfo_t"},
|
||||
#ifdef ROTSPRITE
|
||||
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
||||
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
||||
#endif
|
||||
|
||||
{META_MOBJ, "mobj_t"},
|
||||
{META_MAPTHING, "mapthing_t"},
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "p_mobj.h"
|
||||
#include "p_local.h"
|
||||
#include "z_zone.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_things.h"
|
||||
#include "doomstat.h" // luabanks[]
|
||||
|
||||
#include "lua_script.h"
|
||||
|
@ -221,6 +223,401 @@ static int lib_spr2namelen(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// SPRITE INFO //
|
||||
/////////////////
|
||||
|
||||
// spriteinfo[]
|
||||
static int lib_getSpriteInfo(lua_State *L)
|
||||
{
|
||||
UINT32 i = NUMSPRITES;
|
||||
lua_remove(L, 1);
|
||||
|
||||
if (lua_isstring(L, 1))
|
||||
{
|
||||
const char *name = lua_tostring(L, 1);
|
||||
INT32 spr;
|
||||
for (spr = 0; spr < NUMSPRITES; spr++)
|
||||
{
|
||||
if (fastcmp(name, sprnames[spr]))
|
||||
{
|
||||
i = spr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NUMSPRITES)
|
||||
{
|
||||
char *check;
|
||||
i = strtol(name, &check, 10);
|
||||
if (check == name || *check != '\0')
|
||||
return luaL_error(L, "unknown sprite name %s", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
i = luaL_checkinteger(L, 1);
|
||||
|
||||
if (i == 0 || i >= NUMSPRITES)
|
||||
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
|
||||
|
||||
LUA_PushUserdata(L, &spriteinfo[i], META_SPRITEINFO);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to spriteinfo[] (%s)", e);
|
||||
#define TYPEERROR(f, t1, t2) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t1), lua_typename(L, t2)))
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, int idx)
|
||||
{
|
||||
int okcool = 0;
|
||||
switch (lua_type(L, stk))
|
||||
{
|
||||
case LUA_TTABLE:
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, stk))
|
||||
{
|
||||
const char *key = NULL;
|
||||
lua_Integer ikey = -1;
|
||||
lua_Integer value = 0;
|
||||
// x or y?
|
||||
switch (lua_type(L, stk+1))
|
||||
{
|
||||
case LUA_TSTRING:
|
||||
key = lua_tostring(L, stk+1);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
ikey = lua_tointeger(L, stk+1);
|
||||
break;
|
||||
default:
|
||||
FIELDERROR("pivot key", va("string or number expected, got %s", luaL_typename(L, stk+1)))
|
||||
}
|
||||
// then get value
|
||||
switch (lua_type(L, stk+2))
|
||||
{
|
||||
case LUA_TNUMBER:
|
||||
value = lua_tonumber(L, stk+2);
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
value = (UINT8)lua_toboolean(L, stk+2);
|
||||
break;
|
||||
default:
|
||||
TYPEERROR("pivot value", LUA_TNUMBER, lua_type(L, stk+2))
|
||||
}
|
||||
// finally set omg!!!!!!!!!!!!!!!!!!
|
||||
if (ikey == 1 || (key && fastcmp(key, "x")))
|
||||
pivot[idx].x = (INT32)value;
|
||||
else if (ikey == 2 || (key && fastcmp(key, "y")))
|
||||
pivot[idx].y = (INT32)value;
|
||||
else if (ikey == 3 || (key && fastcmp(key, "rotaxis")))
|
||||
pivot[idx].rotaxis = (UINT8)value;
|
||||
else if (ikey == -1 && (key != NULL))
|
||||
FIELDERROR("pivot key", va("invalid option %s", key));
|
||||
okcool = 1;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
TYPEERROR("sprite pivot", LUA_TTABLE, lua_type(L, stk))
|
||||
}
|
||||
return okcool;
|
||||
}
|
||||
|
||||
static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk)
|
||||
{
|
||||
// Just in case?
|
||||
if (!lua_istable(L, stk))
|
||||
TYPEERROR("pivot table", LUA_TTABLE, lua_type(L, stk));
|
||||
|
||||
lua_pushnil(L);
|
||||
// stk = 0 has the pivot table
|
||||
// stk = 1 has the frame key
|
||||
// stk = 2 has the frame table
|
||||
// stk = 3 has either a string or a number as key
|
||||
// stk = 4 has the value for the key mentioned above
|
||||
while (lua_next(L, stk))
|
||||
{
|
||||
int idx = 0;
|
||||
const char *framestr = NULL;
|
||||
switch (lua_type(L, stk+1))
|
||||
{
|
||||
case LUA_TSTRING:
|
||||
framestr = lua_tostring(L, stk+1);
|
||||
idx = R_Char2Frame(framestr[0]);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
idx = lua_tonumber(L, stk+1);
|
||||
break;
|
||||
default:
|
||||
TYPEERROR("pivot frame", LUA_TNUMBER, lua_type(L, stk+1));
|
||||
}
|
||||
if ((idx < 0) || (idx >= 64))
|
||||
return luaL_error(L, "pivot frame %d out of range (0 - %d)", idx, 63);
|
||||
// the values in pivot[] are also tables
|
||||
if (PopPivotSubTable(info->pivot, L, stk+2, idx))
|
||||
info->available = true;
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lib_setSpriteInfo(lua_State *L)
|
||||
{
|
||||
spriteinfo_t *info;
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "Do not alter spriteinfo_t from within a hook or coroutine!");
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter spriteinfo_t in HUD rendering code!");
|
||||
|
||||
lua_remove(L, 1);
|
||||
{
|
||||
UINT32 i = luaL_checkinteger(L, 1);
|
||||
if (i == 0 || i >= NUMSPRITES)
|
||||
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
|
||||
#ifdef ROTSPRITE
|
||||
if (sprites != NULL)
|
||||
R_FreeSingleRotSprite(&sprites[i]);
|
||||
#endif
|
||||
info = &spriteinfo[i]; // get the spriteinfo to assign to.
|
||||
}
|
||||
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||
lua_remove(L, 1); // pop sprite num, don't need it any more.
|
||||
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the spriteinfo.
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
lua_Integer i = 0;
|
||||
const char *str = NULL;
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
i = lua_tointeger(L, 2);
|
||||
#ifndef ROTSPRITE
|
||||
i++; // shift index in case of missing rotsprite support
|
||||
#endif
|
||||
}
|
||||
else
|
||||
str = luaL_checkstring(L, 2);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (i == 1 || (str && fastcmp(str, "pivot")))
|
||||
{
|
||||
// pivot[] is a table
|
||||
if (lua_istable(L, 3))
|
||||
return PopPivotTable(info, L, 3);
|
||||
else
|
||||
FIELDERROR("pivot", va("%s expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1)))
|
||||
}
|
||||
#endif
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef FIELDERROR
|
||||
#undef TYPEERROR
|
||||
|
||||
static int lib_spriteinfolen(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUMSPRITES);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// spriteinfo_t
|
||||
static int spriteinfo_get(lua_State *L)
|
||||
{
|
||||
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SPRITEINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
I_Assert(sprinfo != NULL);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
// push spriteframepivot_t userdata
|
||||
if (fastcmp(field, "pivot"))
|
||||
{
|
||||
// bypass LUA_PushUserdata
|
||||
void **userdata = lua_newuserdata(L, sizeof(void *));
|
||||
*userdata = &sprinfo->pivot;
|
||||
luaL_getmetatable(L, META_PIVOTLIST);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// stack is left with the userdata on top, as if getting it had originally succeeded.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return luaL_error(L, LUA_QL("spriteinfo_t") " has no field named " LUA_QS, field);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spriteinfo_set(lua_State *L)
|
||||
{
|
||||
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SPRITEINFO));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "Do not alter spriteinfo_t from within a hook or coroutine!");
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter spriteinfo_t in HUD rendering code!");
|
||||
|
||||
I_Assert(sprinfo != NULL);
|
||||
|
||||
lua_remove(L, 1); // remove spriteinfo
|
||||
lua_remove(L, 1); // remove field
|
||||
lua_settop(L, 1); // leave only one value
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (sprites != NULL)
|
||||
R_FreeSingleRotSprite(&sprites[sprinfo-spriteinfo]);
|
||||
|
||||
if (fastcmp(field, "pivot"))
|
||||
{
|
||||
// pivot[] is a table
|
||||
if (lua_istable(L, 1))
|
||||
return PopPivotTable(sprinfo, L, 1);
|
||||
// pivot[] is userdata
|
||||
else if (lua_isuserdata(L, 1))
|
||||
{
|
||||
spriteframepivot_t *pivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
|
||||
memcpy(&sprinfo->pivot, pivot, sizeof(spriteframepivot_t));
|
||||
sprinfo->available = true; // Just in case?
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return luaL_error(L, va("Field %s does not exist in spriteinfo_t", field));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spriteinfo_num(lua_State *L)
|
||||
{
|
||||
spriteinfo_t *sprinfo = *((spriteinfo_t **)luaL_checkudata(L, 1, META_SPRITEINFO));
|
||||
|
||||
I_Assert(sprinfo != NULL);
|
||||
I_Assert(sprinfo >= spriteinfo);
|
||||
|
||||
lua_pushinteger(L, (UINT32)(sprinfo-spriteinfo));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// framepivot_t
|
||||
#ifdef ROTSPRITE
|
||||
static int pivotlist_get(lua_State *L)
|
||||
{
|
||||
void **userdata;
|
||||
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_PIVOTLIST));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
UINT8 frame;
|
||||
|
||||
I_Assert(framepivot != NULL);
|
||||
|
||||
frame = R_Char2Frame(field[0]);
|
||||
if (frame == 255)
|
||||
luaL_error(L, "invalid frame %s", field);
|
||||
|
||||
// bypass LUA_PushUserdata
|
||||
userdata = lua_newuserdata(L, sizeof(void *));
|
||||
*userdata = &framepivot[frame];
|
||||
luaL_getmetatable(L, META_FRAMEPIVOT);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// stack is left with the userdata on top, as if getting it had originally succeeded.
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pivotlist_set(lua_State *L)
|
||||
{
|
||||
// Because I already know it's a spriteframepivot_t anyway
|
||||
spriteframepivot_t *pivotlist = *((spriteframepivot_t **)lua_touserdata(L, 1));
|
||||
//spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
UINT8 frame;
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "Do not alter spriteframepivot_t from within a hook or coroutine!");
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter spriteframepivot_t in HUD rendering code!");
|
||||
|
||||
I_Assert(pivotlist != NULL);
|
||||
|
||||
frame = R_Char2Frame(field[0]);
|
||||
if (frame == 255)
|
||||
luaL_error(L, "invalid frame %s", field);
|
||||
|
||||
// pivot[] is a table
|
||||
if (lua_istable(L, 3))
|
||||
return PopPivotSubTable(pivotlist, L, 3, frame);
|
||||
// pivot[] is userdata
|
||||
else if (lua_isuserdata(L, 3))
|
||||
{
|
||||
spriteframepivot_t *copypivot = *((spriteframepivot_t **)luaL_checkudata(L, 3, META_FRAMEPIVOT));
|
||||
memcpy(&pivotlist[frame], copypivot, sizeof(spriteframepivot_t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pivotlist_num(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, 64);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int framepivot_get(lua_State *L)
|
||||
{
|
||||
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
I_Assert(framepivot != NULL);
|
||||
|
||||
if (fastcmp("x", field))
|
||||
lua_pushinteger(L, framepivot->x);
|
||||
else if (fastcmp("y", field))
|
||||
lua_pushinteger(L, framepivot->y);
|
||||
else if (fastcmp("rotaxis", field))
|
||||
lua_pushinteger(L, (UINT8)framepivot->rotaxis);
|
||||
else
|
||||
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int framepivot_set(lua_State *L)
|
||||
{
|
||||
spriteframepivot_t *framepivot = *((spriteframepivot_t **)luaL_checkudata(L, 1, META_FRAMEPIVOT));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
if (!lua_lumploading)
|
||||
return luaL_error(L, "Do not alter spriteframepivot_t from within a hook or coroutine!");
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter spriteframepivot_t in HUD rendering code!");
|
||||
|
||||
I_Assert(framepivot != NULL);
|
||||
|
||||
if (fastcmp("x", field))
|
||||
framepivot->x = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp("y", field))
|
||||
framepivot->y = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp("rotaxis", field))
|
||||
framepivot->rotaxis = luaL_checkinteger(L, 3);
|
||||
else
|
||||
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int framepivot_num(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, 2);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////
|
||||
// STATE INFO //
|
||||
////////////////
|
||||
|
@ -903,8 +1300,8 @@ static int lib_setSfxInfo(lua_State *L)
|
|||
info = &S_sfx[i]; // get the sfxinfo to assign to.
|
||||
}
|
||||
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||
lua_remove(L, 1); // pop mobjtype num, don't need it any more.
|
||||
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the mobjinfo.
|
||||
lua_remove(L, 1); // pop sfx num, don't need it any more.
|
||||
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the sfx.
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter sfxinfo in HUD rendering code!");
|
||||
|
@ -1130,6 +1527,41 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_SPRITEINFO);
|
||||
lua_pushcfunction(L, spriteinfo_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, spriteinfo_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, spriteinfo_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
luaL_newmetatable(L, META_PIVOTLIST);
|
||||
lua_pushcfunction(L, pivotlist_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, pivotlist_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, pivotlist_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_FRAMEPIVOT);
|
||||
lua_pushcfunction(L, framepivot_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, framepivot_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, framepivot_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSprname);
|
||||
|
@ -1204,6 +1636,20 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_setglobal(L, "S_sfx");
|
||||
lua_setglobal(L, "sfxinfo");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSpriteInfo);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_setSpriteInfo);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, lib_spriteinfolen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "spriteinfo");
|
||||
|
||||
luaL_newmetatable(L, META_LUABANKS);
|
||||
lua_pushcfunction(L, lib_getluabanks);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -22,6 +22,11 @@ extern lua_State *gL;
|
|||
#define META_STATE "STATE_T*"
|
||||
#define META_MOBJINFO "MOBJINFO_T*"
|
||||
#define META_SFXINFO "SFXINFO_T*"
|
||||
#define META_SPRITEINFO "SPRITEINFO_T*"
|
||||
#ifdef ROTSPRITE
|
||||
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
||||
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
||||
#endif
|
||||
|
||||
#define META_MOBJ "MOBJ_T*"
|
||||
#define META_MAPTHING "MAPTHING_T*"
|
||||
|
|
|
@ -32,6 +32,9 @@ enum mobj_e {
|
|||
mobj_snext,
|
||||
mobj_sprev,
|
||||
mobj_angle,
|
||||
#ifdef ROTSPRITE
|
||||
mobj_rollangle,
|
||||
#endif
|
||||
mobj_sprite,
|
||||
mobj_frame,
|
||||
mobj_sprite2,
|
||||
|
@ -98,6 +101,9 @@ static const char *const mobj_opt[] = {
|
|||
"snext",
|
||||
"sprev",
|
||||
"angle",
|
||||
#ifdef ROTSPRITE
|
||||
"rollangle",
|
||||
#endif
|
||||
"sprite",
|
||||
"frame",
|
||||
"sprite2",
|
||||
|
@ -199,6 +205,11 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_angle:
|
||||
lua_pushangle(L, mo->angle);
|
||||
break;
|
||||
#ifdef ROTSPRITE
|
||||
case mobj_rollangle:
|
||||
lua_pushangle(L, mo->rollangle);
|
||||
break;
|
||||
#endif
|
||||
case mobj_sprite:
|
||||
lua_pushinteger(L, mo->sprite);
|
||||
break;
|
||||
|
@ -451,6 +462,11 @@ static int mobj_set(lua_State *L)
|
|||
else if (mo->player == &players[secondarydisplayplayer])
|
||||
localangle2 = mo->angle;
|
||||
break;
|
||||
#ifdef ROTSPRITE
|
||||
case mobj_rollangle:
|
||||
mo->rollangle = luaL_checkangle(L, 3);
|
||||
break;
|
||||
#endif
|
||||
case mobj_sprite:
|
||||
mo->sprite = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
108
src/p_enemy.c
108
src/p_enemy.c
|
@ -181,6 +181,11 @@ void A_SpawnObjectAbsolute(mobj_t *actor);
|
|||
void A_SpawnObjectRelative(mobj_t *actor);
|
||||
void A_ChangeAngleRelative(mobj_t *actor);
|
||||
void A_ChangeAngleAbsolute(mobj_t *actor);
|
||||
#ifdef ROTSPRITE
|
||||
void A_RollAngle(mobj_t *actor);
|
||||
void A_ChangeRollAngleRelative(mobj_t *actor);
|
||||
void A_ChangeRollAngleAbsolute(mobj_t *actor);
|
||||
#endif // ROTSPRITE
|
||||
void A_PlaySound(mobj_t *actor);
|
||||
void A_FindTarget(mobj_t *actor);
|
||||
void A_FindTracer(mobj_t *actor);
|
||||
|
@ -8519,7 +8524,7 @@ void A_ChangeAngleRelative(mobj_t *actor)
|
|||
|
||||
#ifdef PARANOIA
|
||||
if (amin > amax)
|
||||
I_Error("A_ChangeAngleRelative: var1 is greater then var2");
|
||||
I_Error("A_ChangeAngleRelative: var1 is greater than var2");
|
||||
#endif
|
||||
/*
|
||||
if (angle < amin)
|
||||
|
@ -8553,7 +8558,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
|
|||
|
||||
#ifdef PARANOIA
|
||||
if (amin > amax)
|
||||
I_Error("A_ChangeAngleAbsolute: var1 is greater then var2");
|
||||
I_Error("A_ChangeAngleAbsolute: var1 is greater than var2");
|
||||
#endif
|
||||
/*
|
||||
if (angle < amin)
|
||||
|
@ -8564,6 +8569,105 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
|
|||
actor->angle = FixedAngle(P_RandomRange(amin, amax));
|
||||
}
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
// Function: A_RollAngle
|
||||
//
|
||||
// Description: Changes the roll angle.
|
||||
//
|
||||
// var1 = angle
|
||||
// var2 = relative? (default)
|
||||
//
|
||||
void A_RollAngle(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
const angle_t angle = FixedAngle(locvar1*FRACUNIT);
|
||||
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_RollAngle", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
// relative (default)
|
||||
if (!locvar2)
|
||||
actor->rollangle += angle;
|
||||
// absolute
|
||||
else
|
||||
actor->rollangle = angle;
|
||||
}
|
||||
|
||||
// Function: A_ChangeRollAngleRelative
|
||||
//
|
||||
// Description: Changes the roll angle to a random relative value between the min and max. Set min and max to the same value to eliminate randomness
|
||||
//
|
||||
// var1 = min
|
||||
// var2 = max
|
||||
//
|
||||
void A_ChangeRollAngleRelative(mobj_t *actor)
|
||||
{
|
||||
// Oh god, the old code /sucked/. Changed this and the absolute version to get a random range using amin and amax instead of
|
||||
// getting a random angle from the _entire_ spectrum and then clipping. While we're at it, do the angle conversion to the result
|
||||
// rather than the ranges, so <0 and >360 work as possible values. -Red
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
//angle_t angle = (P_RandomByte()+1)<<24;
|
||||
const fixed_t amin = locvar1*FRACUNIT;
|
||||
const fixed_t amax = locvar2*FRACUNIT;
|
||||
//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
|
||||
//const angle_t amax = FixedAngle(locvar2*FRACUNIT);
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_ChangeRollAngleRelative", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (amin > amax)
|
||||
I_Error("A_ChangeRollAngleRelative: var1 is greater than var2");
|
||||
#endif
|
||||
/*
|
||||
if (angle < amin)
|
||||
angle = amin;
|
||||
if (angle > amax)
|
||||
angle = amax;*/
|
||||
|
||||
actor->rollangle += FixedAngle(P_RandomRange(amin, amax));
|
||||
}
|
||||
|
||||
// Function: A_ChangeRollAngleAbsolute
|
||||
//
|
||||
// Description: Changes the roll angle to a random absolute value between the min and max. Set min and max to the same value to eliminate randomness
|
||||
//
|
||||
// var1 = min
|
||||
// var2 = max
|
||||
//
|
||||
void A_ChangeRollAngleAbsolute(mobj_t *actor)
|
||||
{
|
||||
INT32 locvar1 = var1;
|
||||
INT32 locvar2 = var2;
|
||||
//angle_t angle = (P_RandomByte()+1)<<24;
|
||||
const fixed_t amin = locvar1*FRACUNIT;
|
||||
const fixed_t amax = locvar2*FRACUNIT;
|
||||
//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
|
||||
//const angle_t amax = FixedAngle(locvar2*FRACUNIT);
|
||||
#ifdef HAVE_BLUA
|
||||
if (LUA_CallAction("A_ChangeRollAngleAbsolute", actor))
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef PARANOIA
|
||||
if (amin > amax)
|
||||
I_Error("A_ChangeRollAngleAbsolute: var1 is greater than var2");
|
||||
#endif
|
||||
/*
|
||||
if (angle < amin)
|
||||
angle = amin;
|
||||
if (angle > amax)
|
||||
angle = amax;*/
|
||||
|
||||
actor->rollangle = FixedAngle(P_RandomRange(amin, amax));
|
||||
}
|
||||
#endif // ROTSPRITE
|
||||
|
||||
// Function: A_PlaySound
|
||||
//
|
||||
// Description: Plays a sound
|
||||
|
|
|
@ -279,6 +279,9 @@ typedef struct mobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
#ifdef ROTSPRITE
|
||||
angle_t rollangle;
|
||||
#endif
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT8 sprite2; // player sprites
|
||||
|
@ -399,6 +402,9 @@ typedef struct precipmobj_s
|
|||
|
||||
// More drawing info: to determine current sprite.
|
||||
angle_t angle; // orientation
|
||||
#ifdef ROTSPRITE
|
||||
angle_t rollangle;
|
||||
#endif
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT8 sprite2; // player sprites
|
||||
|
|
|
@ -1277,6 +1277,9 @@ typedef enum
|
|||
MD2_SLOPE = 1<<11,
|
||||
#endif
|
||||
MD2_COLORIZED = 1<<12,
|
||||
#ifdef ROTSPRITE
|
||||
MD2_ROLLANGLE = 1<<13,
|
||||
#endif
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -1496,6 +1499,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
#endif
|
||||
if (mobj->colorized)
|
||||
diff2 |= MD2_COLORIZED;
|
||||
#ifdef ROTSPRITE
|
||||
if (mobj->rollangle)
|
||||
diff2 |= MD2_ROLLANGLE;
|
||||
#endif
|
||||
if (diff2 != 0)
|
||||
diff |= MD_MORE;
|
||||
|
||||
|
@ -1660,6 +1667,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
#endif
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
WRITEUINT8(save_p, mobj->colorized);
|
||||
#ifdef ROTSPRITE
|
||||
if (diff2 & MD2_ROLLANGLE)
|
||||
WRITEANGLE(save_p, mobj->rollangle);
|
||||
#endif
|
||||
|
||||
WRITEUINT32(save_p, mobj->mobjnum);
|
||||
}
|
||||
|
@ -2736,6 +2747,12 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
#endif
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
mobj->colorized = READUINT8(save_p);
|
||||
#ifdef ROTSPRITE
|
||||
if (diff2 & MD2_ROLLANGLE)
|
||||
mobj->rollangle = READANGLE(save_p);
|
||||
else
|
||||
mobj->rollangle = 0;
|
||||
#endif
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "r_data.h"
|
||||
#include "r_things.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_draw.h"
|
||||
|
||||
|
@ -543,9 +544,10 @@ levelflat_t *levelflats;
|
|||
size_t P_PrecacheLevelFlats(void)
|
||||
{
|
||||
lumpnum_t lump;
|
||||
size_t i, flatmemory = 0;
|
||||
size_t i;
|
||||
|
||||
//SoM: 4/18/2000: New flat code to make use of levelflats.
|
||||
flatmemory = 0;
|
||||
for (i = 0; i < numlevelflats; i++)
|
||||
{
|
||||
if (levelflats[i].type == LEVELFLAT_FLAT)
|
||||
|
@ -3508,9 +3510,11 @@ boolean P_AddWadFile(const char *wadfilename)
|
|||
if (!mapsadded)
|
||||
CONS_Printf(M_GetText("No maps added\n"));
|
||||
|
||||
R_LoadSpriteInfoLumps(wadnum, numlumps);
|
||||
|
||||
#ifdef HWRENDER
|
||||
HWR_ReloadModels();
|
||||
#endif // HWRENDER
|
||||
#endif
|
||||
|
||||
// reload status bar (warning should have valid player!)
|
||||
if (gamestate == GS_LEVEL)
|
||||
|
|
101
src/p_user.c
101
src/p_user.c
|
@ -744,7 +744,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
|||
player->mo->height = P_GetPlayerHeight(player); // Just to make sure jumping into the drone doesn't result in a squashed hitbox.
|
||||
player->oldscale = player->mo->scale;
|
||||
|
||||
if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
|
||||
if (skins[player->skin].sprites[SPR2_NFLY].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
|
||||
{
|
||||
player->mo->skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
|
@ -6748,6 +6748,17 @@ static void P_DoNiGHTSCapsule(player_t *player)
|
|||
P_SetPlayerMobjState(player->mo, S_PLAY_ROLL);
|
||||
}
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (!(player->charflags & SF_NONIGHTSROTATION))
|
||||
{
|
||||
if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL])
|
||||
&& (player->mo->sprite2 == SPR2_NPUL))
|
||||
player->mo->rollangle -= ANG30;
|
||||
else
|
||||
player->mo->rollangle = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (G_IsSpecialStage(gamemap))
|
||||
{ // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here!
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
|
@ -7009,6 +7020,9 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
INT32 i;
|
||||
statenum_t flystate;
|
||||
UINT16 visangle;
|
||||
#ifdef ROTSPRITE
|
||||
angle_t rollangle = 0;
|
||||
#endif
|
||||
|
||||
player->pflags &= ~PF_DRILLING;
|
||||
|
||||
|
@ -7193,6 +7207,9 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
|
||||
{
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
#ifdef ROTSPRITE
|
||||
player->mo->rollangle = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7201,13 +7218,26 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
player->mo->momx = player->mo->momy = 0;
|
||||
|
||||
if (gametype != GT_RACE && gametype != GT_COMPETITION)
|
||||
P_SetObjectMomZ(player->mo, FRACUNIT/2, true);
|
||||
P_SetObjectMomZ(player->mo, FRACUNIT/2, (P_MobjFlip(player->mo)*player->mo->momz >= 0));
|
||||
else
|
||||
player->mo->momz = 0;
|
||||
|
||||
if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL6])
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6);
|
||||
#if 0//def ROTSPRITE
|
||||
if (!(player->charflags & SF_NONIGHTSROTATION) && player->mo->momz)
|
||||
{
|
||||
if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL])
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL);
|
||||
player->mo->rollangle = ANGLE_90;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (player->mo->state != &states[S_PLAY_NIGHTS_FLOAT])
|
||||
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_FLOAT);
|
||||
player->drawangle += ANGLE_22h;
|
||||
}
|
||||
|
||||
player->mo->flags |= MF_NOCLIPHEIGHT;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7482,31 +7512,60 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT;
|
||||
else
|
||||
{
|
||||
visangle = ((player->anotherflyangle + 7) % 360)/15;
|
||||
if (visangle > 18) // Over 270 degrees.
|
||||
visangle = 30 - visangle;
|
||||
else if (visangle > 12) // Over 180 degrees.
|
||||
visangle -= 6;
|
||||
else if (visangle > 6) // Over 90 degrees.
|
||||
visangle = 12 - visangle;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity
|
||||
flystate = (player->pflags & PF_DRILLING) ? S_PLAY_NIGHTS_DRILL : S_PLAY_NIGHTS_FLY;
|
||||
if (player->charflags & SF_NONIGHTSROTATION)
|
||||
{
|
||||
if (visangle > 6)
|
||||
visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6
|
||||
else
|
||||
visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C
|
||||
#if 0
|
||||
visangle = ((player->anotherflyangle + 7) % 360)/15;
|
||||
if (visangle > 18) // Over 270 degrees.
|
||||
visangle = 30 - visangle;
|
||||
else if (visangle > 12) // Over 180 degrees.
|
||||
visangle -= 6;
|
||||
else if (visangle > 6) // Over 90 degrees.
|
||||
visangle = 12 - visangle;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity
|
||||
{
|
||||
if (visangle > 6)
|
||||
visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6
|
||||
else
|
||||
visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C
|
||||
}
|
||||
|
||||
flystate += (visangle*2); // S_PLAY_NIGHTS_FLY0-C - the *2 is to skip over drill states
|
||||
#endif
|
||||
}
|
||||
#ifdef ROTSPRITE
|
||||
else
|
||||
{
|
||||
angle_t a = R_PointToAngle(player->mo->x, player->mo->y) - player->mo->angle;
|
||||
visangle = (player->flyangle % 360);
|
||||
|
||||
flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states
|
||||
if (player->flyangle >= 90 && player->flyangle <= 270)
|
||||
{
|
||||
if (player->flyangle == 270 && (a < ANGLE_180))
|
||||
;
|
||||
else if (player->flyangle == 90 && (a < ANGLE_180))
|
||||
;
|
||||
else
|
||||
visangle += 180;
|
||||
}
|
||||
|
||||
if (player->pflags & PF_DRILLING)
|
||||
flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C
|
||||
rollangle = FixedAngle(visangle<<FRACBITS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (player->mo->state != &states[flystate])
|
||||
P_SetPlayerMobjState(player->mo, flystate);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (player->charflags & SF_NONIGHTSROTATION)
|
||||
player->mo->rollangle = 0;
|
||||
else
|
||||
player->mo->rollangle = rollangle;
|
||||
#endif
|
||||
|
||||
if (player == &players[consoleplayer])
|
||||
localangle = player->mo->angle;
|
||||
else if (player == &players[secondarydisplayplayer])
|
||||
|
|
602
src/r_data.c
602
src/r_data.c
|
@ -9,7 +9,7 @@
|
|||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \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 "g_game.h"
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include "p_local.h"
|
||||
#include "m_misc.h"
|
||||
#include "r_data.h"
|
||||
#include "r_patch.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "p_setup.h" // levelflats
|
||||
|
@ -41,28 +42,6 @@
|
|||
#include <errno.h>
|
||||
#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.
|
||||
// Each texture is composed of one or more patches,
|
||||
|
@ -136,7 +115,7 @@ sprcache_t *spritecachedinfo;
|
|||
lighttable_t *colormaps;
|
||||
|
||||
// for debugging/info purposes
|
||||
static size_t flatmemory, spritememory, texturememory;
|
||||
size_t flatmemory, spritememory, texturememory;
|
||||
|
||||
// highcolor stuff
|
||||
INT16 color8to16[256]; // remap color index to highcolor rgb value
|
||||
|
@ -2487,578 +2466,3 @@ void R_PrecacheLevel(void)
|
|||
"texturememory: %s k\n"
|
||||
"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_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;
|
||||
}
|
||||
|
||||
#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
|
||||
{
|
||||
const UINT8 *buffer;
|
||||
UINT32 size;
|
||||
UINT32 position;
|
||||
} 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->size - f->position))
|
||||
png_error(png_ptr, "PNG_IOReader: buffer overrun");
|
||||
memcpy(data, f->buffer + f->position, length);
|
||||
f->position += 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;
|
||||
png_io.size = size;
|
||||
png_io.position = 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;
|
||||
png_io.size = size;
|
||||
png_io.position = 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
|
||||
|
|
16
src/r_data.h
16
src/r_data.h
|
@ -88,13 +88,14 @@ void R_CheckTextureCache(INT32 tex);
|
|||
|
||||
// Retrieve column data for span blitting.
|
||||
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
|
||||
|
||||
UINT8 *R_GetFlat(lumpnum_t flatnum);
|
||||
|
||||
// I/O, setting up the stuff.
|
||||
void R_InitData(void);
|
||||
void R_PrecacheLevel(void);
|
||||
|
||||
extern size_t flatmemory, spritememory, texturememory;
|
||||
|
||||
// Retrieval.
|
||||
// Floor/ceiling opaque texture tiles,
|
||||
// lookup by name. For animation?
|
||||
|
@ -158,19 +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_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);
|
||||
|
||||
#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;
|
||||
|
||||
#endif
|
||||
|
|
20
src/r_defs.h
20
src/r_defs.h
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include "screen.h" // MAXVIDWIDTH, MAXVIDHEIGHT
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "m_aatree.h"
|
||||
#endif
|
||||
|
||||
#define POLYOBJECTS
|
||||
|
||||
//
|
||||
|
@ -728,6 +732,18 @@ typedef struct
|
|||
#pragma pack()
|
||||
#endif
|
||||
|
||||
// rotsprite
|
||||
#ifdef ROTSPRITE
|
||||
typedef struct
|
||||
{
|
||||
patch_t *patch[8][ROTANGLES];
|
||||
boolean cached[8];
|
||||
#ifdef HWRENDER
|
||||
aatree_t *hardware_patch[8];
|
||||
#endif
|
||||
} rotsprite_t;
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRF_SINGLE = 0, // 0-angle for all rotations
|
||||
|
@ -765,6 +781,10 @@ typedef struct
|
|||
|
||||
// Flip bits (1 = flip) to use for view angles 0-7.
|
||||
UINT8 flip;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
rotsprite_t rotsprite;
|
||||
#endif
|
||||
} spriteframe_t;
|
||||
|
||||
//
|
||||
|
|
1373
src/r_patch.c
Normal file
1373
src/r_patch.c
Normal file
File diff suppressed because it is too large
Load diff
76
src/r_patch.h
Normal file
76
src/r_patch.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
// 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 enum
|
||||
{
|
||||
ROTAXIS_X, // roll (the default)
|
||||
ROTAXIS_Y, // pitch
|
||||
ROTAXIS_Z // yaw
|
||||
} rotaxis_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 x, y;
|
||||
rotaxis_t rotaxis;
|
||||
} 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);
|
||||
void R_FreeSingleRotSprite(spritedef_t *spritedef);
|
||||
void R_FreeSkinRotSprite(size_t skinnum);
|
||||
extern fixed_t cosang2rad[ROTANGLES];
|
||||
extern fixed_t sinang2rad[ROTANGLES];
|
||||
#endif
|
||||
|
||||
#endif // __R_PATCH__
|
|
@ -1114,8 +1114,6 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
|
||||
zeroheight = FIXED_TO_FLOAT(temp);
|
||||
|
||||
#define ANG2RAD(angle) ((float)((angle)*M_PIl)/ANGLE_180)
|
||||
|
||||
// p is the texture origin in view space
|
||||
// Don't add in the offsets at this stage, because doing so can result in
|
||||
// errors if the flat is rotated.
|
||||
|
|
127
src/r_things.c
127
src/r_things.c
|
@ -22,7 +22,9 @@
|
|||
#include "m_misc.h"
|
||||
#include "info.h" // spr2names
|
||||
#include "i_video.h" // rendermode
|
||||
#include "i_system.h"
|
||||
#include "r_things.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_portal.h"
|
||||
#include "p_tick.h"
|
||||
|
@ -35,6 +37,9 @@
|
|||
#include "fastcmp.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_md2.h"
|
||||
#include "hardware/hw_glob.h"
|
||||
#include "hardware/hw_light.h"
|
||||
#include "hardware/hw_drv.h"
|
||||
#endif
|
||||
|
||||
#ifdef PC_DOS
|
||||
|
@ -68,6 +73,8 @@ static lighttable_t **spritelights;
|
|||
INT16 negonearray[MAXVIDWIDTH];
|
||||
INT16 screenheightarray[MAXVIDWIDTH];
|
||||
|
||||
spriteinfo_t spriteinfo[NUMSPRITES];
|
||||
|
||||
//
|
||||
// INITIALIZATION FUNCTIONS
|
||||
//
|
||||
|
@ -100,7 +107,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
{
|
||||
char cn = R_Frame2Char(frame); // for debugging
|
||||
|
||||
INT32 r;
|
||||
INT32 r, ang;
|
||||
lumpnum_t lumppat = wad;
|
||||
lumppat <<= 16;
|
||||
lumppat += lump;
|
||||
|
@ -111,6 +118,20 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
if (maxframe ==(size_t)-1 || frame > maxframe)
|
||||
maxframe = frame;
|
||||
|
||||
// rotsprite
|
||||
#ifdef ROTSPRITE
|
||||
for (r = 0; r < 8; r++)
|
||||
{
|
||||
sprtemp[frame].rotsprite.cached[r] = false;
|
||||
for (ang = 0; ang < ROTANGLES; ang++)
|
||||
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
|
||||
#endif // HWRENDER
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rotation == 0)
|
||||
{
|
||||
// the lump should be used for all rotations
|
||||
|
@ -222,6 +243,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
// if so, it might patch only certain frames, not all
|
||||
if (spritedef->numframes) // (then spriteframes is not null)
|
||||
{
|
||||
#ifdef ROTSPRITE
|
||||
R_FreeSingleRotSprite(spritedef);
|
||||
#endif
|
||||
// copy the already defined sprite frames
|
||||
M_Memcpy(sprtemp, spritedef->spriteframes,
|
||||
spritedef->numframes * sizeof (spriteframe_t));
|
||||
|
@ -274,12 +298,12 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
|
||||
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
|
||||
if (rendermode != render_none) // not for psprite
|
||||
spritecachedinfo[numspritelumps].topoffset += 4<<FRACBITS;
|
||||
spritecachedinfo[numspritelumps].topoffset += FEETADJUST;
|
||||
// Being selective with this causes bad things. :( Like the special stage tokens breaking apart.
|
||||
/*if (rendermode != render_none // not for psprite
|
||||
&& SHORT(patch.topoffset)>0 && SHORT(patch.topoffset)<SHORT(patch.height))
|
||||
// perfect is patch.height but sometime it is too high
|
||||
spritecachedinfo[numspritelumps].topoffset = min(SHORT(patch.topoffset)+4,SHORT(patch.height))<<FRACBITS;*/
|
||||
spritecachedinfo[numspritelumps].topoffset = min(SHORT(patch.topoffset)+(FEETADJUST>>FRACBITS),SHORT(patch.height))<<FRACBITS;*/
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
|
@ -369,6 +393,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
if (spritedef->numframes && // has been allocated
|
||||
spritedef->numframes < maxframe) // more frames are defined ?
|
||||
{
|
||||
#ifdef ROTSPRITE
|
||||
R_FreeSingleRotSprite(spritedef);
|
||||
#endif
|
||||
Z_Free(spritedef->spriteframes);
|
||||
spritedef->spriteframes = NULL;
|
||||
}
|
||||
|
@ -465,7 +492,6 @@ UINT32 visspritecount;
|
|||
static UINT32 clippedvissprites;
|
||||
static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL};
|
||||
|
||||
|
||||
//
|
||||
// R_InitSprites
|
||||
// Called at program start.
|
||||
|
@ -473,11 +499,23 @@ static vissprite_t *visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL
|
|||
void R_InitSprites(void)
|
||||
{
|
||||
size_t i;
|
||||
#ifdef ROTSPRITE
|
||||
INT32 angle, realangle = 0;
|
||||
float fa;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAXVIDWIDTH; i++)
|
||||
{
|
||||
negonearray[i] = -1;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
for (angle = 0; angle < ROTANGLES; angle++)
|
||||
{
|
||||
fa = ANG2RAD(FixedAngle(realangle<<FRACBITS));
|
||||
cosang2rad[angle] = FLOAT_TO_FIXED(cos(-fa));
|
||||
sinang2rad[angle] = FLOAT_TO_FIXED(sin(-fa));
|
||||
realangle += ROTANGDIFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// count the number of sprite names, and allocate sprites table
|
||||
|
@ -505,6 +543,7 @@ void R_InitSprites(void)
|
|||
{
|
||||
R_AddSkins((UINT16)i);
|
||||
R_PatchSkins((UINT16)i);
|
||||
R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps);
|
||||
}
|
||||
ST_ReloadSkinFaceGraphics();
|
||||
|
||||
|
@ -717,7 +756,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
INT32 texturecolumn;
|
||||
#endif
|
||||
fixed_t frac;
|
||||
patch_t *patch = W_CachePatchNum(vis->patch, PU_CACHE);
|
||||
patch_t *patch = vis->patch;
|
||||
fixed_t this_scale = vis->mobj->scale;
|
||||
INT32 x1, x2;
|
||||
INT64 overflow_test;
|
||||
|
@ -906,7 +945,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
INT64 overflow_test;
|
||||
|
||||
//Fab : R_InitSprites now sets a wad lump number
|
||||
patch = W_CachePatchNum(vis->patch, PU_CACHE);
|
||||
patch = vis->patch;
|
||||
if (!patch)
|
||||
return;
|
||||
|
||||
|
@ -1060,6 +1099,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
#ifdef ROTSPRITE
|
||||
spriteinfo_t *sprinfo;
|
||||
#endif
|
||||
size_t lump;
|
||||
|
||||
size_t rot;
|
||||
|
@ -1086,6 +1128,15 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
INT32 light = 0;
|
||||
fixed_t this_scale = thing->scale;
|
||||
|
||||
// rotsprite
|
||||
fixed_t spr_width, spr_height;
|
||||
fixed_t spr_offset, spr_topoffset;
|
||||
#ifdef ROTSPRITE
|
||||
patch_t *rotsprite = NULL;
|
||||
angle_t arollangle = thing->rollangle;
|
||||
UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS;
|
||||
#endif
|
||||
|
||||
fixed_t ang_scale = FRACUNIT;
|
||||
|
||||
// transform the origin point
|
||||
|
@ -1125,16 +1176,27 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (thing->skin && thing->sprite == SPR_PLAY)
|
||||
{
|
||||
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2];
|
||||
#endif
|
||||
if (rot >= sprdef->numframes) {
|
||||
CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[%sSPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, ((thing->sprite2 & FF_SPR2SUPER) ? "FF_SPR2SUPER|": ""), spr2names[(thing->sprite2 & ~FF_SPR2SUPER)], sizeu5(rot));
|
||||
thing->sprite = states[S_UNKNOWN].sprite;
|
||||
thing->frame = states[S_UNKNOWN].frame;
|
||||
sprdef = &sprites[thing->sprite];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = NULL;
|
||||
#endif
|
||||
rot = thing->frame&FF_FRAMEMASK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprdef = &sprites[thing->sprite];
|
||||
#ifdef ROTSPRITE
|
||||
sprinfo = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rot >= sprdef->numframes)
|
||||
{
|
||||
|
@ -1194,11 +1256,35 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
this_scale = FixedMul(this_scale, ((skin_t *)thing->skin)->highresscale);
|
||||
|
||||
spr_width = spritecachedinfo[lump].width;
|
||||
spr_height = spritecachedinfo[lump].height;
|
||||
spr_offset = spritecachedinfo[lump].offset;
|
||||
spr_topoffset = spritecachedinfo[lump].topoffset;
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
if (rollangle > 0)
|
||||
{
|
||||
if (!sprframe->rotsprite.cached[rot])
|
||||
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
|
||||
rollangle /= ROTANGDIFF;
|
||||
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
|
||||
if (rotsprite != NULL)
|
||||
{
|
||||
spr_width = rotsprite->width << FRACBITS;
|
||||
spr_height = rotsprite->height << FRACBITS;
|
||||
spr_offset = rotsprite->leftoffset << FRACBITS;
|
||||
spr_topoffset = rotsprite->topoffset << FRACBITS;
|
||||
// flip -> rotate, not rotate -> flip
|
||||
flip = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// calculate edges of the shape
|
||||
if (flip)
|
||||
offset = spritecachedinfo[lump].offset - spritecachedinfo[lump].width;
|
||||
offset = spr_offset - spr_width;
|
||||
else
|
||||
offset = -spritecachedinfo[lump].offset;
|
||||
offset = -spr_offset;
|
||||
offset = FixedMul(offset, this_scale);
|
||||
tx += FixedMul(offset, ang_scale);
|
||||
x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS;
|
||||
|
@ -1207,7 +1293,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
offset2 = FixedMul(spritecachedinfo[lump].width, this_scale);
|
||||
offset2 = FixedMul(spr_width, this_scale);
|
||||
tx += FixedMul(offset2, ang_scale);
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1);
|
||||
|
||||
|
@ -1309,13 +1395,13 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
// When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned.
|
||||
// sprite height - sprite topoffset is the proper inverse of the vertical offset, of course.
|
||||
// remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes!
|
||||
gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
gz = oldthing->z + oldthing->height - FixedMul(spr_topoffset, this_scale);
|
||||
gzt = gz + FixedMul(spr_height, this_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale);
|
||||
gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale);
|
||||
gzt = oldthing->z + FixedMul(spr_topoffset, this_scale);
|
||||
gz = gzt - FixedMul(spr_height, this_scale);
|
||||
}
|
||||
|
||||
if (thing->subsector->sector->cullheight)
|
||||
|
@ -1414,7 +1500,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (flip)
|
||||
{
|
||||
vis->startfrac = spritecachedinfo[lump].width-1;
|
||||
vis->startfrac = spr_width-1;
|
||||
vis->xiscale = -iscale;
|
||||
}
|
||||
else
|
||||
|
@ -1431,7 +1517,12 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
//Fab: lumppat is the lump number of the patch to use, this is different
|
||||
// than lumpid for sprites-in-pwad : the graphics are patched
|
||||
vis->patch = sprframe->lumppat[rot];
|
||||
#ifdef ROTSPRITE
|
||||
if (rotsprite != NULL)
|
||||
vis->patch = rotsprite;
|
||||
else
|
||||
#endif
|
||||
vis->patch = W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
|
||||
|
||||
//
|
||||
// determine the colormap (lightlevel & special effects)
|
||||
|
@ -1623,7 +1714,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
|
||||
//Fab: lumppat is the lump number of the patch to use, this is different
|
||||
// than lumpid for sprites-in-pwad : the graphics are patched
|
||||
vis->patch = sprframe->lumppat[0];
|
||||
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
||||
|
||||
// specific translucency
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
|
@ -2801,7 +2892,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
|||
if (player->mo)
|
||||
{
|
||||
fixed_t radius = FixedMul(skin->radius, player->mo->scale);
|
||||
if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
|
||||
if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (skin->sprites[SPR2_NFLY].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
|
||||
{
|
||||
skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
player->followitem = skin->followitem;
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
#include "sounds.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_portal.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
// "Left" and "Right" character symbols for additional rotation functionality
|
||||
#define ROT_L ('L' - '0')
|
||||
|
@ -30,6 +32,8 @@
|
|||
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
|
||||
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
|
||||
|
||||
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
|
@ -128,7 +132,9 @@ typedef struct
|
|||
// specific sounds per skin
|
||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||
|
||||
spritedef_t sprites[NUMPLAYERSPRITES*2]; // contains super versions too
|
||||
// contains super versions too
|
||||
spritedef_t sprites[NUMPLAYERSPRITES*2];
|
||||
spriteinfo_t sprinfo[NUMPLAYERSPRITES*2];
|
||||
|
||||
UINT8 availability; // lock?
|
||||
} skin_t;
|
||||
|
@ -178,7 +184,7 @@ typedef struct vissprite_s
|
|||
fixed_t xiscale; // negative if flipped
|
||||
|
||||
fixed_t texturemid;
|
||||
lumpnum_t patch;
|
||||
patch_t *patch;
|
||||
|
||||
lighttable_t *colormap; // for color translation and shadow draw
|
||||
// maxbright frames as well
|
||||
|
|
|
@ -281,6 +281,7 @@
|
|||
<ClInclude Include="..\r_local.h" />
|
||||
<ClInclude Include="..\r_main.h" />
|
||||
<ClInclude Include="..\r_plane.h" />
|
||||
<ClInclude Include="..\r_patch.h" />
|
||||
<ClInclude Include="..\r_portal.h" />
|
||||
<ClInclude Include="..\r_segs.h" />
|
||||
<ClInclude Include="..\r_sky.h" />
|
||||
|
@ -439,6 +440,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\r_main.c" />
|
||||
<ClCompile Include="..\r_plane.c" />
|
||||
<ClCompile Include="..\r_patch.c" />
|
||||
<ClCompile Include="..\r_portal.c" />
|
||||
<ClCompile Include="..\r_segs.c" />
|
||||
<ClCompile Include="..\r_sky.c" />
|
||||
|
@ -490,4 +492,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -465,6 +465,9 @@
|
|||
<ClInclude Include="..\hardware\hw_clip.h">
|
||||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_patch.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_portal.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
|
@ -922,6 +925,9 @@
|
|||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\apng.c" />
|
||||
<ClCompile Include="..\r_patch.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\r_portal.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
|
@ -931,4 +937,4 @@
|
|||
<Filter>SDLApp</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
18
src/w_wad.c
18
src/w_wad.c
|
@ -1183,21 +1183,6 @@ void zerr(int ret)
|
|||
}
|
||||
#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.
|
||||
* 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
|
||||
{
|
||||
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;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -297,6 +297,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\r_main.c" />
|
||||
<ClCompile Include="..\r_plane.c" />
|
||||
<ClCompile Include="..\r_patch.c" />
|
||||
<ClCompile Include="..\r_portal.c" />
|
||||
<ClCompile Include="..\r_segs.c" />
|
||||
<ClCompile Include="..\r_sky.c" />
|
||||
|
@ -452,6 +453,7 @@
|
|||
<ClInclude Include="..\r_local.h" />
|
||||
<ClInclude Include="..\r_main.h" />
|
||||
<ClInclude Include="..\r_plane.h" />
|
||||
<ClInclude Include="..\r_patch.h" />
|
||||
<ClInclude Include="..\r_portal.h" />
|
||||
<ClInclude Include="..\r_segs.h" />
|
||||
<ClInclude Include="..\r_sky.h" />
|
||||
|
@ -505,4 +507,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -469,6 +469,9 @@
|
|||
<Filter>Hw_Hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\apng.c" />
|
||||
<ClCompile Include="..\r_patch.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\r_portal.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
|
@ -886,6 +889,9 @@
|
|||
<Filter>Hw_Hardware</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\apng.h" />
|
||||
<ClInclude Include="..\r_patch.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_portal.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
|
@ -919,4 +925,4 @@
|
|||
<Filter>A_Asm</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in a new issue