Merge branch 'next' into any-resolution

This commit is contained in:
Lactozilla 2023-11-30 19:00:20 -03:00
commit 14f2dab4eb
51 changed files with 1102 additions and 578 deletions

View file

@ -356,7 +356,7 @@ Debian stable:arm64:
- - | - - |
# make # make
echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2" echo -e "\e[0Ksection_start:`date +%s`:make[collapsed=false]\r\e[0KCompiling SRB2"
- make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1C || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1 - make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 ERRORMODE=1 NONX86=1 ARM64=1 || make --directory=src --keep-going CCACHE=1 ERRORMODE=1 LINUX64=1 NONX86=1 ARM64=1
- | - |
# make # make
echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K" echo -e "\e[0Ksection_end:`date +%s`:make\r\e[0K"

View file

@ -99,6 +99,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
lua_blockmaplib.c lua_blockmaplib.c
lua_hudlib.c lua_hudlib.c
lua_hudlib_drawlist.c lua_hudlib_drawlist.c
lua_colorlib.c
lua_inputlib.c lua_inputlib.c
) )

View file

@ -94,3 +94,4 @@ lua_blockmaplib.c
lua_hudlib.c lua_hudlib.c
lua_hudlib_drawlist.c lua_hudlib_drawlist.c
lua_inputlib.c lua_inputlib.c
lua_colorlib.c

View file

@ -239,7 +239,8 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
// SPINNING // SPINNING
if (!(player->pflags & (PF_SPINNING|PF_STARTDASH)) && mem->thinkstate == AI_SPINFOLLOW) if (!(player->pflags & (PF_SPINNING|PF_STARTDASH)) && mem->thinkstate == AI_SPINFOLLOW)
mem->thinkstate = AI_FOLLOW; mem->thinkstate = AI_FOLLOW;
else if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_SPINFOLLOW) else if ((mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_SPINFOLLOW)
&& bot->charability2 == CA2_SPINDASH)
{ {
if (!_2d) if (!_2d)
{ {
@ -329,7 +330,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_CATCHUP || (mem->thinkstate == AI_SPINFOLLOW && player->pflags & PF_JUMPED)) if (mem->thinkstate == AI_FOLLOW || mem->thinkstate == AI_CATCHUP || (mem->thinkstate == AI_SPINFOLLOW && player->pflags & PF_JUMPED))
{ {
// Flying catch-up // Flying catch-up
if (bot->pflags & PF_THOKKED) if (bot->charability == CA_FLY && bot->pflags & PF_THOKKED)
{ {
cmd->forwardmove = min(MAXPLMOVE, (dist/scale)>>3); cmd->forwardmove = min(MAXPLMOVE, (dist/scale)>>3);
if (zdist < -64*scale) if (zdist < -64*scale)

View file

@ -51,9 +51,11 @@ static void COM_CEchoDuration_f(void);
static void COM_Exec_f(void); static void COM_Exec_f(void);
static void COM_Wait_f(void); static void COM_Wait_f(void);
static void COM_Help_f(void); static void COM_Help_f(void);
static void COM_Find_f(void);
static void COM_Toggle_f(void); static void COM_Toggle_f(void);
static void COM_Add_f(void); static void COM_Add_f(void);
static void CV_EnforceExecVersion(void); static void CV_EnforceExecVersion(void);
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
static boolean CV_Command(void); static boolean CV_Command(void);
@ -344,6 +346,7 @@ void COM_Init(void)
COM_AddCommand("exec", COM_Exec_f, 0); COM_AddCommand("exec", COM_Exec_f, 0);
COM_AddCommand("wait", COM_Wait_f, 0); COM_AddCommand("wait", COM_Wait_f, 0);
COM_AddCommand("help", COM_Help_f, COM_LUA); COM_AddCommand("help", COM_Help_f, COM_LUA);
COM_AddCommand("find", COM_Find_f, COM_LUA);
COM_AddCommand("toggle", COM_Toggle_f, COM_LUA); COM_AddCommand("toggle", COM_Toggle_f, COM_LUA);
COM_AddCommand("add", COM_Add_f, COM_LUA); COM_AddCommand("add", COM_Add_f, COM_LUA);
RegisterNetXCmd(XD_NETVAR, Got_NetVar); RegisterNetXCmd(XD_NETVAR, Got_NetVar);
@ -879,7 +882,7 @@ static void COM_Help_f(void)
boolean floatmode = false; boolean floatmode = false;
const char *cvalue = NULL; const char *cvalue = NULL;
CONS_Printf("\x82""Variable %s:\n", cvar->name); CONS_Printf("\x82""Variable %s:\n", cvar->name);
CONS_Printf(M_GetText(" flags :")); CONS_Printf(M_GetText(" flags: "));
if (cvar->flags & CV_SAVE) if (cvar->flags & CV_SAVE)
CONS_Printf("AUTOSAVE "); CONS_Printf("AUTOSAVE ");
if (cvar->flags & CV_FLOAT) if (cvar->flags & CV_FLOAT)
@ -976,31 +979,8 @@ static void COM_Help_f(void)
return; return;
} }
CONS_Printf("No exact match, searching...\n"); CONS_Printf("No variable or command named %s", help);
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or try typing help without arguments\n");
// variables
CONS_Printf("\x82""Variables:\n");
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if ((cvar->flags & CV_NOSHOWHELP) || (!strstr(cvar->name, help)))
continue;
CONS_Printf("%s ", cvar->name);
i++;
}
// commands
CONS_Printf("\x82""\nCommands:\n");
for (cmd = com_commands; cmd; cmd = cmd->next)
{
if (!strstr(cmd->name, help))
continue;
CONS_Printf("%s ",cmd->name);
i++;
}
CONS_Printf("\x82""\nCheck wiki.srb2.org for more or type help <command or variable>\n");
CONS_Debug(DBG_GAMELOGIC, "\x87Total : %d\n", i);
} }
return; return;
} }
@ -1030,6 +1010,76 @@ static void COM_Help_f(void)
} }
} }
static void COM_Find_f(void)
{
static char prefix[80];
xcommand_t *cmd;
consvar_t *cvar;
cmdalias_t *alias;
const char *match;
const char *help;
size_t helplen;
boolean matchesany;
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("find <text>: Search for variables, commands and aliases containing <text>\n"));
return;
}
help = COM_Argv(1);
helplen = strlen(help);
CONS_Printf("\x82""Variables:\n");
matchesany = false;
for (cvar = consvar_vars; cvar; cvar = cvar->next)
{
if (cvar->flags & CV_NOSHOWHELP)
continue;
match = strstr(cvar->name, help);
if (match != NULL)
{
memcpy(prefix, cvar->name, match - cvar->name);
prefix[match - cvar->name] = '\0';
CONS_Printf(" %s\x83%s\x80%s\n", prefix, help, &match[helplen]);
matchesany = true;
}
}
if (!matchesany)
CONS_Printf(" (none)\n");
CONS_Printf("\x82""Commands:\n");
matchesany = false;
for (cmd = com_commands; cmd; cmd = cmd->next)
{
match = strstr(cmd->name, help);
if (match != NULL)
{
memcpy(prefix, cmd->name, match - cmd->name);
prefix[match - cmd->name] = '\0';
CONS_Printf(" %s\x83%s\x80%s\n", prefix, help, &match[helplen]);
matchesany = true;
}
}
if (!matchesany)
CONS_Printf(" (none)\n");
CONS_Printf("\x82""Aliases:\n");
matchesany = false;
for (alias = com_alias; alias; alias = alias->next)
{
match = strstr(alias->name, help);
if (match != NULL)
{
memcpy(prefix, alias->name, match - alias->name);
prefix[match - alias->name] = '\0';
CONS_Printf(" %s\x83%s\x80%s\n", prefix, help, &match[helplen]);
matchesany = true;
}
}
if (!matchesany)
CONS_Printf(" (none)\n");
}
/** Toggles a console variable. Useful for on/off values. /** Toggles a console variable. Useful for on/off values.
* *
* This works on on/off, yes/no values only * This works on on/off, yes/no values only

View file

@ -918,7 +918,8 @@ boolean CON_Responder(event_t *ev)
static UINT8 consdown = false; // console is treated differently due to rare usage static UINT8 consdown = false; // console is treated differently due to rare usage
// sequential completions a la 4dos // sequential completions a la 4dos
static char completion[80]; static char completioncmd[80 + sizeof("find ")] = "find ";
static char *completion = &completioncmd[sizeof("find ")-1];
static INT32 skips; static INT32 skips;
@ -1054,36 +1055,14 @@ boolean CON_Responder(event_t *ev)
// show all cvars/commands that match what we have inputted // show all cvars/commands that match what we have inputted
if (key == KEY_TAB) if (key == KEY_TAB)
{ {
size_t i, len;
if (!completion[0]) if (!completion[0])
{ {
if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' ')) if (!input_len || input_len >= 40 || strchr(inputlines[inputline], ' '))
return true; return true;
strcpy(completion, inputlines[inputline]); strcpy(completion, inputlines[inputline]);
} }
len = strlen(completion); COM_BufInsertText(completioncmd);
//first check commands
CONS_Printf("\nCommands:\n");
for (i = 0, cmd = COM_CompleteCommand(completion, i); cmd; cmd = COM_CompleteCommand(completion, ++i))
CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len);
if (i == 0) CONS_Printf(" (none)\n");
//now we move on to CVARs
CONS_Printf("Variables:\n");
for (i = 0, cmd = CV_CompleteVar(completion, i); cmd; cmd = CV_CompleteVar(completion, ++i))
CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len);
if (i == 0) CONS_Printf(" (none)\n");
//and finally aliases
CONS_Printf("Aliases:\n");
for (i = 0, cmd = COM_CompleteAlias(completion, i); cmd; cmd = COM_CompleteAlias(completion, ++i))
CONS_Printf(" \x83" "%s" "\x80" "%s\n", completion, cmd+len);
if (i == 0) CONS_Printf(" (none)\n");
completion[0] = 0; completion[0] = 0;
return true; return true;
} }
// --- // ---

View file

@ -158,6 +158,10 @@ typedef enum
PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<28, // Turning inputs are translated into strafing inputs
PF_CANCARRY = 1<<29, // Can carry another player? PF_CANCARRY = 1<<29, // Can carry another player?
PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting PF_FINISHED = 1<<30, // The player finished the level. NOT the same as exiting
// True if shield button down last tic
// This may be the final flag, but 2.3 could free up the others
PF_SHIELDDOWN = 1<<31,
// up to 1<<31 is free // up to 1<<31 is free
} pflags_t; } pflags_t;

View file

@ -26,20 +26,23 @@
// Button/action code definitions. // Button/action code definitions.
typedef enum typedef enum
{ {
// First 4 bits are weapon change info, DO NOT USE! // First 3 bits are weapon change info, DO NOT USE!
BT_WEAPONMASK = 0x0F, //our first four bits. BT_WEAPONMASK = 0x07, //our first three bits.
BT_SHIELD = 1<<3, // shield or super action
BT_WEAPONNEXT = 1<<4, BT_WEAPONNEXT = 1<<4, // select next weapon
BT_WEAPONPREV = 1<<5, BT_WEAPONPREV = 1<<5, // select previous weapon
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7,
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10,
BT_JUMP = 1<<11,
BT_FIRENORMAL = 1<<12, // Fire a normal ring no matter what
BT_ATTACK = 1<<6, // shoot rings
BT_SPIN = 1<<7, // spin action
BT_CAMLEFT = 1<<8, // turn camera left
BT_CAMRIGHT = 1<<9, // turn camera right
BT_TOSSFLAG = 1<<10, // toss flag or emeralds
BT_JUMP = 1<<11, // jump action
BT_FIRENORMAL = 1<<12, // fire a normal ring no matter what
// custom lua buttons
BT_CUSTOM1 = 1<<13, BT_CUSTOM1 = 1<<13,
BT_CUSTOM2 = 1<<14, BT_CUSTOM2 = 1<<14,
BT_CUSTOM3 = 1<<15, BT_CUSTOM3 = 1<<15,

View file

@ -589,7 +589,7 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
{ {
CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN); CacheAndPushConstant(L, word, (lua_Integer)BT_SPIN);
return 1; return 1;
} }
for (i = 0; INT_CONST[i].n; i++) for (i = 0; INT_CONST[i].n; i++)
if (fastcmp(word,INT_CONST[i].n)) { if (fastcmp(word,INT_CONST[i].n)) {

View file

@ -5576,7 +5576,8 @@ struct int_const_s const INT_CONST[] = {
{"ROTAXIS_Z",ROTAXIS_Z}, {"ROTAXIS_Z",ROTAXIS_Z},
// Buttons (ticcmd_t) // Buttons (ticcmd_t)
{"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits. {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first three bits.
{"BT_SHIELD",BT_SHIELD},
{"BT_WEAPONNEXT",BT_WEAPONNEXT}, {"BT_WEAPONNEXT",BT_WEAPONNEXT},
{"BT_WEAPONPREV",BT_WEAPONPREV}, {"BT_WEAPONPREV",BT_WEAPONPREV},
{"BT_ATTACK",BT_ATTACK}, // shoot rings {"BT_ATTACK",BT_ATTACK}, // shoot rings
@ -5756,9 +5757,7 @@ struct int_const_s const INT_CONST[] = {
{"GC_WEPSLOT5",GC_WEPSLOT5}, {"GC_WEPSLOT5",GC_WEPSLOT5},
{"GC_WEPSLOT6",GC_WEPSLOT6}, {"GC_WEPSLOT6",GC_WEPSLOT6},
{"GC_WEPSLOT7",GC_WEPSLOT7}, {"GC_WEPSLOT7",GC_WEPSLOT7},
{"GC_WEPSLOT8",GC_WEPSLOT8}, {"GC_SHIELD",GC_SHIELD},
{"GC_WEPSLOT9",GC_WEPSLOT9},
{"GC_WEPSLOT10",GC_WEPSLOT10},
{"GC_FIRE",GC_FIRE}, {"GC_FIRE",GC_FIRE},
{"GC_FIRENORMAL",GC_FIRENORMAL}, {"GC_FIRENORMAL",GC_FIRENORMAL},
{"GC_TOSSFLAG",GC_TOSSFLAG}, {"GC_TOSSFLAG",GC_TOSSFLAG},

View file

@ -164,7 +164,7 @@ void I_SetMusicVolume(UINT8 volume)
(void)volume; (void)volume;
} }
boolean I_SetSongTrack(int track) boolean I_SetSongTrack(INT32 track)
{ {
(void)track; (void)track;
return false; return false;

View file

@ -433,9 +433,19 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want
// okay, now we actually want searchpath to incorporate d_name // okay, now we actually want searchpath to incorporate d_name
strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name); strcpy(&searchpath[searchpathindex[depthleft]],dent->d_name);
#if defined(__linux__) || defined(__FreeBSD__)
if (dent->d_type == DT_UNKNOWN)
if (lstat(searchpath,&fsstat) == 0 && S_ISDIR(fsstat.st_mode))
dent->d_type = DT_DIR;
// Linux and FreeBSD has a special field for file type on dirent, so use that to speed up lookups.
// FIXME: should we also follow symlinks?
if (dent->d_type == DT_DIR && depthleft)
#else
if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat if (stat(searchpath,&fsstat) < 0) // do we want to follow symlinks? if not: change it to lstat
; // was the file (re)moved? can't stat it ; // was the file (re)moved? can't stat it
else if (S_ISDIR(fsstat.st_mode) && depthleft) else if (S_ISDIR(fsstat.st_mode) && depthleft)
#endif
{ {
searchpathindex[--depthleft] = strlen(searchpath) + 1; searchpathindex[--depthleft] = strlen(searchpath) + 1;
dirhandle[depthleft] = opendir(searchpath); dirhandle[depthleft] = opendir(searchpath);

View file

@ -1335,7 +1335,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
#if NUM_WEAPONS > 10 #if NUM_WEAPONS > 10
"Add extra inputs to g_input.h/gamecontrols_e" "Add extra inputs to g_input.h/gamecontrols_e"
#endif #endif
//use the four avaliable bits to determine the weapon. //use the three avaliable bits to determine the weapon.
cmd->buttons &= ~BT_WEAPONMASK; cmd->buttons &= ~BT_WEAPONMASK;
for (i = 0; i < NUM_WEAPONS; ++i) for (i = 0; i < NUM_WEAPONS; ++i)
if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i)) if (PLAYERINPUTDOWN(ssplayer, GC_WEPSLOT1 + i))
@ -1353,9 +1353,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL); axis = PlayerJoyAxis(ssplayer, JA_FIRENORMAL);
if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0)) if (PLAYERINPUTDOWN(ssplayer, GC_FIRENORMAL) || (usejoystick && axis > 0))
cmd->buttons |= BT_FIRENORMAL; cmd->buttons |= BT_FIRENORMAL;
// Toss flag button
if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG)) if (PLAYERINPUTDOWN(ssplayer, GC_TOSSFLAG))
cmd->buttons |= BT_TOSSFLAG; cmd->buttons |= BT_TOSSFLAG;
// Shield button
if (PLAYERINPUTDOWN(ssplayer, GC_SHIELD))
cmd->buttons |= BT_SHIELD;
// Lua scriptable buttons // Lua scriptable buttons
if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1)) if (PLAYERINPUTDOWN(ssplayer, GC_CUSTOM1))
@ -2748,6 +2753,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->pflags |= PF_SPINDOWN; p->pflags |= PF_SPINDOWN;
p->pflags |= PF_ATTACKDOWN; p->pflags |= PF_ATTACKDOWN;
p->pflags |= PF_JUMPDOWN; p->pflags |= PF_JUMPDOWN;
p->pflags |= PF_SHIELDDOWN;
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation

View file

@ -576,9 +576,7 @@ static const char *gamecontrolname[NUM_GAMECONTROLS] =
"weapon5", "weapon5",
"weapon6", "weapon6",
"weapon7", "weapon7",
"weapon8", "shield",
"weapon9",
"weapon10",
"fire", "fire",
"firenormal", "firenormal",
"tossflag", "tossflag",
@ -693,6 +691,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL; gamecontroldefault[gcs_fps][GC_CENTERVIEW ][0] = KEY_LCTRL;
gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_fps][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_fps][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_fps][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL; gamecontroldefault[gcs_fps][GC_FIRE ][0] = KEY_RCTRL;
gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_fps][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT; gamecontroldefault[gcs_fps][GC_FIRENORMAL ][0] = KEY_RALT;
@ -713,6 +712,7 @@ void G_DefineDefaultControls(void)
gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END; gamecontroldefault[gcs_platform][GC_CENTERVIEW ][0] = KEY_END;
gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE; gamecontroldefault[gcs_platform][GC_JUMP ][0] = KEY_SPACE;
gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT; gamecontroldefault[gcs_platform][GC_SPIN ][0] = KEY_LSHIFT;
gamecontroldefault[gcs_platform][GC_SHIELD ][0] = KEY_LALT;
gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's'; gamecontroldefault[gcs_platform][GC_FIRE ][0] = 's';
gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0; gamecontroldefault[gcs_platform][GC_FIRE ][1] = KEY_MOUSE1+0;
gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w'; gamecontroldefault[gcs_platform][GC_FIRENORMAL ][0] = 'w';
@ -728,9 +728,6 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5'; gamecontroldefault[i][GC_WEPSLOT5 ][0] = '5';
gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6'; gamecontroldefault[i][GC_WEPSLOT6 ][0] = '6';
gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7'; gamecontroldefault[i][GC_WEPSLOT7 ][0] = '7';
gamecontroldefault[i][GC_WEPSLOT8 ][0] = '8';
gamecontroldefault[i][GC_WEPSLOT9 ][0] = '9';
gamecontroldefault[i][GC_WEPSLOT10 ][0] = '0';
gamecontroldefault[i][GC_TOSSFLAG ][0] = '\''; gamecontroldefault[i][GC_TOSSFLAG ][0] = '\'';
gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v'; gamecontroldefault[i][GC_CAMTOGGLE ][0] = 'v';
gamecontroldefault[i][GC_CAMRESET ][0] = 'r'; gamecontroldefault[i][GC_CAMRESET ][0] = 'r';
@ -749,15 +746,15 @@ void G_DefineDefaultControls(void)
gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B gamecontroldefault[i][GC_CUSTOM1 ][1] = KEY_JOY1+1; // B
gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y gamecontroldefault[i][GC_CUSTOM2 ][1] = KEY_JOY1+3; // Y
gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick gamecontroldefault[i][GC_CUSTOM3 ][1] = KEY_JOY1+8; // Left Stick
gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_JOY1+4; // LB gamecontroldefault[i][GC_SHIELD ][1] = KEY_JOY1+4; // LB
gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB gamecontroldefault[i][GC_CENTERVIEW ][1] = KEY_JOY1+5; // RB
gamecontroldefault[i][GC_SCREENSHOT ][1] = KEY_JOY1+6; // Back gamecontroldefault[i][GC_SCORES ][1] = KEY_JOY1+6; // Back
gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start gamecontroldefault[i][GC_SYSTEMMENU ][0] = KEY_JOY1+7; // Start
gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left gamecontroldefault[i][GC_WEAPONPREV ][1] = KEY_HAT1+2; // D-Pad Left
gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right gamecontroldefault[i][GC_WEAPONNEXT ][1] = KEY_HAT1+3; // D-Pad Right
gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick gamecontroldefault[i][GC_VIEWPOINTNEXT][1] = KEY_JOY1+9; // Right Stick
gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up gamecontroldefault[i][GC_TOSSFLAG ][1] = KEY_HAT1+0; // D-Pad Up
gamecontroldefault[i][GC_SCORES ][1] = KEY_HAT1+1; // D-Pad Down gamecontroldefault[i][GC_CAMTOGGLE ][1] = KEY_HAT1+1; // D-Pad Down
// Second player controls only have joypad defaults // Second player controls only have joypad defaults
gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A gamecontrolbisdefault[i][GC_JUMP ][1] = KEY_2JOY1+0; // A
@ -765,15 +762,15 @@ void G_DefineDefaultControls(void)
gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B gamecontrolbisdefault[i][GC_CUSTOM1 ][1] = KEY_2JOY1+1; // B
gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y gamecontrolbisdefault[i][GC_CUSTOM2 ][1] = KEY_2JOY1+3; // Y
gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick gamecontrolbisdefault[i][GC_CUSTOM3 ][1] = KEY_2JOY1+8; // Left Stick
gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2JOY1+4; // LB gamecontrolbisdefault[i][GC_SHIELD ][1] = KEY_2JOY1+4; // LB
gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB gamecontrolbisdefault[i][GC_CENTERVIEW ][1] = KEY_2JOY1+5; // RB
gamecontrolbisdefault[i][GC_SCREENSHOT ][1] = KEY_2JOY1+6; // Back //gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2JOY1+6; // Back
//gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start //gamecontrolbisdefault[i][GC_SYSTEMMENU ][0] = KEY_2JOY1+7; // Start
gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left gamecontrolbisdefault[i][GC_WEAPONPREV ][1] = KEY_2HAT1+2; // D-Pad Left
gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right gamecontrolbisdefault[i][GC_WEAPONNEXT ][1] = KEY_2HAT1+3; // D-Pad Right
gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick gamecontrolbisdefault[i][GC_VIEWPOINTNEXT][1] = KEY_2JOY1+9; // Right Stick
gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up gamecontrolbisdefault[i][GC_TOSSFLAG ][1] = KEY_2HAT1+0; // D-Pad Up
//gamecontrolbisdefault[i][GC_SCORES ][1] = KEY_2HAT1+1; // D-Pad Down gamecontrolbisdefault[i][GC_CAMTOGGLE ][1] = KEY_2HAT1+1; // D-Pad Down
} }
} }
@ -1004,6 +1001,7 @@ static void setcontrol(INT32 (*gc)[2])
// TODO: 2.3: Delete the "use" alias // TODO: 2.3: Delete the "use" alias
namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin"; namectrl = (stricmp(COM_Argv(1), "use")) ? COM_Argv(1) : "spin";
for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]); for (numctrl = 0; numctrl < NUM_GAMECONTROLS && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++) numctrl++)

View file

@ -74,9 +74,7 @@ typedef enum
GC_WEPSLOT5, GC_WEPSLOT5,
GC_WEPSLOT6, GC_WEPSLOT6,
GC_WEPSLOT7, GC_WEPSLOT7,
GC_WEPSLOT8, GC_SHIELD,
GC_WEPSLOT9,
GC_WEPSLOT10,
GC_FIRE, GC_FIRE,
GC_FIRENORMAL, GC_FIRENORMAL,
GC_TOSSFLAG, GC_TOSSFLAG,

View file

@ -276,9 +276,6 @@ struct FSurfaceInfo
}; };
typedef struct FSurfaceInfo FSurfaceInfo; typedef struct FSurfaceInfo FSurfaceInfo;
#define GL_DEFAULTMIX 0x00000000
#define GL_DEFAULTFOG 0xFF000000
//Hurdler: added for backward compatibility //Hurdler: added for backward compatibility
enum hwdsetspecialstate enum hwdsetspecialstate
{ {

View file

@ -155,7 +155,6 @@ ps_metric_t ps_hw_batchdrawtime = {0};
boolean gl_init = false; boolean gl_init = false;
boolean gl_maploaded = false; boolean gl_maploaded = false;
boolean gl_sessioncommandsadded = false;
boolean gl_shadersavailable = true; boolean gl_shadersavailable = true;
// ========================================================================== // ==========================================================================
@ -172,8 +171,8 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
RGBA_t poly_color, tint_color, fade_color; RGBA_t poly_color, tint_color, fade_color;
poly_color.rgba = 0xFFFFFFFF; poly_color.rgba = 0xFFFFFFFF;
tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : GL_DEFAULTMIX; tint_color.rgba = (colormap != NULL) ? (UINT32)colormap->rgba : 0x00000000;
fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : GL_DEFAULTFOG; fade_color.rgba = (colormap != NULL) ? (UINT32)colormap->fadergba : 0xFF000000;
// Crappy backup coloring if you can't do shaders // Crappy backup coloring if you can't do shaders
if (!HWR_UseShader()) if (!HWR_UseShader())
@ -187,7 +186,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
blue = (float)poly_color.s.blue; blue = (float)poly_color.s.blue;
// 48 is just an arbritrary value that looked relatively okay. // 48 is just an arbritrary value that looked relatively okay.
tint_alpha = (float)(sqrt(tint_color.s.alpha) * 48) / 255.0f; tint_alpha = (float)(sqrt((float)tint_color.s.alpha / 10.2) * 48) / 255.0f;
// 8 is roughly the brightness of the "close" color in Software, and 16 the brightness of the "far" color. // 8 is roughly the brightness of the "close" color in Software, and 16 the brightness of the "far" color.
// 8 is too bright for dark levels, and 16 is too dark for bright levels. // 8 is too bright for dark levels, and 16 is too dark for bright levels.
@ -230,7 +229,7 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if
RGBA_t realcolor, surfcolor; RGBA_t realcolor, surfcolor;
INT32 alpha; INT32 alpha;
realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX; realcolor.rgba = (colormap != NULL) ? colormap->rgba : 0x00000000;
if (cv_glshaders.value && gl_shadersavailable) if (cv_glshaders.value && gl_shadersavailable)
{ {
@ -570,10 +569,26 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
P_ClosestPointOnLine(viewx, viewy, line->linedef, &v); P_ClosestPointOnLine(viewx, viewy, line->linedef, &v);
dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y)); dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y));
x1 = ((polyvertex_t *)line->pv1)->x; if (line->pv1)
y1 = ((polyvertex_t *)line->pv1)->y; {
xd = ((polyvertex_t *)line->pv2)->x - x1; x1 = ((polyvertex_t *)line->pv1)->x;
yd = ((polyvertex_t *)line->pv2)->y - y1; y1 = ((polyvertex_t *)line->pv1)->y;
}
else
{
x1 = FIXED_TO_FLOAT(line->v1->x);
y1 = FIXED_TO_FLOAT(line->v1->x);
}
if (line->pv2)
{
xd = ((polyvertex_t *)line->pv2)->x - x1;
yd = ((polyvertex_t *)line->pv2)->y - y1;
}
else
{
xd = FIXED_TO_FLOAT(line->v2->x) - x1;
yd = FIXED_TO_FLOAT(line->v2->y) - y1;
}
// Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion // Based on the seg length and the distance from the line, split horizon into multiple poly sets to reduce distortion
dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f; dist = sqrtf((xd*xd) + (yd*yd)) / dist / 16.0f;
@ -1021,10 +1036,26 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
gl_sidedef = gl_curline->sidedef; gl_sidedef = gl_curline->sidedef;
gl_linedef = gl_curline->linedef; gl_linedef = gl_curline->linedef;
vs.x = ((polyvertex_t *)gl_curline->pv1)->x; if (gl_curline->pv1)
vs.y = ((polyvertex_t *)gl_curline->pv1)->y; {
ve.x = ((polyvertex_t *)gl_curline->pv2)->x; vs.x = ((polyvertex_t *)gl_curline->pv1)->x;
ve.y = ((polyvertex_t *)gl_curline->pv2)->y; vs.y = ((polyvertex_t *)gl_curline->pv1)->y;
}
else
{
vs.x = FIXED_TO_FLOAT(gl_curline->v1->x);
vs.y = FIXED_TO_FLOAT(gl_curline->v1->y);
}
if (gl_curline->pv2)
{
ve.x = ((polyvertex_t *)gl_curline->pv2)->x;
ve.y = ((polyvertex_t *)gl_curline->pv2)->y;
}
else
{
ve.x = FIXED_TO_FLOAT(gl_curline->v2->x);
ve.y = FIXED_TO_FLOAT(gl_curline->v2->y);
}
v1x = FLOAT_TO_FIXED(vs.x); v1x = FLOAT_TO_FIXED(vs.x);
v1y = FLOAT_TO_FIXED(vs.y); v1y = FLOAT_TO_FIXED(vs.y);
@ -1818,10 +1849,26 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope) if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope)
{ {
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x); if (gl_curline->pv1)
v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y); {
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x); v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x);
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y); v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y);
}
else
{
v1x = gl_curline->v1->x;
v1y = gl_curline->v1->y;
}
if (gl_curline->pv2)
{
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x);
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y);
}
else
{
v2x = gl_curline->v2->x;
v2y = gl_curline->v2->y;
}
#define SLOPEPARAMS(slope, end1, end2, normalheight) \ #define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = P_GetZAt(slope, v1x, v1y, normalheight); \ end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
end2 = P_GetZAt(slope, v2x, v2y, normalheight); end2 = P_GetZAt(slope, v2x, v2y, normalheight);
@ -1900,10 +1947,26 @@ static void HWR_AddLine(seg_t * line)
gl_curline = line; gl_curline = line;
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x); if (gl_curline->pv1)
v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y); {
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x); v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x);
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y); v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y);
}
else
{
v1x = gl_curline->v1->x;
v1y = gl_curline->v1->y;
}
if (gl_curline->pv2)
{
v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x);
v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y);
}
else
{
v2x = gl_curline->v2->x;
v2y = gl_curline->v2->y;
}
// OPTIMIZE: quickly reject orthogonal back sides. // OPTIMIZE: quickly reject orthogonal back sides.
angle1 = R_PointToAngle64(v1x, v1y); angle1 = R_PointToAngle64(v1x, v1y);
@ -4575,7 +4638,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
rollangle = R_GetRollAngle(spriterotangle); rollangle = R_GetRollAngle(spriterotangle);
} }
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle);
if (rotsprite != NULL) if (rotsprite != NULL)
{ {
@ -5857,7 +5920,7 @@ consvar_t cv_glfakecontrast = CVAR_INIT ("gr_fakecontrast", "Smooth", CV_SAVE, g
consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange); consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange);
consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange); consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_SAVE|CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange);
consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL); consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL);
@ -5899,19 +5962,12 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glallowshaders); CV_RegisterVar(&cv_glallowshaders);
CV_RegisterVar(&cv_glfiltermode); CV_RegisterVar(&cv_glfiltermode);
CV_RegisterVar(&cv_glanisotropicmode);
CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glsolvetjoin);
CV_RegisterVar(&cv_glbatching); CV_RegisterVar(&cv_glbatching);
} }
void HWR_AddSessionCommands(void)
{
if (gl_sessioncommandsadded)
return;
CV_RegisterVar(&cv_glanisotropicmode);
gl_sessioncommandsadded = true;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Setup the hardware renderer // Setup the hardware renderer
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -5922,7 +5978,6 @@ void HWR_Startup(void)
CONS_Printf("HWR_Startup()...\n"); CONS_Printf("HWR_Startup()...\n");
HWR_InitPolyPool(); HWR_InitPolyPool();
HWR_AddSessionCommands();
HWR_InitMapTextures(); HWR_InitMapTextures();
HWR_InitModels(); HWR_InitModels();
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
@ -5945,10 +6000,6 @@ void HWR_Startup(void)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
void HWR_Switch(void) void HWR_Switch(void)
{ {
// Add session commands
if (!gl_sessioncommandsadded)
HWR_AddSessionCommands();
// Set special states from CVARs // Set special states from CVARs
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value); HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);

View file

@ -51,7 +51,6 @@ UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *pathname); boolean HWR_Screenshot(const char *pathname);
void HWR_AddCommands(void); void HWR_AddCommands(void);
void HWR_AddSessionCommands(void);
void transform(float *cx, float *cy, float *cz); void transform(float *cx, float *cy, float *cz);
INT32 HWR_GetTextureUsed(void); INT32 HWR_GetTextureUsed(void);
void HWR_DoPostProcessor(player_t *player); void HWR_DoPostProcessor(player_t *player);

View file

@ -1140,9 +1140,6 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED); Z_ChangeTag(newMipmap->data, PU_HWRMODELTEXTURE_UNLOCKED);
} }
#define NORMALFOG 0x00000000
#define FADEFOG 0x19000000
static boolean HWR_AllowModel(mobj_t *mobj) static boolean HWR_AllowModel(mobj_t *mobj)
{ {
// Signpost overlay. Not needed. // Signpost overlay. Not needed.

View file

@ -698,7 +698,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
#define GLSL_SOFTWARE_TINT_EQUATION \ #define GLSL_SOFTWARE_TINT_EQUATION \
"if (tint_color.a > 0.0) {\n" \ "if (tint_color.a > 0.0) {\n" \
"float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \
"float strength = sqrt(9.0 * tint_color.a);\n" \ "float strength = sqrt(tint_color.a);\n" \
"final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \
"final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \
"final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \

View file

@ -213,6 +213,8 @@ static const struct {
{META_HUDINFO, "hudinfo_t"}, {META_HUDINFO, "hudinfo_t"},
{META_PATCH, "patch_t"}, {META_PATCH, "patch_t"},
{META_COLORMAP, "colormap"}, {META_COLORMAP, "colormap"},
{META_EXTRACOLORMAP,"extracolormap_t"},
{META_LIGHTTABLE, "lighttable_t"},
{META_CAMERA, "camera_t"}, {META_CAMERA, "camera_t"},
{META_ACTION, "action"}, {META_ACTION, "action"},
@ -1686,11 +1688,12 @@ static int lib_pHomingAttack(lua_State *L)
static int lib_pSuperReady(lua_State *L) static int lib_pSuperReady(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean transform = (boolean)lua_opttrueboolean(L, 2);
//HUDSAFE //HUDSAFE
INLEVEL INLEVEL
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
lua_pushboolean(L, P_SuperReady(player)); lua_pushboolean(L, P_SuperReady(player, transform));
return 1; return 1;
} }
@ -2021,6 +2024,30 @@ static int lib_pCeilingzAtPos(lua_State *L)
return 1; return 1;
} }
static int lib_pGetSectorColormapAt(lua_State *L)
{
boolean has_sector = false;
sector_t *sector = NULL;
if (!lua_isnoneornil(L, 1))
{
has_sector = true;
sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
}
fixed_t x = luaL_checkfixed(L, 2);
fixed_t y = luaL_checkfixed(L, 3);
fixed_t z = luaL_checkfixed(L, 4);
INLEVEL
if (has_sector && !sector)
return LUA_ErrInvalid(L, "sector_t");
extracolormap_t *exc;
if (sector)
exc = P_GetColormapFromSectorAt(sector, x, y, z);
else
exc = P_GetSectorColormapAt(x, y, z);
LUA_PushUserdata(L, exc, META_EXTRACOLORMAP);
return 1;
}
static int lib_pDoSpring(lua_State *L) static int lib_pDoSpring(lua_State *L)
{ {
mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *spring = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -4303,6 +4330,7 @@ static luaL_Reg lib[] = {
{"P_RadiusAttack",lib_pRadiusAttack}, {"P_RadiusAttack",lib_pRadiusAttack},
{"P_FloorzAtPos",lib_pFloorzAtPos}, {"P_FloorzAtPos",lib_pFloorzAtPos},
{"P_CeilingzAtPos",lib_pCeilingzAtPos}, {"P_CeilingzAtPos",lib_pCeilingzAtPos},
{"P_GetSectorColormapAt",lib_pGetSectorColormapAt},
{"P_DoSpring",lib_pDoSpring}, {"P_DoSpring",lib_pDoSpring},
{"P_TouchSpecialThing",lib_pTouchSpecialThing}, {"P_TouchSpecialThing",lib_pTouchSpecialThing},
{"P_TryCameraMove", lib_pTryCameraMove}, {"P_TryCameraMove", lib_pTryCameraMove},

332
src/lua_colorlib.c Normal file
View file

@ -0,0 +1,332 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2021-2022 by "Lactozilla".
// Copyright (C) 2014-2023 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_colorlib.c
/// \brief color and colormap libraries for Lua scripting
#include "doomdef.h"
#include "fastcmp.h"
#include "r_data.h"
#include "lua_script.h"
#include "lua_libs.h"
#define IS_HEX_CHAR(x) ((x >= '0' && x <= '9') || (x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F'))
#define ARE_HEX_CHARS(str, i) IS_HEX_CHAR(str[i]) && IS_HEX_CHAR(str[i + 1])
static UINT32 hex2int(char x)
{
if (x >= '0' && x <= '9')
return x - '0';
else if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
else if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
return 0;
}
static UINT8 ParseHTMLColor(const char *str, UINT8 *rgba, size_t numc)
{
const char *hex = str;
if (hex[0] == '#')
hex++;
else if (!IS_HEX_CHAR(hex[0]))
return 0;
size_t len = strlen(hex);
if (len == 3)
{
// Shorthand like #09C
for (unsigned i = 0; i < 3; i++)
{
if (!IS_HEX_CHAR(hex[i]))
return 0;
UINT32 hx = hex2int(hex[i]);
*rgba++ = (hx * 16) + hx;
}
return 3;
}
else if (len == 6 || len == 8)
{
if (numc != 4)
len = 6;
// A triplet like #0099CC
for (unsigned i = 0; i < len; i += 2)
{
if (!ARE_HEX_CHARS(hex, i))
return false;
*rgba++ = (hex2int(hex[i]) * 16) + hex2int(hex[i + 1]);
}
return len;
}
return 0;
}
/////////////////////////
// extracolormap userdata
/////////////////////////
enum extracolormap_e {
extracolormap_red = 0,
extracolormap_green,
extracolormap_blue,
extracolormap_alpha,
extracolormap_color,
extracolormap_fade_red,
extracolormap_fade_green,
extracolormap_fade_blue,
extracolormap_fade_alpha,
extracolormap_fade_color,
extracolormap_fade_start,
extracolormap_fade_end,
extracolormap_colormap
};
static const char *const extracolormap_opt[] = {
"red",
"green",
"blue",
"alpha",
"color",
"fade_red",
"fade_green",
"fade_blue",
"fade_alpha",
"fade_color",
"fade_start",
"fade_end",
"colormap",
NULL};
static int extracolormap_get(lua_State *L)
{
extracolormap_t *exc = *((extracolormap_t **)luaL_checkudata(L, 1, META_EXTRACOLORMAP));
enum extracolormap_e field = luaL_checkoption(L, 2, NULL, extracolormap_opt);
switch (field)
{
case extracolormap_red:
lua_pushinteger(L, R_GetRgbaR(exc->rgba));
break;
case extracolormap_green:
lua_pushinteger(L, R_GetRgbaG(exc->rgba));
break;
case extracolormap_blue:
lua_pushinteger(L, R_GetRgbaB(exc->rgba));
break;
case extracolormap_alpha:
lua_pushinteger(L, R_GetRgbaA(exc->rgba));
break;
case extracolormap_color:
lua_pushinteger(L, R_GetRgbaR(exc->rgba));
lua_pushinteger(L, R_GetRgbaG(exc->rgba));
lua_pushinteger(L, R_GetRgbaB(exc->rgba));
lua_pushinteger(L, R_GetRgbaA(exc->rgba));
return 4;
case extracolormap_fade_red:
lua_pushinteger(L, R_GetRgbaR(exc->fadergba));
break;
case extracolormap_fade_green:
lua_pushinteger(L, R_GetRgbaG(exc->fadergba));
break;
case extracolormap_fade_blue:
lua_pushinteger(L, R_GetRgbaB(exc->fadergba));
break;
case extracolormap_fade_alpha:
lua_pushinteger(L, R_GetRgbaA(exc->fadergba));
break;
case extracolormap_fade_color:
lua_pushinteger(L, R_GetRgbaR(exc->fadergba));
lua_pushinteger(L, R_GetRgbaG(exc->fadergba));
lua_pushinteger(L, R_GetRgbaB(exc->fadergba));
lua_pushinteger(L, R_GetRgbaA(exc->fadergba));
return 4;
case extracolormap_fade_start:
lua_pushinteger(L, exc->fadestart);
break;
case extracolormap_fade_end:
lua_pushinteger(L, exc->fadeend);
break;
case extracolormap_colormap:
LUA_PushUserdata(L, exc->colormap, META_LIGHTTABLE);
break;
}
return 1;
}
static void GetExtraColormapRGBA(lua_State *L, UINT8 *rgba, int arg)
{
if (lua_type(L, arg) == LUA_TSTRING)
{
const char *str = lua_tostring(L, arg);
UINT8 parsed = ParseHTMLColor(str, rgba, 4);
if (!parsed)
luaL_error(L, "Malformed HTML color '%s'", str);
}
else
{
UINT32 colors = lua_tointeger(L, arg);
if (colors > 0xFFFFFF)
{
rgba[0] = (colors >> 24) & 0xFF;
rgba[1] = (colors >> 16) & 0xFF;
rgba[2] = (colors >> 8) & 0xFF;
rgba[3] = colors & 0xFF;
}
else
{
rgba[0] = (colors >> 16) & 0xFF;
rgba[1] = (colors >> 8) & 0xFF;
rgba[2] = colors & 0xFF;
rgba[3] = 0xFF;
}
}
}
static int extracolormap_set(lua_State *L)
{
extracolormap_t *exc = *((extracolormap_t **)luaL_checkudata(L, 1, META_EXTRACOLORMAP));
enum extracolormap_e field = luaL_checkoption(L, 2, NULL, extracolormap_opt);
UINT8 r = R_GetRgbaR(exc->rgba);
UINT8 g = R_GetRgbaG(exc->rgba);
UINT8 b = R_GetRgbaB(exc->rgba);
UINT8 a = R_GetRgbaA(exc->rgba);
UINT8 fr = R_GetRgbaR(exc->fadergba);
UINT8 fg = R_GetRgbaG(exc->fadergba);
UINT8 fb = R_GetRgbaB(exc->fadergba);
UINT8 fa = R_GetRgbaA(exc->fadergba);
UINT8 rgba[4];
INT32 old_rgba = exc->rgba, old_fade_rgba = exc->fadergba; // It's not unsigned?
UINT8 old_fade_start = exc->fadestart, old_fade_end = exc->fadeend;
#define val luaL_checkinteger(L, 3)
switch(field)
{
case extracolormap_red:
exc->rgba = R_PutRgbaRGBA(val, g, b, a);
break;
case extracolormap_green:
exc->rgba = R_PutRgbaRGBA(r, val, b, a);
break;
case extracolormap_blue:
exc->rgba = R_PutRgbaRGBA(r, g, val, a);
break;
case extracolormap_alpha:
exc->rgba = R_PutRgbaRGBA(r, g, b, val);
break;
case extracolormap_color:
rgba[0] = r;
rgba[1] = g;
rgba[2] = b;
rgba[3] = a;
GetExtraColormapRGBA(L, rgba, 3);
exc->rgba = R_PutRgbaRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
break;
case extracolormap_fade_red:
exc->fadergba = R_PutRgbaRGBA(val, fg, fb, fa);
break;
case extracolormap_fade_green:
exc->fadergba = R_PutRgbaRGBA(fr, val, fb, fa);
break;
case extracolormap_fade_blue:
exc->fadergba = R_PutRgbaRGBA(fr, fg, val, fa);
break;
case extracolormap_fade_alpha:
exc->fadergba = R_PutRgbaRGBA(fr, fg, fb, val);
break;
case extracolormap_fade_color:
rgba[0] = fr;
rgba[1] = fg;
rgba[2] = fb;
rgba[3] = fa;
GetExtraColormapRGBA(L, rgba, 3);
exc->fadergba = R_PutRgbaRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
break;
case extracolormap_fade_start:
if (val > 31)
return luaL_error(L, "fade start %d out of range (0 - 31)", val);
exc->fadestart = val;
break;
case extracolormap_fade_end:
if (val > 31)
return luaL_error(L, "fade end %d out of range (0 - 31)", val);
exc->fadeend = val;
break;
case extracolormap_colormap:
return luaL_error(L, LUA_QL("extracolormap_t") " field " LUA_QS " should not be set directly.", extracolormap_opt[field]);
}
#undef val
if (exc->rgba != old_rgba
|| exc->fadergba != old_fade_rgba
|| exc->fadestart != old_fade_start
|| exc->fadeend != old_fade_end)
R_GenerateLightTable(exc, true);
return 0;
}
static int lighttable_get(lua_State *L)
{
void **userdata;
lighttable_t *table = *((lighttable_t **)luaL_checkudata(L, 1, META_LIGHTTABLE));
UINT32 row = luaL_checkinteger(L, 2);
if (row < 1 || row > 34)
return luaL_error(L, "lighttable row %d out of range (1 - %d)", row, 34);
userdata = lua_newuserdata(L, sizeof(void *));
*userdata = &table[256 * (row - 1)];
luaL_getmetatable(L, META_COLORMAP);
lua_setmetatable(L, -2);
return 1;
}
static int lighttable_len(lua_State *L)
{
lua_pushinteger(L, NUM_PALETTE_ENTRIES);
return 1;
}
int LUA_ColorLib(lua_State *L)
{
luaL_newmetatable(L, META_EXTRACOLORMAP);
lua_pushcfunction(L, extracolormap_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, extracolormap_set);
lua_setfield(L, -2, "__newindex");
lua_pop(L, 1);
luaL_newmetatable(L, META_LIGHTTABLE);
lua_pushcfunction(L, lighttable_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lighttable_len);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
return 0;
}

View file

@ -517,7 +517,7 @@ static int libd_getSpritePatch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle); INT32 rot = R_GetRollAngle(rollangle);
if (rot) { if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), true, &spriteinfo[i], rot); patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &spriteinfo[i], rot);
LUA_PushUserdata(L, rotsprite, META_PATCH); LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false); lua_pushboolean(L, false);
lua_pushboolean(L, true); lua_pushboolean(L, true);
@ -629,7 +629,7 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle); INT32 rot = R_GetRollAngle(rollangle);
if (rot) { if (rot) {
patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), true, &skins[i].sprinfo[j], rot); patch_t *rotsprite = Patch_GetRotatedSprite(sprframe, frame, angle, sprframe->flip & (1<<angle), &skins[i].sprinfo[j], rot);
LUA_PushUserdata(L, rotsprite, META_PATCH); LUA_PushUserdata(L, rotsprite, META_PATCH);
lua_pushboolean(L, false); lua_pushboolean(L, false);
lua_pushboolean(L, true); lua_pushboolean(L, true);

View file

@ -85,6 +85,8 @@ extern boolean ignoregameinputs;
#define META_HUDINFO "HUDINFO_T*" #define META_HUDINFO "HUDINFO_T*"
#define META_PATCH "PATCH_T*" #define META_PATCH "PATCH_T*"
#define META_COLORMAP "COLORMAP" #define META_COLORMAP "COLORMAP"
#define META_EXTRACOLORMAP "EXTRACOLORMAP_T*"
#define META_LIGHTTABLE "LIGHTTABLE_T*"
#define META_CAMERA "CAMERA_T*" #define META_CAMERA "CAMERA_T*"
#define META_ACTION "ACTIONF_T*" #define META_ACTION "ACTIONF_T*"
@ -112,4 +114,5 @@ int LUA_TagLib(lua_State *L);
int LUA_PolyObjLib(lua_State *L); int LUA_PolyObjLib(lua_State *L);
int LUA_BlockmapLib(lua_State *L); int LUA_BlockmapLib(lua_State *L);
int LUA_HudLib(lua_State *L); int LUA_HudLib(lua_State *L);
int LUA_ColorLib(lua_State *L);
int LUA_InputLib(lua_State *L); int LUA_InputLib(lua_State *L);

View file

@ -57,6 +57,7 @@ enum sector_e {
sector_ffloors, sector_ffloors,
sector_fslope, sector_fslope,
sector_cslope, sector_cslope,
sector_colormap,
sector_flags, sector_flags,
sector_specialflags, sector_specialflags,
sector_damagetype, sector_damagetype,
@ -95,6 +96,7 @@ static const char *const sector_opt[] = {
"ffloors", "ffloors",
"f_slope", "f_slope",
"c_slope", "c_slope",
"colormap",
"flags", "flags",
"specialflags", "specialflags",
"damagetype", "damagetype",
@ -751,6 +753,9 @@ static int sector_get(lua_State *L)
case sector_cslope: // c_slope case sector_cslope: // c_slope
LUA_PushUserdata(L, sector->c_slope, META_SLOPE); LUA_PushUserdata(L, sector->c_slope, META_SLOPE);
return 1; return 1;
case sector_colormap: // extra_colormap
LUA_PushUserdata(L, sector->extra_colormap, META_EXTRACOLORMAP);
return 1;
case sector_flags: // flags case sector_flags: // flags
lua_pushinteger(L, sector->flags); lua_pushinteger(L, sector->flags);
return 1; return 1;
@ -1062,7 +1067,7 @@ static int line_get(lua_State *L)
LUA_PushUserdata(L, &sides[line->sidenum[0]], META_SIDE); LUA_PushUserdata(L, &sides[line->sidenum[0]], META_SIDE);
return 1; return 1;
case line_backside: // backside case line_backside: // backside
if (line->sidenum[1] == 0xffff) if (line->sidenum[1] == NO_SIDEDEF)
return 0; return 0;
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE); LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
return 1; return 1;
@ -1235,6 +1240,9 @@ static int side_get(lua_State *L)
// TODO: 2.3: Delete // TODO: 2.3: Delete
case side_text: case side_text:
{ {
boolean isfrontside;
size_t sidei = side-sides;
if (udmf) if (udmf)
{ {
LUA_Deprecated(L, "(sidedef_t).text", "(sidedef_t).line.stringargs"); LUA_Deprecated(L, "(sidedef_t).text", "(sidedef_t).line.stringargs");
@ -1242,7 +1250,7 @@ static int side_get(lua_State *L)
return 1; return 1;
} }
boolean isfrontside = side->line->sidenum[0] == side-sides; isfrontside = side->line->sidenum[0] == sidei;
lua_pushstring(L, side->line->stringargs[isfrontside ? 0 : 1]); lua_pushstring(L, side->line->stringargs[isfrontside ? 0 : 1]);
return 1; return 1;

View file

@ -58,6 +58,7 @@ static lua_CFunction liblist[] = {
LUA_PolyObjLib, // polyobj_t LUA_PolyObjLib, // polyobj_t
LUA_BlockmapLib, // blockmap stuff LUA_BlockmapLib, // blockmap stuff
LUA_HudLib, // HUD stuff LUA_HudLib, // HUD stuff
LUA_ColorLib, // general color functions
LUA_InputLib, // inputs LUA_InputLib, // inputs
NULL NULL
}; };

View file

@ -1069,6 +1069,7 @@ static menuitem_t OP_ChangeControlsMenu[] =
{IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT }, {IT_CALL | IT_STRING2, NULL, "Move Right", M_ChangeControl, GC_STRAFERIGHT },
{IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP }, {IT_CALL | IT_STRING2, NULL, "Jump", M_ChangeControl, GC_JUMP },
{IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN }, {IT_CALL | IT_STRING2, NULL, "Spin", M_ChangeControl, GC_SPIN },
{IT_CALL | IT_STRING2, NULL, "Shield", M_ChangeControl, GC_SHIELD },
{IT_HEADER, NULL, "Camera", NULL, 0}, {IT_HEADER, NULL, "Camera", NULL, 0},
{IT_SPACE, NULL, NULL, NULL, 0}, // padding {IT_SPACE, NULL, NULL, NULL, 0}, // padding
{IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP }, {IT_CALL | IT_STRING2, NULL, "Look Up", M_ChangeControl, GC_LOOKUP },
@ -13114,23 +13115,23 @@ static void M_Setup1PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Unhide the nine non-P2 controls and their headers // Unhide the nine non-P2 controls and their headers
//OP_ChangeControlsMenu[18+0].status = IT_HEADER; //OP_ChangeControlsMenu[19+0].status = IT_HEADER;
//OP_ChangeControlsMenu[18+1].status = IT_SPACE; //OP_ChangeControlsMenu[19+1].status = IT_SPACE;
// ... // ...
OP_ChangeControlsMenu[18+2].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+2].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+4].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+4].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+5].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+5].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+6].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+6].status = IT_CALL|IT_STRING2;
//OP_ChangeControlsMenu[18+7].status = IT_CALL|IT_STRING2; //OP_ChangeControlsMenu[19+7].status = IT_CALL|IT_STRING2;
//OP_ChangeControlsMenu[18+8].status = IT_CALL|IT_STRING2; //OP_ChangeControlsMenu[19+8].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[18+9].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[19+9].status = IT_CALL|IT_STRING2;
// ... // ...
OP_ChangeControlsMenu[28+0].status = IT_HEADER; OP_ChangeControlsMenu[29+0].status = IT_HEADER;
OP_ChangeControlsMenu[28+1].status = IT_SPACE; OP_ChangeControlsMenu[29+1].status = IT_SPACE;
// ... // ...
OP_ChangeControlsMenu[28+2].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[29+2].status = IT_CALL|IT_STRING2;
OP_ChangeControlsMenu[28+3].status = IT_CALL|IT_STRING2; OP_ChangeControlsMenu[29+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
@ -13146,23 +13147,23 @@ static void M_Setup2PControlsMenu(INT32 choice)
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
// Hide the nine non-P2 controls and their headers // Hide the nine non-P2 controls and their headers
//OP_ChangeControlsMenu[18+0].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+0].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+1].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+1].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[18+2].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+2].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+4].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+4].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+5].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+5].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+6].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+6].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+7].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+7].status = IT_GRAYEDOUT2;
//OP_ChangeControlsMenu[18+8].status = IT_GRAYEDOUT2; //OP_ChangeControlsMenu[19+8].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[18+9].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[19+9].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[28+0].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+0].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[28+1].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+1].status = IT_GRAYEDOUT2;
// ... // ...
OP_ChangeControlsMenu[28+2].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+2].status = IT_GRAYEDOUT2;
OP_ChangeControlsMenu[28+3].status = IT_GRAYEDOUT2; OP_ChangeControlsMenu[29+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef; OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level

View file

@ -2805,3 +2805,17 @@ boolean M_IsStringEmpty(const char *s)
return true; return true;
} }
// Rounds off floating numbers and checks for 0 - 255 bounds
int M_RoundUp(double number)
{
if (number > 255.0l)
return 255;
if (number < 0.0l)
return 0;
if ((int)number <= (int)(number - 0.5f))
return (int)number + 1;
return (int)number;
}

View file

@ -112,6 +112,9 @@ boolean M_IsStringEmpty(const char *s);
// counting bits, for weapon ammo code, usually // counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
// Rounds off floating numbers and checks for 0 - 255 bounds
int M_RoundUp(double number);
#include "w_wad.h" #include "w_wad.h"
extern char configfile[MAX_WADPATH]; extern char configfile[MAX_WADPATH];

View file

@ -154,6 +154,8 @@ typedef union
#define ERRSOCKET (-1) #define ERRSOCKET (-1)
#endif #endif
#define IPV6_MULTICAST_ADDRESS "ff15::57e1:1a12"
// define socklen_t in DOS/Windows if it is not already defined // define socklen_t in DOS/Windows if it is not already defined
#ifdef USE_WINSOCK1 #ifdef USE_WINSOCK1
typedef int socklen_t; typedef int socklen_t;
@ -621,6 +623,7 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6); socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
#endif #endif
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t); socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
ssize_t status;
switch (sockaddr->any.sa_family) switch (sockaddr->any.sa_family)
{ {
@ -631,7 +634,12 @@ static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr
default: d = da; break; default: d = da; break;
} }
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d); status = sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
if (status == -1)
{
CONS_Alert(CONS_WARNING, "Unable to send packet to %s: %s\n", SOCK_AddrToStr(sockaddr), strerror(errno));
}
return status;
} }
static void SOCK_Send(void) static void SOCK_Send(void)
@ -770,6 +778,24 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
return (SOCKET_TYPE)ERRSOCKET; return (SOCKET_TYPE)ERRSOCKET;
} }
#ifdef HAVE_IPV6
if (family == AF_INET6)
{
// we need to set all of this *after* binding to an address!
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
{
struct ipv6_mreq maddr;
inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &maddr.ipv6mr_multiaddr);
maddr.ipv6mr_interface = 0;
if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&maddr, sizeof(maddr)) != 0)
{
CONS_Alert(CONS_WARNING, M_GetText("Could not register multicast address\n"));
}
}
}
#endif
#ifdef FIONBIO #ifdef FIONBIO
// make it non blocking // make it non blocking
opt = true; opt = true;
@ -950,65 +976,28 @@ static boolean UDP_Socket(void)
// ip + udp // ip + udp
packetheaderlength = 20 + 8; // for stats packetheaderlength = 20 + 8; // for stats
hints.ai_family = AF_INET; clientaddress[s].any.sa_family = AF_INET;
gaie = I_getaddrinfo("127.0.0.1", "0", &hints, &ai); clientaddress[s].ip4.sin_port = htons(0);
if (gaie == 0) clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
{ s++;
runp = ai;
while (runp != NULL && s < MAXNETNODES+1)
{
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
else
{
clientaddress[s].any.sa_family = AF_INET;
clientaddress[s].ip4.sin_port = htons(0);
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
s++;
}
s = 0; s = 0;
// setup broadcast adress to BROADCASTADDR entry // setup broadcast adress to BROADCASTADDR entry
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai); broadcastaddress[s].any.sa_family = AF_INET;
if (gaie == 0) broadcastaddress[s].ip4.sin_port = htons(atoi(DEFAULTPORT));
{ broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
runp = ai; s++;
while (runp != NULL && s < MAXNETNODES+1)
{
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
else
{
broadcastaddress[s].any.sa_family = AF_INET;
broadcastaddress[s].ip4.sin_port = htons(0);
broadcastaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_BROADCAST);
s++;
}
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
if (b_ipv6) if (b_ipv6)
{ {
hints.ai_family = AF_INET6; broadcastaddress[s].any.sa_family = AF_INET6;
gaie = I_getaddrinfo("ff02::1", "0", &hints, &ai); broadcastaddress[s].ip6.sin6_port = htons(atoi(DEFAULTPORT));
if (gaie == 0) broadcastaddress[s].ip6.sin6_flowinfo = 0;
{ inet_pton(AF_INET6, IPV6_MULTICAST_ADDRESS, &broadcastaddress[s].ip6.sin6_addr);
runp = ai; broadcastaddress[s].ip6.sin6_scope_id = 0;
while (runp != NULL && s < MAXNETNODES+1) s++;
{
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++;
runp = runp->ai_next;
}
I_freeaddrinfo(ai);
}
} }
#endif #endif

View file

@ -202,7 +202,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius); void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius);
boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
boolean P_SuperReady(player_t *player); boolean P_SuperReady(player_t *player, boolean transform);
void P_DoJump(player_t *player, boolean soundandstate); void P_DoJump(player_t *player, boolean soundandstate);
void P_DoSpinDashDust(player_t *player); void P_DoSpinDashDust(player_t *player);
#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) #define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)
@ -445,6 +445,10 @@ boolean PIT_PushableMoved(mobj_t *thing);
boolean P_DoSpring(mobj_t *spring, mobj_t *object); boolean P_DoSpring(mobj_t *spring, mobj_t *object);
INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z);
extracolormap_t *P_GetSectorColormapAt(fixed_t x, fixed_t y, fixed_t z);
// //
// P_SETUP // P_SETUP
// //

View file

@ -3905,7 +3905,7 @@ retry:
P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy, P_PathTraverse(leadx, traily, leadx + mo->momx, traily + mo->momy,
PT_ADDLINES, PTR_SlideTraverse); PT_ADDLINES, PTR_SlideTraverse);
if (bestslideline && mo->player && bestslideline->sidenum[1] != 0xffff) if (bestslideline && mo->player && bestslideline->sidenum[1] != NO_SIDEDEF)
{ {
sector_t *sec = P_PointOnLineSide(mo->x, mo->y, bestslideline) ? bestslideline->frontsector : bestslideline->backsector; sector_t *sec = P_PointOnLineSide(mo->x, mo->y, bestslideline) ? bestslideline->frontsector : bestslideline->backsector;
P_CheckLavaWall(mo, sec); P_CheckLavaWall(mo, sec);
@ -5071,3 +5071,35 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
return ceilingz; return ceilingz;
} }
INT32 P_GetSectorLightAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
{
if (!sector->numlights)
return -1;
INT32 light = sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights!
for (INT32 lightnum = 1; lightnum < sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&sector->lightlist[lightnum], x, y);
if (h <= z) {
light = lightnum - 1;
break;
}
}
return light;
}
extracolormap_t *P_GetColormapFromSectorAt(sector_t *sector, fixed_t x, fixed_t y, fixed_t z)
{
if (sector->numlights)
return *sector->lightlist[P_GetSectorLightAt(sector, x, y, z)].extra_colormap;
else
return sector->extra_colormap;
}
extracolormap_t *P_GetSectorColormapAt(fixed_t x, fixed_t y, fixed_t z)
{
return P_GetColormapFromSectorAt(R_PointInSubsector(x, y)->sector, x, y, z);
}

View file

@ -290,7 +290,7 @@ void P_CameraLineOpening(line_t *linedef)
sector_t *back; sector_t *back;
fixed_t frontfloor, frontceiling, backfloor, backceiling; fixed_t frontfloor, frontceiling, backfloor, backceiling;
if (linedef->sidenum[1] == 0xffff) if (linedef->sidenum[1] == NO_SIDEDEF)
{ {
// single sided line // single sided line
openrange = 0; openrange = 0;
@ -426,7 +426,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
{ {
sector_t *front, *back; sector_t *front, *back;
if (linedef->sidenum[1] == 0xffff) if (linedef->sidenum[1] == NO_SIDEDEF)
{ {
// single sided line // single sided line
openrange = 0; openrange = 0;

View file

@ -11206,6 +11206,10 @@ void P_RemoveMobj(mobj_t *mobj)
P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL)); P_SetTarget(&mobj->hnext, P_SetTarget(&mobj->hprev, NULL));
// clear the reference from the mapthing
if (mobj->spawnpoint)
mobj->spawnpoint->mobj = NULL;
R_RemoveMobjInterpolator(mobj); R_RemoveMobjInterpolator(mobj);
// free block // free block

View file

@ -1079,7 +1079,7 @@ static void ArchiveSectors(void)
if (diff) if (diff)
{ {
WRITEUINT16(save_p, i); WRITEUINT32(save_p, i);
WRITEUINT8(save_p, diff); WRITEUINT8(save_p, diff);
if (diff & SD_DIFF2) if (diff & SD_DIFF2)
WRITEUINT8(save_p, diff2); WRITEUINT8(save_p, diff2);
@ -1150,18 +1150,19 @@ static void ArchiveSectors(void)
} }
} }
WRITEUINT16(save_p, 0xffff); WRITEUINT32(save_p, 0xffffffff);
} }
static void UnArchiveSectors(void) static void UnArchiveSectors(void)
{ {
UINT16 i, j; UINT32 i;
UINT16 j;
UINT8 diff, diff2, diff3, diff4; UINT8 diff, diff2, diff3, diff4;
for (;;) for (;;)
{ {
i = READUINT16(save_p); i = READUINT32(save_p);
if (i == 0xffff) if (i == 0xffffffff)
break; break;
if (i > numsectors) if (i > numsectors)
@ -1299,7 +1300,7 @@ static void ArchiveLines(void)
if (li->executordelay != spawnli->executordelay) if (li->executordelay != spawnli->executordelay)
diff2 |= LD_EXECUTORDELAY; diff2 |= LD_EXECUTORDELAY;
if (li->sidenum[0] != 0xffff) if (li->sidenum[0] != NO_SIDEDEF)
{ {
si = &sides[li->sidenum[0]]; si = &sides[li->sidenum[0]];
spawnsi = &spawnsides[li->sidenum[0]]; spawnsi = &spawnsides[li->sidenum[0]];
@ -1313,7 +1314,7 @@ static void ArchiveLines(void)
if (si->midtexture != spawnsi->midtexture) if (si->midtexture != spawnsi->midtexture)
diff |= LD_S1MIDTEX; diff |= LD_S1MIDTEX;
} }
if (li->sidenum[1] != 0xffff) if (li->sidenum[1] != NO_SIDEDEF)
{ {
si = &sides[li->sidenum[1]]; si = &sides[li->sidenum[1]];
spawnsi = &spawnsides[li->sidenum[1]]; spawnsi = &spawnsides[li->sidenum[1]];
@ -1332,7 +1333,7 @@ static void ArchiveLines(void)
if (diff) if (diff)
{ {
WRITEINT16(save_p, i); WRITEUINT32(save_p, i);
WRITEUINT8(save_p, diff); WRITEUINT8(save_p, diff);
if (diff & LD_DIFF2) if (diff & LD_DIFF2)
WRITEUINT8(save_p, diff2); WRITEUINT8(save_p, diff2);
@ -1391,21 +1392,21 @@ static void ArchiveLines(void)
WRITEINT32(save_p, li->executordelay); WRITEINT32(save_p, li->executordelay);
} }
} }
WRITEUINT16(save_p, 0xffff); WRITEUINT32(save_p, 0xffffffff);
} }
static void UnArchiveLines(void) static void UnArchiveLines(void)
{ {
UINT16 i; UINT32 i;
line_t *li; line_t *li;
side_t *si; side_t *si;
UINT8 diff, diff2; // no diff3 UINT8 diff, diff2; // no diff3
for (;;) for (;;)
{ {
i = READUINT16(save_p); i = READUINT32(save_p);
if (i == 0xffff) if (i == 0xffffffff)
break; break;
if (i > numlines) if (i > numlines)
I_Error("Invalid line number %u from server", i); I_Error("Invalid line number %u from server", i);

View file

@ -1111,40 +1111,40 @@ static void P_InitializeLinedef(line_t *ld)
// cph 2006/09/30 - fix sidedef errors right away. // cph 2006/09/30 - fix sidedef errors right away.
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them // cph 2002/07/20 - these errors are fatal if not fixed, so apply them
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) if (ld->sidenum[j] != NO_SIDEDEF && ld->sidenum[j] >= (UINT32)numsides)
{ {
ld->sidenum[j] = 0xffff; ld->sidenum[j] = NO_SIDEDEF;
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines))); CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines)));
} }
// killough 11/98: fix common wad errors (missing sidedefs): // killough 11/98: fix common wad errors (missing sidedefs):
if (ld->sidenum[0] == 0xffff) if (ld->sidenum[0] == NO_SIDEDEF)
{ {
ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side
// cph - print a warning about the bug // cph - print a warning about the bug
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines))); CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines)));
} }
if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) if ((ld->sidenum[1] == NO_SIDEDEF) && (ld->flags & ML_TWOSIDED))
{ {
ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side
// cph - print a warning about the bug // cph - print a warning about the bug
CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines))); CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines)));
} }
if (ld->sidenum[0] != 0xffff) if (ld->sidenum[0] != NO_SIDEDEF)
{ {
sides[ld->sidenum[0]].special = ld->special; sides[ld->sidenum[0]].special = ld->special;
sides[ld->sidenum[0]].line = ld; sides[ld->sidenum[0]].line = ld;
} }
if (ld->sidenum[1] != 0xffff) if (ld->sidenum[1] != NO_SIDEDEF)
{ {
sides[ld->sidenum[1]].special = ld->special; sides[ld->sidenum[1]].special = ld->special;
sides[ld->sidenum[1]].line = ld; sides[ld->sidenum[1]].line = ld;
} }
} }
static void P_SetLinedefV1(size_t i, UINT16 vertex_num) static void P_SetLinedefV1(size_t i, UINT32 vertex_num)
{ {
if (vertex_num >= numvertexes) if (vertex_num >= numvertexes)
{ {
@ -1154,7 +1154,7 @@ static void P_SetLinedefV1(size_t i, UINT16 vertex_num)
lines[i].v1 = &vertexes[vertex_num]; lines[i].v1 = &vertexes[vertex_num];
} }
static void P_SetLinedefV2(size_t i, UINT16 vertex_num) static void P_SetLinedefV2(size_t i, UINT32 vertex_num)
{ {
if (vertex_num >= numvertexes) if (vertex_num >= numvertexes)
{ {
@ -1179,17 +1179,22 @@ static void P_LoadLinedefs(UINT8 *data)
memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs)); memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs));
ld->alpha = FRACUNIT; ld->alpha = FRACUNIT;
ld->executordelay = 0; ld->executordelay = 0;
P_SetLinedefV1(i, SHORT(mld->v1)); P_SetLinedefV1(i, (UINT16)SHORT(mld->v1));
P_SetLinedefV2(i, SHORT(mld->v2)); P_SetLinedefV2(i, (UINT16)SHORT(mld->v2));
ld->sidenum[0] = SHORT(mld->sidenum[0]); ld->sidenum[0] = (UINT16)SHORT(mld->sidenum[0]);
ld->sidenum[1] = SHORT(mld->sidenum[1]); ld->sidenum[1] = (UINT16)SHORT(mld->sidenum[1]);
if (ld->sidenum[0] == 0xffff)
ld->sidenum[0] = NO_SIDEDEF;
if (ld->sidenum[1] == 0xffff)
ld->sidenum[1] = NO_SIDEDEF;
P_InitializeLinedef(ld); P_InitializeLinedef(ld);
} }
} }
static void P_SetSidedefSector(size_t i, UINT16 sector_num) static void P_SetSidedefSector(size_t i, UINT32 sector_num)
{ {
// cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead // cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead
if (sector_num >= numsectors) if (sector_num >= numsectors)
@ -1350,7 +1355,7 @@ static void P_LoadSidedefs(UINT8 *data)
sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0; sd->offsetx_top = sd->offsetx_mid = sd->offsetx_bot = 0;
sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0; sd->offsety_top = sd->offsety_mid = sd->offsety_bot = 0;
P_SetSidedefSector(i, SHORT(msd->sector)); P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
// Special info stored in texture fields! // Special info stored in texture fields!
switch (sd->special) switch (sd->special)
@ -2489,7 +2494,7 @@ static void P_WriteTextmap(void)
fprintf(f, "v1 = %s;\n", sizeu1(wlines[i].v1 - vertexes)); fprintf(f, "v1 = %s;\n", sizeu1(wlines[i].v1 - vertexes));
fprintf(f, "v2 = %s;\n", sizeu1(wlines[i].v2 - vertexes)); fprintf(f, "v2 = %s;\n", sizeu1(wlines[i].v2 - vertexes));
fprintf(f, "sidefront = %d;\n", wlines[i].sidenum[0]); fprintf(f, "sidefront = %d;\n", wlines[i].sidenum[0]);
if (wlines[i].sidenum[1] != 0xffff) if (wlines[i].sidenum[1] != NO_SIDEDEF)
fprintf(f, "sideback = %d;\n", wlines[i].sidenum[1]); fprintf(f, "sideback = %d;\n", wlines[i].sidenum[1]);
firsttag = Tag_FGet(&wlines[i].tags); firsttag = Tag_FGet(&wlines[i].tags);
if (firsttag != 0) if (firsttag != 0)
@ -2954,8 +2959,8 @@ static void P_LoadTextmap(void)
memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs)); memset(ld->stringargs, 0x00, NUMLINESTRINGARGS*sizeof(*ld->stringargs));
ld->alpha = FRACUNIT; ld->alpha = FRACUNIT;
ld->executordelay = 0; ld->executordelay = 0;
ld->sidenum[0] = 0xffff; ld->sidenum[0] = NO_SIDEDEF;
ld->sidenum[1] = 0xffff; ld->sidenum[1] = NO_SIDEDEF;
TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter);
@ -2963,7 +2968,7 @@ static void P_LoadTextmap(void)
I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i)); I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i));
if (!ld->v2) if (!ld->v2)
I_Error("P_LoadTextmap: linedef %s has no v2 value set!\n", sizeu1(i)); I_Error("P_LoadTextmap: linedef %s has no v2 value set!\n", sizeu1(i));
if (ld->sidenum[0] == 0xffff) if (ld->sidenum[0] == NO_SIDEDEF)
I_Error("P_LoadTextmap: linedef %s has no sidefront value set!\n", sizeu1(i)); I_Error("P_LoadTextmap: linedef %s has no sidefront value set!\n", sizeu1(i));
P_InitializeLinedef(ld); P_InitializeLinedef(ld);
@ -3017,7 +3022,7 @@ static void P_ProcessLinedefsAfterSidedefs(void)
for (; i--; ld++) for (; i--; ld++)
{ {
ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; ld->backsector = ld->sidenum[1] != NO_SIDEDEF ? sides[ld->sidenum[1]].sector : 0;
if (udmf) if (udmf)
continue; continue;
@ -3256,10 +3261,10 @@ static void P_InitializeSeg(seg_t *seg)
{ {
if (seg->linedef) if (seg->linedef)
{ {
UINT16 side = seg->linedef->sidenum[seg->side]; UINT32 side = seg->linedef->sidenum[seg->side];
if (side == 0xffff) if (side == NO_SIDEDEF)
I_Error("P_InitializeSeg: Seg %s refers to side %d of linedef %s, which doesn't exist!\n", sizeu1((size_t)(seg - segs)), seg->side, sizeu1((size_t)(seg->linedef - lines))); I_Error("P_InitializeSeg: Seg %s refers to side %d of linedef %s, which doesn't exist!\n", sizeu1((size_t)(seg - segs)), seg->side, sizeu2((size_t)(seg->linedef - lines)));
seg->sidedef = &sides[side]; seg->sidedef = &sides[side];
@ -3443,7 +3448,7 @@ static boolean P_LoadExtraVertices(UINT8 **data)
static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype) static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype)
{ {
size_t i, k; size_t i, k;
INT16 m; size_t m;
seg_t *seg; seg_t *seg;
// Subsectors // Subsectors
@ -3466,23 +3471,33 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
{ {
case NT_XGLN: case NT_XGLN:
case NT_XGL3: case NT_XGL3:
for (m = 0; m < subsectors[i].numlines; m++, k++) for (m = 0; m < (size_t)subsectors[i].numlines; m++, k++)
{ {
UINT32 vertexnum = READUINT32((*data)); UINT32 vertexnum = READUINT32((*data));
UINT16 linenum;
if (vertexnum >= numvertexes) if (vertexnum >= numvertexes)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid vertex %d!\n", sizeu1(k), m, vertexnum); I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid vertex %d!\n", sizeu1(k), sizeu2(m), vertexnum);
segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum];
READUINT32((*data)); // partner, can be ignored by software renderer READUINT32((*data)); // partner, can be ignored by software renderer
linenum = (nodetype == NT_XGL3) ? READUINT32((*data)) : READUINT16((*data)); if (nodetype == NT_XGL3)
if (linenum != 0xFFFF && linenum >= numlines) {
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu2(i), linenum); UINT32 linenum = READUINT32((*data));
segs[k].glseg = (linenum == 0xFFFF); if (linenum != 0xFFFFFFFF && linenum >= numlines)
segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu2(i), linenum);
segs[k].glseg = linenum == 0xFFFFFFFF;
segs[k].linedef = linenum == 0xFFFFFFFF ? NULL : &lines[linenum];
}
else
{
UINT16 linenum = READUINT16((*data));
if (linenum != 0xFFFF && linenum >= numlines)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu2(i), linenum);
segs[k].glseg = linenum == 0xFFFF;
segs[k].linedef = linenum == 0xFFFF ? NULL : &lines[linenum];
}
segs[k].side = READUINT8((*data)); segs[k].side = READUINT8((*data));
} }
while (segs[subsectors[i].firstline].glseg) while (segs[subsectors[i].firstline].glseg)
@ -3494,18 +3509,18 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
break; break;
case NT_XNOD: case NT_XNOD:
for (m = 0; m < subsectors[i].numlines; m++, k++) for (m = 0; m < (size_t)subsectors[i].numlines; m++, k++)
{ {
UINT32 v1num = READUINT32((*data)); UINT32 v1num = READUINT32((*data));
UINT32 v2num = READUINT32((*data)); UINT32 v2num = READUINT32((*data));
UINT16 linenum = READUINT16((*data)); UINT16 linenum = READUINT16((*data));
if (v1num >= numvertexes) if (v1num >= numvertexes)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v1 %d!\n", sizeu1(k), m, v1num); I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid v1 %d!\n", sizeu1(k), sizeu2(m), v1num);
if (v2num >= numvertexes) if (v2num >= numvertexes)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v2 %d!\n", sizeu1(k), m, v2num); I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid v2 %d!\n", sizeu1(k), sizeu2(m), v2num);
if (linenum >= numlines) if (linenum >= numlines)
I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %s has invalid linedef %d!\n", sizeu1(k), sizeu2(m), linenum);
segs[k].v1 = &vertexes[v1num]; segs[k].v1 = &vertexes[v1num];
segs[k].v2 = &vertexes[v2num]; segs[k].v2 = &vertexes[v2num];
@ -3990,14 +4005,14 @@ static void P_LinkMapData(void)
if (!seg->sidedef) if (!seg->sidedef)
CorruptMapError(va("P_LinkMapData: seg->sidedef is NULL " CorruptMapError(va("P_LinkMapData: seg->sidedef is NULL "
"(subsector %s, firstline is %d)", sizeu1(i), ss->firstline)); "(subsector %s, firstline is %d)", sizeu1(i), ss->firstline));
if (seg->sidedef - sides < 0 || seg->sidedef - sides > (UINT16)numsides) if (seg->sidedef - sides < 0 || sidei > numsides)
CorruptMapError(va("P_LinkMapData: seg->sidedef refers to sidedef %s of %s " CorruptMapError(va("P_LinkMapData: seg->sidedef refers to sidedef %s of %s "
"(subsector %s, firstline is %d)", sizeu1(sidei), sizeu2(numsides), "(subsector %s, firstline is %d)", sizeu1(sidei), sizeu2(numsides),
sizeu3(i), ss->firstline)); sizeu3(i), ss->firstline));
if (!seg->sidedef->sector) if (!seg->sidedef->sector)
CorruptMapError(va("P_LinkMapData: seg->sidedef->sector is NULL " CorruptMapError(va("P_LinkMapData: seg->sidedef->sector is NULL "
"(subsector %s, firstline is %d, sidedef is %s)", sizeu1(i), ss->firstline, "(subsector %s, firstline is %d, sidedef is %s)", sizeu1(i), ss->firstline,
sizeu1(sidei))); sizeu2(sidei)));
ss->sector = seg->sidedef->sector; ss->sector = seg->sidedef->sector;
} }
@ -4915,7 +4930,7 @@ static void P_ConvertBinaryLinedefTypes(void)
break; break;
case 259: //Custom FOF case 259: //Custom FOF
if (lines[i].sidenum[1] == 0xffff) if (lines[i].sidenum[1] == NO_SIDEDEF)
I_Error("Custom FOF (tag %d) found without a linedef back side!", tag); I_Error("Custom FOF (tag %d) found without a linedef back side!", tag);
lines[i].args[0] = tag; lines[i].args[0] = tag;
@ -5269,8 +5284,8 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[1] = sides[lines[i].sidenum[0]].midtexture; lines[i].args[1] = sides[lines[i].sidenum[0]].midtexture;
lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[2] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[3] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[4] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; lines[i].args[4] = (lines[i].sidenum[1] != NO_SIDEDEF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1; lines[i].args[5] = (lines[i].sidenum[1] != NO_SIDEDEF) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1;
lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture; lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture;
break; break;
case 414: //Play sound effect case 414: //Play sound effect
@ -5374,7 +5389,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[1] = max(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, 0); lines[i].args[1] = max(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, 0);
// failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset // failsafe: if user specifies Back Y Offset and NOT Front Y Offset, use the Back Offset
// to be consistent with other light and fade specials // to be consistent with other light and fade specials
lines[i].args[2] = ((lines[i].sidenum[1] != 0xFFFF && !(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS)) ? lines[i].args[2] = ((lines[i].sidenum[1] != NO_SIDEDEF && !(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS)) ?
max(min(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS, 255), 0) max(min(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS, 255), 0)
: max(min(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS, 255), 0)); : max(min(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS, 255), 0));
} }
@ -5479,7 +5494,7 @@ static void P_ConvertBinaryLinedefTypes(void)
break; break;
case 442: //Change object type state case 442: //Change object type state
lines[i].args[0] = tag; lines[i].args[0] = tag;
lines[i].args[1] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0; lines[i].args[1] = (lines[i].sidenum[1] == NO_SIDEDEF) ? 1 : 0;
break; break;
case 443: //Call Lua function case 443: //Call Lua function
if (lines[i].stringargs[0] == NULL) if (lines[i].stringargs[0] == NULL)
@ -5547,7 +5562,7 @@ static void P_ConvertBinaryLinedefTypes(void)
case 452: //Set FOF translucency case 452: //Set FOF translucency
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[2] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS); lines[i].args[2] = lines[i].sidenum[1] != NO_SIDEDEF ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS);
if (lines[i].flags & ML_MIDPEG) if (lines[i].flags & ML_MIDPEG)
lines[i].args[3] |= TMST_RELATIVE; lines[i].args[3] |= TMST_RELATIVE;
if (lines[i].flags & ML_NOCLIMB) if (lines[i].flags & ML_NOCLIMB)
@ -5556,8 +5571,8 @@ static void P_ConvertBinaryLinedefTypes(void)
case 453: //Fade FOF case 453: //Fade FOF
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[2] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (lines[i].dx >> FRACBITS); lines[i].args[2] = lines[i].sidenum[1] != NO_SIDEDEF ? (sides[lines[i].sidenum[1]].textureoffset >> FRACBITS) : (lines[i].dx >> FRACBITS);
lines[i].args[3] = lines[i].sidenum[1] != 0xffff ? (sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) : (abs(lines[i].dy) >> FRACBITS); lines[i].args[3] = lines[i].sidenum[1] != NO_SIDEDEF ? (sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) : (abs(lines[i].dy) >> FRACBITS);
if (lines[i].flags & ML_MIDPEG) if (lines[i].flags & ML_MIDPEG)
lines[i].args[4] |= TMFT_RELATIVE; lines[i].args[4] |= TMFT_RELATIVE;
if (lines[i].flags & ML_WRAPMIDTEX) if (lines[i].flags & ML_WRAPMIDTEX)
@ -5584,7 +5599,7 @@ static void P_ConvertBinaryLinedefTypes(void)
break; break;
case 455: //Fade colormap case 455: //Fade colormap
{ {
INT32 speed = (INT32)((((lines[i].flags & ML_DONTPEGBOTTOM) || !sides[lines[i].sidenum[0]].rowoffset) && lines[i].sidenum[1] != 0xFFFF) ? INT32 speed = (INT32)((((lines[i].flags & ML_DONTPEGBOTTOM) || !sides[lines[i].sidenum[0]].rowoffset) && lines[i].sidenum[1] != NO_SIDEDEF) ?
abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS)); : abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS));
@ -5614,7 +5629,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[0] = tag; lines[i].args[0] = tag;
lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
lines[i].args[3] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0; lines[i].args[3] = (lines[i].sidenum[1] != NO_SIDEDEF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW); lines[i].args[4] = !!(lines[i].flags & ML_NOSKEW);
break; break;
case 459: //Control text prompt case 459: //Control text prompt
@ -5634,7 +5649,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[2] |= TMP_ALLPLAYERS; lines[i].args[2] |= TMP_ALLPLAYERS;
if (lines[i].flags & ML_MIDSOLID) if (lines[i].flags & ML_MIDSOLID)
lines[i].args[2] |= TMP_FREEZETHINKERS;*/ lines[i].args[2] |= TMP_FREEZETHINKERS;*/
lines[i].args[3] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag; lines[i].args[3] = (lines[i].sidenum[1] != NO_SIDEDEF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag;
break; break;
case 460: //Award rings case 460: //Award rings
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
@ -5647,7 +5662,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[3] = (lines[i].flags & ML_SKEWTD) ? AngleFixed(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)) >> FRACBITS : 0; lines[i].args[3] = (lines[i].flags & ML_SKEWTD) ? AngleFixed(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)) >> FRACBITS : 0;
if (lines[i].flags & ML_NOCLIMB) if (lines[i].flags & ML_NOCLIMB)
{ {
if (lines[i].sidenum[1] != 0xffff) // Make sure the linedef has a back side if (lines[i].sidenum[1] != NO_SIDEDEF) // Make sure the linedef has a back side
{ {
lines[i].args[4] = 1; lines[i].args[4] = 1;
lines[i].args[5] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS; lines[i].args[5] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS;
@ -5681,7 +5696,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[0] = tag; lines[i].args[0] = tag;
lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS; lines[i].args[2] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
if (lines[i].sidenum[1] != 0xffff) if (lines[i].sidenum[1] != NO_SIDEDEF)
lines[i].args[3] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS; lines[i].args[3] = sides[lines[i].sidenum[1]].textureoffset >> FRACBITS;
break; break;
case 482: //Polyobject - move case 482: //Polyobject - move
@ -5753,7 +5768,7 @@ static void P_ConvertBinaryLinedefTypes(void)
if (!(lines[i].flags & ML_DONTPEGBOTTOM)) if (!(lines[i].flags & ML_DONTPEGBOTTOM))
lines[i].args[1] /= 100; lines[i].args[1] /= 100;
// allow Back Y Offset to be consistent with other fade specials // allow Back Y Offset to be consistent with other fade specials
lines[i].args[2] = (lines[i].sidenum[1] != 0xffff && !sides[lines[i].sidenum[0]].rowoffset) ? lines[i].args[2] = (lines[i].sidenum[1] != NO_SIDEDEF && !sides[lines[i].sidenum[0]].rowoffset) ?
abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS) abs(sides[lines[i].sidenum[1]].rowoffset >> FRACBITS)
: abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS); : abs(sides[lines[i].sidenum[0]].rowoffset >> FRACBITS);
if (lines[i].flags & ML_MIDPEG) if (lines[i].flags & ML_MIDPEG)
@ -5780,7 +5795,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[0] = tag; lines[i].args[0] = tag;
if (lines[i].flags & ML_MIDPEG) if (lines[i].flags & ML_MIDPEG)
{ {
if (lines[i].sidenum[1] == 0xffff) if (lines[i].sidenum[1] == NO_SIDEDEF)
{ {
CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i)); CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i));
lines[i].special = 0; lines[i].special = 0;
@ -5810,7 +5825,7 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[0] = lines[i].special >= 507; lines[i].args[0] = lines[i].special >= 507;
if (lines[i].special % 2 == 0) if (lines[i].special % 2 == 0)
{ {
if (lines[i].sidenum[1] == 0xffff) if (lines[i].sidenum[1] == NO_SIDEDEF)
{ {
CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i)); CONS_Debug(DBG_GAMELOGIC, "Line special %d (line #%s) missing back side!\n", lines[i].special, sizeu1(i));
lines[i].special = 0; lines[i].special = 0;
@ -5966,7 +5981,7 @@ static void P_ConvertBinaryLinedefTypes(void)
{ {
UINT8 side = lines[i].special >= 714; UINT8 side = lines[i].special >= 714;
if (side == 1 && lines[i].sidenum[1] == 0xffff) if (side == 1 && lines[i].sidenum[1] == NO_SIDEDEF)
CONS_Debug(DBG_GAMELOGIC, "P_ConvertBinaryMap: Line special %d (line #%s) missing 2nd side!\n", lines[i].special, sizeu1(i)); CONS_Debug(DBG_GAMELOGIC, "P_ConvertBinaryMap: Line special %d (line #%s) missing 2nd side!\n", lines[i].special, sizeu1(i));
else else
{ {

View file

@ -557,7 +557,7 @@ static inline sector_t *getSector(INT32 currentSector, INT32 line, INT32 side)
*/ */
static inline boolean twoSided(INT32 sector, INT32 line) static inline boolean twoSided(INT32 sector, INT32 line)
{ {
return (sectors[sector].lines[line])->sidenum[1] != 0xffff; return (sectors[sector].lines[line])->sidenum[1] != NO_SIDEDEF;
} }
#endif #endif
@ -1796,7 +1796,7 @@ void P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller)
if (trigid < 0 || trigid > 31) // limited by 32 bit variable if (trigid < 0 || trigid > 31) // limited by 32 bit variable
{ {
CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", triggerline->sidenum[0], trigid); CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %u): bad trigger ID %d\n", triggerline->sidenum[0], trigid);
return; return;
} }
else if (!(unlocktriggers & (1 << trigid))) else if (!(unlocktriggers & (1 << trigid)))
@ -1809,7 +1809,7 @@ void P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller)
if (unlockid <= 0 || unlockid > MAXUNLOCKABLES) // limited by unlockable count if (unlockid <= 0 || unlockid > MAXUNLOCKABLES) // limited by unlockable count
{ {
CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %hu): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid); CONS_Debug(DBG_GAMELOGIC, "Unlockable check (sidedef %u): bad unlockable ID %d\n", triggerline->sidenum[0], unlockid);
return; return;
} }
else if (!(serverGamedata->unlocked[unlockid-1])) else if (!(serverGamedata->unlocked[unlockid-1]))
@ -2607,7 +2607,15 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0) if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
CONS_Debug(DBG_SETUP, "Line type 415 Executor: script lump %s not found/not valid.\n", line->stringargs[0]); CONS_Debug(DBG_SETUP, "Line type 415 Executor: script lump %s not found/not valid.\n", line->stringargs[0]);
else else
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE)); {
void *lump = W_CacheLumpNum(lumpnum, PU_CACHE);
size_t len = W_LumpLength(lumpnum);
char *text = Z_Malloc(len + 1, PU_CACHE, NULL);
memcpy(text, lump, len);
text[len] = '\0';
COM_BufInsertText(text);
Z_Free(text);
}
} }
break; break;
@ -2897,7 +2905,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
{ {
size_t linenum; size_t linenum;
side_t *setfront = &sides[line->sidenum[0]]; side_t *setfront = &sides[line->sidenum[0]];
side_t *setback = (line->args[3] && line->sidenum[1] != 0xffff) ? &sides[line->sidenum[1]] : setfront; side_t *setback = (line->args[3] && line->sidenum[1] != NO_SIDEDEF) ? &sides[line->sidenum[1]] : setfront;
side_t *this; side_t *this;
boolean always = !(line->args[2]); // If args[2] is set: Only change mid texture if mid texture already exists on tagged lines, etc. boolean always = !(line->args[2]); // If args[2] is set: Only change mid texture if mid texture already exists on tagged lines, etc.
@ -2919,7 +2927,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
// Back side // Back side
if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != 0xffff) if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != NO_SIDEDEF)
{ {
this = &sides[lines[linenum].sidenum[1]]; this = &sides[lines[linenum].sidenum[1]];
if (always || this->toptexture) this->toptexture = setback->toptexture; if (always || this->toptexture) this->toptexture = setback->toptexture;
@ -2940,7 +2948,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT32 trigid = line->args[0]; INT32 trigid = line->args[0];
if (trigid < 0 || trigid > 31) // limited by 32 bit variable if (trigid < 0 || trigid > 31) // limited by 32 bit variable
CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %hu): bad trigger ID %d\n", line->sidenum[0], trigid); CONS_Debug(DBG_GAMELOGIC, "Unlockable trigger (sidedef %u): bad trigger ID %d\n", line->sidenum[0], trigid);
else else
{ {
unlocktriggers |= 1 << trigid; unlocktriggers |= 1 << trigid;
@ -3153,7 +3161,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (line->args[2] & TMCF_RELATIVE) if (line->args[2] & TMCF_RELATIVE)
{ {
extracolormap_t *target = (!udmf && (line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF) ? extracolormap_t *target = (!udmf && (line->flags & ML_TFERLINE) && line->sidenum[1] != NO_SIDEDEF) ?
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap; // use back colormap instead of target sector sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap; // use back colormap instead of target sector
extracolormap_t *exc = R_AddColormaps( extracolormap_t *exc = R_AddColormaps(
@ -3482,7 +3490,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
} }
if (!udmf && (line->flags & ML_TFERLINE)) // use back colormap instead of target sector if (!udmf && (line->flags & ML_TFERLINE)) // use back colormap instead of target sector
sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ? sectors[secnum].extra_colormap = (line->sidenum[1] != NO_SIDEDEF) ?
sides[line->sidenum[1]].colormap_data : NULL; sides[line->sidenum[1]].colormap_data : NULL;
exc = sectors[secnum].extra_colormap; exc = sectors[secnum].extra_colormap;
@ -7600,7 +7608,7 @@ static void P_SpawnScrollers(void)
{ {
if (l->args[1] != TMSD_BACK) if (l->args[1] != TMSD_BACK)
Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[0], accel, 0); Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[0], accel, 0);
if (l->args[1] != TMSD_FRONT && lines[s].sidenum[1] != 0xffff) if (l->args[1] != TMSD_FRONT && lines[s].sidenum[1] != NO_SIDEDEF)
Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[1], accel, 0); Add_Scroller(sc_side, l->args[2] << (FRACBITS - SCROLL_SHIFT), l->args[3] << (FRACBITS - SCROLL_SHIFT), control, lines[s].sidenum[1], accel, 0);
} }
break; break;
@ -7611,7 +7619,7 @@ static void P_SpawnScrollers(void)
Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[0], accel, 0); Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[0], accel, 0);
if (l->args[0] != TMSD_FRONT) if (l->args[0] != TMSD_FRONT)
{ {
if (l->sidenum[1] != 0xffff) if (l->sidenum[1] != NO_SIDEDEF)
Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[1], accel, 0); Add_Scroller(sc_side, -l->args[1] << FRACBITS, l->args[2] << FRACBITS, -1, l->sidenum[1], accel, 0);
else else
CONS_Debug(DBG_GAMELOGIC, "Line special 500 (line #%s) missing back side!\n", sizeu1(i)); CONS_Debug(DBG_GAMELOGIC, "Line special 500 (line #%s) missing back side!\n", sizeu1(i));

View file

@ -666,7 +666,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->powers[pw_carry] = CR_NIGHTSFALL; player->powers[pw_carry] = CR_NIGHTSFALL;
player->powers[pw_underwater] = 0; player->powers[pw_underwater] = 0;
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST); player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
player->secondjump = 0; player->secondjump = 0;
player->homing = 0; player->homing = 0;
player->climbing = 0; player->climbing = 0;
@ -794,7 +794,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
} }
} }
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING); player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING);
player->homing = 0; player->homing = 0;
player->mo->fuse = 0; player->mo->fuse = 0;
player->speed = 0; player->speed = 0;
@ -1342,8 +1342,6 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
P_PlayJingle(player, JT_SUPER); P_PlayJingle(player, JT_SUPER);
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0; player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0;
// Transformation animation // Transformation animation
@ -1360,8 +1358,11 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
player->powers[pw_sneakers] = 0; player->powers[pw_sneakers] = 0;
} }
if (!G_CoopGametype()) if (G_CoopGametype())
S_StartSound(player->mo, sfx_supert); //only hear it near yourself in co-op
else
{ {
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
HU_SetCEchoFlags(0); HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players])); HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players]));
@ -1370,6 +1371,56 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
P_PlayerFlagBurst(player, false); P_PlayerFlagBurst(player, false);
} }
//
// P_DoSuperDetransformation
//
// Detransform into regular Sonic!
static void P_DoSuperDetransformation(player_t *player)
{
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
if (player->mo->sprite2 & FF_SPR2SUPER)
P_SetPlayerMobjState(player->mo, player->mo->state-states);
// Inform the netgame that the champion has fallen in the heat of battle.
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
// If you had a shield, restore its visual significance.
P_SpawnShieldOrb(player);
}
// Adds to the player's score // Adds to the player's score
void P_AddPlayerScore(player_t *player, UINT32 amount) void P_AddPlayerScore(player_t *player, UINT32 amount)
{ {
@ -4086,6 +4137,16 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
I_Assert(player != NULL); I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo)); I_Assert(!P_MobjWasRemoved(player->mo));
// Toss a flag
if (cmd->buttons & BT_TOSSFLAG && G_GametypeHasTeams()
&& !(player->powers[pw_super]) && !(player->tossdelay))
{
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)))
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL))) if (!(cmd->buttons & (BT_ATTACK|BT_FIRENORMAL)))
{ {
@ -4095,9 +4156,10 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return; return;
} }
if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT))) if (player->pflags & PF_ATTACKDOWN || player->climbing)
return; return;
// Fire a fireball if we have the Fire Flower powerup!
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay)) if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay))
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -4109,7 +4171,8 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return; return;
} }
if (!G_RingSlingerGametype() || player->weapondelay) // No ringslinging outside of ringslinger!
if (!G_RingSlingerGametype() || player->weapondelay || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
return; return;
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
@ -4287,34 +4350,7 @@ static void P_DoSuperStuff(player_t *player)
// If you're super and not Sonic, de-superize! // If you're super and not Sonic, de-superize!
if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER)) if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER))
{ {
player->powers[pw_super] = 0; P_DoSuperDetransformation(player);
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
P_SpawnShieldOrb(player);
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
return; return;
} }
@ -4341,69 +4377,37 @@ static void P_DoSuperStuff(player_t *player)
// Ran out of rings while super! // Ran out of rings while super!
if (player->rings <= 0 || player->exiting) if (player->rings <= 0 || player->exiting)
{ P_DoSuperDetransformation(player);
player->powers[pw_emeralds] = 0; // lost the power stones
P_SpawnGhostMobj(player->mo);
player->powers[pw_super] = 0;
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
if (player->mo->sprite2 & FF_SPR2SUPER)
P_SetPlayerMobjState(player->mo, player->mo->state-states);
// Inform the netgame that the champion has fallen in the heat of battle.
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
// Resume normal music if you're the console player
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
// If you had a shield, restore its visual significance.
P_SpawnShieldOrb(player);
}
} }
} }
// //
// P_SuperReady // P_SuperReady
// //
// Returns true if player is ready to turn super, duh // Returns true if player is ready to transform or detransform
// //
boolean P_SuperReady(player_t *player) boolean P_SuperReady(player_t *player, boolean transform)
{ {
if (!player->powers[pw_super] if (!transform &&
&& !player->powers[pw_invulnerability] (player->powers[pw_super] < TICRATE*3/2
|| !G_CoopGametype())) // No turning back in competitive!
return false;
else if (transform
&& (player->powers[pw_super]
|| !ALL7EMERALDS(emeralds)
|| !(player->rings >= 50)))
return false;
if (player->mo
&& !player->powers[pw_tailsfly] && !player->powers[pw_tailsfly]
&& !player->powers[pw_carry]
&& (player->charflags & SF_SUPER) && (player->charflags & SF_SUPER)
&& (player->pflags & PF_JUMPED) && !P_PlayerInPain(player)
&& !(player->powers[pw_shield] & SH_NOSTACK) && !player->climbing
&& !(maptol & TOL_NIGHTS) && !(player->pflags & (PF_FULLSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY))
&& ALL7EMERALDS(emeralds) && ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE
&& (player->rings >= 50)) || player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH))))
&& !(maptol & TOL_NIGHTS))
return true; return true;
return false; return false;
@ -5094,7 +5098,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
{ {
mobj_t *lockonshield = NULL; mobj_t *lockonshield = NULL;
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN) if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SHIELDDOWN)
&& ((!(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 && ((!(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 && !(player->charflags & SF_NOSHIELDABILITY)) if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
@ -5121,7 +5125,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
} }
} }
} }
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SHIELD && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Shield button effects
{ {
// Force stop // Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE) if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
@ -5242,52 +5246,45 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
; ;
else if (P_PlayerShieldThink(player, cmd, lockonthok, visual)) else if (P_PlayerShieldThink(player, cmd, lockonthok, visual))
; ;
else if ((cmd->buttons & BT_SPIN)) else if ((cmd->buttons & BT_SPIN) && !LUA_HookPlayer(player, HOOK(JumpSpinSpecial)))
{ {
if (!(player->pflags & PF_SPINDOWN) && P_SuperReady(player)) switch (player->charability)
{ {
// If you can turn super and aren't already, case CA_THOK:
// and you don't have a shield, do it! if (player->powers[pw_super]) // Super Sonic float
P_DoSuperTransformation(player, false); {
} if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based
else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial))) && (P_MobjFlip(player->mo)*player->mo->momz <= 0))
switch (player->charability)
{
case CA_THOK:
if (player->powers[pw_super]) // Super Sonic float
{ {
if ((player->speed > 5*player->mo->scale) // FixedMul(5<<FRACBITS, player->mo->scale), but scale is FRACUNIT-based if (player->panim != PA_RUN && player->panim != PA_WALK)
&& (P_MobjFlip(player->mo)*player->mo->momz <= 0))
{ {
if (player->panim != PA_RUN && player->panim != PA_WALK) if (player->speed >= FixedMul(player->runspeed, player->mo->scale))
{ P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN);
if (player->speed >= FixedMul(player->runspeed, player->mo->scale)) else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT_RUN); P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
else
P_SetPlayerMobjState(player->mo, S_PLAY_FLOAT);
}
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
} }
player->mo->momz = 0;
player->pflags &= ~(PF_STARTJUMP|PF_SPINNING);
player->secondjump = 1;
} }
break; }
case CA_TELEKINESIS: break;
if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY)) case CA_TELEKINESIS:
{ if (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || (player->charflags & SF_MULTIABILITY))
P_Telekinesis(player, {
-FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player) P_Telekinesis(player,
FixedMul(384*FRACUNIT, player->mo->scale)); -FixedMul(player->actionspd, player->mo->scale), // -ve thrust (pulling towards player)
} FixedMul(384*FRACUNIT, player->mo->scale));
break; }
case CA_TWINSPIN: break;
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY)) case CA_TWINSPIN:
P_DoTwinSpin(player); if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_SPINDOWN)) || player->charflags & SF_MULTIABILITY))
break; P_DoTwinSpin(player);
default: break;
break; default:
} break;
}
} }
} }
@ -5350,12 +5347,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
} }
else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY) else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY)
; ;
/*else if (P_SuperReady(player))
{
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}*/
else if (player->pflags & PF_JUMPED) else if (player->pflags & PF_JUMPED)
{ {
if (!LUA_HookPlayer(player, HOOK(AbilitySpecial))) if (!LUA_HookPlayer(player, HOOK(AbilitySpecial)))
@ -8686,18 +8677,31 @@ void P_MovePlayer(player_t *player)
&& player->panim == PA_IDLE && !(player->powers[pw_carry])) && player->panim == PA_IDLE && !(player->powers[pw_carry]))
P_DoTeeter(player); P_DoTeeter(player);
// Toss a flag // Check for fire and shield buttons
if (G_GametypeHasTeams() && (cmd->buttons & BT_TOSSFLAG) && !(player->powers[pw_super]) && !(player->tossdelay)) if (!player->exiting && !(player->pflags & PF_STASIS))
{ {
if (!(player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // Check for fire buttons
P_PlayerEmeraldBurst(player, true); // Toss emeralds
else
P_PlayerFlagBurst(player, true);
}
// check for fire
if (!player->exiting)
P_DoFiring(player, cmd); P_DoFiring(player, cmd);
// Release the shield button
if (!(cmd->buttons & BT_SHIELD))
player->pflags &= ~PF_SHIELDDOWN;
// Shield button behavior
// Check P_PlayerShieldThink for actual shields!
else if (!(player->pflags & PF_SHIELDDOWN))
{
// Transform into super if we can!
if (P_SuperReady(player, true))
P_DoSuperTransformation(player, false);
// Detransform from super if we can!
else if (P_SuperReady(player, false))
P_DoSuperDetransformation(player);
player->pflags |= PF_SHIELDDOWN;
}
}
{ {
boolean atspinheight = false; boolean atspinheight = false;

View file

@ -267,18 +267,17 @@ static boolean is_tangible (mobj_t *thing)
boolean R_ThingBoundingBoxVisible(mobj_t *thing) boolean R_ThingBoundingBoxVisible(mobj_t *thing)
{ {
INT32 cvmode = cv_renderhitbox.value; INT32 cvmode = cv_renderhitbox.value;
boolean ring = false;
if (multiplayer) // No hitboxes in multiplayer to avoid cheating if (multiplayer) // No hitboxes in multiplayer to avoid cheating
return false; return false;
// Do not render bbox for these
switch (thing->type) switch (thing->type)
{ {
default: default:
// First person / awayviewmobj -- rendering // First person / awayviewmobj -- rendering a bbox
// a bbox too close to the viewpoint causes // too close to the viewpoint causes anomalies
// anomalies and these are exactly on the // and these are exactly on the viewpoint!
// viewpoint!
if (thing != r_viewmobj) if (thing != r_viewmobj)
{ {
break; break;
@ -290,6 +289,17 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing)
// are rendered using portals in Software, // are rendered using portals in Software,
// r_viewmobj does not point here. // r_viewmobj does not point here.
return false; return false;
case MT_RING:
case MT_BLUESPHERE:
case MT_NIGHTSSTAR:
case MT_NIGHTSCHIP:
case MT_COIN:
// Rings and similar objects are often placed
// in large amounts, so they are handled
// separately from other tangible objects.
ring = true;
break;
} }
switch (cvmode) switch (cvmode)
@ -304,16 +314,10 @@ boolean R_ThingBoundingBoxVisible(mobj_t *thing)
return !is_tangible(thing); return !is_tangible(thing);
case RENDERHITBOX_TANGIBLE: case RENDERHITBOX_TANGIBLE:
// Exclude rings from here, lots of them! return !ring && is_tangible(thing);
if (thing->type == MT_RING)
{
return false;
}
return is_tangible(thing);
case RENDERHITBOX_RINGS: case RENDERHITBOX_RINGS:
return (thing->type == MT_RING || thing->type == MT_BLUESPHERE); return ring;
default: default:
return false; return false;

View file

@ -438,7 +438,7 @@ extracolormap_t *R_CreateDefaultColormap(boolean lighttable)
exc->fadeend = 31; exc->fadeend = 31;
exc->flags = 0; exc->flags = 0;
exc->rgba = 0; exc->rgba = 0;
exc->fadergba = 0x19000000; exc->fadergba = 0xFF000000;
exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL; exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL;
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
exc->lump = LUMPERROR; exc->lump = LUMPERROR;
@ -553,7 +553,7 @@ boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba,
&& !flags) && !flags)
) )
&& (!checkrgba ? true : rgba == 0) && (!checkrgba ? true : rgba == 0)
&& (!checkfadergba ? true : fadergba == 0x19000000) && (!checkfadergba ? true : (unsigned)fadergba == 0xFF000000)
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
&& lump == LUMPERROR && lump == LUMPERROR
&& extra_colormap->lumpname[0] == 0 && extra_colormap->lumpname[0] == 0
@ -654,7 +654,7 @@ extracolormap_t *R_ColormapForName(char *name)
if (lump == LUMPERROR) if (lump == LUMPERROR)
I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name); I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name);
exc = R_GetColormapFromListByValues(0, 0x19000000, 0, 31, 0, lump); exc = R_GetColormapFromListByValues(0, 0xFF000000, 0, 31, 0, lump);
if (exc) if (exc)
return exc; return exc;
@ -674,7 +674,7 @@ extracolormap_t *R_ColormapForName(char *name)
exc->fadeend = 31; exc->fadeend = 31;
exc->flags = 0; exc->flags = 0;
exc->rgba = 0; exc->rgba = 0;
exc->fadergba = 0x19000000; exc->fadergba = 0xFF000000;
R_AddColormapToList(exc); R_AddColormapToList(exc);
@ -692,9 +692,26 @@ extracolormap_t *R_ColormapForName(char *name)
// //
static double deltas[256][3], map[256][3]; static double deltas[256][3], map[256][3];
static int RoundUp(double number); static colorlookup_t lighttable_lut;
static UINT8 LightTableNearest(UINT8 r, UINT8 g, UINT8 b)
{
return NearestColor(r, g, b);
}
static UINT8 LightTableNearest_LUT(UINT8 r, UINT8 g, UINT8 b)
{
return GetColorLUT(&lighttable_lut, r, g, b);
}
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
{
extra_colormap->colormap = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8);
R_GenerateLightTable(extra_colormap, false);
return extra_colormap->colormap;
}
void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup)
{ {
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
double maskamt = 0, othermask = 0; double maskamt = 0, othermask = 0;
@ -711,7 +728,6 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
UINT8 fadestart = extra_colormap->fadestart, UINT8 fadestart = extra_colormap->fadestart,
fadedist = extra_colormap->fadeend - extra_colormap->fadestart; fadedist = extra_colormap->fadeend - extra_colormap->fadestart;
lighttable_t *lighttable = NULL;
size_t i; size_t i;
///////////////////// /////////////////////
@ -721,7 +737,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
cmaskg = cg; cmaskg = cg;
cmaskb = cb; cmaskb = cb;
maskamt = (double)(ca/24.0l); maskamt = (double)(ca/255.0l);
othermask = 1 - maskamt; othermask = 1 - maskamt;
maskamt /= 0xff; maskamt /= 0xff;
@ -737,7 +753,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
cdestb = cfb; cdestb = cfb;
// fade alpha unused in software // fade alpha unused in software
// maskamt = (double)(cfa/24.0l); // maskamt = (double)(cfa/255.0l);
// othermask = 1 - maskamt; // othermask = 1 - maskamt;
// maskamt /= 0xff; // maskamt /= 0xff;
@ -753,6 +769,16 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
int p; int p;
char *colormap_p; char *colormap_p;
UINT8 (*NearestColorFunc)(UINT8, UINT8, UINT8);
if (uselookup)
{
InitColorLUT(&lighttable_lut, pMasterPalette, false);
NearestColorFunc = LightTableNearest_LUT;
}
else
NearestColorFunc = LightTableNearest;
// Initialise the map and delta arrays // Initialise the map and delta arrays
// map[i] stores an RGB color (as double) for index i, // map[i] stores an RGB color (as double) for index i,
// which is then converted to SRB2's palette later // which is then converted to SRB2's palette later
@ -783,8 +809,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
// Now allocate memory for the actual colormap array itself! // Now allocate memory for the actual colormap array itself!
// aligned on 8 bit for asm code // aligned on 8 bit for asm code
colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8); colormap_p = (char *)extra_colormap->colormap;
lighttable = (UINT8 *)colormap_p;
// Calculate the palette index for each palette index, for each light level // Calculate the palette index for each palette index, for each light level
// (as well as the two unused colormap lines we inherited from Doom) // (as well as the two unused colormap lines we inherited from Doom)
@ -792,9 +817,9 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
{ {
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
*colormap_p = NearestColor((UINT8)RoundUp(map[i][0]), *colormap_p = NearestColorFunc((UINT8)M_RoundUp(map[i][0]),
(UINT8)RoundUp(map[i][1]), (UINT8)M_RoundUp(map[i][1]),
(UINT8)RoundUp(map[i][2])); (UINT8)M_RoundUp(map[i][2]));
colormap_p++; colormap_p++;
if ((UINT32)p < fadestart) if ((UINT32)p < fadestart)
@ -818,8 +843,6 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
} }
} }
} }
return lighttable;
} }
extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3) extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
@ -828,7 +851,7 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25; UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
UINT32 fadestart = 0, fadeend = 31; UINT32 fadestart = 0, fadeend = 31;
UINT8 flags = 0; UINT8 flags = 0;
INT32 rgba = 0, fadergba = 0x19000000; INT32 rgba = 0, fadergba = 0xFF000000;
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) #define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) #define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0)
@ -836,13 +859,13 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
// Get base colormap value // Get base colormap value
// First alpha-only, then full value // First alpha-only, then full value
if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1]) if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1])
ca = (p1[0] - 'a'); ca = ((p1[0] - 'a') * 102) / 10;
else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2]) else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2])
ca = (p1[1] - 'a'); ca = ((p1[1] - 'a') * 102) / 10;
else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1]) else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1])
ca = (p1[0] - 'A'); ca = ((p1[0] - 'A') * 102) / 10;
else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2]) else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2])
ca = (p1[1] - 'A'); ca = ((p1[1] - 'A') * 102) / 10;
else if (p1[0] == '#') else if (p1[0] == '#')
{ {
// For each subsequent value, the value before it must exist // For each subsequent value, the value before it must exist
@ -858,20 +881,20 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6])); cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
if (p1[7] >= 'a' && p1[7] <= 'z') if (p1[7] >= 'a' && p1[7] <= 'z')
ca = (p1[7] - 'a'); ca = ((p1[7] - 'a') * 102) / 10;
else if (p1[7] >= 'A' && p1[7] <= 'Z') else if (p1[7] >= 'A' && p1[7] <= 'Z')
ca = (p1[7] - 'A'); ca = ((p1[7] - 'A') * 102) / 10;
else else
ca = 25; ca = 255;
} }
else else
ca = 25; ca = 255;
} }
else else
ca = 25; ca = 255;
} }
else else
ca = 25; ca = 255;
} }
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0) #define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
@ -901,13 +924,13 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
// Get fade (dark) colormap value // Get fade (dark) colormap value
// First alpha-only, then full value // First alpha-only, then full value
if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1]) if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1])
cfa = (p3[0] - 'a'); cfa = ((p3[0] - 'a') * 102) / 10;
else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2]) else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2])
cfa = (p3[1] - 'a'); cfa = ((p3[1] - 'a') * 102) / 10;
else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1]) else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1])
cfa = (p3[0] - 'A'); cfa = ((p3[0] - 'A') * 102) / 10;
else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2]) else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2])
cfa = (p3[1] - 'A'); cfa = ((p3[1] - 'A') * 102) / 10;
else if (p3[0] == '#') else if (p3[0] == '#')
{ {
// For each subsequent value, the value before it must exist // For each subsequent value, the value before it must exist
@ -923,20 +946,20 @@ extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6])); cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
if (p3[7] >= 'a' && p3[7] <= 'z') if (p3[7] >= 'a' && p3[7] <= 'z')
cfa = (p3[7] - 'a'); cfa = ((p3[7] - 'a') * 102) / 10;
else if (p3[7] >= 'A' && p3[7] <= 'Z') else if (p3[7] >= 'A' && p3[7] <= 'Z')
cfa = (p3[7] - 'A'); cfa = ((p3[7] - 'A') * 102) / 10;
else else
cfa = 25; cfa = 255;
} }
else else
cfa = 25; cfa = 255;
} }
else else
cfa = 25; cfa = 255;
} }
else else
cfa = 25; cfa = 255;
} }
#undef ALPHA2INT #undef ALPHA2INT
#undef HEX2INT #undef HEX2INT
@ -1133,20 +1156,6 @@ UINT8 NearestPaletteColor(UINT8 r, UINT8 g, UINT8 b, RGBA_t *palette)
return (UINT8)bestcolor; return (UINT8)bestcolor;
} }
// Rounds off floating numbers and checks for 0 - 255 bounds
static int RoundUp(double number)
{
if (number > 255.0l)
return 255;
if (number < 0.0l)
return 0;
if ((int)number <= (int)(number - 0.5f))
return (int)number + 1;
return (int)number;
}
#ifdef EXTRACOLORMAPLUMPS #ifdef EXTRACOLORMAPLUMPS
const char *R_NameForColormap(extracolormap_t *extra_colormap) const char *R_NameForColormap(extracolormap_t *extra_colormap)
{ {

View file

@ -92,6 +92,7 @@ typedef enum
TMCF_OVERRIDE = 1<<13, TMCF_OVERRIDE = 1<<13,
} textmapcolormapflags_t; } textmapcolormapflags_t;
void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup);
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3); extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags); extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);

View file

@ -42,6 +42,9 @@
// Could even use more than 32 levels. // Could even use more than 32 levels.
typedef UINT8 lighttable_t; typedef UINT8 lighttable_t;
#define NUM_PALETTE_ENTRIES 256
#define DEFAULT_STARTTRANSCOLOR 96
#define CMF_FADEFULLBRIGHTSPRITES 1 #define CMF_FADEFULLBRIGHTSPRITES 1
#define CMF_FOG 4 #define CMF_FOG 4
@ -501,6 +504,8 @@ typedef enum
#define NUMLINEARGS 10 #define NUMLINEARGS 10
#define NUMLINESTRINGARGS 2 #define NUMLINESTRINGARGS 2
#define NO_SIDEDEF 0xFFFFFFFF
typedef struct line_s typedef struct line_s
{ {
// Vertices, from v1 to v2. // Vertices, from v1 to v2.
@ -518,7 +523,7 @@ typedef struct line_s
char *stringargs[NUMLINESTRINGARGS]; char *stringargs[NUMLINESTRINGARGS];
// Visual appearance: sidedefs. // Visual appearance: sidedefs.
UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided UINT32 sidenum[2]; // sidenum[1] will be NO_SIDEDEF if one-sided
fixed_t alpha; // translucency fixed_t alpha; // translucency
UINT8 blendmode; // blendmode UINT8 blendmode; // blendmode
INT32 executordelay; INT32 executordelay;
@ -911,7 +916,7 @@ typedef struct
UINT16 flip; UINT16 flip;
#ifdef ROTSPRITE #ifdef ROTSPRITE
rotsprite_t *rotated[2][16]; // Rotated patches rotsprite_t *rotated[16]; // Rotated patches
#endif #endif
} spriteframe_t; } spriteframe_t;

