Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2.git into slope-cleanup

# Conflicts:
#	src/hardware/hw_main.c
#	src/p_spec.c
This commit is contained in:
Louis-Antoine 2020-05-18 16:14:05 +02:00
commit d0abd6e86c
104 changed files with 6565 additions and 7063 deletions

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine.
project(SRB2
VERSION 2.2.2
VERSION 2.2.4
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View File

@ -1,4 +1,4 @@
version: 2.2.2.{branch}-{build}
version: 2.2.4.{branch}-{build}
os: MinGW
environment:

View File

@ -15,7 +15,7 @@
* Oogaland
* Rob
* Shadow Hog
* Spherallic
* sphere
* SRB2-Playah
* SSNTails
* SteelT
@ -435,7 +435,7 @@ sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
512 = "Wind/Current";
1024 = "Conveyor Belt";
@ -490,7 +490,7 @@ gen_sectortypes
112 = "Trigger Line Ex. (NiGHTS Mare)";
128 = "Check for Linedef Executor on FOFs";
144 = "Egg Capsule";
160 = "Special Stage Time/Rings Parameters";
160 = "Special Stage Time/Spheres Parameters";
176 = "Custom Global Gravity";
}
@ -738,12 +738,6 @@ linedeftypes
flags2text = "[1] Use control sector tag";
flags64text = "[6] No sound effect";
}
65
{
title = "Bridge Thinker <disabled>";
prefix = "(65)";
}
}
polyobject
@ -756,16 +750,12 @@ linedeftypes
prefix = "(20)";
}
21
{
title = "Explicitly Include Line <disabled>";
prefix = "(21)";
}
22
{
title = "Parameters";
prefix = "(22)";
flags8text = "[3] Set translucency by X offset";
flags32text = "[5] Render outer sides only";
flags64text = "[6] Trigger linedef executor";
flags128text = "[7] Intangible";
flags256text = "[8] Stopped by pushables";
@ -788,7 +778,6 @@ linedeftypes
{
title = "Angular Displacement by Front Sector";
prefix = "(32)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Don't turn players";
flags512text = "[9] Turn all objects";
}
@ -1136,7 +1125,6 @@ linedeftypes
{
title = "Goo Water, Translucent, No Sides";
prefix = "(125)";
flags8text = "[3] Slope skew sides";
flags64text = "[6] Use two light levels";
flags512text = "[9] Use target light level";
flags1024text = "[10] Ripple effect";
@ -1227,6 +1215,18 @@ linedeftypes
3dfloorflags = "19F";
}
153
{
title = "Dynamically Sinking Platform";
prefix = "(153)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
3dfloor = true;
3dfloorflags = "19F";
}
160
{
title = "Floating, Bobbing";
@ -1282,7 +1282,6 @@ linedeftypes
title = "Rising Platform, Solid, Invisible";
prefix = "(193)";
flags2text = "[1] Sink when stepped on";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Spindash to move";
flags128text = "[7] Only block non-players";
@ -1488,16 +1487,22 @@ linedeftypes
{
title = "Mario Block";
prefix = "(250)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Invisible block";
flags64text = "[6] Brick block";
3dfloor = true;
3dfloorflags = "40019F";
flags323dfloorflagsremove = "19E";
flags643dfloorflagsadd = "200000";
}
251
{
title = "Thwomp Block";
prefix = "(251)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players";
flags512text = "[9] Custom crushing sound";
flags1024text = "[10] Custom speed";
3dfloor = true;
@ -1513,8 +1518,8 @@ linedeftypes
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
3dfloor = true;
3dfloorflags = "8800019";
flags643dfloorflagsadd = "200006";
3dfloorflags = "880001D";
flags643dfloorflagsadd = "200002";
}
253
@ -1525,7 +1530,7 @@ linedeftypes
flags512text = "[9] Shattered by pushables";
flags1024text = "[10] Trigger linedef executor";
3dfloor = true;
3dfloorflags = "8801019";
3dfloorflags = "880101D";
}
254
@ -1533,6 +1538,7 @@ linedeftypes
title = "Bustable Block";
prefix = "(254)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags64text = "[6] Strong characters only";
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
@ -1593,6 +1599,7 @@ linedeftypes
{
title = "Custom FOF";
prefix = "(259)";
flags8text = "[3] Slope skew sides";
flags32text = "[5] Only block player";
flags128text = "[7] Only block non-players";
flags512text = "[9] Shattered by pushables";
@ -1896,6 +1903,27 @@ linedeftypes
prefix = "(333)";
}
334
{
title = "Object Dye - Continuous";
flags64text = "[6] Disable for this color";
prefix = "(334)";
}
335
{
title = "Object Dye - Each Time";
flags64text = "[6] Disable for this color";
prefix = "(335)";
}
336
{
title = "Object Dye - Once";
flags64text = "[6] Disable for this color";
prefix = "(336)";
}
399
{
title = "Level Load";
@ -2161,6 +2189,14 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
}
449
{
title = "Enable Bosses with Parameter";
prefix = "(449)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Disable bosses";
}
457
{
title = "Track Object's Angle";
@ -2180,12 +2216,15 @@ linedeftypes
{
title = "Award Rings";
prefix = "(460)";
flags8text = "[3] Set delay by backside sector";
}
461
{
title = "Spawn Object";
prefix = "(461)";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Use line angle for object";
flags64text = "[6] Spawn inside a range";
}
@ -2193,6 +2232,20 @@ linedeftypes
{
title = "Stop Timer/Exit Stage in Record Attack";
prefix = "(462)";
flags8text = "[3] Set delay by backside sector";
}
463
{
title = "Dye Object";
prefix = "(463)";
}
464
{
title = "Trigger Egg Capsule";
prefix = "(464)";
flags64text = "[6] Don't end level";
}
}
@ -2206,7 +2259,7 @@ linedeftypes
prefix = "(413)";
flags2text = "[1] Keep after death";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Seek to current song position";
flags32text = "[5] Seek from current position";
flags64text = "[6] For everyone";
flags128text = "[7] Fade to custom volume";
flags512text = "[9] Don't loop";
@ -2220,7 +2273,7 @@ linedeftypes
flags2text = "[1] From calling sector";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] From nowhere for triggerer";
flags512text = "[9] For everyone";
flags512text = "[9] From nowhere for everyone";
flags1024text = "[10] From tagged sectors";
}
@ -2298,7 +2351,6 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
}
445
{
title = "Make FOF Disappear/Reappear";
@ -2325,8 +2377,8 @@ linedeftypes
flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values";
flags32768text = "[15] Use back side colormap";
flags256text = "[8] Set relative to current";
flags32768text = "[15] Use backside colormap";
}
448
@ -2359,7 +2411,7 @@ linedeftypes
prefix = "(452)";
flags8text = "[3] Set delay by backside sector";
flags64text = "[6] Do not handle FF_TRANS";
flags256text = "[8] Set relative to current val";
flags256text = "[8] Set relative to current";
}
453
@ -2371,7 +2423,7 @@ linedeftypes
flags32text = "[5] No collision during fade";
flags64text = "[6] Do not handle FF_TRANS";
flags128text = "[7] Do not handle lighting";
flags256text = "[8] Set relative to current val";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision";
@ -2395,11 +2447,11 @@ linedeftypes
flags32text = "[5] Subtract Red value";
flags64text = "[6] Subtract Green value";
flags128text = "[7] Subtract Blue value";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Fade from invisible black";
flags32768text = "[15] Use back side colormap";
flags32768text = "[15] Use backside colormap";
}
456
@ -2416,9 +2468,7 @@ linedeftypes
flags2text = "[1] Close text prompt";
flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Run executor tag on close";
flags64text = "[6] For everyone";
flags128text = "[7] Do not block controls";
flags256text = "[8] Do not freeze time";
flags128text = "[7] Don't disable controls";
flags32768text = "[15] Find prompt by name";
}
}
@ -2524,7 +2574,7 @@ linedeftypes
prefix = "(491)";
flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
}
492
@ -2534,7 +2584,7 @@ linedeftypes
flags8text = "[3] Set delay by backside sector";
flags16text = "[4] Set raw alpha by Front X";
flags32text = "[5] No collision during fade";
flags256text = "[8] Calc relative values";
flags256text = "[8] Set relative to current";
flags512text = "[9] Speed = Tic Duration";
flags1024text = "[10] Override existing fade";
flags16384text = "[14] Do not handle collision";
@ -2632,76 +2682,84 @@ linedeftypes
{
title = "Carry Objects on Floor";
prefix = "(520)";
flags64text = "[6] Exclusive";
}
521
{
title = "Carry Objects on Floor (Accelerative)";
prefix = "(521)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
522
{
title = "Carry Objects on Floor (Displacement)";
prefix = "(522)";
flags64text = "[6] Exclusive";
}
523
{
title = "Carry Objects on Ceiling";
prefix = "(523)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
524
{
title = "Carry Objects on Ceiling (Accelerative)";
prefix = "(524)";
flags64text = "[6] Exclusive";
}
525
{
title = "Carry Objects on Ceiling (Displacement)";
prefix = "(525)";
flags64text = "[6] Exclusive";
}
530
{
title = "Scroll Floor Texture and Carry Objects";
prefix = "(530)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
531
{
title = "Scroll Floor Texture and Carry Objects (Accelerative)";
prefix = "(531)";
flags64text = "[6] Exclusive";
}
532
{
title = "Scroll Floor Texture and Carry Objects (Displacement)";
prefix = "(532)";
flags64text = "[6] Exclusive";
}
533
{
title = "Scroll Ceiling Texture and Carry Objects";
prefix = "(533)";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
534
{
title = "Scroll Ceiling Texture and Carry Objects (Accelerative)";
prefix = "(534)";
flags64text = "[6] Exclusive";
}
535
{
title = "Scroll Ceiling Texture and Carry Objects (Displacement)";
prefix = "(535)";
flags64text = "[6] Exclusive";
}
}
@ -2714,7 +2772,7 @@ linedeftypes
title = "Wind";
prefix = "(541)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
542
@ -2722,7 +2780,7 @@ linedeftypes
title = "Upwards Wind";
prefix = "(542)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
543
@ -2730,7 +2788,7 @@ linedeftypes
title = "Downwards Wind";
prefix = "(543)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
544
@ -2738,7 +2796,7 @@ linedeftypes
title = "Current";
prefix = "(544)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
545
@ -2746,7 +2804,7 @@ linedeftypes
title = "Upwards Current";
prefix = "(545)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
546
@ -2754,13 +2812,14 @@ linedeftypes
title = "Downwards Current";
prefix = "(546)";
flags512text = "[9] Player slides";
flags64text = "[6] Even across edges";
flags64text = "[6] Exclusive";
}
547
{
title = "Push/Pull";
prefix = "(547)";
flags64text = "[6] Exclusive";
}
}
@ -3407,8 +3466,8 @@ thingtypes
sprite = "ESHIA1";
width = 16;
height = 48;
flags1text = "[1] 90 degrees counter-clockwise";
flags4text = "[4] 90 degrees clockwise";
flags1text = "[1] 90 degrees clockwise";
flags4text = "[4] 90 degrees counter-clockwise";
flags8text = "[8] Double speed";
}
115
@ -3674,6 +3733,7 @@ thingtypes
width = 8;
height = 16;
sprite = "internal:capsule";
angletext = "Tag";
}
292
{
@ -3870,6 +3930,8 @@ thingtypes
{
title = "Emerald Hunt Location";
sprite = "SHRDA0";
flags8height = 24;
flags8text = "[8] Float";
}
321
{
@ -3897,9 +3959,10 @@ thingtypes
title = "Monitors";
width = 18;
height = 40;
flags1text = "[1] Run Linedef Executor on pop";
flags1text = "[1] Run linedef executor on pop";
flags4text = "[4] Random (Strong)";
flags8text = "[8] Random (Weak)";
angletext = "Tag";
400
{
@ -4029,7 +4092,8 @@ thingtypes
title = "Monitors (Respawning)";
width = 20;
height = 44;
flags1text = "[1] Run Linedef Executor on pop";
flags1text = "[1] Run linedef executor on pop";
angletext = "Tag";
431
{
@ -4125,7 +4189,9 @@ thingtypes
sprite = "STPTA0M0";
width = 64;
height = 128;
flags4text = "[4] Respawn at center";
angletext = "Angle/Order";
parametertext = "Order";
}
520
{
@ -4152,6 +4218,7 @@ thingtypes
sprite = "WSPKALAR";
width = 16;
height = 14;
arrow = 1;
flags1text = "[1] Start retracted";
flags4text = "[4] Retractable";
flags8text = "[8] Intangible";
@ -4558,6 +4625,7 @@ thingtypes
sprite = "TOADA0";
width = 32;
height = 16;
angletext = "Tag";
}
757
{
@ -5832,7 +5900,7 @@ thingtypes
sprite = "CAPSA0";
width = 72;
height = 144;
angletext = "Rings";
angletext = "Spheres";
parametertext = "Mare";
}
}
@ -6273,7 +6341,7 @@ thingtypes
sprite = "PUMKA0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2007
{
@ -6281,7 +6349,7 @@ thingtypes
sprite = "PUMKB0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2008
{
@ -6289,7 +6357,7 @@ thingtypes
sprite = "PUMKC0";
width = 16;
height = 40;
flags1text = "Don't flicker";
flags1text = "[1] Don't flicker";
}
2009
{

View File

@ -16,6 +16,7 @@ set(SRB2_CORE_SOURCES
f_finale.c
f_wipe.c
filesrch.c
g_demo.c
g_game.c
g_input.c
hu_stuff.c
@ -71,6 +72,7 @@ set(SRB2_CORE_HEADERS
f_finale.h
fastcmp.h
filesrch.h
g_demo.h
g_game.h
g_input.h
g_state.h

View File

@ -422,6 +422,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/z_zone.o \
$(OBJDIR)/f_finale.o \
$(OBJDIR)/f_wipe.o \
$(OBJDIR)/g_demo.o \
$(OBJDIR)/g_game.o \
$(OBJDIR)/g_input.o \
$(OBJDIR)/am_map.o \

View File

@ -19,10 +19,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -52,10 +52,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

View File

@ -459,6 +459,19 @@ boolean B_CheckRespawn(player_t *player)
if (!sonic || sonic->health <= 0)
return false;
// B_RespawnBot doesn't do anything if the condition above this isn't met
{
UINT8 shouldForce = LUAh_BotRespawn(sonic, tails);
if (P_MobjWasRemoved(sonic) || P_MobjWasRemoved(tails))
return (shouldForce == 1); // mobj was removed
if (shouldForce == 1)
return true;
else if (shouldForce == 2)
return false;
}
// Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_BOUNCING)

View File

@ -80,7 +80,7 @@ static boolean joyaxis2_default = false;
static INT32 joyaxis_count = 0;
static INT32 joyaxis2_count = 0;
#define COM_BUF_SIZE 8192 // command buffer size
#define COM_BUF_SIZE (32<<10) // command buffer size
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
static INT32 com_wait; // one command per frame (for cmd sequences)

View File

@ -28,12 +28,14 @@
/* Manually defined asset hashes for non-CMake builds
* Last updated 2020 / 02 / 15 - v2.2.1 - main assets
* Last updated 2020 / 02 / 22 - v2.2.2 - patch.pk3
* Last updated 2020 / 05 / 10 - v2.2.3 - player.dta & patch.pk3
* Last updated 2020 / 05 / 11 - v2.2.4 - patch.pk3
*/
#define ASSET_HASH_SRB2_PK3 "0277c9416756627004e83cbb5b2e3e28"
#define ASSET_HASH_ZONES_PK3 "f7e88afb6af7996a834c7d663144bead"
#define ASSET_HASH_PLAYER_DTA "ad49e07b17cc662f1ad70c454910b4ae"
#define ASSET_HASH_PLAYER_DTA "8a4507ddf9bc0682c09174400f26ad65"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_PK3 "ee54330ecb743314c5f962af4db731ff"
#define ASSET_HASH_PATCH_PK3 "bbbf6af3b20349612ee06e0b55979a76"
#endif
#endif

View File

@ -97,6 +97,7 @@ static void CON_InputInit(void);
static void CON_RecalcSize(void);
static void CON_ChangeHeight(void);
static void CON_DrawBackpic(void);
static void CONS_hudlines_Change(void);
static void CONS_backcolor_Change(void);
@ -1530,6 +1531,51 @@ static void CON_DrawHudlines(void)
con_clearlines = y; // this is handled by HU_Erase();
}
// Lactozilla: Draws the console's background picture.
static void CON_DrawBackpic(void)
{
patch_t *con_backpic;
lumpnum_t piclump;
int x, w, h;
// Get the lumpnum for CONSBACK, or fallback into MISSING.
piclump = W_CheckNumForName("CONSBACK");
if (piclump == LUMPERROR)
piclump = W_GetNumForName("MISSING");
// Cache the Software patch.
con_backpic = W_CacheSoftwarePatchNum(piclump, PU_PATCH);
// Center the backpic, and draw a vertically cropped patch.
w = (con_backpic->width * vid.dupx);
x = (vid.width / 2) - (w / 2);
h = con_curlines/vid.dupy;
// If the patch doesn't fill the entire screen,
// then fill the sides with a solid color.
if (x > 0)
{
column_t *column = (column_t *)((UINT8 *)(con_backpic) + LONG(con_backpic->columnofs[0]));
if (!column->topdelta)
{
UINT8 *source = (UINT8 *)(column) + 3;
INT32 color = (source[0] | V_NOSCALESTART);
// left side
V_DrawFill(0, 0, x, con_curlines, color);
// right side
V_DrawFill((x + w), 0, (vid.width - w), con_curlines, color);
}
}
// Cache the patch normally.
con_backpic = W_CachePatchNum(piclump, PU_PATCH);
V_DrawCroppedPatch(x << FRACBITS, 0, FRACUNIT, V_NOSCALESTART, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
// Unlock the cached patch.
W_UnlockCachedPatch(con_backpic);
}
// draw the console background, text, and prompt if enough place
//
static void CON_DrawConsole(void)
@ -1551,19 +1597,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
int h;
h = con_curlines/vid.dupy;
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
//V_DrawScaledPatch(0, 0, 0, con_backpic);
V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic,
0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h);
W_UnlockCachedPatch(con_backpic);
}
CON_DrawBackpic();
else
{
// inu: no more width (was always 0 and vid.width)

View File

@ -85,6 +85,10 @@ tic_t jointimeout = (10*TICRATE);
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
// Incremented by cv_joindelay when a client joins, decremented each tic.
// If higher than cv_joindelay * 2 (3 joins in a short timespan), joins are temporarily disabled.
static tic_t joindelay = 0;
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
@ -1338,7 +1342,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
if (FindRejoinerNum(node) != -1)
if (!node || FindRejoinerNum(node) != -1)
netbuffer->u.serverinfo.refusereason = 0;
else if (!cv_allownewplayer.value)
netbuffer->u.serverinfo.refusereason = 1;
@ -1686,7 +1690,7 @@ static void CL_LoadReceivedSavegame(void)
// load a base level
if (P_LoadNetGame())
{
const INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
{
@ -3077,6 +3081,8 @@ consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0,
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_joindelay = {"joindelay", "10", CV_SAVE, joindelay_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t rejointimeout_cons_t[] = {{1, "MIN"}, {60 * FRACUNIT, "MAX"}, {0, "Off"}, {0, NULL}};
consvar_t cv_rejointimeout = {"rejointimeout", "Off", CV_SAVE|CV_FLOAT, rejointimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -3164,6 +3170,8 @@ void SV_ResetServer(void)
neededtic = maketic;
tictoclear = maketic;
joindelay = 0;
for (i = 0; i < MAXNETNODES; i++)
ResetNode(i);
@ -3613,6 +3621,9 @@ static void HandleConnect(SINT8 node)
SV_SendRefuse(node, M_GetText("No players from\nthis node."));
else if (luafiletransfers)
SV_SendRefuse(node, M_GetText("The server is broadcasting a file\nrequested by a Lua script.\nPlease wait a bit and then\ntry rejoining."));
else if (netgame && joindelay > 2 * (tic_t)cv_joindelay.value * TICRATE)
SV_SendRefuse(node, va(M_GetText("Too many people are connecting.\nPlease wait %d seconds and then\ntry rejoining."),
(joindelay - 2 * cv_joindelay.value * TICRATE) / TICRATE));
else
{
#ifndef NONET
@ -3670,6 +3681,7 @@ static void HandleConnect(SINT8 node)
DEBFILE("send savegame\n");
}
SV_AddWaitingPlayers(names[0], names[1]);
joindelay += cv_joindelay.value * TICRATE;
player_joining = true;
}
#else
@ -4875,7 +4887,8 @@ static inline void PingUpdate(void)
{
for (i = 1; i < MAXPLAYERS; i++)
{
if (playeringame[i] && (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
if (playeringame[i] && !players[i].quittime
&& (realpingtable[i] / pingmeasurecount > (unsigned)cv_maxping.value))
{
if (players[i].jointime > 30 * TICRATE)
laggers[i] = true;
@ -4894,8 +4907,8 @@ static inline void PingUpdate(void)
if (playeringame[i] && laggers[i])
{
pingtimeout[i]++;
// ok your net has been bad for too long, you deserve to die.
if (pingtimeout[i] > cv_pingtimeout.value)
// ok your net has been bad for too long, you deserve to die.
{
pingtimeout[i] = 0;
SendKick(i, KICK_MSG_PING_HIGH | KICK_MSG_KEEP_BODY);
@ -5037,12 +5050,21 @@ void NetUpdate(void)
hu_resynching = true;
}
}
Net_AckTicker();
// Handle timeouts to prevent definitive freezes from happenning
if (server)
{
for (i = 1; i < MAXNETNODES; i++)
if (nodeingame[i] && freezetimeout[i] < I_GetTime())
Net_ConnectionTimeout(i);
// In case the cvar value was lowered
if (joindelay)
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
}
nowtime /= NEWTICRATERATIO;
if (nowtime > resptime)
{
@ -5050,6 +5072,7 @@ void NetUpdate(void)
M_Ticker();
CON_Ticker();
}
SV_FileSendTicker();
}

View File

@ -20,12 +20,9 @@
#include "d_player.h"
/*
The 'packet version' may be used with packets whose
format is expected to change between versions.
This version is independent of the mod name, and standard
version and subversion. It should only account for the
basic fields of the packet, and change infrequently.
The 'packet version' is used to distinguish packet formats.
This version is independent of VERSION and SUBVERSION. Different
applications may follow different packet versions.
*/
#define PACKETVERSION 3
@ -518,7 +515,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_rejointimeout;
extern consvar_t cv_allownewplayer, cv_joinnextround, cv_maxplayers, cv_joindelay, cv_rejointimeout;
extern consvar_t cv_resynchattempts, cv_blamecfail;
extern consvar_t cv_maxsend, cv_noticedownload, cv_downloadspeed;

View File

@ -125,6 +125,8 @@ boolean advancedemo;
INT32 debugload = 0;
#endif
char savegamename[256];
char srb2home[256] = ".";
char srb2path[256] = ".";
boolean usehome = true;
@ -310,7 +312,9 @@ static void D_Display(void)
F_WipeStartScreen();
// Check for Mega Genesis fade
wipestyleflags = WSF_FADEOUT;
if (F_TryColormapFade(31))
if (wipegamestate == (gamestate_t)FORCEWIPE)
F_WipeColorFill(31);
else if (F_TryColormapFade(31))
wipetypepost = -1; // Don't run the fade below this one
F_WipeEndScreen();
F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN);
@ -876,6 +880,40 @@ static inline void D_CleanFile(void)
}
}
///\brief Checks if a netgame URL is being handled, and changes working directory to the EXE's if so.
/// Done because browsers (at least, Firefox on Windows) launch the game from the browser's directory, which causes problems.
static void ChangeDirForUrlHandler(void)
{
// URL handlers are opened by web browsers (at least Firefox) from the browser's working directory, not the game's stored directory,
// so chdir to that directory unless overridden.
if (M_GetUrlProtocolArg() != NULL && !M_CheckParm("-nochdir"))
{
size_t i;
CONS_Printf("%s connect links load game files from the SRB2 application's stored directory. Switching to ", SERVER_URL_PROTOCOL);
strlcpy(srb2path, myargv[0], sizeof(srb2path));
// Get just the directory, minus the EXE name
for (i = strlen(srb2path)-1; i > 0; i--)
{
if (srb2path[i] == '/' || srb2path[i] == '\\')
{
srb2path[i] = '\0';
break;
}
}
CONS_Printf("%s\n", srb2path);
#if defined (_WIN32)
SetCurrentDirectoryA(srb2path);
#else
if (chdir(srb2path) == -1)
I_OutputMsg("Couldn't change working directory\n");
#endif
}
}
// ==========================================================================
// Identify the SRB2 version, and IWAD file to use.
// ==========================================================================
@ -957,6 +995,7 @@ static void IdentifyVersion(void)
}
MUSICTEST("music.dta")
MUSICTEST("patch_music.pk3")
#ifdef DEVELOP // remove when music_new.dta is merged into music.dta
MUSICTEST("music_new.dta")
#endif
@ -1064,6 +1103,9 @@ void D_SRB2Main(void)
// Test Dehacked lists
DEH_Check();
// Netgame URL special case: change working dir to EXE folder.
ChangeDirForUrlHandler();
// identify the main IWAD file to use
IdentifyVersion();
@ -1149,9 +1191,15 @@ void D_SRB2Main(void)
if (M_CheckParm("-password") && M_IsNextParm())
D_SetPassword(M_GetNextParm());
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// Do this up here so that WADs loaded through the command line can use ExecCfg
COM_Init();
// add any files specified on the command line with -file wadfile
// to the wad list
if (!(M_CheckParm("-connect") && !M_CheckParm("-server")))
if (!((M_GetUrlProtocolArg() || M_CheckParm("-connect")) && !M_CheckParm("-server")))
{
if (M_CheckParm("-file"))
{
@ -1176,9 +1224,6 @@ void D_SRB2Main(void)
if (M_CheckParm("-server") || dedicated)
netgame = server = true;
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
Z_Init();
// adapt tables to SRB2's needs, including extra slots for dehacked file support
P_PatchInfoTables();
@ -1186,7 +1231,7 @@ void D_SRB2Main(void)
M_InitMenuPresTables();
// init title screen display params
if (M_CheckParm("-connect"))
if (M_GetUrlProtocolArg() || M_CheckParm("-connect"))
F_InitMenuPresValues();
//---------------------------------------------------- READY TIME
@ -1250,7 +1295,6 @@ void D_SRB2Main(void)
CONS_Printf("HU_Init(): Setting up heads up display.\n");
HU_Init();
COM_Init();
CON_Init();
D_RegisterServerCommands();
@ -1284,11 +1328,10 @@ void D_SRB2Main(void)
// Set cv_renderer to the new render mode
VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded);
SCR_ChangeRendererCVars(rendermode);
// check the renderer's state, and then clear setrenderneeded
// check the renderer's state
D_CheckRendererState();
setrenderneeded = 0;
}
wipegamestate = gamestate;

View File

@ -811,6 +811,7 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTJOIN",
"NODETIMEOUT",
"RESYNCHING",
"LOGIN",
"PING"
};

View File

@ -573,6 +573,7 @@ void D_RegisterServerCommands(void)
// d_clisrv
CV_RegisterVar(&cv_maxplayers);
CV_RegisterVar(&cv_joindelay);
CV_RegisterVar(&cv_rejointimeout);
CV_RegisterVar(&cv_resynchattempts);
CV_RegisterVar(&cv_maxsend);
@ -1252,7 +1253,7 @@ static void SendNameAndColor(void)
players[consoleplayer].skincolor = cv_playercolor.value;
if (players[consoleplayer].mo)
if (players[consoleplayer].mo && !players[consoleplayer].powers[pw_dye])
players[consoleplayer].mo->color = players[consoleplayer].skincolor;
if (metalrecording)
@ -1364,8 +1365,9 @@ static void SendNameAndColor2(void)
if (botingame)
{
players[secondplaya].skincolor = botcolor;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
SetPlayerSkinByNum(secondplaya, botskin-1);
return;
}
@ -1378,7 +1380,7 @@ static void SendNameAndColor2(void)
// don't use secondarydisplayplayer: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
if (players[secondplaya].mo && !players[secondplaya].powers[pw_dye])
players[secondplaya].mo->color = players[secondplaya].skincolor;
if (cv_forceskin.value >= 0 && (netgame || multiplayer)) // Server wants everyone to use the same player

View File

@ -48,6 +48,7 @@ typedef enum
SF_FASTEDGE = 1<<12, // Faster edge teeter?
SF_MULTIABILITY = 1<<13, // Revenge of Final Demo.
SF_NONIGHTSROTATION = 1<<14, // Disable sprite rotation for NiGHTS
SF_NONIGHTSSUPER = 1<<15, // Disable super colors for NiGHTS (if you have SF_SUPER)
// free up to and including 1<<31
} skinflags_t;
@ -238,7 +239,8 @@ typedef enum
CR_MACESPIN,
CR_MINECART,
CR_ROLLOUT,
CR_PTERABYTE
CR_PTERABYTE,
CR_DUSTDEVIL
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment)
@ -278,6 +280,9 @@ typedef enum
pw_nights_linkfreeze,
pw_nocontrol, //for linedef exec 427
pw_dye, // for dyes
pw_justlaunched, // Launched off a slope this tic (0=none, 1=standard launch, 2=half-pipe launch)
NUMPOWERS

View File

@ -1557,7 +1557,7 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "ACT"))
{
if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19
if (i >= 0 && i <= 99) // 0 for no act number
mapheaderinfo[num-1]->actnum = (UINT8)i;
else
deh_warning("Level header %d: invalid act number %d", num, i);
@ -1863,6 +1863,12 @@ static void readlevelheader(MYFILE *f, INT32 num)
}
else if (fastcmp(word, "STARTRINGS"))
mapheaderinfo[num-1]->startrings = (UINT16)i;
else if (fastcmp(word, "SPECIALSTAGETIME"))
mapheaderinfo[num-1]->sstimer = i;
else if (fastcmp(word, "SPECIALSTAGESPHERES"))
mapheaderinfo[num-1]->ssspheres = i;
else if (fastcmp(word, "GRAVITY"))
mapheaderinfo[num-1]->gravity = FLOAT_TO_FIXED(atof(word2));
else
deh_warning("Level header %d: unknown word '%s'", num, word);
}
@ -2807,7 +2813,7 @@ static actionpointer_t actionpointers[] =
{{A_ThrownRing}, "A_THROWNRING"},
{{A_SetSolidSteam}, "A_SETSOLIDSTEAM"},
{{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"},
{{A_SignSpin}, "S_SIGNSPIN"},
{{A_SignSpin}, "A_SIGNSPIN"},
{{A_SignPlayer}, "A_SIGNPLAYER"},
{{A_OverlayThink}, "A_OVERLAYTHINK"},
{{A_JetChase}, "A_JETCHASE"},
@ -2909,6 +2915,7 @@ static actionpointer_t actionpointers[] =
{{A_SetRandomTics}, "A_SETRANDOMTICS"},
{{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"},
{{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"},
{{A_Dye}, "A_DYE"},
{{A_MoveRelative}, "A_MOVERELATIVE"},
{{A_MoveAbsolute}, "A_MOVEABSOLUTE"},
{{A_Thrust}, "A_THRUST"},
@ -3026,6 +3033,7 @@ static actionpointer_t actionpointers[] =
{{A_DragonbomberSpawn}, "A_DRAGONBOMERSPAWN"},
{{A_DragonWing}, "A_DRAGONWING"},
{{A_DragonSegment}, "A_DRAGONSEGMENT"},
{{A_ChangeHeight}, "A_CHANGEHEIGHT"},
{{NULL}, "NONE"},
// This NULL entry must be the last in the list
@ -3880,7 +3888,26 @@ static void readmaincfg(MYFILE *f)
value = atoi(word2); // used for numerical settings
if (fastcmp(word, "EXECCFG"))
COM_BufAddText(va("exec %s\n", word2));
{
if (strchr(word2, '.'))
COM_BufAddText(va("exec %s\n", word2));
else
{
lumpnum_t lumpnum;
char newname[9];
strncpy(newname, word2, 8);
newname[8] = '\0';
lumpnum = W_CheckNumForName(newname);
if (lumpnum == LUMPERROR || W_LumpLength(lumpnum) == 0)
CONS_Debug(DBG_SETUP, "SOC Error: script lump %s not found/not valid.\n", newname);
else
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
}
}
else if (fastcmp(word, "SPSTAGE_START"))
{
@ -4122,6 +4149,10 @@ static void readmaincfg(MYFILE *f)
{
maxXtraLife = (UINT8)get_number(word2);
}
else if (fastcmp(word, "USECONTINUES"))
{
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "GAMEDATA"))
{
@ -6201,6 +6232,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_ROCKET",
"S_LASER",
"S_LASER2",
"S_LASERFLASH",
"S_LASERFLAME1",
"S_LASERFLAME2",
"S_LASERFLAME3",
"S_LASERFLAME4",
"S_LASERFLAME5",
"S_TORPEDO",
@ -9132,7 +9171,11 @@ static const char *const POWERS_LIST[] = {
//for linedef exec 427
"NOCONTROL",
"JUSTLAUNCHED",
//for dyes
"DYE",
"JUSTLAUNCHED"
};
static const char *const HUDITEMS_LIST[] = {
@ -9196,6 +9239,7 @@ static const char *const MENUTYPES_LIST[] = {
"MP_CONNECT",
"MP_ROOM",
"MP_PLAYERSETUP", // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET
"MP_SERVER_OPTIONS",
// Options
"OP_MAIN",
@ -9205,10 +9249,14 @@ static const char *const MENUTYPES_LIST[] = {
"OP_P1MOUSE",
"OP_P1JOYSTICK",
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
"OP_P1CAMERA",
"OP_P2CONTROLS",
"OP_P2MOUSE",
"OP_P2JOYSTICK",
"OP_P2CAMERA",
"OP_PLAYSTYLE",
"OP_VIDEO",
"OP_VIDEOMODE",
@ -9440,6 +9488,7 @@ struct {
{"CR_MINECART",CR_MINECART},
{"CR_ROLLOUT",CR_ROLLOUT},
{"CR_PTERABYTE",CR_PTERABYTE},
{"CR_DUSTDEVIL",CR_DUSTDEVIL},
// Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon
@ -9467,6 +9516,7 @@ struct {
{"SF_FASTEDGE",SF_FASTEDGE},
{"SF_MULTIABILITY",SF_MULTIABILITY},
{"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION},
{"SF_NONIGHTSSUPER",SF_NONIGHTSSUPER},
// Dashmode constants
{"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD},
@ -9648,11 +9698,11 @@ struct {
{"FF_CUTEXTRA",FF_CUTEXTRA}, ///< Cuts out hidden translucent pixels.
{"FF_CUTLEVEL",FF_CUTLEVEL}, ///< Cuts out all hidden pixels.
{"FF_CUTSPRITES",FF_CUTSPRITES}, ///< Final step in making 3D water.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Renders both planes all the time.
{"FF_BOTHPLANES",FF_BOTHPLANES}, ///< Render inside and outside planes.
{"FF_EXTRA",FF_EXTRA}, ///< Gets cut by ::FF_CUTEXTRA.
{"FF_TRANSLUCENT",FF_TRANSLUCENT}, ///< See through!
{"FF_FOG",FF_FOG}, ///< Fog "brush."
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Reverse the plane visibility rules.
{"FF_INVERTPLANES",FF_INVERTPLANES}, ///< Only render inside planes.
{"FF_ALLSIDES",FF_ALLSIDES}, ///< Render inside and outside sides.
{"FF_INVERTSIDES",FF_INVERTSIDES}, ///< Only render inside sides.
{"FF_DOUBLESHADOW",FF_DOUBLESHADOW}, ///< Make two lightlist entries to reset light?

View File

@ -339,7 +339,4 @@ void I_StartupGraphics(void)
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}
void VID_StartupOpenGL(void) {}

View File

@ -378,10 +378,8 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}

View File

@ -143,13 +143,16 @@ extern char logfilename[1024];
// we use comprevision and compbranch instead.
#else
#define VERSION 202 // Game version
#define SUBVERSION 2 // more precise version number
#define VERSIONSTRING "v2.2.2"
#define VERSIONSTRINGW L"v2.2.2"
#define SUBVERSION 4 // more precise version number
#define VERSIONSTRING "v2.2.4"
#define VERSIONSTRINGW L"v2.2.4"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
/* A custom URL protocol for server links. */
#define SERVER_URL_PROTOCOL "srb2://"
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
#define USE_PATCH_DTA
@ -210,7 +213,7 @@ extern char logfilename[1024];
// it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.2.0 is not version "1".
#define MODVERSION 42
#define MODVERSION 44
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
// Increment MINOREXECVERSION whenever a config change is needed that does not correspond
@ -455,7 +458,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav"
char savegamename[256];
extern char savegamename[256];
// m_misc.h
#ifdef GETTEXT
@ -571,9 +574,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Dumps the contents of a network save game upon consistency failure for debugging.
//#define DUMPCONSISTENCY
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// See name of player in your crosshair
#define SEENAMES

View File

@ -319,6 +319,9 @@ typedef struct
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
UINT16 startrings; ///< Number of rings players start with.
INT32 sstimer; ///< Timer for special stages.
UINT32 ssspheres; ///< Sphere requirement in special stages.
fixed_t gravity; ///< Map-wide gravity.
// Title card.
char ltzzpatch[8]; ///< Zig zag patch.
@ -542,7 +545,7 @@ extern recorddata_t *mainrecords[NUMMAPS];
extern UINT8 mapvisited[NUMMAPS];
// Temporary holding place for nights data for the current map
nightsdata_t ntemprecords;
extern nightsdata_t ntemprecords;
extern UINT32 token; ///< Number of tokens collected in a level
extern UINT32 tokenlist; ///< List of tokens collected
@ -575,6 +578,8 @@ extern UINT8 creditscutscene;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings
extern UINT8 useContinues;
#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0)))
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations

View File

@ -11,10 +11,10 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}
void VID_StartupOpenGL(void){}
void I_SetPalette(RGBA_t *palette)
{
(void)palette;
@ -40,10 +40,8 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
const char *VID_GetModeName(INT32 modenum)
{

View File

@ -3618,7 +3618,7 @@ void F_StartContinue(void)
{
I_Assert(!netgame && !multiplayer);
if (players[consoleplayer].continues <= 0)
if (continuesInSession && players[consoleplayer].continues <= 0)
{
Command_ExitGame_f();
return;
@ -3725,7 +3725,9 @@ void F_ContinueDrawer(void)
}
// Draw the continue markers! Show continues.
if (ncontinues > 10)
if (!continuesInSession)
;
else if (ncontinues > 10)
{
if (!(continuetime & 1) || continuetime > 17)
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);

2505
src/g_demo.c Normal file

File diff suppressed because it is too large Load Diff

86
src/g_demo.h Normal file
View File

@ -0,0 +1,86 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file g_demo.h
/// \brief Demo recording and playback
#ifndef __G_DEMO__
#define __G_DEMO__
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DeferedPlayDemo(const char *demo);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_FreeGhosts(void);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
#endif // __G_DEMO__

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "d_event.h"
#include "g_demo.h"
extern char gamedatafilename[64];
extern char timeattackfolder[64];
@ -31,21 +32,6 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS];
// ======================================
// DEMO playback/recording related stuff.
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, demorecording, timingdemo;
extern tic_t demostarttime;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern boolean demosynced;
extern mobj_t *metalplayback;
// gametic at level start
extern tic_t levelstarttic;
@ -173,7 +159,6 @@ void G_DoLoadLevel(boolean resetplayer);
void G_StartTitleCard(void);
void G_PreLevelTitleCard(void);
boolean G_IsTitleCardAvailable(void);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
void G_LoadGame(UINT32 slot, INT16 mapoverride);
@ -184,54 +169,6 @@ void G_SaveGame(UINT32 slot);
void G_SaveGameOver(UINT32 slot, boolean modifylives);
// Only called by startup code.
void G_RecordDemo(const char *name);
void G_RecordMetal(void);
void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_SetDemoTime(UINT32 ptime, UINT32 pscore, UINT16 prings);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
typedef enum
{
GHC_NORMAL = 0,
GHC_SUPER,
GHC_FIREFLOWER,
GHC_INVINCIBLE,
GHC_NIGHTSSKIN, // not actually a colour
GHC_RETURNSKIN // ditto
} ghostcolor_t;
// Record/playback tics
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostTicker(void);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
void G_LoadMetal(UINT8 **buffer);
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
void G_DoPlayMetal(void);
void G_DoneLevelLoad(void);
void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES];

View File

@ -887,12 +887,10 @@ static void AdjustSegs(void)
float distv1,distv2,tmp;
nearv1 = nearv2 = MYMAX;
#ifdef POLYOBJECTS
// Don't touch polyobject segs. We'll compensate
// for this when we go about drawing them.
if (lseg->polyseg)
continue;
#endif
if (p) {
for (j = 0; j < p->numpts; j++)

View File

@ -291,7 +291,7 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{
@ -450,7 +450,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{
// Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
patch_t *realpatch = W_CacheSoftwarePatchNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
const column_t *column = (const column_t *)((const UINT8 *)(realpatch) + LONG((realpatch)->columnofs[0]));
if (!column->topdelta)
{

View File

@ -298,6 +298,8 @@ light_t *t_lspr[NUMSPRITES] =
// Projectiles
&lspr[NOLIGHT], // SPR_MISL
&lspr[SMALLREDBALL_L], // SPR_LASR
&lspr[REDSHINE_L], // SPR_LASF
&lspr[NOLIGHT], // SPR_TORP
&lspr[NOLIGHT], // SPR_ENRG
&lspr[NOLIGHT], // SPR_MINE

View File

@ -467,7 +467,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c
// -----------------+
// HWR_RenderPlane : Render a floor or ceiling convex polygon
// -----------------+
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
FBITFIELD PolyFlags, INT32 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
{
polyvertex_t * pv;
@ -489,8 +489,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
(void)sector; ///@TODO remove shitty unused variable
// no convex poly were generated for this subsector
if (!xsub->planepoly)
return;
@ -587,8 +585,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight);
// transform
v3d = planeVerts;
if (FOFsector != NULL)
{
if (!isceiling) // it's a floor
@ -631,44 +627,39 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
flatyref = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
}
for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++)
{
// Hurdler: add scrolling texture on floor/ceiling
if (texflat)
{
v3d->sow = (float)(pv->x / fflatwidth) + scrollx;
v3d->tow = -(float)(pv->y / fflatheight) + scrolly;
}
else
{
v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx);
v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly);
}
#define SETUP3DVERT(vert, vx, vy) {\
/* Hurdler: add scrolling texture on floor/ceiling */\
if (texflat)\
{\
vert->sow = (float)((vx) / fflatwidth) + scrollx;\
vert->tow = -(float)((vy) / fflatheight) + scrolly;\
}\
else\
{\
vert->sow = (float)(((vx) / fflatwidth) - flatxref + scrollx);\
vert->tow = (float)(flatyref - ((vy) / fflatheight) + scrolly);\
}\
\
/* Need to rotate before translate */\
if (angle) /* Only needs to be done if there's an altered angle */\
{\
tempxsow = FLOAT_TO_FIXED(vert->sow);\
tempytow = FLOAT_TO_FIXED(vert->tow);\
if (texflat)\
tempytow = -tempytow;\
vert->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));\
vert->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));\
}\
\
vert->x = (vx);\
vert->z = (vy);\
\
fixedheight = P_GetZAt(slope, FLOAT_TO_FIXED((vx)), FLOAT_TO_FIXED((vy)), height);\
vert->y = FIXED_TO_FLOAT(fixedheight);\
}
// Need to rotate before translate
if (angle) // Only needs to be done if there's an altered angle
{
tempxsow = FLOAT_TO_FIXED(v3d->sow);
tempytow = FLOAT_TO_FIXED(v3d->tow);
if (texflat)
tempytow = -tempytow;
v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle))));
v3d->tow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINESINE(angle)) + FixedMul(tempytow, FINECOSINE(angle))));
}
//v3d->sow = (float)(v3d->sow - flatxref + scrollx);
//v3d->tow = (float)(flatyref - v3d->tow + scrolly);
v3d->x = pv->x;
v3d->y = height;
v3d->z = pv->y;
if (slope)
{
fixedheight = P_GetSlopeZAt(slope, FLOAT_TO_FIXED(pv->x), FLOAT_TO_FIXED(pv->y));
v3d->y = FIXED_TO_FLOAT(fixedheight);
}
}
for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++)
SETUP3DVERT(v3d, pv->x, pv->y);
// only useful for flat coloured triangles
//Surf.FlatColor = 0xff804020;
@ -679,36 +670,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
Surf.FlatColor.s.red = Surf.FlatColor.s.green =
Surf.FlatColor.s.blue = LightLevelToLum(lightlevel); // Don't take from the frontsector, or the game will crash
#if 0 // no colormap test
// colormap test
if (gr_frontsector)
{
sector_t *psector = gr_frontsector;
if (slope)
fixedheight = P_GetSlopeZAt(slope, psector->soundorg.x, psector->soundorg.y);
if (psector->ffloors)
{
ffloor_t *caster = psector->lightlist[R_GetPlaneLight(psector, fixedheight, false)].caster;
psector = caster ? &sectors[caster->secnum] : psector;
if (caster)
{
lightlevel = psector->lightlevel;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = LightLevelToLum(lightlevel);
}
}
if (psector->extra_colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,psector->extra_colormap->rgba,psector->extra_colormap->fadergba, false, true);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true);
}
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel,NORMALFOG,FADEFOG, false, true);
#endif // NOPE
if (planecolormap)
{
if (fogplane)
@ -734,6 +695,79 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags);
if (subsector)
{
// Horizon lines
FOutVector horizonpts[6];
float dist, vx, vy;
float x1, y1, xd, yd;
UINT8 numplanes, j;
vertex_t v; // For determining the closest distance from the line to the camera, to split render planes for minimum distortion;
const float renderdist = 27000.0f; // How far out to properly render the plane
const float farrenderdist = 32768.0f; // From here, raise plane to horizon level to fill in the line with some texture distortion
seg_t *line = &segs[subsector->firstline];
for (i = 0; i < subsector->numlines; i++, line++)
{
if (!line->glseg && line->linedef->special == HORIZONSPECIAL && R_PointOnSegSide(dup_viewx, dup_viewy, line) == 0)
{
P_ClosestPointOnLine(viewx, viewy, line->linedef, &v);
dist = FIXED_TO_FLOAT(R_PointToDist(v.x, v.y));
x1 = ((polyvertex_t *)line->pv1)->x;
y1 = ((polyvertex_t *)line->pv1)->y;
xd = ((polyvertex_t *)line->pv2)->x - x1;
yd = ((polyvertex_t *)line->pv2)->y - y1;
// 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;
if (dist > 100.0f)
numplanes = 100;
else
numplanes = (UINT8)dist + 1;
for (j = 0; j < numplanes; j++)
{
// Left side
vx = x1 + xd * j / numplanes;
vy = y1 + yd * j / numplanes;
SETUP3DVERT((&horizonpts[1]), vx, vy);
dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2));
vx = (vx - gr_viewx) * renderdist / dist + gr_viewx;
vy = (vy - gr_viewy) * renderdist / dist + gr_viewy;
SETUP3DVERT((&horizonpts[0]), vx, vy);
// Right side
vx = x1 + xd * (j+1) / numplanes;
vy = y1 + yd * (j+1) / numplanes;
SETUP3DVERT((&horizonpts[2]), vx, vy);
dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2));
vx = (vx - gr_viewx) * renderdist / dist + gr_viewx;
vy = (vy - gr_viewy) * renderdist / dist + gr_viewy;
SETUP3DVERT((&horizonpts[3]), vx, vy);
// Horizon fills
vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx;
vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy;
SETUP3DVERT((&horizonpts[5]), vx, vy);
horizonpts[5].y = gr_viewz;
vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx;
vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy;
SETUP3DVERT((&horizonpts[4]), vx, vy);
horizonpts[4].y = gr_viewz;
// Draw
HWD.pfnDrawPolygon(&Surf, horizonpts, 6, PolyFlags);
}
}
}
}
#ifdef ALAM_LIGHTING
// add here code for dynamic lighting on planes
HWR_PlaneLighting(planeVerts, nrPlaneVerts);
@ -1546,7 +1580,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
// heights of the polygon, and h & l, are the final (clipped)
// poly coords.
#ifdef POLYOBJECTS
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct
// From CB
@ -1556,7 +1589,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
popenbottom = back->floorheight;
}
else
#endif
{
popentop = min(worldtop, worldhigh);
popenbottom = max(worldbottom, worldlow);
@ -1586,7 +1618,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
polybottom = polytop - textureheight[gr_midtexture]*repeats;
}
// CB
#ifdef POLYOBJECTS
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
// you must use the linedef's backsector to be correct
if (gr_curline->polyseg)
@ -1594,7 +1625,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
lowcut = polybottom;
highcut = polytop;
}
#endif
else
{
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
@ -1724,7 +1754,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
break;
}
#ifdef POLYOBJECTS
if (gr_curline->polyseg && gr_curline->polyseg->translucency > 0)
{
if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
@ -1735,7 +1764,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
else
blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, &Surf);
}
#endif
if (gr_frontsector->numlights)
{
@ -1884,7 +1912,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
{
for (rover = gr_backsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || (rover->flags & FF_INVERTSIDES))
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
@ -2024,7 +2054,9 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
{
for (rover = gr_frontsector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (*rover->topheight < lowcut || *rover->bottomheight > highcut)
continue;
@ -2524,10 +2556,8 @@ static void HWR_AddLine(seg_t * line)
static sector_t tempsec;
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
#ifdef POLYOBJECTS
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return;
#endif
gr_curline = line;
@ -2654,13 +2684,10 @@ static void HWR_AddLine(seg_t * line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{
if (
#ifdef POLYOBJECTS
!line->polyseg &&
#endif
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
return; // line is empty, don't even bother
// treat like wide open window instead
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
@ -2696,13 +2723,10 @@ static void HWR_AddLine(seg_t * line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{
if (
#ifdef POLYOBJECTS
!line->polyseg &&
#endif
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!gr_frontsector->ffloors && !gr_backsector->ffloors)
|| (gr_frontsector->tag == gr_backsector->tag)))
return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead
@ -2891,8 +2915,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
#endif
}
#ifdef POLYOBJECTS
//
// HWR_AddPolyObjectSegs
//
@ -2935,7 +2957,6 @@ static inline void HWR_AddPolyObjectSegs(void)
Z_Free(gr_fakeline);
}
#ifdef POLYOBJECTS_PLANES
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap)
@ -3190,8 +3211,6 @@ static void HWR_AddPolyObjectPlanes(void)
}
}
}
#endif
#endif
// -----------------+
// HWR_Subsector : Determine floor/ceiling planes.
@ -3324,7 +3343,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetLevelFlat(&levelflats[gr_frontsector->floorpic]);
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
HWR_RenderPlane(sub, &extrasubsectors[num], false,
// Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
// We now return you to your regularly scheduled rendering.
@ -3346,7 +3365,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount)
{
HWR_GetLevelFlat(&levelflats[gr_frontsector->ceilingpic]);
HWR_RenderPlane(NULL, &extrasubsectors[num], true,
HWR_RenderPlane(sub, &extrasubsectors[num], true,
// Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering.
@ -3388,7 +3407,7 @@ static void HWR_Subsector(size_t num)
if (centerHeight <= locCeilingHeight &&
centerHeight >= locFloorHeight &&
((dup_viewz < cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
((dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
@ -3433,7 +3452,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetLevelFlat(&levelflats[*rover->bottompic]);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
}
}
@ -3444,7 +3463,7 @@ static void HWR_Subsector(size_t num)
if (centerHeight >= locFloorHeight &&
centerHeight <= locCeilingHeight &&
((dup_viewz > cullHeight && !(rover->flags & FF_INVERTPLANES)) ||
((dup_viewz > cullHeight && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(dup_viewz < cullHeight && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
if (rover->flags & FF_FOG)
@ -3490,7 +3509,7 @@ static void HWR_Subsector(size_t num)
{
HWR_GetLevelFlat(&levelflats[*rover->toppic]);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
}
}
@ -3499,7 +3518,6 @@ static void HWR_Subsector(size_t num)
#endif
#endif //doplanes
#ifdef POLYOBJECTS
// Draw all the polyobjects in this subsector
if (sub->polyList)
{
@ -3520,15 +3538,12 @@ static void HWR_Subsector(size_t num)
// Draw polyobject lines.
HWR_AddPolyObjectSegs();
#ifdef POLYOBJECTS_PLANES
if (sub->validcount != validcount) // This validcount situation seems to let us know that the floors have already been drawn.
{
// Draw polyobject planes
HWR_AddPolyObjectPlanes();
}
#endif
}
#endif
// Hurder ici se passe les choses INT32<33>essantes!
// on vient de tracer le sol et le plafond
@ -3551,14 +3566,8 @@ static void HWR_Subsector(size_t num)
while (count--)
{
if (!line->glseg
#ifdef POLYOBJECTS
&& !line->polyseg // ignore segs that belong to polyobjects
#endif
)
{
if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
HWR_AddLine(line);
}
line++;
}
}
@ -3873,7 +3882,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
HWR_GetPatch(gpatch);
scalemul = FixedMul(FRACUNIT - floordiff/640, scale);
scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height);
scalemul = FixedMul(scalemul, (thing->radius*2) / SHORT(gpatch->height));
fscale = FIXED_TO_FLOAT(scalemul);
fx = FIXED_TO_FLOAT(thing->x);
@ -3885,9 +3894,9 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
// 0--1
if (thing && fabsf(fscale - 1.0f) > 1.0E-36f)
offset = (gpatch->height/2) * fscale;
offset = (SHORT(gpatch->height)/2) * fscale;
else
offset = (float)(gpatch->height/2);
offset = (float)(SHORT(gpatch->height)/2);
shadowVerts[0].x = shadowVerts[3].x = fx - offset;
shadowVerts[2].x = shadowVerts[1].x = fx + offset;
@ -3935,7 +3944,10 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
{
light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before
lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
if (*thing->subsector->sector->lightlist[light].lightlevel > 255)
lightlevel = 255;
else
lightlevel = *thing->subsector->sector->lightlist[light].lightlevel;
if (*thing->subsector->sector->lightlist[light].extra_colormap)
colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
@ -3959,7 +3971,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale
}
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts)
static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts, const boolean precip)
{
if (cv_grspritebillboarding.value
&& spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)
@ -3967,7 +3979,7 @@ static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts
{
float basey = FIXED_TO_FLOAT(spr->mobj->z);
float lowy = wallVerts[0].y;
if (P_MobjFlip(spr->mobj) == -1)
if (!precip && P_MobjFlip(spr->mobj) == -1) // precip doesn't have eflags so they can't flip
{
basey = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height);
}
@ -4080,7 +4092,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
}
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, baseWallVerts);
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
realtop = top = baseWallVerts[3].y;
realbot = bot = baseWallVerts[0].y;
@ -4135,7 +4147,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (h <= temp)
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i-1].lightlevel;
lightlevel = *list[i-1].lightlevel > 255 ? 255 : *list[i-1].lightlevel;
colormap = *list[i-1].extra_colormap;
break;
}
@ -4150,7 +4162,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *list[i].lightlevel;
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
colormap = *list[i].extra_colormap;
}
@ -4353,7 +4365,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
}
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, wallVerts);
HWR_RotateSpritePolyToAim(spr, wallVerts, false);
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components
@ -4366,7 +4378,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
extracolormap_t *colormap = sector->extra_colormap;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
@ -4437,7 +4449,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
wallVerts[1].z = wallVerts[2].z = spr->z2;
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, wallVerts);
HWR_RotateSpritePolyToAim(spr, wallVerts, true);
wallVerts[0].sow = wallVerts[3].sow = 0;
wallVerts[2].sow = wallVerts[1].sow = gpatch->max_s;
@ -4463,7 +4475,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap;
@ -4471,7 +4483,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
@ -5187,10 +5199,10 @@ static void HWR_ProjectSprite(mobj_t *thing)
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
@ -6292,7 +6304,6 @@ void HWR_Shutdown(void)
CONS_Printf("HWR_Shutdown()\n");
HWR_FreeExtraSubsectors();
HWR_FreePolyPool();
HWR_FreeMipmapCache();
HWR_FreeTextureCache();
HWD.pfnFlushScreenTextures();
}

