Merge branch 'blankart-dev' into wadstrbuf

This commit is contained in:
GenericHeroGuy 2025-06-27 18:46:47 +02:00
commit 92c59ddbcb
38 changed files with 924 additions and 546 deletions

View file

@ -4,7 +4,11 @@ if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
if("${SRB2_CONFIG_STATIC_STDLIB}")
# On MinGW with internal libraries, link the standard library statically
target_link_options(SRB2SDL2 PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
if(CMAKE_LINKER_TYPE STREQUAL "LLD")
target_link_options(SRB2SDL2 PRIVATE -Wl, -static-libgcc -static-libstdc++ -static -lpthread)
else()
target_link_options(SRB2SDL2 PRIVATE -Wl,--add-stdcall-alias -static-libgcc -static-libstdc++ -static -lpthread)
endif()
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
target_link_libraries(SRB2SDL2 PRIVATE Threads::Threads)

View file

@ -37,6 +37,15 @@
// Allow scripters to write files of these types to SRB2's folder
static const char *whitelist[] = {
".bmp",
".png",
".obj",
".json",
".yaml",
".xml",
".csv",
".soc",
".cfg",
".csv",
".dat",
@ -176,7 +185,7 @@ void MakePathDirs(char *path)
}
static int CheckFileName(lua_State *L, const char *filename)
static int CheckFileName(lua_State* L, const char* filename, boolean extensioncheck)
{
int length = strlen(filename);
boolean pass = false;
@ -188,12 +197,21 @@ static int CheckFileName(lua_State *L, const char *filename)
return pushresult(L,0,filename);
}
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = true;
break;
}
if (extensioncheck)
{
for (i = 0; i < (sizeof(whitelist) / sizeof(const char*)); i++)
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = true;
break;
}
}
else
{
pass = true;
}
if (strstr(filename, "./")
|| strstr(filename, "..") || strchr(filename, ':')
|| filename[0] == '/'
@ -214,7 +232,10 @@ static int io_openlocal (lua_State *L) {
luafiletransfer_t *filetransfer;
int checkresult;
checkresult = CheckFileName(L, filename);
// Decision was made for normal reading (binary + text) to have no whitelist restrictions
boolean readcheck = (strchr(mode, 'w') != NULL) || (strchr(mode, 'a') != NULL) || (strchr(mode, '+') != NULL);
checkresult = CheckFileName(L, filename, readcheck);
if (checkresult)
return checkresult;
@ -240,11 +261,10 @@ static int io_open (lua_State *L) {
const char *mode = luaL_optstring(L, 2, "r");
int checkresult;
checkresult = CheckFileName(L, filename);
checkresult = CheckFileName(L, filename, false);
if (checkresult)
return checkresult;
if (lua_isfunction(L,3))
{
luaL_checktype(L, 3, LUA_TFUNCTION);

View file

@ -553,10 +553,7 @@ char http_source[MAX_MIRROR_LENGTH];
static UINT16 cl_lastcheckedfilecount = 0; // used for full file list
static const char* servmus_1 = "SRVMS1";
static const char* servmus_2 = "SRVMS2";
static void ChangeServMusic(const char* musname, boolean fallback, boolean keepPos)
void ChangeServMusic(const char* musname, boolean fallback, boolean keepPos)
{
if (S_MusicExists(musname))
if (keepPos)
@ -1616,7 +1613,7 @@ static boolean CL_FinishedFileList(void)
"Press ACCEL to continue or BRAKE to cancel.\n\n"
), M_ConfirmConnect, MM_EVENTHANDLER);
cl_mode = CL_CONFIRMCONNECT;
ChangeServMusic(servmus_2, true,true);
ChangeServMusic(SERVMUS_2, true,true);
}
else
cl_mode = CL_LOADFILES;
@ -1686,7 +1683,7 @@ static boolean CL_FinishedFileList(void)
Z_Free(downloadsize);
cl_mode = CL_CONFIRMCONNECT;
ChangeServMusic(servmus_2, true,true);
ChangeServMusic(SERVMUS_2, true,true);
}
#ifdef HAVE_CURL
else
@ -1787,7 +1784,7 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent)
}
cl_mode = CL_VIEWSERVER; //cl_mode = CL_CHECKFILES;
ChangeServMusic(servmus_1, true,false);
ChangeServMusic(SERVMUS_1, true,false);
}
else
{
@ -1834,7 +1831,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved
{
cl_mode = CL_VIEWSERVER; //cl_mode = CL_CHECKFILES;
ChangeServMusic(servmus_1, true,false);
ChangeServMusic(SERVMUS_1, true,false);
}
else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent)
{
@ -5637,7 +5634,6 @@ boolean TryRunTics(tic_t realtics)
if (ticking)
{
{
boolean tickInterp = true;
// run the count * tics
while (neededtic > gametic)
@ -5666,19 +5662,8 @@ boolean TryRunTics(tic_t realtics)
P_PostLoadLevel();
}
boolean run = (gametic % NEWTICRATERATIO) == 0;
if (run && tickInterp)
{
// Update old view state BEFORE ticking so resetting
// the old interpolation state from game logic works.
R_UpdateViewInterpolation();
tickInterp = false; // do not update again in sped-up tics
}
G_Ticker(run);
G_Ticker((gametic % NEWTICRATERATIO) == 0);
}
if (Playing() && netgame && (gametic % TICRATE == 0))
{
Schedule_Run();

View file

@ -554,6 +554,11 @@ extern UINT8 playernode[MAXPLAYERS];
extern UINT8 playerconsole[MAXPLAYERS];
extern SINT8 joinnode;
#define SERVMUS_1 "SRVMS1"
#define SERVMUS_2 "SRVMS2"
void ChangeServMusic(const char* musname, boolean fallback, boolean keepPos);
INT32 GetClientMode(void);
void ChangeClientMode(INT32 mode);

View file

@ -86,8 +86,8 @@
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
#define ASSET_HASH_MAIN_PK3 0xc71788f74f5972ad
#define ASSET_HASH_MAPPATCH_PK3 0xac5a4a1a51f9ec01
#define ASSET_HASH_MAIN_PK3 0x9a6188063fcdcc93
#define ASSET_HASH_MAPPATCH_PK3 0x93a9213b2b2ba260
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
#ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 0x0000000000000000
@ -893,7 +893,9 @@ void D_SRB2Loop(void)
{
renderdeltatics = FLOAT_TO_FIXED(deltatics);
if (!(paused || P_AutoPause()) && !hu_stopped)
const boolean lagging = ((deltatics >= 1.0) || hu_stopped);
if (!(paused || P_AutoPause()) && !lagging)
{
rendertimefrac = g_time.timefrac;
}
@ -902,7 +904,14 @@ void D_SRB2Loop(void)
rendertimefrac = FRACUNIT;
}
rendertimefrac_unpaused = g_time.timefrac;
if (!lagging)
{
rendertimefrac_unpaused = g_time.timefrac;
}
else
{
rendertimefrac_unpaused = FRACUNIT;
}
}
else
{
@ -942,7 +951,7 @@ void D_SRB2Loop(void)
// Fully completed frame made.
finishprecise = I_GetPreciseTime();
// Use the time before sleep for frameskip calculations:
// Use the time before sleep for frameskip calculations:
// post-sleep time is literally being intentionally wasted
deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision();
deltatics = deltasecs * NEWTICRATE;
@ -1238,7 +1247,7 @@ void D_SRB2Main(void)
{
INT32 p;
INT32 pstartmap = 0;
INT32 pstartmap = 1;
boolean autostart = false;
/* break the version string into version numbers, for netplay */
@ -1534,11 +1543,11 @@ void D_SRB2Main(void)
I_Error("modifiedgame set during startup!");
CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n");
// HACK: Refer to https://git.do.srb2.org/KartKrew/RingRacers/-/merge_requests/29#note_61574
partadd_earliestfile = numwadfiles;
W_InitMultipleFiles(startuppwads, true);
// Only search for pwad maps and reload graphics if we actually have a pwad added
if (startuppwads[0] != NULL)
{

View file

@ -1172,6 +1172,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_vhseffect);
CV_RegisterVar(&cv_shittyscreen);
CV_RegisterVar(&cv_votebgscaling);
CV_RegisterVar(&cv_renderer);
CV_RegisterVar(&cv_scr_depth);
CV_RegisterVar(&cv_scr_width);
@ -2815,11 +2816,11 @@ void D_SetupVote(void)
hellpick = 1;
if (i == 2) // sometimes a different gametype
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer);
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, votebuffer);
else if (i >= VOTEROWS) // unknown-random and formerly force-unknown MAP HELL
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, hellpick, (i < VOTEROWSADDSONE), votebuffer);
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, hellpick, votebuffer);
else
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, 0, true, votebuffer);
m = G_RandMap(G_TOLFlag(gt), prevmap, 0, 0, votebuffer);
if (i < VOTEROWS)
votebuffer[min(i, 2)] = m; // min() is a dumb workaround for gcc 4.4 array-bounds error
WRITEUINT16(p, m);
@ -3354,7 +3355,7 @@ static void Command_RandomMap(void)
oldmapnum = -1;
}
newmapnum = G_RandMap(G_TOLFlag(newgametype), oldmapnum, 0, 0, false, NULL) + 1;
newmapnum = G_RandMap(G_TOLFlag(newgametype), oldmapnum, 0, 0, NULL) + 1;
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
}

View file