View file

@ -117,8 +117,6 @@ static INT32 *tiltlighting;
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) #define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL}; static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL};
UINT8 skincolor_modified[MAXSKINCOLORS]; UINT8 skincolor_modified[MAXSKINCOLORS];

View file

@ -158,7 +158,7 @@ consvar_t cv_drawdist = CVAR_INIT ("drawdist", "Infinite", CV_SAVE, drawdist_con
consvar_t cv_drawdist_nights = CVAR_INIT ("drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL); consvar_t cv_drawdist_nights = CVAR_INIT ("drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL);
consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL); consvar_t cv_drawdist_precip = CVAR_INIT ("drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL);
//consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL); //consvar_t cv_precipdensity = CVAR_INIT ("precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL);
consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange); consvar_t cv_fov = CVAR_INIT ("fov", "90", CV_SAVE|CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange);
consvar_t cv_fovadjust = CVAR_INIT ("fovadjust", "On", CV_SAVE|CV_CALL, CV_OnOff, Fov_OnChange); consvar_t cv_fovadjust = CVAR_INIT ("fovadjust", "On", CV_SAVE|CV_CALL, CV_OnOff, Fov_OnChange);
// Okay, whoever said homremoval causes a performance hit should be shot. // Okay, whoever said homremoval causes a performance hit should be shot.