View File

@ -1221,7 +1221,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
light = R_GetPlaneLight(sector, spr->mobj->z + spr->mobj->height, false); // Always use the light at the top instead of whatever I was doing before
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = *sector->lightlist[light].lightlevel;
lightlevel = *sector->lightlist[light].lightlevel > 255 ? 255 : *sector->lightlist[light].lightlevel;
if (*sector->lightlist[light].extra_colormap)
colormap = *sector->lightlist[light].extra_colormap;
@ -1229,7 +1229,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
else
{
if (!(spr->mobj->frame & FF_FULLBRIGHT))
lightlevel = sector->lightlevel;
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (sector->extra_colormap)
colormap = sector->extra_colormap;
@ -1478,7 +1478,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
// rotation axis
if (sprinfo->available)
@ -1490,6 +1490,9 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
p.rollflip = 1;
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
p.rollflip = -1;
if (flip)
p.rollflip *= -1;
}
p.anglex = 0.0f;

View File

@ -68,7 +68,7 @@ patch_t *nightsnum[10]; // 0-9
// Level title and credits fonts
patch_t *lt_font[LT_FONTSIZE];
patch_t *cred_font[CRED_FONTSIZE];
patch_t *ttlnum[20]; // act numbers (0-19)
patch_t *ttlnum[10]; // act numbers (0-9)
// Name tag fonts
patch_t *ntb_font[NT_FONTSIZE];
@ -243,7 +243,7 @@ void HU_LoadGraphics(void)
tallinfin = (patch_t *)W_CachePatchName("STTINFIN", PU_HUDGFX);
// cache act numbers for level titles
for (i = 0; i < 20; i++)
for (i = 0; i < 10; i++)
{
sprintf(buffer, "TTL%.2d", i);
ttlnum[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX);

View File

@ -85,7 +85,7 @@ extern patch_t *lt_font[LT_FONTSIZE];
extern patch_t *cred_font[CRED_FONTSIZE];
extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[20];
extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico;
extern patch_t *bflagico;

View File

@ -1423,6 +1423,7 @@ static void SOCK_ClearBans(void)
boolean I_InitTcpNetwork(void)
{
char serverhostname[255];
const char *urlparam = NULL;
boolean ret = false;
// initilize the OS's TCP/IP stack
if (!I_InitTcpDriver())
@ -1476,10 +1477,12 @@ boolean I_InitTcpNetwork(void)
ret = true;
}
else if (M_CheckParm("-connect"))
else if ((urlparam = M_GetUrlProtocolArg()) != NULL || M_CheckParm("-connect"))
{
if (M_IsNextParm())
strcpy(serverhostname, M_GetNextParm());
if (urlparam != NULL)
strlcpy(serverhostname, urlparam, sizeof(serverhostname));
else if (M_IsNextParm())
strlcpy(serverhostname, M_GetNextParm(), sizeof(serverhostname));
else
serverhostname[0] = 0; // assuming server in the LAN, use broadcast to detect it

View File

@ -36,10 +36,10 @@ typedef enum
*/
extern rendermode_t rendermode;
/** \brief hardware renderer loaded
/** \brief OpenGL state
0 = never loaded, 1 = loaded successfully, -1 = failed loading
*/
extern INT32 hwrenderloaded;
extern INT32 vid_opengl_state;
/** \brief use highcolor modes if true
*/
@ -49,11 +49,7 @@ extern boolean highcolor;
*/
void I_StartupGraphics(void);
/** \brief setup hardware mode
*/
void I_StartupHardwareGraphics(void);
/** \brief restore old video mode
/** \brief shutdown video mode
*/
void I_ShutdownGraphics(void);
@ -97,6 +93,14 @@ INT32 VID_SetMode(INT32 modenum);
*/
void VID_CheckRenderer(void);
/** \brief Load OpenGL mode
*/
void VID_StartupOpenGL(void);
/** \brief Checks if OpenGL loaded
*/
void VID_CheckGLLoaded(rendermode_t oldrender);
/** \brief The VID_GetModeName function
\param modenum video mode number

View File

@ -187,6 +187,8 @@ char sprnames[NUMSPRITES + 1][5] =
// Projectiles
"MISL",
"LASR", // GFZ3 laser
"LASF", // GFZ3 laser flames
"TORP", // Torpedo
"ENRG", // Energy ball
"MINE", // Skim mine
@ -2058,7 +2060,15 @@ state_t states[NUMSTATES] =
{SPR_MISL, FF_FULLBRIGHT, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_ROCKET}, // S_ROCKET
{SPR_MISL, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_LASER
{SPR_LASR, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_NULL}, // S_LASER
{SPR_LASR, FF_FULLBRIGHT|1, 2, {NULL}, 0, 0, S_NULL}, // S_LASER2
{SPR_LASR, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_NULL}, // S_LASERFLASH
{SPR_LASF, FF_FULLBRIGHT|0, 2, {NULL}, 0, 0, S_LASERFLAME2}, // S_LASERFLAME1
{SPR_LASF, FF_FULLBRIGHT|1, 1, {A_ChangeHeight}, 156*FRACUNIT, 3, S_LASERFLAME3}, // S_LASERFLAME2
{SPR_LASF, FF_FULLBRIGHT|2, 0, {A_ChangeHeight}, 32*FRACUNIT, 3, S_LASERFLAME4}, // S_LASERFLAME3
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|2, 4, {NULL}, 1, 2, S_LASERFLAME5}, // S_LASERFLAME4
{SPR_LASF, FF_ANIMATE|FF_PAPERSPRITE|FF_FULLBRIGHT|4, 28, {NULL}, 2, 2, S_NULL}, // S_LASERFLAME5
{SPR_TORP, 0, 1, {A_SmokeTrailer}, MT_SMOKE, 0, S_TORPEDO}, // S_TORPEDO
@ -5665,28 +5675,28 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EGGMOBILE_FIRE
-1, // doomednum
S_SPINFIRE1, // spawnstate
S_LASERFLAME1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
sfx_s3kc2s, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
sfx_s3k8d, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
8*FRACUNIT, // radius
14*FRACUNIT, // height
24*FRACUNIT, // radius
84*FRACUNIT, // height
0, // display offset
DMG_FIRE, // mass
1, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY|MF_FIRE, // flags
MF_NOGRAVITY|MF_FIRE|MF_PAIN, // flags
S_NULL // raisestate
},
@ -9637,8 +9647,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_LASERFLASH, // meleestate
S_LASER2, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
@ -9649,7 +9659,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
0, // mass
20, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY, // flags
MF_MISSILE|MF_NOGRAVITY, // flags
S_NULL // raisestate
},

View File

@ -165,6 +165,7 @@ void A_SetTics();
void A_SetRandomTics();
void A_ChangeColorRelative();
void A_ChangeColorAbsolute();
void A_Dye();
void A_MoveRelative();
void A_MoveAbsolute();
void A_Thrust();
@ -283,6 +284,7 @@ void A_RolloutRock();
void A_DragonbomberSpawn();
void A_DragonWing();
void A_DragonSegment();
void A_ChangeHeight();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 512
@ -450,6 +452,8 @@ typedef enum sprite
// Projectiles
SPR_MISL,
SPR_LASR, // GFZ3 laser
SPR_LASF, // GFZ3 laser flames
SPR_TORP, // Torpedo
SPR_ENRG, // Energy ball
SPR_MINE, // Skim mine
@ -2219,6 +2223,14 @@ typedef enum state
S_ROCKET,
S_LASER,
S_LASER2,
S_LASERFLASH,
S_LASERFLAME1,
S_LASERFLAME2,
S_LASERFLAME3,
S_LASERFLAME4,
S_LASERFLAME5,
S_TORPEDO,

View File

@ -218,10 +218,16 @@ static const char *GetUserdataUType(lua_State *L)
// or players[0].powers -> "player_t.powers"
static int lib_userdataType(lua_State *L)
{
int type;
lua_settop(L, 1); // pop everything except arg 1 (in case somebody decided to add more)
luaL_checktype(L, 1, LUA_TUSERDATA);
lua_pushstring(L, GetUserdataUType(L));
return 1;
type = lua_type(L, 1);
if (type == LUA_TLIGHTUSERDATA || type == LUA_TUSERDATA)
{
lua_pushstring(L, GetUserdataUType(L));
return 1;
}
else
return luaL_typerror(L, 1, "userdata");
}
static int lib_isPlayerAdmin(lua_State *L)
@ -2456,6 +2462,20 @@ static int lib_sStopSound(lua_State *L)
return 0;
}
static int lib_sStopSoundByID(lua_State *L)
{
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
sfxenum_t sound_id = luaL_checkinteger(L, 2);
//NOHUD
if (!origin)
return LUA_ErrInvalid(L, "mobj_t");
if (sound_id >= NUMSFX)
return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1);
S_StopSoundByID(origin, sound_id);
return 0;
}
static int lib_sChangeMusic(lua_State *L)
{
#ifdef MUSICSLOT_COMPATIBILITY
@ -3251,6 +3271,7 @@ static luaL_Reg lib[] = {
{"S_StartSound",lib_sStartSound},
{"S_StartSoundAtVolume",lib_sStartSoundAtVolume},
{"S_StopSound",lib_sStopSound},
{"S_StopSoundByID",lib_sStopSoundByID},
{"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic},
{"S_StopMusic",lib_sStopMusic},

View File

@ -80,9 +80,7 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
{
INT32 offset;
const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -90,7 +88,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset];
@ -133,7 +130,6 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th
}
plink = (polymaplink_t *)(plink->link.next);
}
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];

View File

@ -430,22 +430,8 @@ static int lib_cvRegisterVar(lua_State *L)
static int lib_cvFindVar(lua_State *L)
{
consvar_t *cv;
if (( cv = CV_FindVar(luaL_checkstring(L,1)) ))
{
lua_settop(L,1);/* We only want one argument in the stack. */
lua_pushlightuserdata(L, cv);/* Now the second value on stack. */
luaL_getmetatable(L, META_CVAR);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the cvar.
*/
lua_setmetatable(L,2);
lua_pushvalue(L,2);
return 1;
}
else
return 0;
LUA_PushLightUserdata(L, CV_FindVar(luaL_checkstring(L,1)), META_CVAR);
return 1;
}
// CONS_Printf for a single player

