mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-17 23:21:22 +00:00
Merge branch 'master' into next
This commit is contained in:
commit
31b1188a3e
28 changed files with 1008 additions and 920 deletions
|
@ -120,6 +120,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_main.c
|
||||
r_plane.c
|
||||
r_segs.c
|
||||
r_skins.c
|
||||
r_sky.c
|
||||
r_splats.c
|
||||
r_things.c
|
||||
|
@ -134,6 +135,7 @@ set(SRB2_CORE_RENDER_SOURCES
|
|||
r_main.h
|
||||
r_plane.h
|
||||
r_segs.h
|
||||
r_skins.h
|
||||
r_sky.h
|
||||
r_splats.h
|
||||
r_state.h
|
||||
|
|
|
@ -468,6 +468,7 @@ OBJS:=$(i_main_o) \
|
|||
$(OBJDIR)/r_main.o \
|
||||
$(OBJDIR)/r_plane.o \
|
||||
$(OBJDIR)/r_segs.o \
|
||||
$(OBJDIR)/r_skins.o \
|
||||
$(OBJDIR)/r_sky.o \
|
||||
$(OBJDIR)/r_splats.o \
|
||||
$(OBJDIR)/r_things.o \
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "g_input.h"
|
||||
#include "m_menu.h"
|
||||
#include "r_local.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "s_sound.h"
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "r_data.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_things.h" // R_Char2Frame
|
||||
#include "r_sky.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "r_state.h" // fadecolormap
|
||||
#include "r_draw.h" // transtable
|
||||
#include "p_pspr.h" // tr_transxxx
|
||||
#include "p_local.h"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "byteptr.h"
|
||||
#include "i_joy.h"
|
||||
#include "r_local.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "y_inter.h"
|
||||
#include "v_video.h"
|
||||
#include "dehacked.h" // get_number (for ghost thok)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "../tables.h"
|
||||
#include "../sounds.h"
|
||||
#include "../r_main.h"
|
||||
#include "../r_things.h"
|
||||
#include "../r_skins.h"
|
||||
#include "../m_random.h"
|
||||
#include "../p_local.h"
|
||||
#include "hw3dsdrv.h"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "r_main.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_things.h"
|
||||
#include "r_things.h" // R_Frame2Char etc
|
||||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "p_mobj.h"
|
||||
#include "g_game.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "b_bot.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "p_local.h"
|
||||
#include "g_game.h"
|
||||
#include "p_setup.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "doomdef.h"
|
||||
#ifdef HAVE_BLUA
|
||||
#include "fastcmp.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "v_video.h" // video flags
|
||||
|
||||
#include "g_game.h" // record info
|
||||
#include "r_things.h" // numskins
|
||||
#include "r_skins.h" // numskins
|
||||
#include "r_draw.h" // R_GetColorByName
|
||||
|
||||
// Map triggers for linedef executors
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
#ifndef __X_MENU__
|
||||
#define __X_MENU__
|
||||
|
||||
#include "doomstat.h" // for NUMGAMETYPES
|
||||
#include "d_event.h"
|
||||
#include "command.h"
|
||||
#include "r_things.h" // for SKINNAMESIZE
|
||||
#include "r_skins.h" // for SKINNAMESIZE
|
||||
#include "f_finale.h" // for ttmode_enum
|
||||
|
||||
//
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "m_misc.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "i_video.h"
|
||||
#include "z_zone.h"
|
||||
#include "lua_hook.h"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "r_main.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_splats.h"
|
||||
#include "s_sound.h"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "r_data.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "r_state.h"
|
||||
#include "w_wad.h"
|
||||
#include "y_inter.h"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "i_system.h"
|
||||
|
||||
#include "r_data.h"
|
||||
#include "r_things.h"
|
||||
#include "r_things.h" // for R_AddSpriteDefs
|
||||
#include "r_patch.h"
|
||||
#include "r_sky.h"
|
||||
#include "r_draw.h"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "m_cond.h" //unlock triggers
|
||||
#include "lua_hook.h" // LUAh_LinedefExecute
|
||||
#include "f_finale.h" // control text prompt
|
||||
#include "r_things.h" // skins
|
||||
#include "r_skins.h" // skins
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "hardware/hw3sound.h"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "p_local.h"
|
||||
#include "r_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "d_think.h"
|
||||
#include "r_sky.h"
|
||||
#include "p_setup.h"
|
||||
|
|
825
src/r_skins.c
Normal file
825
src/r_skins.c
Normal file
|
@ -0,0 +1,825 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-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 r_skins.c
|
||||
/// \brief Loading skins
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "console.h"
|
||||
#include "g_game.h"
|
||||
#include "r_local.h"
|
||||
#include "st_stuff.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_misc.h"
|
||||
#include "info.h" // spr2names
|
||||
#include "i_video.h" // rendermode
|
||||
#include "i_system.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "p_local.h"
|
||||
#include "dehacked.h" // get_number (for thok)
|
||||
#include "m_cond.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_md2.h"
|
||||
#endif
|
||||
|
||||
#ifdef PC_DOS
|
||||
#include <stdio.h> // for snprintf
|
||||
int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
INT32 numskins = 0;
|
||||
skin_t skins[MAXSKINS];
|
||||
|
||||
// FIXTHIS: don't work because it must be inistilised before the config load
|
||||
//#define SKINVALUES
|
||||
#ifdef SKINVALUES
|
||||
CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
|
||||
#endif
|
||||
|
||||
//
|
||||
// P_GetSkinSprite2
|
||||
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
|
||||
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
|
||||
//
|
||||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
||||
{
|
||||
UINT8 super = 0, i = 0;
|
||||
|
||||
if (!skin)
|
||||
return 0;
|
||||
|
||||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!skin->sprites[spr2].numframes
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i < 32) // recursion limiter
|
||||
{
|
||||
if (spr2 & FF_SPR2SUPER)
|
||||
{
|
||||
super = FF_SPR2SUPER;
|
||||
spr2 &= ~FF_SPR2SUPER;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(spr2)
|
||||
{
|
||||
// Normal special cases.
|
||||
case SPR2_JUMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = ((player
|
||||
? player->charability
|
||||
: skin->ability)
|
||||
== CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
// Use the handy list, that's what it's there for!
|
||||
default:
|
||||
spr2 = spr2defaults[spr2];
|
||||
break;
|
||||
}
|
||||
|
||||
spr2 |= super;
|
||||
}
|
||||
|
||||
if (i >= 32) // probably an infinite loop...
|
||||
return 0;
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
static void Sk_SetDefaultValue(skin_t *skin)
|
||||
{
|
||||
INT32 i;
|
||||
//
|
||||
// set default skin values
|
||||
//
|
||||
memset(skin, 0, sizeof (skin_t));
|
||||
snprintf(skin->name,
|
||||
sizeof skin->name, "skin %u", (UINT32)(skin-skins));
|
||||
skin->name[sizeof skin->name - 1] = '\0';
|
||||
skin->wadnum = INT16_MAX;
|
||||
|
||||
skin->flags = 0;
|
||||
|
||||
strcpy(skin->realname, "Someone");
|
||||
strcpy(skin->hudname, "???");
|
||||
|
||||
skin->starttranscolor = 96;
|
||||
skin->prefcolor = SKINCOLOR_GREEN;
|
||||
skin->supercolor = SKINCOLOR_SUPERGOLD1;
|
||||
skin->prefoppositecolor = 0; // use tables
|
||||
|
||||
skin->normalspeed = 36<<FRACBITS;
|
||||
skin->runspeed = 28<<FRACBITS;
|
||||
skin->thrustfactor = 5;
|
||||
skin->accelstart = 96;
|
||||
skin->acceleration = 40;
|
||||
|
||||
skin->ability = CA_NONE;
|
||||
skin->ability2 = CA2_SPINDASH;
|
||||
skin->jumpfactor = FRACUNIT;
|
||||
skin->actionspd = 30<<FRACBITS;
|
||||
skin->mindash = 15<<FRACBITS;
|
||||
skin->maxdash = 70<<FRACBITS;
|
||||
|
||||
skin->radius = mobjinfo[MT_PLAYER].radius;
|
||||
skin->height = mobjinfo[MT_PLAYER].height;
|
||||
skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3);
|
||||
|
||||
skin->shieldscale = FRACUNIT;
|
||||
skin->camerascale = FRACUNIT;
|
||||
|
||||
skin->thokitem = -1;
|
||||
skin->spinitem = -1;
|
||||
skin->revitem = -1;
|
||||
skin->followitem = 0;
|
||||
|
||||
skin->highresscale = FRACUNIT;
|
||||
skin->contspeed = 17;
|
||||
skin->contangle = 0;
|
||||
|
||||
skin->availability = 0;
|
||||
|
||||
for (i = 0; i < sfx_skinsoundslot0; i++)
|
||||
if (S_sfx[i].skinsound != -1)
|
||||
skin->soundsid[S_sfx[i].skinsound] = i;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the basic skins
|
||||
//
|
||||
void R_InitSkins(void)
|
||||
{
|
||||
#ifdef SKINVALUES
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i <= MAXSKINS; i++)
|
||||
{
|
||||
skin_cons_t[i].value = 0;
|
||||
skin_cons_t[i].strvalue = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// no default skin!
|
||||
numskins = 0;
|
||||
}
|
||||
|
||||
UINT32 R_GetSkinAvailabilities(void)
|
||||
{
|
||||
INT32 s;
|
||||
UINT32 response = 0;
|
||||
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
{
|
||||
if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked)
|
||||
response |= (1 << s);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
// returns true if available in circumstances, otherwise nope
|
||||
// warning don't use with an invalid skinnum other than -1 which always returns true
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|
||||
|| (!skins[skinnum].availability)
|
||||
|| (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked))
|
||||
|| (modeattacking) // If you have someone else's run you might as well take a look
|
||||
|| (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
|
||||
|| (netgame && (cv_forceskin.value == skinnum)) // Force 2.
|
||||
|| (metalrecording && skinnum == 5) // Force 3.
|
||||
);
|
||||
}
|
||||
|
||||
// returns true if the skin name is found (loaded from pwad)
|
||||
// warning return -1 if not found
|
||||
INT32 R_SkinAvailable(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
// search in the skin list
|
||||
if (stricmp(skins[i].name,name)==0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// network code calls this when a 'skin change' is received
|
||||
void SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||
{
|
||||
INT32 i = R_SkinAvailable(skinname);
|
||||
player_t *player = &players[playernum];
|
||||
|
||||
if ((i != -1) && R_SkinUsable(playernum, i))
|
||||
{
|
||||
SetPlayerSkinByNum(playernum, i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
||||
|
||||
SetPlayerSkinByNum(playernum, 0);
|
||||
}
|
||||
|
||||
// Same as SetPlayerSkin, but uses the skin #.
|
||||
// network code calls this when a 'skin change' is received
|
||||
void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
player_t *player = &players[playernum];
|
||||
skin_t *skin = &skins[skinnum];
|
||||
UINT8 newcolor = 0;
|
||||
|
||||
if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists!
|
||||
{
|
||||
player->skin = skinnum;
|
||||
|
||||
player->camerascale = skin->camerascale;
|
||||
player->shieldscale = skin->shieldscale;
|
||||
|
||||
player->charability = (UINT8)skin->ability;
|
||||
player->charability2 = (UINT8)skin->ability2;
|
||||
|
||||
player->charflags = (UINT32)skin->flags;
|
||||
|
||||
player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
|
||||
player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
|
||||
player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
|
||||
player->followitem = skin->followitem;
|
||||
|
||||
if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff.
|
||||
player->powers[pw_shield] &= SH_STACK;
|
||||
|
||||
player->actionspd = skin->actionspd;
|
||||
player->mindash = skin->mindash;
|
||||
player->maxdash = skin->maxdash;
|
||||
|
||||
player->normalspeed = skin->normalspeed;
|
||||
player->runspeed = skin->runspeed;
|
||||
player->thrustfactor = skin->thrustfactor;
|
||||
player->accelstart = skin->accelstart;
|
||||
player->acceleration = skin->acceleration;
|
||||
|
||||
player->jumpfactor = skin->jumpfactor;
|
||||
|
||||
player->height = skin->height;
|
||||
player->spinheight = skin->spinheight;
|
||||
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
{
|
||||
if (playernum == consoleplayer)
|
||||
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
|
||||
player->skincolor = newcolor = skin->prefcolor;
|
||||
}
|
||||
|
||||
if (player->followmobj)
|
||||
{
|
||||
P_RemoveMobj(player->followmobj);
|
||||
P_SetTarget(&player->followmobj, NULL);
|
||||
}
|
||||
|
||||
if (player->mo)
|
||||
{
|
||||
fixed_t radius = FixedMul(skin->radius, player->mo->scale);
|
||||
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;
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
newcolor = skin->prefcolor; // will be updated in thinker to flashing
|
||||
}
|
||||
player->mo->skin = skin;
|
||||
if (newcolor)
|
||||
player->mo->color = newcolor;
|
||||
P_SetScale(player->mo, player->mo->scale);
|
||||
player->mo->radius = radius;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
}
|
||||
|
||||
//
|
||||
// Add skins from a pwad, each skin preceded by 'S_SKIN' marker
|
||||
//
|
||||
|
||||
// Does the same is in w_wad, but check only for
|
||||
// the first 6 characters (this is so we can have S_SKIN1, S_SKIN2..
|
||||
// for wad editors that don't like multiple resources of the same name)
|
||||
//
|
||||
static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
const char *S_SKIN = "S_SKIN";
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
if (startlump < wadfiles[wadid]->numlumps)
|
||||
{
|
||||
lump_p = wadfiles[wadid]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name,S_SKIN,6)==0)
|
||||
return i;
|
||||
}
|
||||
return INT16_MAX; // not found
|
||||
}
|
||||
|
||||
#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value)
|
||||
|
||||
// turn _ into spaces and . into katana dot
|
||||
#define SYMBOLCONVERT(name) for (value = name; *value; value++)\
|
||||
{\
|
||||
if (*value == '_') *value = ' ';\
|
||||
else if (*value == '.') *value = '\x1E';\
|
||||
}
|
||||
|
||||
//
|
||||
// Patch skins from a pwad, each skin preceded by 'P_SKIN' marker
|
||||
//
|
||||
|
||||
// Does the same is in w_wad, but check only for
|
||||
// the first 6 characters (this is so we can have P_SKIN1, P_SKIN2..
|
||||
// for wad editors that don't like multiple resources of the same name)
|
||||
//
|
||||
static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
const char *P_SKIN = "P_SKIN";
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
if (startlump < wadfiles[wadid]->numlumps)
|
||||
{
|
||||
lump_p = wadfiles[wadid]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name,P_SKIN,6)==0)
|
||||
return i;
|
||||
}
|
||||
return INT16_MAX; // not found
|
||||
}
|
||||
|
||||
static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin)
|
||||
{
|
||||
UINT16 newlastlump;
|
||||
UINT8 sprite2;
|
||||
|
||||
*lump += 1; // start after S_SKIN
|
||||
*lastlump = W_CheckNumForNamePwad("S_END",wadnum,*lump); // stop at S_END
|
||||
|
||||
// old wadding practices die hard -- stop at S_SKIN (or P_SKIN) or S_START if they come before S_END.
|
||||
newlastlump = W_CheckForSkinMarkerInPwad(wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
newlastlump = W_CheckForPatchSkinMarkerInPwad(wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
newlastlump = W_CheckNumForNamePwad("S_START",wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
|
||||
// ...and let's handle super, too
|
||||
newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,*lump);
|
||||
if (newlastlump < *lastlump)
|
||||
{
|
||||
newlastlump++;
|
||||
// load all sprite sets we are aware of... for super!
|
||||
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
|
||||
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump);
|
||||
|
||||
newlastlump--;
|
||||
*lastlump = newlastlump; // okay, make the normal sprite set loading end there
|
||||
}
|
||||
|
||||
// load all sprite sets we are aware of... for normal stuff.
|
||||
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
|
||||
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, *lump, *lastlump);
|
||||
|
||||
if (skin->sprites[0].numframes == 0)
|
||||
I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
|
||||
}
|
||||
|
||||
// returns whether found appropriate property
|
||||
static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
||||
{
|
||||
// custom translation table
|
||||
if (!stricmp(stoken, "startcolor"))
|
||||
skin->starttranscolor = atoi(value);
|
||||
|
||||
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
|
||||
// character type identification
|
||||
FULLPROCESS(flags)
|
||||
FULLPROCESS(ability)
|
||||
FULLPROCESS(ability2)
|
||||
|
||||
FULLPROCESS(thokitem)
|
||||
FULLPROCESS(spinitem)
|
||||
FULLPROCESS(revitem)
|
||||
FULLPROCESS(followitem)
|
||||
#undef FULLPROCESS
|
||||
|
||||
#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
|
||||
GETFRACBITS(normalspeed)
|
||||
GETFRACBITS(runspeed)
|
||||
|
||||
GETFRACBITS(mindash)
|
||||
GETFRACBITS(maxdash)
|
||||
GETFRACBITS(actionspd)
|
||||
|
||||
GETFRACBITS(radius)
|
||||
GETFRACBITS(height)
|
||||
GETFRACBITS(spinheight)
|
||||
#undef GETFRACBITS
|
||||
|
||||
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
|
||||
GETINT(thrustfactor)
|
||||
GETINT(accelstart)
|
||||
GETINT(acceleration)
|
||||
GETINT(contspeed)
|
||||
GETINT(contangle)
|
||||
#undef GETINT
|
||||
|
||||
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
||||
GETSKINCOLOR(prefcolor)
|
||||
GETSKINCOLOR(prefoppositecolor)
|
||||
#undef GETSKINCOLOR
|
||||
else if (!stricmp(stoken, "supercolor"))
|
||||
skin->supercolor = R_GetSuperColorByName(value);
|
||||
|
||||
#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value));
|
||||
GETFLOAT(jumpfactor)
|
||||
GETFLOAT(highresscale)
|
||||
GETFLOAT(shieldscale)
|
||||
GETFLOAT(camerascale)
|
||||
#undef GETFLOAT
|
||||
|
||||
#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \
|
||||
strupr(value); \
|
||||
if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \
|
||||
skin->flags |= (SF_##field); \
|
||||
else \
|
||||
skin->flags &= ~(SF_##field); \
|
||||
}
|
||||
// parameters for individual character flags
|
||||
// these are uppercase so they can be concatenated with SF_
|
||||
// 1, true, yes are all valid values
|
||||
GETFLAG(SUPER)
|
||||
GETFLAG(NOSUPERSPIN)
|
||||
GETFLAG(NOSPINDASHDUST)
|
||||
GETFLAG(HIRES)
|
||||
GETFLAG(NOSKID)
|
||||
GETFLAG(NOSPEEDADJUST)
|
||||
GETFLAG(RUNONWATER)
|
||||
GETFLAG(NOJUMPSPIN)
|
||||
GETFLAG(NOJUMPDAMAGE)
|
||||
GETFLAG(STOMPDAMAGE)
|
||||
GETFLAG(MARIODAMAGE)
|
||||
GETFLAG(MACHINE)
|
||||
GETFLAG(DASHMODE)
|
||||
GETFLAG(FASTEDGE)
|
||||
GETFLAG(MULTIABILITY)
|
||||
GETFLAG(NONIGHTSROTATION)
|
||||
#undef GETFLAG
|
||||
|
||||
else // let's check if it's a sound, otherwise error out
|
||||
{
|
||||
boolean found = false;
|
||||
sfxenum_t i;
|
||||
size_t stokenadjust;
|
||||
|
||||
// Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.)
|
||||
if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS*
|
||||
stokenadjust = 2;
|
||||
else // sfx_*
|
||||
stokenadjust = 4;
|
||||
|
||||
// Remove the prefix. (We can affect this directly since we're not going to use it again.)
|
||||
if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS*
|
||||
value += 2;
|
||||
else // sfx_*
|
||||
value += 4;
|
||||
|
||||
// copy name of sounds that are remapped
|
||||
// for this skin
|
||||
for (i = 0; i < sfx_skinsoundslot0; i++)
|
||||
{
|
||||
if (!S_sfx[i].name)
|
||||
continue;
|
||||
if (S_sfx[i].skinsound != -1
|
||||
&& !stricmp(S_sfx[i].name,
|
||||
stoken + stokenadjust))
|
||||
{
|
||||
skin->soundsid[S_sfx[i].skinsound] =
|
||||
S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Find skin sprites, sounds & optional status bar face, & add them
|
||||
//
|
||||
void R_AddSkins(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lump, lastlump = 0;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean hudname, realname;
|
||||
|
||||
//
|
||||
// search for all skin markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckForSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX)
|
||||
{
|
||||
// advance by default
|
||||
lastlump = lump + 1;
|
||||
|
||||
if (numskins >= MAXSKINS)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS);
|
||||
continue; // so we know how many skins couldn't be added
|
||||
}
|
||||
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
// for strtok
|
||||
buf2 = malloc(size+1);
|
||||
if (!buf2)
|
||||
I_Error("R_AddSkins: No more free memory\n");
|
||||
M_Memcpy(buf2,buf,size);
|
||||
buf2[size] = '\0';
|
||||
|
||||
// set defaults
|
||||
skin = &skins[numskins];
|
||||
Sk_SetDefaultValue(skin);
|
||||
skin->wadnum = wadnum;
|
||||
hudname = realname = false;
|
||||
// parse
|
||||
stoken = strtok (buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto next_token; // find the real next token
|
||||
}
|
||||
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
|
||||
if (!value)
|
||||
I_Error("R_AddSkins: syntax error in S_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
|
||||
// Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines.
|
||||
// Others can't go in there because we don't want them to be patchable.
|
||||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
INT32 skinnum = R_SkinAvailable(value);
|
||||
strlwr(value);
|
||||
if (skinnum == -1)
|
||||
STRBUFCPY(skin->name, value);
|
||||
// the skin name must uniquely identify a single skin
|
||||
// if the name is already used I make the name 'namex'
|
||||
// using the default skin name's number set above
|
||||
else
|
||||
{
|
||||
const size_t stringspace =
|
||||
strlen(value) + sizeof (numskins) + 1;
|
||||
char *value2 = Z_Malloc(stringspace, PU_STATIC, NULL);
|
||||
snprintf(value2, stringspace,
|
||||
"%s%d", value, numskins);
|
||||
value2[stringspace - 1] = '\0';
|
||||
if (R_SkinAvailable(value2) == -1)
|
||||
// I'm lazy so if NEW name is already used I leave the 'skin x'
|
||||
// default skin name set in Sk_SetDefaultValue
|
||||
STRBUFCPY(skin->name, value2);
|
||||
Z_Free(value2);
|
||||
}
|
||||
|
||||
// copy to hudname and fullname as a default.
|
||||
if (!realname)
|
||||
{
|
||||
STRBUFCPY(skin->realname, skin->name);
|
||||
for (value = skin->realname; *value; value++)
|
||||
{
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
|
||||
}
|
||||
}
|
||||
if (!hudname)
|
||||
{
|
||||
HUDNAMEWRITE(skin->name);
|
||||
strupr(skin->hudname);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
}
|
||||
}
|
||||
else if (!stricmp(stoken, "realname"))
|
||||
{ // Display name (eg. "Knuckles")
|
||||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!stricmp(stoken, "availability"))
|
||||
{
|
||||
skin->availability = atoi(value);
|
||||
if (skin->availability >= MAXUNLOCKABLES)
|
||||
skin->availability = 0;
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
|
||||
next_token:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
}
|
||||
free(buf2);
|
||||
|
||||
// Add sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
if (!skin->availability) // Safe to print...
|
||||
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
|
||||
#ifdef SKINVALUES
|
||||
skin_cons_t[numskins].value = numskins;
|
||||
skin_cons_t[numskins].strvalue = skin->name;
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddPlayerModel(numskins);
|
||||
#endif
|
||||
|
||||
numskins++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Patch skin sprites
|
||||
//
|
||||
void R_PatchSkins(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lump, lastlump = 0;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean noskincomplain, realname, hudname;
|
||||
|
||||
//
|
||||
// search for all skin patch markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckForPatchSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX)
|
||||
{
|
||||
INT32 skinnum = 0;
|
||||
|
||||
// advance by default
|
||||
lastlump = lump + 1;
|
||||
|
||||
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
// for strtok
|
||||
buf2 = malloc(size+1);
|
||||
if (!buf2)
|
||||
I_Error("R_PatchSkins: No more free memory\n");
|
||||
M_Memcpy(buf2,buf,size);
|
||||
buf2[size] = '\0';
|
||||
|
||||
skin = NULL;
|
||||
noskincomplain = realname = hudname = false;
|
||||
|
||||
/*
|
||||
Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation)
|
||||
*/
|
||||
|
||||
stoken = strtok(buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto next_token; // find the real next token
|
||||
}
|
||||
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
|
||||
if (!value)
|
||||
I_Error("R_PatchSkins: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
|
||||
if (!skin) // Get the name!
|
||||
{
|
||||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
strlwr(value);
|
||||
skinnum = R_SkinAvailable(value);
|
||||
if (skinnum != -1)
|
||||
skin = &skins[skinnum];
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
noskincomplain = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Get the properties!
|
||||
{
|
||||
// Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines.
|
||||
if (!stricmp(stoken, "realname"))
|
||||
{ // Display name (eg. "Knuckles")
|
||||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
||||
if (!skin)
|
||||
break;
|
||||
|
||||
next_token:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
}
|
||||
free(buf2);
|
||||
|
||||
if (!skin) // Didn't include a name parameter? What a waste.
|
||||
{
|
||||
if (!noskincomplain)
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Patch sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
if (!skin->availability) // Safe to print...
|
||||
CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#undef HUDNAMEWRITE
|
||||
#undef SYMBOLCONVERT
|
103
src/r_skins.h
Normal file
103
src/r_skins.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-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 r_skins.h
|
||||
/// \brief Skins stuff
|
||||
|
||||
#ifndef __R_SKINS__
|
||||
#define __R_SKINS__
|
||||
|
||||
#include "info.h"
|
||||
#include "sounds.h"
|
||||
#include "d_player.h" // skinflags
|
||||
#include "r_patch.h" // spriteinfo_t
|
||||
#include "r_defs.h" // spritedef_t
|
||||
|
||||
/// Defaults
|
||||
#define SKINNAMESIZE 16
|
||||
// should be all lowercase!! S_SKIN processing does a strlwr
|
||||
#define DEFAULTSKIN "sonic"
|
||||
#define DEFAULTSKIN2 "tails" // secondary player
|
||||
#define DEFAULTNIGHTSSKIN 0
|
||||
|
||||
/// The skin_t struct
|
||||
typedef struct
|
||||
{
|
||||
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
|
||||
UINT16 wadnum;
|
||||
skinflags_t flags;
|
||||
|
||||
char realname[SKINNAMESIZE+1]; // Display name for level completion.
|
||||
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
|
||||
|
||||
UINT8 ability; // ability definition
|
||||
UINT8 ability2; // secondary ability definition
|
||||
INT32 thokitem;
|
||||
INT32 spinitem;
|
||||
INT32 revitem;
|
||||
INT32 followitem;
|
||||
fixed_t actionspd;
|
||||
fixed_t mindash;
|
||||
fixed_t maxdash;
|
||||
|
||||
fixed_t normalspeed; // Normal ground
|
||||
fixed_t runspeed; // Speed that you break into your run animation
|
||||
|
||||
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
|
||||
UINT8 accelstart; // Acceleration if speed = 0
|
||||
UINT8 acceleration; // Acceleration
|
||||
|
||||
fixed_t jumpfactor; // multiple of standard jump height
|
||||
|
||||
fixed_t radius; // Bounding box changes.
|
||||
fixed_t height;
|
||||
fixed_t spinheight;
|
||||
|
||||
fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size
|
||||
fixed_t camerascale;
|
||||
|
||||
// Definable color translation table
|
||||
UINT8 starttranscolor;
|
||||
UINT8 prefcolor;
|
||||
UINT8 supercolor;
|
||||
UINT8 prefoppositecolor; // if 0 use tables instead
|
||||
|
||||
fixed_t highresscale; // scale of highres, default is 0.5
|
||||
UINT8 contspeed; // continue screen animation speed
|
||||
UINT8 contangle; // initial angle on continue screen
|
||||
|
||||
// specific sounds per skin
|
||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||
|
||||
// contains super versions too
|
||||
spritedef_t sprites[NUMPLAYERSPRITES*2];
|
||||
spriteinfo_t sprinfo[NUMPLAYERSPRITES*2];
|
||||
|
||||
UINT8 availability; // lock?
|
||||
} skin_t;
|
||||
|
||||
/// Externs
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
|
||||
/// Function prototypes
|
||||
void R_InitSkins(void);
|
||||
|
||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum);
|
||||
UINT32 R_GetSkinAvailabilities(void);
|
||||
INT32 R_SkinAvailable(const char *name);
|
||||
void R_PatchSkins(UINT16 wadnum);
|
||||
void R_AddSkins(UINT16 wadnum);
|
||||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);
|
||||
|
||||
#endif //__R_SKINS__
|
814
src/r_things.c
814
src/r_things.c
|
@ -30,11 +30,8 @@
|
|||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
#include "dehacked.h" // get_number (for thok)
|
||||
#include "d_netfil.h" // blargh. for nameonly().
|
||||
#include "m_cheat.h" // objectplace
|
||||
#include "m_cond.h"
|
||||
#include "fastcmp.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_md2.h"
|
||||
#include "hardware/hw_glob.h"
|
||||
|
@ -42,14 +39,6 @@
|
|||
#include "hardware/hw_drv.h"
|
||||
#endif
|
||||
|
||||
#ifdef PC_DOS
|
||||
#include <stdio.h> // for snprintf
|
||||
int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
static void R_InitSkins(void);
|
||||
|
||||
#define MINZ (FRACUNIT*4)
|
||||
#define BASEYCENTER (BASEVIDHEIGHT/2)
|
||||
|
||||
|
@ -233,7 +222,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
|
|||
//
|
||||
// Returns true if the sprite was succesfully added
|
||||
//
|
||||
static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump)
|
||||
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump)
|
||||
{
|
||||
UINT16 l;
|
||||
UINT8 frame;
|
||||
|
@ -245,6 +234,8 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
|
|||
memset(sprtemp,0xFF, sizeof (sprtemp));
|
||||
maxframe = (size_t)-1;
|
||||
|
||||
spritename = sprname;
|
||||
|
||||
// are we 'patching' a sprite already loaded ?
|
||||
// if so, it might patch only certain frames, not all
|
||||
if (spritedef->numframes) // (then spriteframes is not null)
|
||||
|
@ -476,11 +467,10 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
//
|
||||
for (i = 0; i < numsprites; i++)
|
||||
{
|
||||
spritename = sprnames[i];
|
||||
if (spritename[4] && wadnum >= (UINT16)spritename[4])
|
||||
if (sprnames[i][4] && wadnum >= (UINT16)sprnames[i][4])
|
||||
continue;
|
||||
|
||||
if (R_AddSingleSpriteDef(spritename, &sprites[i], wadnum, start, end))
|
||||
if (R_AddSingleSpriteDef(sprnames[i], &sprites[i], wadnum, start, end))
|
||||
{
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
|
@ -489,7 +479,7 @@ void R_AddSpriteDefs(UINT16 wadnum)
|
|||
// if a new sprite was added (not just replaced)
|
||||
addsprites++;
|
||||
#ifndef ZDEBUG
|
||||
CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", spritename, wadnum);
|
||||
CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", sprnames[i], wadnum);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -2964,795 +2954,3 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
|
|||
|
||||
free(heads);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// SKINS CODE
|
||||
//
|
||||
// ==========================================================================
|
||||
|
||||
INT32 numskins = 0;
|
||||
skin_t skins[MAXSKINS];
|
||||
// FIXTHIS: don't work because it must be inistilised before the config load
|
||||
//#define SKINVALUES
|
||||
#ifdef SKINVALUES
|
||||
CV_PossibleValue_t skin_cons_t[MAXSKINS+1];
|
||||
#endif
|
||||
|
||||
//
|
||||
// P_GetSkinSprite2
|
||||
// For non-super players, tries each sprite2's immediate predecessor until it finds one with a number of frames or ends up at standing.
|
||||
// For super players, does the same as above - but tries the super equivalent for each sprite2 before the non-super version.
|
||||
//
|
||||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player)
|
||||
{
|
||||
UINT8 super = 0, i = 0;
|
||||
|
||||
if (!skin)
|
||||
return 0;
|
||||
|
||||
if ((playersprite_t)(spr2 & ~FF_SPR2SUPER) >= free_spr2)
|
||||
return 0;
|
||||
|
||||
while (!skin->sprites[spr2].numframes
|
||||
&& spr2 != SPR2_STND
|
||||
&& ++i < 32) // recursion limiter
|
||||
{
|
||||
if (spr2 & FF_SPR2SUPER)
|
||||
{
|
||||
super = FF_SPR2SUPER;
|
||||
spr2 &= ~FF_SPR2SUPER;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(spr2)
|
||||
{
|
||||
// Normal special cases.
|
||||
case SPR2_JUMP:
|
||||
spr2 = ((player
|
||||
? player->charflags
|
||||
: skin->flags)
|
||||
& SF_NOJUMPSPIN) ? SPR2_SPNG : SPR2_ROLL;
|
||||
break;
|
||||
case SPR2_TIRE:
|
||||
spr2 = ((player
|
||||
? player->charability
|
||||
: skin->ability)
|
||||
== CA_SWIM) ? SPR2_SWIM : SPR2_FLY;
|
||||
break;
|
||||
// Use the handy list, that's what it's there for!
|
||||
default:
|
||||
spr2 = spr2defaults[spr2];
|
||||
break;
|
||||
}
|
||||
|
||||
spr2 |= super;
|
||||
}
|
||||
|
||||
if (i >= 32) // probably an infinite loop...
|
||||
return 0;
|
||||
|
||||
return spr2;
|
||||
}
|
||||
|
||||
static void Sk_SetDefaultValue(skin_t *skin)
|
||||
{
|
||||
INT32 i;
|
||||
//
|
||||
// set default skin values
|
||||
//
|
||||
memset(skin, 0, sizeof (skin_t));
|
||||
snprintf(skin->name,
|
||||
sizeof skin->name, "skin %u", (UINT32)(skin-skins));
|
||||
skin->name[sizeof skin->name - 1] = '\0';
|
||||
skin->wadnum = INT16_MAX;
|
||||
|
||||
skin->flags = 0;
|
||||
|
||||
strcpy(skin->realname, "Someone");
|
||||
strcpy(skin->hudname, "???");
|
||||
|
||||
skin->starttranscolor = 96;
|
||||
skin->prefcolor = SKINCOLOR_GREEN;
|
||||
skin->supercolor = SKINCOLOR_SUPERGOLD1;
|
||||
skin->prefoppositecolor = 0; // use tables
|
||||
|
||||
skin->normalspeed = 36<<FRACBITS;
|
||||
skin->runspeed = 28<<FRACBITS;
|
||||
skin->thrustfactor = 5;
|
||||
skin->accelstart = 96;
|
||||
skin->acceleration = 40;
|
||||
|
||||
skin->ability = CA_NONE;
|
||||
skin->ability2 = CA2_SPINDASH;
|
||||
skin->jumpfactor = FRACUNIT;
|
||||
skin->actionspd = 30<<FRACBITS;
|
||||
skin->mindash = 15<<FRACBITS;
|
||||
skin->maxdash = 70<<FRACBITS;
|
||||
|
||||
skin->radius = mobjinfo[MT_PLAYER].radius;
|
||||
skin->height = mobjinfo[MT_PLAYER].height;
|
||||
skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3);
|
||||
|
||||
skin->shieldscale = FRACUNIT;
|
||||
skin->camerascale = FRACUNIT;
|
||||
|
||||
skin->thokitem = -1;
|
||||
skin->spinitem = -1;
|
||||
skin->revitem = -1;
|
||||
skin->followitem = 0;
|
||||
|
||||
skin->highresscale = FRACUNIT;
|
||||
skin->contspeed = 17;
|
||||
skin->contangle = 0;
|
||||
|
||||
skin->availability = 0;
|
||||
|
||||
for (i = 0; i < sfx_skinsoundslot0; i++)
|
||||
if (S_sfx[i].skinsound != -1)
|
||||
skin->soundsid[S_sfx[i].skinsound] = i;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the basic skins
|
||||
//
|
||||
void R_InitSkins(void)
|
||||
{
|
||||
#ifdef SKINVALUES
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i <= MAXSKINS; i++)
|
||||
{
|
||||
skin_cons_t[i].value = 0;
|
||||
skin_cons_t[i].strvalue = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// no default skin!
|
||||
numskins = 0;
|
||||
}
|
||||
|
||||
UINT32 R_GetSkinAvailabilities(void)
|
||||
{
|
||||
INT32 s;
|
||||
UINT32 response = 0;
|
||||
|
||||
for (s = 0; s < MAXSKINS; s++)
|
||||
{
|
||||
if (skins[s].availability && unlockables[skins[s].availability - 1].unlocked)
|
||||
response |= (1 << s);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
// returns true if available in circumstances, otherwise nope
|
||||
// warning don't use with an invalid skinnum other than -1 which always returns true
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|
||||
|| (!skins[skinnum].availability)
|
||||
|| (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked))
|
||||
|| (modeattacking) // If you have someone else's run you might as well take a look
|
||||
|| (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
|
||||
|| (netgame && (cv_forceskin.value == skinnum)) // Force 2.
|
||||
|| (metalrecording && skinnum == 5) // Force 3.
|
||||
);
|
||||
}
|
||||
|
||||
// returns true if the skin name is found (loaded from pwad)
|
||||
// warning return -1 if not found
|
||||
INT32 R_SkinAvailable(const char *name)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
// search in the skin list
|
||||
if (stricmp(skins[i].name,name)==0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// network code calls this when a 'skin change' is received
|
||||
void SetPlayerSkin(INT32 playernum, const char *skinname)
|
||||
{
|
||||
INT32 i = R_SkinAvailable(skinname);
|
||||
player_t *player = &players[playernum];
|
||||
|
||||
if ((i != -1) && R_SkinUsable(playernum, i))
|
||||
{
|
||||
SetPlayerSkinByNum(playernum, i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Skin '%s' not found.\n"), skinname);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Player %d (%s) skin '%s' not found\n"), playernum, player_names[playernum], skinname);
|
||||
|
||||
SetPlayerSkinByNum(playernum, 0);
|
||||
}
|
||||
|
||||
// Same as SetPlayerSkin, but uses the skin #.
|
||||
// network code calls this when a 'skin change' is received
|
||||
void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
|
||||
{
|
||||
player_t *player = &players[playernum];
|
||||
skin_t *skin = &skins[skinnum];
|
||||
UINT8 newcolor = 0;
|
||||
|
||||
if (skinnum >= 0 && skinnum < numskins && R_SkinUsable(playernum, skinnum)) // Make sure it exists!
|
||||
{
|
||||
player->skin = skinnum;
|
||||
|
||||
player->camerascale = skin->camerascale;
|
||||
player->shieldscale = skin->shieldscale;
|
||||
|
||||
player->charability = (UINT8)skin->ability;
|
||||
player->charability2 = (UINT8)skin->ability2;
|
||||
|
||||
player->charflags = (UINT32)skin->flags;
|
||||
|
||||
player->thokitem = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
|
||||
player->spinitem = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
|
||||
player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
|
||||
player->followitem = skin->followitem;
|
||||
|
||||
if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff.
|
||||
player->powers[pw_shield] &= SH_STACK;
|
||||
|
||||
player->actionspd = skin->actionspd;
|
||||
player->mindash = skin->mindash;
|
||||
player->maxdash = skin->maxdash;
|
||||
|
||||
player->normalspeed = skin->normalspeed;
|
||||
player->runspeed = skin->runspeed;
|
||||
player->thrustfactor = skin->thrustfactor;
|
||||
player->accelstart = skin->accelstart;
|
||||
player->acceleration = skin->acceleration;
|
||||
|
||||
player->jumpfactor = skin->jumpfactor;
|
||||
|
||||
player->height = skin->height;
|
||||
player->spinheight = skin->spinheight;
|
||||
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
{
|
||||
if (playernum == consoleplayer)
|
||||
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
|
||||
else if (playernum == secondarydisplayplayer)
|
||||
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
|
||||
player->skincolor = newcolor = skin->prefcolor;
|
||||
}
|
||||
|
||||
if (player->followmobj)
|
||||
{
|
||||
P_RemoveMobj(player->followmobj);
|
||||
P_SetTarget(&player->followmobj, NULL);
|
||||
}
|
||||
|
||||
if (player->mo)
|
||||
{
|
||||
fixed_t radius = FixedMul(skin->radius, player->mo->scale);
|
||||
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;
|
||||
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
|
||||
newcolor = skin->prefcolor; // will be updated in thinker to flashing
|
||||
}
|
||||
player->mo->skin = skin;
|
||||
if (newcolor)
|
||||
player->mo->color = newcolor;
|
||||
P_SetScale(player->mo, player->mo->scale);
|
||||
player->mo->radius = radius;
|
||||
|
||||
P_SetPlayerMobjState(player->mo, player->mo->state-states); // Prevent visual errors when switching between skins with differing number of frames
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Requested skin %d not found\n"), skinnum);
|
||||
else if(server || IsPlayerAdmin(consoleplayer))
|
||||
CONS_Alert(CONS_WARNING, "Player %d (%s) skin %d not found\n", playernum, player_names[playernum], skinnum);
|
||||
SetPlayerSkinByNum(playernum, 0); // not found put the sonic skin
|
||||
}
|
||||
|
||||
//
|
||||
// Add skins from a pwad, each skin preceded by 'S_SKIN' marker
|
||||
//
|
||||
|
||||
// Does the same is in w_wad, but check only for
|
||||
// the first 6 characters (this is so we can have S_SKIN1, S_SKIN2..
|
||||
// for wad editors that don't like multiple resources of the same name)
|
||||
//
|
||||
static UINT16 W_CheckForSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
const char *S_SKIN = "S_SKIN";
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
if (startlump < wadfiles[wadid]->numlumps)
|
||||
{
|
||||
lump_p = wadfiles[wadid]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name,S_SKIN,6)==0)
|
||||
return i;
|
||||
}
|
||||
return INT16_MAX; // not found
|
||||
}
|
||||
|
||||
#define HUDNAMEWRITE(value) STRBUFCPY(skin->hudname, value)
|
||||
|
||||
// turn _ into spaces and . into katana dot
|
||||
#define SYMBOLCONVERT(name) for (value = name; *value; value++)\
|
||||
{\
|
||||
if (*value == '_') *value = ' ';\
|
||||
else if (*value == '.') *value = '\x1E';\
|
||||
}
|
||||
|
||||
//
|
||||
// Patch skins from a pwad, each skin preceded by 'P_SKIN' marker
|
||||
//
|
||||
|
||||
// Does the same is in w_wad, but check only for
|
||||
// the first 6 characters (this is so we can have P_SKIN1, P_SKIN2..
|
||||
// for wad editors that don't like multiple resources of the same name)
|
||||
//
|
||||
static UINT16 W_CheckForPatchSkinMarkerInPwad(UINT16 wadid, UINT16 startlump)
|
||||
{
|
||||
UINT16 i;
|
||||
const char *P_SKIN = "P_SKIN";
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
// scan forward, start at <startlump>
|
||||
if (startlump < wadfiles[wadid]->numlumps)
|
||||
{
|
||||
lump_p = wadfiles[wadid]->lumpinfo + startlump;
|
||||
for (i = startlump; i < wadfiles[wadid]->numlumps; i++, lump_p++)
|
||||
if (memcmp(lump_p->name,P_SKIN,6)==0)
|
||||
return i;
|
||||
}
|
||||
return INT16_MAX; // not found
|
||||
}
|
||||
|
||||
static void R_LoadSkinSprites(UINT16 wadnum, UINT16 *lump, UINT16 *lastlump, skin_t *skin)
|
||||
{
|
||||
UINT16 newlastlump;
|
||||
UINT8 sprite2;
|
||||
|
||||
*lump += 1; // start after S_SKIN
|
||||
*lastlump = W_CheckNumForNamePwad("S_END",wadnum,*lump); // stop at S_END
|
||||
|
||||
// old wadding practices die hard -- stop at S_SKIN (or P_SKIN) or S_START if they come before S_END.
|
||||
newlastlump = W_CheckForSkinMarkerInPwad(wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
newlastlump = W_CheckForPatchSkinMarkerInPwad(wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
newlastlump = W_CheckNumForNamePwad("S_START",wadnum,*lump);
|
||||
if (newlastlump < *lastlump) *lastlump = newlastlump;
|
||||
|
||||
// ...and let's handle super, too
|
||||
newlastlump = W_CheckNumForNamePwad("S_SUPER",wadnum,*lump);
|
||||
if (newlastlump < *lastlump)
|
||||
{
|
||||
newlastlump++;
|
||||
// load all sprite sets we are aware of... for super!
|
||||
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
|
||||
R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[FF_SPR2SUPER|sprite2], wadnum, newlastlump, *lastlump);
|
||||
|
||||
newlastlump--;
|
||||
*lastlump = newlastlump; // okay, make the normal sprite set loading end there
|
||||
}
|
||||
|
||||
// load all sprite sets we are aware of... for normal stuff.
|
||||
for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
|
||||
R_AddSingleSpriteDef((spritename = spr2names[sprite2]), &skin->sprites[sprite2], wadnum, *lump, *lastlump);
|
||||
|
||||
if (skin->sprites[0].numframes == 0)
|
||||
I_Error("R_LoadSkinSprites: no frames found for sprite SPR2_%s\n", spr2names[0]);
|
||||
}
|
||||
|
||||
// returns whether found appropriate property
|
||||
static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
||||
{
|
||||
// custom translation table
|
||||
if (!stricmp(stoken, "startcolor"))
|
||||
skin->starttranscolor = atoi(value);
|
||||
|
||||
#define FULLPROCESS(field) else if (!stricmp(stoken, #field)) skin->field = get_number(value);
|
||||
// character type identification
|
||||
FULLPROCESS(flags)
|
||||
FULLPROCESS(ability)
|
||||
FULLPROCESS(ability2)
|
||||
|
||||
FULLPROCESS(thokitem)
|
||||
FULLPROCESS(spinitem)
|
||||
FULLPROCESS(revitem)
|
||||
FULLPROCESS(followitem)
|
||||
#undef FULLPROCESS
|
||||
|
||||
#define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
|
||||
GETFRACBITS(normalspeed)
|
||||
GETFRACBITS(runspeed)
|
||||
|
||||
GETFRACBITS(mindash)
|
||||
GETFRACBITS(maxdash)
|
||||
GETFRACBITS(actionspd)
|
||||
|
||||
GETFRACBITS(radius)
|
||||
GETFRACBITS(height)
|
||||
GETFRACBITS(spinheight)
|
||||
#undef GETFRACBITS
|
||||
|
||||
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
|
||||
GETINT(thrustfactor)
|
||||
GETINT(accelstart)
|
||||
GETINT(acceleration)
|
||||
GETINT(contspeed)
|
||||
GETINT(contangle)
|
||||
#undef GETINT
|
||||
|
||||
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
||||
GETSKINCOLOR(prefcolor)
|
||||
GETSKINCOLOR(prefoppositecolor)
|
||||
#undef GETSKINCOLOR
|
||||
else if (!stricmp(stoken, "supercolor"))
|
||||
skin->supercolor = R_GetSuperColorByName(value);
|
||||
|
||||
#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value));
|
||||
GETFLOAT(jumpfactor)
|
||||
GETFLOAT(highresscale)
|
||||
GETFLOAT(shieldscale)
|
||||
GETFLOAT(camerascale)
|
||||
#undef GETFLOAT
|
||||
|
||||
#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \
|
||||
strupr(value); \
|
||||
if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \
|
||||
skin->flags |= (SF_##field); \
|
||||
else \
|
||||
skin->flags &= ~(SF_##field); \
|
||||
}
|
||||
// parameters for individual character flags
|
||||
// these are uppercase so they can be concatenated with SF_
|
||||
// 1, true, yes are all valid values
|
||||
GETFLAG(SUPER)
|
||||
GETFLAG(NOSUPERSPIN)
|
||||
GETFLAG(NOSPINDASHDUST)
|
||||
GETFLAG(HIRES)
|
||||
GETFLAG(NOSKID)
|
||||
GETFLAG(NOSPEEDADJUST)
|
||||
GETFLAG(RUNONWATER)
|
||||
GETFLAG(NOJUMPSPIN)
|
||||
GETFLAG(NOJUMPDAMAGE)
|
||||
GETFLAG(STOMPDAMAGE)
|
||||
GETFLAG(MARIODAMAGE)
|
||||
GETFLAG(MACHINE)
|
||||
GETFLAG(DASHMODE)
|
||||
GETFLAG(FASTEDGE)
|
||||
GETFLAG(MULTIABILITY)
|
||||
GETFLAG(NONIGHTSROTATION)
|
||||
#undef GETFLAG
|
||||
|
||||
else // let's check if it's a sound, otherwise error out
|
||||
{
|
||||
boolean found = false;
|
||||
sfxenum_t i;
|
||||
size_t stokenadjust;
|
||||
|
||||
// Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.)
|
||||
if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS*
|
||||
stokenadjust = 2;
|
||||
else // sfx_*
|
||||
stokenadjust = 4;
|
||||
|
||||
// Remove the prefix. (We can affect this directly since we're not going to use it again.)
|
||||
if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS*
|
||||
value += 2;
|
||||
else // sfx_*
|
||||
value += 4;
|
||||
|
||||
// copy name of sounds that are remapped
|
||||
// for this skin
|
||||
for (i = 0; i < sfx_skinsoundslot0; i++)
|
||||
{
|
||||
if (!S_sfx[i].name)
|
||||
continue;
|
||||
if (S_sfx[i].skinsound != -1
|
||||
&& !stricmp(S_sfx[i].name,
|
||||
stoken + stokenadjust))
|
||||
{
|
||||
skin->soundsid[S_sfx[i].skinsound] =
|
||||
S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Find skin sprites, sounds & optional status bar face, & add them
|
||||
//
|
||||
void R_AddSkins(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lump, lastlump = 0;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean hudname, realname;
|
||||
|
||||
//
|
||||
// search for all skin markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckForSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX)
|
||||
{
|
||||
// advance by default
|
||||
lastlump = lump + 1;
|
||||
|
||||
if (numskins >= MAXSKINS)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS);
|
||||
continue; // so we know how many skins couldn't be added
|
||||
}
|
||||
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
// for strtok
|
||||
buf2 = malloc(size+1);
|
||||
if (!buf2)
|
||||
I_Error("R_AddSkins: No more free memory\n");
|
||||
M_Memcpy(buf2,buf,size);
|
||||
buf2[size] = '\0';
|
||||
|
||||
// set defaults
|
||||
skin = &skins[numskins];
|
||||
Sk_SetDefaultValue(skin);
|
||||
skin->wadnum = wadnum;
|
||||
hudname = realname = false;
|
||||
// parse
|
||||
stoken = strtok (buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto next_token; // find the real next token
|
||||
}
|
||||
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
|
||||
if (!value)
|
||||
I_Error("R_AddSkins: syntax error in S_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
|
||||
// Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines.
|
||||
// Others can't go in there because we don't want them to be patchable.
|
||||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
INT32 skinnum = R_SkinAvailable(value);
|
||||
strlwr(value);
|
||||
if (skinnum == -1)
|
||||
STRBUFCPY(skin->name, value);
|
||||
// the skin name must uniquely identify a single skin
|
||||
// if the name is already used I make the name 'namex'
|
||||
// using the default skin name's number set above
|
||||
else
|
||||
{
|
||||
const size_t stringspace =
|
||||
strlen(value) + sizeof (numskins) + 1;
|
||||
char *value2 = Z_Malloc(stringspace, PU_STATIC, NULL);
|
||||
snprintf(value2, stringspace,
|
||||
"%s%d", value, numskins);
|
||||
value2[stringspace - 1] = '\0';
|
||||
if (R_SkinAvailable(value2) == -1)
|
||||
// I'm lazy so if NEW name is already used I leave the 'skin x'
|
||||
// default skin name set in Sk_SetDefaultValue
|
||||
STRBUFCPY(skin->name, value2);
|
||||
Z_Free(value2);
|
||||
}
|
||||
|
||||
// copy to hudname and fullname as a default.
|
||||
if (!realname)
|
||||
{
|
||||
STRBUFCPY(skin->realname, skin->name);
|
||||
for (value = skin->realname; *value; value++)
|
||||
{
|
||||
if (*value == '_') *value = ' '; // turn _ into spaces.
|
||||
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
|
||||
}
|
||||
}
|
||||
if (!hudname)
|
||||
{
|
||||
HUDNAMEWRITE(skin->name);
|
||||
strupr(skin->hudname);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
}
|
||||
}
|
||||
else if (!stricmp(stoken, "realname"))
|
||||
{ // Display name (eg. "Knuckles")
|
||||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!stricmp(stoken, "availability"))
|
||||
{
|
||||
skin->availability = atoi(value);
|
||||
if (skin->availability >= MAXUNLOCKABLES)
|
||||
skin->availability = 0;
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
|
||||
next_token:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
}
|
||||
free(buf2);
|
||||
|
||||
// Add sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(numskins); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
if (!skin->availability) // Safe to print...
|
||||
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
|
||||
#ifdef SKINVALUES
|
||||
skin_cons_t[numskins].value = numskins;
|
||||
skin_cons_t[numskins].strvalue = skin->name;
|
||||
#endif
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl)
|
||||
HWR_AddPlayerModel(numskins);
|
||||
#endif
|
||||
|
||||
numskins++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Patch skin sprites
|
||||
//
|
||||
void R_PatchSkins(UINT16 wadnum)
|
||||
{
|
||||
UINT16 lump, lastlump = 0;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
char *stoken;
|
||||
char *value;
|
||||
size_t size;
|
||||
skin_t *skin;
|
||||
boolean noskincomplain, realname, hudname;
|
||||
|
||||
//
|
||||
// search for all skin patch markers in pwad
|
||||
//
|
||||
|
||||
while ((lump = W_CheckForPatchSkinMarkerInPwad(wadnum, lastlump)) != INT16_MAX)
|
||||
{
|
||||
INT32 skinnum = 0;
|
||||
|
||||
// advance by default
|
||||
lastlump = lump + 1;
|
||||
|
||||
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
|
||||
size = W_LumpLengthPwad(wadnum, lump);
|
||||
|
||||
// for strtok
|
||||
buf2 = malloc(size+1);
|
||||
if (!buf2)
|
||||
I_Error("R_PatchSkins: No more free memory\n");
|
||||
M_Memcpy(buf2,buf,size);
|
||||
buf2[size] = '\0';
|
||||
|
||||
skin = NULL;
|
||||
noskincomplain = realname = hudname = false;
|
||||
|
||||
/*
|
||||
Parse. Has more phases than the parser in R_AddSkins because it needs to have the patching name first (no default skin name is acceptible for patching, unlike skin creation)
|
||||
*/
|
||||
|
||||
stoken = strtok(buf2, "\r\n= ");
|
||||
while (stoken)
|
||||
{
|
||||
if ((stoken[0] == '/' && stoken[1] == '/')
|
||||
|| (stoken[0] == '#'))// skip comments
|
||||
{
|
||||
stoken = strtok(NULL, "\r\n"); // skip end of line
|
||||
goto next_token; // find the real next token
|
||||
}
|
||||
|
||||
value = strtok(NULL, "\r\n= ");
|
||||
|
||||
if (!value)
|
||||
I_Error("R_PatchSkins: syntax error in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
|
||||
if (!skin) // Get the name!
|
||||
{
|
||||
if (!stricmp(stoken, "name"))
|
||||
{
|
||||
strlwr(value);
|
||||
skinnum = R_SkinAvailable(value);
|
||||
if (skinnum != -1)
|
||||
skin = &skins[skinnum];
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: unknown skin name in P_SKIN lump# %d(%s) in WAD %s\n", lump, W_CheckNameForNumPwad(wadnum,lump), wadfiles[wadnum]->filename);
|
||||
noskincomplain = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Get the properties!
|
||||
{
|
||||
// Some of these can't go in R_ProcessPatchableFields because they have side effects for future lines.
|
||||
if (!stricmp(stoken, "realname"))
|
||||
{ // Display name (eg. "Knuckles")
|
||||
realname = true;
|
||||
STRBUFCPY(skin->realname, value);
|
||||
SYMBOLCONVERT(skin->realname)
|
||||
if (!hudname)
|
||||
HUDNAMEWRITE(skin->realname);
|
||||
}
|
||||
else if (!stricmp(stoken, "hudname"))
|
||||
{ // Life icon name (eg. "K.T.E")
|
||||
hudname = true;
|
||||
HUDNAMEWRITE(value);
|
||||
SYMBOLCONVERT(skin->hudname)
|
||||
if (!realname)
|
||||
STRBUFCPY(skin->realname, skin->hudname);
|
||||
}
|
||||
else if (!R_ProcessPatchableFields(skin, stoken, value))
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: Unknown keyword '%s' in P_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
|
||||
}
|
||||
|
||||
if (!skin)
|
||||
break;
|
||||
|
||||
next_token:
|
||||
stoken = strtok(NULL, "\r\n= ");
|
||||
}
|
||||
free(buf2);
|
||||
|
||||
if (!skin) // Didn't include a name parameter? What a waste.
|
||||
{
|
||||
if (!noskincomplain)
|
||||
CONS_Debug(DBG_SETUP, "R_PatchSkins: no skin name given in P_SKIN lump #%d (WAD %s)\n", lump, wadfiles[wadnum]->filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Patch sprites
|
||||
R_LoadSkinSprites(wadnum, &lump, &lastlump, skin);
|
||||
//ST_LoadFaceGraphics(skinnum); -- nah let's do this elsewhere
|
||||
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
if (!skin->availability) // Safe to print...
|
||||
CONS_Printf(M_GetText("Patched skin '%s'\n"), skin->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#undef HUDNAMEWRITE
|
||||
#undef SYMBOLCONVERT
|
||||
|
|
136
src/r_things.h
136
src/r_things.h
|
@ -14,26 +14,27 @@
|
|||
#ifndef __R_THINGS__
|
||||
#define __R_THINGS__
|
||||
|
||||
#include "sounds.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_portal.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_skins.h"
|
||||
|
||||
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
|
||||
// Fab: this is a hack : should allocate the lookup tables per sprite
|
||||
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
||||
|
||||
#define VISSPRITECHUNKBITS 6 // 2^6 = 64 sprites per chunk
|
||||
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
|
||||
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
|
||||
// --------------
|
||||
// SPRITE LOADING
|
||||
// --------------
|
||||
|
||||
#define FEETADJUST (4<<FRACBITS) // R_AddSingleSpriteDef
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||
boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 wadnum, UINT16 startlump, UINT16 endlump);
|
||||
|
||||
//faB: find sprites in wadfile, replace existing, add new ones
|
||||
// (only sprites from namelist are added or replaced)
|
||||
void R_AddSpriteDefs(UINT16 wadnum);
|
||||
|
||||
// ---------------------
|
||||
// MASKED COLUMN DRAWING
|
||||
// ---------------------
|
||||
|
||||
// vars for R_DrawMaskedColumn
|
||||
extern INT16 *mfloorclip;
|
||||
|
@ -47,9 +48,14 @@ extern fixed_t windowbottom;
|
|||
void R_DrawMaskedColumn(column_t *column);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
|
||||
|
||||
//faB: find sprites in wadfile, replace existing, add new ones
|
||||
// (only sprites from namelist are added or replaced)
|
||||
void R_AddSpriteDefs(UINT16 wadnum);
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
// ----------------
|
||||
|
||||
// Constant arrays used for psprite clipping
|
||||
// and initializing clipping.
|
||||
extern INT16 negonearray[MAXVIDWIDTH];
|
||||
extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
|
@ -68,6 +74,9 @@ boolean R_ThingVisibleWithinDist (mobj_t *thing,
|
|||
boolean R_PrecipThingVisible (precipmobj_t *precipthing,
|
||||
fixed_t precip_draw_dist);
|
||||
|
||||
// --------------
|
||||
// MASKED DRAWING
|
||||
// --------------
|
||||
/** Used to count the amount of masked elements
|
||||
* per portal to later group them in separate
|
||||
* drawnode lists.
|
||||
|
@ -82,73 +91,18 @@ typedef struct
|
|||
|
||||
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);
|
||||
|
||||
// -----------
|
||||
// SKINS STUFF
|
||||
// -----------
|
||||
#define SKINNAMESIZE 16
|
||||
// should be all lowercase!! S_SKIN processing does a strlwr
|
||||
#define DEFAULTSKIN "sonic"
|
||||
#define DEFAULTSKIN2 "tails" // secondary player
|
||||
#define DEFAULTNIGHTSSKIN 0
|
||||
// ----------
|
||||
// VISSPRITES
|
||||
// ----------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[SKINNAMESIZE+1]; // INT16 descriptive name of the skin
|
||||
UINT16 wadnum;
|
||||
skinflags_t flags;
|
||||
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
|
||||
// Fab: this is a hack : should allocate the lookup tables per sprite
|
||||
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
|
||||
|
||||
char realname[SKINNAMESIZE+1]; // Display name for level completion.
|
||||
char hudname[SKINNAMESIZE+1]; // HUD name to display (officially exactly 5 characters long)
|
||||
#define VISSPRITECHUNKBITS 6 // 2^6 = 64 sprites per chunk
|
||||
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
|
||||
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
|
||||
|
||||
UINT8 ability; // ability definition
|
||||
UINT8 ability2; // secondary ability definition
|
||||
INT32 thokitem;
|
||||
INT32 spinitem;
|
||||
INT32 revitem;
|
||||
INT32 followitem;
|
||||
fixed_t actionspd;
|
||||
fixed_t mindash;
|
||||
fixed_t maxdash;
|
||||
|
||||
fixed_t normalspeed; // Normal ground
|
||||
fixed_t runspeed; // Speed that you break into your run animation
|
||||
|
||||
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
|
||||
UINT8 accelstart; // Acceleration if speed = 0
|
||||
UINT8 acceleration; // Acceleration
|
||||
|
||||
fixed_t jumpfactor; // multiple of standard jump height
|
||||
|
||||
fixed_t radius; // Bounding box changes.
|
||||
fixed_t height;
|
||||
fixed_t spinheight;
|
||||
|
||||
fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size
|
||||
fixed_t camerascale;
|
||||
|
||||
// Definable color translation table
|
||||
UINT8 starttranscolor;
|
||||
UINT8 prefcolor;
|
||||
UINT8 supercolor;
|
||||
UINT8 prefoppositecolor; // if 0 use tables instead
|
||||
|
||||
fixed_t highresscale; // scale of highres, default is 0.5
|
||||
UINT8 contspeed; // continue screen animation speed
|
||||
UINT8 contangle; // initial angle on continue screen
|
||||
|
||||
// specific sounds per skin
|
||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||
|
||||
// contains super versions too
|
||||
spritedef_t sprites[NUMPLAYERSPRITES*2];
|
||||
spriteinfo_t sprinfo[NUMPLAYERSPRITES*2];
|
||||
|
||||
UINT8 availability; // lock?
|
||||
} skin_t;
|
||||
|
||||
// -----------
|
||||
// NOT SKINS STUFF !
|
||||
// -----------
|
||||
typedef enum
|
||||
{
|
||||
// actual cuts
|
||||
|
@ -227,6 +181,12 @@ typedef struct vissprite_s
|
|||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
} vissprite_t;
|
||||
|
||||
extern UINT32 visspritecount;
|
||||
|
||||
// ----------
|
||||
// DRAW NODES
|
||||
// ----------
|
||||
|
||||
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
||||
// middle texture. This is used for sorting with sprites.
|
||||
typedef struct drawnode_s
|
||||
|
@ -241,23 +201,11 @@ typedef struct drawnode_s
|
|||
struct drawnode_s *prev;
|
||||
} drawnode_t;
|
||||
|
||||
extern INT32 numskins;
|
||||
extern skin_t skins[MAXSKINS];
|
||||
extern UINT32 visspritecount;
|
||||
|
||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||
boolean R_SkinUsable(INT32 playernum, INT32 skinnum);
|
||||
UINT32 R_GetSkinAvailabilities(void);
|
||||
INT32 R_SkinAvailable(const char *name);
|
||||
void R_PatchSkins(UINT16 wadnum);
|
||||
void R_AddSkins(UINT16 wadnum);
|
||||
|
||||
UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player);
|
||||
|
||||
void R_InitDrawNodes(void);
|
||||
|
||||
char *GetPlayerFacePic(INT32 skinnum);
|
||||
// -----------------------
|
||||
// SPRITE FRAME CHARACTERS
|
||||
// -----------------------
|
||||
|
||||
// Functions to go from sprite character ID to frame number
|
||||
// for 2.1 compatibility this still uses the old 'A' + frame code
|
||||
|
|
|
@ -27,7 +27,7 @@ extern INT32 msg_id;
|
|||
#include "g_game.h"
|
||||
#include "m_argv.h"
|
||||
#include "r_main.h" // R_PointToAngle2() used to calc stereo sep.
|
||||
#include "r_things.h" // for skins
|
||||
#include "r_skins.h" // for skins
|
||||
#include "i_system.h"
|
||||
#include "i_sound.h"
|
||||
#include "s_sound.h"
|
||||
|
|
|
@ -284,6 +284,7 @@
|
|||
<ClInclude Include="..\r_patch.h" />
|
||||
<ClInclude Include="..\r_portal.h" />
|
||||
<ClInclude Include="..\r_segs.h" />
|
||||
<ClInclude Include="..\r_skins.h" />
|
||||
<ClInclude Include="..\r_sky.h" />
|
||||
<ClInclude Include="..\r_splats.h" />
|
||||
<ClInclude Include="..\r_state.h" />
|
||||
|
@ -446,6 +447,7 @@
|
|||
<ClCompile Include="..\r_patch.c" />
|
||||
<ClCompile Include="..\r_portal.c" />
|
||||
<ClCompile Include="..\r_segs.c" />
|
||||
<ClCompile Include="..\r_skins.c" />
|
||||
<ClCompile Include="..\r_sky.c" />
|
||||
<ClCompile Include="..\r_splats.c" />
|
||||
<ClCompile Include="..\r_things.c" />
|
||||
|
|
|
@ -417,6 +417,9 @@
|
|||
<ClInclude Include="..\r_segs.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_skins.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\r_sky.h">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClInclude>
|
||||
|
@ -849,6 +852,9 @@
|
|||
<ClCompile Include="..\r_segs.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\r_skins.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\r_sky.c">
|
||||
<Filter>R_Rend</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "i_sound.h"
|
||||
#include "sounds.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "lua_script.h"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "i_video.h"
|
||||
#include "p_tick.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_things.h"
|
||||
#include "r_skins.h"
|
||||
#include "s_sound.h"
|
||||
#include "st_stuff.h"
|
||||
#include "v_video.h"
|
||||
|
|
Loading…
Reference in a new issue