View file

@ -37,7 +37,7 @@ patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip);
patch_t *Patch_GetRotatedSprite( patch_t *Patch_GetRotatedSprite(
spriteframe_t *sprite, spriteframe_t *sprite,
size_t frame, size_t spriteangle, size_t frame, size_t spriteangle,
boolean flip, boolean adjustfeet, boolean flip,
void *info, INT32 rotationangle); void *info, INT32 rotationangle);
angle_t R_ModelRotationAngle(interpmobjstate_t *interp); angle_t R_ModelRotationAngle(interpmobjstate_t *interp);
angle_t R_SpriteRotationAngle(interpmobjstate_t *interp); angle_t R_SpriteRotationAngle(interpmobjstate_t *interp);

View file

@ -10,7 +10,7 @@
/// \brief Patch rotation. /// \brief Patch rotation.
#include "r_patchrotation.h" #include "r_patchrotation.h"
#include "r_things.h" // FEETADJUST #include "r_things.h" // FEETADJUST (todo: is this needed anymore? -- Monster Iestyn 21 Sep 2023 )
#include "z_zone.h" #include "z_zone.h"
#include "w_wad.h" #include "w_wad.h"
#include "r_main.h" // R_PointToAngle #include "r_main.h" // R_PointToAngle
@ -66,23 +66,20 @@ patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip)
patch_t *Patch_GetRotatedSprite( patch_t *Patch_GetRotatedSprite(
spriteframe_t *sprite, spriteframe_t *sprite,
size_t frame, size_t spriteangle, size_t frame, size_t spriteangle,
boolean flip, boolean adjustfeet, boolean flip,
void *info, INT32 rotationangle) void *info, INT32 rotationangle)
{ {
rotsprite_t *rotsprite; rotsprite_t *rotsprite = sprite->rotated[spriteangle];
spriteinfo_t *sprinfo = (spriteinfo_t *)info; spriteinfo_t *sprinfo = (spriteinfo_t *)info;
INT32 idx = rotationangle; INT32 idx = rotationangle;
UINT8 type = (adjustfeet ? 1 : 0);
if (rotationangle < 1 || rotationangle >= ROTANGLES) if (rotationangle < 1 || rotationangle >= ROTANGLES)
return NULL; return NULL;
rotsprite = sprite->rotated[type][spriteangle];
if (rotsprite == NULL) if (rotsprite == NULL)
{ {
rotsprite = RotatedPatch_Create(ROTANGLES); rotsprite = RotatedPatch_Create(ROTANGLES);
sprite->rotated[type][spriteangle] = rotsprite; sprite->rotated[spriteangle] = rotsprite;
} }
if (flip) if (flip)
@ -111,10 +108,6 @@ patch_t *Patch_GetRotatedSprite(
} }
RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip); RotatedPatch_DoRotation(rotsprite, patch, rotationangle, xpivot, ypivot, flip);
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
if (adjustfeet)
((patch_t *)rotsprite->patches[idx])->topoffset += FEETADJUST>>FRACBITS;
} }
return rotsprite->patches[idx]; return rotsprite->patches[idx];