View File

@ -40,6 +40,7 @@ enum hook {
hook_JumpSpinSpecial,
hook_BotTiccmd,
hook_BotAI,
hook_BotRespawn,
hook_LinedefExecute,
hook_PlayerMsg,
hook_HurtMsg,
@ -91,6 +92,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages

View File

@ -52,6 +52,7 @@ const char *const hookNames[hook_MAX+1] = {
"JumpSpinSpecial",
"BotTiccmd",
"BotAI",
"BotRespawn",
"LinedefExecute",
"PlayerMsg",
"HurtMsg",
@ -80,9 +81,7 @@ struct hook_s
UINT16 id;
union {
mobjtype_t mt;
char *skinname;
char *musname;
char *funcname;
char *str;
} s;
boolean error;
};
@ -151,28 +150,16 @@ static int lib_addHook(lua_State *L)
break;
case hook_BotAI:
case hook_ShouldJingleContinue:
hook.s.skinname = NULL;
hook.s.str = NULL;
if (lua_isstring(L, 2))
{ // lowercase copy
const char *s = lua_tostring(L, 2);
char *p = hook.s.skinname = ZZ_Alloc(strlen(s)+1);
do {
*p = tolower(*s);
++p;
} while(*(++s));
*p = 0;
hook.s.str = Z_StrDup(lua_tostring(L, 2));
strlwr(hook.s.str);
}
break;
case hook_LinedefExecute: // Linedef executor functions
{ // uppercase copy
const char *s = luaL_checkstring(L, 2);
char *p = hook.s.funcname = ZZ_Alloc(strlen(s)+1);
do {
*p = toupper(*s);
++p;
} while(*(++s));
*p = 0;
}
hook.s.str = Z_StrDup(luaL_checkstring(L, 2));
strupr(hook.s.str);
break;
default:
break;
@ -1075,7 +1062,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_BotAI
|| (hookp->s.skinname && strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name)))
|| (hookp->s.str && strcmp(hookp->s.str, ((skin_t*)tails->skin)->name)))
continue;
if (lua_gettop(gL) == 0)
@ -1125,6 +1112,51 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
return hooked;
}
// Hook for B_CheckRespawn
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails)
{
hook_p hookp;
UINT8 shouldRespawn = 0; // 0 = default, 1 = force yes, 2 = force no.
if (!gL || !(hooksAvailable[hook_BotRespawn/8] & (1<<(hook_BotRespawn%8))))
return false;
lua_settop(gL, 0);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_BotRespawn)
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, sonic, META_MOBJ);
LUA_PushUserdata(gL, tails, META_MOBJ);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1))
{
if (lua_toboolean(gL, -1))
shouldRespawn = 1; // Force yes
else
shouldRespawn = 2; // Force no
}
lua_pop(gL, 1);
}
lua_settop(gL, 0);
return shouldRespawn;
}
// Hook for linedef executors
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
{
@ -1137,7 +1169,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector)
for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next)
{
if (strcmp(hookp->s.funcname, line->text))
if (strcmp(hookp->s.str, line->text))
continue;
if (lua_gettop(gL) == 0)
@ -1675,7 +1707,7 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_ShouldJingleContinue
|| (hookp->s.musname && strcmp(hookp->s.musname, musname)))
|| (hookp->s.str && strcmp(hookp->s.str, musname)))
continue;
if (lua_gettop(gL) == 0)

View File

@ -412,9 +412,9 @@ static int libd_cachePatch(lua_State *L)
HUDONLY
luapat = patchinfohead;
lumpnum = W_CheckNumForName(luaL_checkstring(L, 1));
lumpnum = W_CheckNumForLongName(luaL_checkstring(L, 1));
if (lumpnum == LUMPERROR)
lumpnum = W_GetNumForName("MISSING");
lumpnum = W_GetNumForLongName("MISSING");
for (i = 0; i < numluapatches; i++)
{
@ -454,7 +454,7 @@ static int libd_cachePatch(lua_State *L)
numluapatches++;
#else
HUDONLY
LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
LUA_PushUserdata(L, W_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
#endif
return 1;
}

View File

@ -388,10 +388,7 @@ static int lib_setSpriteInfo(lua_State *L)
lua_Integer i = 0;
const char *str = NULL;
if (lua_isnumber(L, 2))
{
i = lua_tointeger(L, 2);
i++; // shift index in case of missing rotsprite support
}
else
str = luaL_checkstring(L, 2);
@ -1634,7 +1631,6 @@ int LUA_InfoLib(lua_State *L)
lua_pushcfunction(L, lib_spriteinfolen);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_pushvalue(L, -1);
lua_setglobal(L, "spriteinfo");
luaL_newmetatable(L, META_LUABANKS);

View File

@ -2082,6 +2082,12 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->menuflags);
else if (fastcmp(field,"startrings"))
lua_pushinteger(L, header->startrings);
else if (fastcmp(field, "sstimer"))
lua_pushinteger(L, header->sstimer);
else if (fastcmp(field, "ssspheres"))
lua_pushinteger(L, header->ssspheres);
else if (fastcmp(field, "gravity"))
lua_pushfixed(L, header->gravity);
// TODO add support for reading numGradedMares and grades
else {
// Read custom vars now

View File

@ -441,9 +441,9 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
else // If it's not a .lua file, copy the lump name in too.
{
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
len += 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
len += 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
name = malloc(len+1);
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->fullname);
name[len] = '\0';
}
@ -568,6 +568,27 @@ fixed_t LUA_EvalMath(const char *word)
return res;
}
/*
LUA_PushUserdata but no userdata is created.
You can't invalidate it therefore.
*/
void LUA_PushLightUserdata (lua_State *L, void *data, const char *meta)
{
if (data)
{
lua_pushlightuserdata(L, data);
luaL_getmetatable(L, meta);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the userdata.
*/
lua_setmetatable(L, -2);
}
else
lua_pushnil(L);
}
// Takes a pointer, any pointer, and a metatable name
// Creates a userdata for that pointer with the given metatable
// Pushes it to the stack and stores it in the registry.
@ -709,9 +730,13 @@ void LUA_InvalidatePlayer(player_t *player)
enum
{
ARCH_NULL=0,
ARCH_BOOLEAN,
ARCH_SIGNED,
ARCH_STRING,
ARCH_TRUE,
ARCH_FALSE,
ARCH_INT8,
ARCH_INT16,
ARCH_INT32,
ARCH_SMALLSTRING,
ARCH_LARGESTRING,
ARCH_TABLE,
ARCH_MOBJINFO,
@ -796,22 +821,33 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
WRITEUINT8(save_p, ARCH_NULL);
return 2;
case LUA_TBOOLEAN:
WRITEUINT8(save_p, ARCH_BOOLEAN);
WRITEUINT8(save_p, lua_toboolean(gL, myindex));
WRITEUINT8(save_p, lua_toboolean(gL, myindex) ? ARCH_TRUE : ARCH_FALSE);
break;
case LUA_TNUMBER:
{
lua_Integer number = lua_tointeger(gL, myindex);
WRITEUINT8(save_p, ARCH_SIGNED);
WRITEFIXED(save_p, number);
if (number >= INT8_MIN && number <= INT8_MAX)
{
WRITEUINT8(save_p, ARCH_INT8);
WRITESINT8(save_p, number);
}
else if (number >= INT16_MIN && number <= INT16_MAX)
{
WRITEUINT8(save_p, ARCH_INT16);
WRITEINT16(save_p, number);
}
else
{
WRITEUINT8(save_p, ARCH_INT32);
WRITEFIXED(save_p, number);
}
break;
}
case LUA_TSTRING:
{
UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros
UINT32 len = (UINT32)lua_objlen(gL, myindex); // get length of string, including embedded zeros
const char *s = lua_tostring(gL, myindex);
UINT16 i = 0;
WRITEUINT8(save_p, ARCH_STRING);
UINT32 i = 0;
// if you're wondering why we're writing a string to save_p this way,
// it turns out that Lua can have embedded zeros ('\0') in the strings,
// so we can't use WRITESTRING as that cuts off when it finds a '\0'.
@ -819,7 +855,16 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
// fixing the awful crashes previously encountered for reading strings longer than 1024
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
// -- Monster Iestyn 05/08/18
WRITEUINT16(save_p, len); // save size of string
if (len < 255)
{
WRITEUINT8(save_p, ARCH_SMALLSTRING);
WRITEUINT8(save_p, len); // save size of string
}
else
{
WRITEUINT8(save_p, ARCH_LARGESTRING);
WRITEUINT32(save_p, len); // save size of string
}
while (i < len)
WRITECHAR(save_p, s[i++]); // write chars individually, including the embedded zeros
break;
@ -989,16 +1034,8 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
if (!rover)
WRITEUINT8(save_p, ARCH_NULL);
else {
ffloor_t *r2;
UINT16 i = 0;
// search for id
for (r2 = rover->target->ffloors; r2; r2 = r2->next)
{
if (r2 == rover)
break;
i++;
}
if (!r2)
UINT16 i = P_GetFFloorID(rover);
if (i == UINT16_MAX) // invalid ID
WRITEUINT8(save_p, ARCH_NULL);
else
{
@ -1157,21 +1194,36 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
case ARCH_NULL:
lua_pushnil(gL);
break;
case ARCH_BOOLEAN:
lua_pushboolean(gL, READUINT8(save_p));
case ARCH_TRUE:
lua_pushboolean(gL, true);
break;
case ARCH_SIGNED:
case ARCH_FALSE:
lua_pushboolean(gL, false);
break;
case ARCH_INT8:
lua_pushinteger(gL, READSINT8(save_p));
break;
case ARCH_INT16:
lua_pushinteger(gL, READINT16(save_p));
break;
case ARCH_INT32:
lua_pushinteger(gL, READFIXED(save_p));
break;
case ARCH_STRING:
case ARCH_SMALLSTRING:
case ARCH_LARGESTRING:
{
UINT16 len = READUINT16(save_p); // length of string, including embedded zeros
UINT32 len;
char *value;
UINT16 i = 0;
UINT32 i = 0;
// See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either)
// -- Monster Iestyn 05/08/18
if (type == ARCH_SMALLSTRING)
len = READUINT8(save_p); // length of string, including embedded zeros
else
len = READUINT32(save_p); // length of string, including embedded zeros
value = malloc(len); // make temp buffer of size len
// now read the actual string
while (i < len)

View File

@ -44,6 +44,7 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump);
void LUA_DumpFile(const char *filename);
#endif
fixed_t LUA_EvalMath(const char *word);
void LUA_PushLightUserdata(lua_State *L, void *data, const char *meta);
void LUA_PushUserdata(lua_State *L, void *data, const char *meta);
void LUA_InvalidateUserdata(void *data);
void LUA_InvalidateLevel(void);

View File

@ -490,29 +490,28 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by
static UINT8 *gifframe_data = NULL;
static size_t gifframe_size = 8192;
//
// GIF_rgbconvert
// converts an RGB frame to a frame with a palette.
//
#ifdef HWRENDER
static void hwrconvert(void)
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{
UINT8 *linear = HWR_GetScreenshot();
UINT8 *dest = screens[2];
UINT8 r, g, b;
INT32 x, y;
size_t i = 0;
size_t src = 0, dest = 0;
size_t size = (vid.width * vid.height * 3);
InitColorLUT(gif_framepalette);
for (y = 0; y < vid.height; y++)
while (src < size)
{
for (x = 0; x < vid.width; x++, i += 3)
{
r = (UINT8)linear[i];
g = (UINT8)linear[i + 1];
b = (UINT8)linear[i + 2];
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
}
r = (UINT8)linear[src];
g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2];
scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
src += (3 * scrbuf_downscaleamt);
dest += scrbuf_downscaleamt;
}
free(linear);
}
#endif
@ -556,7 +555,11 @@ static void GIF_framewrite(void)
I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
hwrconvert();
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, movie_screen);
free(linear);
}
#endif
}
else
@ -565,18 +568,20 @@ static void GIF_framewrite(void)
blitw = vid.width;
blith = vid.height;
if (gif_frames == 0)
{
if (rendermode == render_soft)
I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
hwrconvert();
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
}
#endif
// Copy the current OpenGL frame into the base screen
if (rendermode == render_opengl)
{
UINT8 *linear = HWR_GetScreenshot();
GIF_rgbconvert(linear, screens[0]);
free(linear);
}
#endif
// Copy the first frame into the movie screen
// OpenGL already does the same above.
if (gif_frames == 0 && rendermode == render_soft)
I_ReadScreen(movie_screen);
movie_screen = screens[0];
}

View File

@ -34,6 +34,25 @@ boolean myargmalloc = false;
*/
static INT32 found;
/** \brief Parses a server URL (such as srb2://127.0.0.1) as may be passed to the game via a web browser, etc.
\return the contents of the URL after the protocol (a server to join), or NULL if not found
*/
const char *M_GetUrlProtocolArg(void)
{
INT32 i;
const size_t len = strlen(SERVER_URL_PROTOCOL);
for (i = 1; i < myargc; i++)
{
if (strlen(myargv[i]) > len && !strnicmp(myargv[i], SERVER_URL_PROTOCOL, len))
{
return &myargv[i][len];
}
}
return NULL;
}
/** \brief The M_CheckParm function

View File

@ -21,6 +21,9 @@ extern INT32 myargc;
extern char **myargv;
extern boolean myargmalloc;
// Looks for an srb2:// (or similar) URL passed in as an argument and returns the IP to connect to if found.
const char *M_GetUrlProtocolArg(void);
// Returns the position of the given parameter in the arg list (0 if not found).
INT32 M_CheckParm(const char *check);

View File

@ -934,6 +934,12 @@ void Command_Setcontinues_f(void)
REQUIRE_NOULTIMATE;
REQUIRE_PANDORA;
if (!continuesInSession)
{
CONS_Printf(M_GetText("This session does not use continues.\n"));
return;
}
if (COM_Argc() > 1)
{
INT32 numcontinues = atoi(COM_Argv(1));

View File

@ -38,8 +38,20 @@ typedef INT32 fixed_t;
/*!
\brief convert fixed_t into floating number
*/
#define FIXED_TO_FLOAT(x) (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) (fixed_t)((f) * ((float)FRACUNIT))
FUNCMATH FUNCINLINE static ATTRINLINE float FixedToFloat(fixed_t x)
{
return x / (float)FRACUNIT;
}
FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FloatToFixed(float f)
{
return (fixed_t)(f * FRACUNIT);
}
// for backwards compat
#define FIXED_TO_FLOAT(x) FixedToFloat(x) // (((float)(x)) / ((float)FRACUNIT))
#define FLOAT_TO_FIXED(f) FloatToFixed(f) // (fixed_t)((f) * ((float)FRACUNIT))
#if defined (__WATCOMC__) && FRACBITS == 16

View File

@ -522,6 +522,8 @@ static menuitem_t MISC_AddonsMenu[] =
// ---------------------------------
static menuitem_t MAPauseMenu[] =
{
{IT_CALL | IT_STRING, NULL, "Emblem Hints...", M_EmblemHints, 32},
{IT_CALL | IT_STRING, NULL, "Continue", M_SelectableClearMenus,48},
{IT_CALL | IT_STRING, NULL, "Retry", M_ModeAttackRetry, 56},
{IT_CALL | IT_STRING, NULL, "Abort", M_ModeAttackEndGame, 64},
@ -529,6 +531,7 @@ static menuitem_t MAPauseMenu[] =
typedef enum
{
mapause_hints,
mapause_continue,
mapause_retry,
mapause_abort
@ -730,9 +733,9 @@ static menuitem_t SR_SoundTestMenu[] =
static menuitem_t SR_EmblemHintMenu[] =
{
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
{IT_WHITESTRING|IT_SUBMENU, NULL, "Back", &SPauseDef, 30}
{IT_STRING | IT_ARROWS, NULL, "Page", M_HandleEmblemHints, 10},
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 20},
{IT_WHITESTRING|IT_CALL, NULL, "Back", M_GoBack, 30}
};
// --------------------------------
@ -879,7 +882,8 @@ static menuitem_t SP_NightsAttackLevelSelectMenu[] =
static menuitem_t SP_NightsAttackMenu[] =
{
{IT_STRING|IT_KEYHANDLER, NULL, "Level Select...", &M_HandleTimeAttackLevelSelect, 52},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 62},
{IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 62},
{IT_STRING|IT_CVAR, NULL, "Show Records For", &cv_dummymares, 72},
{IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 100},
{IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 110},
@ -890,6 +894,7 @@ static menuitem_t SP_NightsAttackMenu[] =
enum
{
nalevel,
nachar,
narecords,
naguest,
@ -1580,7 +1585,7 @@ static menuitem_t OP_ServerOptionsMenu[] =
{IT_HEADER, NULL, "General", NULL, 0},
#ifndef NONET
{IT_STRING | IT_CVAR | IT_CV_STRING,
NULL, "Server name", &cv_servername, 7},
NULL, "Server name", &cv_servername, 7},
{IT_STRING | IT_CVAR, NULL, "Max Players", &cv_maxplayers, 21},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 26},
{IT_STRING | IT_CVAR, NULL, "Allow players to join", &cv_allownewplayer, 31},
@ -1625,8 +1630,9 @@ static menuitem_t OP_ServerOptionsMenu[] =
#ifndef NONET
{IT_HEADER, NULL, "Advanced", NULL, 225},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245},
{IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231},
{IT_STRING | IT_CVAR, NULL, "Join delay", &cv_joindelay, 246},
{IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 251},
#endif
};
@ -1698,7 +1704,7 @@ static INT32 highlightflags, recommendedflags, warningflags;
// Sky Room
menu_t SR_PandoraDef =
{
MN_SR_MAIN + (MN_SR_PANDORA << 6),
MTREE2(MN_SR_MAIN, MN_SR_PANDORA),
"M_PANDRA",
sizeof (SR_PandorasBox)/sizeof (menuitem_t),
&SPauseDef,
@ -1712,12 +1718,12 @@ menu_t SR_PandoraDef =
menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40);
menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SR_MAIN + (MN_SR_LEVELSELECT << 6),
MTREE2(MN_SR_MAIN, MN_SR_LEVELSELECT),
NULL, SR_LevelSelectMenu);
menu_t SR_UnlockChecklistDef =
{
MN_SR_MAIN + (MN_SR_UNLOCKCHECKLIST << 6),
MTREE2(MN_SR_MAIN, MN_SR_UNLOCKCHECKLIST),
"M_SECRET",
1,
&SR_MainDef,
@ -1730,7 +1736,7 @@ menu_t SR_UnlockChecklistDef =
menu_t SR_SoundTestDef =
{
MN_SR_MAIN + (MN_SR_SOUNDTEST << 6),
MTREE2(MN_SR_MAIN, MN_SR_SOUNDTEST),
NULL,
sizeof (SR_SoundTestMenu)/sizeof (menuitem_t),
&SR_MainDef,
@ -1743,7 +1749,7 @@ menu_t SR_SoundTestDef =
menu_t SR_EmblemHintDef =
{
MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6),
MTREE2(MN_SR_MAIN, MN_SR_EMBLEMHINT),
NULL,
sizeof (SR_EmblemHintMenu)/sizeof (menuitem_t),
&SPauseDef,
@ -1770,7 +1776,7 @@ menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
menu_t SP_LoadDef =
{
MN_SP_MAIN + (MN_SP_LOAD << 6),
MTREE2(MN_SP_MAIN, MN_SP_LOAD),
"M_PICKG",
1,
&SP_MainDef,
@ -1782,12 +1788,12 @@ menu_t SP_LoadDef =
};
menu_t SP_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12) + (MN_SP_LEVELSELECT << 18),
MTREE4(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER, MN_SP_LEVELSELECT),
NULL, SP_LevelSelectMenu);
menu_t SP_LevelStatsDef =
{
MN_SP_MAIN + (MN_SP_LEVELSTATS << 6),
MTREE2(MN_SP_MAIN, MN_SP_LEVELSTATS),
"M_STATS",
1,
&SP_MainDef,
@ -1799,12 +1805,12 @@ menu_t SP_LevelStatsDef =
};
menu_t SP_TimeAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_TIMEATTACK_LEVELSELECT << 12),
MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_TIMEATTACK_LEVELSELECT),
"M_ATTACK", SP_TimeAttackLevelSelectMenu);
static menu_t SP_TimeAttackDef =
{
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6),
MTREE2(MN_SP_MAIN, MN_SP_TIMEATTACK),
"M_ATTACK",
sizeof (SP_TimeAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter.
@ -1816,7 +1822,7 @@ static menu_t SP_TimeAttackDef =
};
static menu_t SP_ReplayDef =
{
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_REPLAY << 12),
MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_REPLAY),
"M_ATTACK",
sizeof(SP_ReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef,
@ -1828,7 +1834,7 @@ static menu_t SP_ReplayDef =
};
static menu_t SP_GuestReplayDef =
{
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GUESTREPLAY << 12),
MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GUESTREPLAY),
"M_ATTACK",
sizeof(SP_GuestReplayMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef,
@ -1840,7 +1846,7 @@ static menu_t SP_GuestReplayDef =
};
static menu_t SP_GhostDef =
{
MN_SP_MAIN + (MN_SP_TIMEATTACK << 6) + (MN_SP_GHOST << 12),
MTREE3(MN_SP_MAIN, MN_SP_TIMEATTACK, MN_SP_GHOST),
"M_ATTACK",
sizeof(SP_GhostMenu)/sizeof(menuitem_t),
&SP_TimeAttackDef,
@ -1852,12 +1858,12 @@ static menu_t SP_GhostDef =
};
menu_t SP_NightsAttackLevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_LEVELSELECT << 12),
MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_LEVELSELECT),
"M_NIGHTS", SP_NightsAttackLevelSelectMenu);
static menu_t SP_NightsAttackDef =
{
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6),
MTREE2(MN_SP_MAIN, MN_SP_NIGHTSATTACK),
"M_NIGHTS",
sizeof (SP_NightsAttackMenu)/sizeof (menuitem_t),
&MainDef, // Doesn't matter.
@ -1869,7 +1875,7 @@ static menu_t SP_NightsAttackDef =
};
static menu_t SP_NightsReplayDef =
{
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_REPLAY << 12),
MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_REPLAY),
"M_NIGHTS",
sizeof(SP_NightsReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef,
@ -1881,7 +1887,7 @@ static menu_t SP_NightsReplayDef =
};
static menu_t SP_NightsGuestReplayDef =
{
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GUESTREPLAY << 12),
MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GUESTREPLAY),
"M_NIGHTS",
sizeof(SP_NightsGuestReplayMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef,
@ -1893,7 +1899,7 @@ static menu_t SP_NightsGuestReplayDef =
};
static menu_t SP_NightsGhostDef =
{
MN_SP_MAIN + (MN_SP_NIGHTSATTACK << 6) + (MN_SP_NIGHTS_GHOST << 12),
MTREE3(MN_SP_MAIN, MN_SP_NIGHTSATTACK, MN_SP_NIGHTS_GHOST),
"M_NIGHTS",
sizeof(SP_NightsGhostMenu)/sizeof(menuitem_t),
&SP_NightsAttackDef,
@ -1907,7 +1913,7 @@ static menu_t SP_NightsGhostDef =
menu_t SP_PlayerDef =
{
MN_SP_MAIN + (MN_SP_LOAD << 6) + (MN_SP_PLAYER << 12),
MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER),
"M_PICKP",
sizeof (SP_PlayerMenu)/sizeof (menuitem_t),
&SP_MainDef,
@ -1922,7 +1928,7 @@ menu_t SP_PlayerDef =
menu_t MP_SplitServerDef =
{
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6),
MTREE2(MN_MP_MAIN, MN_MP_SPLITSCREEN),
"M_MULTI",
sizeof (MP_SplitServerMenu)/sizeof (menuitem_t),
#ifndef NONET
@ -1954,7 +1960,7 @@ menu_t MP_MainDef =
menu_t MP_ServerDef =
{
MN_MP_MAIN + (MN_MP_SERVER << 6),
MTREE2(MN_MP_MAIN, MN_MP_SERVER),
"M_MULTI",
sizeof (MP_ServerMenu)/sizeof (menuitem_t),
&MP_MainDef,
@ -1967,7 +1973,7 @@ menu_t MP_ServerDef =
menu_t MP_ConnectDef =
{
MN_MP_MAIN + (MN_MP_CONNECT << 6),
MTREE2(MN_MP_MAIN, MN_MP_CONNECT),
"M_MULTI",
sizeof (MP_ConnectMenu)/sizeof (menuitem_t),
&MP_MainDef,
@ -1980,7 +1986,7 @@ menu_t MP_ConnectDef =
menu_t MP_RoomDef =
{
MN_MP_MAIN + (MN_MP_ROOM << 6),
MTREE2(MN_MP_MAIN, MN_MP_ROOM),
"M_MULTI",
sizeof (MP_RoomMenu)/sizeof (menuitem_t),
&MP_ConnectDef,
@ -1995,9 +2001,9 @@ menu_t MP_RoomDef =
menu_t MP_PlayerSetupDef =
{
#ifdef NONET
MN_MP_MAIN + (MN_MP_PLAYERSETUP << 6),
MTREE2(MN_MP_MAIN, MN_MP_PLAYERSETUP),
#else
MN_MP_MAIN + (MN_MP_SPLITSCREEN << 6) + (MN_MP_PLAYERSETUP << 12),
MTREE3(MN_MP_MAIN, MN_MP_SPLITSCREEN, MN_MP_PLAYERSETUP),
#endif
"M_SPLAYR",
sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t),
@ -2013,12 +2019,13 @@ menu_t MP_PlayerSetupDef =
menu_t OP_MainDef = DEFAULTMENUSTYLE(
MN_OP_MAIN,
"M_OPTTTL", OP_MainMenu, &MainDef, 50, 30);
menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE(
MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime
MTREE3(MN_OP_MAIN, 0, MN_OP_CHANGECONTROLS), // second level set on runtime
OP_ChangeControlsMenu, &OP_MainDef);
menu_t OP_P1ControlsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6),
MTREE2(MN_OP_MAIN, MN_OP_P1CONTROLS),
"M_CONTRO",
sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef,
@ -2026,7 +2033,7 @@ menu_t OP_P1ControlsDef = {
M_DrawControlsDefMenu,
50, 30, 0, NULL};
menu_t OP_P2ControlsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6),
MTREE2(MN_OP_MAIN, MN_OP_P2CONTROLS),
"M_CONTRO",
sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t),
&OP_MainDef,
@ -2035,20 +2042,22 @@ menu_t OP_P2ControlsDef = {
50, 30, 0, NULL};
menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12),
MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1MOUSE),
"M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30);
menu_t OP_Mouse2OptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2MOUSE << 12),
MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2MOUSE),
"M_CONTRO", OP_Mouse2OptionsMenu, &OP_P2ControlsDef, 35, 30);
menu_t OP_Joystick1Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1JOYSTICK << 12),
MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1JOYSTICK),
"M_CONTRO", OP_Joystick1Menu, &OP_P1ControlsDef, 50, 30);
menu_t OP_Joystick2Def = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2JOYSTICK << 12),
MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2JOYSTICK),
"M_CONTRO", OP_Joystick2Menu, &OP_P2ControlsDef, 50, 30);
menu_t OP_JoystickSetDef =
{
MN_OP_MAIN + (MN_OP_JOYSTICKSET << MENUBITS*3), // second (<<6) and third level (<<12) set on runtime
MTREE4(MN_OP_MAIN, 0, 0, MN_OP_JOYSTICKSET), // second and third level set on runtime
"M_CONTRO",
sizeof (OP_JoystickSetMenu)/sizeof (menuitem_t),
&OP_Joystick1Def,
@ -2060,7 +2069,7 @@ menu_t OP_JoystickSetDef =
};
menu_t OP_CameraOptionsDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12),
MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_P1CAMERA),
"M_CONTRO",
sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t),
&OP_P1ControlsDef,
@ -2071,7 +2080,7 @@ menu_t OP_CameraOptionsDef = {
NULL
};
menu_t OP_Camera2OptionsDef = {
MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12),
MTREE3(MN_OP_MAIN, MN_OP_P2CONTROLS, MN_OP_P2CAMERA),
"M_CONTRO",
sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t),
&OP_P2ControlsDef,
@ -2085,7 +2094,7 @@ menu_t OP_Camera2OptionsDef = {
static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}};
menu_t OP_PlaystyleDef = {
MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12),
MTREE3(MN_OP_MAIN, MN_OP_P1CONTROLS, MN_OP_PLAYSTYLE), ///@TODO the second level should be set in runtime
NULL,
1,
&OP_P1ControlsDef,
@ -2098,7 +2107,7 @@ static void M_VideoOptions(INT32 choice)
{
(void)choice;
#ifdef HWRENDER
if (hwrenderloaded == -1)
if (vid_opengl_state == -1)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
@ -2111,7 +2120,7 @@ static void M_VideoOptions(INT32 choice)
menu_t OP_VideoOptionsDef =
{
MN_OP_MAIN + (MN_OP_VIDEO << 6),
MTREE2(MN_OP_MAIN, MN_OP_VIDEO),
"M_VIDEO",
sizeof (OP_VideoOptionsMenu)/sizeof (menuitem_t),
&OP_MainDef,
@ -2123,7 +2132,7 @@ menu_t OP_VideoOptionsDef =
};
menu_t OP_VideoModeDef =
{
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_VIDEOMODE << 12),
MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_VIDEOMODE),
"M_VIDEO",
1,
&OP_VideoOptionsDef,
@ -2135,7 +2144,7 @@ menu_t OP_VideoModeDef =
};
menu_t OP_ColorOptionsDef =
{
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_COLOR << 12),
MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_COLOR),
"M_VIDEO",
sizeof (OP_ColorOptionsMenu)/sizeof (menuitem_t),
&OP_VideoOptionsDef,
@ -2146,17 +2155,19 @@ menu_t OP_ColorOptionsDef =
NULL
};
menu_t OP_SoundOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_SOUND << 6),
MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(MN_OP_MAIN + (MN_OP_SOUND << 6), "M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
menu_t OP_SoundAdvancedDef = DEFAULTMENUSTYLE(
MTREE2(MN_OP_MAIN, MN_OP_SOUND),
"M_SOUND", OP_SoundAdvancedMenu, &OP_SoundOptionsDef, 30, 30);
menu_t OP_ServerOptionsDef = DEFAULTSCROLLMENUSTYLE(
MN_OP_MAIN + (MN_OP_SERVER << 6),
MTREE2(MN_OP_MAIN, MN_OP_SERVER),
"M_SERVER", OP_ServerOptionsMenu, &OP_MainDef, 30, 30);
menu_t OP_MonitorToggleDef =
{
MN_OP_MAIN + (MN_OP_SERVER << 6) + (MN_OP_MONITORTOGGLE << 12),
MTREE3(MN_OP_MAIN, MN_OP_SOUND, MN_OP_MONITORTOGGLE),
"M_SERVER",
sizeof (OP_MonitorToggleMenu)/sizeof (menuitem_t),
&OP_ServerOptionsDef,
@ -2177,16 +2188,16 @@ static void M_OpenGLOptionsMenu(void)
}
menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12),
MTREE3(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL),
"M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
#ifdef ALAM_LIGHTING
menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_LIGHTING << 18),
MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING),
"M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40);
#endif
menu_t OP_OpenGLFogDef =
{
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_FOG << 18),
MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG),
"M_VIDEO",
sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef,
@ -2198,12 +2209,12 @@ menu_t OP_OpenGLFogDef =
};
#endif
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6),
MTREE2(MN_OP_MAIN, MN_OP_DATA),
"M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
menu_t OP_ScreenshotOptionsDef =
{
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_SCREENSHOTS << 12),
MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_SCREENSHOTS),
"M_SCREEN",
sizeof (OP_ScreenshotOptionsMenu)/sizeof (menuitem_t),
&OP_DataOptionsDef,
@ -2215,11 +2226,11 @@ menu_t OP_ScreenshotOptionsDef =
};
menu_t OP_AddonsOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ADDONS << 12),
MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ADDONS),
"M_ADDONS", OP_AddonsOptionsMenu, &OP_DataOptionsDef, 30, 30);
menu_t OP_EraseDataDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_DATA << 6) + (MN_OP_ERASEDATA << 12),
MTREE3(MN_OP_MAIN, MN_OP_DATA, MN_OP_ERASEDATA),
"M_DATA", OP_EraseDataMenu, &OP_DataOptionsDef, 60, 30);
// ==========================================================================
@ -3634,6 +3645,7 @@ void M_StartControlPanel(void)
else if (modeattacking)
{
currentMenu = &MAPauseDef;
MAPauseMenu[mapause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
itemOn = mapause_continue;
}
else if (!(netgame || multiplayer)) // Single Player
@ -5074,6 +5086,17 @@ static boolean M_SetNextMapOnPlatter(void)
}
#endif
static boolean M_GametypeHasLevels(INT32 gt)
{
INT32 mapnum;
for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
if (M_CanShowLevelOnPlatter(mapnum, gt))
return true;
return false;
}
static INT32 M_CountRowsToShowOnPlatter(INT32 gt)
{
INT32 mapnum = 0, prevmapnum = 0, col = 0, rows = 0;
@ -5165,7 +5188,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick)
{
if (M_CanShowLevelOnPlatter(mapnum, gt))
{
const INT32 actnum = mapheaderinfo[mapnum]->actnum;
const UINT8 actnum = mapheaderinfo[mapnum]->actnum;
const boolean headingisname = (fastcmp(mapheaderinfo[mapnum]->selectheading, mapheaderinfo[mapnum]->lvlttl));
const boolean wide = (mapheaderinfo[mapnum]->menuflags & LF2_WIDEICON);
@ -5391,7 +5414,10 @@ static void M_HandleLevelPlatter(INT32 choice)
case KEY_RIGHTARROW:
if (levellistmode == LLM_CREATESERVER && !lsrow)
{
CV_AddValue(&cv_newgametype, 1);
INT32 startinggametype = cv_newgametype.value;
do
CV_AddValue(&cv_newgametype, 1);
while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value));
S_StartSound(NULL,sfx_menu1);
lscol = 0;
@ -5420,7 +5446,10 @@ static void M_HandleLevelPlatter(INT32 choice)
case KEY_LEFTARROW:
if (levellistmode == LLM_CREATESERVER && !lsrow)
{
CV_AddValue(&cv_newgametype, -1);
INT32 startinggametype = cv_newgametype.value;
do
CV_AddValue(&cv_newgametype, -1);
while (cv_newgametype.value != startinggametype && !M_GametypeHasLevels(cv_newgametype.value));
S_StartSound(NULL,sfx_menu1);
lscol = 0;
@ -6707,6 +6736,7 @@ static void M_PandorasBox(INT32 choice)
else
CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1));
CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues);
SR_PandorasBox[3].status = (continuesInSession) ? (IT_STRING | IT_CVAR) : (IT_GRAYEDOUT);
SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL);
M_SetupNextMenu(&SR_PandoraDef);
@ -6723,7 +6753,7 @@ static boolean M_ExitPandorasBox(void)
}
if (cv_dummylives.value != players[consoleplayer].lives)
COM_ImmedExecute(va("setlives %d", cv_dummylives.value));
if (cv_dummycontinues.value != players[consoleplayer].continues)
if (continuesInSession && cv_dummycontinues.value != players[consoleplayer].continues)
COM_ImmedExecute(va("setcontinues %d", cv_dummycontinues.value));
return true;
}
@ -7287,6 +7317,7 @@ static void M_EmblemHints(INT32 choice)
SR_EmblemHintMenu[0].status = (local > NUMHINTS*2) ? (IT_STRING | IT_ARROWS) : (IT_DISABLED);
SR_EmblemHintMenu[1].status = (M_SecretUnlocked(SECRET_ITEMFINDER)) ? (IT_CVAR|IT_STRING) : (IT_SECRET);
hintpage = 1;
SR_EmblemHintDef.prevMenu = currentMenu;
M_SetupNextMenu(&SR_EmblemHintDef);
itemOn = 2; // always start on back.
}
@ -7967,12 +7998,20 @@ static void M_CustomLevelSelect(INT32 choice)
static void M_SinglePlayerMenu(INT32 choice)
{
(void)choice;
SP_MainMenu[sptutorial].status =
tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
SP_MainMenu[sprecordattack].status =
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
SP_MainMenu[spnightsmode].status =
(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
levellistmode = LLM_RECORDATTACK;
if (M_GametypeHasLevels(-1))
SP_MainMenu[sprecordattack].status = (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
else
SP_MainMenu[sprecordattack].status = IT_NOTHING|IT_DISABLED;
levellistmode = LLM_NIGHTSATTACK;
if (M_GametypeHasLevels(-1))
SP_MainMenu[spnightsmode].status = (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
else
SP_MainMenu[spnightsmode].status = IT_NOTHING|IT_DISABLED;
SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
M_SetupNextMenu(&SP_MainDef);
}
@ -8234,9 +8273,19 @@ static void M_DrawLoadGameData(void)
V_DrawRightAlignedThinString(x + 79, y, V_YELLOWMAP, savegameinfo[savetodraw].levelname);
}
if ((savegameinfo[savetodraw].lives == -42)
|| (savegameinfo[savetodraw].lives == -666))
if (savegameinfo[savetodraw].lives == -42)
{
if (!useContinues)
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_GRAYMAP, "00000000");
continue;
}
if (savegameinfo[savetodraw].lives == -666)
{
if (!useContinues)
V_DrawRightAlignedThinString(x + 80, y+1+60+16, V_REDMAP, "????????");
continue;
}
y += 64;
@ -8253,7 +8302,7 @@ static void M_DrawLoadGameData(void)
y -= 4;
// character heads, lives, and continues
// character heads, lives, and continues/score
{
spritedef_t *sprdef;
spriteframe_t *sprframe;
@ -8304,10 +8353,14 @@ skipbot:
skipsign:
y += 16;
tempx = x + 10;
if (savegameinfo[savetodraw].lives != INFLIVES
&& savegameinfo[savetodraw].lives > 9)
tempx -= 4;
tempx = x;
if (useContinues)
{
tempx += 10;
if (savegameinfo[savetodraw].lives != INFLIVES
&& savegameinfo[savetodraw].lives > 9)
tempx -= 4;
}
if (!charskin) // shut up compiler
goto skiplife;
@ -8337,22 +8390,45 @@ skiplife:
else
V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives));
tempx = x + 47;
if (savegameinfo[savetodraw].continues > 9)
tempx -= 4;
// continues
if (savegameinfo[savetodraw].continues > 0)
if (!useContinues)
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues));
INT32 workingscorenum = savegameinfo[savetodraw].continuescore;
char workingscorestr[11] = " 000000000\0";
SINT8 j = 9;
// Change the above two lines if MAXSCORE ever changes from 8 digits long.
workingscorestr[0] = '\x86'; // done here instead of in initialiser 'cuz compiler complains
if (!workingscorenum)
j--; // just so ONE digit is not greyed out
else
{
while (workingscorenum)
{
workingscorestr[j--] = '0' + (workingscorenum % 10);
workingscorenum /= 10;
}
}
workingscorestr[j] = (savegameinfo[savetodraw].continuescore == MAXSCORE) ? '\x83' : '\x80';
V_DrawRightAlignedThinString(x + 80, y+1, 0, workingscorestr);
}
else
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH));
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
tempx = x + 47;
if (savegameinfo[savetodraw].continuescore > 9)
tempx -= 4;
// continues
if (savegameinfo[savetodraw].continuescore > 0)
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continuescore));
}
else
{
V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH));
V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH));
V_DrawString(tempx + 16, y, V_GRAYMAP, "0");
}
}
}
}
@ -8485,9 +8561,11 @@ static void M_ReadSavegameInfo(UINT32 slot)
CHECKPOS
savegameinfo[slot].lives = READSINT8(save_p); // lives
CHECKPOS
(void)READINT32(save_p); // Score
savegameinfo[slot].continuescore = READINT32(save_p); // score
CHECKPOS
savegameinfo[slot].continues = READINT32(save_p); // continues
fake = READINT32(save_p); // continues
if (useContinues)
savegameinfo[slot].continuescore = fake;
// File end marker check
CHECKPOS
@ -8869,16 +8947,11 @@ static void M_SetupChoosePlayer(INT32 choice)
/* the menus suck -James */
if (currentMenu == &SP_LoadDef)/* from save states */
{
SP_PlayerDef.menuid =
MN_SP_MAIN +
( MN_SP_LOAD << 6 ) +
( MN_SP_PLAYER << 12 );
SP_PlayerDef.menuid = MTREE3(MN_SP_MAIN, MN_SP_LOAD, MN_SP_PLAYER);
}
else/* from Secret level select */
{
SP_PlayerDef.menuid =
MN_SR_MAIN +
( MN_SR_PLAYER << 6 );
SP_PlayerDef.menuid = MTREE2(MN_SR_MAIN, MN_SR_PLAYER);
}
SP_PlayerDef.prevMenu = currentMenu;
@ -9024,7 +9097,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
col = Color_Opposite[charskin->prefcolor - 1][0];
// Make the translation colormap
colormap = R_GetTranslationColormap(TC_DEFAULT, col, 0);
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_CACHE);
// Don't render the title map
hidetitlemap = true;
@ -9100,8 +9173,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, curtextcolor, 0),
R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, 0),
R_GetTranslationColormap(TC_DEFAULT, curtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, curoutlinecolor, GTC_CACHE),
curtext
);
}
@ -9133,8 +9206,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, 0),
R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, 0),
R_GetTranslationColormap(TC_DEFAULT, prevtextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, prevoutlinecolor, GTC_CACHE),
prevtext
);
}
@ -9163,8 +9236,8 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
V_DrawNameTag(
x, y, V_CENTERNAMETAG, FRACUNIT,
R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, 0),
R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, 0),
R_GetTranslationColormap(TC_DEFAULT, nexttextcolor, GTC_CACHE),
R_GetTranslationColormap(TC_DEFAULT, nextoutlinecolor, GTC_CACHE),
nexttext
);
}
@ -10752,7 +10825,8 @@ static void M_ServerOptions(INT32 choice)
OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading
OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join
OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server
OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise
OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Minimum delay between joins
OP_ServerOptionsMenu[37].status = IT_GRAYEDOUT; // Attempts to resynchronise
}
else
{
@ -10764,14 +10838,15 @@ static void M_ServerOptions(INT32 choice)
? IT_GRAYEDOUT
: (IT_STRING | IT_CVAR | IT_CV_STRING));
OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR;
OP_ServerOptionsMenu[37].status = IT_STRING | IT_CVAR;
}
#endif
/* Disable fading because of different menu head. */
if (currentMenu == &OP_MainDef)/* from Options menu */
OP_ServerOptionsDef.menuid = MN_OP_MAIN + ( MN_OP_SERVER << 6 );
OP_ServerOptionsDef.menuid = MTREE2(MN_OP_MAIN, MN_OP_SERVER);
else/* from Multiplayer menu */
OP_ServerOptionsDef.menuid = MN_MP_MAIN + ( MN_MP_SERVER_OPTIONS << 6 );
OP_ServerOptionsDef.menuid = MTREE2(MN_MP_MAIN, MN_MP_SERVER_OPTIONS);
OP_ServerOptionsDef.prevMenu = currentMenu;
M_SetupNextMenu(&OP_ServerOptionsDef);
@ -11688,8 +11763,8 @@ static void M_Setup1PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_CALL|IT_STRING2;
OP_ChangeControlsDef.prevMenu = &OP_P1ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6)
OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine first level (<< 6)
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P1CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef);
}
@ -11719,8 +11794,8 @@ static void M_Setup2PControlsMenu(INT32 choice)
OP_ChangeControlsMenu[27+3].status = IT_GRAYEDOUT2;
OP_ChangeControlsDef.prevMenu = &OP_P2ControlsDef;
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove first level (<< 6)
OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine first level (<< 6)
OP_ChangeControlsDef.menuid &= ~(((1 << MENUBITS) - 1) << MENUBITS); // remove second level
OP_ChangeControlsDef.menuid |= MN_OP_P2CONTROLS << MENUBITS; // combine second level
M_SetupNextMenu(&OP_ChangeControlsDef);
}