@ -3214,6 +3214,47 @@ void readmaincfg(MYFILE *f)
{
ammoremovaltics = get_number(word2);
}
// BlanKart: Easy ways to set these for balance purposes
else if (fastcmp(word, "HYUDOROTIME"))
{
hyudorotime = get_number(word2);
}
else if (fastcmp(word, "STEALTIME"))
{
stealtime = get_number(word2);
}
else if (fastcmp(word, "WATERPANELTIME"))
{
waterpaneltime = get_number(word2);
}
else if (fastcmp(word, "SNEAKERTIME"))
{
sneakertime = get_number(word2);
}
else if (fastcmp(word, "BUBBLETIME"))
{
bubbletime = get_number(word2);
}
else if (fastcmp(word, "COMEBACKTIME"))
{
comebacktime = get_number(word2);
}
else if (fastcmp(word, "GREASETICS"))
{
greasetics = get_number(word2);
}
else if (fastcmp(word, "WIPEOUTSLOWTIME"))
{
wipeoutslowtime = get_number(word2);
}
else if (fastcmp(word, "WANTEDREDUCE"))
{
wantedreduce = get_number(word2);
}
else if (fastcmp(word, "WANTEDFREQUENCY"))
{
wantedfrequency = get_number(word2);
}
else if (fastcmp(word, "INTROTOPLAY"))
{
introtoplay = (UINT8)get_number(word2);
@ -3229,10 +3270,6 @@ void readmaincfg(MYFILE *f)
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "USEBLACKROCK"))
{
useBlackRock = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "LOOPTITLE"))
{
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');

View file

@ -176,6 +176,34 @@ static void ignorelines(MYFILE *f)
Z_Free(s);
}
static void ignoremenulines(MYFILE *f)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *tmp;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
ignorelines(f);
}
} while (!myfeof(f));
Z_Free(s);
}
void DEH_Link(const char *name, dehinfo_t *info, strbuf_t **buf)
{
info->namehash = HASH32(name, strlen(name));
@ -625,7 +653,10 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
else if (fastcmp(word, "MENU"))
{
if (dedicated)
{
ignoremenulines(f);
continue; // dedis don't need menus, silly!
}
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_menutype(word2); // find a huditem by name

View file

@ -611,6 +611,7 @@ extern tic_t battleexittime;
extern INT32 hyudorotime;
extern INT32 stealtime;
extern INT32 sneakertime;
extern INT32 waterpaneltime;
extern INT32 itemtime;
extern INT32 bubbletime;
extern INT32 comebacktime;
@ -622,7 +623,6 @@ extern INT32 wantedfrequency;
extern UINT8 introtoplay;
extern UINT8 creditscutscene;
extern UINT8 useBlackRock;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings

View file

@ -337,16 +337,16 @@ static void F_IntroDrawScene(void)
{
background = W_CachePatchLongName("KARTKREW", PU_CACHE);
highres = true;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
}
if (intro_scenenum == 1)
{
background = W_CachePatchLongName("BLANKART", PU_CACHE);
highres = false;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
}
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
if (background)
{
if (highres)
@ -465,7 +465,9 @@ void F_IntroTicker(void)
}
if (finalecount == 80)
{
sfxenum_t rsound = skins[1].soundsid[SKSKWIN];
char chars[5][10] = {"tails", "chao", "aiai", "sakura"};
SINT8 random = M_RandomRange(0, 3);
sfxenum_t rsound = skins[R_SkinAvailable(chars[random])].soundsid[SKSKWIN];
S_StartSound(NULL, sfx_flgcap);
S_StartSound(NULL, rsound);
}
@ -478,7 +480,7 @@ void F_IntroTicker(void)
// check for skipping
if (keypressed)
keypressed = false;
if (animtimer > 0)
animtimer--;
}
@ -1594,7 +1596,7 @@ void F_TitleScreenTicker(boolean run)
// prevent console spam if failed
demoIdleLeft = demoIdleTime;
mapnum = G_RandMap(TOL_RACE, -2, 2, 0, false, NULL);
mapnum = G_RandMap(TOL_RACE, -2, 2, 0, NULL);
if (mapnum == 0) // gotta have ONE
{
return;

View file

@ -240,6 +240,7 @@ tic_t battleexittime = 8*TICRATE;
INT32 hyudorotime = 7*TICRATE;
INT32 stealtime = TICRATE/2;
INT32 sneakertime = TICRATE + (TICRATE/3);
INT32 waterpaneltime = TICRATE*2;
INT32 itemtime = 8*TICRATE;
INT32 bubbletime = TICRATE/2;
INT32 comebacktime = 3*TICRATE;
@ -254,7 +255,6 @@ UINT8 maxXtraLife = 2; // Max extra lives from rings
UINT8 introtoplay;
UINT8 creditscutscene;
UINT8 useBlackRock = 1;
// Emerald locations
mobj_t *hunt1;
@ -1152,6 +1152,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
if (joystickvector.xaxis != 0)
{
cmd->turning -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
cmd->angle -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
side += (joystickvector.xaxis * 4) / JOYAXISRANGE;
}
@ -1160,6 +1161,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
{
INT32 mousex = gamekeydown[0][KEY_MOUSEMOVE+3] - gamekeydown[0][KEY_MOUSEMOVE+2];
cmd->turning -= (mousex * 8) * (encoremode ? -1 : 1);
cmd->angle -= (mousex * 8) * (encoremode ? -1 : 1);
}
if (spectating || objectplacing) // SRB2Kart: spectators need special controls
@ -1316,6 +1318,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
else if (cmd->turning < -KART_FULLTURN)
cmd->turning = -KART_FULLTURN;
if (cmd->angle > KART_FULLTURN)
cmd->angle = KART_FULLTURN;
else if (cmd->angle < -KART_FULLTURN)
cmd->angle = -KART_FULLTURN;
if (cmd->throwdir > KART_FULLTURN)
cmd->throwdir = KART_FULLTURN;
else if (cmd->throwdir < -KART_FULLTURN)
@ -3778,11 +3785,11 @@ static INT32 TOLMaps(UINT8 pgametype)
* has those flags.
* \author Graue <graue@oceanbase.org>
*/
static INT16 *okmaps = NULL;
INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer)
INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphell, INT16 *extbuffer)
{
UINT32 numokmaps = 0;
INT16 ix, bufx;
INT16 *okmaps = NULL;
UINT16 extbufsize = 0;
boolean usehellmaps; // Only consider Hell maps in this pick
@ -3924,12 +3931,9 @@ tryagain:
ix = okmaps[M_RandomKey(numokmaps)];
}
if (!callagainsoon)
{
//CONS_Printf("(freeing okmaps)\n");
Z_Free(okmaps);
okmaps = NULL;
}
//CONS_Printf("(freeing okmaps)\n");
Z_Free(okmaps);
okmaps = NULL;
return ix;
}
@ -4196,7 +4200,7 @@ static INT16 G_GetNextMap(boolean advancemap)
}
else if (cv_advancemap.value == 2) // Go to random map.
{
newmap = G_RandMap(G_TOLFlag(gametype), curmap, 0, 0, false, NULL);
newmap = G_RandMap(G_TOLFlag(gametype), curmap, 0, 0, NULL);
}
else if (nextmap >= NEXTMAP_SPECIAL) // Loop back around
{

View file

@ -275,7 +275,7 @@ FUNCMATH INT32 G_TicsToMilliseconds(tic_t tics);
UINT32 G_TOLFlag(INT32 pgametype);
INT16 G_GetFirstMapOfGametype(UINT8 pgametype);
INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphell, boolean callagainsoon, INT16 *extbuffer);
INT16 G_RandMap(UINT32 tolflags, INT16 pprevmap, UINT8 ignorebuffer, UINT8 maphell, INT16 *extbuffer);
void G_AddMapToBuffer(INT16 map);
#ifdef __cplusplus

View file

@ -335,7 +335,7 @@ angle_t gld_FrustumAngle(angle_t tiltangle)
// but at least it doesn't overestimate too much...
clipfov = atan(1 / projMatrix[0]) * 360 / M_PI; // use the actual view of the scene
floatangle = 2.0f + (45.0f + (tilt / 1.9f)) * clipfov / 90.0f;
if (floatangle >= ANGLE_180)
if (floatangle >= 180.0)
return 0xffffffff;
a1 = (angle_t)(ANG1 * (int)floatangle);
return a1;

View file

@ -2461,11 +2461,14 @@ static void K_drawRingMeter(void)
UINT8 *colormap = NULL;
SINT8 coloroffset = 0;
if (gametype == GT_BATTLE)
ringoffsety -= 4;
if (cv_speed_xoffset.value == 0 && cv_speed_yoffset.value == 0)
{
if (gametype == GT_BATTLE)
ringoffsety -= 4;
if (itembreaker)
ringoffsety -= 2;
if (itembreaker)
ringoffsety -= 2;
}
if (K_UseColorHud())
coloroffset = 2;

View file

@ -5535,7 +5535,7 @@ static void K_SneakerPanelEffect(player_t *player, INT32 type)
void K_DoSneaker(player_t *player, INT32 type)
{
const fixed_t intendedboost = K_GetSneakerBoostSpeed();
const tic_t sneakerduration = (type == 3) ? TICRATE*2 : sneakertime;
const tic_t sneakerduration = (type == SNEAKERTYPE_WATERPANEL) ? waterpaneltime : sneakertime;
if (player->floorboost == 0 || player->floorboost == 3)
{
@ -5548,7 +5548,7 @@ void K_DoSneaker(player_t *player, INT32 type)
K_SneakerPanelEffect(player, type);
if (type != 0 && type != 3)
if (type != SNEAKERTYPE_PANEL && type != SNEAKERTYPE_WATERPANEL)
{
K_PlayBoostTaunt(player->mo);
}
@ -5561,7 +5561,7 @@ void K_DoSneaker(player_t *player, INT32 type)
player->numsneakers = CLAMP(player->numsneakers+1, 0, stackingactive ? MAXSNEAKERSTACK : 1);
}
if (type == 3)
if (type == SNEAKERTYPE_WATERPANEL)
{
// Water Running please!
player->mo->flags2 |= MF2_WATERRUN;
@ -9152,25 +9152,24 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y)
// turndir is the direction the controls are telling us to turn, -1 if turning right and 1 if turning left
static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
{
INT16 basedrift, driftadjust;
INT16 basedrift, driftangle;
fixed_t driftweight = player->kartweight*14; // 12
if (player->drift == 0 || !P_IsObjectOnGround(player->mo))
{
// If they aren't drifting or on the ground, this doesn't apply
// If they aren't drifting or on the ground this doesn't apply
return 0;
}
if (player->pflags & PF_DRIFTEND)
{
// Drift has ended and we are tweaking their angle back a bit
return -266*player->drift;
return -266*player->drift; // Drift has ended and we are tweaking their angle back a bit
}
basedrift = (83 * player->drift) - (((driftweight - 14) * player->drift) / 5); // 415 - 303
driftadjust = abs((252 - driftweight) * player->drift / 5);
basedrift = 83*player->drift - (driftweight - 14)*player->drift/5; // 415 - 303
driftangle = abs((252 - driftweight)*player->drift/5);
return basedrift + (FixedMul(driftadjust * FRACUNIT, countersteer) / FRACUNIT);
return basedrift + FixedMul(driftangle, countersteer);
}
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)

View file

@ -1532,15 +1532,10 @@ static int lib_hudenabled(lua_State *L)
static int lib_hudsetvotebackground(lua_State *L)
{
memset(VoteScreen.luaPrefix, 0, sizeof(VoteScreen.luaPrefix));
if (lua_isnoneornil(L, 1))
{
if (luaVoteScreen)
{
free(luaVoteScreen);
}
luaVoteScreen = NULL;
return 0;
}
@ -1551,15 +1546,8 @@ static int lib_hudsetvotebackground(lua_State *L)
return luaL_argerror(L, 1, "prefix should 4 characters wide");
}
if (!luaVoteScreen)
{
luaVoteScreen = (char*)malloc(5);
luaVoteScreen[4] = 0;
}
strncpy(luaVoteScreen, prefix, 4);
strupr(luaVoteScreen);
strncpy(VoteScreen.luaPrefix, prefix, 4);
strupr(VoteScreen.luaPrefix);
return 0;
}

View file

@ -365,6 +365,12 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"gamespeed")) {
lua_pushinteger(L, gamespeed);
return 1;
} else if (fastcmp(word,"nummapboxes")) {
lua_pushinteger(L, nummapboxes);
return 1;
} else if (fastcmp(word,"numgotboxes")) {
lua_pushinteger(L, numgotboxes);
return 1;
} else if (fastcmp(word,"itembreaker")) {
lua_pushinteger(L, itembreaker);
return 1;
@ -428,6 +434,36 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word, "compatmode")) {
lua_pushboolean(L, lua_compatmode);
return 1;
} else if (fastcmp(word, "hyudorotime")) {
lua_pushinteger(L, hyudorotime);
return 1;
} else if (fastcmp(word, "stealtime")) {
lua_pushinteger(L, stealtime);
return 1;
} else if (fastcmp(word, "sneakertime")) {
lua_pushinteger(L, sneakertime);
return 1;
} else if (fastcmp(word, "waterpaneltime")) {
lua_pushinteger(L, waterpaneltime);
return 1;
} else if (fastcmp(word, "bubbletime")) {
lua_pushinteger(L, bubbletime);
return 1;
} else if (fastcmp(word, "comebacktime")) {
lua_pushinteger(L, comebacktime);
return 1;
} else if (fastcmp(word, "greasetics")) {
lua_pushinteger(L, greasetics);
return 1;
} else if (fastcmp(word, "wipeoutslowtime")) {
lua_pushinteger(L, wipeoutslowtime);
return 1;
} else if (fastcmp(word, "wantedreduce")) {
lua_pushinteger(L, wantedreduce);
return 1;
} else if (fastcmp(word, "wantedfrequency")) {
lua_pushinteger(L, wantedfrequency);
return 1;
} else if (fastcmp(word, "mapnamespace")) {
lua_pushstring(L, P_MapNamespaceString(mapnamespace));
return 1;
@ -513,6 +549,26 @@ int LUA_WriteGlobals(lua_State *L, const char *word)
nummapboxes = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word,"numgotboxes"))
numgotboxes = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "hyudorotime"))
hyudorotime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "stealtime"))
stealtime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "sneakertime"))
sneakertime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "waterpaneltime"))
waterpaneltime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "bubbletime"))
bubbletime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "comebacktime"))
comebacktime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "greasetics"))
greasetics = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "wipeoutslowtime"))
wipeoutslowtime = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "wantedreduce"))
wantedreduce = (INT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "wantedfrequency"))
wantedfrequency = (INT32)luaL_checkinteger(L, 2);
else
return 0;