View file

@ -138,8 +138,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
#ifdef ROTSPRITE #ifdef ROTSPRITE
for (r = 0; r < 16; r++) for (r = 0; r < 16; r++)
{ {
sprtemp[frame].rotated[0][r] = NULL; sprtemp[frame].rotated[r] = NULL;
sprtemp[frame].rotated[1][r] = NULL;
} }
#endif #endif
@ -337,6 +336,11 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
spritecachedinfo[numspritelumps].height = height<<FRACBITS; spritecachedinfo[numspritelumps].height = height<<FRACBITS;
// BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer // BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
// Monster Iestyn (21 Sep 2023): the above comment no longer makes sense in context!!! So I give an explanation here!
// FEETADJUST was originally an OpenGL-exclusive hack from Doom Legacy to avoid the player's feet being clipped as
// a result of rendering partially under the ground, but sometime before SRB2 2.1's release this was changed to apply
// to the software renderer as well.
// TODO: kill FEETADJUST altogether somehow and somehow fix OpenGL not to clip sprites that are partially underground (if possible)?
spritecachedinfo[numspritelumps].topoffset += FEETADJUST; spritecachedinfo[numspritelumps].topoffset += FEETADJUST;
//---------------------------------------------------- //----------------------------------------------------
@ -1336,8 +1340,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
patch_t *patch; patch_t *patch;
fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2; fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2;
INT32 heightsec, phs; INT32 heightsec, phs;
INT32 light = 0; fixed_t scalemul;
fixed_t scalemul; UINT8 trans; UINT8 trans;
fixed_t floordiff; fixed_t floordiff;
fixed_t groundz; fixed_t groundz;
pslope_t *groundslope; pslope_t *groundslope;
@ -1453,27 +1457,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
if (thing->renderflags & RF_NOCOLORMAPS) if (thing->renderflags & RF_NOCOLORMAPS)
shadow->extra_colormap = NULL; shadow->extra_colormap = NULL;
else else
{ shadow->extra_colormap = P_GetColormapFromSectorAt(thing->subsector->sector, interp.x, interp.y, shadow->gzt);
if (thing->subsector->sector->numlights)
{
INT32 lightnum;
light = thing->subsector->sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
if (h <= shadow->gzt) {
light = lightnum - 1;
break;
}
}
}
if (thing->subsector->sector->numlights)
shadow->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
else
shadow->extra_colormap = thing->subsector->sector->extra_colormap;
}
shadow->transmap = R_GetTranslucencyTable(trans + 1); shadow->transmap = R_GetTranslucencyTable(trans + 1);
shadow->colormap = scalelight[0][0]; // full dark! shadow->colormap = scalelight[0][0]; // full dark!
@ -1814,7 +1798,7 @@ static void R_ProjectSprite(mobj_t *thing)
rollangle = R_GetRollAngle(spriterotangle); rollangle = R_GetRollAngle(spriterotangle);
} }
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle); rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, sprinfo, rollangle);
if (rotsprite != NULL) if (rotsprite != NULL)
{ {
@ -2170,21 +2154,9 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
{ {
INT32 lightnum; light = P_GetSectorLightAt(thing->subsector->sector, interp.x, interp.y, splat ? gz : gzt);
fixed_t top = (splat) ? gz : gzt;
light = thing->subsector->sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
if (h <= top) {
light = lightnum - 1;
break;
}
}
//light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
INT32 lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
if (lightnum < 0) if (lightnum < 0)
spritelights = scalelight[0]; spritelights = scalelight[0];
else if (lightnum >= LIGHTLEVELS) else if (lightnum >= LIGHTLEVELS)
@ -3221,8 +3193,8 @@ static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2)
INT16 sz = spr->sz; INT16 sz = spr->sz;
INT16 szt = spr->szt; INT16 szt = spr->szt;
fixed_t texturemid, yscale, scalestep = spr->scalestep; fixed_t texturemid = 0, yscale = 0, scalestep = spr->scalestep; // "= 0" pleases the compiler
INT32 height; INT32 height = 0;
if (scalestep) if (scalestep)
{ {

View file

@ -608,6 +608,7 @@ void I_GetConsoleEvents(void)
return; return;
ev.type = ev_console; ev.type = ev_console;
ev.key = 0;
if (read(STDIN_FILENO, &key, 1) == -1 || !key) if (read(STDIN_FILENO, &key, 1) == -1 || !key)
return; return;
@ -634,7 +635,7 @@ void I_GetConsoleEvents(void)
} }
else return; else return;
} }
else else if (tty_con.cursor < sizeof (tty_con.buffer))
{ {
// push regular character // push regular character
ev.key = tty_con.buffer[tty_con.cursor] = key; ev.key = tty_con.buffer[tty_con.cursor] = key;

View file

@ -759,8 +759,8 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
music_volume = 18; music_volume = 18;
// apply volume to stream // apply volume to stream
for (i = 0, p = (short *)stream; i < len/2; i++, p++) for (i = 0, p = (short *)stream; i < len / 2; i++, p++)
*p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 40; *p = ((INT32)*p) * music_volume * internal_volume / 100 / 20;
} }
#endif #endif
@ -783,8 +783,8 @@ static void mix_openmpt(void *udata, Uint8 *stream, int len)
music_volume = 18; music_volume = 18;
// apply volume to stream // apply volume to stream
for (i = 0, p = (short *)stream; i < len/2; i++, p++) for (i = 0, p = (short *)stream; i < len / 2; i++, p++)
*p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 40; *p = ((INT32)*p) * music_volume * internal_volume / 100 / 20;
} }
#endif #endif
@ -1441,7 +1441,7 @@ void I_SetMusicVolume(UINT8 volume)
Mix_VolumeMusic(get_real_volume(music_volume)); Mix_VolumeMusic(get_real_volume(music_volume));
} }
boolean I_SetSongTrack(int track) boolean I_SetSongTrack(INT32 track)
{ {
#ifdef HAVE_GME #ifdef HAVE_GME
// If the specified track is within the number of tracks playing, then change it // If the specified track is within the number of tracks playing, then change it

View file

@ -1471,7 +1471,7 @@ void I_SetMusicVolume(UINT8 volume)
(void)volume; (void)volume;
} }
boolean I_SetSongTrack(int track) boolean I_SetSongTrack(INT32 track)
{ {
(void)track; (void)track;
return false; return false;

View file

@ -579,9 +579,9 @@ void Y_IntermissionDrawer(void)
{ {
if (LUA_HudEnabled(hud_intermissiontitletext)) if (LUA_HudEnabled(hud_intermissiontitletext))
{ {
const char *ringtext = "\x82" "50 rings, no shield"; const char *ringtext = "\x82" "get 50 rings then";
const char *tut1text = "\x82" "press " "\x80" "spin"; const char *tut1text = "\x82" "press " "\x80" "shield";
const char *tut2text = "\x82" "mid-" "\x80" "jump"; const char *tut2text = "\x82" "to " "\x80" "transform";
ttheight = 8; ttheight = 8;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed3) + 2; ttheight += V_LevelNameHeight(data.spec.passed3) + 2;