View File

@ -31,6 +31,9 @@
#define MENUBITS 6
// Menu IDs sectioned by numeric places to signify hierarchy
/**
* IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH.
*/
typedef enum
{
MN_NONE,
@ -129,6 +132,9 @@ typedef enum
MN_SPECIAL,
NUMMENUTYPES,
} menutype_t; // up to 63; MN_SPECIAL = 53
#define MTREE2(a,b) (a | (b<<MENUBITS))
#define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c))
#define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d))
typedef struct
{
@ -397,7 +403,7 @@ typedef struct
UINT8 numemeralds;
UINT8 numgameovers;
INT32 lives;
INT32 continues;
INT32 continuescore;
INT32 gamemap;
} saveinfo_t;

View File

@ -68,7 +68,7 @@ extern consvar_t cv_masterserver, cv_servername;
// < 0 to not connect (usually -1) (offline mode)
// == 0 to show all rooms, not a valid hosting room
// anything else is whatever room the MS assigns to that number (online mode)
INT16 ms_RoomId;
extern INT16 ms_RoomId;
const char *GetMasterServerPort(void);
const char *GetMasterServerIP(void);

View File

@ -47,8 +47,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
case 0: // IN STASIS
break;
case 1: // UP
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false,
1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
@ -159,8 +158,7 @@ void T_MoveCeiling(ceiling_t *ceiling)
break;
case -1: // DOWN
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
ceiling->crush, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
if (ceiling->type == bounceCeiling)
{
@ -314,11 +312,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce)
{
// Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, 0, -ceiling->direction);
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight-(ceiling->topheight-ceiling->bottomheight), false, false, -ceiling->direction);
}
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight,
false, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false, true, ceiling->direction);
if (res == pastdest)
{
@ -357,11 +354,10 @@ void T_CrushCeiling(ceiling_t *ceiling)
if (ceiling->type == crushBothOnce)
{
// Move the floor
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, 0, -ceiling->direction);
T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, false, -ceiling->direction);
}
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight,
ceiling->crush, 1, ceiling->direction);
res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush, true, ceiling->direction);
if (res == pastdest)
{
@ -399,7 +395,7 @@ INT32 EV_DoCeiling(line_t *line, ceiling_e type)
sector_t *sec;
ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{
sec = &sectors[secnum];
@ -619,7 +615,7 @@ INT32 EV_DoCrush(line_t *line, ceiling_e type)
sector_t *sec;
ceiling_t *ceiling;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
while ((secnum = P_FindSectorFromTag(line->tag,secnum)) >= 0)
{
sec = &sectors[secnum];

View File

@ -189,6 +189,7 @@ void A_SetTics(mobj_t *actor);
void A_SetRandomTics(mobj_t *actor);
void A_ChangeColorRelative(mobj_t *actor);
void A_ChangeColorAbsolute(mobj_t *actor);
void A_Dye(mobj_t *actor);
void A_MoveRelative(mobj_t *actor);
void A_MoveAbsolute(mobj_t *actor);
void A_Thrust(mobj_t *actor);
@ -311,6 +312,7 @@ void A_RolloutRock(mobj_t *actor);
void A_DragonbomberSpawn(mobj_t *actor);
void A_DragonWing(mobj_t *actor);
void A_DragonSegment(mobj_t *actor);
void A_ChangeHeight(mobj_t *actor);
//for p_enemy.c
@ -2989,6 +2991,19 @@ void A_Boss1Laser(mobj_t *actor)
angle_t angle;
mobj_t *point;
tic_t dur;
static const UINT8 LASERCOLORS[] =
{
SKINCOLOR_SUPERRED3,
SKINCOLOR_SUPERRED4,
SKINCOLOR_SUPERRED5,
SKINCOLOR_FLAME,
SKINCOLOR_RED,
SKINCOLOR_RED,
SKINCOLOR_FLAME,
SKINCOLOR_SUPERRED5,
SKINCOLOR_SUPERRED4,
SKINCOLOR_SUPERRED3,
};
if (LUA_CallAction("A_Boss1Laser", actor))
return;
@ -3063,7 +3078,7 @@ void A_Boss1Laser(mobj_t *actor)
point = P_SpawnMobj(x, y, z, locvar1);
P_SetTarget(&point->target, actor);
point->angle = actor->angle;
speed = point->radius*2;
speed = point->radius;
point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed);
point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed));
point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed));
@ -3072,23 +3087,69 @@ void A_Boss1Laser(mobj_t *actor)
{
mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type);
mo->angle = point->angle;
mo->color = LASERCOLORS[((UINT8)(i + 3*dur) >> 2) % sizeof(LASERCOLORS)]; // codeing
P_UnsetThingPosition(mo);
mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
mo->flags = MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
P_SetThingPosition(mo);
if (dur & 1 && mo->info->missilestate)
{
P_SetMobjState(mo, mo->info->missilestate);
if (mo->info->meleestate)
{
mobj_t *mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE);
mo2->flags2 |= MF2_LINKDRAW;
P_SetTarget(&mo2->tracer, actor);
P_SetMobjState(mo2, mo->info->meleestate);
}
}
if (dur == 1)
P_SpawnGhostMobj(mo);
x = point->x, y = point->y, z = point->z;
if (P_RailThinker(point))
break;
}
x += point->momx;
y += point->momy;
floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height);
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1)
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1 && dur & 1)
{
point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE);
point = P_SpawnMobj(x, y, floorz, MT_EGGMOBILE_FIRE);
point->angle = actor->angle;
point->destscale = actor->scale;
P_SetScale(point, point->destscale);
P_SetTarget(&point->target, actor);
point->destscale = 3*FRACUNIT;
point->scalespeed = FRACUNIT>>2;
point->fuse = TICRATE;
P_MobjCheckWater(point);
if (point->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))
{
for (i = 0; i < 2; i++)
{
UINT8 size = 3;
mobj_t *steam = P_SpawnMobj(x, y, point->watertop - size*mobjinfo[MT_DUST].height, MT_DUST);
P_SetScale(steam, size*actor->scale);
P_SetObjectMomZ(steam, FRACUNIT + 2*P_RandomFixed(), true);
P_InstaThrust(steam, FixedAngle(P_RandomKey(360)*FRACUNIT), 2*P_RandomFixed());
if (point->info->painsound)
S_StartSound(steam, point->info->painsound);
}
}
else
{
fixed_t distx = P_ReturnThrustX(point, point->angle, point->radius);
fixed_t disty = P_ReturnThrustY(point, point->angle, point->radius);
if (P_TryMove(point, point->x + distx, point->y + disty, false) // prevents the sprite from clipping into the wall or dangling off ledges
&& P_TryMove(point, point->x - 2*distx, point->y - 2*disty, false)
&& P_TryMove(point, point->x + distx, point->y + disty, false))
{
if (point->info->seesound)
S_StartSound(point, point->info->seesound);
}
else
P_RemoveMobj(point);
}
}
if (dur > 1)
@ -8773,6 +8834,40 @@ void A_ChangeColorAbsolute(mobj_t *actor)
actor->color = (UINT8)locvar2;
}
// Function: A_Dye
//
// Description: Colorizes an object.
//
// var1 = if (var1 != 0), dye your target instead of yourself
// var2 = color value to dye
//
void A_Dye(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *target = ((locvar1 && actor->target) ? actor->target : actor);
UINT8 color = (UINT8)locvar2;
if (LUA_CallAction("A_Dye", actor))
return;
if (color >= MAXTRANSLATIONS)
return;
if (!color)
target->colorized = false;
else
target->colorized = true;
// What if it's a player?
if (target->player)
{
target->player->powers[pw_dye] = color;
return;
}
target->color = color;
}
// Function: A_MoveRelative
//
// Description: Moves an object (wrapper for P_Thrust)
@ -13274,8 +13369,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
P_ResetPlayer(player);
A_PlayActiveSound(dustdevil);
}
player->powers[pw_carry] = CR_DUSTDEVIL;
player->powers[pw_nocontrol] = 2;
player->drawangle += ANG20;
P_SetTarget(&thing->tracer, dustdevil);
P_SetPlayerMobjState(thing, S_PLAY_PAIN);
if (dist > dragamount)
@ -13295,7 +13391,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
P_ResetPlayer(player);
thing->z = dustdevil->z + dustdevil->height;
thrust = 20 * FRACUNIT;
player->powers[pw_carry] = CR_NONE;
player->powers[pw_nocontrol] = 0;
P_SetTarget(&thing->tracer, NULL);
S_StartSound(thing, sfx_wdjump);
P_SetPlayerMobjState(thing, S_PLAY_FALL);
}
@ -14372,3 +14470,43 @@ void A_DragonSegment(mobj_t *actor)
actor->angle = hangle;
P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist);
}
// Function: A_ChangeHeight
//
// Description: Changes the actor's height by var1
//
// var1 = height
// var2 =
// &1: height is absolute
// &2: scale with actor's scale
//
void A_ChangeHeight(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
fixed_t height = locvar1;
boolean reverse;
if (LUA_CallAction("A_ChangeHeight", actor))
return;
reverse = (actor->eflags & MFE_VERTICALFLIP) || (actor->flags2 & MF2_OBJECTFLIP);
if (locvar2 & 2)
height = FixedMul(height, actor->scale);
P_UnsetThingPosition(actor);
if (locvar2 & 1)
{
if (reverse)
actor->z += actor->height - locvar1;
actor->height = locvar1;
}
else
{
if (reverse)
actor->z -= locvar1;
actor->height += locvar1;
}
P_SetThingPosition(actor);
}

File diff suppressed because it is too large Load Diff

View File

@ -633,7 +633,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (ALL7EMERALDS(emeralds)) // Got all 7
{
if (!(netgame || multiplayer))
if (continuesInSession)
{
player->continues += 1;
player->gotcontinue = true;
@ -643,7 +643,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, sfx_chchng);
}
else
{
P_GiveCoopLives(player, 1, true); // if continues are disabled, a life is a reasonable substitute
S_StartSound(toucher, sfx_chchng);
}
}
else
{
@ -3150,7 +3153,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
return false;
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype()))
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
{
if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
{

View File

@ -2157,7 +2157,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{
validcount++;
@ -2229,7 +2228,6 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
}
}
}
#endif
// tmfloorthing is set when tmfloorz comes from a thing's top
tmfloorthing = NULL;
@ -2387,7 +2385,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
BMBOUNDFIX(xl, xh, yl, yh);
#ifdef POLYOBJECTS
// Check polyobjects and see if tmfloorz/tmceilingz need to be altered
{
validcount++;
@ -2458,7 +2455,6 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
}
}
}
#endif
// check lines
for (bx = xl; bx <= xh; bx++)
@ -4192,21 +4188,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
{
//If the thing was crushed by a crumbling FOF, reward the player who made it crumble!
thinker_t *think;
elevator_t *crumbler;
crumble_t *crumbler;
for (think = thlist[THINK_MAIN].next; think != &thlist[THINK_MAIN]; think = think->next)
{
if (think->function.acp1 != (actionf_p1)T_StartCrumble)
continue;
crumbler = (elevator_t *)think;
crumbler = (crumble_t *)think;
if (crumbler->player && crumbler->player->mo
&& crumbler->player->mo != thing
&& crumbler->actionsector == thing->subsector->sector
&& crumbler->sector == rover->master->frontsector
&& (crumbler->type == elevateBounce
|| crumbler->type == elevateContinuous))
&& crumbler->sector == rover->master->frontsector)
{
killer = crumbler->player->mo;
}

View File

@ -439,7 +439,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
I_Assert(back != NULL);
openfloorrover = openceilingrover = NULL;
#ifdef POLYOBJECTS
if (linedef->polyobj)
{
// set these defaults so that polyobjects don't interfere with collision above or below them
@ -450,7 +449,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
opentopslope = openbottomslope = NULL;
}
else
#endif
{ // Set open and high/low values here
fixed_t frontheight, backheight;
@ -505,7 +503,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
texheight = textures[texnum]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries
#if 0 // #ifdef POLYOBJECTS
#if 0
// don't remove this code unless solid midtextures
// on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
@ -548,7 +546,6 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
}
}
}
#ifdef POLYOBJECTS
if (linedef->polyobj)
{
// Treat polyobj's backsector like a 3D Floor
@ -585,94 +582,95 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
// otherwise don't do anything special, pretend there's nothing else there
}
else
#endif
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{
ffloor_t *rover;
fixed_t delta1, delta2;
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
// Check for fake floors in the sector.
if (front->ffloors || back->ffloors)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
ffloor_t *rover;
fixed_t delta1, delta2;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
// Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next)
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
// Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
else if (topheight > lowfloor)
lowfloor = topheight;
}
}
// Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if (mobj->player && (P_CheckSolidLava(rover) || P_CanRunOnWater(mobj->player, rover)))
;
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue;
topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF
{
if (bottomheight < opentop) {
opentop = bottomheight;
opentopslope = *rover->b_slope;
openceilingrover = rover;
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
}
else if (bottomheight < highceiling)
highceiling = bottomheight;
}
if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF
{
if (topheight > openbottom) {
openbottom = topheight;
openbottomslope = *rover->t_slope;
openfloorrover = rover;
}
else if (topheight > lowfloor)
lowfloor = topheight;
}
}
}
@ -922,9 +920,7 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
{
INT32 offset;
const INT32 *list; // Big blockmap
#ifdef POLYOBJECTS
polymaplink_t *plink; // haleyjd 02/22/06
#endif
line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
@ -932,7 +928,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
offset = y*bmapwidth + x;
#ifdef POLYOBJECTS
// haleyjd 02/22/06: consider polyobject lines
plink = polyblocklinks[offset];
@ -956,7 +951,6 @@ boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean (*func)(line_t *))
}
plink = (polymaplink_t *)(plink->link.next);
}
#endif
offset = *(blockmap + offset); // offset = blockmap[y*bmapwidth+x];

View File

@ -1686,7 +1686,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
// Needs ML_EFFECT4 flag for pushables to break it
if (!(rover->master->flags & ML_EFFECT4)) continue;
if (!rover->master->frontsector->crumblestate)
if (rover->master->frontsector->crumblestate == CRUMBLE_NONE)
{
topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
@ -2890,7 +2890,6 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->eflags |= MFE_JUSTHITFLOOR; // Spin Attack
{
#ifdef POLYOBJECTS
// Check if we're on a polyobject
// that triggers a linedef executor.
msecnode_t *node;
@ -2950,8 +2949,6 @@ static void P_PlayerZMovement(mobj_t *mo)
}
if (!stopmovecut)
#endif
// Cut momentum in half when you hit the ground and
// aren't pressing any controls.
if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
@ -7026,8 +7023,7 @@ static void P_MobjScaleThink(mobj_t *mobj)
fixed_t oldheight = mobj->height;
UINT8 correctionType = 0; // Don't correct Z position, just gain height
if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz))
&& mobj->type != MT_EGGMOBILE_FIRE)
if (mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz))
correctionType = 1; // Correct Z position by centering
else if (mobj->eflags & MFE_VERTICALFLIP)
correctionType = 2; // Correct Z position by moving down
@ -7048,10 +7044,6 @@ static void P_MobjScaleThink(mobj_t *mobj)
/// \todo Lua hook for "reached destscale"?
switch (mobj->type)
{
case MT_EGGMOBILE_FIRE:
mobj->destscale = FRACUNIT;
mobj->scalespeed = FRACUNIT>>4;
break;
default:
break;
}
@ -8227,6 +8219,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj)
// See Linedef Exec 457 (Track mobj angle to point)
static void P_TracerAngleThink(mobj_t *mobj)
{
angle_t looking;
angle_t ang;
if (!mobj->tracer)
@ -8241,7 +8234,12 @@ static void P_TracerAngleThink(mobj_t *mobj)
// mobj->cvval - Allowable failure delay
// mobj->cvmem - Failure timer
ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
if (mobj->player)
looking = ( mobj->player->cmd.angleturn << 16 );/* fixes CS_LMAOGALOG */
else
looking = mobj->angle;
ang = looking - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
// \todo account for distance between mobj and tracer
// Because closer mobjs can be facing beyond the angle tolerance
@ -9250,8 +9248,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0
&& P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16)
{
var1 = mobj->info->speed;
var2 = 1;
// Home in on the target.
P_HomingAttack(mobj, mobj->tracer);
A_HomingChase(mobj);
if (mobj->z < mobj->floorz)
mobj->z = mobj->floorz;
@ -11564,7 +11565,7 @@ void P_MovePlayerToStarpost(INT32 playernum)
mapthing_t *huntemeralds[MAXHUNTEMERALDS];
INT32 numhuntemeralds;
static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip)
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip)
{
const subsector_t *ss = R_PointInSubsector(x, y);
@ -11579,7 +11580,7 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x,
return P_GetSectorFloorZAt(ss->sector, x, y) + offset;
}
static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
{
fixed_t offset = mthing->z << FRACBITS;
boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
@ -11619,6 +11620,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin
// Ring-like items, may float additional units with MTF_AMBUSH.
case MT_SPIKEBALL:
case MT_EMERHUNT:
case MT_EMERALDSPAWN:
case MT_TOKEN:
case MT_EMBLEM:

View File

@ -451,6 +451,9 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing);
void P_MovePlayerToStarpost(INT32 playernum);
void P_AfterPlayerSpawn(INT32 playernum);
fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip);
fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y);
mobj_t *P_SpawnMapThing(mapthing_t *mthing);
void P_SpawnHoop(mapthing_t *mthing);
void P_SetBonusTime(mobj_t *mobj);

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,6 @@
#include "p_mobj.h"
#include "r_defs.h"
// haleyjd: temporary define
#ifdef POLYOBJECTS
//
// Defines
//
@ -31,7 +29,6 @@
#define POLYOBJ_SPAWNCRUSH_DOOMEDNUM 762 // todo: REMOVE
#define POLYOBJ_START_LINE 20
#define POLYOBJ_EXPLICIT_LINE 21
#define POLYINFO_SPECIALNUM 22
typedef enum
@ -301,6 +298,14 @@ typedef struct polyrotdisplacedata_s
UINT8 turnobjs;
} polyrotdisplacedata_t;
typedef struct polyflagdata_s
{
INT32 polyObjNum;
INT32 speed;
UINT32 angle;
fixed_t momx;
} polyflagdata_t;
typedef struct polyfadedata_s
{
INT32 polyObjNum;
@ -322,7 +327,6 @@ boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y);
boolean P_MobjTouchingPolyobj(polyobj_t *po, mobj_t *mo);
boolean P_MobjInsidePolyobj(polyobj_t *po, mobj_t *mo);
boolean P_BBoxInsidePolyobj(polyobj_t *po, fixed_t *bbox);
void Polyobj_GetInfo(INT16 poid, INT32 *poflags, INT32 *parentID, INT32 *potrans);
// thinkers (needed in p_saveg.c)
void T_PolyObjRotate(polyrotate_t *);
@ -335,14 +339,14 @@ void T_PolyObjRotDisplace (polyrotdisplace_t *);
void T_PolyObjFlag (polymove_t *);
void T_PolyObjFade (polyfade_t *);
INT32 EV_DoPolyDoor(polydoordata_t *);
INT32 EV_DoPolyObjMove(polymovedata_t *);
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
INT32 EV_DoPolyObjFlag(struct line_s *);
INT32 EV_DoPolyObjFade(polyfadedata_t *);
boolean EV_DoPolyDoor(polydoordata_t *);
boolean EV_DoPolyObjMove(polymovedata_t *);
boolean EV_DoPolyObjWaypoint(polywaypointdata_t *);
boolean EV_DoPolyObjRotate(polyrotdata_t *);
boolean EV_DoPolyObjDisplace(polydisplacedata_t *);
boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
boolean EV_DoPolyObjFlag(polyflagdata_t *);
boolean EV_DoPolyObjFade(polyfadedata_t *);
//
@ -353,8 +357,6 @@ extern polyobj_t *PolyObjects;
extern INT32 numPolyObjects;
extern polymaplink_t **polyblocklinks; // polyobject blockmap
#endif // ifdef POLYOBJECTS
#endif
// EOF

File diff suppressed because it is too large Load Diff

View File

