mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-21 17:00:59 +00:00
Merge remote-tracking branch 'origin/next' into hooklib-refactor
This commit is contained in:
commit
353692fa79
37 changed files with 1003 additions and 293 deletions
|
@ -276,6 +276,7 @@ set(SRB2_LUA_SOURCES
|
|||
lua_hudlib.c
|
||||
lua_infolib.c
|
||||
lua_maplib.c
|
||||
lua_taglib.c
|
||||
lua_mathlib.c
|
||||
lua_mobjlib.c
|
||||
lua_playerlib.c
|
||||
|
|
|
@ -47,6 +47,7 @@ OBJS:=$(OBJS) \
|
|||
$(OBJDIR)/lua_skinlib.o \
|
||||
$(OBJDIR)/lua_thinkerlib.o \
|
||||
$(OBJDIR)/lua_maplib.o \
|
||||
$(OBJDIR)/lua_taglib.o \
|
||||
$(OBJDIR)/lua_polyobjlib.o \
|
||||
$(OBJDIR)/lua_blockmaplib.o \
|
||||
$(OBJDIR)/lua_hudlib.o
|
||||
|
|
|
@ -360,30 +360,48 @@ static void CON_SetupColormaps(void)
|
|||
for (i = 0; i < (256*15); i++, ++memorysrc)
|
||||
*memorysrc = (UINT8)(i & 0xFF); // remap each color to itself...
|
||||
|
||||
#define colset(map, a, b, c) \
|
||||
map[1] = (UINT8)a;\
|
||||
map[3] = (UINT8)b;\
|
||||
map[9] = (UINT8)c
|
||||
#define colset(map, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
|
||||
map[0x0] = (UINT8)a;\
|
||||
map[0x1] = (UINT8)b;\
|
||||
map[0x2] = (UINT8)c;\
|
||||
map[0x3] = (UINT8)d;\
|
||||
map[0x4] = (UINT8)e;\
|
||||
map[0x5] = (UINT8)f;\
|
||||
map[0x6] = (UINT8)g;\
|
||||
map[0x7] = (UINT8)h;\
|
||||
map[0x8] = (UINT8)i;\
|
||||
map[0x9] = (UINT8)j;\
|
||||
map[0xA] = (UINT8)k;\
|
||||
map[0xB] = (UINT8)l;\
|
||||
map[0xC] = (UINT8)m;\
|
||||
map[0xD] = (UINT8)n;\
|
||||
map[0xE] = (UINT8)o;\
|
||||
map[0xF] = (UINT8)p;
|
||||
|
||||
colset(magentamap, 177, 178, 184);
|
||||
colset(yellowmap, 82, 73, 66);
|
||||
colset(lgreenmap, 97, 98, 106);
|
||||
colset(bluemap, 146, 147, 155);
|
||||
colset(redmap, 210, 32, 39);
|
||||
colset(graymap, 6, 8, 14);
|
||||
colset(orangemap, 51, 52, 57);
|
||||
colset(skymap, 129, 130, 133);
|
||||
colset(purplemap, 160, 161, 163);
|
||||
colset(aquamap, 120, 121, 123);
|
||||
colset(peridotmap, 88, 188, 190);
|
||||
colset(azuremap, 144, 145, 170);
|
||||
colset(brownmap, 219, 221, 224);
|
||||
colset(rosymap, 200, 201, 203);
|
||||
colset(invertmap, 27, 26, 22);
|
||||
invertmap[26] = (UINT8)3;
|
||||
// Tried to keep the colors vanilla while adding some shades in between them ~SonicX8000
|
||||
|
||||
// 0x1 0x3 0x9 0xF
|
||||
colset(magentamap, 177, 177, 178, 178, 178, 180, 180, 180, 182, 182, 182, 182, 184, 184, 184, 185);
|
||||
colset(yellowmap, 82, 82, 73, 73, 73, 64, 64, 64, 66, 66, 66, 66, 67, 67, 67, 68);
|
||||
colset(lgreenmap, 96, 96, 98, 98, 98, 101, 101, 101, 104, 104, 104, 104, 106, 106, 106, 107);
|
||||
colset(bluemap, 146, 146, 147, 147, 147, 149, 149, 149, 152, 152, 152, 152, 155, 155, 155, 157);
|
||||
colset(redmap, 32, 32, 33, 33, 33, 35, 35, 35, 39, 39, 39, 39, 42, 42, 42, 44);
|
||||
colset(graymap, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23);
|
||||
colset(orangemap, 50, 50, 52, 52, 52, 54, 54, 54, 56, 56, 56, 56, 59, 59, 59, 60);
|
||||
colset(skymap, 129, 129, 130, 130, 130, 131, 131, 131, 133, 133, 133, 133, 135, 135, 135, 136);
|
||||
colset(purplemap, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 163, 164, 164, 164, 165);
|
||||
colset(aquamap, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 123, 124, 124, 124, 125);
|
||||
colset(peridotmap, 72, 72, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191, 191, 191, 94);
|
||||
colset(azuremap, 144, 144, 145, 145, 145, 146, 146, 146, 170, 170, 170, 170, 171, 171, 171, 172);
|
||||
colset(brownmap, 219, 219, 221, 221, 221, 222, 222, 222, 224, 224, 224, 224, 227, 227, 227, 229);
|
||||
colset(rosymap, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 204, 204, 204, 205);
|
||||
|
||||
#undef colset
|
||||
|
||||
// Yeah just straight up invert it like a normal person
|
||||
for (i = 0x00; i <= 0x1F; i++)
|
||||
invertmap[0x1F - i] = i;
|
||||
|
||||
// Init back colormap
|
||||
CON_SetupBackColormap();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ typedef enum
|
|||
SF_NOSUPERSPRITES = 1<<16, // Don't use super sprites while super
|
||||
SF_NOSUPERJUMPBOOST = 1<<17, // Disable the jump boost given while super (i.e. Knuckles)
|
||||
SF_CANBUSTWALLS = 1<<18, // Can naturally bust walls on contact? (i.e. Knuckles)
|
||||
SF_NOSHIELDABILITY = 1<<19, // Disable shield abilities
|
||||
|
||||
// free up to and including 1<<31
|
||||
} skinflags_t;
|
||||
|
||||
|
|
|
@ -1522,6 +1522,13 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
|
|||
"S_SPINFIRE5",
|
||||
"S_SPINFIRE6",
|
||||
|
||||
"S_TEAM_SPINFIRE1",
|
||||
"S_TEAM_SPINFIRE2",
|
||||
"S_TEAM_SPINFIRE3",
|
||||
"S_TEAM_SPINFIRE4",
|
||||
"S_TEAM_SPINFIRE5",
|
||||
"S_TEAM_SPINFIRE6",
|
||||
|
||||
// Spikes
|
||||
"S_SPIKE1",
|
||||
"S_SPIKE2",
|
||||
|
@ -5015,6 +5022,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"SF_NOSUPERSPRITES",SF_NOSUPERSPRITES},
|
||||
{"SF_NOSUPERJUMPBOOST",SF_NOSUPERJUMPBOOST},
|
||||
{"SF_CANBUSTWALLS",SF_CANBUSTWALLS},
|
||||
{"SF_NOSHIELDABILITY",SF_NOSHIELDABILITY},
|
||||
|
||||
// Dashmode constants
|
||||
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
|
||||
|
|
|
@ -381,6 +381,28 @@ Needed for some lua shenanigans.
|
|||
#define FIELDFROM( type, field, have, want ) \
|
||||
(void *)((intptr_t)(field) - offsetof (type, have) + offsetof (type, want))
|
||||
|
||||
typedef UINT8 bitarray_t;
|
||||
|
||||
#define BIT_ARRAY_SIZE(n) (((n) + 7) >> 3)
|
||||
|
||||
static inline int
|
||||
in_bit_array (const bitarray_t * const array, const int value)
|
||||
{
|
||||
return (array[value >> 3] & (1<<(value & 7)));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_bit_array (bitarray_t * const array, const int value)
|
||||
{
|
||||
array[value >> 3] |= (1<<(value & 7));
|
||||
}
|
||||
|
||||
static inline void
|
||||
unset_bit_array (bitarray_t * const array, const int value)
|
||||
{
|
||||
array[value >> 3] &= ~(1<<(value & 7));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
typedef UINT64 precise_t;
|
||||
#endif
|
||||
|
|
|
@ -108,7 +108,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
|
|||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
texel = mipmap->colormap->data[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
|
@ -218,7 +218,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
|
|||
|
||||
//Hurdler: 25/04/2000: now support colormap in hardware mode
|
||||
if (mipmap->colormap)
|
||||
texel = mipmap->colormap[texel];
|
||||
texel = mipmap->colormap->data[texel];
|
||||
|
||||
// hope compiler will get this switch out of the loops (dreams...)
|
||||
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
|
||||
|
@ -659,7 +659,10 @@ void HWR_FreeTextureColormaps(patch_t *patch)
|
|||
// Free image data from memory.
|
||||
if (next->data)
|
||||
Z_Free(next->data);
|
||||
if (next->colormap)
|
||||
Z_Free(next->colormap);
|
||||
next->data = NULL;
|
||||
next->colormap = NULL;
|
||||
HWD.pfnDeleteTexture(next);
|
||||
|
||||
// Free the old colormap mipmap from memory.
|
||||
|
@ -667,16 +670,29 @@ void HWR_FreeTextureColormaps(patch_t *patch)
|
|||
}
|
||||
}
|
||||
|
||||
static boolean FreeTextureCallback(void *mem)
|
||||
{
|
||||
patch_t *patch = (patch_t *)mem;
|
||||
HWR_FreeTexture(patch);
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean FreeColormapsCallback(void *mem)
|
||||
{
|
||||
patch_t *patch = (patch_t *)mem;
|
||||
HWR_FreeTextureColormaps(patch);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void HWR_FreePatchCache(boolean freeall)
|
||||
{
|
||||
INT32 i;
|
||||
boolean (*callback)(void *mem) = FreeTextureCallback;
|
||||
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
INT32 j = 0;
|
||||
for (; j < wadfiles[i]->numlumps; j++)
|
||||
(freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]);
|
||||
}
|
||||
if (!freeall)
|
||||
callback = FreeColormapsCallback;
|
||||
|
||||
Z_IterateTags(PU_PATCH, PU_PATCH_ROTATED, callback);
|
||||
Z_IterateTags(PU_SPRITE, PU_HUDGFX, callback);
|
||||
}
|
||||
|
||||
// free all textures after each level
|
||||
|
@ -977,8 +993,28 @@ static void HWR_LoadPatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
|
|||
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
// ----------------------+
|
||||
// HWR_UpdatePatchMipmap : Updates a mipmap.
|
||||
// ----------------------+
|
||||
static void HWR_UpdatePatchMipmap(patch_t *patch, GLMipmap_t *grMipmap)
|
||||
{
|
||||
GLPatch_t *grPatch = patch->hardware;
|
||||
HWR_MakePatch(patch, grPatch, grMipmap, true);
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
// If it does have the texture, then call pfnUpdateTexture to update it
|
||||
if (!grMipmap->downloaded)
|
||||
HWD.pfnSetTexture(grMipmap);
|
||||
else
|
||||
HWD.pfnUpdateTexture(grMipmap);
|
||||
HWR_SetCurrentTexture(grMipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
// HWR_GetPatch : Download a patch to the hardware cache and make it ready for use
|
||||
// HWR_GetPatch : Downloads a patch to the hardware cache and make it ready for use
|
||||
// -----------------+
|
||||
void HWR_GetPatch(patch_t *patch)
|
||||
{
|
||||
|
@ -1006,14 +1042,20 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
|
|||
return;
|
||||
}
|
||||
|
||||
// search for the mimmap
|
||||
// search for the mipmap
|
||||
// skip the first (no colormap translated)
|
||||
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
|
||||
{
|
||||
grMipmap = grMipmap->nextcolormap;
|
||||
if (grMipmap->colormap == colormap)
|
||||
if (grMipmap->colormap && grMipmap->colormap->source == colormap)
|
||||
{
|
||||
HWR_LoadPatchMipmap(patch, grMipmap);
|
||||
if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
|
||||
{
|
||||
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
|
||||
HWR_UpdatePatchMipmap(patch, grMipmap);
|
||||
}
|
||||
else
|
||||
HWR_LoadPatchMipmap(patch, grMipmap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1029,7 +1071,10 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
|
|||
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
|
||||
grMipmap->nextcolormap = newMipmap;
|
||||
|
||||
newMipmap->colormap = colormap;
|
||||
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
|
||||
newMipmap->colormap->source = colormap;
|
||||
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
|
||||
|
||||
HWR_LoadPatchMipmap(patch, newMipmap);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,15 @@ typedef enum GLTextureFormat_e
|
|||
GL_TEXFMT_ALPHA_INTENSITY_88 = 0x22,
|
||||
} GLTextureFormat_t;
|
||||
|
||||
// Colormap structure for mipmaps.
|
||||
struct GLColormap_s
|
||||
{
|
||||
const UINT8 *source;
|
||||
UINT8 data[256];
|
||||
};
|
||||
typedef struct GLColormap_s GLColormap_t;
|
||||
|
||||
|
||||
// data holds the address of the graphics data cached in heap memory
|
||||
// NULL if the texture is not in Doom heap cache.
|
||||
struct GLMipmap_s
|
||||
|
@ -53,7 +62,7 @@ struct GLMipmap_s
|
|||
UINT32 downloaded; // The GPU has this texture.
|
||||
|
||||
struct GLMipmap_s *nextcolormap;
|
||||
const UINT8 *colormap;
|
||||
struct GLColormap_s *colormap;
|
||||
|
||||
struct GLMipmap_s *nextmipmap; // Linked list of all textures
|
||||
};
|
||||
|
@ -77,7 +86,7 @@ struct GLPatch_s
|
|||
{
|
||||
float max_s,max_t;
|
||||
GLMipmap_t *mipmap;
|
||||
} ATTRPACK;
|
||||
};
|
||||
typedef struct GLPatch_s GLPatch_t;
|
||||
|
||||
#endif //_HWR_DATA_
|
||||
|
|
|
@ -253,6 +253,7 @@ light_t *t_lspr[NUMSPRITES] =
|
|||
&lspr[NOLIGHT], // SPR_SIGN
|
||||
&lspr[NOLIGHT], // SPR_SPIK
|
||||
&lspr[NOLIGHT], // SPR_SFLM
|
||||
&lspr[NOLIGHT], // SPR_TFLM
|
||||
&lspr[NOLIGHT], // SPR_USPK
|
||||
&lspr[NOLIGHT], // SPR_WSPK
|
||||
&lspr[NOLIGHT], // SPR_WSPB
|
||||
|
|
|
@ -5295,7 +5295,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
vis->colormap = R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color ? vis->mobj->color : SKINCOLOR_CYAN, GTC_CACHE);
|
||||
}
|
||||
else
|
||||
vis->colormap = colormaps;
|
||||
vis->colormap = NULL;
|
||||
|
||||
// set top/bottom coords
|
||||
vis->gzt = gzt;
|
||||
|
@ -5396,7 +5396,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
vis->flip = flip;
|
||||
vis->mobj = (mobj_t *)thing;
|
||||
|
||||
vis->colormap = colormaps;
|
||||
vis->colormap = NULL;
|
||||
|
||||
// set top/bottom coords
|
||||
vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
|
||||
|
|
|
@ -1106,11 +1106,19 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
|
|||
for (grMipmap = grPatch->mipmap; grMipmap->nextcolormap; )
|
||||
{
|
||||
grMipmap = grMipmap->nextcolormap;
|
||||
if (grMipmap->colormap == colormap)
|
||||
if (grMipmap->colormap && grMipmap->colormap->source == colormap)
|
||||
{
|
||||
if (grMipmap->downloaded && grMipmap->data)
|
||||
{
|
||||
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
|
||||
if (memcmp(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8)))
|
||||
{
|
||||
M_Memcpy(grMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
|
||||
HWR_CreateBlendedTexture(patch, blendpatch, grMipmap, skinnum, color);
|
||||
HWD.pfnUpdateTexture(grMipmap);
|
||||
}
|
||||
else
|
||||
HWD.pfnSetTexture(grMipmap); // found the colormap, set it to the correct texture
|
||||
|
||||
Z_ChangeTag(grMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
|
||||
return;
|
||||
}
|
||||
|
@ -1128,7 +1136,10 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
|
|||
if (newMipmap == NULL)
|
||||
I_Error("%s: Out of memory", "HWR_GetBlendedTexture");
|
||||
grMipmap->nextcolormap = newMipmap;
|
||||
newMipmap->colormap = colormap;
|
||||
|
||||
newMipmap->colormap = Z_Calloc(sizeof(*newMipmap->colormap), PU_HWRPATCHCOLMIPMAP, NULL);
|
||||
newMipmap->colormap->source = colormap;
|
||||
M_Memcpy(newMipmap->colormap->data, colormap, 256 * sizeof(UINT8));
|
||||
|
||||
HWR_CreateBlendedTexture(patch, blendpatch, newMipmap, skinnum, color);
|
||||
|
||||
|
|
32
src/info.c
32
src/info.c
|
@ -150,6 +150,7 @@ char sprnames[NUMSPRITES + 1][5] =
|
|||
"SIGN", // Level end sign
|
||||
"SPIK", // Spike Ball
|
||||
"SFLM", // Spin fire
|
||||
"TFLM", // Spin fire (team)
|
||||
"USPK", // Floor spike
|
||||
"WSPK", // Wall spike
|
||||
"WSPB", // Wall spike base
|
||||
|
@ -1894,6 +1895,13 @@ state_t states[NUMSTATES] =
|
|||
{SPR_SFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_SPINFIRE6}, // S_SPINFIRE5
|
||||
{SPR_SFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_SPINFIRE1}, // S_SPINFIRE6
|
||||
|
||||
{SPR_TFLM, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE2}, // S_TEAM_SPINFIRE1
|
||||
{SPR_TFLM, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE3}, // S_TEAM_SPINFIRE2
|
||||
{SPR_TFLM, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE4}, // S_TEAM_SPINFIRE3
|
||||
{SPR_TFLM, FF_FULLBRIGHT|3, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE5}, // S_TEAM_SPINFIRE4
|
||||
{SPR_TFLM, FF_FULLBRIGHT|4, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE6}, // S_TEAM_SPINFIRE5
|
||||
{SPR_TFLM, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_TEAM_SPINFIRE1}, // S_TEAM_SPINFIRE6
|
||||
|
||||
// Floor Spike
|
||||
{SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended
|
||||
{SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2
|
||||
|
@ -3291,18 +3299,18 @@ state_t states[NUMSTATES] =
|
|||
{SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_RANDOMANIM, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
|
||||
|
||||
// Spindash dust
|
||||
{SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1
|
||||
{SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2
|
||||
{SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3
|
||||
{SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4
|
||||
{SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1
|
||||
{SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2
|
||||
{SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3
|
||||
{SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4
|
||||
{SPR_FPRT, 0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1
|
||||
{SPR_FPRT, 0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2
|
||||
{SPR_FPRT, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3
|
||||
{SPR_FPRT, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4
|
||||
{SPR_DUST, 0, 7, {NULL}, 0, 0, S_SPINDUST2}, // S_SPINDUST1
|
||||
{SPR_DUST, 1, 6, {NULL}, 0, 0, S_SPINDUST3}, // S_SPINDUST2
|
||||
{SPR_DUST, FF_TRANS30|2, 4, {NULL}, 0, 0, S_SPINDUST4}, // S_SPINDUST3
|
||||
{SPR_DUST, FF_TRANS60|3, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST4
|
||||
{SPR_BUBL, 0, 7, {NULL}, 0, 0, S_SPINDUST_BUBBLE2}, // S_SPINDUST_BUBBLE1
|
||||
{SPR_BUBL, 0, 6, {NULL}, 0, 0, S_SPINDUST_BUBBLE3}, // S_SPINDUST_BUBBLE2
|
||||
{SPR_BUBL, FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_BUBBLE4}, // S_SPINDUST_BUBBLE3
|
||||
{SPR_BUBL, FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_BUBBLE4
|
||||
{SPR_FPRT, FF_FULLBRIGHT|0, 7, {NULL}, 0, 0, S_SPINDUST_FIRE2}, // S_SPINDUST_FIRE1
|
||||
{SPR_FPRT, FF_FULLBRIGHT|0, 6, {NULL}, 0, 0, S_SPINDUST_FIRE3}, // S_SPINDUST_FIRE2
|
||||
{SPR_FPRT, FF_FULLBRIGHT|FF_TRANS30|0, 4, {NULL}, 0, 0, S_SPINDUST_FIRE4}, // S_SPINDUST_FIRE3
|
||||
{SPR_FPRT, FF_FULLBRIGHT|FF_TRANS60|0, 3, {NULL}, 0, 0, S_NULL}, // S_SPINDUST_FIRE4
|
||||
|
||||
|
||||
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1
|
||||
|
|
|
@ -684,6 +684,7 @@ typedef enum sprite
|
|||
SPR_SIGN, // Level end sign
|
||||
SPR_SPIK, // Spike Ball
|
||||
SPR_SFLM, // Spin fire
|
||||
SPR_TFLM, // Spin fire (team)
|
||||
SPR_USPK, // Floor spike
|
||||
SPR_WSPK, // Wall spike
|
||||
SPR_WSPB, // Wall spike base
|
||||
|
@ -2324,6 +2325,13 @@ typedef enum state
|
|||
S_SPINFIRE5,
|
||||
S_SPINFIRE6,
|
||||
|
||||
S_TEAM_SPINFIRE1,
|
||||
S_TEAM_SPINFIRE2,
|
||||
S_TEAM_SPINFIRE3,
|
||||
S_TEAM_SPINFIRE4,
|
||||
S_TEAM_SPINFIRE5,
|
||||
S_TEAM_SPINFIRE6,
|
||||
|
||||
// Spikes
|
||||
S_SPIKE1,
|
||||
S_SPIKE2,
|
||||
|
|
|
@ -155,6 +155,8 @@ static const struct {
|
|||
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
||||
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
||||
|
||||
{META_TAGLIST, "taglist"},
|
||||
|
||||
{META_MOBJ, "mobj_t"},
|
||||
{META_MAPTHING, "mapthing_t"},
|
||||
|
||||
|
@ -186,6 +188,9 @@ static const struct {
|
|||
{META_CVAR, "consvar_t"},
|
||||
|
||||
{META_SECTORLINES, "sector_t.lines"},
|
||||
#ifdef MUTABLE_TAGS
|
||||
{META_SECTORTAGLIST, "sector_t.taglist"},
|
||||
#endif
|
||||
{META_SIDENUM, "line_t.sidenum"},
|
||||
{META_LINEARGS, "line_t.args"},
|
||||
{META_LINESTRINGARGS, "line_t.stringargs"},
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
extern lua_State *gL;
|
||||
|
||||
#define MUTABLE_TAGS
|
||||
|
||||
#define LREG_VALID "VALID_USERDATA"
|
||||
#define LREG_EXTVARS "LUA_VARS"
|
||||
#define LREG_STATEACTION "STATE_ACTION"
|
||||
|
@ -27,6 +29,8 @@ extern lua_State *gL;
|
|||
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
||||
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
||||
|
||||
#define META_TAGLIST "TAGLIST"
|
||||
|
||||
#define META_MOBJ "MOBJ_T*"
|
||||
#define META_MAPTHING "MAPTHING_T*"
|
||||
|
||||
|
@ -58,6 +62,9 @@ extern lua_State *gL;
|
|||
#define META_CVAR "CONSVAR_T*"
|
||||
|
||||
#define META_SECTORLINES "SECTOR_T*LINES"
|
||||
#ifdef MUTABLE_TAGS
|
||||
#define META_SECTORTAGLIST "sector_t.taglist"
|
||||
#endif
|
||||
#define META_SIDENUM "LINE_T*SIDENUM"
|
||||
#define META_LINEARGS "LINE_T*ARGS"
|
||||
#define META_LINESTRINGARGS "LINE_T*STRINGARGS"
|
||||
|
@ -95,6 +102,7 @@ int LUA_PlayerLib(lua_State *L);
|
|||
int LUA_SkinLib(lua_State *L);
|
||||
int LUA_ThinkerLib(lua_State *L);
|
||||
int LUA_MapLib(lua_State *L);
|
||||
int LUA_TagLib(lua_State *L);
|
||||
int LUA_PolyObjLib(lua_State *L);
|
||||
int LUA_BlockmapLib(lua_State *L);
|
||||
int LUA_HudLib(lua_State *L);
|
||||
|
|
|
@ -37,6 +37,7 @@ enum sector_e {
|
|||
sector_lightlevel,
|
||||
sector_special,
|
||||
sector_tag,
|
||||
sector_taglist,
|
||||
sector_thinglist,
|
||||
sector_heightsec,
|
||||
sector_camsec,
|
||||
|
@ -55,6 +56,7 @@ static const char *const sector_opt[] = {
|
|||
"lightlevel",
|
||||
"special",
|
||||
"tag",
|
||||
"taglist",
|
||||
"thinglist",
|
||||
"heightsec",
|
||||
"camsec",
|
||||
|
@ -89,6 +91,7 @@ enum line_e {
|
|||
line_flags,
|
||||
line_special,
|
||||
line_tag,
|
||||
line_taglist,
|
||||
line_args,
|
||||
line_stringargs,
|
||||
line_sidenum,
|
||||
|
@ -113,6 +116,7 @@ static const char *const line_opt[] = {
|
|||
"flags",
|
||||
"special",
|
||||
"tag",
|
||||
"taglist",
|
||||
"args",
|
||||
"stringargs",
|
||||
"sidenum",
|
||||
|
@ -581,6 +585,9 @@ static int sector_get(lua_State *L)
|
|||
case sector_tag:
|
||||
lua_pushinteger(L, Tag_FGet(§or->tags));
|
||||
return 1;
|
||||
case sector_taglist:
|
||||
LUA_PushUserdata(L, §or->tags, META_SECTORTAGLIST);
|
||||
return 1;
|
||||
case sector_thinglist: // thinglist
|
||||
lua_pushcfunction(L, lib_iterateSectorThinglist);
|
||||
LUA_PushUserdata(L, sector->thinglist, META_MOBJ);
|
||||
|
@ -682,6 +689,8 @@ static int sector_set(lua_State *L)
|
|||
case sector_tag:
|
||||
Tag_SectorFSet((UINT32)(sector - sectors), (INT16)luaL_checkinteger(L, 3));
|
||||
break;
|
||||
case sector_taglist:
|
||||
return LUA_ErrSetDirectly(L, "sector_t", "taglist");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -821,6 +830,9 @@ static int line_get(lua_State *L)
|
|||
case line_tag:
|
||||
lua_pushinteger(L, Tag_FGet(&line->tags));
|
||||
return 1;
|
||||
case line_taglist:
|
||||
LUA_PushUserdata(L, &line->tags, META_TAGLIST);
|
||||
return 1;
|
||||
case line_args:
|
||||
LUA_PushUserdata(L, line->args, META_LINEARGS);
|
||||
return 1;
|
||||
|
@ -1385,25 +1397,15 @@ static int lib_iterateSectors(lua_State *L)
|
|||
|
||||
static int lib_getSector(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
size_t i = lua_tointeger(L, 2);
|
||||
if (i >= numsectors)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, §ors[i], META_SECTOR);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateSectors);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1489,25 +1491,15 @@ static int lib_iterateLines(lua_State *L)
|
|||
|
||||
static int lib_getLine(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
size_t i = lua_tointeger(L, 2);
|
||||
if (i >= numlines)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &lines[i], META_LINE);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateLines);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2360,15 +2352,13 @@ int LUA_MapLib(lua_State *L)
|
|||
//lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSector);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numsectors);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "sectors");
|
||||
LUA_PushTaggableObjectArray(L, "sectors",
|
||||
lib_iterateSectors,
|
||||
lib_getSector,
|
||||
lib_numsectors,
|
||||
tags_sectors,
|
||||
&numsectors, §ors,
|
||||
sizeof (sector_t), META_SECTOR);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
|
@ -2380,15 +2370,13 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "subsectors");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getLine);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numlines);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "lines");
|
||||
LUA_PushTaggableObjectArray(L, "lines",
|
||||
lib_iterateLines,
|
||||
lib_getLine,
|
||||
lib_numlines,
|
||||
tags_lines,
|
||||
&numlines, &lines,
|
||||
sizeof (line_t), META_LINE);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include "lua_hud.h" // hud_running errors
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
|
||||
enum mobj_e {
|
||||
mobj_valid = 0,
|
||||
mobj_x,
|
||||
|
@ -904,6 +902,11 @@ static int mapthing_get(lua_State *L)
|
|||
number = mt->extrainfo;
|
||||
else if(fastcmp(field,"tag"))
|
||||
number = Tag_FGet(&mt->tags);
|
||||
else if(fastcmp(field,"taglist"))
|
||||
{
|
||||
LUA_PushUserdata(L, &mt->tags, META_TAGLIST);
|
||||
return 1;
|
||||
}
|
||||
else if(fastcmp(field,"args"))
|
||||
{
|
||||
LUA_PushUserdata(L, mt->args, META_THINGARGS);
|
||||
|
@ -966,6 +969,8 @@ static int mapthing_set(lua_State *L)
|
|||
}
|
||||
else if (fastcmp(field,"tag"))
|
||||
Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3));
|
||||
else if (fastcmp(field,"taglist"))
|
||||
return LUA_ErrSetDirectly(L, "mapthing_t", "taglist");
|
||||
else if(fastcmp(field,"mobj"))
|
||||
mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
||||
else
|
||||
|
@ -1003,25 +1008,15 @@ static int lib_iterateMapthings(lua_State *L)
|
|||
|
||||
static int lib_getMapthing(lua_State *L)
|
||||
{
|
||||
int field;
|
||||
INLEVEL
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // dummy userdata table is unused.
|
||||
if (lua_isnumber(L, 1))
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
size_t i = lua_tointeger(L, 1);
|
||||
size_t i = lua_tointeger(L, 2);
|
||||
if (i >= nummapthings)
|
||||
return 0;
|
||||
LUA_PushUserdata(L, &mapthings[i], META_MAPTHING);
|
||||
return 1;
|
||||
}
|
||||
field = luaL_checkoption(L, 1, NULL, array_opt);
|
||||
switch(field)
|
||||
{
|
||||
case 0: // iterate
|
||||
lua_pushcfunction(L, lib_iterateMapthings);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1068,14 +1063,13 @@ int LUA_MobjLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L,1);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getMapthing);
|
||||
lua_setfield(L, -2, "__index");
|
||||
LUA_PushTaggableObjectArray(L, "mapthings",
|
||||
lib_iterateMapthings,
|
||||
lib_getMapthing,
|
||||
lib_nummapthings,
|
||||
tags_mapthings,
|
||||
&nummapthings, &mapthings,
|
||||
sizeof (mapthing_t), META_MAPTHING);
|
||||
|
||||
lua_pushcfunction(L, lib_nummapthings);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "mapthings");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ static lua_CFunction liblist[] = {
|
|||
LUA_SkinLib, // skin_t, skins[]
|
||||
LUA_ThinkerLib, // thinker_t
|
||||
LUA_MapLib, // line_t, side_t, sector_t, subsector_t
|
||||
LUA_TagLib, // tags
|
||||
LUA_PolyObjLib, // polyobj_t
|
||||
LUA_BlockmapLib, // blockmap stuff
|
||||
LUA_HudLib, // HUD stuff
|
||||
|
@ -739,25 +740,37 @@ void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta)
|
|||
// Pushes it to the stack and stores it in the registry.
|
||||
void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
|
||||
{
|
||||
if (LUA_RawPushUserdata(L, data) == LPUSHED_NEW)
|
||||
{
|
||||
luaL_getmetatable(L, meta);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
// Same as LUA_PushUserdata but don't set a metatable yet.
|
||||
lpushed_t LUA_RawPushUserdata(lua_State *L, void *data)
|
||||
{
|
||||
lpushed_t status = LPUSHED_NIL;
|
||||
|
||||
void **userdata;
|
||||
|
||||
if (!data) { // push a NULL
|
||||
lua_pushnil(L);
|
||||
return;
|
||||
return status;
|
||||
}
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LREG_VALID);
|
||||
I_Assert(lua_istable(L, -1));
|
||||
|
||||
lua_pushlightuserdata(L, data);
|
||||
lua_rawget(L, -2);
|
||||
|
||||
if (lua_isnil(L, -1)) { // no userdata? deary me, we'll have to make one.
|
||||
lua_pop(L, 1); // pop the nil
|
||||
|
||||
// create the userdata
|
||||
userdata = lua_newuserdata(L, sizeof(void *));
|
||||
*userdata = data;
|
||||
luaL_getmetatable(L, meta);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
// Set it in the registry so we can find it again
|
||||
lua_pushlightuserdata(L, data); // k (store the userdata via the data's pointer)
|
||||
|
@ -765,8 +778,15 @@ void LUA_PushUserdata(lua_State *L, void *data, const char *meta)
|
|||
lua_rawset(L, -4);
|
||||
|
||||
// stack is left with the userdata on top, as if getting it had originally succeeded.
|
||||
|
||||
status = LPUSHED_NEW;
|
||||
}
|
||||
else
|
||||
status = LPUSHED_EXISTING;
|
||||
|
||||
lua_remove(L, -2); // remove LREG_VALID
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// When userdata is freed, use this function to remove it from Lua.
|
||||
|
@ -826,6 +846,7 @@ void LUA_InvalidateLevel(void)
|
|||
{
|
||||
LUA_InvalidateUserdata(§ors[i]);
|
||||
LUA_InvalidateUserdata(§ors[i].lines);
|
||||
LUA_InvalidateUserdata(§ors[i].tags);
|
||||
if (sectors[i].ffloors)
|
||||
{
|
||||
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||
|
@ -835,6 +856,7 @@ void LUA_InvalidateLevel(void)
|
|||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(&lines[i]);
|
||||
LUA_InvalidateUserdata(&lines[i].tags);
|
||||
LUA_InvalidateUserdata(lines[i].sidenum);
|
||||
}
|
||||
for (i = 0; i < numsides; i++)
|
||||
|
@ -866,7 +888,10 @@ void LUA_InvalidateMapthings(void)
|
|||
return;
|
||||
|
||||
for (i = 0; i < nummapthings; i++)
|
||||
{
|
||||
LUA_InvalidateUserdata(&mapthings[i]);
|
||||
LUA_InvalidateUserdata(&mapthings[i].tags);
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_InvalidatePlayer(player_t *player)
|
||||
|
@ -1681,3 +1706,36 @@ int Lua_optoption(lua_State *L, int narg,
|
|||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LUA_PushTaggableObjectArray
|
||||
( lua_State *L,
|
||||
const char *field,
|
||||
lua_CFunction iterator,
|
||||
lua_CFunction indexer,
|
||||
lua_CFunction counter,
|
||||
taggroup_t *garray[],
|
||||
size_t * max_elements,
|
||||
void * element_array,
|
||||
size_t sizeof_element,
|
||||
const char *meta)
|
||||
{
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, iterator);
|
||||
lua_setfield(L, -2, "iterate");
|
||||
|
||||
LUA_InsertTaggroupIterator(L, garray,
|
||||
max_elements, element_array, sizeof_element, meta);
|
||||
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushcfunction(L, indexer);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, counter);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, field);
|
||||
}
|
||||
|
|
|
@ -10,10 +10,14 @@
|
|||
/// \file lua_script.h
|
||||
/// \brief Lua scripting basics
|
||||
|
||||
#ifndef LUA_SCRIPT_H
|
||||
#define LUA_SCRIPT_H
|
||||
|
||||
#include "m_fixed.h"
|
||||
#include "doomtype.h"
|
||||
#include "d_player.h"
|
||||
#include "g_state.h"
|
||||
#include "taglist.h"
|
||||
|
||||
#include "blua/lua.h"
|
||||
#include "blua/lualib.h"
|
||||
|
@ -46,12 +50,6 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults);
|
|||
void LUA_DumpFile(const char *filename);
|
||||
#endif
|
||||
fixed_t LUA_EvalMath(const char *word);
|
||||
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
|
||||
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
|
||||
void LUA_InvalidateUserdata(void *data);
|
||||
void LUA_InvalidateLevel(void);
|
||||
void LUA_InvalidateMapthings(void);
|
||||
void LUA_InvalidatePlayer(player_t *player);
|
||||
void LUA_Step(void);
|
||||
void LUA_Archive(void);
|
||||
void LUA_UnArchive(void);
|
||||
|
@ -63,11 +61,49 @@ int Lua_optoption(lua_State *L, int narg,
|
|||
const char *def, const char *const lst[]);
|
||||
void LUA_HookNetArchive(lua_CFunction archFunc);
|
||||
|
||||
void LUA_PushTaggableObjectArray
|
||||
( lua_State *L,
|
||||
const char *field,
|
||||
lua_CFunction iterator,
|
||||
lua_CFunction indexer,
|
||||
lua_CFunction counter,
|
||||
taggroup_t *garray[],
|
||||
size_t * max_elements,
|
||||
void * element_array,
|
||||
size_t sizeof_element,
|
||||
const char *meta);
|
||||
|
||||
void LUA_InsertTaggroupIterator
|
||||
( lua_State *L,
|
||||
taggroup_t *garray[],
|
||||
size_t * max_elements,
|
||||
void * element_array,
|
||||
size_t sizeof_element,
|
||||
const char * meta);
|
||||
|
||||
typedef enum {
|
||||
LPUSHED_NIL,
|
||||
LPUSHED_NEW,
|
||||
LPUSHED_EXISTING,
|
||||
} lpushed_t;
|
||||
|
||||
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
|
||||
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
|
||||
lpushed_t LUA_RawPushUserdata(lua_State *L, void *data);
|
||||
|
||||
void LUA_InvalidateUserdata(void *data);
|
||||
|
||||
void LUA_InvalidateLevel(void);
|
||||
void LUA_InvalidateMapthings(void);
|
||||
void LUA_InvalidatePlayer(player_t *player);
|
||||
|
||||
// Console wrapper
|
||||
void COM_Lua_f(void);
|
||||
|
||||
#define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type ".");
|
||||
|
||||
#define LUA_ErrSetDirectly(L, type, field) luaL_error(L, type " field " LUA_QL(field) " cannot be set directly.")
|
||||
|
||||
// Deprecation warnings
|
||||
// Shows once upon use. Then doesn't show again.
|
||||
#define LUA_Deprecated(L,this_func,use_instead)\
|
||||
|
@ -98,3 +134,5 @@ void COM_Lua_f(void);
|
|||
|
||||
#define INLEVEL if (! ISINLEVEL)\
|
||||
return luaL_error(L, "This can only be used in a level!");
|
||||
|
||||
#endif/*LUA_SCRIPT_H*/
|
||||
|
|
451
src/lua_taglib.c
Normal file
451
src/lua_taglib.c
Normal file
|
@ -0,0 +1,451 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2020 by James R.
|
||||
// Copyright (C) 2020 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 lua_taglib.c
|
||||
/// \brief tag list iterator for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "taglist.h"
|
||||
#include "r_state.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
#ifdef MUTABLE_TAGS
|
||||
#include "z_zone.h"
|
||||
#endif
|
||||
|
||||
static int tag_iterator(lua_State *L)
|
||||
{
|
||||
INT32 tag = lua_isnil(L, 2) ? -1 : lua_tonumber(L, 2);
|
||||
do
|
||||
{
|
||||
if (++tag >= MAXTAGS)
|
||||
return 0;
|
||||
}
|
||||
while (! in_bit_array(tags_available, tag)) ;
|
||||
lua_pushnumber(L, tag);
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum {
|
||||
#define UPVALUE lua_upvalueindex
|
||||
up_garray = UPVALUE(1),
|
||||
up_max_elements = UPVALUE(2),
|
||||
up_element_array = UPVALUE(3),
|
||||
up_sizeof_element = UPVALUE(4),
|
||||
up_meta = UPVALUE(5),
|
||||
#undef UPVALUE
|
||||
};
|
||||
|
||||
static INT32 next_element(lua_State *L, const mtag_t tag, const size_t p)
|
||||
{
|
||||
taggroup_t ** garray = lua_touserdata(L, up_garray);
|
||||
const size_t * max_elements = lua_touserdata(L, up_max_elements);
|
||||
return Taggroup_Iterate(garray, *max_elements, tag, p);
|
||||
}
|
||||
|
||||
static void push_element(lua_State *L, void *element)
|
||||
{
|
||||
if (LUA_RawPushUserdata(L, element) == LPUSHED_NEW)
|
||||
{
|
||||
lua_pushvalue(L, up_meta);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
}
|
||||
|
||||
static void push_next_element(lua_State *L, const INT32 element)
|
||||
{
|
||||
char * element_array = *(char **)lua_touserdata(L, up_element_array);
|
||||
const size_t sizeof_element = lua_tonumber(L, up_sizeof_element);
|
||||
push_element(L, &element_array[element * sizeof_element]);
|
||||
}
|
||||
|
||||
struct element_iterator_state {
|
||||
mtag_t tag;
|
||||
size_t p;
|
||||
};
|
||||
|
||||
static int element_iterator(lua_State *L)
|
||||
{
|
||||
struct element_iterator_state * state = lua_touserdata(L, 1);
|
||||
if (lua_isnoneornil(L, 3))
|
||||
state->p = 0;
|
||||
lua_pushnumber(L, ++state->p);
|
||||
lua_gettable(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateTags(lua_State *L)
|
||||
{
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
lua_pushcfunction(L, tag_iterator);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return tag_iterator(L);
|
||||
}
|
||||
|
||||
static int lib_numTags(lua_State *L)
|
||||
{
|
||||
lua_pushnumber(L, num_tags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_getTaggroup(lua_State *L)
|
||||
{
|
||||
struct element_iterator_state *state;
|
||||
|
||||
mtag_t tag;
|
||||
|
||||
if (lua_gettop(L) > 1)
|
||||
return luaL_error(L, "too many arguments");
|
||||
|
||||
if (lua_isnoneornil(L, 1))
|
||||
{
|
||||
tag = MTAG_GLOBAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag = lua_tonumber(L, 1);
|
||||
luaL_argcheck(L, tag >= -1, 1, "tag out of range");
|
||||
}
|
||||
|
||||
state = lua_newuserdata(L, sizeof *state);
|
||||
state->tag = tag;
|
||||
state->p = 0;
|
||||
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_getTaggroupElement(lua_State *L)
|
||||
{
|
||||
const size_t p = luaL_checknumber(L, 2) - 1;
|
||||
const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1);
|
||||
const INT32 element = next_element(L, tag, p);
|
||||
|
||||
if (element == -1)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
push_next_element(L, element);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int lib_numTaggroupElements(lua_State *L)
|
||||
{
|
||||
const mtag_t tag = *(mtag_t *)lua_touserdata(L, 1);
|
||||
if (tag == MTAG_GLOBAL)
|
||||
lua_pushnumber(L, *(size_t *)lua_touserdata(L, up_max_elements));
|
||||
else
|
||||
{
|
||||
const taggroup_t ** garray = lua_touserdata(L, up_garray);
|
||||
lua_pushnumber(L, Taggroup_Count(garray[tag]));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef MUTABLE_TAGS
|
||||
static int meta_ref[2];
|
||||
#endif
|
||||
|
||||
static int has_valid_field(lua_State *L)
|
||||
{
|
||||
int equal;
|
||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
||||
equal = lua_rawequal(L, 2, -1);
|
||||
lua_pop(L, 1);
|
||||
return equal;
|
||||
}
|
||||
|
||||
static taglist_t * valid_taglist(lua_State *L, int idx, boolean getting)
|
||||
{
|
||||
taglist_t *list = *(taglist_t **)lua_touserdata(L, idx);
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
if (getting && has_valid_field(L))
|
||||
lua_pushboolean(L, 0);
|
||||
else
|
||||
LUA_ErrInvalid(L, "taglist");/* doesn't actually return */
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return list;
|
||||
}
|
||||
|
||||
static taglist_t * check_taglist(lua_State *L, int idx)
|
||||
{
|
||||
if (lua_isuserdata(L, idx) && lua_getmetatable(L, idx))
|
||||
{
|
||||
lua_getref(L, meta_ref[0]);
|
||||
lua_getref(L, meta_ref[1]);
|
||||
|
||||
if (lua_rawequal(L, -3, -2) || lua_rawequal(L, -3, -1))
|
||||
{
|
||||
lua_pop(L, 3);
|
||||
return valid_taglist(L, idx, false);
|
||||
}
|
||||
}
|
||||
|
||||
return luaL_argerror(L, idx, "must be a tag list"), NULL;
|
||||
}
|
||||
|
||||
static int taglist_get(lua_State *L)
|
||||
{
|
||||
const taglist_t *list = valid_taglist(L, 1, true);
|
||||
|
||||
if (list == NULL)/* valid check */
|
||||
return 1;
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
const size_t i = lua_tonumber(L, 2);
|
||||
|
||||
if (list && i <= list->count)
|
||||
{
|
||||
lua_pushnumber(L, list->tags[i - 1]);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if (has_valid_field(L))
|
||||
{
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_getmetatable(L, 1);
|
||||
lua_replace(L, 1);
|
||||
lua_rawget(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int taglist_len(lua_State *L)
|
||||
{
|
||||
const taglist_t *list = valid_taglist(L, 1, false);
|
||||
lua_pushnumber(L, list->count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int taglist_equal(lua_State *L)
|
||||
{
|
||||
const taglist_t *lhs = check_taglist(L, 1);
|
||||
const taglist_t *rhs = check_taglist(L, 2);
|
||||
lua_pushboolean(L, Tag_Compare(lhs, rhs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int taglist_iterator(lua_State *L)
|
||||
{
|
||||
const taglist_t *list = valid_taglist(L, 1, false);
|
||||
const size_t i = 1 + lua_tonumber(L, lua_upvalueindex(1));
|
||||
if (i <= list->count)
|
||||
{
|
||||
lua_pushnumber(L, list->tags[i - 1]);
|
||||
/* watch me exploit an upvalue as a control because
|
||||
I want to use the control as the value */
|
||||
lua_pushnumber(L, i);
|
||||
lua_replace(L, lua_upvalueindex(1));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int taglist_iterate(lua_State *L)
|
||||
{
|
||||
check_taglist(L, 1);
|
||||
lua_pushnumber(L, 0);
|
||||
lua_pushcclosure(L, taglist_iterator, 1);
|
||||
lua_pushvalue(L, 1);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int taglist_find(lua_State *L)
|
||||
{
|
||||
const taglist_t *list = check_taglist(L, 1);
|
||||
const mtag_t tag = luaL_checknumber(L, 2);
|
||||
lua_pushboolean(L, Tag_Find(list, tag));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int taglist_shares(lua_State *L)
|
||||
{
|
||||
const taglist_t *lhs = check_taglist(L, 1);
|
||||
const taglist_t *rhs = check_taglist(L, 2);
|
||||
lua_pushboolean(L, Tag_Share(lhs, rhs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* only sector tags are mutable... */
|
||||
|
||||
#ifdef MUTABLE_TAGS
|
||||
static size_t sector_of_taglist(taglist_t *list)
|
||||
{
|
||||
return (sector_t *)((char *)list - offsetof (sector_t, tags)) - sectors;
|
||||
}
|
||||
|
||||
static int this_taglist(lua_State *L)
|
||||
{
|
||||
lua_settop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int taglist_add(lua_State *L)
|
||||
{
|
||||
taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST);
|
||||
const mtag_t tag = luaL_checknumber(L, 2);
|
||||
|
||||
if (! Tag_Find(list, tag))
|
||||
{
|
||||
Taggroup_Add(tags_sectors, tag, sector_of_taglist(list));
|
||||
Tag_Add(list, tag);
|
||||
}
|
||||
|
||||
return this_taglist(L);
|
||||
}
|
||||
|
||||
static int taglist_remove(lua_State *L)
|
||||
{
|
||||
taglist_t *list = *(taglist_t **)luaL_checkudata(L, 1, META_SECTORTAGLIST);
|
||||
const mtag_t tag = luaL_checknumber(L, 2);
|
||||
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < list->count; ++i)
|
||||
{
|
||||
if (list->tags[i] == tag)
|
||||
{
|
||||
if (list->count > 1)
|
||||
{
|
||||
memmove(&list->tags[i], &list->tags[i + 1],
|
||||
(list->count - 1 - i) * sizeof (mtag_t));
|
||||
list->tags = Z_Realloc(list->tags,
|
||||
(--list->count) * sizeof (mtag_t), PU_LEVEL, NULL);
|
||||
Taggroup_Remove(tags_sectors, tag, sector_of_taglist(list));
|
||||
}
|
||||
else/* reset to default tag */
|
||||
Tag_SectorFSet(sector_of_taglist(list), 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this_taglist(L);
|
||||
}
|
||||
#endif/*MUTABLE_TAGS*/
|
||||
|
||||
void LUA_InsertTaggroupIterator
|
||||
( lua_State *L,
|
||||
taggroup_t *garray[],
|
||||
size_t * max_elements,
|
||||
void * element_array,
|
||||
size_t sizeof_element,
|
||||
const char * meta)
|
||||
{
|
||||
lua_createtable(L, 0, 3);
|
||||
lua_pushlightuserdata(L, garray);
|
||||
lua_pushlightuserdata(L, max_elements);
|
||||
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushlightuserdata(L, element_array);
|
||||
lua_pushnumber(L, sizeof_element);
|
||||
luaL_getmetatable(L, meta);
|
||||
lua_pushcclosure(L, lib_getTaggroupElement, 5);
|
||||
lua_setfield(L, -4, "__index");
|
||||
|
||||
lua_pushcclosure(L, lib_numTaggroupElements, 2);
|
||||
lua_setfield(L, -2, "__len");
|
||||
|
||||
lua_pushcfunction(L, element_iterator);
|
||||
lua_setfield(L, -2, "__call");
|
||||
lua_pushcclosure(L, lib_getTaggroup, 1);
|
||||
lua_setfield(L, -2, "tagged");
|
||||
}
|
||||
|
||||
static luaL_Reg taglist_lib[] = {
|
||||
{"iterate", taglist_iterate},
|
||||
{"find", taglist_find},
|
||||
{"shares", taglist_shares},
|
||||
#ifdef MUTABLE_TAGS
|
||||
{"add", taglist_add},
|
||||
{"remove", taglist_remove},
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
static void open_taglist(lua_State *L)
|
||||
{
|
||||
luaL_register(L, "taglist", taglist_lib);
|
||||
|
||||
lua_getfield(L, -1, "find");
|
||||
lua_setfield(L, -2, "has");
|
||||
}
|
||||
|
||||
#define new_literal(L, s) \
|
||||
(lua_pushliteral(L, s), luaL_ref(L, -2))
|
||||
|
||||
#ifdef MUTABLE_TAGS
|
||||
static int
|
||||
#else
|
||||
static void
|
||||
#endif
|
||||
set_taglist_metatable(lua_State *L, const char *meta)
|
||||
{
|
||||
luaL_newmetatable(L, meta);
|
||||
lua_pushcfunction(L, taglist_get);
|
||||
lua_createtable(L, 0, 1);
|
||||
new_literal(L, "valid");
|
||||
lua_setfenv(L, -2);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, taglist_len);
|
||||
lua_setfield(L, -2, "__len");
|
||||
|
||||
lua_pushcfunction(L, taglist_equal);
|
||||
lua_setfield(L, -2, "__eq");
|
||||
#ifdef MUTABLE_TAGS
|
||||
return luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
int LUA_TagLib(lua_State *L)
|
||||
{
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushcfunction(L, lib_iterateTags);
|
||||
lua_setfield(L, -2, "iterate");
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_numTags);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "tags");
|
||||
|
||||
open_taglist(L);
|
||||
|
||||
#ifdef MUTABLE_TAGS
|
||||
meta_ref[0] = set_taglist_metatable(L, META_TAGLIST);
|
||||
meta_ref[1] = set_taglist_metatable(L, META_SECTORTAGLIST);
|
||||
#else
|
||||
set_taglist_metatable(L, META_TAGLIST);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
11
src/m_menu.c
11
src/m_menu.c
|
@ -8421,7 +8421,7 @@ static void M_DrawLoadGameData(void)
|
|||
sprdef = &charbotskin->sprites[SPR2_SIGN];
|
||||
if (!sprdef->numframes)
|
||||
goto skipbot;
|
||||
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, 0);
|
||||
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin-1, charbotskin->prefcolor, GTC_CACHE);
|
||||
sprframe = &sprdef->spriteframes[0];
|
||||
patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
|
||||
|
||||
|
@ -8431,8 +8431,6 @@ static void M_DrawLoadGameData(void)
|
|||
charbotskin->highresscale,
|
||||
0, patch, colormap);
|
||||
|
||||
Z_Free(colormap);
|
||||
|
||||
tempx -= (20<<FRACBITS);
|
||||
//flip = V_FLIP;
|
||||
}
|
||||
|
@ -8441,7 +8439,7 @@ skipbot:
|
|||
if (!charskin) // shut up compiler
|
||||
goto skipsign;
|
||||
sprdef = &charskin->sprites[SPR2_SIGN];
|
||||
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, 0);
|
||||
colormap = R_GetTranslationColormap(savegameinfo[savetodraw].skinnum, charskin->prefcolor, GTC_CACHE);
|
||||
if (!sprdef->numframes)
|
||||
goto skipsign;
|
||||
sprframe = &sprdef->spriteframes[0];
|
||||
|
@ -8481,8 +8479,6 @@ skipsign:
|
|||
charskin->highresscale/2,
|
||||
0, patch, colormap);
|
||||
skiplife:
|
||||
if (colormap)
|
||||
Z_Free(colormap);
|
||||
|
||||
patch = W_CachePatchName("STLIVEX", PU_PATCH);
|
||||
|
||||
|
@ -11753,7 +11749,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
goto faildraw;
|
||||
|
||||
// ok, draw player sprite for sure now
|
||||
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, 0);
|
||||
colormap = R_GetTranslationColormap(setupm_fakeskin, setupm_fakecolor->color, GTC_CACHE);
|
||||
|
||||
if (multi_frame >= sprdef->numframes)
|
||||
multi_frame = 0;
|
||||
|
@ -11771,7 +11767,6 @@ static void M_DrawSetupMultiPlayerMenu(void)
|
|||
FixedDiv(skins[setupm_fakeskin].highresscale, skins[setupm_fakeskin].shieldscale),
|
||||
flags, patch, colormap);
|
||||
|
||||
Z_Free(colormap);
|
||||
goto colordraw;
|
||||
|
||||
faildraw:
|
||||
|
|
|
@ -279,6 +279,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype);
|
|||
void P_RespawnSpecials(void);
|
||||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
void P_SetMobjSpawnDefaults(mobj_t *mobj);
|
||||
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
|
96
src/p_mobj.c
96
src/p_mobj.c
|
@ -9837,7 +9837,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
|
|||
if (mobj->type == MT_REDFLAG)
|
||||
{
|
||||
if (!(mobj->flags2 & MF2_JUSTATTACKED))
|
||||
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80);
|
||||
CONS_Printf(M_GetText("The \205Red flag\200 has returned to base.\n"));
|
||||
|
||||
// Assumedly in splitscreen players will be on opposing teams
|
||||
if (players[consoleplayer].ctfteam == 1 || splitscreen)
|
||||
|
@ -9850,7 +9850,7 @@ static void P_FlagFuseThink(mobj_t *mobj)
|
|||
else // MT_BLUEFLAG
|
||||
{
|
||||
if (!(mobj->flags2 & MF2_JUSTATTACKED))
|
||||
CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80);
|
||||
CONS_Printf(M_GetText("The \204Blue flag\200 has returned to base.\n"));
|
||||
|
||||
// Assumedly in splitscreen players will be on opposing teams
|
||||
if (players[consoleplayer].ctfteam == 2 || splitscreen)
|
||||
|
@ -10440,52 +10440,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->x = x;
|
||||
mobj->y = y;
|
||||
|
||||
mobj->radius = info->radius;
|
||||
mobj->height = info->height;
|
||||
mobj->flags = info->flags;
|
||||
|
||||
mobj->health = (info->spawnhealth ? info->spawnhealth : 1);
|
||||
|
||||
mobj->reactiontime = info->reactiontime;
|
||||
|
||||
mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer
|
||||
|
||||
// do not set the state with P_SetMobjState,
|
||||
// because action routines can not be called yet
|
||||
st = &states[info->spawnstate];
|
||||
|
||||
mobj->state = st;
|
||||
mobj->tics = st->tics;
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
|
||||
mobj->friction = ORIG_FRICTION;
|
||||
|
||||
mobj->movefactor = FRACUNIT;
|
||||
|
||||
// All mobjs are created at 100% scale.
|
||||
mobj->scale = FRACUNIT;
|
||||
mobj->destscale = mobj->scale;
|
||||
mobj->scalespeed = FRACUNIT/12;
|
||||
|
||||
// TODO: Make this a special map header
|
||||
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
|
||||
mobj->destscale = FRACUNIT/2;
|
||||
|
||||
// Sprite rendering
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
mobj->floorspriteslope = NULL;
|
||||
P_SetMobjSpawnDefaults(mobj);
|
||||
|
||||
// set subsector and/or block links
|
||||
P_SetThingPosition(mobj);
|
||||
I_Assert(mobj->subsector != NULL);
|
||||
|
||||
// Make sure scale matches destscale immediately when spawned
|
||||
P_SetScale(mobj, mobj->destscale);
|
||||
|
||||
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||
|
||||
|
@ -10787,6 +10747,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->frame &= ~FF_FRAMEMASK;
|
||||
}
|
||||
|
||||
st = &states[info->spawnstate];
|
||||
|
||||
// Call action functions when the state is set
|
||||
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
|
||||
{
|
||||
|
@ -10817,6 +10779,52 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
return mobj;
|
||||
}
|
||||
|
||||
void P_SetMobjSpawnDefaults(mobj_t *mobj)
|
||||
{
|
||||
const mobjinfo_t *info = mobj->info;
|
||||
state_t *st = &states[info->spawnstate];
|
||||
|
||||
mobj->radius = info->radius;
|
||||
mobj->height = info->height;
|
||||
mobj->flags = info->flags;
|
||||
|
||||
mobj->health = (info->spawnhealth ? info->spawnhealth : 1);
|
||||
|
||||
mobj->reactiontime = info->reactiontime;
|
||||
|
||||
mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer
|
||||
|
||||
// do not set the state with P_SetMobjState,
|
||||
// because action routines can not be called yet
|
||||
mobj->state = st;
|
||||
mobj->tics = st->tics;
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
|
||||
P_SetupStateAnimation(mobj, st);
|
||||
|
||||
mobj->friction = ORIG_FRICTION;
|
||||
|
||||
mobj->movefactor = FRACUNIT;
|
||||
|
||||
// All mobjs are created at 100% scale.
|
||||
mobj->scale = FRACUNIT;
|
||||
mobj->destscale = mobj->scale;
|
||||
mobj->scalespeed = FRACUNIT/12;
|
||||
|
||||
// TODO: Make this a special map header
|
||||
if ((maptol & TOL_ERZ3) && !(mobj->type == MT_BLACKEGGMAN))
|
||||
mobj->destscale = FRACUNIT/2;
|
||||
|
||||
// Make sure scale matches destscale immediately when spawned
|
||||
P_SetScale(mobj, mobj->destscale);
|
||||
|
||||
// Sprite rendering
|
||||
mobj->blendmode = AST_TRANSLUCENT;
|
||||
mobj->spritexscale = mobj->spriteyscale = FRACUNIT;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
mobj->floorspriteslope = NULL;
|
||||
}
|
||||
|
||||
static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
{
|
||||
state_t *st;
|
||||
|
@ -11798,7 +11806,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
|||
if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA)))
|
||||
return false; // she doesn't hang out here
|
||||
|
||||
if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3)
|
||||
if (!(netgame || multiplayer) && players[consoleplayer].skin == 3)
|
||||
return false; // no doubles
|
||||
|
||||
break;
|
||||
|
|
|
@ -1506,7 +1506,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
{
|
||||
const mobj_t *mobj = (const mobj_t *)th;
|
||||
UINT32 diff;
|
||||
UINT16 diff2;
|
||||
UINT32 diff2;
|
||||
|
||||
// Ignore stationary hoops - these will be respawned from mapthings.
|
||||
if (mobj->type == MT_HOOP)
|
||||
|
@ -1638,7 +1638,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_SHADOWSCALE;
|
||||
if (mobj->renderflags)
|
||||
diff2 |= MD2_RENDERFLAGS;
|
||||
if (mobj->renderflags)
|
||||
if (mobj->blendmode != AST_TRANSLUCENT)
|
||||
diff2 |= MD2_BLENDMODE;
|
||||
if (mobj->spritexscale != FRACUNIT)
|
||||
diff2 |= MD2_SPRITEXSCALE;
|
||||
|
@ -1646,6 +1646,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
diff2 |= MD2_SPRITEYSCALE;
|
||||
if (mobj->spritexoffset)
|
||||
diff2 |= MD2_SPRITEXOFFSET;
|
||||
if (mobj->spriteyoffset)
|
||||
diff2 |= MD2_SPRITEYOFFSET;
|
||||
if (mobj->floorspriteslope)
|
||||
{
|
||||
pslope_t *slope = mobj->floorspriteslope;
|
||||
|
@ -1667,7 +1669,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, diff);
|
||||
if (diff & MD_MORE)
|
||||
WRITEUINT16(save_p, diff2);
|
||||
WRITEUINT32(save_p, diff2);
|
||||
|
||||
// save pointer, at load time we will search this pointer to reinitilize pointers
|
||||
WRITEUINT32(save_p, (size_t)mobj);
|
||||
|
@ -2615,14 +2617,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
thinker_t *next;
|
||||
mobj_t *mobj;
|
||||
UINT32 diff;
|
||||
UINT16 diff2;
|
||||
UINT32 diff2;
|
||||
INT32 i;
|
||||
fixed_t z, floorz, ceilingz;
|
||||
ffloor_t *floorrover = NULL, *ceilingrover = NULL;
|
||||
|
||||
diff = READUINT32(save_p);
|
||||
if (diff & MD_MORE)
|
||||
diff2 = READUINT16(save_p);
|
||||
diff2 = READUINT32(save_p);
|
||||
else
|
||||
diff2 = 0;
|
||||
|
||||
|
@ -2690,7 +2692,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
}
|
||||
mobj->type = i;
|
||||
}
|
||||
|
||||
mobj->info = &mobjinfo[mobj->type];
|
||||
P_SetMobjSpawnDefaults(mobj);
|
||||
|
||||
if (diff & MD_POS)
|
||||
{
|
||||
mobj->x = READFIXED(save_p);
|
||||
|
@ -2716,35 +2721,21 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
|
||||
if (diff & MD_RADIUS)
|
||||
mobj->radius = READFIXED(save_p);
|
||||
else
|
||||
mobj->radius = mobj->info->radius;
|
||||
if (diff & MD_HEIGHT)
|
||||
mobj->height = READFIXED(save_p);
|
||||
else
|
||||
mobj->height = mobj->info->height;
|
||||
if (diff & MD_FLAGS)
|
||||
mobj->flags = READUINT32(save_p);
|
||||
else
|
||||
mobj->flags = mobj->info->flags;
|
||||
if (diff & MD_FLAGS2)
|
||||
mobj->flags2 = READUINT32(save_p);
|
||||
if (diff & MD_HEALTH)
|
||||
mobj->health = READINT32(save_p);
|
||||
else
|
||||
mobj->health = mobj->info->spawnhealth;
|
||||
if (diff & MD_RTIME)
|
||||
mobj->reactiontime = READINT32(save_p);
|
||||
else
|
||||
mobj->reactiontime = mobj->info->reactiontime;
|
||||
|
||||
if (diff & MD_STATE)
|
||||
mobj->state = &states[READUINT16(save_p)];
|
||||
else
|
||||
mobj->state = &states[mobj->info->spawnstate];
|
||||
if (diff & MD_TICS)
|
||||
mobj->tics = READINT32(save_p);
|
||||
else
|
||||
mobj->tics = mobj->state->tics;
|
||||
if (diff & MD_SPRITE) {
|
||||
mobj->sprite = READUINT16(save_p);
|
||||
if (mobj->sprite == SPR_PLAY)
|
||||
|
@ -2760,11 +2751,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->frame = READUINT32(save_p);
|
||||
mobj->anim_duration = READUINT16(save_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->frame = mobj->state->frame;
|
||||
mobj->anim_duration = (UINT16)mobj->state->var2;
|
||||
}
|
||||
if (diff & MD_EFLAGS)
|
||||
mobj->eflags = READUINT16(save_p);
|
||||
if (diff & MD_PLAYER)
|
||||
|
@ -2781,20 +2767,14 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->threshold = READINT32(save_p);
|
||||
if (diff & MD_LASTLOOK)
|
||||
mobj->lastlook = READINT32(save_p);
|
||||
else
|
||||
mobj->lastlook = -1;
|
||||
if (diff & MD_TARGET)
|
||||
mobj->target = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
if (diff & MD_TRACER)
|
||||
mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p);
|
||||
if (diff & MD_FRICTION)
|
||||
mobj->friction = READFIXED(save_p);
|
||||
else
|
||||
mobj->friction = ORIG_FRICTION;
|
||||
if (diff & MD_MOVEFACTOR)
|
||||
mobj->movefactor = READFIXED(save_p);
|
||||
else
|
||||
mobj->movefactor = FRACUNIT;
|
||||
if (diff & MD_FUSE)
|
||||
mobj->fuse = READINT32(save_p);
|
||||
if (diff & MD_WATERTOP)
|
||||
|
@ -2803,16 +2783,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
mobj->waterbottom = READFIXED(save_p);
|
||||
if (diff & MD_SCALE)
|
||||
mobj->scale = READFIXED(save_p);
|
||||
else
|
||||
mobj->scale = FRACUNIT;
|
||||
if (diff & MD_DSCALE)
|
||||
mobj->destscale = READFIXED(save_p);
|
||||
else
|
||||
mobj->destscale = mobj->scale;
|
||||
if (diff2 & MD2_SCALESPEED)
|
||||
mobj->scalespeed = READFIXED(save_p);
|
||||
else
|
||||
mobj->scalespeed = FRACUNIT/12;
|
||||
if (diff2 & MD2_CUSVAL)
|
||||
mobj->cusval = READINT32(save_p);
|
||||
if (diff2 & MD2_CVMEM)
|
||||
|
|
|
@ -3171,7 +3171,7 @@ static void P_ConvertBinaryMap(void)
|
|||
switch (mapthings[i].type)
|
||||
{
|
||||
case 750:
|
||||
Tag_Add(&mapthings[i].tags, mapthings[i].angle);
|
||||
Tag_FSet(&mapthings[i].tags, mapthings[i].angle);
|
||||
break;
|
||||
case 760:
|
||||
case 761:
|
||||
|
|
|
@ -4304,7 +4304,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
if (leveltime % (TICRATE/2) == 0 && player->rings > 0)
|
||||
{
|
||||
player->rings--;
|
||||
S_StartSound(player->mo, sfx_itemup);
|
||||
S_StartSound(player->mo, sfx_antiri);
|
||||
}
|
||||
break;
|
||||
case 11: // Special Stage Damage
|
||||
|
@ -4604,7 +4604,7 @@ DoneSection2:
|
|||
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sBLUE FLAG%s.\\\\\\\\"), "\x85", player_names[player-players], "\x80", "\x84", "\x80"));
|
||||
HU_DoCEcho(va(M_GetText("\205%s\200\\CAPTURED THE \204BLUE FLAG\200.\\\\\\\\"), player_names[player-players]));
|
||||
|
||||
if (splitscreen || players[consoleplayer].ctfteam == 1)
|
||||
S_StartSound(NULL, sfx_flgcap);
|
||||
|
@ -4637,7 +4637,7 @@ DoneSection2:
|
|||
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(va(M_GetText("%s%s%s\\CAPTURED THE %sRED FLAG%s.\\\\\\\\"), "\x84", player_names[player-players], "\x80", "\x85", "\x80"));
|
||||
HU_DoCEcho(va(M_GetText("\204%s\200\\CAPTURED THE \205RED FLAG\200.\\\\\\\\"), player_names[player-players]));
|
||||
|
||||
if (splitscreen || players[consoleplayer].ctfteam == 2)
|
||||
S_StartSound(NULL, sfx_flgcap);
|
||||
|
@ -4827,6 +4827,8 @@ DoneSection2:
|
|||
|
||||
if (player->laps >= (UINT8)cv_numlaps.value)
|
||||
CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]);
|
||||
else if (player->laps == (UINT8)cv_numlaps.value-1)
|
||||
CONS_Printf(M_GetText("%s started the \205final lap\200!\n"), player_names[player-players]);
|
||||
else
|
||||
CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);
|
||||
|
||||
|
|
16
src/p_user.c
16
src/p_user.c
|
@ -5024,7 +5024,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
|
|||
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN)
|
||||
&& ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted
|
||||
{
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT)
|
||||
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
|
||||
{
|
||||
if ((lockonshield = P_LookForEnemies(player, false, false)))
|
||||
{
|
||||
|
@ -5047,7 +5047,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
|
|||
}
|
||||
}
|
||||
}
|
||||
if (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial))) // Spin button effects
|
||||
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects
|
||||
{
|
||||
// Force stop
|
||||
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
|
||||
|
@ -5495,7 +5495,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super])
|
||||
else if ((!(player->charflags & SF_NOSHIELDABILITY)) && ((player->powers[pw_shield] & SH_NOSTACK) == SH_WHIRLWIND && !player->powers[pw_super] && !LUA_HookPlayer(player, HOOK(ShieldSpecial))))
|
||||
P_DoJumpShield(player);
|
||||
}
|
||||
|
||||
|
@ -7756,6 +7756,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
|
||||
P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale));
|
||||
P_SetObjectMomZ(flame, 3*FRACUNIT, false);
|
||||
if (!(gametyperules & GTR_FRIENDLY))
|
||||
{
|
||||
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
|
||||
flame->color = player->mo->color;
|
||||
}
|
||||
}
|
||||
#undef limitangle
|
||||
#undef numangles
|
||||
|
@ -7783,6 +7788,11 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
|
|||
flame->destscale = player->mo->scale;
|
||||
P_SetScale(flame, player->mo->scale);
|
||||
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
|
||||
if (!(gametyperules & GTR_FRIENDLY))
|
||||
{
|
||||
P_SetMobjState(flame, S_TEAM_SPINFIRE1);
|
||||
flame->color = player->mo->color;
|
||||
}
|
||||
|
||||
flame->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others
|
||||
P_XYMovement(flame);
|
||||
|
|
|
@ -544,21 +544,22 @@ void *Picture_GetPatchPixel(
|
|||
UINT16 *s16 = NULL;
|
||||
UINT32 *s32 = NULL;
|
||||
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
|
||||
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
|
||||
INT16 width;
|
||||
|
||||
if (patch == NULL)
|
||||
I_Error("Picture_GetPatchPixel: patch == NULL");
|
||||
|
||||
width = (Picture_IsDoomPatchFormat(informat) ? patch->width : SHORT(patch->width));
|
||||
width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
|
||||
|
||||
if (x >= 0 && x < width)
|
||||
{
|
||||
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
INT32 colofs = (Picture_IsDoomPatchFormat(informat) ? LONG(patch->columnofs[colx]) : patch->columnofs[colx]);
|
||||
INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]);
|
||||
|
||||
// Column offsets are pointers so no casting required
|
||||
if (Picture_IsDoomPatchFormat(informat))
|
||||
// Column offsets are pointers, so no casting is required.
|
||||
if (isdoompatch)
|
||||
column = (column_t *)((UINT8 *)doompatch + colofs);
|
||||
else
|
||||
column = (column_t *)((UINT8 *)patch->columns + colofs);
|
||||
|
|
|
@ -607,6 +607,7 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
|
|||
void R_DrawPlanes(void)
|
||||
{
|
||||
visplane_t *pl;
|
||||
angle_t va = viewangle;
|
||||
INT32 i;
|
||||
|
||||
R_UpdatePlaneRipple();
|
||||
|
@ -621,6 +622,8 @@ void R_DrawPlanes(void)
|
|||
R_DrawSinglePlane(pl);
|
||||
}
|
||||
}
|
||||
|
||||
viewangle = va;
|
||||
}
|
||||
|
||||
// R_DrawSkyPlane
|
||||
|
@ -705,9 +708,9 @@ void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planev
|
|||
n.z = -xscale * cos(ang);
|
||||
|
||||
ang = ANG2RAD(planeangle);
|
||||
temp = P_GetSlopeZAt(slope, planeviewx + yscale * FLOAT_TO_FIXED(sin(ang)), planeviewy + yscale * FLOAT_TO_FIXED(cos(ang)));
|
||||
temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(yscale * sin(ang)), planeviewy + FLOAT_TO_FIXED(yscale * cos(ang)));
|
||||
m.y = FIXED_TO_FLOAT(temp) - zeroheight;
|
||||
temp = P_GetSlopeZAt(slope, planeviewx + xscale * FLOAT_TO_FIXED(cos(ang)), planeviewy - xscale * FLOAT_TO_FIXED(sin(ang)));
|
||||
temp = P_GetSlopeZAt(slope, planeviewx + FLOAT_TO_FIXED(xscale * cos(ang)), planeviewy - FLOAT_TO_FIXED(xscale * sin(ang)));
|
||||
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
|
||||
|
||||
if (ds_powersoftwo)
|
||||
|
@ -788,7 +791,6 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
ffloor_t *rover;
|
||||
int type;
|
||||
int spanfunctype = BASEDRAWFUNC;
|
||||
angle_t viewang = viewangle;
|
||||
|
||||
if (!(pl->minx <= pl->maxx))
|
||||
return;
|
||||
|
@ -1153,8 +1155,6 @@ using the palette colors.
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
viewangle = viewang;
|
||||
}
|
||||
|
||||
void R_PlaneBounds(visplane_t *plane)
|
||||
|
|
|
@ -514,6 +514,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
|||
GETFLAG(NOSUPERSPRITES)
|
||||
GETFLAG(NOSUPERJUMPBOOST)
|
||||
GETFLAG(CANBUSTWALLS)
|
||||
GETFLAG(NOSHIELDABILITY)
|
||||
#undef GETFLAG
|
||||
|
||||
else // let's check if it's a sound, otherwise error out
|
||||
|
|
|
@ -604,7 +604,7 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
levelflat->height = ds_flatheight = SHORT(patch->height);
|
||||
|
||||
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
|
||||
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, patch->topoffset, patch->leftoffset, 0);
|
||||
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
|
||||
M_Memcpy(levelflat->picture, converted, size);
|
||||
Z_Free(converted);
|
||||
}
|
||||
|
|
|
@ -1298,6 +1298,10 @@ boolean I_PlaySong(boolean looping)
|
|||
if (gme)
|
||||
{
|
||||
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
|
||||
#if GME_VERSION >= 0x000603
|
||||
if (looping)
|
||||
gme_set_autoload_playback_limit(gme, 0);
|
||||
#endif
|
||||
gme_set_equalizer(gme, &eq);
|
||||
gme_start_track(gme, 0);
|
||||
current_track = 0;
|
||||
|
|
130
src/taglist.c
130
src/taglist.c
|
@ -15,6 +15,11 @@
|
|||
#include "z_zone.h"
|
||||
#include "r_data.h"
|
||||
|
||||
// Bit array of whether a tag exists for sectors/lines/things.
|
||||
bitarray_t tags_available[BIT_ARRAY_SIZE (MAXTAGS)];
|
||||
|
||||
size_t num_tags;
|
||||
|
||||
// Taggroups are used to list elements of the same tag, for iteration.
|
||||
// Since elements can now have multiple tags, it means an element may appear
|
||||
// in several taggroups at the same time. These are built on level load.
|
||||
|
@ -105,6 +110,39 @@ size_t Taggroup_Find (const taggroup_t *group, const size_t id)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/// group->count, but also checks for NULL
|
||||
size_t Taggroup_Count (const taggroup_t *group)
|
||||
{
|
||||
return group ? group->count : 0;
|
||||
}
|
||||
|
||||
/// Iterate thru elements in a global taggroup.
|
||||
INT32 Taggroup_Iterate
|
||||
( taggroup_t *garray[],
|
||||
const size_t max_elements,
|
||||
const mtag_t tag,
|
||||
const size_t p)
|
||||
{
|
||||
const taggroup_t *group;
|
||||
|
||||
if (tag == MTAG_GLOBAL)
|
||||
{
|
||||
if (p < max_elements)
|
||||
return p;
|
||||
return -1;
|
||||
}
|
||||
|
||||
group = garray[(UINT16)tag];
|
||||
|
||||
if (group)
|
||||
{
|
||||
if (p < group->count)
|
||||
return group->elements[p];
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Add an element to a global taggroup.
|
||||
void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
|
||||
{
|
||||
|
@ -120,6 +158,12 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
|
|||
if (Taggroup_Find(group, id) != (size_t)-1)
|
||||
return;
|
||||
|
||||
if (! in_bit_array(tags_available, tag))
|
||||
{
|
||||
num_tags++;
|
||||
set_bit_array(tags_available, tag);
|
||||
}
|
||||
|
||||
// Create group if empty.
|
||||
if (!group)
|
||||
{
|
||||
|
@ -133,25 +177,34 @@ void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id)
|
|||
for (i = 0; i < group->count; i++)
|
||||
if (group->elements[i] > id)
|
||||
break;
|
||||
|
||||
group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL);
|
||||
|
||||
// Offset existing elements to make room for the new one.
|
||||
if (i < group->count)
|
||||
memmove(&group->elements[i + 1], &group->elements[i], group->count - i);
|
||||
}
|
||||
|
||||
group->elements = Z_Realloc(group->elements, (group->count + 1) * sizeof(size_t), PU_LEVEL, NULL);
|
||||
|
||||
// Offset existing elements to make room for the new one.
|
||||
if (i < group->count)
|
||||
memmove(&group->elements[i + 1], &group->elements[i], group->count - i);
|
||||
|
||||
group->count++;
|
||||
group->elements = Z_Realloc(group->elements, group->count * sizeof(size_t), PU_LEVEL, NULL);
|
||||
group->elements[i] = id;
|
||||
}
|
||||
|
||||
static size_t total_elements_with_tag (const mtag_t tag)
|
||||
{
|
||||
return
|
||||
(
|
||||
Taggroup_Count(tags_sectors[tag]) +
|
||||
Taggroup_Count(tags_lines[tag]) +
|
||||
Taggroup_Count(tags_mapthings[tag])
|
||||
);
|
||||
}
|
||||
|
||||
/// Remove an element from a global taggroup.
|
||||
void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
|
||||
{
|
||||
taggroup_t *group;
|
||||
size_t rempos;
|
||||
size_t newcount;
|
||||
size_t oldcount;
|
||||
|
||||
if (tag == MTAG_GLOBAL)
|
||||
return;
|
||||
|
@ -161,8 +214,14 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
|
|||
if ((rempos = Taggroup_Find(group, id)) == (size_t)-1)
|
||||
return;
|
||||
|
||||
if (group->count == 1 && total_elements_with_tag(tag) == 1)
|
||||
{
|
||||
num_tags--;
|
||||
unset_bit_array(tags_available, tag);
|
||||
}
|
||||
|
||||
// Strip away taggroup if no elements left.
|
||||
if (!(newcount = --group->count))
|
||||
if (!(oldcount = group->count--))
|
||||
{
|
||||
Z_Free(group->elements);
|
||||
Z_Free(group);
|
||||
|
@ -170,19 +229,18 @@ void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id)
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t *newelements = Z_Malloc(newcount * sizeof(size_t), PU_LEVEL, NULL);
|
||||
size_t *newelements = Z_Malloc(group->count * sizeof(size_t), PU_LEVEL, NULL);
|
||||
size_t i;
|
||||
|
||||
// Copy the previous entries save for the one to remove.
|
||||
for (i = 0; i < rempos; i++)
|
||||
newelements[i] = group->elements[i];
|
||||
|
||||
for (i = rempos + 1; i < group->count; i++)
|
||||
for (i = rempos + 1; i < oldcount; i++)
|
||||
newelements[i - 1] = group->elements[i];
|
||||
|
||||
Z_Free(group->elements);
|
||||
group->elements = newelements;
|
||||
group->count = newcount;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,6 +267,9 @@ void Taglist_InitGlobalTables(void)
|
|||
{
|
||||
size_t i, j;
|
||||
|
||||
memset(tags_available, 0, sizeof tags_available);
|
||||
num_tags = 0;
|
||||
|
||||
for (i = 0; i < MAXTAGS; i++)
|
||||
{
|
||||
tags_sectors[i] = NULL;
|
||||
|
@ -236,56 +297,17 @@ void Taglist_InitGlobalTables(void)
|
|||
|
||||
INT32 Tag_Iterate_Sectors (const mtag_t tag, const size_t p)
|
||||
{
|
||||
if (tag == MTAG_GLOBAL)
|
||||
{
|
||||
if (p < numsectors)
|
||||
return p;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tags_sectors[(UINT16)tag])
|
||||
{
|
||||
if (p < tags_sectors[(UINT16)tag]->count)
|
||||
return tags_sectors[(UINT16)tag]->elements[p];
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
return Taggroup_Iterate(tags_sectors, numsectors, tag, p);
|
||||
}
|
||||
|
||||
INT32 Tag_Iterate_Lines (const mtag_t tag, const size_t p)
|
||||
{
|
||||
if (tag == MTAG_GLOBAL)
|
||||
{
|
||||
if (p < numlines)
|
||||
return p;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tags_lines[(UINT16)tag])
|
||||
{
|
||||
if (p < tags_lines[(UINT16)tag]->count)
|
||||
return tags_lines[(UINT16)tag]->elements[p];
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
return Taggroup_Iterate(tags_lines, numlines, tag, p);
|
||||
}
|
||||
|
||||
INT32 Tag_Iterate_Things (const mtag_t tag, const size_t p)
|
||||
{
|
||||
if (tag == MTAG_GLOBAL)
|
||||
{
|
||||
if (p < nummapthings)
|
||||
return p;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tags_mapthings[(UINT16)tag])
|
||||
{
|
||||
if (p < tags_mapthings[(UINT16)tag]->count)
|
||||
return tags_mapthings[(UINT16)tag]->elements[p];
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
return Taggroup_Iterate(tags_mapthings, nummapthings, tag, p);
|
||||
}
|
||||
|
||||
INT32 Tag_FindLineSpecial(const INT16 special, const mtag_t tag)
|
||||
|
|
|
@ -43,6 +43,10 @@ typedef struct
|
|||
size_t count;
|
||||
} taggroup_t;
|
||||
|
||||
extern bitarray_t tags_available[];
|
||||
|
||||
extern size_t num_tags;
|
||||
|
||||
extern taggroup_t* tags_sectors[];
|
||||
extern taggroup_t* tags_lines[];
|
||||
extern taggroup_t* tags_mapthings[];
|
||||
|
@ -50,6 +54,13 @@ extern taggroup_t* tags_mapthings[];
|
|||
void Taggroup_Add (taggroup_t *garray[], const mtag_t tag, size_t id);
|
||||
void Taggroup_Remove (taggroup_t *garray[], const mtag_t tag, size_t id);
|
||||
size_t Taggroup_Find (const taggroup_t *group, const size_t id);
|
||||
size_t Taggroup_Count (const taggroup_t *group);
|
||||
|
||||
INT32 Taggroup_Iterate
|
||||
( taggroup_t *garray[],
|
||||
const size_t max_elements,
|
||||
const mtag_t tag,
|
||||
const size_t p);
|
||||
|
||||
void Taglist_InitGlobalTables(void);
|
||||
|
||||
|
|
|
@ -1747,6 +1747,9 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
|
|||
|
||||
void W_UnlockCachedPatch(void *patch)
|
||||
{
|
||||
if (!patch)
|
||||
return;
|
||||
|
||||
// The hardware code does its own memory management, as its patches
|
||||
// have different lifetimes from software's.
|
||||
#ifdef HWRENDER
|
||||
|
|
|
@ -1229,7 +1229,10 @@ void Y_StartIntermission(void)
|
|||
data.coop.tics = players[consoleplayer].realtime;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
|
||||
{
|
||||
if (strlen(data.coop.bonuses[i].patch))
|
||||
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
|
||||
}
|
||||
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH);
|
||||
|
||||
// get act number
|
||||
|
@ -1733,7 +1736,6 @@ static void Y_SetNullBonus(player_t *player, y_bonus_t *bstruct)
|
|||
{
|
||||
(void)player;
|
||||
memset(bstruct, 0, sizeof(y_bonus_t));
|
||||
strncpy(bstruct->patch, "MISSING", sizeof(bstruct->patch));
|
||||
}
|
||||
|
||||
//
|
||||
|
|
12
src/z_zone.c
12
src/z_zone.c
|
@ -813,12 +813,12 @@ static void Command_Memfree_f(void)
|
|||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
|
||||
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
|
||||
CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
|
||||
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
|
||||
CONS_Printf(M_GetText("HW model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
|
||||
CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10);
|
||||
CONS_Printf(M_GetText("Patch info headers : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
|
||||
CONS_Printf(M_GetText("Cached textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
|
||||
CONS_Printf(M_GetText("Texture colormaps : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
|
||||
CONS_Printf(M_GetText("Model textures : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRMODELTEXTURE)>>10));
|
||||
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
|
||||
CONS_Printf(M_GetText("All GPU textures : %7d KB\n"), HWR_GetTextureUsed()>>10);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue