Compare commits

...
Author SHA1 Message Date
Alug d122f80d53 cache vid.height 2025-10-11 21:20:42 +02:00
indev ab4a4ae42f Update VHS effect for transposed drawing 2025-10-11 21:11:00 +03:00
Alug f9b6e94744 style fix 2025-10-11 17:35:22 +02:00
Alug 80bbf1c777 fix intermission background 2025-10-11 17:32:52 +02:00
Alug 9d18846134 move "newview sky" check before skyplane loop
saves us some pointless work going through all planes if we dont need to draw the sky
2025-10-10 23:37:13 +02:00
Alug 93c4278753 double kSpanTaskGranularity
seems to slightly speed up spans now
2025-10-10 23:32:35 +02:00
Alug 38c2648cce fix compiler warning 2025-10-10 23:03:40 +02:00
Alug 2a9bce9481 remove stride variable from column drawers
not needed since we increment per pixel now
also inlines the drawpixel stuff
2025-10-10 23:02:37 +02:00
Alug ad7c6b711f Merge branch 'Saturn-Next' into transposesoft 2025-10-10 22:42:07 +02:00
Alug b7f1a0b631 speed up masked sprites a bit
thx eternity engine!
2025-10-10 22:33:04 +02:00
indev f2aafbb8f6 Fix V_FLIP handling for V_DrawStretchyFixedPatch 2025-10-10 23:32:23 +03:00
indev 4b125a3446 Fix POSTIMG_MIRROR and POSTIMG_FLIP (POSTIMG_MIRROR|POSTIMG_FLIP don't need to be changed) 2025-10-10 23:02:41 +03:00
Alug 5b3d6a4ff8 size_t deez 2025-10-10 22:02:46 +02:00
Alug 65b41cc59f merge I_ReadScreen loops
both did the same thing
2025-10-10 21:52:50 +02:00
Alug 5baaa3207d fix gif recording 2025-10-10 21:49:29 +02:00
Alug 5164628b6b fix wipes 2025-10-10 21:44:33 +02:00
Alug 8434c29d47 use the other titled span drawer loop + fix warnings
seems to be faster in this case
2025-10-10 21:38:35 +02:00
Alug e85d8d6185 fix most things
fix patch drawers mostly (V_FLIP seems broken)
fix VID_BlitLinearScreen
fix wöter ripples
fix screenshots

gif recording is still wonky, but atleast doesent draw complete garbage
wipes are still broken
flipcam and encore aswell
2025-10-10 21:22:01 +02:00
Alug f10470fadf WIP: transpose software renderer
so far, level renders correctly
some patches also render correctly
everything else is still broken
2025-10-10 20:18:19 +02:00
Alug 513613d83b dont update hud during skipped frames
this was to fix issues with some lua huds looking really bad during frameskip
but this causes issues with the hud flashing during gif recording
2025-10-09 19:13:09 +02:00
Alug f2afc5135c fix buffer overflows in dedi build too 2025-10-09 18:17:09 +02:00
K J 3783e30a8a fix: multiple additional buffer overruns
found by Zwip-Zwap_Zapony
2025-10-09 18:11:59 +02:00
Alug ff80a34627 unnest fsp counter and ping display stuff 2025-10-09 18:01:27 +02:00
Alug 2ec467f062 check with "__SIZEOF_POINTER__" 2025-10-08 21:38:20 +02:00
Alug b3106d55d1 inline R_ThingLightLevel
just points to thing->lightlevel field eitherway
2025-10-08 21:38:17 +02:00
indev d7422b8ec9 Don't I_Error in W_InitFileError, that causes dedicated servers to bootloop 2025-10-06 17:44:47 +03:00
James R 0bbd8246cc Read only header bytes when creating textures list
R_LoadTextures was reading in the entirety of every
texture lump, now it only reads the 8 byte PNG header.
This saved more than 1 second for me (1.68 s -> 0.24 s).

PNG still need to be read in entirely to check their
dimensions; I didn't bother looking into optimizing it
since we don't have many PNG textures right now.
2025-10-05 20:59:40 +02:00
Alug 9e8ddd5f9e add a print to Joinable_OnChange
also change the other cvar messages to CONS_NOTICE
2025-10-05 20:39:09 +02:00
indev 3964d4e188 Always initialize all column offsets inside multi-patch textures 2025-10-05 21:12:46 +03:00
Alug 005af4362e remove unused W_LumpLenghtPwad call from R_GenerateTexture 2025-10-05 20:11:05 +02:00
Alug f817676033 fix uninitialized "i" counter in R_StoreWallRange 2025-10-05 20:10:49 +02:00
Alug 79140b3bdc fix oopsie in R_GenerateTexture 2025-10-05 20:10:46 +02:00
Alug 48722ef591 fix oob access in CV_AddValue and M_CanShowLevelInList
lets hope this doesent break anything Zzz....
2025-10-05 20:10:42 +02:00
Alug 6be5478fa8 dont free levelstate in D_ClearState
Titledemos be damned!
2025-10-05 20:10:36 +02:00
James R 953d9d15d6 Clear g_dc each frame
I was running into a memcpy of overlapping memory regions
in R_RenderMaskedSegRange.

- This is because of the reallocation of lightlists, which
  uses Z_Frame_Alloc.
- The memory pool that Z_Frame_Alloc draws from is cleared
  each frame.
- g_dc was not cleared though, so when the lightlists were
  reallocated, it'd try to copy from invalidated pointers.
- Access to invalid pointers within the memory pool does
  not cause a segfault directly (because the memory pool
  is allocated once). However, a memcpy involving such an
  invalid pointer leads to overlap, which may cause memory
  corruption.
2025-10-05 20:10:33 +02:00
Alug 0c56755e09 fix R_MarkSegBounds 2025-10-05 20:10:30 +02:00
Lactozilla c166075754 Don't generate textures in R_GetColumn 2025-10-05 20:10:27 +02:00
Alug 90ff1c4fc0 small fixups for r_segs 2025-10-05 20:10:23 +02:00
Alug 1d0fedddfd add bounds check to R_GetLinedefTransTable 2025-10-05 20:10:20 +02:00
Alug f5b60c3f36 port "Use separate table for maskedtexturecol"
from: https://git.do.srb2.org/STJr/SRB2/-/commit/97311dc5b00ab232a6e898c085c20d2f6bdbfa3b

~~cherry-picking this would be horrendous sry~~
2025-10-05 20:10:16 +02:00
Alug 78ad3e9710 some fixes for texture generation
- Fix negative y offsets for both normal and y-flipped patches
- simplify column wrapping/nonpow2 handling
- Single-patch textures: print an error if patch header is missing, cease memory errors

sadly does not fix our invalid columns we get occasionally
2025-10-05 20:10:13 +02:00
Alug b03d5c53ed simplify titledlighting stuff for span drawers
- use a std::vector for the tiltlightbufffer, only for easier checking if it needs to be resized from resolution change
- move stuff into its own function
- simplify R_CalcTiltedLighting
no functional change, no performance improvement, just looks neater
2025-10-04 22:05:07 +02:00
indev c5dce0e785 oops 2025-10-04 17:25:39 +03:00
indev f85c7ef961 Copyleft :3 2025-10-04 17:25:03 +03:00
Alug 4d211f8f82 Merge branch 'updatelibbacktrace' into Saturn-Next 2025-10-03 22:42:28 +01:00
40 changed files with 1055 additions and 743 deletions

No files matched your search

+1 -1
View File
@@ -785,7 +785,7 @@ static void AM_drawPixel(INT32 xx, INT32 yy, INT32 cc)
{
if (xx < 0 || yy < 0 || xx >= f_w || yy >= f_h)
return; // off the screen
am_buf[(yy*f_w) + xx] = cc;
am_buf[(xx*f_h) + yy] = cc;
}
//
+2 -2
View File
@@ -110,7 +110,7 @@ void I_Error(const char *error, ...)
char logbuf[8192];
va_start(argptr, error);
vsprintf(logbuf, error, argptr);
vsnprintf(logbuf, 8192, error, argptr);
va_end(argptr);
LOGE(logbuf);
@@ -166,7 +166,7 @@ void I_OutputMsg(const char *fmt, ...)
char logbuf[8192];
va_start(argptr, fmt);
vsprintf(logbuf, fmt, argptr);
vsnprintf(logbuf, 8192, fmt, argptr);
va_end(argptr);
LOGD(logbuf);
+11 -12
View File
@@ -1650,13 +1650,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Printf(M_GetText("Only the server or admin can change: %s %s\n"), var->name, var->string);
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
return;
}
if (var == &cv_kartencore && !M_SecretUnlocked(SECRET_ENCORE))
{
CONS_Printf(M_GetText("You haven't unlocked Encore Mode yet!\n"));
CONS_Alert(CONS_NOTICE, "You haven't unlocked Encore Mode yet!\n");
return;
}
@@ -1664,7 +1664,7 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
{
if (!stricmp(value, "Hard") || atoi(value) == 2)
{
CONS_Printf(M_GetText("You haven't unlocked this yet!\n"));
CONS_Alert(CONS_NOTICE, "You haven't unlocked this yet!\n");
return;
}
}
@@ -1681,14 +1681,13 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
else
Setvalue(var, value, stealth);
}
else if ((var->flags & CV_NOTINNET) && netgame)
{
CONS_Alert(CONS_NOTICE, "This variable can't be changed while in netgame: %s %s\n", var->name, var->string);
return;
}
else
if ((var->flags & CV_NOTINNET) && netgame)
{
CONS_Printf(M_GetText("This variable can't be changed while in netgame: %s %s\n"), var->name, var->string);
return;
}
else
Setvalue(var, value, stealth);
Setvalue(var, value, stealth);
}
/** Sets a value to a variable without calling its callback function.
@@ -1771,7 +1770,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
newvalue = var->value - 1;
do
{
if(increment > 0) // Going up!
if (increment > 0) // Going up!
{
if (++newvalue == NUMMAPS)
newvalue = -1;
@@ -1785,7 +1784,7 @@ void CV_AddValue(consvar_t *var, INT32 increment)
if (newvalue == oldvalue)
break; // don't loop forever if there's none of a certain gametype
if(!mapheaderinfo[newvalue])
if (newvalue >= 0 && !mapheaderinfo[newvalue])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(newvalue, gt));
+2 -2
View File
@@ -1282,7 +1282,7 @@ void CONS_Alert(alerttype_t level, const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, 8192, fmt, argptr);
va_end(argptr);
switch (level)
@@ -1318,7 +1318,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...)
txt = malloc(8192);
va_start(argptr, fmt);
vsprintf(txt, fmt, argptr);
vsnprintf(txt, 8192, fmt, argptr);
va_end(argptr);
// Again I am lazy, oh well
+3
View File
@@ -4161,7 +4161,10 @@ static void Joinable_OnChange(void)
UINT8 maxplayer;
if (!server)
{
CONS_Alert(CONS_NOTICE, ("Only the server can change: %s %s\n"), cv_allownewplayer.name, cv_allownewplayer.string);
return;
}
#ifdef SATURNJOIN
// disabling joins should also disable saturn joins unless its called with CV_StealthSet and vice versa to make life a bit easier
+3 -8
View File
@@ -609,7 +609,7 @@ static boolean D_Display(void)
{
if (rendermode == render_soft)
{
VID_BlitLinearScreen(vid.screens[0], vid.screens[1], vid.width, vid.height, vid.width, vid.width);
VID_BlitLinearScreen(vid.screens[0], vid.screens[1], vid.width, vid.height, vid.height, vid.height);
}
lastdraw = false;
@@ -774,6 +774,7 @@ void D_SRB2Loop(void)
precise_t capbudget;
precise_t enterprecise = I_GetPreciseTime();
memset(&g_dc, 0, sizeof(g_dc));
Z_Frame_Reset();
// Casting the return value of a function is bad practice (apparently)
@@ -889,12 +890,6 @@ void D_SRB2Loop(void)
// always update console and hud
// otherwise it may take minutes to open it
CON_Drawer();
if (gamestate == GS_LEVEL)
{
ST_Drawer();
HU_Drawer();
}
}
}
@@ -1026,7 +1021,7 @@ void D_ClearState(void)
S_StopSounds();
S_ResetKeepAndSpecialMus(); // just in case
P_FreeLevelState();
//P_FreeLevelState();
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
+2 -2
View File
@@ -1468,7 +1468,7 @@ void I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
I_OutputMsg("SRB2Kart %s Recursive Error", buffer);
@@ -1482,7 +1482,7 @@ void I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
+10 -10
View File
@@ -249,16 +249,16 @@ static void F_DoWipe(fademask_t *fademask)
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
relativepos = (draw_rowstart * vid.height) + draw_linestart;
draw_linestogo = draw_rowend - draw_rowstart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_lineend-draw_linestart);
relativepos += vid.height;
}
}
else if (*mask == 10)
@@ -266,8 +266,8 @@ static void F_DoWipe(fademask_t *fademask)
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_lineend-draw_linestart);
relativepos += vid.height;
}
}
else
@@ -281,12 +281,12 @@ static void F_DoWipe(fademask_t *fademask)
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
draw_rowstogo = draw_lineend - draw_linestart;
while (draw_rowstogo--)
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
relativepos += vid.width;
relativepos += vid.height;
}
// END DRAWING LOOP
}
@@ -314,7 +314,7 @@ void F_WipeStartScreen(void)
}
#endif
wipe_scr_start = vid.screens[3];
I_ReadScreen(wipe_scr_start, 1);
M_Memcpy(wipe_scr_start, vid.screens[0], vid.width*vid.height);
#endif
}
@@ -331,7 +331,7 @@ void F_WipeEndScreen(void)
}
#endif
wipe_scr_end = vid.screens[4];
I_ReadScreen(wipe_scr_end, 1);
M_Memcpy(wipe_scr_end, vid.screens[0], vid.width*vid.height);
V_DrawBlock(0, 0, 0, vid.width, vid.height, wipe_scr_start);
#endif
}
+85 -74
View File
@@ -2540,17 +2540,91 @@ Ping_conversion (UINT32 lag)
// HU_drawPing
//
static void HU_drawOldPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean gentleman)
{
const INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
}
}
if (cv_pingicon.value)
{
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
yoffset -= 2;
}
}
}
static void HU_drawKartPing(INT32 x, INT32 y, UINT32 lag, INT32 flags, boolean gentleman)
{
const INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
{
INT32 gfxnum = Ping_gfx_num(lag); // gfx to draw
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
}
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
}
void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
{
INT32 measureid = cv_pingmeasurement.value ? 1 : 0;
INT32 gfxnum; // gfx to draw
//SRB2/Kart v1.0 style
UINT8 numbars = 0; // how many ping bars do we draw?
UINT8 barcolor = 31; // color we use for the bars (green, yellow, red or black)
SINT8 i = 0;
SINT8 yoffset = 6;
UINT32 lag = playerpingtable[pnum];
const boolean gentleman = (cv_mindelay.value && (lag < (tic_t)simulated_lag));
@@ -2561,74 +2635,11 @@ void HU_drawPlayerPing(INT32 x, INT32 y, INT32 pnum, INT32 flags)
if (cv_pingstyle.value == 0) // kart
{
gfxnum = Ping_gfx_num(lag);
if (measureid == 1)
V_DrawScaledPatch(x+11 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
if (cv_pingicon.value)
V_DrawScaledPatch(x+2, y, flags, pinggfx[gfxnum]);
x = V_DrawPingNum(x + (measureid == 1 ? 11 - pingmeasure[measureid]->width : 10), y+9, flags, Ping_conversion(lag), Ping_gfx_colormap(lag, gentleman));
if (measureid == 0)
V_DrawScaledPatch(x+1 - pingmeasure[measureid]->width, y+9, flags, pingmeasure[measureid]);
HU_drawKartPing(x, y, lag, flags, gentleman);
}
else if (cv_pingstyle.value == 1) // old style ping
{
if (vid.width >= 640) // how sad, we're using a shit resolution.
{
if (measureid == 1)
{
V_DrawRightAlignedSmallString(x+12, y+13, V_ALLOWLOWERCASE|flags, va("%dms", Ping_conversion(lag)));
}
else if (measureid == 0)
{
V_DrawRightAlignedSmallString(x+12, y+13, flags, va("d%d", Ping_conversion(lag)));
}
}
if (cv_pingicon.value)
{
switch (lag)
{
case 0 ... 1:
numbars = 3;
barcolor = 215; // Blue
break;
case 2 ... 3:
numbars = 3;
barcolor = 184; // Green
break;
case 4 ... 6:
numbars = 2; // Apparently ternaries w/ multiple statements don't look good in C so I decided against it.
barcolor = 103; // Yellow
break;
case 7 ... 9:
numbars = 1;
barcolor = 155; // Red
break;
default: // Brazil
numbars = 0;
barcolor = 31; // black
break;
}
if (gentleman)
{
barcolor = 194; // make it purplish
// bars get indirectly set earlier
}
for (i = 0; (i < 3); i++) // Draw the ping bar
{
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-4, 2, 8-yoffset, 31|flags);
if (i < numbars)
V_DrawFill(x+2 *(i-1)+7, y+8+yoffset-3, 1, 8-yoffset-1, barcolor|flags);
yoffset -= 2;
}
}
HU_drawOldPing(x, y, lag, flags, gentleman);
}
}
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_stats.c
/// \brief Game statistics handling
#include "k_stats.h"
#include "doomstat.h"
#include "g_game.h"
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_stats.h
/// \brief Game statistics handling
#ifndef __K_STATS__
#define __K_STATS__
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.c
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#include "doomtype.h"
#include "m_fixed.h"
#include "lua_udatalib.h"
+12 -1
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file lua_udatalib.h
/// \brief Implementation of lua userdata object metatables based on getter/setter functions
#ifndef __LUA_UDATALIB_H__
#define __LUA_UDATALIB_H__
@@ -100,4 +111,4 @@ void udatalib_addfields(lua_State *L, int mt, const udata_field_t fields[]);
return 0; \
}
#endif
#endif
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_curl.c
/// \brief Common curl-related functions shared across http-mserv and file download
#include "m_curl.h"
#include "doomtype.h"
#include "i_system.h" // I_OutputMsg
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_curl.h
/// \brief Common curl-related functions shared across http-mserv and file download
#ifndef __M_CURL__
#define __M_CURL__
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_emotes.cpp
/// \brief Chat emotes handling
#include <map>
#include <string>
#include <sstream>
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_emotes.h
/// \brief Chat emotes handling
#ifndef __M_EMOTES__
#define __M_EMOTES__
+6 -2
View File
@@ -2713,6 +2713,10 @@ static void M_PrepareLevelSelect(void)
//
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
{
// invalid mapnum
if (mapnum < -1)
return false;
// Random map!
if (mapnum == -1)
return (gamestate != GS_TIMEATTACK && !modeattacking);
@@ -7220,7 +7224,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
if (i == oldval)
return;
if(!mapheaderinfo[i])
if (i >= 0 && !mapheaderinfo[i])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
@@ -7258,7 +7262,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade)
if (i == oldval)
return;
if(!mapheaderinfo[i])
if (i >= 0 && !mapheaderinfo[i])
continue; // Don't allocate the header. That just makes memory usage skyrocket.
} while (!M_CanShowLevelInList(i, cv_newgametype.value));
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_textinput.c
/// \brief User text input implementation
#include "m_textinput.h"
#include "m_menu.h" // MAXSTRINGLENGTH
#include "v_video.h"
+11
View File
@@ -1,3 +1,14 @@
// SONIC ROBO BLAST 2 KART SATURN
//-----------------------------------------------------------------------------
// Copyright (C) 2025 by Indev.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_textinput.h
/// \brief User text input implementation
#ifndef __M_TEXTINPUT__
#define __M_TEXTINPUT__
+113 -76
View File
@@ -94,7 +94,7 @@ static UINT32 **texturecolumnofs; // column offset lookup table for each texture
UINT8 **texturecache; // graphics data for each generated full-size texture
// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask
static INT32 *texturewidthmask;
static INT32 *texturewidth;
fixed_t *textureheight; // needed for texture pegging
@@ -241,11 +241,12 @@ static INT32 tidcachelen = 0;
// R_DrawColumnInCache
// Clip and draw a column from a patch into a cached post.
//
static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight)
static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight)
{
INT32 count, position;
UINT8 *source;
INT32 topdelta, prevdelta = -1;
INT32 originy = originPatch->originy;
while (patch->topdelta != 0xff)
{
@@ -260,6 +261,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig
if (position < 0)
{
count += position;
source -= position; // start further down the column
position = 0;
}
@@ -273,6 +275,50 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig
}
}
static UINT8 *R_AllocateTextureBlock(size_t blocksize, UINT8 **user)
{
texturememory += blocksize;
return Z_Malloc(blocksize, PU_LEVEL, user);
}
static UINT8 *R_AllocateDummyTextureBlock(size_t width, UINT8 **user)
{
// Allocate dummy data. Keep 4-bytes aligned.
// Column offsets will be initialized to 0, which points to the 0xff byte (empty column flag).
size_t blocksize = 4 + (width * 4);
UINT8 *block = R_AllocateTextureBlock(blocksize, user);
memset(block, 0, blocksize);
block[0] = 0xff;
return block;
}
static boolean R_CheckTextureLumpLength(texture_t *texture, size_t patch)
{
UINT16 wadnum = texture->patches[patch].wad;
UINT16 lumpnum = texture->patches[patch].lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (lumplength < offsetof(softwarepatch_t, columnofs))
{
CONS_Alert(
CONS_ERROR,
"%.8s: texture lump data is too small. Expected %s bytes, got %s. (%s)\n",
texture->name,
sizeu1(offsetof(softwarepatch_t, columnofs)),
sizeu2(lumplength),
wadfiles[wadnum]->lumpinfo[lumpnum].fullname
);
return false;
}
return true;
}
//
// R_GenerateTexture
//
@@ -297,6 +343,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
column_t *patchcol;
UINT8 *colofs;
UINT16 wadnum;
lumpnum_t lumpnum;
size_t lumplength;
I_Assert(texnum <= (size_t)numtextures);
texture = textures[texnum];
I_Assert(texture != NULL);
@@ -311,45 +361,57 @@ UINT8 *R_GenerateTexture(size_t texnum)
{
boolean holey = false;
patch = texture->patches;
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_LEVEL);
wadnum = patch->wad;
lumpnum = patch->lump;
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (R_CheckTextureLumpLength(texture, 0) == false)
{
block = R_AllocateDummyTextureBlock(texture->width, &texturecache[texnum]);
texturecolumnofs[texnum] = (UINT32*)&block[4];
textures[texnum]->holes = true;
return block;
}
pdata = (UINT8*)W_CacheLumpNumPwad(wadnum, lumpnum, PU_LEVEL);
realpatch = (softwarepatch_t *)pdata;
// Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true;
else
colofs = (UINT8 *)realpatch->columnofs;
for (x = 0; x < texture->width && !holey; x++)
{
colofs = (UINT8 *)realpatch->columnofs;
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
for (x = 0; x < texture->width; x++)
INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff)
{
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff)
{
topdelta = col->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
if (topdelta > y)
break;
y = topdelta + col->length + 1;
col = (column_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
topdelta = col->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
if (topdelta > y)
break;
y = topdelta + col->length + 1;
col = (column_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
}
// If the patch uses transparency, we have to save it this way.
if (holey)
{
texture->holes = true;
blocksize = W_LumpLengthPwad(patch->wad, patch->lump);
block = Z_Calloc(blocksize, PU_LEVEL, &texturecache[texnum]);
blocksize = lumplength;
block = Z_Calloc(blocksize, PU_LEVEL, &texturecache[texnum]); // will change tag at end of this function
M_Memcpy(block, realpatch, blocksize);
texturememory += blocksize;
@@ -365,7 +427,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
goto done;
}
// Otherwise, do multipatch format.
}
@@ -384,10 +445,18 @@ UINT8 *R_GenerateTexture(size_t texnum)
// texture data after the lookup table
blocktex = block + (texture->width*4);
for (x = 0; x < texture->width; ++x)
{
// generate column ofset lookup
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
}
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_LEVEL);
wadnum = patch->wad;
lumpnum = patch->lump;
pdata = (UINT8*)W_CacheLumpNumPwad(wadnum, lumpnum, PU_LEVEL);
realpatch = (softwarepatch_t *)pdata;
x1 = patch->originx;
@@ -418,9 +487,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
{
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
// generate column ofset lookup
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch->originy, texture->height);
R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch, texture->height);
}
}
@@ -439,6 +506,7 @@ INT32 R_GetTextureNum(INT32 texnum)
{
if (texnum < 0 || texnum >= numtextures)
return 0;
return texturetranslation[texnum];
}
@@ -456,17 +524,12 @@ void R_CheckTextureCache(INT32 tex)
static inline INT32 wrap_column(fixed_t tex, INT32 col)
{
if (texturewidthmask[tex])
col &= texturewidthmask[tex]; // set by load textures
else
{
const INT16 texwidth = textures[tex]->width;
INT32 width = texturewidth[tex];
// Odd width texture, cannot just mask.
// Sometime gets colnum = -1 or = width, even without tiling.
// Test LostCiv, Map 20, crates.
col = ((col % texwidth) + texwidth) % texwidth;
}
if (width & (width - 1))
col = (UINT32)col % width;
else
col &= (width - 1);
return col;
}
@@ -476,13 +539,6 @@ static inline INT32 wrap_column(fixed_t tex, INT32 col)
//
UINT8 *R_GetColumn(fixed_t tex, INT32 col)
{
if (!texturecache[tex])
{
// This must be here because cache can be freed by other operations.
// To prevent must lock individual texture cache on every draw.
R_GenerateTexture(tex);
}
return texturecache[tex] + LONG(texturecolumnofs[tex][wrap_column(tex, col)]);
}
@@ -516,11 +572,10 @@ static INT32
Rloadtextures (INT32 i, INT32 w)
{
UINT16 j, numlumps = 0;
INT32 k;
UINT16 texstart, texend, texturesLumpPos;
softwarepatch_t *patchlump;
texpatch_t *patch;
texture_t *texture;
softwarepatch_t patchlump;
// Get the lump numbers for the markers in the WAD, if they exist.
if (W_FileHasFolders(wadfiles[w]))
@@ -560,7 +615,7 @@ Rloadtextures (INT32 i, INT32 w)
continue; // If it is then SKIP IT
}
patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0);
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((wadnum, lumpnum), patchlump->width, patchlump->height);
texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
@@ -568,8 +623,10 @@ Rloadtextures (INT32 i, INT32 w)
// Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name));
texture->hash = quickncasehash(texture->name, 8);
texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height);
texture->width = SHORT(patchlump.width);
texture->height = SHORT(patchlump.height);
texture->type = TEXTURETYPE_SINGLEPATCH;
texture->patchcount = 1;
texture->holes = false;
@@ -581,27 +638,7 @@ Rloadtextures (INT32 i, INT32 w)
patch->wad = wadnum;
patch->lump = texstart + j;
Z_Free(patchlump);
// determine width power of 2
#if 1
// [WDJ] only need to determine if exact power of 2.
k = 1;
while (k < texture->width)
k<<=1;
#else
// Largest power of 2 that fits within width.
k = 1;
while (k << 1 <= texture->width)
k <<= 1;
#endif
if (k != texture->width)
{
// Odd width
k = 1; // make texturewidthmask = 0
}
texturewidthmask[i] = k - 1;
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;
}
@@ -709,7 +746,7 @@ static void R_AllocateTextures(INT32 add)
// Allocate texture referencing cache.
recallocuser(&texturecache, oldsize, newsize);
// Allocate texture width table.
recallocuser(&texturewidthmask, oldsize, newsize);
recallocuser(&texturewidth, oldsize, newsize);
// Allocate texture height table.
recallocuser(&textureheight, oldsize, newsize);
// Create translation table for global animation.
@@ -1181,7 +1218,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
newTexture = R_ParseTexture(true);
// Store the new texture
textures[*texindex] = newTexture;
texturewidthmask[*texindex] = newTexture->width - 1;
texturewidth[*texindex] = newTexture->width;
textureheight[*texindex] = newTexture->height << FRACBITS;
// Increment i back in R_LoadTextures()
(*texindex)++;
+2 -2
View File
@@ -615,12 +615,12 @@ typedef struct drawseg_s
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
INT16 *sprtopclip;
INT16 *sprbottomclip;
INT16 *maskedtexturecol;
fixed_t *maskedtexturecol;
struct visplane_s *ffloorplanes[MAXFFLOORS];
INT32 numffloorplanes;
struct ffloor_s *thicksides[MAXFFLOORS];
INT16 *thicksidecol;
fixed_t *thicksidecol;
INT32 numthicksides;
fixed_t *frontscale;
+1 -1
View File
@@ -30,7 +30,7 @@ extern INT32 linesize;
FUNCINLINE static ATTRINLINE UINT8 *R_Address(INT32 px, INT32 py)
{
return renderscreen + (py + viewwindowy) * linesize + (viewwindowx + px);
return renderscreen + (py + viewwindowy) + (viewwindowx + px) * vid.height;
}
+13 -12
View File
@@ -31,7 +31,8 @@ enum DrawColumnType
};
template<DrawColumnType Type>
static constexpr UINT8 R_GetColumnTranslated(drawcolumndata_t* dc, UINT8 col, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetColumnTranslated(drawcolumndata_t* dc, UINT8 col, const UINT8 * restrict colormap)
{
if constexpr (Type & DrawColumnType::DC_COLORMAP)
{
@@ -42,7 +43,8 @@ static constexpr UINT8 R_GetColumnTranslated(drawcolumndata_t* dc, UINT8 col, co
}
template<DrawColumnType Type>
static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * restrict dest, UINT8 col, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * restrict dest, UINT8 col, const UINT8 * restrict colormap)
{
col = R_GetColumnTranslated<Type>(dc, col, colormap);
@@ -57,7 +59,8 @@ static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * rest
}
template<DrawColumnType Type>
static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap)
{
UINT8 col = source[bit];
@@ -187,7 +190,6 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
const intptr_t heightmask = dc->sourcelength-1;
constexpr INT32 npow2min = -1;
const INT32 npow2max = dc->sourcelength;
const INT32 stride = vid.width;
const UINT8 * restrict source = dc->source;
const lighttable_t * restrict colormap = dc->colormap;
@@ -208,12 +210,12 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
while(count--)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
dest++;
frac += fracstep;
}
}
break;
case -1:
case npow2min:
{
if (frac < 0)
// adjust in case we underread
@@ -223,7 +225,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
while (--count >= 0)
{
*dest = R_DrawColumnPixel<Type>(dc, dest, frac>>FRACBITS, source, colormap);
dest += stride;
dest++;
frac += fracstep;
}
}
@@ -235,11 +237,11 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
while ((count -= 2) >= 0) // texture height is a power of 2 -- killough
{
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
dest++;
frac += fracstep;
*dest = R_DrawColumnPixel<Type>(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap);
dest += stride;
dest++;
frac += fracstep;
}
@@ -277,7 +279,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
// and a few bytes after as well
*dest = R_DrawColumnPixel<Type>(dc, dest, CLAMP((frac >> FRACBITS), npow2min, npow2max), source, colormap);
dest += stride;
dest++;
#if __SIZEOF_POINTER__ < 8 // 64-bit systems have large enough numbers for this to be a non-issue
// Avoid overflow.
@@ -343,7 +345,6 @@ void R_DrawFogColumn(drawcolumndata_t* dc)
// Framebuffer destination address.
dest = R_Address(dc->x, dc->yl);
const INT32 stride = vid.width;
const lighttable_t * restrict colormap = dc->colormap;
// Determine scaling, which is the only mapping to be done.
@@ -351,6 +352,6 @@ void R_DrawFogColumn(drawcolumndata_t* dc)
{
// Simple. Apply the colormap to what's already on the screen.
*dest = colormap[*dest];
dest += stride;
dest++;
} while (count--);
}
+73 -77
View File
@@ -25,6 +25,9 @@
#define local_for_thread static
#endif
#include <vector>
#include <algorithm>
// ==========================================================================
// SPANS
// ==========================================================================
@@ -47,7 +50,8 @@ enum DrawSpanType
};
template<DrawSpanType Type>
static constexpr UINT8 R_GetSpanTranslated(drawspandata_t* ds, UINT8 col)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetSpanTranslated(drawspandata_t* ds, UINT8 col)
{
if constexpr (Type & DrawSpanType::DS_COLORMAP)
{
@@ -60,7 +64,8 @@ static constexpr UINT8 R_GetSpanTranslated(drawspandata_t* ds, UINT8 col)
}
template<DrawSpanType Type>
static constexpr UINT8 R_GetSpanTranslucent(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT8 col)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_GetSpanTranslucent(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT8 col)
{
col = colormap[R_GetSpanTranslated<Type>(ds, col)];
@@ -75,7 +80,8 @@ static constexpr UINT8 R_GetSpanTranslucent(drawspandata_t* ds, UINT8 *dsrc, con
}
template<DrawSpanType Type>
static constexpr UINT8 R_DrawSpanPixel(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT32 bit, const UINT8 *source)
FUNCINLINE static ATTRINLINE constexpr UINT8
R_DrawSpanPixel(drawspandata_t* ds, UINT8 *dsrc, const UINT8 *colormap, UINT32 bit, const UINT8 *source)
{
UINT8 col = source[bit];
@@ -104,15 +110,17 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
UINT8 * restrict dest = R_Address(ds->x1, ds->y);
UINT8 * restrict dsrc;
const UINT8 * restrict deststop = vid.screens[0] + vid.width * vid.height;
const UINT8 * restrict deststop = vid.screens[0] + vid.height *vid.width;
if (dest+8 > deststop)
if (dest > deststop)
{
return;
}
intptr_t count = (ds->x2 - ds->x1 + 1);
size_t i;
//size_t i;
const INT32 stride = vid.height;
xposition = ds->xfrac; yposition = ds->yfrac;
xstep = ds->xstep; ystep = ds->ystep;
@@ -137,14 +145,14 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
if constexpr (Type & DS_RIPPLE)
{
dsrc = vid.screens[1] + (ds->y + ds->bgofs) * vid.width + ds->x1;
dsrc = vid.screens[1] + (ds->y + ds->bgofs) + ds->x1 * vid.height;
}
else
{
dsrc = dest;
}
while (count >= 8)
/*while (count >= 8)
{
// SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't
// have the uber complicated math to calculate it now, so that was a memory write we didn't
@@ -164,7 +172,7 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
dsrc += 8;
count -= 8;
}
}*/
while (count-- && dest <= deststop)
{
@@ -172,8 +180,8 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
dest++;
dsrc++;
dest += stride;
dsrc += stride;
xposition += xstep;
yposition += ystep;
@@ -182,31 +190,39 @@ static void R_DrawSpanTemplate(drawspandata_t* ds)
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static void R_CalcTiltedLighting(INT32 *lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end)
static void R_CalcTiltedLighting(std::vector<INT32>& lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 i, left = x1, right = x2;
INT32 i;
const fixed_t step = (end-start)/(x2 - x1 + 1);
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++)
for (i = x1; i <= x2; i++)
{
lightbuffer[i] = (start += step) >> FRACBITS;
if (lightbuffer[i] < 0)
{
lightbuffer[i] = 0;
}
else if (lightbuffer[i] >= MAXLIGHTSCALE)
{
lightbuffer[i] = MAXLIGHTSCALE-1;
}
fixed_t light = start >> FRACBITS;
lightbuffer[i] = CLAMP(light, 0, MAXLIGHTSCALE - 1);
start += step;
}
}
static void R_GetTiltedLighting(std::vector<INT32>& tiltlighting, const drawspandata_t* ds, const float iz, const int width, const INT32 stride)
{
float planelightfloat = PLANELIGHTFLOAT;
const fixed_t lightstart = FloatToFixed(iz * planelightfloat);
const fixed_t lightend = FloatToFixed((iz + ds->szp.x * width) * planelightfloat);
if (tiltlighting.size() != (size_t)viewwidth)
{
tiltlighting.resize(viewwidth);
}
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, lightstart, lightend);
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", FixedToFloat(lightstart), FixedToFloat(lightend), focallengthf);
}
template<DrawSpanType Type>
static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
{
@@ -223,35 +239,18 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
float endz, endu, endv;
UINT32 stepu, stepv;
UINT32 bit;
local_for_thread INT32 *tiltlighting = NULL;
local_for_thread INT32 oldviewwidth = 0;
// dont realloc every frame pls thx
if (tiltlighting == NULL || oldviewwidth != viewwidth)
{
tiltlighting = static_cast<INT32*>(realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth));
oldviewwidth = viewwidth;
}
INT32 x1 = ds->x1;
//INT32 x1 = ds->x1;
const INT32 nflatxshift = ds->nflatxshift;
const INT32 nflatyshift = ds->nflatyshift;
const INT32 nflatmask = ds->nflatmask;
const INT32 stride = vid.width;
const INT32 stride = vid.height;
local_for_thread std::vector<INT32> tiltlighting;
iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds->szp.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
R_GetTiltedLighting(tiltlighting, ds, iz, width, stride);
uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx);
vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx);
@@ -261,7 +260,7 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
if constexpr (Type & DS_RIPPLE)
{
dsrc = vid.screens[1] + (ds->y + ds->bgofs) * stride + ds->x1;
dsrc = vid.screens[1] + (ds->y + ds->bgofs) + ds->x1 * stride;
}
else
{
@@ -313,18 +312,31 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
u = (INT64)(startu);
v = (INT64)(startv);
x1 = ds->x1;
//x1 = ds->x1;
for (i = 0; i < SPANSIZE; i++)
// not sure which one does a better job
for (i = SPANSIZE-1; i >= 0; i--)
{
bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);
colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps);
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
dest += stride;
dsrc += stride;
u += stepu;
v += stepv;
}
/*for (i = 0; i < SPANSIZE; i++)
{
bit = (((v + stepv * i) >> nflatyshift) & nflatmask) | ((u + stepu * i) >> nflatxshift);
colormap = ds->planezlight[tiltlighting[x1 + i]] + (ds->colormap - colormaps);
dest[i] = R_DrawSpanPixel<Type>(ds, &dsrc[i], colormap, bit, source);
dest[i * stride] = R_DrawSpanPixel<Type>(ds, &dsrc[i * stride], colormap, bit, source);
}
ds->x1 += SPANSIZE;
dest += SPANSIZE;
dsrc += SPANSIZE;
dest += SPANSIZE * stride;
dsrc += SPANSIZE * stride;*/
startu = endu;
startv = endv;
width -= SPANSIZE;
@@ -362,9 +374,9 @@ static void R_DrawTiltedSpanTemplate(drawspandata_t* ds)
bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift);
colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps);
*dest = R_DrawSpanPixel<Type>(ds, dsrc, colormap, bit, source);
dest++;
dest += stride;
dsrc += stride;
ds->x1++;
dsrc++;
u += stepu;
v += stepv;
}
@@ -400,7 +412,9 @@ void R_DrawFogSpan(drawspandata_t* ds)
intptr_t count = ds->x2 - ds->x1 + 1;
while (count >= 4)
const INT32 stride = vid.height;
/*while (count >= 4)
{
dest[0] = colormap[dest[0]];
dest[1] = colormap[dest[1]];
@@ -409,12 +423,12 @@ void R_DrawFogSpan(drawspandata_t* ds)
dest += 4;
count -= 4;
}
}*/
while (count--)
{
*dest = colormap[*dest];
dest++;
dest += stride;
}
}
@@ -423,37 +437,19 @@ void R_DrawFogSpan_Tilted(drawspandata_t* ds)
int width = ds->x2 - ds->x1;
float iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
UINT8 * restrict dest;
local_for_thread INT32 *tiltlighting = NULL;
local_for_thread INT32 oldviewwidth = 0;
// dont realloc every frame pls thx
if (tiltlighting == NULL || oldviewwidth != viewwidth)
{
tiltlighting = static_cast<INT32*>(realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth));
oldviewwidth = viewwidth;
}
local_for_thread std::vector<INT32> tiltlighting;
dest = R_Address(ds->x1, ds->y);
const INT32 stride = vid.width;
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds->szp.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
R_GetTiltedLighting(tiltlighting, ds, iz, width, stride);
do
{
UINT8 *colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps);
*dest = colormap[*dest];
dest++;
dest += stride;
}
while (--width >= 0);
}
+2
View File
@@ -1400,6 +1400,7 @@ void R_RenderPlayerView(player_t *player)
R_ClearClipSegs();
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearPlanes();
R_ClearSprites();
@@ -1434,6 +1435,7 @@ void R_RenderPlayerView(player_t *player)
R_ClearClipSegs();
}
R_ClearDrawSegs();
R_ClearSegTables();
R_ClearSprites();
// check for new console commands.
+2
View File
@@ -36,6 +36,8 @@ typedef struct
boolean available;
} spriteinfo_t;
#define PNG_HEADER_SIZE (8)
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_Free(patch_t *patch);
+23 -29
View File
@@ -60,10 +60,6 @@ INT32 numffloors;
#define visplane_hash(picnum,lightlevel,height) \
((unsigned)((picnum)*3+(lightlevel)+(height)*7) & VISPLANEHASHMASK)
//SoM: 3/23/2000: Use boom opening limit removal
size_t maxopenings;
INT16 *openings, *lastopening; /// \todo free leak
//
// Clip values are the solid pixel bounding the range.
// floorclip starts out SCREENHEIGHT
@@ -339,13 +335,13 @@ void R_ClearPlanes(void)
R_ClearFFloorClips();
for (i = 0; i < MAXVISPLANES; i++)
{
for (*freehead = visplanes[i], visplanes[i] = NULL;
freehead && *freehead ;)
{
freehead = &(*freehead)->next;
}
lastopening = openings;
}
// left to right mapping
angle = (viewangle-ANGLE_90)>>ANGLETOFINESHIFT;
@@ -634,8 +630,9 @@ static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(draw
// coarse enough to not be too slow due to task scheduling overhead.
// To safely do this, we need to copy part of spanstart to a local.
// This is essentially loop unrolling across threads.
constexpr const int kSpanTaskGranularity = 8;
constexpr const int kSpanTaskGranularity = 16;
drawspandata_t ds_copy = *ds;
while (t1 < t2 && t1 <= b1)
{
INT32 spanstartcopy[kSpanTaskGranularity] = {0};
@@ -753,6 +750,13 @@ void R_DrawSkyPlanes(void)
visplane_t *pl;
INT32 i;
// If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything!
// This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately
if (!newview->sky)
{
return;
}
#ifdef HAVE_THREADS
srb2::ThreadPool::Sema tp_sema;
srb2::g_main_threadpool->begin_sema();
@@ -781,14 +785,8 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
if (!(pl->minx <= pl->maxx))
return;
// If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything!
// This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately
if (!newview->sky)
{
return;
}
drawcolumndata_t dc = {};
const INT32 texture = texturetranslation[skytexture];
// Reset column drawer function (note: couldn't we just call walldrawerfunc directly?)
// (that is, unless we'll need to switch drawers in future for some reason)
@@ -807,24 +805,21 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
dc.colormap += COLORMAP_REMAPOFFSET;
dc.texturemid = skytexturemid;
dc.texheight = textureheight[skytexture] >>FRACBITS;
dc.texheight = textureheight[texture] >>FRACBITS;
dc.sourcelength = dc.texheight;
x = pl->minx;
// Precache the texture so we don't corrupt the zoned heap off-main thread
if (!texturecache[texturetranslation[skytexture]])
{
R_GenerateTexture(texturetranslation[skytexture]);
}
R_CheckTextureCache(texture);
#ifdef HAVE_THREADS
// Tune concurrency granularity here to maximize throughput
// The cheaper colfunc is, the more coarse the task should be
constexpr const int kSkyPlaneMacroColumns = 8;
while (x <= pl->maxx)
{
// Tune concurrency granularity here to maximize throughput
// The cheaper colfunc is, the more coarse the task should be
constexpr const int kSkyPlaneMacroColumns = 8;
auto thunk = [=]() mutable -> void {
for (int i = 0; i < kSkyPlaneMacroColumns && i + x <= pl->maxx; i++)
{
@@ -841,9 +836,7 @@ static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc2)(drawcolumndata_t*), b
dc.iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x + i]>>ANGLETOFINESHIFT));
dc.x = x + i;
dc.source =
R_GetColumn(texturetranslation[skytexture],
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
dc.source = R_GetColumn(texture, -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
colfunc2(&dc);
}
@@ -1164,13 +1157,14 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle
}
}
offset = (scry*vid.width) + scrx;
//offset = (scry*vid.width) + scrx;
offset = (scrx*vid.height) + scry;
// No idea if this works
VID_BlitLinearScreen(renderscreen + offset,
vid.screens[1] + (top*vid.width), // intentionally not +offset
vid.screens[1] + top, // intentionally not +offset
viewwidth, bottom-top,
vid.width, vid.width);
vid.height, vid.height);
}
}
}
-2
View File
@@ -67,8 +67,6 @@ extern visplane_t *floorplane;
extern visplane_t *ceilingplane;
// Visplane related.
extern INT16 *lastopening, *openings;
extern size_t maxopenings;
extern INT16 *floorclip, *ceilingclip;
extern fixed_t *frontscale, *yslopetab;
+270 -206
View File
@@ -78,9 +78,21 @@ static fixed_t topfrac, topstep;
static fixed_t bottomfrac, bottomstep;
static lighttable_t **walllights;
static INT16 *maskedtexturecol;
static fixed_t *maskedtexturecol;
static fixed_t *maskedtextureheight = NULL;
static size_t numopenings;
static INT16 *openings, *lastopening;
static size_t texturecolumntablesize;
static fixed_t *texturecolumntable, *curtexturecolumntable;
void R_ClearSegTables(void)
{
lastopening = openings;
curtexturecolumntable = texturecolumntable;
}
// ==========================================================================
// R_RenderMaskedSegRange
// ==========================================================================
@@ -140,7 +152,18 @@ static void R_Render2sidedMultiPatchColumn(drawcolumndata_t* dc, column_t *colum
transnum_t R_GetLinedefTransTable(fixed_t alpha)
{
return static_cast<transnum_t>((20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1));
if (alpha >= FRACUNIT)
{
return static_cast<transnum_t>(0);
}
else if (alpha <= 0)
{
return NUMTRANSMAPS;
}
else
{
return static_cast<transnum_t>((20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1));
}
}
static inline boolean R_OverflowTest(drawcolumndata_t* dc)
@@ -173,7 +196,7 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
ldef = curline->linedef;
range = std::max(drawseg->x2-drawseg->x1, 1);
range = std::max<INT32>(drawseg->x2-drawseg->x1, 1);
// Setup lighting based on the presence/lack-of 3D floors.
dc->numlights = 0;
@@ -306,141 +329,137 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
else
dc->texturemid -= (textureheight[texnum])*times;
const INT16 colnum = maskedtexturecol[dc->x];
// Check for overflows first
if (R_OverflowTest(dc))
{
// Eh, no, go away, don't waste our time
if (dc->numlights)
{
for (i = 0; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
}
spryscale += rw_scalestep;
continue;
}
// calculate lighting
if (colnum != INT16_MAX)
if (dc->numlights)
{
// Check for overflows first
if (R_OverflowTest(dc))
lighttable_t **xwalllights;
sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc->texturemid, spryscale));
realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
auto set_light_vars = [&](INT32 k)
{
// Eh, no, go away, don't waste our time
if (dc->numlights)
rlight = &dc->lightlist[k];
lightnum = rlight->lightnum;
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
if ((dc->lightlist[i].flags & FF_NOSHADE))
continue;
set_light_vars(i);
height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop)
{
for (i = 0; i < dc->numlights; i++)
set_colormap_below_light();
continue;
}
windowbottom = height;
if (windowbottom >= realbot)
{
windowbottom = realbot;
colfunc_2s(dc, col);
for (i++; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
continue;
}
spryscale += rw_scalestep;
continue;
}
colfunc_2s(dc, col);
if (dc->numlights)
{
lighttable_t **xwalllights;
sprbotscreen = INT32_MAX;
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc->texturemid, spryscale));
realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, colnum) - 3);
auto set_light_vars = [&](INT32 k)
{
rlight = &dc->lightlist[k];
lightnum = rlight->lightnum;
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
if (rlight->extra_colormap)
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
else
rlight->rcolormap = xwalllights[pindex];
};
auto set_colormap_below_light = [&]
{
dc->colormap = rlight->rcolormap;
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
};
// Use the base sector's light level above the first FOF.
// You can imagine it as the sky casting its light on top of the highest FOF.
set_light_vars(0);
windowtop = windowbottom + 1;
set_colormap_below_light();
for (i = 0; i < dc->numlights; i++)
{
if ((dc->lightlist[i].flags & FF_NOSHADE))
continue;
set_light_vars(i);
height = rlight->height;
rlight->height += rlight->heightstep;
if (height <= windowtop)
{
set_colormap_below_light();
continue;
}
windowbottom = height;
if (windowbottom >= realbot)
{
windowbottom = realbot;
colfunc_2s(dc, col);
for (i++; i < dc->numlights; i++)
{
rlight = &dc->lightlist[i];
rlight->height += rlight->heightstep;
}
continue;
}
colfunc_2s(dc, col);
windowtop = windowbottom + 1;
set_colormap_below_light();
}
windowbottom = realbot;
if (windowtop < windowbottom)
colfunc_2s(dc, col);
spryscale += rw_scalestep;
continue;
}
windowbottom = realbot;
if (windowtop < windowbottom)
colfunc_2s(dc, col);
// calculate lighting
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
dc->colormap = walllights[pindex];
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
if (frontsector->extra_colormap)
dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps);
sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale);
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, colnum) - 3);
colfunc_2s(dc, col);
spryscale += rw_scalestep;
continue;
}
// calculate lighting
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1;
dc->colormap = walllights[pindex];
if (encoremap && !(ldef->flags & ML_TFERLINE))
dc->colormap += COLORMAP_REMAPOFFSET;
if (frontsector->extra_colormap)
dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps);
sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale);
dc->iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
colfunc_2s(dc, col);
spryscale += rw_scalestep;
}
}
@@ -632,6 +651,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
void (*colfunc_2s) (drawcolumndata_t* dc, column_t *);
// Calculate light table.
// Use different light tables
// for horizontal / vertical / diagonal. Diagonal?
@@ -674,7 +694,7 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
fog = true;
}
range = std::max(drawseg->x2-drawseg->x1, 1);
range = std::max<INT32>(drawseg->x2-drawseg->x1, 1);
//SoM: Moved these up here so they are available for my lightlist calculations
rw_scalestep = drawseg->scalestep;
spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep;
@@ -899,14 +919,11 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
// draw the columns
for (dc->x = x1; dc->x <= x2; dc->x++)
{
if (maskedtexturecol[dc->x] == INT16_MAX)
continue;
// skew FOF walls
if (ffloortextureslide)
{
if (oldx != -1)
dc->texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x])<<FRACBITS);
dc->texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x]));
oldx = dc->x;
}
@@ -936,9 +953,6 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
continue;
}
// Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3);
if (!fog)
{
dc->iscale = 0xffffffffu / (unsigned)spryscale;
@@ -949,6 +963,9 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
R_SetColumnFunc(BASEDRAWFUNC);
}
// Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc->x] >> FRACBITS)) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed which
// will (hopefully) put less strain on the stack.
if (dc->numlights)
@@ -1159,13 +1176,14 @@ static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bott
static void R_DrawWallColumn(drawcolumndata_t* dc, INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean remap)
{
const INT32 itexturecolumn = texturecolumn >> FRACBITS;
dc->yl = yl;
dc->yh = yh;
dc->texturemid = mid;
dc->source = R_GetColumn(texture, texturecolumn);
dc->source = R_GetColumn(texture, itexturecolumn);
dc->texheight = textureheight[texture] >> FRACBITS;
dc->sourcelength = dc->texheight;
//R_SetColumnFunc(colfunctype);
R_SetColumnFunc(colfunctype);
coldrawfunc_t* colfunccopy = colfunc;
drawcolumndata_t dc_copy = *dc;
if (remap)
@@ -1191,13 +1209,21 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
INT32 bottom;
INT32 i;
if (midtexture)
R_CheckTextureCache(midtexture);
if (toptexture)
R_CheckTextureCache(toptexture);
if (bottomtexture)
R_CheckTextureCache(bottomtexture);
// Loop over width
for (; rw_x < rw_stopx; rw_x++)
{
// mark floor / ceiling areas
yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
yh = bottomfrac>>HEIGHTBITS;
// no space above wall?
// Mark ceiling
top = ceilingclip[rw_x]+1;
// no space above wall?
@@ -1214,10 +1240,10 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
}
}
yh = bottomfrac>>HEIGHTBITS;
// Mark floor
bottom = floorclip[rw_x]-1;
// no space below floor?
if (yh > bottom)
yh = bottom;
@@ -1346,7 +1372,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
// calculate texture offset
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
// Mask 4095 to guarantee this index is within bounds
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle & 4095),rw_distance);
texturecolumn = rw_offset-FixedMul(FINETANGENT(angle & 4095), rw_distance);
if (oldtexturecolumn != -1)
{
@@ -1357,8 +1383,6 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
}
oldtexturecolumn = texturecolumn;
texturecolumn >>= FRACBITS;
// texturecolumn and lighting are independent of wall tiers
if (segtextured)
{
@@ -1515,7 +1539,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
if (maskedtexture || numthicksides)
{
// save texturecol for backdrawing of masked mid texture
maskedtexturecol[rw_x] = (INT16)texturecolumn;
maskedtexturecol[rw_x] = texturecolumn;
if (maskedtextureheight != NULL)
{
@@ -1561,7 +1585,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
static void R_MarkSegBounds(void)
{
INT32 yl, yh;
INT32 yl, yh;
INT32 top, bottom;
INT16 topclip, bottomclip;
@@ -1570,8 +1594,9 @@ static void R_MarkSegBounds(void)
{
// mark floor / ceiling areas
yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
yh = bottomfrac>>HEIGHTBITS;
// no space above wall?
// Mark ceiling
top = ceilingclip[rw_x]+1;
// no space above wall?
@@ -1588,10 +1613,10 @@ static void R_MarkSegBounds(void)
}
}
yh = bottomfrac>>HEIGHTBITS;
// Mark floor
bottom = floorclip[rw_x]-1;
// no space below floor?
if (yh > bottom)
yh = bottom;
@@ -1616,12 +1641,6 @@ static void R_MarkSegBounds(void)
if (markfloor) // no bottom wall
floorclip[rw_x] = bottomclip;
if (floorclip[rw_x] <= ceilingclip[rw_x] + 1)
{
solidcol[rw_x] = 1;
didsolidcol = true;
}
rw_scale += rw_scalestep;
topfrac += topstep;
bottomfrac += bottomstep;
@@ -1663,15 +1682,87 @@ void R_AllocSegMemory(void)
fixed_t *frontscale_p = frontscaletable;
fixed_t *maskedheight_p = maskedheighttable;
for (drawseg_t *ds = drawsegs; ds < lastseg; ds++)
for (drawseg_t *drawseg = drawsegs; drawseg < lastseg; drawseg++)
{
ds->frontscale = frontscale_p;
ds->maskedtextureheight = maskedheight_p;
drawseg->frontscale = frontscale_p;
drawseg->maskedtextureheight = maskedheight_p;
frontscale_p += viewwidth;
maskedheight_p += viewwidth;
}
}
//SoM: Code to remove limits on openings.
static void R_AllocClippingTables(size_t range)
{
size_t pos = lastopening - openings;
size_t need = range * 2; // for both sprtopclip and sprbottomclip
if (pos + need < numopenings)
return;
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
if (numopenings == 0)
numopenings = 16384;
numopenings += need;
openings = static_cast<INT16*>(Z_Realloc(openings, numopenings * sizeof (*openings), PU_STATIC, NULL));
lastopening = openings + pos;
if (oldopenings == NULL)
return;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (drawseg_t *drawseg = drawsegs; drawseg < ds_p; drawseg++)
{
// Check if it's in range of the openings
#define CHECK(which) \
if (which + drawseg->x1 >= oldopenings && which + drawseg->x1 <= oldlast) \
which = (which - oldopenings) + openings
CHECK(drawseg->sprtopclip);
CHECK(drawseg->sprbottomclip);
#undef CHECK
}
}
static void R_AllocTextureColumnTables(size_t range)
{
size_t pos = curtexturecolumntable - texturecolumntable;
// For both tables, we reserve exactly an amount of memory that's equivalent to
// how many columns the seg will take on the entire screen (think about it)
if (pos + range < texturecolumntablesize)
return;
fixed_t *oldtable = texturecolumntable;
fixed_t *oldlast = curtexturecolumntable;
if (texturecolumntablesize == 0)
texturecolumntablesize = 16384;
texturecolumntablesize += range;
texturecolumntable = static_cast<fixed_t*>(Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL));
curtexturecolumntable = texturecolumntable + pos;
if (oldtable == NULL)
return;
for (drawseg_t *drawseg = drawsegs; drawseg < ds_p; drawseg++)
{
// Check if it's in range of the tables
#define CHECK(which) \
if (which + drawseg->x1 >= oldtable && which + drawseg->x1 <= oldlast) \
which = (which - oldtable) + texturecolumntable
CHECK(drawseg->maskedtexturecol);
CHECK(drawseg->thicksidecol);
#undef CHECK
}
}
//
// R_StoreWallRange
// A wall segment will be drawn
@@ -1684,12 +1775,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
angle_t distangle, offsetangle;
boolean longboi;
INT32 lightnum;
INT32 i, p;
INT32 i = 0, p;
lightlist_t *light;
r_lightlist_t *rlight;
INT32 range;
vertex_t segleft, segright;
fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
const INT32 twosidedmidtexture = R_GetTextureNum(curline->sidedef->midtexture);
drawcolumndata_t dc = {};
maskedtextureheight = NULL;
@@ -1745,41 +1837,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->curline = curline;
rw_stopx = stop+1;
//SoM: Code to remove limits on openings.
{
size_t pos = lastopening - openings;
size_t need = (rw_stopx - start)*4 + pos;
if (need > maxopenings)
{
drawseg_t *ds; //needed for fix from *cough* zdoom *cough*
INT16 *oldopenings = openings;
INT16 *oldlast = lastopening;
do
maxopenings = maxopenings ? maxopenings*2 : 16384;
while (need > maxopenings);
openings = static_cast<INT16*>(Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL));
lastopening = openings + pos;
if (oldopenings == NULL)
return;
// borrowed fix from *cough* zdoom *cough*
// [RH] We also need to adjust the openings pointers that
// were already stored in drawsegs.
for (ds = drawsegs; ds < ds_p; ds++)
{
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = (ds->p - oldopenings) + openings;
ADJUST(maskedtexturecol);
ADJUST(sprtopclip);
ADJUST(sprbottomclip);
ADJUST(thicksidecol);
#undef ADJUST
}
}
} // end of code to remove limits on openings
// calculate scale at both ends and step
ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]);
@@ -1874,8 +1931,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
numbackffloors = 0;
for (i = 0; i < MAXFFLOORS; i++)
ds_p->thicksides[i] = NULL;
memset(ds_p->thicksides, 0, MAXFFLOORS * sizeof(*ds_p->thicksides));
if (numffloors)
{
@@ -2160,6 +2216,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturemid += sidedef->rowoffset;
rw_bottomtexturemid += sidedef->rowoffset;
R_AllocTextureColumnTables(rw_stopx - start);
// allocate space for masked texture tables
if (frontsector && backsector && (frontsector->tag != backsector->tag) && (backsector->ffloors || frontsector->ffloors))
{
@@ -2173,8 +2231,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtexture = true;
ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x;
lastopening += rw_stopx - rw_x;
ds_p->thicksidecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
lowcut = std::max(worldbottom, worldlow) + viewz;
highcut = std::min(worldtop, worldhigh) + viewz;
@@ -2353,13 +2411,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i;
}
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
if (twosidedmidtexture)
{
// masked midtexture
if (!ds_p->thicksidecol)
{
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
lastopening += rw_stopx - rw_x;
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x;
}
else
ds_p->maskedtexturecol = ds_p->thicksidecol;
@@ -2939,18 +2998,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
// save sprite clipping info
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
if (maskedtexture || (ds_p->silhouette & (SIL_TOP | SIL_BOTTOM)))
{
M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start));
ds_p->sprtopclip = lastopening - start;
lastopening += rw_stopx - start;
}
R_AllocClippingTables(rw_stopx - start);
if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
{
M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start));
ds_p->sprbottomclip = lastopening - start;
lastopening += rw_stopx - start;
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{
M_Memcpy(lastopening, ceilingclip + start, 2*(rw_stopx - start));
ds_p->sprtopclip = lastopening - start;
lastopening += rw_stopx - start;
}
if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
{
M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx - start));
ds_p->sprbottomclip = lastopening - start;
lastopening += rw_stopx - start;
}
}
if (maskedtexture)
@@ -2958,13 +3022,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (!(ds_p->silhouette & SIL_TOP))
{
ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN: INT32_MAX;
ds_p->tsilheight = (twosidedmidtexture) ? INT32_MIN : INT32_MAX;
}
if (!(ds_p->silhouette & SIL_BOTTOM))
{
ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN;
ds_p->bsilheight = (twosidedmidtexture) ? INT32_MAX : INT32_MIN;
}
}
+1
View File
@@ -25,6 +25,7 @@ extern "C" {
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop);
void R_ClearSegTables(void);
void R_AllocSegMemory(void);
+8 -9
View File
@@ -94,13 +94,6 @@ static drawseg_xrange_item_t *drawsegs_xrange;
static size_t drawsegs_xrange_size = 0;
static INT32 drawsegs_xrange_count = 0;
INT32 R_ThingLightLevel(mobj_t* thing)
{
INT32 lightlevel = thing->lightlevel;
return lightlevel;
}
//
// Sprite rotation 0 is facing the viewer,
// rotation 1 is one angle turn CLOCKWISE around the axis.
@@ -312,7 +305,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// store sprite info in lookup tables
//FIXME : numspritelumps do not duplicate sprite replacements
W_ReadLumpHeaderPwad(wadnum, l, &patch, (sizeof(INT16) *4), 0);
W_ReadLumpHeaderPwad(wadnum, l, &patch, PNG_HEADER_SIZE, 0);
spritecachedinfo[numspritelumps].width = (INT32)(SHORT(patch.width))<<FRACBITS;
spritecachedinfo[numspritelumps].offset = (INT32)(SHORT(patch.leftoffset))<<FRACBITS;
spritecachedinfo[numspritelumps].topoffset = (INT32)(SHORT(patch.topoffset))<<FRACBITS;
@@ -2249,11 +2242,13 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
}
ds->curline->polyseg->visplane = NULL;
}
if (ds->maskedtexturecol)
{
entry = R_CreateDrawNode(head);
entry->seg = ds;
}
if (ds->numffloorplanes)
{
for (i = 0; i < ds->numffloorplanes; i++)
@@ -2824,6 +2819,7 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
if (drawsegs_xrange_size < maxdrawsegs)
{
// haleyjd: fix reallocation to track 2x size
drawsegs_xrange_size = 2 * maxdrawsegs;
for (i = 0; i < DS_RANGES_COUNT; i++)
@@ -2863,6 +2859,9 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
}
}
// haleyjd: terminate with a nullptr user for faster loop - adds ~3 FPS
drawsegs_xranges[0].items[drawsegs_xranges[0].count].user = nullptr;
for (; clippedvissprites < visspritecount; clippedvissprites++)
{
vissprite_t *spr = R_GetVisSprite(clippedvissprites);
@@ -3028,7 +3027,7 @@ static void R_DrawMaskedList(drawnode_t* head)
else if (r2->seg && r2->seg->maskedtexturecol != NULL)
{
next = r2->prev;
R_RenderMaskedSegRange( r2->seg, r2->seg->x1, r2->seg->x2);
R_RenderMaskedSegRange(r2->seg, r2->seg->x1, r2->seg->x2);
r2->seg->maskedtexturecol = NULL;
R_DoneWithNode(r2);
r2 = next;
+8 -5
View File
@@ -23,10 +23,10 @@ extern "C" {
// number of sprite lumps for spritewidth,offset,topoffset lookup tables
// Fab: this is a hack : should allocate the lookup tables per sprite
#if defined(__x86_64__) || defined(__amd64__) || defined(__aarch64__) || defined(__arm64__) // only for 64bit (idk how else to proper check lmao)
#define MAXVISSPRITES 4096
#else
#if __SIZEOF_POINTER__ < 8
#define MAXVISSPRITES 2048 // added 2-2-98 was 128
#else
#define MAXVISSPRITES 4096 // only for 64bit
#endif
#define VISSPRITECHUNKBITS 6 // 2^6 = 64 sprites per chunk
@@ -63,7 +63,10 @@ extern fixed_t windowtop;
extern fixed_t windowbottom;
extern INT32 lengthcol;
INT32 R_ThingLightLevel(mobj_t *thing);
FUNCINLINE static ATTRINLINE INT32 R_ThingLightLevel(mobj_t* thing)
{
return (INT32)thing->lightlevel;
}
fixed_t R_GetSpriteDirectionalLighting(angle_t angle);
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
@@ -83,7 +86,7 @@ typedef struct
{
size_t drawsegs[2];
size_t vissprites[2];
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
sector_t* viewsector;
} maskcount_t;
+84 -62
View File
@@ -400,74 +400,97 @@ void SCR_CalculateFPS(void)
#endif
}
static void SCR_DrawOldTicRate(UINT32 cap, UINT32 benchmark, double fps, INT32 fpsflags)
{
const char *fps_string;
INT32 ticcntcolor = 0;
if (fps > (benchmark - 5))
ticcntcolor = V_GREENMAP;
else if (fps < 20)
ticcntcolor = V_REDMAP;
if (cap != 0)
fps_string = va("%d/%d\x82", (INT32)fps, cap);
else
fps_string = va("%d\x82", (INT32)fps);
// draw "FPS"
if (cv_ticrate.value == 3)
V_DrawRightAlignedString(319, 181, V_YELLOWMAP|fpsflags, "FPS");
V_DrawRightAlignedString(319, 190, ticcntcolor|fpsflags, fps_string);
}
static void SCR_DrawKartTicRate(UINT32 cap, UINT32 benchmark, double fps, INT32 fpsflags)
{
UINT8 *ticcntcolor = NULL;
INT32 x = 318;
// draw "FPS"
if (cv_ticrate.value == 1)
{
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE);
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, fpsflags, framecounter, ticcntcolor);
}
if (fps > (benchmark - 5))
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
else if (fps < 20)
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
else
ticcntcolor = NULL;
if (cap != 0)
{
UINT32 digits = 1;
UINT32 c2 = cap;
while (c2 > 0)
{
c2 = c2 / 10;
digits++;
}
// draw total frame:
V_DrawPingNum(x, 190, fpsflags, cap, ticcntcolor);
x -= digits * 4;
// draw "/"
V_DrawFixedPatch(x<<FRACBITS, 190<<FRACBITS, FRACUNIT, fpsflags, frameslash, ticcntcolor);
}
// draw our actual framerate
V_DrawPingNum(x, 190, fpsflags, fps, ticcntcolor);
}
void SCR_DisplayTicRate(void)
{
UINT32 cap = R_GetFramerateCap();
UINT32 benchmark = (cap == 0) ? I_GetRefreshRate() : cap;
double fps = round(averageFPS);
INT32 fpsflags = V_LocalTransFlag()|V_SNAPTOBOTTOM|V_SNAPTORIGHT;
UINT32 cap, benchmark;
double fps;
INT32 fpsflags;
if (gamestate == GS_NULL)
return;
// new kart counter
if (cv_ticrate.value == 1 || cv_ticrate.value == 2)
cap = R_GetFramerateCap();
benchmark = (cap == 0) ? I_GetRefreshRate() : cap;
fps = round(averageFPS);
fpsflags = V_LocalTransFlag()|V_SNAPTOBOTTOM|V_SNAPTORIGHT;
switch (cv_ticrate.value)
{
const UINT8 *ticcntcolor = NULL;
INT32 x = 318;
// draw "FPS"
if (cv_ticrate.value == 1)
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, fpsflags, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
if (fps > (benchmark - 5))
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
else if (fps < 20)
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE);
if (cap != 0)
{
UINT32 digits = 1;
UINT32 c2 = cap;
while (c2 > 0)
{
c2 = c2 / 10;
digits++;
}
// draw total frame:
V_DrawPingNum(x, 190, fpsflags, cap, ticcntcolor);
x -= digits * 4;
// draw "/"
V_DrawFixedPatch(x<<FRACBITS, 190<<FRACBITS, FRACUNIT, fpsflags, frameslash, ticcntcolor);
}
// draw our actual framerate
V_DrawPingNum(x, 190, fpsflags, fps, ticcntcolor);
}
else if (cv_ticrate.value == 3 || cv_ticrate.value == 4) // kart v1.0/srb2 counter
{
const char *fps_string;
INT32 ticcntcolor2 = 0;
if (fps > (benchmark - 5))
ticcntcolor2 = V_GREENMAP;
else if (fps < 20)
ticcntcolor2 = V_REDMAP;
if (cap != 0)
fps_string = va("%d/%d\x82", (INT32)fps, cap);
else
fps_string = va("%d\x82", (INT32)fps);
// draw "FPS"
if (cv_ticrate.value == 3)
V_DrawRightAlignedString(319, 181, V_YELLOWMAP|fpsflags, "FPS");
V_DrawRightAlignedString(319, 190, ticcntcolor2|fpsflags, fps_string);
case 1: // new kart counter
case 2:
SCR_DrawKartTicRate(cap, benchmark, fps, fpsflags);
break;
case 3: // kart v1.0/srb2 counter
case 4:
SCR_DrawOldTicRate(cap, benchmark, fps, fpsflags);
break;
default:
break;
}
}
@@ -482,7 +505,6 @@ void SCR_DisplayLocalPing(void)
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = (cv_ticrate.value == 1) ? 165 : ((cv_ticrate.value == 2 || cv_ticrate.value == 4) ? 172 : ((cv_ticrate.value == 3) ? 163 : 181)); // absolute buttpain
HU_drawPlayerPing(308, dispy, consoleplayer, pingflags); // consoleplayer's ping is everyone's ping in a splitnetgame :P
}
}
+2 -2
View File
@@ -2021,7 +2021,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
if (errorcount > 20)
{
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
// Implement message box with SDL_ShowSimpleMessageBox,
// which should fail gracefully if it can't put a message box up
@@ -2039,7 +2039,7 @@ FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
// Display error message in the console before we start shutting it down
va_start(argptr, error);
vsprintf(buffer, error, argptr);
vsnprintf(buffer, 8192, error, argptr);
va_end(argptr);
I_OutputMsg("\nI_Error(): %s\n", buffer);
+18 -10
View File
@@ -1304,7 +1304,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
SDL_DestroyTexture(texture);
}
texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height);
texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, height, width);
}
}
@@ -1339,6 +1339,7 @@ void I_UpdateNoBlit(void)
// I_FinishUpdate
//
static SDL_Rect src_rect = { 0, 0, 0, 0 };
static SDL_Rect dst_rect = { 0, 0, 0, 0 };
void I_FinishUpdate(void)
{
@@ -1368,13 +1369,13 @@ void I_FinishUpdate(void)
void *pixels;
int pitch;
SDL_LockTexture(texture, NULL, &pixels, &pitch);
int step = pitch / 4 - vid.width;
int step = pitch / 4 - vid.height;
UINT32 *restrict dst = pixels;
UINT8 *restrict src = vid.screens[0];
UINT32 *restrict palette = localPalette;
for (INT32 y = 0; y < vid.height; y++)
for (INT32 y = 0; y < vid.width; y++)
{
UINT8 *restrict end = src + vid.width;
UINT8 *restrict end = src + vid.height;
do *dst++ = palette[*src++];
while (src < end);
dst += step;
@@ -1382,7 +1383,8 @@ void I_FinishUpdate(void)
SDL_UnlockTexture(texture);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, &src_rect, NULL);
//SDL_RenderCopy(renderer, texture, &src_rect, NULL);
SDL_RenderCopyEx(renderer, texture, NULL, &dst_rect, 90.0, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
}
#ifdef HWRENDER
@@ -1413,18 +1415,17 @@ void I_ReadScreen(UINT8 * restrict scr, INT32 scale)
{
if (rendermode != render_soft)
I_Error("I_ReadScreen: called while in non-software mode");
else if (scale == 1)
VID_BlitLinearScreen(vid.screens[0], scr, vid.width, vid.height, vid.width, vid.width);
else
{
UINT8 * restrict source = vid.screens[0];
uintptr_t w = vid.width/scale*scale, h = vid.height/scale*scale;
// size_t saves a lea + movsxd over INT32. mind your types!
// uintptr_t is even better since it's guaranteed to be the size of a pointer
for (uintptr_t y = 0; y < h; y += scale)
for (uintptr_t x = 0; x < w; x += scale)
*scr++ = source[y*vid.width + x];
*scr++ = source[x*vid.height + y];
}
}
@@ -1562,8 +1563,15 @@ INT32 VID_SetMode(INT32 modeNum)
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
src_rect.w = vid.width;
src_rect.h = vid.height;
src_rect.w = vid.height;
src_rect.h = vid.width;
dst_rect.x = (vid.width - vid.height) / 2;
dst_rect.y = (vid.height - vid.width) / 2;
dst_rect.w = vid.height;
dst_rect.h = vid.width;
refresh_rate = VID_GetRefreshRate();
+196 -130
View File
@@ -614,9 +614,9 @@ static void CV_constextsize_OnChange(void)
// --------------------------------------------------------------------------
void VID_BlitLinearScreen(const UINT8 *restrict srcptr, UINT8 *restrict destptr, INT32 width, INT32 height, size_t srcrowbytes, size_t destrowbytes)
{
if (srcrowbytes == destrowbytes && srcrowbytes == (size_t)width)
if (srcrowbytes == destrowbytes && srcrowbytes == (size_t)height)
{
size_t i = srcrowbytes * height;
size_t i = srcrowbytes * width;
#if defined(__SSE__)
while (i >= 16)
{
@@ -631,9 +631,9 @@ void VID_BlitLinearScreen(const UINT8 *restrict srcptr, UINT8 *restrict destptr,
}
else
{
while (height--)
while (width--)
{
M_Memcpy(destptr, srcptr, width);
M_Memcpy(destptr, srcptr, height);
destptr += destrowbytes;
srcptr += srcrowbytes;
@@ -663,7 +663,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dup;
const column_t *column;
UINT8 *desttop, *dest, *deststart, *destend;
UINT8 *desttop, *dest/*, *deststart, *destend*/;
const UINT8 *source, *deststop;
fixed_t pwidth; // patch width
fixed_t offx = 0; // x offset
@@ -791,13 +791,10 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if (!desttop)
return;
deststop = desttop + vid.width * vid.height;
if (scrn & V_NOSCALESTART)
{
x >>= FRACBITS;
y >>= FRACBITS;
desttop += (y*vid.width) + x;
}
else
{
@@ -843,9 +840,8 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
y += (vid.height - (BASEVIDHEIGHT * dup)) / 2;
}
}
desttop += (y*vid.width) + x;
}
desttop += (x*vid.height) + y;
if (pscale != FRACUNIT) // scale width properly
{
@@ -857,29 +853,29 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
else
pwidth = patch->width * dup;
deststart = desttop;
destend = desttop + pwidth;
//deststart = desttop;
//destend = desttop + pwidth*vid.height;
const INT32 stride = vid.width;
for (col = 0; (col>>FRACBITS) < patch->width; col += colfrac, ++offx, desttop++)
for (col = 0; (col>>FRACBITS) < patch->width; col += colfrac, ++offx, desttop += vid.height)
{
INT32 topdelta, prevdelta = -1;
if (scrn & V_FLIP) // offx is measured from right edge instead of left
{
if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
break;
if (x+pwidth-offx >= stride) // don't draw off the right of the screen (WRAP PREVENTION)
if (x+pwidth-offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
continue;
}
else
{
if (x+offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x+offx >= stride) // don't draw off the right of the screen (WRAP PREVENTION)
if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
}
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
INT32 realcol = (scrn & V_FLIP) ? ((patch->width-(col>>FRACBITS)-1)<<FRACBITS) : col;
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[realcol>>FRACBITS]));
switch (patchdrawtype)
{
@@ -892,15 +888,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*stride;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup));
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + ((x + offx)*vid.height);
deststop = col_start + vid.height;
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = source[ofs>>FRACBITS];
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -915,15 +912,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*stride;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup));
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + ((x + offx)*vid.height);
deststop = col_start + vid.height;
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_colormap + source[ofs>>FRACBITS]);
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -938,15 +936,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*stride;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup));
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + ((x + offx)*vid.height);
deststop = col_start + vid.height;
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff));
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -961,15 +960,16 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*stride;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup));
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + ((x + offx)*vid.height);
deststop = col_start + vid.height;
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + (((*(v_colormap + source[ofs>>FRACBITS]))<<8)&0xff00) + (*dest&0xff));
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -1039,13 +1039,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
if (!desttop)
return;
deststop = desttop + vid.width * vid.height;
if (scrn & V_NOSCALESTART)
{
x >>= FRACBITS;
y >>= FRACBITS;
desttop += (y*vid.width) + x;
}
else
{
@@ -1079,20 +1076,18 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
y += (vid.height - (BASEVIDHEIGHT * vid.dup)) / 2;
}
}
desttop += (y*vid.width) + x;
}
const INT32 stride = vid.width;
desttop += (y*vid.width) + x;
for (col = sx<<FRACBITS; (col>>FRACBITS) < patch->width && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop++)
for (col = sx<<FRACBITS; (col>>FRACBITS) < patch->width && ((col>>FRACBITS) - sx) < w; col += colfrac, ++x, desttop += vid.height)
{
INT32 topdelta, prevdelta = -1;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x >= stride) // don't draw off the right of the screen (WRAP PREVENTION)
if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
@@ -1110,17 +1105,20 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
dest = desttop;
if (topdelta-sy > 0)
{
dest += FixedInt(FixedMul((topdelta-sy)<<FRACBITS,fdup))*stride;
dest += FixedInt(FixedMul((topdelta-sy)<<FRACBITS,fdup));
ofs = 0;
}
else
ofs = (sy-topdelta)<<FRACBITS;
for (; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + (x*vid.height);
deststop = col_start + vid.height;
for (; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = source[ofs>>FRACBITS];
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -1137,17 +1135,20 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
dest = desttop;
if (topdelta-sy > 0)
{
dest += FixedInt(FixedMul((topdelta-sy)<<FRACBITS,fdup))*stride;
dest += FixedInt(FixedMul((topdelta-sy)<<FRACBITS,fdup));
ofs = 0;
}
else
ofs = (sy-topdelta)<<FRACBITS;
for (; dest < deststop && (ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
UINT8 *col_start = vid.screens[0] + (x*vid.height);
deststop = col_start + vid.height;
for (; dest < deststop && (size_t)(ofs>>FRACBITS) < column->length && (((ofs>>FRACBITS) - sy) + topdelta) < h; ofs += rowfrac)
{
if (dest >= vid.screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
if (dest >= col_start) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = *(v_translevel + ((source[ofs>>FRACBITS]<<8)&0xff00) + (*dest&0xff));
dest += stride;
dest++;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
@@ -1189,8 +1190,8 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
I_Error("Bad V_DrawBlock");
#endif
dest = vid.screens[scrn] + y*vid.width + x;
deststop = vid.screens[scrn] + vid.width * vid.height;
dest = vid.screens[scrn] + x*vid.height + y;
deststop = vid.screens[scrn] + vid.height * vid.width;
while (height--)
{
@@ -1209,7 +1210,7 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
// alug: now with translucency support X)
void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
{
UINT8 *dest;
UINT8 *dest, *desttop;
const UINT8 *deststop;
UINT32 alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT);
@@ -1285,8 +1286,8 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if (y + h > vid.height)
h = vid.height-y;
dest = vid.screens[0] + y*vid.width + x;
deststop = vid.screens[0] + vid.width * vid.height;
dest = desttop = vid.screens[0] + x*vid.height + y;
deststop = vid.screens[0] + vid.height * vid.width;
if (alphalevel)
{
@@ -1312,16 +1313,31 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if (alphalevel)
{
const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
for (;(--h >= 0) && dest < deststop; dest += vid.width)
for (;(--h >= 0) && desttop < deststop; desttop++)
{
for (x = 0; x < w; x++)
dest[x] = fadetable[dest[x]];
dest = desttop;
UINT8 *row_end = dest + (w * vid.height);
while (dest < row_end)
{
*dest = fadetable[*dest];
dest += vid.height;
}
}
}
else
{
for (;(--h >= 0) && dest < deststop; dest += vid.width)
memset(dest, c, w);
for (;(--h >= 0) && desttop < deststop; desttop++)
{
dest = desttop;
UINT8 *row_end = dest + (w * vid.height);
while (dest < row_end)
{
*dest = c;
dest += vid.height;
}
}
}
}
@@ -1367,8 +1383,8 @@ static UINT32 V_GetHWConsBackColor(void)
void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
{
UINT8 *dest;
INT32 u, v;
UINT8 *dest, *desttop;
INT32 v;
UINT32 alphalevel = 0;
if (rendermode == render_none)
@@ -1435,7 +1451,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if (y + h > vid.height)
h = vid.height-y;
dest = vid.screens[0] + y*vid.width + x;
dest = desttop = vid.screens[0] + x*vid.height + y;
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
@@ -1460,11 +1476,14 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if (!alphalevel)
{
for (v = 0; v < h; v++, dest += vid.width)
for (v = 0; v < h; v++, desttop++)
{
for (u = 0; u < w; u++)
dest = desttop;
UINT8 *row_end = dest + w*vid.height;
while (dest < row_end)
{
dest[u] = consolebgmap[dest[u]];
*dest = consolebgmap[*dest];
dest += vid.height;
}
}
}
@@ -1475,11 +1494,14 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
w = clip(w,vid.width);
h = clip(h,vid.height);
#undef clip
for (v = 0; v < h; v++, dest += vid.width)
for (v = 0; v < h; v++, desttop++)
{
for (u = 0; u < w; u++)
dest = desttop;
UINT8 *row_end = dest + w*vid.height;
while (dest < row_end)
{
dest[u] = fadetable[consolebgmap[dest[u]]];
*dest = fadetable[consolebgmap[*dest]];
dest += vid.height;
}
}
}
@@ -1494,7 +1516,8 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
//
void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c)
{
UINT8 *dest;
UINT8 *dest, *desttop;
const UINT8 *deststop;
INT32 w, h, wait = 0;
@@ -1569,19 +1592,28 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c)
if (h > w)
h = w;
dest = vid.screens[0] + y*vid.width + x;
deststop = vid.screens[0] + vid.width * vid.height;
dest = desttop = vid.screens[0] + x*vid.height + y;
deststop = vid.screens[0] + vid.height * vid.width;
c &= 255;
for (;(--h >= 0) && dest < deststop; dest += vid.width)
for (;(--h >= 0) && desttop < deststop; desttop++)
{
memset(dest, c, w);
dest = desttop;
UINT8 *row_end = dest + (w * vid.height);
while (dest < row_end)
{
*dest = c;
dest += vid.height;
}
if (wait)
wait--;
else
w--;
}
}
//
@@ -1592,7 +1624,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
INT32 u, v;
fixed_t dx, dy, xfrac, yfrac;
const UINT8 *src, *deststop;
UINT8 *flat, *dest;
UINT8 *flat, *dest, *desttop;
size_t size, lflatsize, flatshift;
#ifdef HWRENDER
@@ -1639,7 +1671,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
flat = W_CacheLumpNum(flatnum, PU_CACHE);
dest = vid.screens[0] + y*vid.dup*vid.width + x*vid.dup;
dest = desttop = vid.screens[0] + y*vid.dup*vid.width + x*vid.dup;
deststop = vid.screens[0] + vid.width * vid.height;
// from V_DrawScaledPatch
@@ -1663,15 +1695,18 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
dy = FixedDiv(FRACUNIT, vid.dup<<(FRACBITS-2));
yfrac = 0;
for (v = 0; v < h; v++, dest += vid.width)
for (v = 0; v < h; v++, desttop++)
{
xfrac = 0;
src = flat + (((yfrac>>FRACBITS) & (lflatsize - 1)) << flatshift);
dest = desttop;
for (u = 0; u < w; u++)
{
if (&dest[u] > deststop)
if (dest > deststop)
return;
dest[u] = src[(xfrac>>FRACBITS)&(lflatsize-1)];
*dest = src[(xfrac>>FRACBITS)&(lflatsize-1)];
dest += vid.height;
xfrac += dx;
}
yfrac += dy;
@@ -1743,7 +1778,7 @@ void V_DrawVhsEffect(boolean rewind)
UINT8 *buf = vid.screens[0], *tmp = vid.screens[4];
UINT16 y;
UINT32 x, pos = 0;
INT32 x;
UINT8 *normalmapstart = ((UINT8 *)transtables + (8<<FF_TRANSSHIFT|(19<<8)));
#ifdef HQ_VHS
@@ -1777,32 +1812,40 @@ void V_DrawVhsEffect(boolean rewind)
}
#endif
for (y = 0; y < vid.height; y+=2)
// Since we go through columns now instead of rows, we need to keep same random offset values for each row
// Don't need a random value for each row, just a bunch of values to cycle through will do
#define ROWOFFSLEN 128
SINT8 rowoffs[ROWOFFSLEN];
for (y = 0; y < ROWOFFSLEN; y++)
rowoffs[y] = M_RandomKey(vid.dup<<1);
for (x = 0; x < vid.width; ++x)
{
thismapstart = normalmapstart;
offs = 0;
if (y >= uby && y < uby+barsize)
for (y = 0; y < vid.height; y++)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs += updistort * 2.0f * min(y-uby, uby+barsize-y) / barsize;
}
offs = rowoffs[y/2 % ROWOFFSLEN];
if (y >= dby && y < dby+barsize)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs -= downdistort * 2.0f * min(y-dby, dby+barsize-y) / barsize;
}
thismapstart = normalmapstart;
offs += M_RandomKey(vid.dup<<1);
if (y >= uby && y < uby+barsize)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs += updistort * 2.0f * min(y-uby, uby+barsize-y) / barsize;
}
// lazy way to avoid crashes
if ((y == 0 && offs < 0) || (y >= vid.height-2 && offs > 0))
offs = 0;
if (y >= dby && y < dby+barsize)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs -= downdistort * 2.0f * min(y-dby, dby+barsize-y) / barsize;
}
for (x = min(pos+(size_t)vid.width*2, (size_t)vid.width*vid.height); pos < x; pos++)
{
tmp[pos] = thismapstart[buf[pos+offs]];
INT32 pos = x*vid.height + y;
INT32 offspos = pos + offs*vid.height;
if (offspos < 0 || offspos > vid.width*vid.height)
offspos = pos;
tmp[pos] = thismapstart[buf[offspos]];
#ifdef HQ_VHS
tmp[pos] = tmapstart[buf[pos]<<8 | tmp[pos]];
#endif
@@ -1810,6 +1853,7 @@ void V_DrawVhsEffect(boolean rewind)
}
memcpy(buf, tmp, vid.width*vid.height);
#undef ROWOFFSLEN
}
//
@@ -1837,7 +1881,7 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
: ((color & 0xFF00) // Color is not palette index?
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
const UINT8 *deststop = vid.screens[0] + vid.width * vid.height;
const UINT8 *deststop = vid.screens[0] + vid.height * vid.width;
UINT8 *buf = vid.screens[0];
// heavily simplified -- we don't need to know x or y
@@ -1849,7 +1893,7 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
// Simple translucency with one color, over a set number of lines starting from the top.
void V_DrawFadeConsBack(INT32 plines)
{
UINT8 *deststop, *buf;
UINT8 *deststop, *dest, *desttop;
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode == render_opengl)
@@ -1862,9 +1906,18 @@ void V_DrawFadeConsBack(INT32 plines)
// heavily simplified -- we don't need to know x or y position,
// just the stop position
deststop = vid.screens[0] + vid.width * min(plines, vid.height);
for (buf = vid.screens[0]; buf < deststop; ++buf)
*buf = consolebgmap[*buf];
dest = desttop = vid.screens[0];
deststop = vid.screens[0] + min(plines, vid.height);
for (; desttop < deststop; desttop++)
{
dest = desttop;
UINT8 *row_end = dest + (vid.width * vid.height);
while (dest < row_end)
{
*dest = consolebgmap[*dest];
dest += vid.height;
}
}
}
// Gets string colormap, used for 0x80 color codes
@@ -3599,7 +3652,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
if (thiscam->postimg & POSTIMG_WATER)
{
INT32 y;
INT32 y, x;
// Set disStart to a range from 0 to FINEANGLE, incrementing by 128 per tic
angle_t disStart = (((leveltime-1)*128) + (R_GetTimeFrac(RTF_LEVEL) / (FRACUNIT/128))) & FINEMASK;
INT32 newpix;
@@ -3609,7 +3662,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
for (y = yoffset; y < yoffset+viewheight; y++)
{
sine = (FINESINE(disStart)*5)>>FRACBITS;
newpix = abs(sine);
/*newpix = abs(sine);
if (sine < 0)
{
@@ -3632,7 +3685,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
tmpscr[(y*vid.width)+xoffset+viewwidth-newpix] = srcscr[(y*vid.width)+xoffset+(viewwidth-1)];
newpix--;
}
}
}*/
/*
Unoptimized version
@@ -3648,6 +3701,18 @@ void V_DoPostProcessor(INT32 view, INT32 param)
tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
}*/
for (x = 0; x < vid.width; x++)
{
newpix = (x + sine);
if (newpix < 0)
newpix = 0;
else if (newpix >= vid.width)
newpix = vid.width-1;
tmpscr[y + x*vid.height] = srcscr[y+newpix*vid.height]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
}
disStart += 22;//the offset into the displacement map, increment each game loop
disStart &= FINEMASK; //clip it to FINEMASK
}
@@ -3658,7 +3723,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
}
else if (thiscam->postimg & POSTIMG_HEAT) // Heat wave
{
INT32 y;
INT32 y, x;
// Make sure table is built
if (heatshifter == NULL || lastheight != viewheight)
@@ -3683,11 +3748,12 @@ void V_DoPostProcessor(INT32 view, INT32 param)
if (heatshifter[heatindex[view]++])
{
// Shift this row of pixels to the right by 2
tmpscr[(y*vid.width)+xoffset] = srcscr[(y*vid.width)+xoffset];
M_Memcpy(&tmpscr[(y*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset+vid.dup], viewwidth-vid.dup);
tmpscr[y] = srcscr[y];
for (x = vid.dup; x < vid.width; x++)
tmpscr[y+x*vid.height] = srcscr[y+(x-vid.dup)*vid.height];
}
else
M_Memcpy(&tmpscr[(y*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
else for (x = 0; x < vid.width; x++)
tmpscr[y+x*vid.height] = srcscr[y+x*vid.height];
heatindex[view] %= viewheight;
}
@@ -3719,10 +3785,11 @@ void V_DoPostProcessor(INT32 view, INT32 param)
if ((thiscam->postimg & POSTIMG_FLIP) && !(thiscam->postimg & POSTIMG_MIRROR)) // Flip the screen upside-down
{
INT32 y, y2;
INT32 x, y, y2;
for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--)
M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
for (x = xoffset; x < xoffset+viewwidth; x++)
for (y = yoffset, y2 = yoffset+(viewheight-1); y < yoffset+viewheight; y++, y2--)
tmpscr[x*vid.height + y2] = srcscr[x*vid.height + y];
UINT8 *tmp = tmpscr;
tmpscr = srcscr;
@@ -3730,11 +3797,10 @@ void V_DoPostProcessor(INT32 view, INT32 param)
}
else if ((thiscam->postimg & POSTIMG_MIRROR) && !(thiscam->postimg & POSTIMG_FLIP)) // Flip the screen on the x axis
{
INT32 y, x, x2;
INT32 x, x2;
for (y = yoffset; y < yoffset+viewheight; y++)
for (x = xoffset, x2 = xoffset+(viewwidth-1); x < xoffset+viewwidth; x++, x2--)
tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x];
for (x = xoffset, x2 = xoffset+viewwidth - 1; x < xoffset+viewwidth; x++, x2--)
M_Memcpy(&tmpscr[(x2*vid.height)+yoffset], &srcscr[(x*vid.height)+yoffset], viewheight);
UINT8 *tmp = tmpscr;
tmpscr = srcscr;
@@ -3754,7 +3820,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
}
VID_BlitLinearScreen(srcscr+vid.width*yoffset+xoffset, tmpscr+vid.width*yoffset+xoffset,
viewwidth, viewheight, vid.width, vid.width);
viewwidth, viewheight, vid.height, vid.height);
#endif
}
@@ -3810,7 +3876,7 @@ UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
void V_Init(void)
{
INT32 i;
INT32 screensize = vid.width * vid.height;
INT32 screensize = vid.height * vid.width;
for (i = 0; i < NUMSCREENS; i++)
{
+1 -4
View File
@@ -45,6 +45,7 @@
#include "w_wad.h"
#include "z_zone.h"
#include "fastcmp.h"
#include "console.h"
#include "g_game.h" // G_LoadGameData
#include "d_main.h"
@@ -760,11 +761,7 @@ static UINT16 W_InitFileError(const char *filename, boolean exitworthy)
{
if (exitworthy)
{
#ifdef _DEBUG
CONS_Error(va("%s was not found or not valid.\nCheck the log for more details.\n", filename));
#else
I_Error("%s was not found or not valid.\nCheck the log for more details.\n", filename);
#endif
}
else
CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), filename);
+1 -1
View File
@@ -118,7 +118,7 @@ static VOID FPrintf(HANDLE fileHandle, LPCSTR lpFmt, ...)
DWORD bytesWritten;
va_start(arglist, lpFmt);
vsprintf(str, lpFmt, arglist);
vsnprintf(str, 1999, lpFmt, arglist);
va_end(arglist);
WriteFile(fileHandle, str, (DWORD)strlen(str), &bytesWritten, NULL);
+1 -1
View File
@@ -450,7 +450,7 @@ void Y_IntermissionDrawer(void)
else
{
if (rendermode == render_soft)
VID_BlitLinearScreen(vid.screens[1], vid.screens[0], vid.width, vid.height, vid.width, vid.width);
VID_BlitLinearScreen(vid.screens[1], vid.screens[0], vid.width, vid.height, vid.height, vid.height);
#ifdef HWRENDER
else if (rendermode == render_opengl)
HWR_DrawIntermissionBG();