@ -218,6 +218,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
mapheaderinfo[num]->startrings = 0;
mapheaderinfo[num]->sstimer = 90;
mapheaderinfo[num]->ssspheres = 1;
mapheaderinfo[num]->gravity = FRACUNIT/2;
mapheaderinfo[num]->keywords[0] = '\0';
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0;
@ -693,47 +696,27 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
static void P_SpawnEmeraldHunt(void)
{
INT32 emer1, emer2, emer3;
INT32 timeout = 0; // keeps from getting stuck
INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey;
fixed_t x, y, z;
emer1 = emer2 = emer3 = 0;
for (i = 0; i < numhuntemeralds; i++)
num[i] = i;
//increment spawn numbers because zero is valid.
emer1 = (P_RandomKey(numhuntemeralds)) + 1;
while (timeout++ < 100)
for (i = 0; i < 3; i++)
{
emer2 = (P_RandomKey(numhuntemeralds)) + 1;
// generate random index, shuffle afterwards
randomkey = P_RandomKey(numhuntemeralds--);
emer[i] = num[randomkey];
num[randomkey] = num[numhuntemeralds];
num[numhuntemeralds] = emer[i];
if (emer2 != emer1)
break;
// spawn emerald
x = huntemeralds[emer[i]]->x<<FRACBITS;
y = huntemeralds[emer[i]]->y<<FRACBITS;
z = P_GetMapThingSpawnHeight(MT_EMERHUNT, huntemeralds[emer[i]], x, y);
P_SetMobjStateNF(P_SpawnMobj(x, y, z, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+i);
}
timeout = 0;
while (timeout++ < 100)
{
emer3 = (P_RandomKey(numhuntemeralds)) + 1;
if (emer3 != emer2 && emer3 != emer1)
break;
}
//decrement spawn values to the actual number because zero is valid.
if (emer1--)
P_SpawnMobj(huntemeralds[emer1]->x<<FRACBITS,
huntemeralds[emer1]->y<<FRACBITS,
huntemeralds[emer1]->z<<FRACBITS, MT_EMERHUNT);
if (emer2--)
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer2]->x<<FRACBITS,
huntemeralds[emer2]->y<<FRACBITS,
huntemeralds[emer2]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+1);
if (emer3--)
P_SetMobjStateNF(P_SpawnMobj(huntemeralds[emer3]->x<<FRACBITS,
huntemeralds[emer3]->y<<FRACBITS,
huntemeralds[emer3]->z<<FRACBITS, MT_EMERHUNT),
mobjinfo[MT_EMERHUNT].spawnstate+2);
}
static void P_SpawnMapThings(boolean spawnemblems)
@ -866,13 +849,12 @@ static void P_InitializeSector(sector_t *ss)
ss->camsec = -1;
ss->floorlightsec = ss->ceilinglightsec = -1;
ss->crumblestate = 0;
ss->crumblestate = CRUMBLE_NONE;
ss->touching_thinglist = NULL;
ss->linecount = 0;
ss->lines = NULL;
ss->tagline = NULL;
ss->ffloors = NULL;
ss->attached = NULL;
@ -974,9 +956,7 @@ static void P_InitializeLinedef(line_t *ld)
ld->splats = NULL;
#endif
ld->firsttag = ld->nexttag = -1;
#ifdef POLYOBJECTS
ld->polyobj = NULL;
#endif
ld->text = NULL;
ld->callcount = 0;
@ -1181,10 +1161,14 @@ static void P_LoadSidedefs(UINT8 *data)
case 9: // Mace parameters
case 14: // Bustable block parameters
case 15: // Fan particle spawner parameters
case 334: // Trigger linedef executor: Object dye - Continuous
case 335: // Trigger linedef executor: Object dye - Each time
case 336: // Trigger linedef executor: Object dye - Once
case 425: // Calls P_SetMobjState on calling mobj
case 434: // Custom Power
case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors
case 461: // Spawns an object on the map based on texture offsets
case 463: // Colorizes an object
{
char process[8*3+1];
memset(process,0,8*3+1);
@ -1886,10 +1870,8 @@ static void P_InitializeSeg(seg_t *seg)
seg->numlights = 0;
seg->rlights = NULL;
#ifdef POLYOBJECTS
seg->polyseg = NULL;
seg->dontrenderme = false;
#endif
}
static void P_LoadSegs(UINT8 *data)
@ -2252,11 +2234,9 @@ static boolean P_LoadBlockMap(UINT8 *data, size_t count)
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
blockmap = blockmaplump+4;
#ifdef POLYOBJECTS
// haleyjd 2/22/06: setup polyobject blockmap
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
#endif
return true;
}
@ -2507,11 +2487,9 @@ static void P_CreateBlockMap(void)
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
blockmap = blockmaplump + 4;
#ifdef POLYOBJECTS
// haleyjd 2/22/06: setup polyobject blockmap
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
#endif
}
}
@ -3774,12 +3752,12 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
{
UINT16 numlumps = *pnumlumps;
size_t i = *pi;
if (!stricmp(lumpinfo->name2, folName))
if (!stricmp(lumpinfo->fullname, folName))
{
lumpinfo++;
*start = ++i;
for (; i < numlumps; i++, lumpinfo++)
if (strnicmp(lumpinfo->name2, folName, strlen(folName)))
if (strnicmp(lumpinfo->fullname, folName, strlen(folName)))
break;
lumpinfo--;
*end = i-- - *start;

View File

@ -100,7 +100,6 @@ static fixed_t P_InterceptVector2(divline_t *v2, divline_t *v1)
return frac;
}
#ifdef POLYOBJECTS
static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
{
size_t i;
@ -169,7 +168,6 @@ static boolean P_CrossSubsecPolyObj(polyobj_t *po, register los_t *los)
return true;
}
#endif
//
// P_CrossSubsector
@ -180,9 +178,7 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
{
seg_t *seg;
INT32 count;
#ifdef POLYOBJECTS
polyobj_t *po; // haleyjd 02/23/06
#endif
#ifdef RANGECHECK
if (num >= numsubsectors)
@ -192,7 +188,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
// haleyjd 02/23/06: this assignment should be after the above check
seg = segs + subsectors[num].firstline;
#ifdef POLYOBJECTS
// haleyjd 02/23/06: check polyobject lines
if ((po = subsectors[num].polyList))
{
@ -207,7 +202,6 @@ static boolean P_CrossSubsector(size_t num, register los_t *los)
po = (polyobj_t *)(po->link.next);
}
}
#endif
for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines
{
@ -413,15 +407,10 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
// killough 11/98: shortcut for melee situations
// same subsector? obviously visible
#ifndef POLYOBJECTS
if (t1->subsector == t2->subsector)
return true;
#else
// haleyjd 02/23/06: can't do this if there are polyobjects in the subsec
if (!t1->subsector->polyList &&
t1->subsector == t2->subsector)
return true;
#endif
// An unobstructed LOS is possible.
// Now look from eyes of t1 to any part of t2.
@ -484,7 +473,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
if (rover->flags & FF_SOLID)
continue; // shortcut since neither mobj can be inside the 3dfloor
if (!(rover->flags & FF_INVERTPLANES))
if (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))
{
if (los.sightzstart >= topz1 && t2->z + t2->height < topz2)
return false; // blocked by upper outside plane
@ -493,7 +482,7 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
return false; // blocked by lower outside plane
}
if (rover->flags & FF_INVERTPLANES || rover->flags & FF_BOTHPLANES)
if (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES)
{
if (los.sightzstart < topz1 && t2->z >= topz2)
return false; // blocked by upper inside plane

View File

@ -566,7 +566,7 @@ void P_CopySectorSlope(line_t *line)
int i, special = line->special;
// Check for copy linedefs
for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;)
for (i = -1; (i = P_FindSectorFromTag(line->tag, i)) >= 0;)
{
sector_t *srcsec = sectors + i;

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,6 @@ fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight);
fixed_t P_FindLowestCeilingSurrounding(sector_t *sec);
fixed_t P_FindHighestCeilingSurrounding(sector_t *sec);
INT32 P_FindSectorFromLineTag(line_t *line, INT32 start);
INT32 P_FindSectorFromTag(INT16 tag, INT32 start);
INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start);
@ -74,6 +73,7 @@ void P_RunDeNightserizeExecutors(mobj_t *actor);
void P_RunNightsLapExecutors(mobj_t *actor);
void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres);
UINT16 P_GetFFloorID(ffloor_t *fflr);
ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id);
//
@ -104,10 +104,9 @@ typedef struct
typedef struct
{
thinker_t thinker; ///< Thinker structure for laser.
ffloor_t *ffloor; ///< 3Dfloor that is a laser.
sector_t *sector; ///< Sector in which the effect takes place.
sector_t *sec;
INT16 tag;
line_t *sourceline;
UINT8 nobosses;
} laserthink_t;
/** Strobe light action structure..
@ -307,18 +306,130 @@ typedef struct
fixed_t delaytimer;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
player_t *player; // Player who initiated the thinker (used for airbob)
line_t *sourceline;
} elevator_t;
typedef enum
{
CF_RETURN = 1, // Return after crumbling
CF_FLOATBOB = 1<<1, // Float on water
CF_REVERSE = 1<<2, // Reverse gravity
} crumbleflag_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
sector_t *actionsector; // The sector the rover action is taking place in.
player_t *player; // Player who initiated the thinker (used for airbob)
INT32 direction;
INT32 origalpha;
INT32 timer;
fixed_t speed;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
UINT8 flags;
} crumble_t;
typedef struct
{
thinker_t thinker;
fixed_t vars[16]; // Misc. variables
fixed_t var2s[16]; // Second misc variables buffer.
line_t *sourceline; // Source line of the thinker
sector_t *sector; // Sector the thinker is from
} levelspecthink_t;
} noenemies_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
fixed_t destheight;
} continuousfall_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t speed;
fixed_t distance;
fixed_t floorwasheight;
fixed_t ceilingwasheight;
boolean low;
} bouncecheese_t;
typedef struct
{
thinker_t thinker;
sector_t *sector;
fixed_t speed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT16 tag;
} mariothink_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
} mariocheck_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
fixed_t crushspeed;
fixed_t retractspeed;
INT32 direction;
fixed_t floorstartheight;
fixed_t ceilingstartheight;
INT32 delay;
INT16 tag;
UINT16 sound;
} thwomp_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline;
sector_t *sector;
INT16 tag;
} floatthink_t;
typedef struct
{
thinker_t thinker;
line_t *sourceline; // Source line of the thinker
boolean playersInArea[MAXPLAYERS];
boolean playersOnArea[MAXPLAYERS];
boolean triggerOnExit;
} eachtime_t;
typedef enum
{
RF_REVERSE = 1, //Lower when stood on
RF_SPINDASH = 1<<1, //Require spindash to move
RF_DYNAMIC = 1<<2, //Dynamically sinking platform
} raiseflag_t;
typedef struct
{
thinker_t thinker;
INT16 tag;
sector_t *sector;
fixed_t ceilingbottom;
fixed_t ceilingtop;
fixed_t basespeed;
fixed_t extraspeed; //For dynamically sinking platform
UINT8 shaketimer; //For dynamically sinking platform
UINT8 flags;
} raise_t;
#define ELEVATORSPEED (FRACUNIT*4)
#define FLOORSPEED (FRACUNIT)
@ -331,36 +442,34 @@ typedef enum
} result_e;
result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush,
INT32 floorOrCeiling, INT32 direction);
INT32 EV_DoFloor(line_t *line, floor_e floortype);
INT32 EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
boolean ceiling, INT32 direction);
void EV_DoFloor(line_t *line, floor_e floortype);
void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
INT32 EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
// Some other special 3dfloor types
INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards);
void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher);
void T_MoveFloor(floormove_t *movefloor);
void T_MoveElevator(elevator_t *elevator);
void T_ContinuousFalling(levelspecthink_t *faller);
void T_BounceCheese(levelspecthink_t *bouncer);
void T_StartCrumble(elevator_t *elevator);
void T_MarioBlock(levelspecthink_t *block);
void T_SpikeSector(levelspecthink_t *spikes);
void T_FloatSector(levelspecthink_t *floater);
void T_BridgeThinker(levelspecthink_t *bridge);
void T_MarioBlockChecker(levelspecthink_t *block);
void T_ThwompSector(levelspecthink_t *thwomp);
void T_NoEnemiesSector(levelspecthink_t *nobaddies);
void T_EachTimeThinker(levelspecthink_t *eachtime);
void T_ContinuousFalling(continuousfall_t *faller);
void T_BounceCheese(bouncecheese_t *bouncer);
void T_StartCrumble(crumble_t *crumble);
void T_MarioBlock(mariothink_t *block);
void T_FloatSector(floatthink_t *floater);
void T_MarioBlockChecker(mariocheck_t *block);
void T_ThwompSector(thwomp_t *thwomp);
void T_NoEnemiesSector(noenemies_t *nobaddies);
void T_EachTimeThinker(eachtime_t *eachtime);
void T_CameraScanner(elevator_t *elevator);
void T_RaiseSector(levelspecthink_t *sraise);
void T_RaiseSector(raise_t *raise);
typedef struct
{

View File

@ -1388,7 +1388,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
// Continues are worthless in netgames.
// If that stops being the case uncomment this.
/* if (!ultimatemode && players[i].marescore > 50000
/* if (!ultimatemode && continuesInSession && players[i].marescore > 50000
&& oldscore < 50000)
{
players[i].continues += 1;
@ -1408,7 +1408,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
else
player->marescore = MAXSCORE;
if (!ultimatemode && !(netgame || multiplayer) && G_IsSpecialStage(gamemap)
if (!ultimatemode && continuesInSession && G_IsSpecialStage(gamemap)
&& player->marescore >= 50000 && oldscore < 50000)
{
player->continues += 1;
@ -1490,17 +1490,10 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player))
return;
if (use1upSound)
if (use1upSound || cv_1upsound.value)
S_StartSound(NULL, sfx_oneup);
else if (mariomode)
S_StartSound(NULL, sfx_marioa);
else if (cv_1upsound.value)
{
if (S_sfx[sfx_oneup].lumpnum != LUMPERROR)
S_StartSound(NULL, sfx_oneup);
else
S_StartSound(NULL, sfx_chchng);/* at least play something! */
}
else
{
P_PlayJingle(player, JT_1UP);
@ -2562,7 +2555,7 @@ static void P_CheckBustableBlocks(player_t *player)
{
if (!(rover->flags & FF_EXISTS)) continue;
if ((rover->flags & FF_BUSTUP)/* && !rover->master->frontsector->crumblestate*/)
if ((rover->flags & FF_BUSTUP)/* && rover->master->frontsector->crumblestate == CRUMBLE_NONE*/)
{
// If it's an FF_SHATTER, you can break it just by touching it.
if (rover->flags & FF_SHATTER)
@ -3833,7 +3826,6 @@ static void P_DoTeeter(player_t *player)
BMBOUNDFIX(xl, xh, yl, yh);
// Polyobjects
#ifdef POLYOBJECTS
validcount++;
for (by = yl; by <= yh; by++)
@ -3927,7 +3919,6 @@ static void P_DoTeeter(player_t *player)
plink = (polymaplink_t *)(plink->link.next);
}
}
#endif
if (teeter) // only bother with objects as a last resort if you were already teetering
{
mobj_t *oldtmthing = tmthing;
@ -4428,13 +4419,16 @@ void P_DoJump(player_t *player, boolean soundandstate)
else if (player->powers[pw_carry] == CR_ROLLOUT)
{
player->mo->momz = 9*FRACUNIT;
if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0)
player->mo->momz += player->mo->tracer->momz;
if (!P_IsObjectOnGround(player->mo->tracer))
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
if (player->mo->tracer)
{
if (P_MobjFlip(player->mo->tracer)*player->mo->tracer->momz > 0)
player->mo->momz += player->mo->tracer->momz;
if (!P_IsObjectOnGround(player->mo->tracer))
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->tracer, NULL);
}
player->powers[pw_carry] = CR_NONE;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->tracer, NULL);
P_SetTarget(&player->mo->tracer, NULL);
}
else if (player->mo->eflags & MFE_GOOWATER)
@ -4992,6 +4986,15 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
player->pflags |= PF_THOKKED;
}
static void P_DoTwinSpin(player_t *player)
{
player->pflags &= ~PF_NOJUMPDAMAGE;
player->pflags |= P_GetJumpFlags(player) | PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
//
// P_DoJumpStuff
//
@ -5162,12 +5165,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break;
case CA_TWINSPIN:
if ((player->charability2 == CA2_MELEE) && (!(player->pflags & (PF_THOKKED|PF_USEDOWN)) || player->charflags & SF_MULTIABILITY))
{
player->pflags |= PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
P_DoTwinSpin(player);
break;
default:
break;
@ -5424,12 +5422,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
break;
case CA_TWINSPIN:
if (!(player->pflags & PF_THOKKED) || player->charflags & SF_MULTIABILITY)
{
player->pflags |= PF_THOKKED;
S_StartSound(player->mo, sfx_s3k42);
player->mo->frame = 0;
P_SetPlayerMobjState(player->mo, S_PLAY_TWINSPIN);
}
P_DoTwinSpin(player);
break;
default:
break;
@ -5688,11 +5681,7 @@ static void P_2dMovement(player_t *player)
}
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4
#ifdef POLYOBJECTS
&& player->onconveyor != 1
#endif
)
else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx;
@ -5887,11 +5876,7 @@ static void P_3dMovement(player_t *player)
}
else if (player->onconveyor == 4 && !P_IsObjectOnGround(player->mo)) // Actual conveyor belt
player->cmomx = player->cmomy = 0;
else if (player->onconveyor != 2 && player->onconveyor != 4
#ifdef POLYOBJECTS
&& player->onconveyor != 1
#endif
)
else if (player->onconveyor != 2 && player->onconveyor != 4 && player->onconveyor != 1)
player->cmomx = player->cmomy = 0;
player->rmomx = player->mo->momx - player->cmomx;
@ -7968,7 +7953,7 @@ static void P_MovePlayer(player_t *player)
&& player->mo->state < &states[S_PLAY_NIGHTS_TRANS6]))) // Note the < instead of <=
{
skin_t *skin = ((skin_t *)(player->mo->skin));
if (skin->flags & SF_SUPER)
if (( skin->flags & (SF_SUPER|SF_NONIGHTSSUPER) ) == SF_SUPER)
{
player->mo->color = skin->supercolor
+ ((player->nightstime == player->startedtime)
@ -9317,7 +9302,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
if (enemy->health <= 0) // dead
return false;
if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag
if (source->player && (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag
return false;
if (enemy->flags2 & MF2_FRET)
@ -9529,7 +9514,7 @@ static void P_DeathThink(player_t *player)
// continue logic
if (!(netgame || multiplayer) && player->lives <= 0)
{
if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && player->continues > 0)
if (player->deadtimer > (3*TICRATE) && (cmd->buttons & BT_USE || cmd->buttons & BT_JUMP) && (!continuesInSession || player->continues > 0))
G_UseContinue();
else if (player->deadtimer >= gameovertics)
G_UseContinue(); // Even if we don't have one this handles ending the game
@ -10221,7 +10206,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
}
}
#ifdef POLYOBJECTS
// Check polyobjects and see if floorz/ceilingz need to be altered
{
INT32 xl, xh, yl, yh, bx, by;
@ -10300,7 +10284,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
}
}
}
#endif
// crushed camera
if (myceilingz <= myfloorz + thiscam->height && !resetcalled && !cameranoclip)
@ -11711,10 +11694,8 @@ void P_PlayerThink(player_t *player)
P_MobjCheckWater(player->mo);
#ifndef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif
player->onconveyor = 0;
player->onconveyor = 0;
// check special sectors : damage & secrets
if (!player->spectator)
@ -11927,6 +11908,9 @@ void P_PlayerThink(player_t *player)
factor = 4;
}
break;
case CR_DUSTDEVIL:
player->drawangle += ANG20;
break;
/* -- in case we wanted to have the camera freely movable during zoom tubes
case CR_ZOOMTUBE:*/
case CR_ROPEHANG:
@ -12072,12 +12056,10 @@ void P_PlayerThink(player_t *player)
// it lasts for one tic.
player->pflags &= ~PF_FULLSTASIS;
#ifdef POLYOBJECTS
if (player->onconveyor == 1)
player->onconveyor = 3;
else if (player->onconveyor == 3)
player->cmomy = player->cmomx = 0;
#endif
P_DoSuperStuff(player);
P_CheckSneakerAndLivesTimer(player);
@ -12410,10 +12392,8 @@ void P_PlayerAfterThink(player_t *player)
cmd = &player->cmd;
#ifdef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif
player->onconveyor = 0;
player->onconveyor = 0;
// check special sectors : damage & secrets
if (!player->spectator)
@ -12703,6 +12683,19 @@ void P_PlayerAfterThink(player_t *player)
}
break;
}
case CR_DUSTDEVIL:
{
mobj_t *mo = player->mo, *dustdevil = player->mo->tracer;
if (abs(mo->x - dustdevil->x) > dustdevil->radius || abs(mo->y - dustdevil->y) > dustdevil->radius)
{
P_SetTarget(&player->mo->tracer, NULL);
player->powers[pw_carry] = CR_NONE;
break;
}
break;
}
case CR_ROLLOUT:
{
mobj_t *mo = player->mo, *rock = player->mo->tracer;
@ -12844,6 +12837,12 @@ void P_PlayerAfterThink(player_t *player)
player->mo->flags |= MF_NOGRAVITY;
}
if (player->powers[pw_dye])
{
player->mo->colorized = true;
player->mo->color = player->powers[pw_dye];
}
if (player->followmobj && (player->spectator || player->mo->health <= 0 || player->followmobj->type != player->followitem))
{
P_RemoveMobj(player->followmobj);

View File

@ -354,9 +354,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
{
return (
#ifdef POLYOBJECTS
!line->polyseg &&
#endif
back->ceilingpic == front->ceilingpic
&& back->floorpic == front->floorpic
&& back->f_slope == front->f_slope
@ -482,13 +480,10 @@ static void R_AddLine(seg_t *line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{
if (
#ifdef POLYOBJECTS
!line->polyseg &&
#endif
!line->sidedef->midtexture
&& ((!frontsector->ffloors && !backsector->ffloors)
|| (frontsector->tag == backsector->tag)))
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!frontsector->ffloors && !backsector->ffloors)
|| (frontsector->tag == backsector->tag)))
return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead
@ -651,8 +646,6 @@ static boolean R_CheckBBox(const fixed_t *bspcoord)
return true;
}
#ifdef POLYOBJECTS
size_t numpolys; // number of polyobjects in current subsector
size_t num_po_ptrs; // number of polyobject pointers allocated
polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
@ -816,7 +809,6 @@ static void R_AddPolyObjects(subsector_t *sub)
R_AddLine(po_ptrs[i]->segs[j]);
}
}
#endif
//
// R_Subsector
@ -888,11 +880,7 @@ static void R_Subsector(size_t num)
|| (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))
{
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, frontsector->f_slope);
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL, NULL, frontsector->f_slope);
}
else
floorplane = NULL;
@ -903,11 +891,7 @@ static void R_Subsector(size_t num)
{
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, frontsector->c_slope);
ceilingcolormap, NULL, NULL, frontsector->c_slope);
}
else
ceilingplane = NULL;
@ -943,19 +927,15 @@ static void R_Subsector(size_t num)
planecenterz = P_GetFFloorBottomZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
if (planecenterz <= ceilingcenterz
&& planecenterz >= floorcenterz
&& ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
&& ((viewz < heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz,
viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, *rover->b_slope);
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope);
ffloor[numffloors].slope = *rover->b_slope;
@ -977,18 +957,14 @@ static void R_Subsector(size_t num)
planecenterz = P_GetFFloorTopZAt(rover, frontsector->soundorg.x, frontsector->soundorg.y);
if (planecenterz >= floorcenterz
&& planecenterz <= ceilingcenterz
&& ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
&& ((viewz > heightcheck && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES)))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
*frontsector->lightlist[light].extra_colormap, rover
#ifdef POLYOBJECTS_PLANES
, NULL
#endif
, *rover->t_slope);
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope);
ffloor[numffloors].slope = *rover->t_slope;
@ -1003,7 +979,6 @@ static void R_Subsector(size_t num)
}
}
#ifdef POLYOBJECTS_PLANES
// Polyobjects have planes, too!
if (sub->polyList)
{
@ -1069,7 +1044,6 @@ static void R_Subsector(size_t num)
po = (polyobj_t *)(po->link.next);
}
}
#endif
#ifdef FLOORSPLATS
if (sub->splats)
@ -1092,21 +1066,15 @@ static void R_Subsector(size_t num)
firstseg = NULL;
#ifdef POLYOBJECTS
// haleyjd 02/19/06: draw polyobjects before static lines
if (sub->polyList)
R_AddPolyObjects(sub);
#endif
while (count--)
{
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
if (!line->glseg
#ifdef POLYOBJECTS
&& !line->polyseg // ignore segs that belong to polyobjects
#endif
)
R_AddLine(line);
if (!line->glseg && !line->polyseg) // ignore segs that belong to polyobjects
R_AddLine(line);
line++;
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
}

View File

@ -40,13 +40,11 @@ void R_PortalClearClipSegs(INT32 start, INT32 end);
void R_ClearDrawSegs(void);
void R_RenderBSPNode(INT32 bspnum);
#ifdef POLYOBJECTS
void R_SortPolyObjects(subsector_t *sub);
extern size_t numpolys; // number of polyobjects in current subsector
extern size_t num_po_ptrs; // number of polyobject pointers allocated
extern polyobj_t **po_ptrs; // temp ptr array to sort polyobject pointers
#endif
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
INT32 *ceilinglightlevel, boolean back);

View File

@ -721,14 +721,12 @@ Rloadflats (INT32 i, INT32 w)
}
else
{
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
}
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
@ -841,7 +839,7 @@ Rloadtextures (INT32 i, INT32 w)
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0);
if (texturesLumpPos != INT16_MAX)
@ -850,8 +848,6 @@ Rloadtextures (INT32 i, INT32 w)
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// Work through each lump between the markers in the WAD.
for (j = 0; j < (texend - texstart); j++)
{
@ -958,14 +954,12 @@ void R_LoadTextures(void)
}
else
{
texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad("F_START", (UINT16)w, 0);
texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart);
}
if (!( texstart == INT16_MAX || texend == INT16_MAX ))
{
texstart++; // Do not count the first marker
// PK3s have subfolders, so we can't just make a simple sum
if (wadfiles[w]->type == RET_PK3)
{
@ -998,15 +992,13 @@ void R_LoadTextures(void)
}
else
{
texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0);
texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0);
texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0);
}
if (texstart == INT16_MAX || texend == INT16_MAX)
continue;
texstart++; // Do not count the first marker
// PK3s have subfolders, so we can't just make a simple sum
if (wadfiles[w]->type == RET_PK3)
{
@ -1592,9 +1584,9 @@ lumpnum_t R_GetFlatNumForName(const char *name)
switch (wadfiles[i]->type)
{
case RET_WAD:
if ((start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0)) == INT16_MAX)
if ((start = W_CheckNumForMarkerStartPwad("F_START", (UINT16)i, 0)) == INT16_MAX)
{
if ((start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0)) == INT16_MAX)
if ((start = W_CheckNumForMarkerStartPwad("FF_START", (UINT16)i, 0)) == INT16_MAX)
continue;
else if ((end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start)) == INT16_MAX)
continue;

View File

@ -28,8 +28,6 @@
#include "m_aatree.h"
#endif
#define POLYOBJECTS
//
// ClipWallSegment
// Clips the given range of columns
@ -107,9 +105,7 @@ typedef struct
fixed_t z; ///< Z coordinate.
} degenmobj_t;
#ifdef POLYOBJECTS
#include "p_polyobj.h"
#endif
// Store fake planes in a resizable array insted of just by
// heightsec. Allows for multiple fake planes.
@ -130,11 +126,11 @@ typedef enum
FF_CUTEXTRA = 0x100, ///< Cuts out hidden translucent pixels.
FF_CUTLEVEL = 0x180, ///< Cuts out all hidden pixels.
FF_CUTSPRITES = 0x200, ///< Final step in making 3D water.
FF_BOTHPLANES = 0x400, ///< Renders both planes all the time.
FF_BOTHPLANES = 0x400, ///< Render inside and outside planes.
FF_EXTRA = 0x800, ///< Gets cut by ::FF_CUTEXTRA.
FF_TRANSLUCENT = 0x1000, ///< See through!
FF_FOG = 0x2000, ///< Fog "brush."
FF_INVERTPLANES = 0x4000, ///< Reverse the plane visibility rules.
FF_INVERTPLANES = 0x4000, ///< Only render inside planes.
FF_ALLSIDES = 0x8000, ///< Render inside and outside sides.
FF_INVERTSIDES = 0x10000, ///< Only render inside sides.
FF_DOUBLESHADOW = 0x20000, ///< Make two lightlist entries to reset light?
@ -277,6 +273,16 @@ typedef enum
SF_INVERTPRECIP = 1<<4,
} sectorflags_t;
typedef enum
{
CRUMBLE_NONE, // No crumble thinker
CRUMBLE_WAIT, // Don't float on water because this is supposed to wait for a crumble
CRUMBLE_ACTIVATED, // Crumble thinker activated, but hasn't fallen yet
CRUMBLE_FALL, // Crumble thinker is falling
CRUMBLE_RESTORE, // Crumble thinker is about to restore to original position
} crumblestate_t;
//
// The SECTORS record, at runtime.
// Stores things/mobjs.
@ -328,11 +334,6 @@ typedef struct sector_s
size_t linecount;
struct line_s **lines; // [linecount] size
// Hack: store special line tagging to some sectors
// to efficiently help work around bugs by directly
// referencing the specific line that the problem happens in.
// (used in T_MovePlane mobj physics)
struct line_s *tagline;
// Improved fake floor hack
ffloor_t *ffloors;
@ -429,9 +430,7 @@ typedef struct line_s
void *splats; // wallsplat_t list
#endif
INT32 firsttag, nexttag; // improves searches for tags.
#ifdef POLYOBJECTS
polyobj_t *polyobj; // Belongs to a polyobject?
#endif
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
@ -474,9 +473,7 @@ typedef struct subsector_s
sector_t *sector;
INT16 numlines;
UINT16 firstline;
#ifdef POLYOBJECTS
struct polyobj_s *polyList; // haleyjd 02/19/06: list of polyobjects
#endif
#if 1//#ifdef FLOORSPLATS
void *splats; // floorsplat_t list
#endif
@ -579,10 +576,8 @@ typedef struct seg_s
// Why slow things down by calculating lightlists for every thick side?
size_t numlights;
r_lightlist_t *rlights;
#ifdef POLYOBJECTS
polyobj_t *polyseg;
boolean dontrenderme;
#endif
boolean glseg;
} seg_t;

View File

