From 4396f4b59d6657b737f29b3d4e398c8277736e0f Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 18 Aug 2024 16:24:15 +0100 Subject: [PATCH 01/10] k_color: Fix support for more than 255 skincolors Resolves KartKrew/RingRacers#109 --- src/k_color.c | 6 +++--- src/k_color.h | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/k_color.c b/src/k_color.c index c7b0bbf91..a71faaa4c 100644 --- a/src/k_color.c +++ b/src/k_color.c @@ -43,11 +43,11 @@ UINT16 K_RainbowColor(tic_t time) } /*-------------------------------------------------- - void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) + void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor) See header file for description. --------------------------------------------------*/ -void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) +void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor) { INT32 i; RGBA_t color; @@ -95,7 +95,7 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) See header file for description. --------------------------------------------------*/ -void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) +void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, skincolornum_t color) { INT32 i; INT32 starttranscolor; diff --git a/src/k_color.h b/src/k_color.h index 6e94ed2f5..0bcd2a16e 100644 --- a/src/k_color.h +++ b/src/k_color.h @@ -51,7 +51,7 @@ UINT8 K_ColorRelativeLuminance(UINT8 r, UINT8 g, UINT8 b); UINT16 K_RainbowColor(tic_t time); /*-------------------------------------------------- - void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); + void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor); Generates a colormap to "colorize" all palette indicies to the provided skincolor. @@ -64,11 +64,11 @@ UINT16 K_RainbowColor(tic_t time); None --------------------------------------------------*/ -void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); +void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor); /*-------------------------------------------------- - void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); + void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, skincolornum_t color); Generates a translation colormap for Kart, to replace R_GenerateTranslationColormap in r_draw.c @@ -80,6 +80,7 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); Return:- None --------------------------------------------------*/ -void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); + +void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, skincolornum_t color); #endif From 784099c85ae59a621c0af3f499902871d84a2f55 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:14:22 -0400 Subject: [PATCH 02/10] Fix encore music replacing start music --- src/p_tick.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_tick.c b/src/p_tick.c index 8016cdc80..3c4f11238 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -685,11 +685,17 @@ void P_Ticker(boolean run) S_StartSound(NULL, sfx_s3kad); // GO! } } - if (leveltime == (starttime + (TICRATE/2))) + + if (leveltime < starttime) // SRB2Kart + S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); // yes this will be spammed otherwise encore and some stuff WILL overwrite it + else if (leveltime == starttime) // The GO! sound stops the level start ambience + S_StopMusic(); + else if (leveltime == starttime + (TICRATE/2)) // Plays the music after the starting countdown. { S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); S_ShowMusicCredit(); } + } ps_lua_thinkframe_time = I_GetPreciseTime(); From 6a6b804339846a8ca1ef51424879e2770288aa95 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Mon, 21 Oct 2024 23:55:41 -0400 Subject: [PATCH 03/10] Fix mapid music lumps --- src/s_sound.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 3413f05a9..e95c110ed 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2521,7 +2521,12 @@ void S_InitLevelMusic(boolean fromnetsave) mapmusrng = 0; } } - strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname[mapmusrng], 7); + + if (mapheaderinfo[gamemap-1]->musname[0][0] == 0) + strncpy(mapmusname, va("%sM", G_BuildMapName(gamemap)), 7); + else + strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname[mapmusrng], 7); + mapmusname[6] = 0; mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK); mapmusposition = mapheaderinfo[gamemap-1]->muspos; From dc5ec519812cc7aed650b87e3a1b8512ef5b8bf4 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 22 Oct 2024 00:10:33 -0400 Subject: [PATCH 04/10] Push cmd.angle to lua --- src/lua_playerlib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 59ace7435..8aa440333 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -931,6 +931,8 @@ static int ticcmd_get(lua_State *L) lua_pushinteger(L, cmd->sidemove); else if (fastcmp(field,"turning")) lua_pushinteger(L, cmd->turning); + else if (fastcmp(field,"angle")) + lua_pushinteger(L, cmd->angle); else if (fastcmp(field,"throwdir")) lua_pushinteger(L, cmd->throwdir); else if (fastcmp(field,"aiming")) @@ -961,6 +963,8 @@ static int ticcmd_set(lua_State *L) cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"turning")) cmd->turning = (INT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"angle")) + cmd->angle = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"throwdir")) cmd->throwdir = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"aiming")) From 8b87544579d8a9c9a78880d1e389c534cd195c74 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 22 Oct 2024 00:17:42 -0400 Subject: [PATCH 05/10] fix floorboost being pushed as a boolean --- src/lua_playerlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 8aa440333..b7e99eab4 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -331,7 +331,7 @@ static int player_get(lua_State *L) else if (fastcmp(field,"sneakertimer")) lua_pushinteger(L, plr->sneakertimer); else if (fastcmp(field,"floorboost")) - lua_pushboolean(L, plr->floorboost); + lua_pushinteger(L, plr->floorboost); else if (fastcmp(field,"waterrun")) lua_pushinteger(L, plr->waterrun); else if (fastcmp(field,"growshrinktimer")) From 66913e646172103eced463de8704044283844e2e Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 22 Oct 2024 02:08:07 -0400 Subject: [PATCH 06/10] Reimplement default Kart v1 medals --- src/d_main.c | 3 + src/m_cond.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/m_cond.h | 1 + 3 files changed, 180 insertions(+), 6 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 58da12a8d..87975cf6f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1412,6 +1412,9 @@ void D_SRB2Main(void) // Make backups of some SOCcable tables. P_BackupTables(); + + // Setup default unlockable conditions + M_SetupDefaultConditionSets(); // Setup character tables // Have to be done here before files are loaded diff --git a/src/m_cond.c b/src/m_cond.c index ceff3c167..7475894d4 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -29,18 +29,188 @@ UINT32 unlocktriggers; // The meat of this system lies in condition sets conditionset_t conditionSets[MAXCONDITIONSETS]; -// Emblem locations -emblem_t emblemlocations[MAXEMBLEMS]; +// Default Emblem locations +emblem_t emblemlocations[MAXEMBLEMS] = +{ + // GOLD DEV MEDALS + // These values are directly lifted from the Champion ghost, through the power of hex editing! + {ET_TIME, 0, 1, 'A', SKINCOLOR_GOLD, 3021, "", 0}, // Green Hills Zone - 1'26"31 + {ET_TIME, 0, 2, 'A', SKINCOLOR_GOLD, 4466, "", 0}, // Dark Race - 2'07"60 + {ET_TIME, 0, 3, 'A', SKINCOLOR_GOLD, 4337, "", 0}, // Northern District Zone - 2'03"91 + {ET_TIME, 0, 4, 'A', SKINCOLOR_GOLD, 3452, "", 0}, // Darkvile Garden Zone - 1'38"62 + {ET_TIME, 0, 5, 'A', SKINCOLOR_GOLD, 3525, "", 0}, // Daytona Speedway Zone - 1'40"71 + {ET_TIME, 0, 6, 'A', SKINCOLOR_GOLD, 4047, "", 0}, // Egg Zeppelin Zone - 1'55"62 + {ET_TIME, 0, 7, 'A', SKINCOLOR_GOLD, 4041, "", 0}, // Sonic Speedway Zone - 1'55"45 + {ET_TIME, 0, 8, 'A', SKINCOLOR_GOLD, 3281, "", 0}, // Hill Top Zone - 1'33"74 + {ET_TIME, 0, 9, 'A', SKINCOLOR_GOLD, 4764, "", 0}, // Misty Maze Zone - 2'16"11 + {ET_TIME, 0, 10, 'A', SKINCOLOR_GOLD, 4378, "", 0}, // Grand Metropolis - 2'05"08 + {ET_TIME, 0, 11, 'A', SKINCOLOR_GOLD, 3678, "", 0}, // Sunbeam Paradise Zone - 1'45"08 + {ET_TIME, 0, 12, 'A', SKINCOLOR_GOLD, 3928, "", 0}, // Diamond Square Zone - 1'52"22 + {ET_TIME, 0, 13, 'A', SKINCOLOR_GOLD, 3846, "", 0}, // Midnight Meadow Zone - 1'49"88 + {ET_TIME, 0, 14, 'A', SKINCOLOR_GOLD, 3278, "", 0}, // Twinkle Cart - 1'33"65 + {ET_TIME, 0, 15, 'A', SKINCOLOR_GOLD, 3591, "", 0}, // Pleasure Castle - 1'42"60 + {ET_TIME, 0, 16, 'A', SKINCOLOR_GOLD, 5187, "", 0}, // Paradise Hill Zone - 2'28"20 + {ET_TIME, 0, 17, 'A', SKINCOLOR_GOLD, 4976, "", 0}, // Sub-Zero Peak Zone - 2'22"17 + {ET_TIME, 0, 18, 'A', SKINCOLOR_GOLD, 3696, "", 0}, // Sapphire Coast Zone - 1'45"60 + {ET_TIME, 0, 19, 'A', SKINCOLOR_GOLD, 4931, "", 0}, // Sand Valley Zone - 2'20"88 + {ET_TIME, 0, 20, 'A', SKINCOLOR_GOLD, 4220, "", 0}, // Megablock Castle Zone - 2'00"57 + {ET_TIME, 0, 21, 'A', SKINCOLOR_GOLD, 4053, "", 0}, // Canyon Rush Zone - 1'55"80 + {ET_TIME, 0, 22, 'A', SKINCOLOR_GOLD, 3613, "", 0}, // Casino Resort Zone - 1'43"22 + {ET_TIME, 0, 23, 'A', SKINCOLOR_GOLD, 4385, "", 0}, // Silvercloud Island Zone - 2'05"28 + {ET_TIME, 0, 24, 'A', SKINCOLOR_GOLD, 5321, "", 0}, // Blue Mountain Zone - 2'32"02 + {ET_TIME, 0, 25, 'A', SKINCOLOR_GOLD, 4476, "", 0}, // Petroleum Refinery Zone - 2'07"88 + {ET_TIME, 0, 26, 'A', SKINCOLOR_GOLD, 3295, "", 0}, // Desert Palace Zone - 1'34"14 + {ET_TIME, 0, 27, 'A', SKINCOLOR_GOLD, 4765, "", 0}, // Aurora Atoll Zone - 2'16"14 + {ET_TIME, 0, 28, 'A', SKINCOLOR_GOLD, 4670, "", 0}, // Barren Badlands Zone - 2'13"42 + {ET_TIME, 0, 29, 'A', SKINCOLOR_GOLD, 5888, "", 0}, // Red Barrage Area - 2'48"22 + {ET_TIME, 0, 30, 'A', SKINCOLOR_GOLD, 4047, "", 0}, // Midnight Channel - 1'55"62 + {ET_TIME, 0, 31, 'A', SKINCOLOR_GOLD, 4944, "", 0}, // Vanilla Hotel Zone - 2'21"25 + {ET_TIME, 0, 32, 'A', SKINCOLOR_GOLD, 4638, "", 0}, // Toxic Palace Zone - 2'12"51 + {ET_TIME, 0, 33, 'A', SKINCOLOR_GOLD, 4036, "", 0}, // Ancient Tomb Zone - 1'55"31 + {ET_TIME, 0, 34, 'A', SKINCOLOR_GOLD, 3595, "", 0}, // Cloud Cradle Zone K - 1'42"71 + {ET_TIME, 0, 35, 'A', SKINCOLOR_GOLD, 4705, "", 0}, // Volcanic Valley Zone - 2'14"42 + {ET_TIME, 0, 36, 'A', SKINCOLOR_GOLD, 3314, "", 0}, // Kodachrome Void Zone - 1'34"68 + {ET_TIME, 0, 37, 'A', SKINCOLOR_GOLD, 3501, "", 0}, // Boiling Bedrock Zone - 1'40"02 + {ET_TIME, 0, 38, 'A', SKINCOLOR_GOLD, 4920, "", 0}, // Egg Quarters - 2'20"57 + {ET_TIME, 0, 39, 'A', SKINCOLOR_GOLD, 4318, "", 0}, // Virtual Highway Zone - 2'03"37 + {ET_TIME, 0, 40, 'A', SKINCOLOR_GOLD, 3550, "", 0}, // Eggman's Nightclub Zone - 1'41"42 + {ET_TIME, 0, 41, 'A', SKINCOLOR_GOLD, 2572, "", 0}, // KKR Ganbare Dochu 2 - 1'13"48 + {ET_TIME, 0, 42, 'A', SKINCOLOR_GOLD, 3091, "", 0}, // CK Chao Circuit 1 - 1'28"31 + {ET_TIME, 0, 43, 'A', SKINCOLOR_GOLD, 3454, "", 0}, // CK Chao Circuit 2 - 1'38"68 + {ET_TIME, 0, 44, 'A', SKINCOLOR_GOLD, 2958, "", 0}, // CK Cloud Tops 2 - 1'24"51 + {ET_TIME, 0, 45, 'A', SKINCOLOR_GOLD, 3693, "", 0}, // CK Regal Raceway - 1'45"51 + {ET_TIME, 0, 46, 'A', SKINCOLOR_GOLD, 3437, "", 0}, // SD2 Balloon Panic - 1'38"20 + {ET_TIME, 0, 47, 'A', SKINCOLOR_GOLD, 3238, "", 0}, // SM Dimension Heist - 1'32"51 + {ET_TIME, 0, 48, 'A', SKINCOLOR_GOLD, 3063, "", 0}, // MKSC Sky Garden - 1'27"51 + {ET_TIME, 0, 49, 'A', SKINCOLOR_GOLD, 2980, "", 0}, // MKDS Peach Gardens - 1'25"14 + {ET_TIME, 0, 50, 'A', SKINCOLOR_GOLD, 2914, "", 0}, // MKSC Rainbow Road - 1'23"25 + {ET_TIME, 0, 51, 'A', SKINCOLOR_GOLD, 3003, "", 0}, // SMK Donut Plains 1 - 1'25"80 + {ET_TIME, 0, 52, 'A', SKINCOLOR_GOLD, 2930, "", 0}, // SMK Mario Circuit 2 - 1'23"71 + {ET_TIME, 0, 53, 'A', SKINCOLOR_GOLD, 2389, "", 0}, // SMK Ghost Valley 2 - 1'08"25 + {ET_TIME, 0, 54, 'A', SKINCOLOR_GOLD, 4292, "", 0}, // SMK Bowser Castle 3 - 2'02"62 + {ET_TIME, 0, 55, 'A', SKINCOLOR_GOLD, 2346, "", 0}, // SMK Vanilla Lake 2 - 1'07"02 -// Extra emblems -extraemblem_t extraemblems[MAXEXTRAEMBLEMS]; + // SILVER NORMAL MEDALS + // The general "guideline" of how good we want a player to be at a map. + {ET_TIME, 0, 1, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Green Hills Zone - 1'50"00 + {ET_TIME, 0, 2, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Dark Race - 2'40"00 + {ET_TIME, 0, 3, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Northern District Zone - 2'40"00 + {ET_TIME, 0, 4, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Darkvile Garden Zone - 2'00"00 + {ET_TIME, 0, 5, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Daytona Speedway Zone - 2'10"00 + {ET_TIME, 0, 6, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Egg Zeppelin Zone - 2'20"00 + {ET_TIME, 0, 7, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Sonic Speedway Zone - 2'20"00 + {ET_TIME, 0, 8, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Hill Top Zone - 1'50"00 + {ET_TIME, 0, 9, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Misty Maze Zone - 2'50"00 + {ET_TIME, 0, 10, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Grand Metropolis - 2'20"00 + {ET_TIME, 0, 11, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Sunbeam Paradise Zone - 2'00"00 + {ET_TIME, 0, 12, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Diamond Square Zone - 2'10"00 + {ET_TIME, 0, 13, 'B', SKINCOLOR_GREY, 135*TICRATE, "", 0}, // Midnight Meadow Zone - 2'15"00 + {ET_TIME, 0, 14, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Twinkle Cart - 2'00"00 + {ET_TIME, 0, 15, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Pleasure Castle - 2'00"00 + {ET_TIME, 0, 16, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Paradise Hill Zone - 2'40"00 + {ET_TIME, 0, 17, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Sub-Zero Peak Zone - 2'50"00 + {ET_TIME, 0, 18, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Sapphire Coast Zone - 2'10"00 + {ET_TIME, 0, 19, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Sand Valley Zone - 2'50"00 + {ET_TIME, 0, 20, 'B', SKINCOLOR_GREY, 145*TICRATE, "", 0}, // Megablock Castle Zone - 2'25"00 + {ET_TIME, 0, 21, 'B', SKINCOLOR_GREY, 140*TICRATE, "", 0}, // Canyon Rush Zone - 2'20"00 + {ET_TIME, 0, 22, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Casino Resort Zone - 2'00"00 + {ET_TIME, 0, 23, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Silvercloud Island Zone - 2'30"00 + {ET_TIME, 0, 24, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Blue Mountain Zone - 2'50"00 + {ET_TIME, 0, 25, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Petroleum Refinery Zone - 2'30"00 + {ET_TIME, 0, 26, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Desert Palace Zone - 2'00"00 + {ET_TIME, 0, 27, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Aurora Atoll Zone - 2'40"00 + {ET_TIME, 0, 28, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Barren Badlands Zone - 2'30"00 + {ET_TIME, 0, 29, 'B', SKINCOLOR_GREY, 170*TICRATE, "", 0}, // Red Barrage Area - 2'50"00 + {ET_TIME, 0, 30, 'B', SKINCOLOR_GREY, 135*TICRATE, "", 0}, // Midnight Channel - 2'15"00 + {ET_TIME, 0, 31, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Vanilla Hotel Zone - 2'40"00 + {ET_TIME, 0, 32, 'B', SKINCOLOR_GREY, 160*TICRATE, "", 0}, // Toxic Palace Zone - 2'40"00 + {ET_TIME, 0, 33, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // Ancient Tomb Zone - 2'30"00 + {ET_TIME, 0, 34, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Cloud Cradle Zone K - 2'00"00 + {ET_TIME, 0, 35, 'B', SKINCOLOR_GREY, 165*TICRATE, "", 0}, // Volcanic Valley Zone - 2'45"00 + {ET_TIME, 0, 36, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // Kodachrome Void Zone - 1'50"00 + {ET_TIME, 0, 37, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // Boiling Bedrock Zone - 2'10"00 + {ET_TIME, 0, 38, 'B', SKINCOLOR_GREY, 165*TICRATE, "", 0}, // Egg Quarters - 2'45"00 + {ET_TIME, 0, 39, 'B', SKINCOLOR_GREY, 145*TICRATE, "", 0}, // Virtual Highway Zone - 2'25"00 + {ET_TIME, 0, 40, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // Eggman's Nightclub Zone - 2'00"00 + {ET_TIME, 0, 41, 'B', SKINCOLOR_GREY, 100*TICRATE, "", 0}, // KKR Ganbare Dochu 2 - 1'40"00 + {ET_TIME, 0, 42, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // CK Chao Circuit 1 - 1'50"00 + {ET_TIME, 0, 43, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // CK Chao Circuit 2 - 2'00"00 + {ET_TIME, 0, 44, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // CK Cloud Tops 2 - 1'50"00 + {ET_TIME, 0, 45, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // CK Regal Raceway - 2'10"00 + {ET_TIME, 0, 46, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // SD2 Balloon Panic - 1'50"00 + {ET_TIME, 0, 47, 'B', SKINCOLOR_GREY, 130*TICRATE, "", 0}, // SM Dimension Heist - 2'10"00 + {ET_TIME, 0, 48, 'B', SKINCOLOR_GREY, 110*TICRATE, "", 0}, // MKSC Sky Garden - 1'50"00 + {ET_TIME, 0, 49, 'B', SKINCOLOR_GREY, 105*TICRATE, "", 0}, // MKDS Peach Gardens - 1'45"00 + {ET_TIME, 0, 50, 'B', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // MKSC Rainbow Road - 2'00"00 + {ET_TIME, 0, 51, 'B', SKINCOLOR_GREY, 100*TICRATE, "", 0}, // SMK Donut Plains 1 - 1'40"00 + {ET_TIME, 0, 52, 'B', SKINCOLOR_GREY, 105*TICRATE, "", 0}, // SMK Mario Circuit 2 - 1'45"00 + {ET_TIME, 0, 53, 'B', SKINCOLOR_GREY, 90*TICRATE, "", 0}, // SMK Ghost Valley 2 - 1'30"00 + {ET_TIME, 0, 54, 'B', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // SMK Bowser Castle 3 - 2'30"00 + {ET_TIME, 0, 55, 'B', SKINCOLOR_GREY, 90*TICRATE, "", 0} // SMK Vanilla Lake 2 - 1'30"00 +}; + +// Default Extra Emblems +extraemblem_t extraemblems[MAXEXTRAEMBLEMS] = +{ + {"Novice", "Play 100 matches", 10, 'C', SKINCOLOR_RED, 0}, + {"Standard", "Play 250 matches", 11, 'C', SKINCOLOR_RED, 0}, + {"Expert", "Play 500 matches", 12, 'C', SKINCOLOR_RED, 0}, + {"Master", "Play 750 matches", 13, 'C', SKINCOLOR_RED, 0}, + {"Nightmare", "Play 1000 matches", 14, 'C', SKINCOLOR_RED, 0}, +}; // Unlockables unlockable_t unlockables[MAXUNLOCKABLES]; // Number of emblems and extra emblems -INT32 numemblems = 0; -INT32 numextraemblems = 0; +INT32 numemblems = 110; +INT32 numextraemblems = 5; + +// DEFAULT CONDITION SETS FOR SRB2KART: +void M_SetupDefaultConditionSets(void) +{ + memset(conditionSets, 0, sizeof(conditionSets)); + + // UNLOCKABLES + // -- 1: Collect 5 medals OR play 25 matches + M_AddRawCondition(1, 1, UC_TOTALEMBLEMS, 5, 0, 0); + M_AddRawCondition(1, 2, UC_MATCHESPLAYED, 25, 0, 0); + + // -- 2: Collect 15 medals OR play 50 matches + M_AddRawCondition(2, 1, UC_TOTALEMBLEMS, 15, 0, 0); + M_AddRawCondition(2, 2, UC_MATCHESPLAYED, 50, 0, 0); + + // -- 3: Collect 30 medals OR play 150 matches + M_AddRawCondition(3, 1, UC_TOTALEMBLEMS, 30, 0, 0); + M_AddRawCondition(3, 2, UC_MATCHESPLAYED, 150, 0, 0); + + // -- 4: Collect 50 medals OR play 200 matches + M_AddRawCondition(4, 1, UC_TOTALEMBLEMS, 50, 0, 0); + M_AddRawCondition(4, 2, UC_MATCHESPLAYED, 200, 0, 0); + + // -- 5: Collect 70 medals OR play 300 matches + M_AddRawCondition(5, 1, UC_TOTALEMBLEMS, 70, 0, 0); + M_AddRawCondition(5, 2, UC_MATCHESPLAYED, 300, 0, 0); + + // -- 6: Collect 110 medals ONLY + M_AddRawCondition(6, 1, UC_TOTALEMBLEMS, 110, 0, 0); + + // MILESTONES + // -- 10: Play 100 matches + M_AddRawCondition(10, 1, UC_MATCHESPLAYED, 100, 0, 0); + + // -- 11: Play 250 matches + M_AddRawCondition(11, 1, UC_MATCHESPLAYED, 250, 0, 0); + + // -- 12: Play 500 matches + M_AddRawCondition(12, 1, UC_MATCHESPLAYED, 500, 0, 0); + + // -- 13: Play 750 matches + M_AddRawCondition(13, 1, UC_MATCHESPLAYED, 750, 0, 0); + + // -- 14: Play 1000 matches + M_AddRawCondition(14, 1, UC_MATCHESPLAYED, 1000, 0, 0); +} void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2) { diff --git a/src/m_cond.h b/src/m_cond.h index ed29fe326..bbefe09cf 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -144,6 +144,7 @@ extern INT32 numextraemblems; extern UINT32 unlocktriggers; // Condition set setup +void M_SetupDefaultConditionSets(void); void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2); // Clearing secrets From 57b92b9491d7733a410a1d6929f6ef353c2ae289 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 22 Oct 2024 02:44:53 -0400 Subject: [PATCH 07/10] prevent map command crash from maps with invalid or non existing mapinfo https://github.com/Indev450/SRB2Kart-Saturn/commit/dba7a7dc3cb55ea4d8885f28e29edf3d22eeaef9 --- src/d_netcmd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6e798af1e..2c76b7581 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2862,6 +2862,15 @@ static void Command_Map_f(void) // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer else { + + if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL) + { + CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum)); + Z_Free(realmapname); + Z_Free(mapname); + return; + } + if (!( mapheaderinfo[newmapnum-1] && mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype) From f381a1ce4799a02c2c08f3f778da0b7cc1a0f1d4 Mon Sep 17 00:00:00 2001 From: NepDisk <16447892+NepDisk@users.noreply.github.com> Date: Tue, 22 Oct 2024 17:50:15 -0400 Subject: [PATCH 08/10] use saturn behaviour for lib_sStopSoundByID --- src/lua_baselib.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a0aa04b49..50d71a1fb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2562,16 +2562,11 @@ static int lib_sStopSound(lua_State *L) static int lib_sStopSoundByID(lua_State *L) { - void *origin = NULL; + void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); sfxenum_t sound_id = luaL_checkinteger(L, 2); - //NOHUD - - if (sound_id >= NUMSFX) - return luaL_error(L, "sfx %d out of range (0 - %d)", sound_id, NUMSFX-1); - if (!lua_isnil(L, 1)) - if (!GetValidSoundOrigin(L, &origin)) - return LUA_ErrInvalid(L, "mobj_t/sector_t"); - + NOHUD + if (!origin) + return LUA_ErrInvalid(L, "mobj_t"); S_StopSoundByID(origin, sound_id); return 0; } From c58a08baba43661c9f2a50690d8ed7e07b6ddddf Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 23 Oct 2024 17:20:41 +0200 Subject: [PATCH 09/10] replace those with macros + remove unused pointtoangleex reduces function call overhead, those are called quite often for alot of things and R_PointToAngleEx is basically useless due to R_PointToAngle64 --- src/r_main.c | 56 ++-------------------------------------------------- src/r_main.h | 7 +++---- 2 files changed, 5 insertions(+), 58 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 972d3d5c1..275550dca 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -289,7 +289,7 @@ INT32 R_PointOnSideUDMF(fixed_t x, fixed_t y, const node_t *node) // Try to quickly decide by looking at sign bits. INT32 mask = (node->dy ^ node->dx ^ dx ^ dy) >> 31; return (mask & ((node->dy ^ dx) < 0)) | // (left is negative) - (~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx))); + (~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx))); } INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *restrict node) @@ -307,7 +307,7 @@ INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *restrict node) // also use a mask to avoid branch prediction INT32 mask = (node->dy ^ node->dx ^ x ^ y) >> 31; return (mask & ((node->dy ^ x) < 0)) | // (left is negative) - (~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x))); + (~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x))); } // killough 5/2/98: reformatted @@ -333,24 +333,6 @@ INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) return FixedMul(dy, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, dx); } -// -// R_PointToAngle -// To get a global angle from cartesian coordinates, -// the coordinates are flipped until they are in -// the first octant of the coordinate system, then -// the y (<=x) is scaled and divided by x to get a -// tangent (slope) value which is looked up in the -// tantoangle[] table. The +1 size of tantoangle[] -// is to handle the case when x==y without additional -// checking. -// -// killough 5/2/98: reformatted, cleaned up - -angle_t R_PointToAngle(fixed_t x, fixed_t y) -{ - return R_PointToAngle2(viewx, viewy, x, y); -} - // Similar to R_PointToAngle, but requires an additional player_t argument. // If this player is a local displayplayer, this will base off the calculations off of their camera instead, otherwise use viewx/viewy as usual. // Yes this is kinda ghetto. @@ -413,40 +395,6 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) 0; } -fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) -{ - return FixedHypot(px1 - px2, py1 - py2); -} - -// Little extra utility. Works in the same way as R_PointToAngle2 -fixed_t R_PointToDist(fixed_t x, fixed_t y) -{ - return R_PointToDist2(viewx, viewy, x, y); -} - -angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) -{ - INT64 dx = x1-x2; - INT64 dy = y1-y2; - if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX) - { - x1 = (int)(dx / 2 + x2); - y1 = (int)(dy / 2 + y2); - } - return (y1 -= y2, (x1 -= x2) || y1) ? - x1 >= 0 ? - y1 >= 0 ? - (x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0 - ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1 - x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8 - ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7 - y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2 - (x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4 - ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5 - 0; -} - // // R_ScaleFromGlobalAngle // Returns the texture mapping scale for the current line (horizontal span) diff --git a/src/r_main.h b/src/r_main.h index 71d28af75..bb8ed13db 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -71,13 +71,12 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; INT32 R_PointOnSideUDMF(fixed_t x, fixed_t y, const node_t *node); INT32 R_PointOnSideKart(fixed_t x, fixed_t y, const node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line); -angle_t R_PointToAngle(fixed_t x, fixed_t y); +#define R_PointToAngle(x, y) R_PointToAngle2(viewx, viewy, x, y) angle_t R_PointToAnglePlayer(player_t *player, fixed_t x, fixed_t y); angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); -angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); -fixed_t R_PointToDist(fixed_t x, fixed_t y); -fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); +#define R_PointToDist(x, y) R_PointToDist2(viewx, viewy, x, y) +#define R_PointToDist2(px2, py2, px1, py1) FixedHypot((px1) - (px2), (py1) - (py2)) fixed_t R_ScaleFromGlobalAngle(angle_t visangle); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); From 7091bd6691adde96322ec4d50432e3e00eac04e3 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 23 Oct 2024 18:57:43 +0200 Subject: [PATCH 10/10] Fix HWR_SplitWall and sloped midtextures based on https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1781/ but modified from saturn to not make performance worse --- src/hardware/hw_main.c | 549 +++++++++++++++++++++++------------------ 1 file changed, 302 insertions(+), 247 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 177fd616b..7a4883e9e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -833,13 +833,11 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL // // HWR_SplitWall +// SoM: split up and light walls according to the lightlist. +// This may also include leaving out parts of the wall that can't be seen // static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags) { - /* SoM: split up and light walls according to the - lightlist. This may also include leaving out parts - of the wall that can't be seen */ - float realtop, realbot, top, bot; float pegt, pegb, pegmul; float height = 0.0f, bheight = 0.0f; @@ -848,38 +846,51 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; - // compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetSlopeZAt's return value each time - fixed_t temp; + float diff; - fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); - fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo - fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x); - fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo + fixed_t v1x = FloatToFixed(wallVerts[0].x); + fixed_t v1y = FloatToFixed(wallVerts[0].z); + fixed_t v2x = FloatToFixed(wallVerts[1].x); + fixed_t v2y = FloatToFixed(wallVerts[1].z); - INT32 solid, i; - lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->PolyColor.s.alpha; FUINT lightnum = sector->lightlevel; extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; realbot = bot = wallVerts[0].y; + diff = top - bot; + pegt = wallVerts[3].t; pegb = wallVerts[0].t; - pegmul = (pegb - pegt) / (top - bot); + + // Lactozilla: If both heights of a side lay on the same position, then this wall is a triangle. + // To avoid division by zero, which would result in a NaN, we check if the vertical difference + // between the two vertices is not zero. + if (fpclassify(diff) == FP_ZERO) + pegmul = 0.0; + else + pegmul = (pegb - pegt) / diff; endrealtop = endtop = wallVerts[2].y; endrealbot = endbot = wallVerts[1].y; + diff = endtop - endbot; + endpegt = wallVerts[2].t; endpegb = wallVerts[1].t; - endpegmul = (endpegb - endpegt) / (endtop - endbot); - for (i = 0; i < sector->numlights; i++) + if (fpclassify(diff) == FP_ZERO) + endpegmul = 0.0; + else + endpegmul = (endpegb - endpegt) / diff; + + for (INT32 i = 0; i < sector->numlights; i++) { if (endtop < endrealbot && top < realbot) return; + lightlist_t *list = sector->lightlist; + if (!(list[i].flags & FOF_NOSHADE)) { if (pfloor && (pfloor->fofflags & FOF_FOG)) @@ -894,7 +905,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, } } - solid = false; + boolean solid = false; if ((sector->lightlist[i].flags & FOF_CUTSOLIDS) && !(cutflag & FOF_EXTRA)) solid = true; @@ -911,16 +922,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, else solid = false; - temp = P_GetLightZAt(&list[i], v1x, v1y); - height = FIXED_TO_FLOAT(temp); - temp = P_GetLightZAt(&list[i], v2x, v2y); - endheight = FIXED_TO_FLOAT(temp); + height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y)); + endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y)); + if (solid) { - temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); + bheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v1x, v1y)); + endbheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v2x, v2y)); } if (endheight >= endtop && height >= top) @@ -933,10 +941,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, if (i + 1 < sector->numlights) { - temp = P_GetLightZAt(&list[i+1], v1x, v1y); - bheight = FIXED_TO_FLOAT(temp); - temp = P_GetLightZAt(&list[i+1], v2x, v2y); - endbheight = FIXED_TO_FLOAT(temp); + bheight = FixedToFloat(P_GetLightZAt(&list[i+1], v1x, v1y)); + endbheight = FixedToFloat(P_GetLightZAt(&list[i+1], v2x, v2y)); } else { @@ -944,19 +950,20 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, endbheight = endrealbot; } - if (endbheight >= endtop && bheight >= top) + if (endbheight > endtop) + endbot = endtop; + + if (bheight >= top) continue; - //Found a break; + // Found a break + // The heights are clamped to ensure the polygon doesn't cross itself. bot = bheight; if (bot < realbot) bot = realbot; - endbot = endbheight; - - if (endbot < endrealbot) - endbot = endrealbot; + endbot = min(max(endbheight, endrealbot), endtop); Surf->PolyColor.s.alpha = alpha; @@ -1025,6 +1032,42 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) // PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer } +// Returns true if the midtexture is visible, and false if... it isn't... +static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) +{ + FUINT blendmode = PF_Masked; + + pSurf->PolyColor.s.alpha = 0xFF; + + if (!gl_curline->polyseg) + { + if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG) + { + if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf); + else + blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode); + } + else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) + blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf); + } + else if (gl_curline->polyseg->translucency > 0) + { + // Polyobject translucency is done differently + if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn + return false; + else + blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, pSurf); + } + + if (blendmode != PF_Masked && pSurf->PolyColor.s.alpha == 0x00) + return false; + + pSurf->PolyFlags = blendmode; + + return true; +} + // // HWR_ProcessSeg // A portion or all of a wall segment will be drawn, from startfrac to endfrac, @@ -1043,16 +1086,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom fixed_t worldhighslope = 0, worldlowslope = 0; fixed_t v1x, v1y, v2x, v2y; - GLMapTexture_t *grTex = NULL; - float cliplow = 0.0f, cliphigh = 0.0f; - INT32 gl_midtexture; fixed_t h, l; // 3D sides and 2s middle textures fixed_t hS, lS; - FUINT lightnum = 255; - extracolormap_t *colormap; - FSurfaceInfo Surf; - boolean tripwire; gl_sidedef = gl_curline->sidedef; @@ -1104,11 +1140,15 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].z = wallVerts[1].z = ve.y; // x offset the texture - { - fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; - cliplow = (float)texturehpeg; - cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT)); - } + fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; + float cliplow = (float)texturehpeg; + float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT)); + + FUINT lightnum = 255; + extracolormap_t *colormap = gl_frontsector->extra_colormap; + + FSurfaceInfo Surf; + Surf.PolyColor.s.alpha = 255; tripwire = P_IsLineTripWire(gl_linedef); @@ -1117,15 +1157,16 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, gl_curline); } - colormap = gl_frontsector->extra_colormap; - - if (gl_frontsector) - Surf.PolyColor.s.alpha = 255; + INT32 gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); + GLMapTexture_t *grTex = NULL; + // two sided line if (gl_backsector) { INT32 gl_toptexture = 0, gl_bottomtexture = 0; - // two sided line + + fixed_t texturevpeg; + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky boolean bothfloorssky = false; // likewise, but for floors @@ -1241,51 +1282,47 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // check TOP TEXTURE if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) { + // PEGGING + if (gl_linedef->flags & ML_DONTPEGTOP) + texturevpeg = 0; + else if (gl_linedef->flags & ML_SKEWTD) + texturevpeg = worldhigh + textureheight[gl_toptexture] - worldtop; + else + texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight; + + texturevpeg += gl_sidedef->rowoffset; + + // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway + texturevpeg %= textureheight[gl_toptexture]; + + grTex = HWR_GetTexture(gl_toptexture); + + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + + // Adjust t value for sloped walls + if (!(gl_linedef->flags & ML_SKEWTD)) { - fixed_t texturevpegtop; // top - - grTex = HWR_GetTexture(gl_toptexture); - - // PEGGING - if (gl_linedef->flags & ML_DONTPEGTOP) - texturevpegtop = 0; - else if (gl_linedef->flags & ML_SKEWTD) - texturevpegtop = worldhigh + textureheight[gl_sidedef->toptexture] - worldtop; - else - texturevpegtop = gl_backsector->ceilingheight + textureheight[gl_sidedef->toptexture] - gl_frontsector->ceilingheight; - - texturevpegtop += gl_sidedef->rowoffset; - - // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegtop %= (textures[gl_toptexture]->height)<scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; - - // Adjust t value for sloped walls - if (!(gl_linedef->flags & ML_SKEWTD)) - { - // Unskewed - wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY; - wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY; - } - else if (gl_linedef->flags & ML_DONTPEGTOP) - { - // Skewed by top - wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY; - wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY; - } - else - { - // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY; - wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY; - } + // Unskewed + wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY; + wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY; + wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY; + wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY; + } + else if (gl_linedef->flags & ML_DONTPEGTOP) + { + // Skewed by top + wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; + wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY; + } + else + { + // Skewed by bottom + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY; } // set top/bottom coords @@ -1294,71 +1331,62 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope); - { - FBITFIELD polyflags = PF_Masked; + FBITFIELD polyflags = PF_Masked; - if (grTex->mipmap.flags & TF_TRANSPARENT) - polyflags = PF_Environment; + if (grTex->mipmap.flags & TF_TRANSPARENT) + polyflags = PF_Environment; - if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); - else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, polyflags, false, lightnum, colormap); - else - HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap); - } + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); + else if (grTex->mipmap.flags & TF_TRANSPARENT) + HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, polyflags, false, lightnum, colormap); + else + HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap); } // check BOTTOM TEXTURE - if (( - worldlowslope > worldbottomslope || - worldlow > worldbottom) && gl_bottomtexture) //only if VISIBLE!!! + if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) { + // PEGGING + if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) + texturevpeg = 0; + else if (gl_linedef->flags & ML_SKEWTD) + texturevpeg = worldbottom - worldlow; + else + texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight; + + texturevpeg += gl_sidedef->rowoffset; + + // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway + texturevpeg %= textureheight[gl_bottomtexture]; + + grTex = HWR_GetTexture(gl_bottomtexture); + + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + + // Adjust t value for sloped walls + if (!(gl_linedef->flags & ML_SKEWTD)) { - fixed_t texturevpegbottom = 0; // bottom - - grTex = HWR_GetTexture(gl_bottomtexture); - - // PEGGING - if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) - texturevpegbottom = 0; - else if (gl_linedef->flags & ML_SKEWTD) - texturevpegbottom = worldbottom - worldlow; - else - texturevpegbottom = gl_frontsector->floorheight - gl_backsector->floorheight; - - texturevpegbottom += gl_sidedef->rowoffset; - - // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegbottom %= (textures[gl_bottomtexture]->height)<scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; - - // Adjust t value for sloped walls - if (!(gl_linedef->flags & ML_SKEWTD)) - { - // Unskewed - wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY; - wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY; - } - else if (gl_linedef->flags & ML_DONTPEGBOTTOM) - { - // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY; - //wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this - wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY; - } - else - { - // Skewed by top - wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY; - wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY; - } + // Unskewed + wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY; + wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY; + wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY; + wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY; + } + else if (gl_linedef->flags & ML_DONTPEGBOTTOM) + { + // Skewed by bottom + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY; + } + else + { + // Skewed by top + wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY; + wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY; } // set top/bottom coords @@ -1367,29 +1395,23 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); - { - FBITFIELD polyflags = PF_Masked; + FBITFIELD polyflags = PF_Masked; - if (grTex->mipmap.flags & TF_TRANSPARENT) - polyflags = PF_Environment; + if (grTex->mipmap.flags & TF_TRANSPARENT) + polyflags = PF_Environment; - if (gl_frontsector->numlights) - HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); - else if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, polyflags, false, lightnum, colormap); - else - HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap); - } + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FOF_CUTLEVEL, NULL, polyflags); + else if (grTex->mipmap.flags & TF_TRANSPARENT) + HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, polyflags, false, lightnum, colormap); + else + HWR_ProjectWall(wallVerts, &Surf, polyflags, lightnum, colormap); } - gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); - - if (gl_midtexture) + // Render midtexture if there's one. Determine if it's visible first, though + if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) { - FBITFIELD blendmode; sector_t *front, *back; - fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; - fixed_t texturevpeg = 0; INT32 repeats; if (gl_linedef->frontsector->heightsec != -1) @@ -1418,57 +1440,73 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else low = back->floorheight; - repeats = (high - low)/textureheight[gl_sidedef->midtexture]; - if ((high-low)%textureheight[gl_sidedef->midtexture]) + repeats = (high - low) / textureheight[gl_midtexture]; + if ((high - low) % textureheight[gl_midtexture]) repeats++; // tile an extra time to fill the gap -- Monster Iestyn } else repeats = 1; - // SoM: a little note: This code re-arranging will - // fix the bug in Nimrod map02. popentop and popenbottom + // SoM: a little note: popentop and popenbottom // record the limits the texture can be displayed in. // polytop and polybottom, are the ideal (i.e. unclipped) // heights of the polygon, and h & l, are the final (clipped) // poly coords. + fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; + fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; // 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 if (gl_curline->polyseg) { - popentop = back->ceilingheight; - popenbottom = back->floorheight; + popentop = popentopslope = back->ceilingheight; + popenbottom = popenbottomslope = back->floorheight; } else { popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); + popentopslope = min(worldtopslope, worldhighslope); + popenbottomslope = max(worldbottomslope, worldlowslope); } + // Find the wall's coordinates + fixed_t midtexheight = textureheight[gl_midtexture] * repeats; + + // Texture is not skewed if (gl_linedef->flags & ML_NOSKEW) { - if (gl_linedef->flags & ML_MIDPEG) + if (gl_linedef->flags & ML_MIDPEG) // Peg it to the floor { polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset; - polytop = polybottom + textureheight[gl_midtexture]*repeats; + polytop = polybottom + midtexheight; } - else + else // Peg it to the ceiling { polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset; - polybottom = polytop - textureheight[gl_midtexture]*repeats; + polybottom = polytop - midtexheight; } + + // The right side's coordinates are the the same as the left side + polytopslope = polytop; + polybottomslope = polybottom; } - else if (gl_linedef->flags & ML_MIDPEG) + else if (gl_linedef->flags & ML_MIDPEG) // Skew the texture, but peg it to the floor { polybottom = popenbottom + gl_sidedef->rowoffset; - polytop = polybottom + textureheight[gl_midtexture]*repeats; + polytop = polybottom + midtexheight; + polybottomslope = popenbottomslope + gl_sidedef->rowoffset; + polytopslope = polybottomslope + midtexheight; } - else + else // Skew it according to the ceiling's slope { polytop = popentop + gl_sidedef->rowoffset; - polybottom = polytop - textureheight[gl_midtexture]*repeats; + polybottom = polytop - midtexheight; + polytopslope = popentopslope + gl_sidedef->rowoffset; + polybottomslope = polytopslope - midtexheight; } + // CB // 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 @@ -1476,40 +1514,63 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { lowcut = polybottom; highcut = polytop; + lowcutslope = polybottomslope; + highcutslope = polytopslope; } else { // The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector lowcut = popenbottom; highcut = popentop; + lowcutslope = popenbottomslope; + highcutslope = popentopslope; } h = min(highcut, polytop); l = max(polybottom, lowcut); + hS = min(highcutslope, polytopslope); + lS = max(polybottomslope, lowcutslope); + // PEGGING + fixed_t texturevpegslope; + + if (gl_linedef->flags & ML_MIDPEG) { - // PEGGING - if (gl_linedef->flags & ML_MIDPEG) - texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom; - else - texturevpeg = polytop - h; - - grTex = HWR_GetTexture(gl_midtexture); - - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + texturevpeg = midtexheight - h + polybottom; + texturevpegslope = midtexheight - hS + polybottomslope; } + else + { + texturevpeg = polytop - h; + texturevpegslope = polytopslope - hS; + } + + grTex = HWR_GetTexture(gl_midtexture); + + // Left side + wallVerts[3].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + + // Right side + wallVerts[2].t = texturevpegslope * grTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; + wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past // where the polygon might not be. - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h); - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l); + wallVerts[3].y = FIXED_TO_FLOAT(h); + wallVerts[0].y = FIXED_TO_FLOAT(l); + wallVerts[2].y = FIXED_TO_FLOAT(hS); + wallVerts[1].y = FIXED_TO_FLOAT(lS); - // Correct to account for slopes + // TODO: Actually use the surface's flags so that I don't have to do this + FUINT blendmode = Surf.PolyFlags; + + if (udmf) // lug: idk if we should even keep this? seems like it doesent do anything since udmf maps still had issues which this did not fix { + // Correct to account for slopes fixed_t midtextureslant; if (gl_linedef->flags & ML_NOSKEW) @@ -1603,26 +1664,22 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { if (!gl_curline->polyseg) // Don't do it for polyobjects { - if (gl_frontsector->ceilingpic == skyflatnum) + if (gl_frontsector->ceilingpic == skyflatnum + && gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky { - if (gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky - { - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space - wallVerts[0].y = FIXED_TO_FLOAT(worldtop); - wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); - HWR_DrawSkyWall(wallVerts, &Surf); - } + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); + HWR_DrawSkyWall(wallVerts, &Surf); } - if (gl_frontsector->floorpic == skyflatnum) + if (gl_frontsector->floorpic == skyflatnum + && gl_backsector->floorpic != skyflatnum) // same thing here { - if (gl_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky - { - wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); - wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space - HWR_DrawSkyWall(wallVerts, &Surf); - } + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); } } } @@ -1630,40 +1687,38 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { // Single sided line... Deal only with the middletexture (if one exists) - gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); - if (gl_midtexture && gl_linedef->special != 41) // (Ignore horizon line for OGL) + if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // (Ignore horizon line for OGL) { - { - fixed_t texturevpeg; - // PEGGING - if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) - texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset; - else if (gl_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset; - else - // top of texture at top - texturevpeg = gl_sidedef->rowoffset; + fixed_t texturevpeg; - grTex = HWR_GetTexture(gl_midtexture); + // PEGGING + if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW)) + texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset; + else if (gl_linedef->flags & ML_DONTPEGBOTTOM) + texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset; + else + // top of texture at top + texturevpeg = gl_sidedef->rowoffset; - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + grTex = HWR_GetTexture(gl_midtexture); - // Texture correction for slopes - if (gl_linedef->flags & ML_NOSKEW) { - wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY; - wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; - wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY; - wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY; - } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { - wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY; - } else { - wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY; - wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY; - } + wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + + // Texture correction for slopes + if (gl_linedef->flags & ML_NOSKEW) { + wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY; + wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; + wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY; + wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY; + } else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { + wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY; + wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY; + } else { + wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY; + wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY; } //Set textures properly on single sided walls that are sloped @@ -1726,7 +1781,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom //Hurdler: 3d-floors test - if (gl_frontsector && gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors)) + if (gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors)) { ffloor_t * rover; fixed_t highcut = 0, lowcut = 0;