View file

@ -332,6 +332,9 @@ CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
consvar_t cv_newgametype = CVAR_INIT ("newgametype", "Race", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange);
consvar_t cv_showallmaps = CVAR_INIT ("showallmaps", "No", CV_SAVE, CV_YesNo, NULL);
consvar_t cv_showtrackaddon = CVAR_INIT ("showtrackaddon", "Yes", CV_SAVE, CV_YesNo, NULL);
static CV_PossibleValue_t serversort_cons_t[] = {
{0,"Ping"},
{1,"Modified State"},
@ -1311,6 +1314,21 @@ boolean M_Responder(event_t *ev)
default:
break;
}
if (menustack[0])
{
menuitem_t *item = currentMenu->numitems ? &currentMenu->menuitems[itemOn] : NULL;
if (item && item->cvar == &cv_nextmap)
{
if (ch == gamecontrol[0][gc_fire][0]
|| ch == gamecontrol[0][gc_fire][1])
{
S_StartSound(NULL, sfx_menu1);
COM_ImmedExecute("add kartencore 1");
}
}
}
}
else if (menustack[0])
{
@ -2002,6 +2020,9 @@ void M_Init(void)
COM_AddCommand("manual", Command_Manual_f);
CV_RegisterVar(&cv_showallmaps);
CV_RegisterVar(&cv_showtrackaddon);
// Menu hacks
CV_RegisterVar(&cv_dummymenuplayer);
CV_RegisterVar(&cv_dummyteam);
@ -2831,17 +2852,17 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
switch (levellistmode)
{
case LLM_CREATESERVER:
// Should the map be hidden?
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU && mapnum+1 != gamemap)
return false;
if (M_MapLocked(mapnum+1))
return false; // not unlocked
// Check for TOL
if (gt >= 0 && !(mapheaderinfo[mapnum]->typeoflevel & G_TOLFlag(gt)))
return false;
// Should the map be hidden?
if (mapheaderinfo[mapnum]->menuflags & LF2_HIDEINMENU && mapnum+1 != gamemap)
return cv_showallmaps.value;
if (M_MapLocked(mapnum+1))
return cv_showallmaps.value; // not unlocked
return true;
/*case LLM_LEVELSELECT:
@ -4482,7 +4503,7 @@ INT32 MR_PlaybackQuit(INT32 choice)
INT32 MR_ChangeLevel(INT32 choice)
{
(void)choice;
INT16 map = cv_nextmap.value ? cv_nextmap.value : G_RandMap(G_TOLFlag(cv_newgametype.value), gamestate == GS_LEVEL ? gamemap-1 : prevmap, 0, 0, false, NULL);
INT16 map = cv_nextmap.value ? cv_nextmap.value : G_RandMap(G_TOLFlag(cv_newgametype.value), gamestate == GS_LEVEL ? gamemap-1 : prevmap, 0, 0, NULL);
M_ClearMenus(true);
COM_BufAddText(va("map %d -gametype \"%s\"\n", map, cv_newgametype.string));
return true;
@ -6368,7 +6389,7 @@ INT32 MR_StartServer(INT32 choice)
G_StopMetalDemo();
if (!cv_nextmap.value)
CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, 0, 0, false, NULL)+1);
CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, 0, 0, NULL)+1);
if (cv_maxplayers.value < ssplayers+1)
CV_SetValue(&cv_maxplayers, ssplayers+1);
@ -6401,12 +6422,28 @@ static void M_DrawLevelSelectOnly(INT16 y, boolean selected, boolean leftfade, b
patch_t *PictureOfLevel;
INT32 x, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1;
fixed_t scale = M_GetMapThumbnail(cv_nextmap.value-1, &PictureOfLevel)/4;
menuitem_t *item = currentMenu->numitems ? &currentMenu->menuitems[itemOn] : NULL;
w = FixedMul(SHORT(PictureOfLevel->width), scale);
i = FixedMul(SHORT(PictureOfLevel->height), scale);
x = BASEVIDWIDTH/2 - w/2;
y = y + 60 - i;
if ((levellistmode != LLM_TIMEATTACK) && (item->cvar == &cv_nextmap)) // so it doesent show in record attack menu
{
char encoretoggle[40] = {0};
const char *item1 = gamecontrol[0][gc_fire][0] != 0 ? G_KeynumToString(gamecontrol[0][gc_fire][0]) : NULL;
const char *item2 = gamecontrol[0][gc_fire][1] != 0 ? G_KeynumToString(gamecontrol[0][gc_fire][1]) : NULL;
if (item1 != NULL && item2 != NULL)
snprintf(encoretoggle, 40, "%s/%s - Toggle Encore: %s", item1, item2, cv_kartencore.string);
else
snprintf(encoretoggle, 40, "%s - Toggle Encore: %s", item1 != NULL ? item1 : item2 != NULL ? item2 : "Item", cv_kartencore.string);
V_DrawThinString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_TRANSLUCENT|V_ALLOWLOWERCASE, encoretoggle);
}
if (selected && skullAnimCounter < 4)
trans = 0;
else
@ -6414,6 +6451,21 @@ static void M_DrawLevelSelectOnly(INT16 y, boolean selected, boolean leftfade, b
V_DrawFill(x-1, y-1, w+2, i+2, trans); // variable reuse...
if (cv_nextmap.value && cv_showtrackaddon.value)
{
char *addonname = wadfiles[WADFILENUM(mapheaderinfo[cv_nextmap.value-1]->lumpnum)]->filename;
INT32 len;
INT32 charlimit = 21 + (dupadjust/5);
nameonly(addonname);
len = strlen(addonname);
#define charsonside 14
if (len > charlimit)
V_DrawThinString(x+w+5, y+i-8, V_TRANSLUCENT|MENUCAPS, va("%.*s...%s", charsonside, addonname, addonname+((len-charlimit) + charsonside))); // variable reuse...
#undef charsonside
else
V_DrawThinString(x+w+5, y+i-8, V_TRANSLUCENT|MENUCAPS, addonname); // variable reuse...
}
if ((cv_kartencore.value != 1) || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, 0, PictureOfLevel, NULL);
else
@ -8047,6 +8099,7 @@ INT32 MR_HandleViewServer(INT32 choice)
case KEY_ENTER:
S_StartSound(NULL, sfx_menu1);
ChangeClientMode(CL_CHECKFILES);
ChangeServMusic(SERVMUS_2, true,true);
M_ClearMenus(false);
return true;
break;

View file

@ -71,7 +71,7 @@ typedef enum
THINK_MOBJ,
THINK_FLOORS, // thanks diamond square
THINK_DYNSLOPE,
// Lists after this may exist but they do not call an
// action in P_RunThinkers
NUM_ACTIVETHINKERLISTS,

View file

@ -5209,6 +5209,7 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITEFIXED(save->p, mapobjectscale);
// SRB2kart
WRITEINT32(save->p, nummapboxes);
WRITEINT32(save->p, numgotboxes);
WRITEUINT8(save->p, numtargets);
WRITEUINT8(save->p, itembreaker);
@ -5239,6 +5240,19 @@ static void P_NetArchiveMisc(savebuffer_t *save, boolean resending)
WRITEUINT32(save->p, introtime);
WRITEUINT32(save->p, starttime);
WRITEINT32(save->p, hyudorotime);
WRITEINT32(save->p, stealtime);
WRITEINT32(save->p, sneakertime);
WRITEINT32(save->p, waterpaneltime);
WRITEINT32(save->p, itemtime);
WRITEINT32(save->p, bubbletime);
WRITEINT32(save->p, comebacktime);
WRITEINT32(save->p, bumptime);
WRITEINT32(save->p, greasetics);
WRITEINT32(save->p, wipeoutslowtime);
WRITEINT32(save->p, wantedreduce);
WRITEINT32(save->p, wantedfrequency);
WRITEUINT32(save->p, timelimitintics);
WRITEUINT32(save->p, extratimeintics);
WRITEUINT32(save->p, secretextratime);
@ -5379,6 +5393,7 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
mapobjectscale = READFIXED(save->p);
// SRB2kart
nummapboxes = READINT32(save->p);
numgotboxes = READINT32(save->p);
numtargets = READUINT8(save->p);
itembreaker = (boolean)READUINT8(save->p);
@ -5408,6 +5423,19 @@ FUNCINLINE static ATTRINLINE boolean P_NetUnArchiveMisc(savebuffer_t *save, bool
introtime = READUINT32(save->p);
starttime = READUINT32(save->p);
hyudorotime = READINT32(save->p);
stealtime = READINT32(save->p);
sneakertime = READINT32(save->p);
waterpaneltime = READINT32(save->p);
itemtime = READINT32(save->p);
bubbletime = READINT32(save->p);
comebacktime = READINT32(save->p);
bumptime = READINT32(save->p);
greasetics = READINT32(save->p);
wipeoutslowtime = READINT32(save->p);
wantedreduce = READINT32(save->p);
wantedfrequency = READINT32(save->p);
timelimitintics = READUINT32(save->p);
extratimeintics = READUINT32(save->p);

View file

@ -70,6 +70,8 @@
#include "deh_tables.h"
#include "y_inter.h"
// for MapLoad hook
#include "lua_script.h"
#include "lua_hook.h"
@ -9049,6 +9051,11 @@ static void P_LoadSoundsRange(UINT16 wadnum, size_t *sreplaces)
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name);
I_FreeSfx(&S_sfx[j]);
// Re-cache it
//if (S_PrecacheSound())
//S_sfx[j].data = I_GetSfx(&S_sfx[j]);
*sreplaces += 1;
break; // there shouldn't be two sounds with the same name, so stop looking
}
@ -9233,6 +9240,35 @@ boolean P_AddWadFile(const char *wadfilename, wadcompat_t compat)
return true;
}
//
// check for non Lua votescreen replacements
//
static boolean P_CheckVoteReplacements(UINT16 wad)
{
UINT16 i;
for (i = 0; i < wadfiles[wad]->numlumps; i++)
{
const char *name = W_CheckNameForNumPwad(wad, i);
// widescreen patch Race
if (!VoteScreen.replaced.widerace && !strncmp(name, "INTERSCW", 8))
VoteScreen.replaced.widerace = true;
if (!VoteScreen.replaced.race && !strncmp(name, "INTERSCR", 8))
VoteScreen.replaced.race = true;
// widescreen patch Battle
if (!VoteScreen.replaced.widebattle && !strncmp(name, "BATTLSCW", 8))
VoteScreen.replaced.widebattle = true;
if (!VoteScreen.replaced.battle && !strncmp(name, "BATTLSCR", 8))
VoteScreen.replaced.battle = true;
}
return VoteScreen.replaced.widerace && VoteScreen.replaced.race
&& VoteScreen.replaced.widebattle && VoteScreen.replaced.battle;
}
//
// Add a WAD file and do the per-WAD setup stages.
// Call P_MultiSetupWadFiles as soon as possible after any number of these.
@ -9241,6 +9277,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
{
size_t sreplaces = 0, mreplaces = 0, digmreplaces = 0;
UINT16 numlumps, wadnum;
static boolean allvotereplaced = false;
// Init file.
if ((numlumps = W_InitFile(wadfilename, false, false, compat)) == LUMPERROR)
@ -9264,6 +9301,9 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, wadcompat_t compat)
P_LoadSoundsRange(wadnum, &sreplaces);
P_LoadMusicsRange(wadnum, &digmreplaces, &mreplaces);
if (!allvotereplaced && P_CheckVoteReplacements(wadnum))
allvotereplaced = true;
if (!devparm && sreplaces)
CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces));
if (!devparm && mreplaces)

View file

@ -217,7 +217,7 @@ void P_InitThinkers(void)
boss3cap = NULL;
waypointcap = NULL;
kitemcap = NULL;
iquehead = iquetail = 0;
for (i = 0; i <= 15; i++)
@ -665,6 +665,13 @@ void P_Ticker(boolean run)
players[i].jointime++;
}
if (run)
{
// Update old view state BEFORE ticking so resetting
// the old interpolation state from game logic works.
R_UpdateViewInterpolation();
}
if (objectplacing)
{
if (OP_FreezeObjectplace())
@ -782,7 +789,7 @@ void P_Ticker(boolean run)
S_StartSound(NULL, sfx_s3kad); // GO!
}
}
if (!(gametyperules & GTR_FREEROAM) && 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
@ -793,7 +800,7 @@ void P_Ticker(boolean run)
S_ShowMusicCredit();
}
}
}
ps_lua_thinkframe_time = I_GetPreciseTime();
@ -924,10 +931,9 @@ void P_Ticker(boolean run)
if (!player->mo)
continue;
const boolean isSkyVisibleForPlayer = (!udmf ? skyVisiblePerPlayer[i] : true);
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
if (isSkyVisibleForPlayer && skybox)
if (skyVisiblePerPlayer[i] && skybox)
{
R_SkyboxFrame(i);
}

View file

@ -45,16 +45,6 @@
#include "hardware/hw_main.h"
#endif
//profile stuff ---------------------------------------------------------
//#define TIMING
#ifdef TIMING
#include "p5prof.h"
INT64 mycount;
INT64 mytotal = 0;
//unsigned long nombre = 100000;
#endif
//profile stuff ---------------------------------------------------------
extern consvar_t cv_debugrender_visplanes;
extern consvar_t cv_debugrender_freezebsp;
@ -1420,7 +1410,6 @@ void R_SkyboxFrame(int s)
newview->z += campos.z * -mh->skybox_scalez;
}
R_SetupCommonFrame(player, r_viewmobj->subsector);
}
@ -1513,14 +1502,17 @@ static void Mask_Post (maskcount_t* m)
// ================
// viewx, viewy, viewangle, all that good stuff must be set
static void R_RenderViewpoint(maskcount_t* mask, INT32 cachenum)
static void R_RenderViewpoint(maskcount_t* mask, INT32 cachenum, boolean drawprecip)
{
Mask_Pre(mask);
curdrawsegs = ds_p;
R_RenderFirstBSPNode(cachenum);
R_AddPrecipitationSprites();
// dont draw precip in skyboxes!
if (drawprecip)
R_AddPrecipitationSprites();
Mask_Post(mask);
}
@ -1533,47 +1525,29 @@ static void R_RenderViewpoint(maskcount_t* mask, INT32 cachenum)
void R_RenderPlayerView(void)
{
INT32 nummasks = 1;
maskcount_t* masks = static_cast<maskcount_t*>(malloc(sizeof(maskcount_t)));
player_t * player = &players[displayplayers[viewssnum]];
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
UINT8 i;
INT32 nummasks = 1;
maskcount_t* masks = static_cast<maskcount_t*>(malloc(sizeof(maskcount_t)));
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
const boolean oldsky = (skybox && mapnamespace == MNS_SRB2KART);
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
// using sky portals on kart maps usually results in pretty bad performance
skyVisible = oldsky && skyVisiblePerPlayer[viewssnum];
// using sky portals on kart maps usually results in very bad performance
if (mapnamespace == MNS_SRB2KART)
if (skyVisible)
{
// load previous saved value of skyVisible for the player
for (i = 0; i <= splitscreen; i++)
{
if (player != &players[displayplayers[i]])
continue;
skyVisible = skyVisiblePerPlayer[i];
break;
}
if (skybox && skyVisible)
{
R_SkyboxFrame(viewssnum);
R_ClearClipSegs();
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearPlanes();
R_ClearSprites();
Mask_Pre(&masks[nummasks - 1]);
R_RenderBSPNode((INT32)numnodes - 1);
Mask_Post(&masks[nummasks - 1]);
R_ClipSprites(drawsegs, NULL);
R_DrawPlanes();
// well sometimes synchronization is off and may result in some visual glitching, oh well
tp_sema = srb2::g_main_threadpool->end_sema();
srb2::g_main_threadpool->notify_sema(tp_sema);
srb2::g_main_threadpool->wait_sema(tp_sema);
srb2::g_main_threadpool->begin_sema();
R_DrawMasked(masks, nummasks);
}
R_SkyboxFrame(viewssnum);
R_ClearClipSegs();
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearPlanes();
R_ClearSprites();
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1, false);
R_ClipSprites(drawsegs, NULL);
R_DrawSkyPlanes();
R_DrawPlanes();
R_DrawMasked(masks, nummasks);
}
R_SetupFrame(viewssnum, skybox);
skyVisible = false;
framecount++;
@ -1589,7 +1563,7 @@ void R_RenderPlayerView(void)
portalclipend = viewwidth-viewmorph[viewssnum].x1-1;
R_PortalClearClipSegs(portalclipstart, portalclipend);
memcpy(ceilingclip, viewmorph[viewssnum].ceilingclip, sizeof(INT16)*vid.width);
memcpy(floorclip, viewmorph[viewssnum].floorclip, sizeof(INT16)*vid.width);
memcpy(floorclip, viewmorph[viewssnum].floorclip, sizeof(INT16)*vid.width);
}
else
{
@ -1603,35 +1577,17 @@ void R_RenderPlayerView(void)
Portal_InitList();
// The head node is the last node output.
Mask_Pre(&masks[nummasks - 1]);
curdrawsegs = ds_p;
//profile stuff ---------------------------------------------------------
#ifdef TIMING
mytotal = 0;
ProfZeroTimer();
#endif
ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0;
ps_bsptime = I_GetPreciseTime();
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1);
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1, true);
ps_bsptime = I_GetPreciseTime() - ps_bsptime;
#ifdef TIMING
RDMSR(0x10, &mycount);
mytotal += mycount; // 64bit add
CONS_Debug(DBG_RENDER, "RenderBSPNode: 0x%d %d\n", *((INT32 *)&mytotal + 1), (INT32)mytotal);
#endif
//profile stuff ---------------------------------------------------------
Mask_Post(&masks[nummasks - 1]);
ps_sw_spritecliptime = I_GetPreciseTime();
R_ClipSprites(drawsegs, NULL);
ps_sw_spritecliptime = I_GetPreciseTime() - ps_sw_spritecliptime;
// Add skybox portals caused by sky visplanes.
if (mapnamespace != MNS_SRB2KART && skybox)
if (skybox && !oldsky)
Portal_AddSkyboxPortals();
// Portal rendering. Hijacks the BSP traversal.
@ -1645,7 +1601,7 @@ void R_RenderPlayerView(void)
portal_t *portal;
for(portal = portal_base; portal; portal = portal_base)
for (portal = portal_base; portal; portal = portal_base)
{
portalrender = portal->pass; // Recursiveness depth.
@ -1667,15 +1623,9 @@ void R_RenderPlayerView(void)
masks = static_cast<maskcount_t*>(realloc(masks, (++nummasks)*sizeof(maskcount_t)));
Mask_Pre(&masks[nummasks - 1]);
curdrawsegs = ds_p;
// Render the BSP from the new viewpoint, and clip
// any sprites with the new clipsegs and window.
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1);
//portalskipprecipmobjs = false;
R_RenderViewpoint(&masks[nummasks - 1], nummasks - 1, !portal->isskybox);
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
@ -1690,10 +1640,8 @@ void R_RenderPlayerView(void)
ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime;
ps_sw_planetime = I_GetPreciseTime();
R_DrawSkyPlanes();
R_DrawPlanes();
tp_sema = srb2::g_main_threadpool->end_sema();
srb2::g_main_threadpool->notify_sema(tp_sema);
srb2::g_main_threadpool->wait_sema(tp_sema);
ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime;
// draw mid texture and sprite
@ -1710,6 +1658,7 @@ void R_RenderPlayerView(void)
{
if (pl->minx > pl->maxx)
continue;
auto col = [](int x, int top, int bot)
{
if (top > bot)
@ -1718,7 +1667,9 @@ void R_RenderPlayerView(void)
top = 0;
if (bot > viewheight-1)
bot = viewheight-1;
UINT8* p = &topleft[x + top * vid.width];
while (top <= bot)
{
*p = 35;
@ -1726,21 +1677,27 @@ void R_RenderPlayerView(void)
top++;
}
};
auto span = [col](int x, int top, int bot)
{
if (top <= bot)
col(x, top, bot);
};
INT32 top = pl->top[pl->minx];
INT32 bottom = pl->bottom[pl->minx];
span(pl->minx, top, bottom);
span(pl->maxx, pl->top[pl->maxx], pl->bottom[pl->maxx]);
for (INT32 x = pl->minx + 1; x < std::min(pl->maxx, viewwidth); ++x)
{
INT32 new_top = pl->top[x];
INT32 new_bottom = pl->bottom[x];
if (new_top > new_bottom)
continue;
if (top > bottom)
{
col(x, new_top, new_top);
@ -1751,6 +1708,7 @@ void R_RenderPlayerView(void)
col(x, top, new_top);
col(x, bottom, new_bottom);
}
top = new_top;
bottom = new_bottom;
}
@ -1761,13 +1719,13 @@ void R_RenderPlayerView(void)
// debugrender_portal: fill portals with red, draw over everything
if (portal_base && cv_debugrender_portal.value)
{
const UINT8 pal = 0x23; // red
portal_t *portal;
constexpr UINT8 pal = 0x23; // red
for (portal = portal_base; portal; portal = portal_base)
{
INT32 width = (portal->end - portal->start);
INT32 i;
INT32 width = (portal->end - portal->start);
for (i = 0; i < std::min(width, viewwidth); ++i)
{
@ -1784,18 +1742,9 @@ void R_RenderPlayerView(void)
}
}
if (mapnamespace == MNS_SRB2KART)
{
// save value to skyVisiblePerPlayer
// this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa
for (i = 0; i <= splitscreen; i++)
{
if (player != &players[displayplayers[i]])
continue;
skyVisiblePerPlayer[i] = skyVisible;
break;
}
}
// save value to skyVisiblePerPlayer
// this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa
skyVisiblePerPlayer[viewssnum] = (!oldsky || skyVisible); // if we dont draw the sky using the old method, always mark this as true
free(masks);
}

View file

@ -149,12 +149,13 @@ static void R_MapPlane(drawspandata_t *ds, spandrawfunc_t *spanfunc, INT32 y, IN
if (!R_CheckMapPlane(__func__, y, x1, x2))
return;
angle = (ds->currentplane->viewangle + ds->currentplane->plangle)>>ANGLETOFINESHIFT;
angle = (ds->currentplane->viewangle + ds->currentplane->plangle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
distance = FixedMul(ds->planeheight, yslope[y]);
span = abs(centery - y);
span = abs(centery - y);
if (span) // Don't divide by zero
{
ds->xstep = FixedMul(planesin, ds->planeheight) / span;
@ -214,7 +215,7 @@ static void R_MapPlane(drawspandata_t *ds, spandrawfunc_t *spanfunc, INT32 y, IN
}
}
ds->y = y;
ds->y = y;
ds->x1 = x1;
ds->x2 = x2;
@ -306,6 +307,7 @@ void R_ClearPlanes(void)
static visplane_t *new_visplane(unsigned hash)
{
visplane_t *check = freetail;
if (!check)
{
check = static_cast<visplane_t*>(calloc(1, sizeof (*check)));
@ -317,6 +319,7 @@ static visplane_t *new_visplane(unsigned hash)
if (!freetail)
freehead = &freetail;
}
check->next = visplanes[hash];
visplanes[hash] = check;
@ -409,6 +412,7 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
if (!pfloor)
{
hash = visplane_hash(picnum, lightlevel, height);
for (check = visplanes[hash]; check; check = check->next)
{
if (polyobj != check->polyobj)
@ -456,8 +460,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->ripple = ripple;
check->damage = damage;
memset(check->top, 0xff, sizeof (check->top));
memset(check->bottom, 0x00, sizeof (check->bottom));
memset(check->top, 0xff, sizeof(check->top));
memset(check->bottom, 0x00, sizeof(check->bottom));
return check;
}
@ -512,8 +516,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
}
else
{
unsigned hash =
visplane_hash(pl->picnum, pl->lightlevel, pl->height);
unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height);
new_pl = new_visplane(hash);
}
@ -537,8 +540,8 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
pl = new_pl;
pl->minx = start;
pl->maxx = stop;
memset(pl->top, 0xff, sizeof pl->top);
memset(pl->bottom, 0x00, sizeof pl->bottom);
memset(pl->top, 0xff, sizeof(pl->top));
memset(pl->bottom, 0x00, sizeof(pl->bottom));
}
return pl;
}
@ -570,7 +573,7 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
if (b1 >= vid.height) b1 = vid.height-1;
if (t2 >= vid.height) t2 = vid.height-1;
if (b2 >= vid.height) b2 = vid.height-1;
if (x-1 >= vid.width) x = vid.width;
if (x-1 >= vid.width) x = vid.width;
// We want to draw N spans per subtask to ensure the work is
// coarse enough to not be too slow due to task scheduling overhead.
@ -582,6 +585,7 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
{
INT32 spanstartcopy[kSpanTaskGranularity] = {0};
INT32 taskspans = 0;
for (int i = 0; i < kSpanTaskGranularity; i++)
{
if (!((t1 + i) < t2 && (t1 + i) <= b1))
@ -591,12 +595,14 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
spanstartcopy[i] = spanstart[t1 + i];
taskspans += 1;
}
auto task = [=]() mutable -> void {
for (int i = 0; i < taskspans; i++)
{
mapfunc(&dc_copy, spanfunc, t1 + i, spanstartcopy[i], x - 1, false);
}
};
if (allow_parallel)
{
srb2::g_main_threadpool->schedule(std::move(task));
@ -605,12 +611,14 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
{
(task)();
}
t1 += taskspans;
}
while (b1 > b2 && b1 >= t1)
{
INT32 spanstartcopy[kSpanTaskGranularity] = {0};
INT32 taskspans = 0;
for (int i = 0; i < kSpanTaskGranularity; i++)
{
if (!((b1 - i) > b2 && (b1 - i) >= t1))
@ -620,12 +628,14 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
spanstartcopy[i] = spanstart[b1 - i];
taskspans += 1;
}
auto task = [=]() mutable -> void {
for (int i = 0; i < taskspans; i++)
{
mapfunc(&dc_copy, spanfunc, b1 - i, spanstartcopy[i], x - 1, false);
}
};
if (allow_parallel)
{
srb2::g_main_threadpool->schedule(std::move(task));
@ -634,6 +644,7 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
{
(task)();
}
b1 -= taskspans;
}
@ -643,28 +654,6 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
spanstart[b2--] = x;
}
void R_DrawPlanes(void)
{
visplane_t *pl;
INT32 i;
drawspandata_t ds {0};
ZoneScoped;
R_UpdatePlaneRipple(&ds);
for (i = 0; i < MAXVISPLANES; i++, pl++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->ffloor != NULL || pl->polyobj != NULL)
continue;
R_DrawSinglePlane(&ds, pl, cv_parallelsoftware.value);
}
}
}
// R_DrawSkyPlane
//
// Draws the sky within the plane's top/bottom bounds
@ -759,6 +748,75 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc)(drawcolumndata_t*), bo
}
}
void R_DrawSkyPlanes(void)
{
INT32 i;
visplane_t *pl;
ZoneScoped;
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
for (i = 0; i < MAXVISPLANES; i++, pl++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->picnum != skyflatnum || pl->ffloor || pl->polyobj)
continue;
INT16 highlight = R_PlaneIsHighlighted(pl);
if (highlight != -1)
{
drawcolumndata_t dc = {};
dc.r8_flatcolor = highlight;
dc.lightmap = colormaps;
for (dc.x = pl->minx; dc.x <= pl->maxx; ++dc.x)
{
dc.yl = pl->top[dc.x];
dc.yh = pl->bottom[dc.x];
R_DrawColumn_Flat(&dc);
}
}
else
{
R_DrawSkyPlane(pl, colfunc, cv_parallelsoftware.value);
}
}
}
tp_sema = srb2::g_main_threadpool->end_sema();
srb2::g_main_threadpool->notify_sema(tp_sema);
srb2::g_main_threadpool->wait_sema(tp_sema);
}
void R_DrawPlanes(void)
{
visplane_t *pl;
INT32 i;
drawspandata_t ds {0};
ZoneScoped;
R_UpdatePlaneRipple(&ds);
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
for (i = 0; i < MAXVISPLANES; i++, pl++)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->ffloor != NULL || pl->polyobj != NULL)
continue;
R_DrawSinglePlane(&ds, pl, cv_parallelsoftware.value);
}
}
tp_sema = srb2::g_main_threadpool->end_sema();
srb2::g_main_threadpool->notify_sema(tp_sema);
srb2::g_main_threadpool->wait_sema(tp_sema);
}
// Returns the height of the sloped plane at (x, y) as a 32.16 fixed_t
static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
{
@ -939,38 +997,23 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
INT32 spanfunctype = BASEDRAWFUNC;
debugrender_highlight_t debug = debugrender_highlight_t::SW_HI_PLANES;
void (*mapfunc)(drawspandata_t*, void(*)(drawspandata_t*), INT32, INT32, INT32, boolean) = R_MapPlane;
INT16 highlight = R_PlaneIsHighlighted(pl);
INT16 highlight;
if (!(pl->minx <= pl->maxx))
return;
ZoneScoped;
R_UpdatePlaneRipple(ds);
// sky flat
// we check this here due to drawmasked
if (pl->picnum == skyflatnum)
{
if (highlight != -1)
{
drawcolumndata_t dc = {};
dc.r8_flatcolor = highlight;
dc.lightmap = colormaps;
for (dc.x = pl->minx; dc.x <= pl->maxx; ++dc.x)
{
dc.yl = pl->top[dc.x];
dc.yh = pl->bottom[dc.x];
R_DrawColumn_Flat(&dc);
}
}
else
{
R_DrawSkyPlane(pl, colfunc, allow_parallel);
}
return;
}
R_UpdatePlaneRipple(ds);
highlight = R_PlaneIsHighlighted(pl);
ds->planeripple.active = false;
ds->brightmap = NULL;
R_SetSpanFunc(BASEDRAWFUNC, false, false);
@ -980,13 +1023,13 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
// Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red)
if (pl->polyobj->translucency >= NUMTRANSMAPS)
return; // Don't even draw it
else if (pl->polyobj->translucency > 0)
{
spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
ds->transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
}
else if (pl->polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
else if (pl->polyobj->translucency > 0)
{
spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
ds->transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
}
else if (pl->polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if (pl->polyobj->translucency == 0 || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
light = (pl->lightlevel >> LIGHTSEGSHIFT);
@ -1050,7 +1093,6 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
debug = SW_HI_PLANES;
}
#ifndef NOWATER
if (pl->ripple)
{
INT32 top, bottom;
@ -1061,13 +1103,8 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
if (top < 0)
top = 0;
if (bottom > viewheight)
bottom = viewheight;
top = std::max(0, pl->high - 8);
bottom = std::min(viewheight, pl->low + 8);
// Only copy the part of the screen we need
UINT8 i = R_GetViewNumber();
@ -1104,7 +1141,6 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
vid.width, vid.width);
}
}
#endif
}
ds->currentplane = pl;
@ -1116,7 +1152,7 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
return;
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)];
ds->flatwidth = texture->width;
ds->flatwidth = texture->width;
ds->flatheight = texture->height;
/*(if (R_CheckSolidColorFlat())
@ -1228,8 +1264,8 @@ void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_paralle
}
// set the maximum value for unsigned
pl->top[pl->maxx+1] = 0xffff;
pl->top[pl->minx-1] = 0xffff;
pl->top[pl->maxx+1] = 0xffff;
pl->top[pl->minx-1] = 0xffff;
pl->bottom[pl->maxx+1] = 0x0000;
pl->bottom[pl->minx-1] = 0x0000;
@ -1250,10 +1286,11 @@ void R_PlaneBounds(visplane_t *plane)
for (i = plane->minx + 1; i <= plane->maxx; i++)
{
if (plane->top[i] < hi)
hi = plane->top[i];
hi = plane->top[i];
if (plane->bottom[i] > low)
low = plane->bottom[i];
low = plane->bottom[i];
}
plane->high = hi;
plane->low = low;
}
@ -1262,11 +1299,11 @@ INT16 R_PlaneIsHighlighted(const visplane_t *pl)
{
switch (pl->damage)
{
case SD_DEATHPIT:
case SD_INSTAKILL:
return 35; // red
case SD_DEATHPIT:
case SD_INSTAKILL:
return 35; // red
default:
return -1;
default:
return -1;
}
}

View file

@ -81,6 +81,7 @@ void R_ClearPlanes(void);
void R_ClearFFloorClips (void);
void R_DrawPlanes(void);
void R_DrawSkyPlanes(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, polyobj_t *polyobj, pslope_t *slope, boolean noencore,
boolean ripple, boolean reverseLight, const sector_t *lighting_sector, sectordamage_t damage);

View file

@ -20,7 +20,7 @@
#include "r_things.h"
#include "r_sky.h"
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
// Linked list for portals.
portal_t *portal_base, *portal_cap;
@ -31,7 +31,7 @@ INT32 portalclipstart, portalclipend;
portal_t *g_portal; // is curline a portal seg?
void Portal_InitList (void)
void Portal_InitList(void)
{
portalrender = 0;
portal_base = portal_cap = NULL;
@ -43,15 +43,15 @@ void Portal_InitList (void)
* the function is called, so it is useful for converting one-sided
* lines into portals.
*/
void Portal_ClipRange (portal_t* portal)
void Portal_ClipRange(portal_t* portal)
{
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
INT32 i;
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
for (i = 0; i < end-start; i++)
{
*ceil = ceilingclip[start+i];
@ -65,14 +65,14 @@ void Portal_ClipRange (portal_t* portal)
/** Apply the clipping window from a portal.
*/
void Portal_ClipApply (const portal_t* portal)
void Portal_ClipApply(const portal_t* portal)
{
INT32 i;
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
INT32 start = portal->start;
INT32 end = portal->end;
INT16 *ceil = portal->ceilingclip;
INT16 *floor = portal->floorclip;
fixed_t *scale = portal->frontscale;
for (i = 0; i < end-start; i++)
{
@ -97,12 +97,12 @@ void Portal_ClipApply (const portal_t* portal)
}
}
static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
static portal_t* Portal_Add(const INT16 x1, const INT16 x2)
{
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
// Linked list.
if (!portal_base)
@ -118,19 +118,21 @@ static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
portal->next = NULL;
// Store clipping values so they can be restored once the portal is rendered.
portal->ceilingclip = ceilingclipsave;
portal->floorclip = floorclipsave;
portal->frontscale = frontscalesave;
portal->start = x1;
portal->end = x2;
portal->ceilingclip = ceilingclipsave;
portal->floorclip = floorclipsave;
portal->frontscale = frontscalesave;
portal->start = x1;
portal->end = x2;
// Increase recursion level.
portal->pass = portalrender+1;
portal->isskybox = false;
return portal;
}
void Portal_Remove (portal_t* portal)
void Portal_Remove(portal_t* portal)
{
portalcullsector = NULL;
portal_base = portal->next;
@ -150,13 +152,13 @@ void Portal_Remove (portal_t* portal)
* When the portal renders, it will create the illusion of
* the two lines being seamed together.
*/
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
void Portal_Add2Lines(const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
{
portal_t* portal = Portal_Add(x1, x2);
// Offset the portal view by the linedef centers
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
line_t* start = &lines[line1];
line_t* dest = &lines[line2];
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
@ -165,13 +167,6 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
vertex_t dest_c, start_c;
if (mapnamespace == MNS_SRB2KART)
{
portal->viewx = viewx;
portal->viewy = viewy;
portal->viewz = viewz;
}
// looking glass center
start_c.x = (start->v1->x + start->v2->x) / 2;
start_c.y = (start->v1->y + start->v2->y) / 2;
@ -180,24 +175,24 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
if ((dangle == 0) && (mapnamespace == MNS_SRB2KART))
if ((mapnamespace == MNS_SRB2KART) && dangle == 0)
{
// the entrance goes straight opposite the exit, so we just need to mess with the offset.
portal->viewx += dest_c.x - start_c.x;
portal->viewy += dest_c.y - start_c.y;
portal->viewx = viewx + (dest_c.x - start_c.x);
portal->viewy = viewy + (dest_c.y - start_c.y);
}
else
{
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
}
portal->viewz = viewz + (dest->frontsector->floorheight - start->frontsector->floorheight);
portal->viewangle = viewangle + dangle;
portal->clipline = line2;
@ -213,30 +208,31 @@ void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, con
* Since visplanes top/bottom windows work in an identical way,
* it can just be copied almost directly.
*/
static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal)
static void Portal_ClipVisplane(const visplane_t* plane, portal_t* portal)
{
INT16 start = portal->start;
INT16 end = portal->end;
INT32 i;
INT16 start = portal->start;
INT16 end = portal->end;
for (i = 0; i < end - start; i++)
{
// Invalid column.
if (plane->top[i + start] == 65535)
if (plane->top[i + start] == UINT16_MAX)
{
portal->ceilingclip[i] = -1;
portal->floorclip[i] = -1;
portal->floorclip[i] = -1;
continue;
}
portal->ceilingclip[i] = plane->top[i + start] - 1;
portal->floorclip[i] = plane->bottom[i + start] + 1;
portal->frontscale[i] = INT32_MAX;
portal->floorclip[i] = plane->bottom[i + start] + 1;
portal->frontscale[i] = INT32_MAX;
}
}
extern INT32 viewwidth;
static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* end)
static boolean TrimVisplaneBounds(const visplane_t* plane, INT16* start, INT16* end)
{
*start = plane->minx;
*end = plane->maxx + 1;
@ -249,7 +245,6 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
if (!(*start < *end))
return true;
/** Trims a visplane's horizontal gap to match its render area.
*
* Visplanes' minx/maxx may sometimes exceed the area they're
@ -257,13 +252,12 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
* valid area.
*/
while (plane->bottom[*start] == 0 && plane->top[*start] == 65535 && *start < *end)
while (plane->bottom[*start] == 0 && plane->top[*start] == UINT16_MAX && *start < *end)
{
(*start)++;
}
while (plane->bottom[*end - 1] == 0 && plane->top[*start] == 65535 && *end > *start)
while (plane->bottom[*end - 1] == 0 && plane->top[*start] == UINT16_MAX && *end > *start)
{
(*end)--;
}
@ -276,7 +270,7 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16*
* Applies the necessary offsets and rotation to give
* a depth illusion to the skybox.
*/
void Portal_AddSkybox (const visplane_t* plane)
void Portal_AddSkybox(const visplane_t* plane)
{
INT16 start, end;
mapheader_t *mh;
@ -289,9 +283,9 @@ void Portal_AddSkybox (const visplane_t* plane)
Portal_ClipVisplane(plane, portal);
portal->viewx = skyboxmo[0]->x;
portal->viewy = skyboxmo[0]->y;
portal->viewz = skyboxmo[0]->z;
portal->viewx = skyboxmo[0]->x;
portal->viewy = skyboxmo[0]->y;
portal->viewz = skyboxmo[0]->z;
portal->viewangle = viewangle + skyboxmo[0]->angle;
mh = mapheaderinfo[gamemap-1];
@ -323,12 +317,13 @@ void Portal_AddSkybox (const visplane_t* plane)
portal->viewz += viewz * -mh->skybox_scalez;
portal->clipline = -1;
portal->isskybox = true;
}
/** Creates portals for the currently existing sky visplanes.
* The visplanes are also removed and cleared from the list.
*/
void Portal_AddSkyboxPortals (void)
void Portal_AddSkyboxPortals(void)
{
visplane_t *pl;
INT32 i;
@ -338,15 +333,15 @@ void Portal_AddSkyboxPortals (void)
{
for (pl = visplanes[i]; pl; pl = pl->next)
{
if (pl->picnum == skyflatnum && !pl->damage)
{
Portal_AddSkybox(pl);
if (pl->picnum != skyflatnum || pl->damage)
continue;
pl->minx = 0;
pl->maxx = -1;
Portal_AddSkybox(pl);
count++;
}
pl->minx = 0;
pl->maxx = -1;
count++;
}
}

View file

@ -34,15 +34,16 @@ struct portal_t
fixed_t viewz;
angle_t viewangle;
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
INT32 clipline; /**< Optional clipline for line-based portals. */
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
INT32 clipline; /**< Optional clipline for line-based portals. */
boolean isskybox;
// Clipping information.
INT32 start; /**< First horizontal pixel coordinate to draw at. */
INT32 end; /**< Last horizontal pixel coordinate to draw at. */
INT16 *ceilingclip; /**< Temporary screen top clipping array. */
INT16 *floorclip; /**< Temporary screen bottom clipping array. */
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
INT32 start; /**< First horizontal pixel coordinate to draw at. */
INT32 end; /**< Last horizontal pixel coordinate to draw at. */
INT16 *ceilingclip; /**< Temporary screen top clipping array. */
INT16 *floorclip; /**< Temporary screen bottom clipping array. */
fixed_t *frontscale; /**< Temporary screen bottom clipping array. */
};
extern portal_t* portal_base;
@ -53,15 +54,15 @@ extern line_t *portalclipline;
extern sector_t *portalcullsector;
extern INT32 portalclipstart, portalclipend;
void Portal_InitList (void);
void Portal_Remove (portal_t* portal);
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_AddSkybox (const visplane_t* plane);
void Portal_InitList(void);
void Portal_Remove(portal_t* portal);
void Portal_Add2Lines(const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
void Portal_AddSkybox(const visplane_t* plane);
void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal);
void Portal_ClipRange(portal_t* portal);
void Portal_ClipApply(const portal_t* portal);
void Portal_AddSkyboxPortals (void);
void Portal_AddSkyboxPortals(void);
#ifdef __cplusplus
} // extern "C"

View file

@ -3786,7 +3786,12 @@ static void R_DrawMaskedList (drawnode_t* head)
{
drawspandata_t ds = {0};
next = r2->prev;
R_DrawSinglePlane(&ds, r2->plane, false);
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
R_DrawSinglePlane(&ds, r2->plane, cv_parallelsoftware.value);
tp_sema = srb2::g_main_threadpool->end_sema();
srb2::g_main_threadpool->notify_sema(tp_sema);
srb2::g_main_threadpool->wait_sema(tp_sema);
R_DoneWithNode(r2);
r2 = next;
}

View file

@ -65,6 +65,9 @@ consvar_t cv_vhseffect = CVAR_INIT ("vhspause", "On", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}};
consvar_t cv_shittyscreen = CVAR_INIT ("televisionsignal", "Okay", 0, shittyscreen_cons_t, NULL);
static CV_PossibleValue_t votescale_cons_t[] = {{0, "Vanilla"}, {1, "Adaptive"}, {2, "VerticalFill"}, {3, "HorizontalFill"}, {0, NULL}};
consvar_t cv_votebgscaling = CVAR_INIT ("votebgscaling", "Adaptive", 0, votescale_cons_t, NULL);
CV_PossibleValue_t cv_renderer_t[] = {
{1, "Software"},
#ifdef HWRENDER

View file

@ -133,7 +133,7 @@ extern INT32 scr_bpp;
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_renderhitbox, cv_fullscreen;
extern consvar_t cv_vhseffect, cv_shittyscreen;
extern consvar_t cv_vhseffect, cv_shittyscreen, cv_votebgscaling;
extern consvar_t cv_parallelsoftware;
// wait for page flipping to end or not

View file

@ -1532,6 +1532,51 @@ void V_DrawPatchFill(patch_t *pat)
}
}
// Draws a patch and tries to always fill the screen with the patch
void V_DrawAdaptiveScaledFullScreenPatch(patch_t *patch)
{
fixed_t x = 0, y = 0;
fixed_t scale = ((vid.width * FRACUNIT) / patch->width); // fit the screen horizontally
fixed_t scaled_height = FixedMul(patch->height << FRACBITS, scale);
// however, if this means the patch doesent fill out the screen vertically then
if (scaled_height < (vid.height << FRACBITS))
{
scale = ((vid.height * FRACUNIT) / patch->height); // scale it to fit the screen vertically
x = ((vid.width << FRACBITS) - FixedMul(patch->width << FRACBITS, scale)) / 2;
}
else
y = (vid.height << FRACBITS) - scaled_height;
V_DrawFixedPatch(x, y, scale, V_NOSCALEPATCH, patch, NULL);
}
// Draws a patch and scales it to fill out the screen vertically while remaining centered
void V_DrawVerticallyScaledFullScreenPatch(patch_t *patch)
{
fixed_t scale = ((vid.height * FRACUNIT) / patch->height);
fixed_t x = ((vid.width << FRACBITS) - FixedMul(patch->width << FRACBITS, scale)) / 2; // i fucking hate maths
V_DrawFixedPatch(x, 0, scale, V_NOSCALEPATCH, patch, NULL);
}
// Draws a patch and scales it to fill out the screen horizontally
// centers the patch when its too small to fit the screen vertically
void V_DrawHorizontallyScaledFullScreenPatch(patch_t *patch)
{
fixed_t scale = ((vid.width * FRACUNIT) / patch->width);
fixed_t scaled_height = FixedMul(patch->height << FRACBITS, scale);
fixed_t y = (vid.height << FRACBITS) - scaled_height;
// center it if it does not fit the screen vertically
if (scaled_height < (vid.height << FRACBITS))
{
y /= 2;
}
V_DrawFixedPatch(0, y, scale, V_NOSCALEPATCH, patch, NULL);
}
void V_DrawVhsEffect(boolean rewind)
{
static fixed_t upbary = 100*FRACUNIT, downbary = 150*FRACUNIT;

View file

@ -340,6 +340,10 @@ void V_DoPostProcessor(INT32 view, INT32 param);
void V_DrawPatchFill(patch_t *pat);
void V_DrawAdaptiveScaledFullScreenPatch(patch_t *patch);
void V_DrawVerticallyScaledFullScreenPatch(patch_t *patch);
void V_DrawHorizontallyScaledFullScreenPatch(patch_t *patch);
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,
size_t destrowbytes);

View file

@ -1,9 +1,6 @@
#include <winuser.h>
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#include "winver.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////

View file

@ -84,11 +84,10 @@ typedef struct
static y_data data;
// graphics
static patch_t *bgpatch = NULL; // INTERSCR
static patch_t *widebgpatch = NULL;
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
static patch_t *interpic = NULL; // custom picture defined in map header
static boolean usetile;
static INT32 timer;
typedef struct
@ -111,19 +110,6 @@ static INT32 intertic;
static INT32 endtic = -1;
static INT32 sorttic = -1;
patch_t *animVoteFramesPatches = NULL;
// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch)
// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch)
// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch used in software)
// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch used in software)
char animPrefix[] = "INTSC";
char animWidePrefix[] = "INTSW";
char *luaVoteScreen = NULL;
INT32 currentAnimFrame = 0;
static INT32 foundAnimVoteFrames = 0;
static INT32 foundAnimVoteWideFrames = 0;
intertype_t intertype = int_none;
intertype_t intermissiontypes[NUMGAMETYPES];
@ -163,6 +149,9 @@ typedef struct
boolean loaded;
} y_voteclient;
// votescreen stuff
votescreen_t VoteScreen = {0};
static y_votelvlinfo levelinfo[13];
static y_voteclient voteclient;
static INT32 votetic;
@ -172,12 +161,6 @@ static SINT8 votemax = 3;
static INT32 voterowmem = 0;
static boolean rowchange = false;
static boolean votenotyetpicked;
static patch_t *cursor = NULL;
static patch_t *cursor1 = NULL;
static patch_t *cursor2 = NULL;
static patch_t *cursor3 = NULL;
static patch_t *cursor4 = NULL;
static patch_t *rubyicon = NULL;
static void Y_UnloadVoteData(void);
@ -360,53 +343,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
}
}
//
// Y_AnimatedVoteScreenCheck
//
// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle)
static void Y_AnimatedVoteScreenCheck(void)
{
char tmpPrefix[] = "INTS";
boolean stopSearching = false;
if (luaVoteScreen)
strncpy(tmpPrefix, luaVoteScreen, 4);
else
{
if(gametype == GT_BATTLE)
strcpy(tmpPrefix, "BTLS");
}
strncpy(animPrefix, tmpPrefix, 4);
animPrefix[4] = 'C';
strncpy(animWidePrefix, tmpPrefix, 4);
animWidePrefix[4] = 'W';
foundAnimVoteFrames = 0;
foundAnimVoteWideFrames = 0;
currentAnimFrame = 0;
INT32 i = 1;
while(!stopSearching)
{
boolean normalLumpExists = W_LumpExists(va("%sC%d", tmpPrefix, i));
boolean wideLumpExists = W_LumpExists(va("%sW%d", tmpPrefix, i));
if (normalLumpExists || wideLumpExists)
{
if (normalLumpExists)
foundAnimVoteFrames++;
if (wideLumpExists)
foundAnimVoteWideFrames++;
}
else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking
stopSearching = true;
i++;
}
}
//
// Y_ConsiderScreenBuffer
//
@ -526,11 +462,11 @@ void Y_IntermissionDrawer(void)
else if (rendermode != render_soft && usebuffer)
HWR_DrawIntermissionBG();
#endif
else if (bgpatch)
else if (VoteScreen.bgpatch)
{
fixed_t hs = vid.width * FRACUNIT / BASEVIDWIDTH;
fixed_t vs = vid.height * FRACUNIT / BASEVIDHEIGHT;
V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, bgpatch, NULL);
V_DrawStretchyFixedPatch(0, 0, hs, vs, V_NOSCALEPATCH, VoteScreen.bgpatch, NULL);
}
}
else if (bgtile)
@ -1091,7 +1027,8 @@ void Y_EndIntermission(void)
K_RetireBots();
}
Y_UnloadData();
if (!dedicated)
Y_UnloadData();
endtic = -1;
sorttic = -1;
@ -1110,7 +1047,7 @@ static void Y_FollowIntermission(void)
G_AfterIntermission();
}
#define UNLOAD(x) if (x) {Patch_Free(x);} x = NULL;
#define UNLOAD(x) {if ((x) != NULL) {Patch_Free(x);} x = NULL;}
#define CLEANUP(x) x = NULL;
//
@ -1118,49 +1055,171 @@ static void Y_FollowIntermission(void)
//
static void Y_UnloadData(void)
{
// In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName().
// It doesn't work and is unnecessary.
if (rendermode != render_soft)
return;
// unload the background patches
UNLOAD(bgpatch);
UNLOAD(widebgpatch);
UNLOAD(VoteScreen.bgpatch);
UNLOAD(VoteScreen.widebgpatch);
UNLOAD(bgtile);
UNLOAD(interpic);
}
// SRB2Kart: Voting!
// Y_DrawAnimatedVoteScreenPatch
//
// Draw animated patch based on frame counter on vote screen
// Y_VoteScreenCheck
//
static inline void Y_DrawAnimatedVoteScreenPatch(boolean widePatch)
static void Y_VoteScreenCheck(void)
{
char tempAnimPrefix[7];
(widePatch) ? strcpy(tempAnimPrefix, animWidePrefix) : strcpy(tempAnimPrefix, animPrefix);
INT32 tempFoundAnimVoteFrames = (widePatch) ? foundAnimVoteWideFrames : foundAnimVoteFrames;
strcpy(VoteScreen.Prefix, "INTS");
if (VoteScreen.luaPrefix[0] != 0)
strlcpy(VoteScreen.Prefix, VoteScreen.luaPrefix, sizeof(VoteScreen.Prefix));
else if (gametype == GT_BATTLE)
strcpy(VoteScreen.Prefix, "BTLS");
VoteScreen.foundLuaVoteFrames = VoteScreen.foundLuaVoteWideFrames = 0;
VoteScreen.currentAnimFrame = 0;
INT32 i = 1;
// check for lua vote background replacements
for (;;)
{
// Check if the lumps exist (checking for VEXTR(N|W)xx for race and VEXTRB(N|W)xx for battle)
boolean normalLumpExists = W_LumpExists(va("%sC%d", VoteScreen.Prefix, i));
boolean wideLumpExists = W_LumpExists(va("%sW%d", VoteScreen.Prefix, i));
if (normalLumpExists || wideLumpExists)
{
if (normalLumpExists)
VoteScreen.foundLuaVoteFrames++;
if (wideLumpExists)
VoteScreen.foundLuaVoteWideFrames++;
}
else // If we don't find at least frame 1 (e.g VEXTRN1), let's just stop looking
break;
i++;
}
// non lua vote background handling
boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_BATTLE);
VoteScreen.widebgpatch = W_CachePatchLongName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH);
VoteScreen.bgpatch = W_CachePatchLongName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH);
}
//
// Y_VoteBackgroundDrawer
//
// Determines which patch drawer to use for scaling
//
static void Y_VoteBackgroundDrawer(patch_t *patch)
{
switch (cv_votebgscaling.value)
{
case 1: // adaptive
V_DrawAdaptiveScaledFullScreenPatch(patch);
break;
case 2: // vertical-fill
V_DrawVerticallyScaledFullScreenPatch(patch);
break;
case 3: // horizontal-fill
V_DrawHorizontallyScaledFullScreenPatch(patch);
break;
case 0: // vanilla
default:
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (patch->width/2),
(vid.height / vid.dupy) - patch->height,
V_SNAPTOTOP|V_SNAPTOLEFT, patch);
break;
}
}
//
// Y_DrawLuaVoteScreenPatch
//
// Handles votebackgrounds set by "setVoteBackground"
// Aswell as animated patches
//
static void Y_DrawLuaVoteScreenPatch(boolean widePatch)
{
INT32 nextframe = 0;
patch_t *votebg = NULL;
char tempPrefix[6];
const INT32 tempfoundAnimLuaVoteFrames = ((widePatch ? VoteScreen.foundLuaVoteWideFrames : VoteScreen.foundLuaVoteFrames) - 1);
strcpy(tempPrefix, va("%s%s", VoteScreen.Prefix, (widePatch ? "W" : "C")));
// Draw non animated patch
if (!tempfoundAnimLuaVoteFrames)
{
votebg = W_CachePatchLongName(va("%s1", tempPrefix), PU_PATCH);
Y_VoteBackgroundDrawer(votebg);
return;
}
// Draw animated patch based on frame counter on vote screen
// Just in case someone provides LESS widescreen frames than normal frames or vice versa, reset the frame counter to 0
if (widePatch)
if (VoteScreen.currentAnimFrame > tempfoundAnimLuaVoteFrames)
VoteScreen.currentAnimFrame = 0;
nextframe = (VoteScreen.currentAnimFrame + 1);
votebg = W_CachePatchLongName(va("%s%d", tempPrefix, nextframe), PU_PATCH);
Y_VoteBackgroundDrawer(votebg);
if (renderisnewtic && (votetic % 2 == 0) && !paused)
VoteScreen.currentAnimFrame = (nextframe > tempfoundAnimLuaVoteFrames) ? 0 : nextframe;
}
//
// Y_DrawVoteScreenPatch
//
static void Y_DrawVoteScreenPatch(void)
{
patch_t *votebg = NULL;
const boolean widescreen = (vid.width / vid.dupx > 320);
if (VoteScreen.foundLuaVoteWideFrames || VoteScreen.foundLuaVoteFrames)
{
if (currentAnimFrame > foundAnimVoteWideFrames-1)
currentAnimFrame = 0;
}
else
{
if (currentAnimFrame > foundAnimVoteFrames-1)
currentAnimFrame = 0;
Y_DrawLuaVoteScreenPatch(((widescreen && VoteScreen.foundLuaVoteWideFrames) || !VoteScreen.foundLuaVoteFrames));
return;
}
patch_t *background = W_CachePatchLongName(va("%s%d", tempAnimPrefix, currentAnimFrame + 1), PU_CACHE);
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(background->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
(vid.height / vid.dupy) - SHORT(background->height),
V_SNAPTOTOP|V_SNAPTOLEFT, background);
// non widescreen patch
votebg = VoteScreen.bgpatch;
if (renderisnewtic && votetic % 2 == 0 && !paused)
currentAnimFrame = (currentAnimFrame + 1 > tempFoundAnimVoteFrames - 1) ? 0 : currentAnimFrame + 1;
UINT8 prefgametype = (votelevels[0][1] & ~0x80);
const boolean widebgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.widebattle : VoteScreen.replaced.widerace;
const boolean bgreplaced = (prefgametype == GT_BATTLE) ? VoteScreen.replaced.battle : VoteScreen.replaced.race;
// we check a bunch of stuff to always have a "valid" fallback
if ((widescreen && (widebgreplaced || !bgreplaced))
|| (!widescreen && (widebgreplaced && !bgreplaced)))
{
votebg = VoteScreen.widebgpatch; // widescreen patch
}
Y_VoteBackgroundDrawer(votebg);
}
static fixed_t Y_CalculatePicScale(fixed_t picscale, INT32 hypoti)
{
picscale *= 10;
picscale /= (40-hypoti);
if ( ((hypoti % 5) == 1) || ((hypoti % 5) == 4) || ((hypoti % 5) == 2) )
{
if ((hypoti % 5) == 2) // scale DOWN the image
picscale -= (hypoti*16);
else
picscale += (hypoti*2); // scale UP the image
}
return picscale;
}
//
@ -1176,7 +1235,6 @@ void Y_VoteDrawer(void)
fixed_t scale;
patch_t *pic;
INT16 mapnum;
fixed_t picscale = FRACUNIT; // GREENRES
fixed_t picwidth = 160;
// CEP: scale by screen hypotenuse for extra voting rows
@ -1202,18 +1260,7 @@ void Y_VoteDrawer(void)
INT32 hypotdiv = max(10, (40-hypoti));
// readjust the picscale
picscale *= 10;
picscale /= (40-hypoti);
picwidth *= picscale;
// shitty hack to prevent alignment issues
if ( ((hypoti % 5) == 1) || ((hypoti % 5) == 4) || ((hypoti % 5) == 2) )
{
if ((hypoti % 5) == 2) // scale DOWN the image
picscale -= (hypoti*16);
else
picscale += (hypoti*2); // scale UP the image
}
picwidth *= Y_CalculatePicScale(FRACUNIT, hypoti);
if (rendermode == render_none)
return;
@ -1232,31 +1279,8 @@ void Y_VoteDrawer(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
if (widebgpatch && vid.width / vid.dupx > 320) {
if(foundAnimVoteWideFrames == 0){
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(widebgpatch->width)/2),
(vid.height / vid.dupy) - SHORT(widebgpatch->height),
V_SNAPTOTOP|V_SNAPTOLEFT, widebgpatch);
} else {
// patch_t *currPatch = W_CachePatchName(va("%s%d", animPrefix, currentAnimFrame+1), PU_CACHE);
// V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(currPatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
// (vid.height / vid.dupy) - SHORT(currPatch->height),
// V_SNAPTOTOP|V_SNAPTOLEFT, currPatch);
// if(votetic % 4 == 0 && !paused){
// currentAnimFrame = (currentAnimFrame+1 > foundAnimVoteFrames-1) ? 0 : currentAnimFrame + 1;
// }
Y_DrawAnimatedVoteScreenPatch(true);
}
} else {
if(foundAnimVoteFrames == 0) {
V_DrawScaledPatch(((vid.width/2) / vid.dupx) - (SHORT(bgpatch->width)/2), // Keep the width/height adjustments, for screens that are less wide than 320(?)
(vid.height / vid.dupy) - SHORT(bgpatch->height),
V_SNAPTOTOP|V_SNAPTOLEFT, bgpatch);
} else {
Y_DrawAnimatedVoteScreenPatch(false);
}
}
// decides which votebg to draw and draws it
Y_DrawVoteScreenPatch();
rowval = (votemax*3)+((votemax > 1) ? (votemax - 1) : 0);
for (i = 0; i < (rowval+1); i++) // First, we need to figure out the height of this thing...
@ -1313,7 +1337,7 @@ void Y_VoteDrawer(void)
str = levelinfo[i].str;
mapnum = votelevels[i][0];
}
scale = M_GetMapThumbnail(mapnum, &pic)/4;
scale = M_GetMapThumbnail(mapnum, &pic)/2;
if (selected[i])
{
@ -1331,7 +1355,7 @@ void Y_VoteDrawer(void)
if (!splitscreen)
{
thiscurs = cursor;
thiscurs = VoteScreen.cursor[0];
p = consoleplayer;
color = levelinfo[i].gtc;
colormap = NULL;
@ -1341,19 +1365,19 @@ void Y_VoteDrawer(void)
switch (j)
{
case 1:
thiscurs = cursor2;
thiscurs = VoteScreen.cursor[2];
p = g_localplayers[1];
break;
case 2:
thiscurs = cursor3;
thiscurs = VoteScreen.cursor[3];
p = g_localplayers[2];
break;
case 3:
thiscurs = cursor4;
thiscurs = VoteScreen.cursor[4];
p = g_localplayers[3];
break;
default:
thiscurs = cursor1;
thiscurs = VoteScreen.cursor[1];
p = g_localplayers[0];
break;
}
@ -1377,11 +1401,11 @@ void Y_VoteDrawer(void)
}
if (!levelinfo[i].encore)
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, picscale/2, V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, Y_CalculatePicScale(scale,hypoti)/2, V_SNAPTORIGHT, pic, 0);
else
{
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, picscale/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, picscale, V_SNAPTORIGHT, rubyicon, NULL);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, Y_CalculatePicScale(scale,hypoti)/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, Y_CalculatePicScale(FRACUNIT,hypoti), V_SNAPTORIGHT, VoteScreen.rubyicon, NULL);
}
V_DrawRightAlignedThinString(BASEVIDWIDTH-(420/hypotdiv)-scaledpicdiff, (400/hypotdiv)+y, V_SNAPTORIGHT|V_6WIDTHSPACE, str);
@ -1421,13 +1445,12 @@ void Y_VoteDrawer(void)
}
else
{
scale /= 2;
if (!levelinfo[i].encore)
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, picscale/2, V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS, y<<FRACBITS, Y_CalculatePicScale(scale,hypoti)/2, V_SNAPTORIGHT, pic, 0);
else
{
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, picscale/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, picscale, V_SNAPTORIGHT, rubyicon, NULL);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/2), y<<FRACBITS, Y_CalculatePicScale(scale,hypoti)/2, V_FLIP|V_SNAPTORIGHT, pic, 0);
V_DrawFixedPatch(((BASEVIDWIDTH-(1200/hypotdiv)-scaledpicdiff)<<FRACBITS) + (picwidth/4), (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, Y_CalculatePicScale(FRACUNIT,hypoti), V_SNAPTORIGHT, VoteScreen.rubyicon, NULL);
}
if (levelinfo[i].gts)
@ -1479,7 +1502,7 @@ void Y_VoteDrawer(void)
if (!timer && i == voteclient.ranim)
{
V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, cursor);
V_DrawScaledPatch(x-18, y+9, V_SNAPTOLEFT, VoteScreen.cursor[0]);
if (voteendtic != -1 && !(votetic % 4))
V_DrawFill(x-1, y-1, 42, 27, 0|V_SNAPTOLEFT);
else
@ -1491,7 +1514,7 @@ void Y_VoteDrawer(void)
else
{
V_DrawFixedPatch((x+FixedMul(pic->width, scale))<<FRACBITS, y<<FRACBITS, scale, V_SNAPTOLEFT|V_FLIP, pic, NULL);
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, rubyicon, NULL);
V_DrawFixedPatch((x+20)<<FRACBITS, (y<<FRACBITS) + (25<<(FRACBITS-1)) - rubyheight, FRACUNIT/2, V_SNAPTOLEFT, VoteScreen.rubyicon, NULL);
}
if (levelinfo[votes[i]].gts)
@ -1832,11 +1855,28 @@ void Y_VoteTicker(void)
//
// MK online style voting screen, appears after intermission
//
static void Y_InitVoteDrawing(void)
{
if (dedicated)
return;
// setup the background patches
Y_VoteScreenCheck();
VoteScreen.cursor[0] = W_CachePatchLongName("M_CURSOR", PU_PATCH);
VoteScreen.cursor[1] = W_CachePatchLongName("P1CURSOR", PU_PATCH);
VoteScreen.cursor[2] = W_CachePatchLongName("P2CURSOR", PU_PATCH);
VoteScreen.cursor[3] = W_CachePatchLongName("P3CURSOR", PU_PATCH);
VoteScreen.cursor[4] = W_CachePatchLongName("P4CURSOR", PU_PATCH);
VoteScreen.rubyicon = W_CachePatchLongName("RUBYICON", PU_PATCH);
}
void Y_StartVote(void)
{
INT32 i = 0;
INT32 rowval = (cv_votemaxrows.value*3)+((cv_votemaxrows.value > 1) ? (cv_votemaxrows.value - 1) : 0);
boolean battlemode = ((votelevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); // todo gametyperules
votemax = cv_votemaxrows.value; // can we please avoid SIGSEGVs
voterowmem = cv_votemaxrows.value; // this is just for the notif system
@ -1849,16 +1889,8 @@ void Y_StartVote(void)
I_Error("voteendtic is dirty");
#endif
Y_AnimatedVoteScreenCheck();
widebgpatch = W_CachePatchLongName((battlemode ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
bgpatch = W_CachePatchLongName((battlemode ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
cursor = W_CachePatchLongName("M_CURSOR", PU_STATIC);
cursor1 = W_CachePatchLongName("P1CURSOR", PU_STATIC);
cursor2 = W_CachePatchLongName("P2CURSOR", PU_STATIC);
cursor3 = W_CachePatchLongName("P3CURSOR", PU_STATIC);
cursor4 = W_CachePatchLongName("P4CURSOR", PU_STATIC);
rubyicon = W_CachePatchLongName("RUBYICON", PU_STATIC);
// cache vote patches
Y_InitVoteDrawing();
timer = cv_votetime.value*TICRATE;
pickedvote = -1;
@ -1947,17 +1979,17 @@ static void Y_UnloadVoteData(void)
{
voteclient.loaded = false;
if (rendermode != render_soft)
if (dedicated)
return;
UNLOAD(widebgpatch);
UNLOAD(bgpatch);
UNLOAD(cursor);
UNLOAD(cursor1);
UNLOAD(cursor2);
UNLOAD(cursor3);
UNLOAD(cursor4);
UNLOAD(rubyicon);
UNLOAD(VoteScreen.widebgpatch);
UNLOAD(VoteScreen.bgpatch);
UNLOAD(VoteScreen.cursor[0]);
UNLOAD(VoteScreen.cursor[1]);
UNLOAD(VoteScreen.cursor[2]);
UNLOAD(VoteScreen.cursor[3]);
UNLOAD(VoteScreen.cursor[4]);
UNLOAD(VoteScreen.rubyicon);
}
//

View file

@ -17,7 +17,6 @@ extern "C" {
#endif
extern boolean usebuffer;
extern char *luaVoteScreen;
void Y_IntermissionDrawer(void);
void Y_Ticker(void);
@ -47,6 +46,39 @@ typedef enum
extern intertype_t intertype;
extern intertype_t intermissiontypes[NUMGAMETYPES];
// Votescreen stuff
typedef struct
{
boolean race; // non lua race patch replaced
boolean widerace; // non lua widescreen race patch replaced
boolean battle; // non lua battle patch replaced
boolean widebattle; // non lua widescreen battle patch replaced
} votereplace_t;
// VEXTRN - Vote (V) Extra (EXT) Race (R) Normal (N - Normal sized patch)
// VEXTRW - Vote (V) Extra (EXT) Race (R) Normal (W - Wide patch)
// VEXTBN - Vote (V) Extra (EXT) Battle (B) Normal (N - Normal sized patch)
// VEXTBW - Vote (V) Extra (EXT) Battle (B) Normal (W - Wide patch)
typedef struct
{
char Prefix[5]; // Race = INTSX, Battle = BTLSX
char luaPrefix[5]; // prefix for lua votescreens
INT32 currentAnimFrame; // current animated background frame
INT32 foundLuaVoteFrames; // normal lua patch frames
INT32 foundLuaVoteWideFrames; // widescreen lua patch frames
votereplace_t replaced; // checks which non lua patch has been replaced
patch_t *bgpatch; // votebackground patch
patch_t *widebgpatch; // wide votebackground patch
patch_t *cursor[5]; // cursor patches
patch_t *rubyicon; // encore ruby patch
} votescreen_t;
extern votescreen_t VoteScreen;
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -5,3 +5,6 @@ set(CMAKE_CXX_COMPILER clang++)
# Set that this is clang.
set(CMAKE_C_COMPILER_ID clang)
set(CMAKE_CXX_COMPILER_ID clang)
# Use LLD to link
set(CMAKE_LINKER_TYPE LLD)

View file

@ -16,3 +16,6 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Use LLD to link
set(CMAKE_LINKER_TYPE LLD)