@ -233,11 +233,11 @@ const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = {
{0x00, 0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERORANGE4
{0xd0, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERORANGE5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48}, // SKINCOLOR_SUPERGOLD1
{0x00, 0x50, 0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41}, // SKINCOLOR_SUPERGOLD2
{0x51, 0x52, 0x53, 0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43}, // SKINCOLOR_SUPERGOLD3
{0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, // SKINCOLOR_SUPERGOLD4
{0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, // SKINCOLOR_SUPERGOLD5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x51, 0x52, 0x53, 0x48, 0x48, 0x48}, // SKINCOLOR_SUPERGOLD1
{0x00, 0x50, 0x51, 0x52, 0x53, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x41, 0x41}, // SKINCOLOR_SUPERGOLD2
{0x51, 0x52, 0x53, 0x53, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x43, 0x43}, // SKINCOLOR_SUPERGOLD3
{0x53, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x46, 0x46}, // SKINCOLOR_SUPERGOLD4
{0x48, 0x48, 0x49, 0x49, 0x49, 0x40, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x47}, // SKINCOLOR_SUPERGOLD5
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc}, // SKINCOLOR_SUPERPERIDOT1
{0x00, 0x58, 0x58, 0x58, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe}, // SKINCOLOR_SUPERPERIDOT2

View File

@ -1388,7 +1388,7 @@ void R_RenderPlayerView(player_t *player)
else
{
portalclipstart = 0;
portalclipend = viewwidth-1;
portalclipend = viewwidth;
R_ClearClipSegs();
}
R_ClearDrawSegs();

View File

@ -1231,9 +1231,9 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
if (!R_CheckIfPatch(lump))
return;
width = patch->width;
height = patch->height;
leftoffset = patch->leftoffset;
width = SHORT(patch->width);
height = SHORT(patch->height);
leftoffset = SHORT(patch->leftoffset);
// rotation pivot
px = SPRITE_XCENTER;
@ -1348,7 +1348,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size);
{
newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px);
newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py);
newpatch->topoffset = (newpatch->height / 2) + (SHORT(patch->topoffset) - py);
}
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
@ -1358,6 +1358,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp
// P_PrecacheLevel
if (devparm) spritememory += size;
// convert everything to little-endian, for big-endian support
newpatch->width = SHORT(newpatch->width);
newpatch->height = SHORT(newpatch->height);
newpatch->leftoffset = SHORT(newpatch->leftoffset);
newpatch->topoffset = SHORT(newpatch->topoffset);
#ifdef HWRENDER
if (rendermode == render_opengl)
{

View File

@ -337,11 +337,7 @@ static visplane_t *new_visplane(unsigned hash)
//
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
, pslope_t *slope)
ffloor_t *pfloor, polyobj_t *polyobj, pslope_t *slope)
{
visplane_t *check;
unsigned hash;
@ -361,7 +357,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
}
}
#ifdef POLYOBJECTS_PLANES
if (polyobj)
{
if (polyobj->angle != 0)
@ -376,7 +371,6 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
yoff += polyobj->centerPt.y;
}
}
#endif
// This appears to fix the Nimbus Ruins sky bug.
if (picnum == skyflatnum && pfloor)
@ -390,12 +384,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
for (check = visplanes[hash]; check; check = check->next)
{
#ifdef POLYOBJECTS_PLANES
if (check->polyobj && pfloor)
continue;
if (polyobj != check->polyobj)
continue;
#endif
if (height == check->height && picnum == check->picnum
&& lightlevel == check->lightlevel
&& xoff == check->xoffs && yoff == check->yoffs
@ -426,9 +418,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->viewz = viewz;
check->viewangle = viewangle;
check->plangle = plangle;
#ifdef POLYOBJECTS_PLANES
check->polyobj = polyobj;
#endif
check->slope = slope;
memset(check->top, 0xff, sizeof (check->top));
@ -496,9 +486,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->viewz = pl->viewz;
new_pl->viewangle = pl->viewangle;
new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj;
#endif
new_pl->slope = pl->slope;
pl = new_pl;
pl->minx = start;
@ -523,11 +511,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
// INT32 unionl, unionh;
// INT32 x;
#ifdef POLYOBJECTS_PLANES
// Don't expand polyobject planes here - we do that on our own.
if (pl->polyobj)
return;
#endif
if (pl->minx > start) pl->minx = start;
if (pl->maxx < stop) pl->maxx = stop;
@ -603,11 +589,7 @@ void R_DrawPlanes(void)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->ffloor != NULL
#ifdef POLYOBJECTS_PLANES
|| pl->polyobj != NULL
#endif
)
if (pl->ffloor != NULL || pl->polyobj != NULL)
continue;
R_DrawSinglePlane(pl);
@ -961,7 +943,6 @@ void R_DrawSinglePlane(visplane_t *pl)
#endif
spanfunc = spanfuncs[BASEDRAWFUNC];
#ifdef POLYOBJECTS_PLANES
if (pl->polyobj && pl->polyobj->translucency != 0)
{
spanfunctype = SPANDRAWFUNC_TRANS;
@ -979,95 +960,98 @@ void R_DrawSinglePlane(visplane_t *pl)
else
light = LIGHTLEVELS-1;
} else
#endif
if (pl->ffloor)
}
else
{
// Don't draw planes that shouldn't be drawn.
for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next)
if (pl->ffloor)
{
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
// Don't draw planes that shouldn't be drawn.
for (rover = pl->ffloor->target->ffloors; rover; rover = rover->next)
{
if (pl->ffloor->flags & FF_EXTRA)
if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA))
{
// The plane is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
&& pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
if (pl->ffloor->flags & FF_EXTRA)
{
// The plane is from an extra 3D floor... Check the flags so
// there are no undesired cuts.
if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE)))
&& pl->height < *rover->topheight
&& pl->height > *rover->bottomheight)
return;
}
}
}
}
if (pl->ffloor->flags & FF_TRANSLUCENT)
{
spanfunctype = SPANDRAWFUNC_TRANS;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pl->ffloor->alpha < 12)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64)
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89)
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115)
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140)
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166)
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192)
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
}
else if (pl->ffloor->flags & FF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
itswater = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
if (pl->ffloor->flags & FF_TRANSLUCENT)
{
spanfunctype = SPANDRAWFUNC_WATER;
spanfunctype = SPANDRAWFUNC_TRANS;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pl->ffloor->alpha < 12)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64)
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89)
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115)
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140)
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166)
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192)
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
// Only copy the part of the screen we need
VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
}
else if (pl->ffloor->flags & FF_FOG)
{
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
itswater = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{
spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
// Only copy the part of the screen we need
VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
}
}
#endif
}
#endif
else
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
&& viewangle != pl->viewangle+pl->plangle)

View File

@ -47,9 +47,7 @@ typedef struct visplane_s
fixed_t xoffs, yoffs; // Scrolling flats.
struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj;
#endif
pslope_t *slope;
} visplane_t;
@ -80,11 +78,7 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
void R_DrawPlanes(void);
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle,
extracolormap_t *planecolormap, ffloor_t *ffloor
#ifdef POLYOBJECTS_PLANES
, polyobj_t *polyobj
#endif
, pslope_t *slope);
extracolormap_t *planecolormap, ffloor_t *ffloor, polyobj_t *polyobj, pslope_t *slope);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane);
@ -112,9 +106,7 @@ typedef struct planemgr_s
struct pslope_s *slope;
struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj;
#endif
} visffloor_t;
extern visffloor_t ffloor[MAXFFLOORS];

View File

@ -236,14 +236,13 @@ static void R_DrawWallSplats(void)
// way we don't have to store extra post_t info with each column for
// multi-patch textures. They are not normally needed as multi-patch
// textures don't have holes in it. At least not for now.
static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height
static void R_Render2sidedMultiPatchColumn(column_t *column)
{
INT32 topscreen, bottomscreen;
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
bottomscreen = topscreen + spryscale * column2s_length;
bottomscreen = topscreen + spryscale * lengthcol;
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
@ -275,13 +274,6 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
}
}
// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value
// uses column2s_length for texture->height as above
static void R_DrawFlippedMaskedSegColumn(column_t *column)
{
R_DrawFlippedMaskedColumn(column, column2s_length);
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
size_t pindex;
@ -356,8 +348,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
if (textures[texnum]->flip & 2) // vertically flipped?
{
colfunc_2s = R_DrawFlippedMaskedSegColumn;
column2s_length = textures[texnum]->height;
colfunc_2s = R_DrawFlippedMaskedColumn;
lengthcol = textures[texnum]->height;
}
else
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
@ -365,7 +357,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
else
{
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
column2s_length = textures[texnum]->height;
lengthcol = textures[texnum]->height;
}
// Setup lighting based on the presence/lack-of 3D floors.
@ -615,7 +607,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
//#ifdef POLYOBJECTS_PLANES
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
{
@ -692,7 +683,7 @@ static void R_DrawRepeatMaskedColumn(column_t *col)
static void R_DrawRepeatFlippedMaskedColumn(column_t *col)
{
do {
R_DrawFlippedMaskedColumn(col, column2s_length);
R_DrawFlippedMaskedColumn(col);
sprtopscreen += dc_texheight*spryscale;
} while (sprtopscreen < sprbotscreen);
}
@ -978,7 +969,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (textures[texnum]->flip & 2) // vertically flipped?
{
colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
column2s_length = textures[texnum]->height;
lengthcol = textures[texnum]->height;
}
else
colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture
@ -986,7 +977,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else
{
colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info)
column2s_length = textures[texnum]->height;
lengthcol = textures[texnum]->height;
}
// Set heights according to plane, or slope, whichever
@ -1298,10 +1289,8 @@ static void R_RenderSegLoop (void)
for (i = 0; i < numffloors; i++)
{
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg))
continue;
#endif
if (ffloor[i].height < viewz)
{
@ -1314,18 +1303,19 @@ static void R_RenderSegLoop (void)
if (bottom_w > bottom)
bottom_w = bottom;
#ifdef POLYOBJECTS_PLANES
// Polyobject-specific hack to fix plane leaking -Red
if (ffloor[i].polyobj && top_w >= bottom_w) {
if (ffloor[i].polyobj && top_w >= bottom_w)
{
ffloor[i].plane->top[rw_x] = 0xFFFF;
ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18
} else
#endif
if (top_w <= bottom_w)
}
else
{
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
if (top_w <= bottom_w)
{
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
}
}
}
else if (ffloor[i].height > viewz)
@ -1339,18 +1329,19 @@ static void R_RenderSegLoop (void)
if (bottom_w > bottom)
bottom_w = bottom;
#ifdef POLYOBJECTS_PLANES
// Polyobject-specific hack to fix plane leaking -Red
if (ffloor[i].polyobj && top_w >= bottom_w) {
if (ffloor[i].polyobj && top_w >= bottom_w)
{
ffloor[i].plane->top[rw_x] = 0xFFFF;
ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18
} else
#endif
if (top_w <= bottom_w)
}
else
{
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
if (top_w <= bottom_w)
{
ffloor[i].plane->top[rw_x] = (INT16)top_w;
ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w;
}
}
}
}
@ -1804,10 +1795,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (i = 0; i < numffloors; i++)
{
#ifdef POLYOBJECTS_PLANES
if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg))
continue;
#endif
ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft .x, segleft .y, ffloor[i].height) - viewz;
ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y, ffloor[i].height) - viewz;
@ -2139,7 +2128,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (rover->flags & FF_INVERTSIDES)
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
@ -2194,7 +2183,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
@ -2249,7 +2238,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES)
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES) && rover->flags & FF_INVERTSIDES)
continue;
if (rover->norender == leveltime)
continue;
@ -2269,7 +2260,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next)
{
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES))
if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS))
continue;
if (!(rover->flags & FF_ALLSIDES || rover->flags & FF_INVERTSIDES))
continue;
if (rover->norender == leveltime)
continue;
@ -2306,33 +2299,40 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
#ifdef POLYOBJECTS
if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up
if (curline->polyseg)
{ // use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz;
} else
#endif
// Set midtexture starting height
if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
}
else
{
// Set midtexture starting height
if (linedef->flags & ML_EFFECT2)
{ // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
rw_midtexturemid = worldbottom;
rw_midtextureslide = floorfrontslide;
rw_midtextureback = worldlow;
rw_midtexturebackslide = floorbackslide;
} else {
rw_midtexturemid = worldtop;
rw_midtextureslide = ceilingfrontslide;
rw_midtextureback = worldhigh;
rw_midtexturebackslide = ceilingbackslide;
}
else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
{
rw_midtexturemid = worldbottom;
rw_midtextureslide = floorfrontslide;
rw_midtextureback = worldlow;
rw_midtexturebackslide = floorbackslide;
}
else
{
rw_midtexturemid = worldtop;
rw_midtextureslide = ceilingfrontslide;
rw_midtextureback = worldhigh;
rw_midtexturebackslide = ceilingbackslide;
}
}
rw_midtexturemid += sidedef->rowoffset;
rw_midtextureback += sidedef->rowoffset;
@ -2586,8 +2586,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2609,8 +2609,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;
@ -2643,8 +2643,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz < planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz > planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->b_slope;
ffloor[i].b_pos = roverleft;
@ -2666,8 +2666,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) &&
(roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) &&
((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES))))
((viewz > planevistest && (rover->flags & FF_BOTHPLANES || !(rover->flags & FF_INVERTPLANES))) ||
(viewz < planevistest && (rover->flags & FF_BOTHPLANES || rover->flags & FF_INVERTPLANES))))
{
//ffloor[i].slope = *rover->t_slope;
ffloor[i].b_pos = roverleft;
@ -2681,7 +2681,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
}
}
#ifdef POLYOBJECTS_PLANES
if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES))
{
while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++;
@ -2720,7 +2719,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
i++;
}
}
#endif
numbackffloors = i;
}
@ -2774,7 +2772,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (i = 0; i < numffloors; i++)
R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1);
}
#ifdef POLYOBJECTS_PLANES
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
if (curline->polyseg)
{
@ -2789,7 +2786,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ffloor[i].plane->maxx = rw_stopx - 1;
}
}
#endif
}
#ifdef WALLSPLATS

View File

@ -504,6 +504,7 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
GETFLAG(FASTEDGE)
GETFLAG(MULTIABILITY)
GETFLAG(NONIGHTSROTATION)
GETFLAG(NONIGHTSSUPER)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out

View File

@ -428,9 +428,9 @@ void R_AddSpriteDefs(UINT16 wadnum)
switch (wadfiles[wadnum]->type)
{
case RET_WAD:
start = W_CheckNumForNamePwad("S_START", wadnum, 0);
start = W_CheckNumForMarkerStartPwad("S_START", wadnum, 0);
if (start == INT16_MAX)
start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib.
start = W_CheckNumForMarkerStartPwad("SS_START", wadnum, 0); //deutex compatib.
end = W_CheckNumForNamePwad("S_END",wadnum,start);
if (end == INT16_MAX)
@ -452,8 +452,6 @@ void R_AddSpriteDefs(UINT16 wadnum)
start = 0; //let say S_START is lump 0
}
else
start++; // just after S_START
if (end == INT16_MAX || start >= end)
{
@ -641,10 +639,10 @@ void R_DrawMaskedColumn(column_t *column)
dc_yl = mceilingclip[dc_x]+1;
if (dc_yl < 0)
dc_yl = 0;
if (dc_yh >= vid.height)
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
dc_yh = vid.height - 1;
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
if (dc_yl <= dc_yh && dc_yh > 0)
{
dc_source = (UINT8 *)column + 3;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
@ -655,15 +653,10 @@ void R_DrawMaskedColumn(column_t *column)
// quick fix... something more proper should be done!!!
if (ylookup[dc_yl])
colfunc();
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
{
static INT32 first = 1;
if (first)
{
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
first = 0;
}
}
#ifdef PARANOIA
else
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
#endif
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
@ -671,7 +664,9 @@ void R_DrawMaskedColumn(column_t *column)
dc_texturemid = basetexturemid;
}
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
void R_DrawFlippedMaskedColumn(column_t *column)
{
INT32 topscreen;
INT32 bottomscreen;
@ -687,7 +682,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = texheight-column->length-topdelta;
topdelta = lengthcol-column->length-topdelta;
topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
: sprbotscreen + spryscale*column->length;
@ -709,10 +704,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
dc_yl = mceilingclip[dc_x]+1;
if (dc_yl < 0)
dc_yl = 0;
if (dc_yh >= vid.height)
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
dc_yh = vid.height - 1;
if (dc_yl <= dc_yh && dc_yl < vid.height && dc_yh > 0)
if (dc_yl <= dc_yh && dc_yh > 0)
{
dc_source = ZZ_Alloc(column->length);
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
@ -722,15 +717,10 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
// Still drawn by R_DrawColumn.
if (ylookup[dc_yl])
colfunc();
else if (colfunc == colfuncs[COLDRAWFUNC_BASE])
{
static INT32 first = 1;
if (first)
{
CONS_Debug(DBG_RENDER, "WARNING: avoiding a crash in %s %d\n", __FILE__, __LINE__);
first = 0;
}
}
#ifdef PARANOIA
else
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
#endif
Z_Free(dc_source);
}
column = (column_t *)((UINT8 *)column + column->length + 4);
@ -746,7 +736,9 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight)
static void R_DrawVisSprite(vissprite_t *vis)
{
column_t *column;
void (*localcolfunc)(column_t *);
INT32 texturecolumn;
INT32 pwidth;
fixed_t frac;
patch_t *patch = vis->patch;
fixed_t this_scale = vis->mobj->scale;
@ -895,50 +887,52 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (vis->x2 >= vid.width)
vis->x2 = vid.width-1;
localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
lengthcol = SHORT(patch->height);
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
if (vis->scalestep)
{
// Papersprite drawing loop
pwidth = SHORT(patch->width);
// Papersprite drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep)
{
angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale;
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
if (texturecolumn < 0 || texturecolumn >= pwidth)
continue;
if (vis->xiscale < 0) // Flipped sprite
texturecolumn = SHORT(patch->width) - 1 - texturecolumn;
texturecolumn = pwidth - 1 - texturecolumn;
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
dc_iscale = (0xffffffffu / (unsigned)spryscale);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
if (vis->cut & SC_VFLIP)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
localcolfunc (column);
}
}
else
{
#ifdef RANGECHECK
pwidth = SHORT(patch->width);
#endif
// Non-paper drawing loop
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
{
#ifdef RANGECHECK
texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
#else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
#endif
if (vis->cut & SC_VFLIP)
R_DrawFlippedMaskedColumn(column, patch->height);
else
R_DrawMaskedColumn(column);
localcolfunc (column);
}
}
@ -1147,7 +1141,6 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
}
#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7.
//#ifdef POLYOBJECTS
// Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz
if (thing->type == MT_RING)
{
@ -1238,8 +1231,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
yscale = FixedDiv(projectiony, tz);
shadowxscale = FixedMul(thing->radius*2, scalemul);
shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz));
shadowyscale = min(shadowyscale, shadowxscale) / patch->height;
shadowxscale /= patch->width;
shadowyscale = min(shadowyscale, shadowxscale) / SHORT(patch->height);
shadowxscale /= SHORT(patch->width);
shadowskew = 0;
if (floorslope)
@ -1254,24 +1247,24 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
//CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope);
if (viewz < floorz)
shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
shadowyscale += FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
else
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope);
shadowyscale -= FixedMul(FixedMul(thing->radius*2 / SHORT(patch->height), scalemul), zslope);
shadowyscale = abs(shadowyscale);
shadowskew = xslope;
}
tx -= patch->width * shadowxscale/2;
tx -= SHORT(patch->width) * shadowxscale/2;
x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS;
if (x1 >= viewwidth) return;
tx += patch->width * shadowxscale;
tx += SHORT(patch->width) * shadowxscale;
x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--;
if (x2 < 0 || x2 <= x1) return;
if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes?
if (shadowyscale < FRACUNIT/SHORT(patch->height)) return; // fix some crashes?
shadow = R_NewVisSprite();
shadow->patch = patch;
@ -1286,8 +1279,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->dispoffset = vis->dispoffset - 5;
shadow->gx = thing->x;
shadow->gy = thing->y;
shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2;
shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale;
shadow->gzt = shadow->pz + SHORT(patch->height) * shadowyscale / 2;
shadow->gz = shadow->gzt - SHORT(patch->height) * shadowyscale;
shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale));
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale);
@ -1308,7 +1301,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale,
shadow->startfrac = 0;
//shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2);
shadow->xiscale = (patch->width<<FRACBITS)/(x2-x1+1); // fuck it
shadow->xiscale = (SHORT(patch->width)<<FRACBITS)/(x2-x1+1); // fuck it
if (shadow->x1 > x1)
shadow->startfrac += shadow->xiscale*(shadow->x1-x1);
@ -1534,10 +1527,10 @@ static void R_ProjectSprite(mobj_t *thing)
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = rotsprite->width << FRACBITS;
spr_height = rotsprite->height << FRACBITS;
spr_offset = rotsprite->leftoffset << FRACBITS;
spr_topoffset = rotsprite->topoffset << FRACBITS;
spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
@ -1695,7 +1688,7 @@ static void R_ProjectSprite(mobj_t *thing)
// PORTAL SPRITE CLIPPING
if (portalrender && portalclipline)
{
if (x2 < portalclipstart || x1 > portalclipend)
if (x2 < portalclipstart || x1 >= portalclipend)
return;
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
@ -1964,7 +1957,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// PORTAL SPRITE CLIPPING
if (portalrender && portalclipline)
{
if (x2 < portalclipstart || x1 > portalclipend)
if (x2 < portalclipstart || x1 >= portalclipend)
return;
if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0)
@ -2276,7 +2269,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
entry->ffloor = ds->thicksides[i];
}
}
#ifdef POLYOBJECTS_PLANES
// Check for a polyobject plane, but only if this is a front line
if (ds->curline->polyseg && ds->curline->polyseg->visplane && !ds->curline->side) {
plane = ds->curline->polyseg->visplane;
@ -2292,7 +2284,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
}
ds->curline->polyseg->visplane = NULL;
}
#endif
if (ds->maskedtexturecol)
{
entry = R_CreateDrawNode(head);
@ -2340,7 +2331,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
if (tempskip)
return;
#ifdef POLYOBJECTS_PLANES
// find all the remaining polyobject planes and add them on the end of the list
// probably this is a terrible idea if we wanted them to be sorted properly
// but it works getting them in for now
@ -2361,7 +2351,6 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
// note: no seg is set, for what should be obvious reasons
PolyObjects[i].visplane = NULL;
}
#endif
// No vissprites in this mask?
if (mask->vissprites[1] - mask->vissprites[0] == 0)

View File

@ -44,9 +44,10 @@ extern fixed_t sprtopscreen;
extern fixed_t sprbotscreen;
extern fixed_t windowtop;
extern fixed_t windowbottom;
extern INT32 lengthcol;
void R_DrawMaskedColumn(column_t *column);
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
void R_DrawFlippedMaskedColumn(column_t *column);
// ----------------
// SPRITE RENDERING

View File

@ -134,6 +134,7 @@ consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_Y
consvar_t cv_playsoundsifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef HAVE_OPENMPT
openmpt_module *openmpt_mhandle = NULL;
static CV_PossibleValue_t interpolationfilter_cons_t[] = {{0, "Default"}, {1, "None"}, {2, "Linear"}, {4, "Cubic"}, {8, "Windowed sinc"}, {0, NULL}};
consvar_t cv_modfilter = {"modfilter", "0", CV_SAVE|CV_CALL, interpolationfilter_cons_t, ModFilter_OnChange, 0, NULL, NULL, 0, 0, NULL};
#endif
@ -1456,6 +1457,7 @@ musicdef_t soundtestsfx = {
0, // with no conditions
0,
0,
0,
false,
NULL
};
@ -1651,6 +1653,8 @@ ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
fixed_t bpmf = FLOAT_TO_FIXED(bpm);
if (bpmf > 0)
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
} else if (!stricmp(stoken, "loopms")) {
def->loop_ms = atoi(textline);
} else {
CONS_Alert(CONS_WARNING,
"MUSICDEF: Invalid field '%s'. (file %s, line %d)\n",
@ -1672,7 +1676,7 @@ void S_LoadMusicDefs(UINT16 wadnum)
char *lf;
char *stoken;
size_t nlf;
size_t nlf = 0xFFFFFFFF;
size_t ncr;
musicdef_t *def = NULL;
@ -1907,6 +1911,10 @@ UINT32 S_GetMusicPosition(void)
/// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers!
/// ------------------------
char music_stack_nextmusname[7];
boolean music_stack_noposition = false;
UINT32 music_stack_fadeout = 0;
UINT32 music_stack_fadein = 0;
static musicstack_t *music_stacks = NULL;
static musicstack_t *last_music_stack = NULL;
@ -2262,6 +2270,8 @@ static void S_UnloadMusic(void)
static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
{
musicdef_t *def;
if (S_MusicDisabled())
return false;
@ -2273,6 +2283,17 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
return false;
}
/* set loop point from MUSICDEF */
for (def = musicdefstart; def; def = def->next)
{
if (strcasecmp(def->name, music_name) == 0)
{
if (def->loop_ms)
S_SetMusicLoopPoint(def->loop_ms);
break;
}
}
S_InitMusicVolume(); // switch between digi and sequence volume
if (S_MusicNotInFocus())

View File

@ -22,7 +22,7 @@
#ifdef HAVE_OPENMPT
#include "libopenmpt/libopenmpt.h"
openmpt_module *openmpt_mhandle;
extern openmpt_module *openmpt_mhandle;
#endif
// mask used to indicate sound origin is player item pickup
@ -208,6 +208,7 @@ typedef struct musicdef_s
INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here
tic_t stoppingtics;
fixed_t bpm;
UINT32 loop_ms;/* override LOOPPOINT/LOOPMS */
boolean allowed; // question marks or listenable on sound test?
struct musicdef_s *next;
} musicdef_t;
@ -261,10 +262,10 @@ typedef struct musicstack_s
struct musicstack_s *next;
} musicstack_t;
char music_stack_nextmusname[7];
boolean music_stack_noposition;
UINT32 music_stack_fadeout;
UINT32 music_stack_fadein;
extern char music_stack_nextmusname[7];
extern boolean music_stack_noposition;
extern UINT32 music_stack_fadeout;
extern UINT32 music_stack_fadein;
void S_SetStackAdjustmentStart(void);
void S_AdjustMusicStackTics(void);
@ -332,7 +333,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#ifdef MUSICSLOT_COMPATIBILITY
// For compatibility with code/scripts relying on older versions
// This is a list of all the "special" slot names and their associated numbers
const char *compat_special_music_slots[16];
extern const char *compat_special_music_slots[16];
#endif
#endif

View File

@ -449,7 +449,7 @@ void SCR_ActuallyChangeRenderer(void)
#ifdef HWRENDER
// Well, it didn't even load anyway.
if ((hwrenderloaded == -1) && (setrenderneeded == render_opengl))
if ((vid_opengl_state == -1) && (setrenderneeded == render_opengl))
{
if (M_CheckParm("-nogl"))
CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n");
@ -474,7 +474,7 @@ void SCR_ChangeRenderer(void)
{
target_renderer = cv_renderer.value;
#ifdef HWRENDER
if (M_CheckParm("-opengl") && (hwrenderloaded == 1))
if (M_CheckParm("-opengl") && (vid_opengl_state == 1))
target_renderer = rendermode = render_opengl;
else
#endif
@ -526,6 +526,9 @@ void SCR_DisplayTicRate(void)
INT32 ticcntcolor = 0;
const INT32 h = vid.height-(8*vid.dupy);
if (gamestate == GS_NULL)
return;
for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i)
fpsgraph[i % TICRATE] = false;
@ -538,10 +541,16 @@ void SCR_DisplayTicRate(void)
if (totaltics <= TICRATE/2) ticcntcolor = V_REDMAP;
else if (totaltics == TICRATE) ticcntcolor = V_GREENMAP;
V_DrawString(vid.width-(72*vid.dupx), h,
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
V_DrawString(vid.width-(40*vid.dupx), h,
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE));
if (cv_ticrate.value == 2) // compact counter
V_DrawString(vid.width-(16*vid.dupx), h,
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d", totaltics));
else if (cv_ticrate.value == 1) // full counter
{
V_DrawString(vid.width-(72*vid.dupx), h,
V_YELLOWMAP|V_NOSCALESTART|V_USERHUDTRANS, "FPS:");
V_DrawString(vid.width-(40*vid.dupx), h,
ticcntcolor|V_NOSCALESTART|V_USERHUDTRANS, va("%02d/%02u", totaltics, TICRATE));
}
lasttic = ontic;
}

View File

@ -213,6 +213,7 @@
<ClInclude Include="..\fastcmp.h" />
<ClInclude Include="..\filesrch.h" />
<ClInclude Include="..\f_finale.h" />
<ClInclude Include="..\g_demo.h" />
<ClInclude Include="..\g_game.h" />
<ClInclude Include="..\g_input.h" />
<ClInclude Include="..\g_state.h" />
@ -364,6 +365,7 @@
<ClCompile Include="..\filesrch.c" />
<ClCompile Include="..\f_finale.c" />
<ClCompile Include="..\f_wipe.c" />
<ClCompile Include="..\g_demo.c" />
<ClCompile Include="..\g_game.c" />
<ClCompile Include="..\g_input.c" />
<ClCompile Include="..\hardware\hw3sound.c" />

View File

@ -180,6 +180,9 @@
<ClInclude Include="..\f_finale.h">
<Filter>F_Frame</Filter>
</ClInclude>
<ClInclude Include="..\g_demo.h">
<Filter>G_Game</Filter>
</ClInclude>
<ClInclude Include="..\g_game.h">
<Filter>G_Game</Filter>
</ClInclude>
@ -600,6 +603,9 @@
<ClCompile Include="..\f_wipe.c">
<Filter>F_Frame</Filter>
</ClCompile>
<ClCompile Include="..\g_demo.c">
<Filter>G_Game</Filter>
</ClCompile>
<ClCompile Include="..\g_game.c">
<Filter>G_Game</Filter>
</ClCompile>

View File

@ -27,7 +27,7 @@
#include <unistd.h>
#endif
#ifdef __unix__
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#include <errno.h>
#endif
@ -142,7 +142,7 @@ int main(int argc, char **argv)
const char *reldir;
int left;
boolean fileabs;
#ifdef __unix__
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
const char *link;
#endif
@ -201,7 +201,7 @@ int main(int argc, char **argv)
M_PathParts(logdir) - 1,
M_PathParts(logfilename) - 1, 0755);
#ifdef __unix__
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
logstream = fopen(logfilename, "w");
#ifdef DEFAULTDIR
if (logdir)
@ -214,9 +214,9 @@ int main(int argc, char **argv)
{
I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno));
}
#else/*__unix__*/
#else/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/
logstream = fopen("latest-log.txt", "wt+");
#endif/*__unix__*/
#endif/*defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)*/
}
//I_OutputMsg("I_StartupSystem() ...\n");

View File

@ -2484,7 +2484,7 @@ void I_RemoveExitFunc(void (*func)())
}
}
#ifndef __unix__
#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))
static void Shittycopyerror(const char *name)
{
I_OutputMsg(
@ -2524,7 +2524,7 @@ static void Shittylogcopy(void)
Shittycopyerror(logfilename);
}
}
#endif/*__unix__*/
#endif/*!(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))*/
//
// Closes down everything. This includes restoring the initial
@ -2548,7 +2548,7 @@ void I_ShutdownSystem(void)
if (logstream)
{
I_OutputMsg("I_ShutdownSystem(): end of logstream.\n");
#ifndef __unix__
#if !(defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON))
Shittylogcopy();
#endif
fclose(logstream);

View File

@ -104,7 +104,7 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff
static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
UINT8 graphics_started = 0; // Is used in console.c and screen.c
INT32 hwrenderloaded = 0;
INT32 vid_opengl_state = 0;
// To disable fullscreen at startup; is set in VID_PrepareModeList
boolean allow_fullscreen = false;
@ -217,7 +217,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen, SDL_bool
else
{
Impl_CreateWindow(fullscreen);
Impl_SetWindowIcon();
wasfullscreen = fullscreen;
SDL_SetWindowSize(window, width, height);
if (fullscreen)
@ -372,7 +371,9 @@ static boolean IgnoreMouse(void)
return false;
if (menuactive)
return !M_MouseNeeded();
if (paused || con_destlines || chat_on || gamestate != GS_LEVEL)
if (paused || con_destlines || chat_on)
return true;
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION && gamestate != GS_CUTSCENE)
return true;
return false;
}
@ -1440,7 +1441,7 @@ static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
if ((rendermode == render_opengl) && (hwrenderloaded != -1))
if ((rendermode == render_opengl) && (vid_opengl_state != -1))
{
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
@ -1473,10 +1474,10 @@ static SDL_bool Impl_CreateContext(void)
return SDL_TRUE;
}
#ifdef HWRENDER
static void VID_CheckGLLoaded(rendermode_t oldrender)
void VID_CheckGLLoaded(rendermode_t oldrender)
{
if (hwrenderloaded == -1) // Well, it didn't work the first time anyway.
#ifdef HWRENDER
if (vid_opengl_state == -1) // Well, it didn't work the first time anyway.
{
rendermode = oldrender;
if (chosenrendermode == render_opengl) // fallback to software
@ -1488,40 +1489,66 @@ static void VID_CheckGLLoaded(rendermode_t oldrender)
setrenderneeded = 0;
}
}
}
#endif
}
void VID_CheckRenderer(void)
{
SDL_bool rendererchanged = SDL_FALSE;
boolean rendererchanged = false;
boolean contextcreated = false;
rendermode_t oldrenderer = rendermode;
if (dedicated)
return;
#ifdef HWRENDER
if (!graphics_started)
VID_CheckGLLoaded(oldrenderer);
#endif
if (setrenderneeded)
{
rendermode = setrenderneeded;
rendererchanged = SDL_TRUE;
rendererchanged = true;
#ifdef HWRENDER
if (rendermode == render_opengl)
{
VID_CheckGLLoaded(oldrenderer);
// Initialise OpenGL before calling SDLSetMode!!!
if (hwrenderloaded != 1)
I_StartupHardwareGraphics();
else if (hwrenderloaded == -1)
rendererchanged = SDL_FALSE;
// This is because SDLSetMode calls OglSdlSurface.
if (vid_opengl_state == 0)
{
VID_StartupOpenGL();
// Loaded successfully!
if (vid_opengl_state == 1)
{
// Destroy the current window, if it exists.
if (window)
{
SDL_DestroyWindow(window);
window = NULL;
}
// Destroy the current window rendering context, if that also exists.
if (renderer)
{
SDL_DestroyRenderer(renderer);
renderer = NULL;
}
// Create a new window.
Impl_CreateWindow(USE_FULLSCREEN);
// From there, the OpenGL context was already created.
contextcreated = true;
}
}
else if (vid_opengl_state == -1)
rendererchanged = false;
}
#endif
Impl_CreateContext();
if (!contextcreated)
Impl_CreateContext();
setrenderneeded = 0;
}
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN, (rendererchanged ? SDL_FALSE : SDL_TRUE));
@ -1534,15 +1561,25 @@ void VID_CheckRenderer(void)
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
if (rendererchanged)
{
#ifdef HWRENDER
if (hwrenderloaded == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
if (vid_opengl_state == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
SCR_SetDrawFuncs();
}
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
R_InitHardwareMode();
{
if (rendererchanged)
{
R_InitHardwareMode();
V_SetPalette(0);
}
}
#else
(void)oldrenderer;
#endif
@ -1586,7 +1623,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (hwrenderloaded != -1)
if (vid_opengl_state == 1)
flags |= SDL_WINDOW_OPENGL;
#endif
@ -1594,12 +1631,15 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
realwidth, realheight, flags);
if (window == NULL)
{
CONS_Printf(M_GetText("Couldn't create window: %s\n"), SDL_GetError());
return SDL_FALSE;
}
Impl_SetWindowIcon();
return Impl_CreateContext();
}
@ -1616,12 +1656,8 @@ static void Impl_SetWindowName(const char *title)
static void Impl_SetWindowIcon(void)
{
if (window == NULL || icoSurface == NULL)
{
return;
}
//SDL2STUB(); // Monster Iestyn: why is this stubbed?
SDL_SetWindowIcon(window, icoSurface);
if (window && icoSurface)
SDL_SetWindowIcon(window, icoSurface);
}
static void Impl_VideoSetupSDLBuffer(void)
@ -1720,13 +1756,19 @@ void I_StartupGraphics(void)
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f();
#ifdef HWRENDER
if (M_CheckParm("-nogl"))
hwrenderloaded = -1; // Don't call SDL_GL_LoadLibrary
else
I_StartupHardwareGraphics();
vid_opengl_state = -1; // Don't startup OpenGL
else if (chosenrendermode == render_opengl)
VID_StartupOpenGL();
#endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
// Fury: we do window initialization after GL setup to allow
// SDL_GL_LoadLibrary to work well on Windows
@ -1745,11 +1787,6 @@ void I_StartupGraphics(void)
#ifdef HAVE_TTF
I_ShutdownTTF();
#endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
Impl_SetWindowIcon();
VID_SetMode(VID_GetModeForSize(BASEVIDWIDTH, BASEVIDHEIGHT));
@ -1779,12 +1816,13 @@ void I_StartupGraphics(void)
graphics_started = true;
}
void I_StartupHardwareGraphics(void)
void VID_StartupOpenGL(void)
{
#ifdef HWRENDER
static boolean glstartup = false;
if (!glstartup)
{
CONS_Printf("VID_StartupOpenGL()...\n");
HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
@ -1816,13 +1854,13 @@ void I_StartupHardwareGraphics(void)
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
{
CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));
hwrenderloaded = -1;
CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable!\nBe sure you have installed SRB2 properly.\n"));
vid_opengl_state = -1;
}
else
hwrenderloaded = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library
vid_opengl_state = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library
if (hwrenderloaded == -1)
if (vid_opengl_state == -1)
{
rendermode = render_soft;
setrenderneeded = 0;

View File

@ -1219,7 +1219,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.2.2;
CURRENT_PROJECT_VERSION = 2.2.4;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1231,7 +1231,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.2.2;
CURRENT_PROJECT_VERSION = 2.2.4;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -527,7 +527,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"},
{"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"},
{"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Humming power"},
{"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"},
{"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accelerating"},
{"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"},
{"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Impact"},

View File

@ -1325,12 +1325,21 @@ void ST_drawTitleCard(void)
{
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl;
INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
INT32 lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlscroll = FixedInt(lt_scroll);
INT32 zzticker;
patch_t *actpat, *zigzag, *zztext;
UINT8 colornum;
const UINT8 *colormap;
if (players[consoleplayer].skincolor)
colornum = players[consoleplayer].skincolor;
else
colornum = cv_playercolor.value;
colormap = R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE);
if (!G_IsTitleCardAvailable())
return;
@ -1364,16 +1373,21 @@ void ST_drawTitleCard(void)
if (!splitscreen || (splitscreen && stplyr == &players[displayplayer]))
{
zzticker = lt_ticker;
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag);
V_DrawScaledPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
V_DrawScaledPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext);
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zigzag->height-zzticker) % zigzag->height, V_SNAPTOTOP|V_SNAPTOLEFT, zigzag, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (-zigzag->height+zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
V_DrawMappedPatch(FixedInt(lt_zigzag), (zzticker) % zztext->height, V_SNAPTOTOP|V_SNAPTOLEFT, zztext, colormap);
}
if (actnum)
{
if (!splitscreen)
V_DrawScaledPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat);
{
if (actnum > 9) // slightly offset the act diamond for two-digit act numbers
V_DrawMappedPatch(ttlnumxpos + (V_LevelActNumWidth(actnum)/4) + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
else
V_DrawMappedPatch(ttlnumxpos + ttlscroll, 104 - ttlscroll, 0, actpat, colormap);
}
V_DrawLevelActNum(ttlnumxpos + ttlscroll, 104, V_PERPLAYER, actnum);
}

View File

@ -42,7 +42,8 @@ UINT8 *screens[5];
// screens[3] = fade screen start
// screens[4] = fade screen end, postimage tempoarary buffer
consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t ticrate_cons_t[] = {{0, "No"}, {1, "Full"}, {2, "Compact"}, {0, NULL}};
consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, ticrate_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_palette_OnChange(void);
@ -2951,13 +2952,19 @@ void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits)
}
// Draw an act number for a level title
// Todo: actually draw two-digit numbers as two act num patches
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num)
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num)
{
if (num < 0 || num > 19)
if (num > 99)
return; // not supported
V_DrawScaledPatch(x, y, flags, ttlnum[num]);
while (num > 0)
{
if (num > 9) // if there are two digits, draw second digit first
V_DrawScaledPatch(x + (V_LevelActNumWidth(num) - V_LevelActNumWidth(num%10)), y, flags, ttlnum[num%10]);
else
V_DrawScaledPatch(x, y, flags, ttlnum[num]);
num = num/10;
}
}
// Write a string using the credit font
@ -3338,13 +3345,21 @@ INT32 V_LevelNameHeight(const char *string)
}
// For ST_drawTitleCard
// Returns the width of the act num patch
INT32 V_LevelActNumWidth(INT32 num)
// Returns the width of the act num patch(es)
INT16 V_LevelActNumWidth(UINT8 num)
{
if (num < 0 || num > 19)
return 0; // not a valid number
INT16 result = 0;
return SHORT(ttlnum[num]->width);
if (num == 0)
result = SHORT(ttlnum[num]->width);
while (num > 0 && num <= 99)
{
result = result + SHORT(ttlnum[num%10]->width);
num = num/10;
}
return result;
}
//

View File

@ -238,12 +238,12 @@ void V_DrawRightAlignedSmallThinStringAtFixed(fixed_t x, fixed_t y, INT32 option
// Draw tall nums, used for menu, HUD, intermission
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawLevelActNum(INT32 x, INT32 y, INT32 flags, UINT8 num);
// Find string width from lt_font chars
INT32 V_LevelNameWidth(const char *string);
INT32 V_LevelNameHeight(const char *string);
INT32 V_LevelActNumWidth(INT32 num); // act number width
INT16 V_LevelActNumWidth(UINT8 num); // act number width
void V_DrawCreditString(fixed_t x, fixed_t y, INT32 option, const char *string);
INT32 V_CreditStringWidth(const char *string);

View File

@ -76,6 +76,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
#endif
#ifdef _DEBUG
#include "console.h"
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
@ -92,7 +96,7 @@ typedef struct
typedef struct lumpnum_cache_s
{
char lumpname[8];
char lumpname[32];
lumpnum_t lumpnum;
} lumpnum_cache_t;
@ -114,13 +118,18 @@ void W_Shutdown(void)
{
while (numwadfiles--)
{
fclose(wadfiles[numwadfiles]->handle);
Z_Free(wadfiles[numwadfiles]->filename);
while (wadfiles[numwadfiles]->numlumps--)
Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2);
wadfile_t *wad = wadfiles[numwadfiles];
Z_Free(wadfiles[numwadfiles]->lumpinfo);
Z_Free(wadfiles[numwadfiles]);
fclose(wad->handle);
Z_Free(wad->filename);
while (wad->numlumps--)
{
Z_Free(wad->lumpinfo[wad->numlumps].longname);
Z_Free(wad->lumpinfo[wad->numlumps].fullname);
}
Z_Free(wad->lumpinfo);
Z_Free(wad);
}
}
@ -194,7 +203,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
if (posStart != INT16_MAX)
{
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
posStart++; // first "lump" will be "Lua/" folder itself, so ignore it
for (; posStart < posEnd; posStart++)
LUA_LoadLump(wadnum, posStart);
}
@ -204,13 +212,12 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
{
posEnd = W_CheckNumForFolderEndPK3("SOC/", wadnum, posStart);
posStart++; // first "lump" will be "SOC/" folder itself, so ignore it
for(; posStart < posEnd; posStart++)
{
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
char *name = malloc(length + 1);
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
name[length] = '\0';
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
@ -237,9 +244,9 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
{ // shameless copy+paste of code from LUA_LoadLump
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
char *name = malloc(length + 1);
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->fullname);
name[length] = '\0';
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
@ -341,10 +348,17 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
lumpinfo->size = ftell(handle);
fseek(handle, 0, SEEK_SET);
strcpy(lumpinfo->name, lumpname);
// Allocate the lump's long name.
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->longname, lumpname);
lumpinfo->longname[8] = '\0';
// Allocate the lump's full name.
lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->name2, lumpname);
lumpinfo->name2[8] = '\0';
lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->fullname, lumpname);
lumpinfo->fullname[8] = '\0';
*numlumps = 1;
return lumpinfo;
}
@ -431,10 +445,16 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
lump_p->compression = CM_NOCOMPRESSION;
memset(lump_p->name, 0x00, 9);
strncpy(lump_p->name, fileinfo->name, 8);
// Allocate the lump's long name.
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->longname, fileinfo->name, 8);
lump_p->longname[8] = '\0';
// Allocate the lump's full name.
lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->name2, fileinfo->name, 8);
lump_p->name2[8] = '\0';
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->fullname, fileinfo->name, 8);
lump_p->fullname[8] = '\0';
}
free(fileinfov);
*nlmp = numlumps;
@ -525,8 +545,8 @@ typedef struct zlentry_s
static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
{
zend_t zend;
zentry_t* zentries;
zentry_t* zentry;
zentry_t zentry;
zlentry_t zlentry;
UINT16 numlumps = *nlmp;
lumpinfo_t* lumpinfo;
@ -554,40 +574,36 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
numlumps = zend.entries;
lump_p = lumpinfo = Z_Malloc(numlumps * sizeof (*lumpinfo), PU_STATIC, NULL);
zentry = zentries = malloc(numlumps * sizeof (*zentries));
fseek(handle, zend.cdiroffset, SEEK_SET);
for (i = 0; i < numlumps; i++, zentry++, lump_p++)
for (i = 0; i < numlumps; i++, lump_p++)
{
char* fullname;
char* trimname;
char* dotpos;
if (fread(zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
if (fread(&zentry, 1, sizeof(zentry_t), handle) < sizeof(zentry_t))
{
CONS_Alert(CONS_ERROR, "Failed to read central directory (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
return NULL;
}
if (memcmp(zentry->signature, pat_central, 4))
if (memcmp(zentry.signature, pat_central, 4))
{
CONS_Alert(CONS_ERROR, "Central directory is corrupt\n");
Z_Free(lumpinfo);
free(zentries);
return NULL;
}
lump_p->position = zentry->offset + zentry->namelen + zentry->xtralen + sizeof(zlentry_t);
lump_p->disksize = zentry->compsize;
lump_p->size = zentry->size;
lump_p->position = zentry.offset; // NOT ACCURATE YET: we still need to read the local entry to find our true position
lump_p->disksize = zentry.compsize;
lump_p->size = zentry.size;
fullname = malloc(zentry->namelen + 1);
if (fgets(fullname, zentry->namelen + 1, handle) != fullname)
fullname = malloc(zentry.namelen + 1);
if (fgets(fullname, zentry.namelen + 1, handle) != fullname)
{
CONS_Alert(CONS_ERROR, "Unable to read lumpname (%s)\n", M_FileError(handle));
Z_Free(lumpinfo);
free(zentries);
free(fullname);
return NULL;
}
@ -604,12 +620,15 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
lump_p->name2 = Z_Calloc(zentry->namelen + 1, PU_STATIC, NULL);
strncpy(lump_p->name2, fullname, zentry->namelen);
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
strncpy(lump_p->fullname, fullname, zentry.namelen);
free(fullname);
switch(zentry->compression)
switch(zentry.compression)
{
case 0:
lump_p->compression = CM_NOCOMPRESSION;
@ -627,9 +646,29 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
lump_p->compression = CM_UNSUPPORTED;
break;
}
// skip and ignore comments/extra fields
if (fseek(handle, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
{
CONS_Alert(CONS_ERROR, "Central directory is corrupt\n");
Z_Free(lumpinfo);
return NULL;
}
}
free(zentries);
// Adjust lump position values properly
for (i = 0, lump_p = lumpinfo; i < numlumps; i++, lump_p++)
{
// skip and ignore comments/extra fields
if ((fseek(handle, lump_p->position, SEEK_SET) != 0) || (fread(&zlentry, 1, sizeof(zlentry_t), handle) < sizeof(zlentry_t)))
{
CONS_Alert(CONS_ERROR, "Local headers for lump %s are corrupt\n", lump_p->fullname);
Z_Free(lumpinfo);
return NULL;
}
lump_p->position += sizeof(zlentry_t) + zlentry.namelen + zlentry.xtralen;
}
*nlmp = numlumps;
return lumpinfo;
@ -887,16 +926,14 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum)
UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[9];
memset(uname, 0x00, sizeof uname);
strncpy(uname, name, 8);
uname[8] = 0;
strupr(uname);
static char uname[8 + 1];
if (!TestValidLump(wad,0))
return INT16_MAX;
strlcpy(uname, name, sizeof uname);
strupr(uname);
//
// scan forward
// start at 'startlump', useful parameter when there are multiple
@ -906,7 +943,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (memcmp(lump_p->name,uname,8) == 0)
if (!strncmp(lump_p->name, uname, sizeof(uname) - 1))
return i;
}
@ -914,15 +951,66 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
return INT16_MAX;
}
//
// Like W_CheckNumForNamePwad, but can find entries with long names
//
// Should be the only version, but that's not possible until we fix
// all the instances of non null-terminated strings in the codebase...
//
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[256 + 1];
if (!TestValidLump(wad,0))
return INT16_MAX;
strlcpy(uname, name, sizeof uname);
strupr(uname);
//
// scan forward
// start at 'startlump', useful parameter when there are multiple
// resources with the same name
//
if (startlump < wadfiles[wad]->numlumps)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (!strcmp(lump_p->longname, uname))
return i;
}
// not found.
return INT16_MAX;
}
UINT16
W_CheckNumForMarkerStartPwad (const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 marker;
marker = W_CheckNumForNamePwad(name, wad, startlump);
if (marker != INT16_MAX)
marker++; // Do not count the first marker
return marker;
}
// Look for the first lump from a folder.
UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump)
{
size_t name_length;
INT32 i;
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
name_length = strlen(name);
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (strnicmp(name, lump_p->name2, strlen(name)) == 0)
if (strnicmp(name, lump_p->fullname, name_length) == 0)
{
/* SLADE is special and puts a single directory entry. Skip that. */
if (strlen(lump_p->fullname) == name_length)
i++;
break;
}
}
return i;
}
@ -936,7 +1024,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (strnicmp(name, lump_p->name2, strlen(name)))
if (strnicmp(name, lump_p->fullname, strlen(name)))
break;
}
return i;
@ -950,7 +1038,7 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump)
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (!strnicmp(name, lump_p->name2, strlen(name)))
if (!strnicmp(name, lump_p->fullname, strlen(name)))
{
return i;
}
@ -975,7 +1063,8 @@ lumpnum_t W_CheckNumForName(const char *name)
// most recent entries first
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
{
if (strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
if (!lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname[8]
&& strncmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name, 8) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
@ -995,6 +1084,7 @@ lumpnum_t W_CheckNumForName(const char *name)
{
// Update the cache.
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
strncpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 8);
lumpnumcache[lumpnumcacheindex].lumpnum = (i<<16)+check;
@ -1002,6 +1092,55 @@ lumpnum_t W_CheckNumForName(const char *name)
}
}
//
// Like W_CheckNumForName, but can find entries with long names
//
// Should be the only version, but that's not possible until we fix
// all the instances of non null-terminated strings in the codebase...
//
lumpnum_t W_CheckNumForLongName(const char *name)
{
INT32 i;
lumpnum_t check = INT16_MAX;
if (!*name) // some doofus gave us an empty string?
return LUMPERROR;
// Check the lumpnumcache first. Loop backwards so that we check
// most recent entries first
for (i = lumpnumcacheindex + LUMPNUMCACHESIZE; i > lumpnumcacheindex; i--)
{
if (strcmp(lumpnumcache[i & (LUMPNUMCACHESIZE - 1)].lumpname, name) == 0)
{
lumpnumcacheindex = i & (LUMPNUMCACHESIZE - 1);
return lumpnumcache[lumpnumcacheindex].lumpnum;
}
}
// scan wad files backwards so patch lump files take precedence
for (i = numwadfiles - 1; i >= 0; i--)
{
check = W_CheckNumForLongNamePwad(name,(UINT16)i,0);
if (check != INT16_MAX)
break; //found it
}
if (check == INT16_MAX) return LUMPERROR;
else
{
if (strlen(name) < 32)
{
// Update the cache.
lumpnumcacheindex = (lumpnumcacheindex + 1) & (LUMPNUMCACHESIZE - 1);
memset(lumpnumcache[lumpnumcacheindex].lumpname, '\0', 32);
strlcpy(lumpnumcache[lumpnumcacheindex].lumpname, name, 32);
lumpnumcache[lumpnumcacheindex].lumpnum = (i << 16) + check;
}
return (i << 16) + check;
}
}
// Look for valid map data through all added files in descendant order.
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
// TODO: Make it search through cache first, maybe...?
@ -1025,7 +1164,7 @@ lumpnum_t W_CheckNumForMap(const char *name)
else
continue;
// Now look for the specified map.
for (++lumpNum; lumpNum < end; lumpNum++)
for (; lumpNum < end; lumpNum++)
if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8))
return (i<<16) + lumpNum;
}
@ -1050,6 +1189,24 @@ lumpnum_t W_GetNumForName(const char *name)
return i;
}
//
// Like W_GetNumForName, but can find entries with long names
//
// Should be the only version, but that's not possible until we fix
// all the instances of non null-terminated strings in the codebase...
//
lumpnum_t W_GetNumForLongName(const char *name)
{
lumpnum_t i;
i = W_CheckNumForLongName(name);
if (i == LUMPERROR)
I_Error("W_GetNumForLongName: %s not found!\n", name);
return i;
}
//
// W_CheckNumForNameInBlock
// Checks only in blocks from blockstart lump to blockend lump
@ -1089,7 +1246,7 @@ UINT8 W_LumpExists(const char *name)
{
lumpinfo_t *lump_p = wadfiles[i]->lumpinfo;
for (j = 0; j < wadfiles[i]->numlumps; ++j, ++lump_p)
if (fastcmp(lump_p->name,name))
if (fastcmp(lump_p->longname, name))
return true;
}
return false;
@ -1120,7 +1277,7 @@ boolean W_IsLumpWad(lumpnum_t lumpnum)
{
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
{
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->name2;
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->fullname;
if (strlen(lumpfullName) < 4)
return false; // can't possibly be a WAD can it?
@ -1138,7 +1295,7 @@ boolean W_IsLumpFolder(UINT16 wad, UINT16 lump)
{
if (wadfiles[wad]->type == RET_PK3)
{
const char *name = wadfiles[wad]->lumpinfo[lump].name2;
const char *name = wadfiles[wad]->lumpinfo[lump].fullname;
return (name[strlen(name)-1] == '/'); // folders end in '/'
}
@ -1216,7 +1373,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
{
size_t bytesread = fread(dest, 1, size, handle);
if (R_IsLumpPNG((UINT8 *)dest, bytesread))
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
return bytesread;
}
#else
@ -1258,7 +1415,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
Z_Free(decData);
#ifdef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)dest, size))
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
#endif
return size;
#else
@ -1321,7 +1478,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
#ifdef NO_PNG_LUMPS
if (R_IsLumpPNG((UINT8 *)dest, size))
W_ThrowPNGError(l->name2, wadfiles[wad]->filename);
W_ThrowPNGError(l->fullname, wadfiles[wad]->filename);
#endif
return size;
}
@ -1505,6 +1662,57 @@ void *W_CacheLumpName(const char *name, INT32 tag)
// Cache a patch into heap memory, convert the patch format as necessary
//
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
lumpcache_t *lumpcache = NULL;
if (needpatchflush)
W_FlushCachedPatches();
if (!TestValidLump(wad, lump))
return NULL;
lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata;
#ifndef NO_PNG_LUMPS
void *srcdata = NULL;
#endif
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
}
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
{
return W_CacheSoftwarePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
#ifdef HWRENDER
@ -1522,39 +1730,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
if (rendermode == render_soft || rendermode == render_none)
#endif
{
lumpcache_t *lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata;
#ifndef NO_PNG_LUMPS
void *srcdata = NULL;
#endif
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
return W_CacheSoftwarePatchNumPwad(wad, lump, tag);
}
#ifdef HWRENDER
@ -1611,6 +1787,17 @@ void *W_CachePatchName(const char *name, INT32 tag)
return W_CachePatchNum(W_GetNumForName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
void *W_CachePatchLongName(const char *name, INT32 tag)
{
lumpnum_t num;
num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
#ifndef NOMD5
#define MD5_LEN 16
@ -1829,6 +2016,10 @@ W_VerifyPK3 (FILE *fp, lumpchecklist_t *checklist, boolean status)
}
free(fullname);
// skip and ignore comments/extra fields
if (fseek(fp, zentry.xtralen + zentry.commlen, SEEK_CUR) != 0)
return true;
}
return true;

Some files were not shown because too many files have changed in this diff Show More