Merge remote-tracking branch 'origin/next' into more-platform-fixes

This commit is contained in:
Lachlan 2020-07-04 05:25:38 +08:00
commit e2bdb56f97
94 changed files with 4576 additions and 3208 deletions

View File

@ -418,6 +418,7 @@ endif()
if(${SRB2_CONFIG_HWRENDER})
add_definitions(-DHWRENDER)
set(SRB2_HWRENDER_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c
@ -433,6 +434,7 @@ if(${SRB2_CONFIG_HWRENDER})
)
set (SRB2_HWRENDER_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h

View File

@ -222,12 +222,10 @@ endif
ifdef NOHW
OPTS+=-DNOHW
else
#Hurdler: not really supported and not tested recently
#OPTS+=-DUSE_PALETTED_TEXTURE
OPTS+=-DHWRENDER
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
endif
ifdef NOHS

View File

@ -770,7 +770,7 @@ boolean CON_Responder(event_t *ev)
// check for console toggle key
if (ev->type != ev_console)
{
if (modeattacking || metalrecording)
if (modeattacking || metalrecording || marathonmode)
return false;
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
@ -1649,10 +1649,7 @@ void CON_Drawer(void)
return;
if (needpatchrecache)
{
W_FlushCachedPatches();
HU_LoadGraphics();
}
if (con_recalc)
{

View File

@ -45,7 +45,7 @@
#include "lua_hook.h"
#include "md5.h"
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
// cl loading screen
#include "v_video.h"
#include "f_finale.h"
@ -1107,19 +1107,13 @@ static void SV_AcknowledgeResynchAck(INT32 node, UINT8 rsg)
static INT16 Consistancy(void);
#ifndef NONET
#define JOININGAME
#endif
typedef enum
{
CL_SEARCHING,
CL_DOWNLOADFILES,
CL_ASKJOIN,
CL_WAITJOINRESPONSE,
#ifdef JOININGAME
CL_DOWNLOADSAVEGAME,
#endif
CL_CONNECTED,
CL_ABORTED
} cl_mode_t;
@ -1162,7 +1156,7 @@ static void CV_LoadPlayerNames(UINT8 **p)
}
}
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
#define SNAKE_SPEED 5
#define SNAKE_NUM_BLOCKS_X 20
@ -1684,7 +1678,6 @@ static inline void CL_DrawConnectionStatus(void)
switch (cl_mode)
{
#ifdef JOININGAME
case CL_DOWNLOADSAVEGAME:
if (lastfilenum != -1)
{
@ -1710,7 +1703,6 @@ static inline void CL_DrawConnectionStatus(void)
else
cltext = M_GetText("Waiting to download game state...");
break;
#endif
case CL_ASKJOIN:
case CL_WAITJOINRESPONSE:
cltext = M_GetText("Requesting to join...");
@ -2048,7 +2040,7 @@ static boolean SV_SendServerConfig(INT32 node)
return waspacketsent;
}
#ifdef JOININGAME
#ifndef NONET
#define SAVEGAMESIZE (768*1024)
static void SV_SendSaveGame(INT32 node)
@ -2494,7 +2486,9 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
if (CL_SendFileRequest())
{
cl_mode = CL_DOWNLOADFILES;
#ifndef NONET
Snake_Initialise();
#endif
}
}
}
@ -2559,18 +2553,20 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
if (waitmore)
break; // exit the case
#ifndef NONET
if (snake)
{
free(snake);
snake = NULL;
}
#endif
cl_mode = CL_ASKJOIN; // don't break case continue to cljoin request now
/* FALLTHRU */
case CL_ASKJOIN:
CL_LoadServerFiles();
#ifdef JOININGAME
#ifndef NONET
// prepare structures to save the file
// WARNING: this can be useless in case of server not in GS_LEVEL
// but since the network layer doesn't provide ordered packets...
@ -2580,7 +2576,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
cl_mode = CL_WAITJOINRESPONSE;
break;
#ifdef JOININGAME
#ifndef NONET
case CL_DOWNLOADSAVEGAME:
// At this state, the first (and only) needed file is the gamestate
if (fileneeded[0].status == FS_FOUND)
@ -2620,11 +2616,13 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
// M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
#ifndef NONET
if (snake)
{
free(snake);
snake = NULL;
}
#endif
D_QuitNetGame();
CL_Reset();
@ -2632,8 +2630,10 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
memset(gamekeydown, 0, NUMKEYS);
return false;
}
#ifndef NONET
else if (cl_mode == CL_DOWNLOADFILES && snake)
Snake_Handle();
#endif
if (client && (cl_mode == CL_DOWNLOADFILES || cl_mode == CL_DOWNLOADSAVEGAME))
FileReceiveTicker();
@ -2644,7 +2644,7 @@ static boolean CL_ServerConnectionTicker(boolean viams, const char *tmpsave, tic
//FileSendTicker();
*oldtic = I_GetTime();
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
if (client && cl_mode != CL_CONNECTED && cl_mode != CL_ABORTED)
{
if (cl_mode != CL_DOWNLOADFILES && cl_mode != CL_DOWNLOADSAVEGAME)
@ -2683,20 +2683,16 @@ static void CL_ConnectToServer(boolean viams)
tic_t oldtic;
#ifndef NONET
tic_t asksent;
#endif
#ifdef JOININGAME
char tmpsave[256];
sprintf(tmpsave, "%s" PATHSEP TMPSAVENAME, srb2home);
lastfilenum = -1;
#endif
cl_mode = CL_SEARCHING;
#ifdef CLIENT_LOADINGSCREEN
lastfilenum = -1;
#endif
#ifdef JOININGAME
#ifndef NONET
// Don't get a corrupt savegame error because tmpsave already exists
if (FIL_FileExists(tmpsave) && unlink(tmpsave) == -1)
I_Error("Can't delete %s\n", tmpsave);
@ -3576,6 +3572,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
if (pnum == consoleplayer)
{
if (Playing())
LUAh_GameQuit();
#ifdef DUMPCONSISTENCY
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
#endif
@ -4215,7 +4213,7 @@ static void HandleConnect(SINT8 node)
G_SetGamestate(backupstate);
DEBFILE("new node joined\n");
}
#ifdef JOININGAME
#ifndef NONET
if (nodewaiting[node])
{
if ((gamestate == GS_LEVEL || gamestate == GS_INTERMISSION) && newnode)
@ -4227,11 +4225,6 @@ static void HandleConnect(SINT8 node)
joindelay += cv_joindelay.value * TICRATE;
player_joining = true;
}
#else
#ifndef NONET
// I guess we have no use for this if we aren't doing mid-level joins?
(void)newnode;
#endif
#endif
}
}
@ -4244,6 +4237,8 @@ static void HandleConnect(SINT8 node)
static void HandleShutdown(SINT8 node)
{
(void)node;
if (Playing())
LUAh_GameQuit();
D_QuitNetGame();
CL_Reset();
D_StartTitle();
@ -4258,6 +4253,8 @@ static void HandleShutdown(SINT8 node)
static void HandleTimeout(SINT8 node)
{
(void)node;
if (Playing())
LUAh_GameQuit();
D_QuitNetGame();
CL_Reset();
D_StartTitle();
@ -4409,7 +4406,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
playernode[(UINT8)serverplayer] = servernode;
if (netgame)
#ifdef JOININGAME
#ifndef NONET
CONS_Printf(M_GetText("Join accepted, waiting for complete game state...\n"));
#else
CONS_Printf(M_GetText("Join accepted, waiting for next level change...\n"));
@ -4433,7 +4430,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
scp = netbuffer->u.servercfg.varlengthinputs;
CV_LoadPlayerNames(&scp);
CV_LoadNetVars(&scp);
#ifdef JOININGAME
#ifndef NONET
/// \note Wait. What if a Lua script uses some global custom variables synched with the NetVars hook?
/// Shouldn't them be downloaded even at intermission time?
/// Also, according to HandleConnect, the server will send the savegame even during intermission...
@ -5499,7 +5496,7 @@ void NetUpdate(void)
// update node latency values so we can take an average later.
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && playernode[i] != UINT8_MAX)
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
realpingtable[i] += GetLag(playernode[i]) * (1000.00f / TICRATE);
pingmeasurecount++;
}

View File

@ -33,7 +33,7 @@ applications may follow different packet versions.
// be transmitted.
// Networking and tick handling related.
#define BACKUPTICS 96
#define BACKUPTICS 1024
#define CLIENTBACKUPTICS 32
#define MAXTEXTCMD 256
//

View File

@ -129,6 +129,7 @@ UINT16 numskincolors;
menucolor_t *menucolorhead, *menucolortail;
char savegamename[256];
char liveeventbackup[256];
char srb2home[256] = ".";
char srb2path[256] = ".";
@ -416,6 +417,7 @@ static void D_Display(void)
if (!automapactive && !dedicated && cv_renderview.value)
{
rs_rendercalltime = I_GetTimeMicros();
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
{
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
@ -462,6 +464,7 @@ static void D_Display(void)
if (postimgtype2)
V_DoPostProcessor(1, postimgtype2, postimgparam2);
}
rs_rendercalltime = I_GetTimeMicros() - rs_rendercalltime;
}
if (lastdraw)
@ -596,23 +599,97 @@ static void D_Display(void)
snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
}
if (cv_renderstats.value)
{
char s[50];
int frametime = I_GetTimeMicros() - rs_prevframetime;
int divisor = 1;
rs_prevframetime = I_GetTimeMicros();
if (rs_rendercalltime > 10000) divisor = 1000;
snprintf(s, sizeof s - 1, "ft %d", frametime / divisor);
V_DrawThinString(30, 10, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "rtot %d", rs_rendercalltime / divisor);
V_DrawThinString(30, 20, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "bsp %d", rs_bsptime / divisor);
V_DrawThinString(30, 30, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "nbsp %d", rs_numbspcalls);
V_DrawThinString(80, 10, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "nspr %d", rs_numsprites);
V_DrawThinString(80, 20, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "nnod %d", rs_numdrawnodes);
V_DrawThinString(80, 30, V_MONOSPACE | V_BLUEMAP, s);
snprintf(s, sizeof s - 1, "npob %d", rs_numpolyobjects);
V_DrawThinString(80, 40, V_MONOSPACE | V_BLUEMAP, s);
if (rendermode == render_opengl) // OpenGL specific stats
{
snprintf(s, sizeof s - 1, "nsrt %d", rs_hw_nodesorttime / divisor);
V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ndrw %d", rs_hw_nodedrawtime / divisor);
V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "ssrt %d", rs_hw_spritesorttime / divisor);
V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "sdrw %d", rs_hw_spritedrawtime / divisor);
V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor);
V_DrawThinString(30, 80, V_MONOSPACE | V_YELLOWMAP, s);
if (cv_grbatching.value)
{
snprintf(s, sizeof s - 1, "bsrt %d", rs_hw_batchsorttime / divisor);
V_DrawThinString(80, 55, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "bdrw %d", rs_hw_batchdrawtime / divisor);
V_DrawThinString(80, 65, V_MONOSPACE | V_REDMAP, s);
snprintf(s, sizeof s - 1, "npol %d", rs_hw_numpolys);
V_DrawThinString(130, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ndc %d", rs_hw_numcalls);
V_DrawThinString(130, 20, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "nshd %d", rs_hw_numshaders);
V_DrawThinString(130, 30, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "nvrt %d", rs_hw_numverts);
V_DrawThinString(130, 40, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ntex %d", rs_hw_numtextures);
V_DrawThinString(185, 10, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "npf %d", rs_hw_numpolyflags);
V_DrawThinString(185, 20, V_MONOSPACE | V_PURPLEMAP, s);
snprintf(s, sizeof s - 1, "ncol %d", rs_hw_numcolors);
V_DrawThinString(185, 30, V_MONOSPACE | V_PURPLEMAP, s);
}
}
else // software specific stats
{
snprintf(s, sizeof s - 1, "prtl %d", rs_sw_portaltime / divisor);
V_DrawThinString(30, 40, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "plns %d", rs_sw_planetime / divisor);
V_DrawThinString(30, 50, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "mskd %d", rs_sw_maskedtime / divisor);
V_DrawThinString(30, 60, V_MONOSPACE | V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "fin %d", rs_swaptime / divisor);
V_DrawThinString(30, 70, V_MONOSPACE | V_YELLOWMAP, s);
}
}
rs_swaptime = I_GetTimeMicros();
I_FinishUpdate(); // page flip or blit buffer
rs_swaptime = I_GetTimeMicros() - rs_swaptime;
}
needpatchflush = false;
needpatchrecache = false;
}
// Lactozilla: Check the renderer's state
// Check the renderer's state
// after a possible renderer switch.
void D_CheckRendererState(void)
{
// flush all patches from memory
// (also frees memory tagged with PU_CACHE)
// (which are not necessarily patches but I don't care)
if (needpatchflush)
{
Z_FlushCachedPatches();
needpatchflush = false;
}
// some patches have been freed,
// so cache them again
@ -668,7 +745,7 @@ void D_SRB2Loop(void)
*/
/* Smells like a hack... Don't fade Sonic's ass into the title screen. */
if (gamestate != GS_TITLESCREEN)
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_PATCH));
for (;;)
{
@ -820,6 +897,7 @@ void D_StartTitle(void)
// In case someone exits out at the same time they start a time attack run,
// reset modeattacking
modeattacking = ATTACKING_NONE;
marathonmode = 0;
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
maptol = 0;
@ -1136,6 +1214,7 @@ void D_SRB2Main(void)
// default savegame
strcpy(savegamename, SAVEGAMENAME"%u.ssg");
strcpy(liveeventbackup, "live"SAVEGAMENAME".bkp"); // intentionally not ending with .ssg
{
const char *userhome = D_Home(); //Alam: path to home
@ -1164,6 +1243,7 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
strcatbf(liveeventbackup, srb2home, PATHSEP);
snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", srb2home);
#else // DEFAULTDIR
@ -1176,6 +1256,7 @@ void D_SRB2Main(void)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, userhome, PATHSEP);
strcatbf(liveeventbackup, userhome, PATHSEP);
snprintf(luafiledir, sizeof luafiledir, "%s" PATHSEP "luafiles", userhome);
#endif // DEFAULTDIR

View File

@ -1156,7 +1156,7 @@ UINT8 CanChangeSkin(INT32 playernum)
// Server has skin change restrictions.
if (cv_restrictskinchange.value)
{
if (gametype == GT_COOP)
if (gametyperules & GTR_FRIENDLY)
return true;
// Can change skin during initial countdown.
@ -1747,7 +1747,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
}
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP)))
if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN)))
FLS = false;
if (delay != 2)
@ -1989,7 +1989,7 @@ static void Command_Map_f(void)
fromlevelselect =
( netgame || multiplayer ) &&
newgametype == gametype &&
newgametype == GT_COOP;
gametypedefaultrules[newgametype] & GTR_CAMPAIGN;
}
}
@ -2779,7 +2779,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
players[playernum].spectator = false;
//If joining after hidetime in normal tag, default to being IT.
if (gametype == GT_TAG && (leveltime > (hidetime * TICRATE)))
if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) && (leveltime > (hidetime * TICRATE)))
{
NetPacket.packet.newteam = 1; //minor hack, causes the "is it" message to be printed later.
players[playernum].pflags |= PF_TAGIT; //make the player IT.
@ -3570,6 +3570,8 @@ static void Command_Playintro_f(void)
*/
FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
{
if (Playing())
LUAh_GameQuit();
I_Quit();
}
@ -3627,7 +3629,7 @@ static void PointLimit_OnChange(void)
static void NumLaps_OnChange(void)
{
// Just don't be verbose
if (gametype == GT_RACE)
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value);
}
@ -3741,7 +3743,7 @@ static void ExitMove_OnChange(void)
{
UINT8 i;
if (!(netgame || multiplayer) || gametype != GT_COOP)
if (!(netgame || multiplayer) || !(gametyperules & GTR_FRIENDLY))
return;
if (cv_exitmove.value)
@ -4231,6 +4233,9 @@ void Command_ExitGame_f(void)
{
INT32 i;
if (Playing())
LUAh_GameQuit();
D_QuitNetGame();
CL_Reset();
CV_ClearChangedFlags();
@ -4615,7 +4620,7 @@ static void Command_ShowTime_f(void)
static void BaseNumLaps_OnChange(void)
{
if (gametype == GT_RACE)
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
{
if (cv_basenumlaps.value)
CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n"));

View File

@ -106,7 +106,7 @@ typedef struct
} pauseddownload_t;
static pauseddownload_t *pauseddownload = NULL;
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
// for cl loading screen
INT32 lastfilenum = -1;
#endif
@ -188,7 +188,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr)
void CL_PrepareDownloadSaveGame(const char *tmpsave)
{
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
lastfilenum = -1;
#endif
@ -1360,7 +1360,7 @@ void PT_FileFragment(void)
I_Error("Received a file not requested (file id: %d, file status: %s)\n", filenum, s);
}
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
lastfilenum = filenum;
#endif
}

View File

@ -58,7 +58,7 @@ extern INT32 fileneedednum;
extern fileneeded_t fileneeded[MAX_WADFILES];
extern char downloaddir[512];
#ifdef CLIENT_LOADINGSCREEN
#ifndef NONET
extern INT32 lastfilenum;
#endif

View File

@ -1669,6 +1669,22 @@ static void readlevelheader(MYFILE *f, INT32 num)
mapheaderinfo[num-1]->nextlevel = (INT16)i;
}
else if (fastcmp(word, "MARATHONNEXT"))
{
if (fastcmp(word2, "TITLE")) i = 1100;
else if (fastcmp(word2, "EVALUATION")) i = 1101;
else if (fastcmp(word2, "CREDITS")) i = 1102;
else if (fastcmp(word2, "ENDING")) i = 1103;
else
// Support using the actual map name,
// i.e., MarathonNext = AB, MarathonNext = FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
mapheaderinfo[num-1]->marathonnext = (INT16)i;
}
else if (fastcmp(word, "TYPEOFLEVEL"))
{
if (i) // it's just a number
@ -4011,7 +4027,20 @@ static void readmaincfg(MYFILE *f)
else
value = get_number(word2);
spstage_start = (INT16)value;
spstage_start = spmarathon_start = (INT16)value;
}
else if (fastcmp(word, "SPMARATHON_START"))
{
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z')
value = M_MapNumber(word2[0], word2[1]);
else
value = get_number(word2);
spmarathon_start = (INT16)value;
}
else if (fastcmp(word, "SSTAGE_START"))
{
@ -4105,6 +4134,17 @@ static void readmaincfg(MYFILE *f)
introtoplay = 128;
introchanged = true;
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
creditscutscene = (UINT8)get_number(word2);
// range check, you morons.
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "USEBLACKROCK"))
{
useBlackRock = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "LOOPTITLE"))
{
looptitle = (value || word2[0] == 'T' || word2[0] == 'Y');
@ -4206,13 +4246,6 @@ static void readmaincfg(MYFILE *f)
titlescrollyspeed = get_number(word2);
titlechanged = true;
}
else if (fastcmp(word, "CREDITSCUTSCENE"))
{
creditscutscene = (UINT8)get_number(word2);
// range check, you morons.
if (creditscutscene > 128)
creditscutscene = 128;
}
else if (fastcmp(word, "DISABLESPEEDADJUST"))
{
disableSpeedAdjust = (value || word2[0] == 'T' || word2[0] == 'Y');
@ -4269,6 +4302,9 @@ static void readmaincfg(MYFILE *f)
// can't use sprintf since there is %u in savegamename
strcatbf(savegamename, srb2home, PATHSEP);
strcpy(liveeventbackup, va("live%s.bkp", timeattackfolder));
strcatbf(liveeventbackup, srb2home, PATHSEP);
gamedataadded = true;
titlechanged = true;
}
@ -5720,10 +5756,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FANG_PINCHPATHINGSTART1",
"S_FANG_PINCHPATHINGSTART2",
"S_FANG_PINCHPATHING",
"S_FANG_PINCHBOUNCE0",
"S_FANG_PINCHBOUNCE1",
"S_FANG_PINCHBOUNCE2",
"S_FANG_PINCHBOUNCE3",
"S_FANG_PINCHBOUNCE4",
"S_FANG_PINCHFALL0",
"S_FANG_PINCHFALL1",
"S_FANG_PINCHFALL2",
"S_FANG_PINCHSKID1",
@ -9364,8 +9402,6 @@ static const char *const MENUTYPES_LIST[] = {
"OP_COLOR",
"OP_OPENGL",
"OP_OPENGL_LIGHTING",
"OP_OPENGL_FOG",
"OP_OPENGL_COLOR",
"OP_SOUND",
@ -9470,6 +9506,7 @@ struct {
{"FF_GLOBALANIM",FF_GLOBALANIM},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
@ -9998,6 +10035,12 @@ struct {
{"TC_BLINK",TC_BLINK},
{"TC_DASHMODE",TC_DASHMODE},
// marathonmode flags
{"MA_INIT",MA_INIT},
{"MA_RUNNING",MA_RUNNING},
{"MA_NOCUTSCENES",MA_NOCUTSCENES},
{"MA_INGAME",MA_INGAME},
{NULL,0}
};

View File

@ -90,6 +90,9 @@ static unsigned long nombre = NEWTICRATE*10;
static void I_BlitScreenVesa1(void); //see later
void I_FinishUpdate (void)
{
if (marathonmode)
SCR_DisplayMarathonInfo();
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();

View File

@ -479,6 +479,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
// Things that used to be in dstrings.h
#define SAVEGAMENAME "srb2sav"
extern char savegamename[256];
extern char liveeventbackup[256];
// m_misc.h
#ifdef GETTEXT
@ -616,11 +617,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// memory that never gets touched.
#define ALLOW_RESETDATA
#ifndef NONET
/// Display a connection screen on join attempts.
#define CLIENT_LOADINGSCREEN
#endif
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG
@ -638,17 +634,13 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// OpenGL shaders
#define GL_SHADERS
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
#define SECTORSPECIALSAFTERTHINK
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
/// on the bright side it fixes some weird issues with translucent walls
/// \note SRB2CB port.
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// Cache patches in Lua in a way that renderer switching will work flawlessly.
//#define LUA_PATCH_SAFETY

View File

@ -45,7 +45,19 @@ extern INT32 curWeather;
extern INT32 cursaveslot;
//extern INT16 lastmapsaved;
extern INT16 lastmaploaded;
extern boolean gamecomplete;
extern UINT8 gamecomplete;
// Extra abilities/settings for skins (combinable stuff)
typedef enum
{
MA_RUNNING = 1, // In action
MA_INIT = 1<<1, // Initialisation
MA_NOCUTSCENES = 1<<2, // No cutscenes
MA_INGAME = 1<<3 // Timer ignores loads
} marathonmode_t;
extern marathonmode_t marathonmode;
extern tic_t marathontime;
#define maxgameovers 13
extern UINT8 numgameovers;
@ -127,7 +139,7 @@ extern INT32 displayplayer;
extern INT32 secondarydisplayplayer; // for splitscreen
// Maps of special importance
extern INT16 spstage_start;
extern INT16 spstage_start, spmarathon_start;
extern INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
extern INT16 titlemap;
@ -289,6 +301,7 @@ typedef struct
UINT8 actnum; ///< Act number or 0 for none.
UINT32 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
INT16 marathonnext; ///< See nextlevel, but for Marathon mode. Necessary to support hub worlds ala SUGOI.
char keywords[33]; ///< Keywords separated by space to search for. 32 characters.
char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
@ -575,11 +588,12 @@ extern UINT16 nightslinktics;
extern UINT8 introtoplay;
extern UINT8 creditscutscene;
extern UINT8 useBlackRock;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings
extern UINT8 useContinues;
#define continuesInSession (!multiplayer && (useContinues || ultimatemode || !(cursaveslot > 0)))
#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0))))
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations

View File

@ -16,6 +16,11 @@ tic_t I_GetTime(void)
return 0;
}
int I_GetTimeMicros(void)
{
return 0;
}
void I_Sleep(void){}
void I_GetEvent(void){}

View File

@ -1118,9 +1118,6 @@ static const char *credits[] = {
"\1Sonic Robo Blast II",
"\1Credits",
"",
"\1Producer",
"Rob Tisdell",
"",
"\1Game Design",
"Ben \"Mystic\" Geyer",
"\"SSNTails\"",
@ -1151,11 +1148,13 @@ static const char *credits[] = {
"",
"\1Programming",
"\1Assistance",
"Colette \"fickleheart\" Bordelon",
"\"chi.miru\"", // helped port slope drawing code from ZDoom
"Andrew \"orospakr\" Clunis",
"Sally \"TehRealSalt\" Cochenour",
"Gregor \"Oogaland\" Dick",
"Julio \"Chaos Zero 64\" Guir",
"\"Hannu_Hanhi\"", // For many OpenGL performance improvements!
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"\"Lat'\"", // SRB2-CHAT, the chat window from Kart
"Matthew \"Shuffle\" Marsalko",
@ -1174,6 +1173,7 @@ static const char *credits[] = {
"\1Art",
"Victor \"VAdaPEGA\" Ara\x1Fjo", // Araújo -- sorry for our limited font! D:
"Ryan \"Blaze Hedgehog\" Bloom",
"\"ChrispyPixels\"",
"Paul \"Boinciel\" Clempson",
"Sally \"TehRealSalt\" Cochenour",
"\"Dave Lite\"",
@ -1220,6 +1220,7 @@ static const char *credits[] = {
"\"SSNTails\"",
"",
"\1Level Design",
"Colette \"fickleheart\" Bordelon",
"Hank \"FuriousFox\" Brannock",
"Matthew \"Fawfulfan\" Chapman",
"Paul \"Boinciel\" Clempson",
@ -1255,6 +1256,7 @@ static const char *credits[] = {
"Johnny \"Sonikku\" Wallbank",
"",
"\1Testing",
"Discord Community Testers",
"Hank \"FuriousFox\" Brannock",
"Cody \"SRB2 Playah\" Koester",
"Skye \"OmegaVelocity\" Meredith",
@ -1330,10 +1332,6 @@ void F_StartCredits(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save the second we enter the credits
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
if (creditscutscene)
{
F_StartCustomCutscene(creditscutscene - 1, false, false);
@ -1529,12 +1527,6 @@ void F_StartGameEvaluation(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save the second we enter the evaluation
// We need to do this again! Remember, it's possible a mod designed skipped
// the credits sequence!
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
goodending = (ALL7EMERALDS(emeralds));
gameaction = ga_nothing;
@ -1551,13 +1543,20 @@ void F_GameEvaluationDrawer(void)
angle_t fa;
INT32 eemeralds_cur;
char patchname[7] = "CEMGx0";
const char* endingtext = (goodending ? "CONGRATULATIONS!" : "TRY AGAIN...");
const char* endingtext;
if (marathonmode)
endingtext = "THANKS FOR THE RUN!";
else if (goodending)
endingtext = "CONGRATULATIONS!";
else
endingtext = "TRY AGAIN...";
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Draw all the good crap here.
if (finalecount > 0)
if (finalecount > 0 && useBlackRock)
{
INT32 scale = FRACUNIT;
patch_t *rockpat;
@ -1684,7 +1683,9 @@ void F_GameEvaluationTicker(void)
return;
}
if (!goodending)
if (!useBlackRock)
;
else if (!goodending)
{
if (sparklloop)
sparklloop--;
@ -1841,10 +1842,6 @@ void F_StartEnding(void)
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save before the credits sequence.
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
@ -3959,6 +3956,7 @@ static void F_AdvanceToNextScene(void)
animtimer = pictime = cutscenes[cutnum]->scene[scenenum].picduration[picnum];
}
// See also G_AfterIntermission, the only other place which handles intra-map/ending transitions
void F_EndCutScene(void)
{
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later

View File

@ -82,7 +82,10 @@ INT32 curWeather = PRECIP_NONE;
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
//INT16 lastmapsaved = 0; // Last map we auto-saved at
INT16 lastmaploaded = 0; // Last map the game loaded
boolean gamecomplete = false;
UINT8 gamecomplete = 0;
marathonmode_t marathonmode = 0;
tic_t marathontime = 0;
UINT8 numgameovers = 0; // for startinglives balance
SINT8 startinglivesbalance[maxgameovers+1] = {3, 5, 7, 9, 12, 15, 20, 25, 30, 40, 50, 75, 99, 0x7F};
@ -118,7 +121,7 @@ UINT32 ssspheres; // old special stage
INT16 lastmap; // last level you were at (returning from special stages)
tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
INT16 spstage_start;
INT16 spstage_start, spmarathon_start;
INT16 sstage_start, sstage_end, smpstage_start, smpstage_end;
INT16 titlemap = 0;
@ -223,6 +226,7 @@ UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scena
UINT8 introtoplay;
UINT8 creditscutscene;
UINT8 useBlackRock = 1;
// Emerald locations
mobj_t *hunt1;
@ -716,14 +720,14 @@ void G_SetNightsRecords(void)
I_Error("Out of memory for replay filepath\n");
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
snprintf(lastdemo, 255, "%s-last.lmp", gpath);
snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, skins[cv_chooseskin.value-1].name);
if (FIL_FileExists(lastdemo))
{
UINT8 *buf;
size_t len = FIL_ReadFile(lastdemo, &buf);
snprintf(bestdemo, 255, "%s-time-best.lmp", gpath);
snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, skins[cv_chooseskin.value-1].name);;
if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1)
{ // Better time, save this demo.
if (FIL_FileExists(bestdemo))
@ -732,7 +736,7 @@ void G_SetNightsRecords(void)
CONS_Printf("\x83%s\x80 %s '%s'\n", M_GetText("NEW RECORD TIME!"), M_GetText("Saved replay as"), bestdemo);
}
snprintf(bestdemo, 255, "%s-score-best.lmp", gpath);
snprintf(bestdemo, 255, "%s-%s-score-best.lmp", gpath, skins[cv_chooseskin.value-1].name);
if (!FIL_FileExists(bestdemo) || (G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)))
{ // Better score, save this demo.
if (FIL_FileExists(bestdemo))
@ -769,6 +773,8 @@ void G_SetGameModified(boolean silent)
// If in record attack recording, cancel it.
if (modeattacking)
M_EndModeAttackRun();
else if (marathonmode)
Command_ExitGame_f();
}
/** Builds an original game map name from a map number.
@ -2061,7 +2067,7 @@ boolean G_Responder(event_t *ev)
&& players[displayplayer].ctfteam != players[consoleplayer].ctfteam)
continue;
}
else if (gametype == GT_HIDEANDSEEK)
else if (gametyperules & GTR_HIDEFROZEN)
{
if (players[consoleplayer].pflags & PF_TAGIT)
continue;
@ -2179,6 +2185,10 @@ void G_Ticker(boolean run)
UINT32 i;
INT32 buf;
// see also SCR_DisplayMarathonInfo
if ((marathonmode & (MA_INIT|MA_INGAME)) == MA_INGAME && gamestate == GS_LEVEL)
marathontime++;
P_MapStart();
// do player reborns if needed
if (gamestate == GS_LEVEL)
@ -2195,8 +2205,13 @@ void G_Ticker(boolean run)
}
else
{
// Costs a life to retry ... unless the player in question is dead already.
if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES)
// Costs a life to retry ... unless the player in question is dead already, or you haven't even touched the first starpost in marathon run.
if (marathonmode && gamemap == spmarathon_start && !players[consoleplayer].starposttime)
{
marathonmode |= MA_INIT;
marathontime = 0;
}
else if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE && players[consoleplayer].lives != INFLIVES)
players[consoleplayer].lives -= 1;
G_DoReborn(consoleplayer);
@ -2603,7 +2618,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
if (gametype == GT_COOP)
if (gametyperules & GTR_EMERALDHUNT)
P_FindEmerald(); // scan for emeralds to hunt for
// If NiGHTS, find lowest mare to start with.
@ -2771,6 +2786,26 @@ mapthing_t *G_FindCoopStart(INT32 playernum)
return NULL;
}
// Find a Co-op start, or fallback into other types of starts.
static inline mapthing_t *G_FindCoopStartOrFallback(INT32 playernum)
{
mapthing_t *spawnpoint = NULL;
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
spawnpoint = G_FindCTFStart(playernum); // fallback
return spawnpoint;
}
// Find a Match start, or fallback into other types of starts.
static inline mapthing_t *G_FindMatchStartOrFallback(INT32 playernum)
{
mapthing_t *spawnpoint = NULL;
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
spawnpoint = G_FindCoopStart(playernum); // fallback
return spawnpoint;
}
mapthing_t *G_FindMapStart(INT32 playernum)
{
mapthing_t *spawnpoint;
@ -2778,9 +2813,22 @@ mapthing_t *G_FindMapStart(INT32 playernum)
if (!playeringame[playernum])
return NULL;
// -- Spectators --
// Order in platform gametypes: Coop->DM->CTF
// And, with deathmatch starts: DM->CTF->Coop
if (players[playernum].spectator)
{
// In platform gametypes, spawn in Co-op starts first
// Overriden by GTR_DEATHMATCHSTARTS.
if (G_PlatformGametype() && !(gametyperules & GTR_DEATHMATCHSTARTS))
spawnpoint = G_FindCoopStartOrFallback(playernum);
else
spawnpoint = G_FindMatchStartOrFallback(playernum);
}
// -- CTF --
// Order: CTF->DM->Coop
if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
else if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam)
{
if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
@ -2789,21 +2837,13 @@ mapthing_t *G_FindMapStart(INT32 playernum)
// -- DM/Tag/CTF-spectator/etc --
// Order: DM->CTF->Coop
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
{
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
spawnpoint = G_FindCoopStart(playernum); // fallback
}
else if (G_TagGametype() ? (!(players[playernum].pflags & PF_TAGIT)) : (gametyperules & GTR_DEATHMATCHSTARTS))
spawnpoint = G_FindMatchStartOrFallback(playernum);
// -- Other game modes --
// Order: Coop->DM->CTF
else
{
if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start
&& !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start
spawnpoint = G_FindCTFStart(playernum); // fallback
}
spawnpoint = G_FindCoopStartOrFallback(playernum);
//No spawns found. ANYWHERE.
if (!spawnpoint)
@ -2889,7 +2929,7 @@ void G_DoReborn(INT32 playernum)
return;
}
if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
if (countdowntimeup || (!(netgame || multiplayer) && (gametyperules & GTR_CAMPAIGN)))
resetlevel = true;
else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
{
@ -2963,7 +3003,7 @@ void G_DoReborn(INT32 playernum)
players[i].starpostnum = 0;
}
}
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD))
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) && !(marathonmode & MA_INIT))
{
P_RespawnThings();
@ -3094,7 +3134,7 @@ void G_AddPlayer(INT32 playernum)
p->height = mobjinfo[MT_PLAYER].height;
if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP))
if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY)))
p->lives = cv_startinglives.value;
if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap))
@ -3143,7 +3183,7 @@ void G_ExitLevel(void)
CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value);
}
if (!(gametyperules & GTR_CAMPAIGN))
if (!(gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN)))
CONS_Printf(M_GetText("The round has ended.\n"));
// Remove CEcho text on round end.
@ -3209,7 +3249,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
// Tag
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
// Hide and Seek
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_HIDEFROZEN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
// CTF
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
@ -3554,6 +3594,16 @@ boolean G_PlatformGametype(void)
return (!(gametyperules & GTR_RINGSLINGER));
}
//
// G_CoopGametype
//
// Returns true if a gametype is a Co-op gametype.
//
boolean G_CoopGametype(void)
{
return ((gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN)) == (GTR_FRIENDLY|GTR_CAMPAIGN));
}
//
// G_TagGametype
//
@ -3661,6 +3711,24 @@ static void G_UpdateVisited(void)
}
}
static boolean CanSaveLevel(INT32 mapnum)
{
// You can never save in a special stage.
if (G_IsSpecialStage(mapnum))
return false;
// If the game is complete for this save slot, then any level can save!
if (gamecomplete)
return true;
// Be kind with Marathon Mode live event backups.
if (marathonmode)
return true;
// Any levels that have the savegame flag can save normally.
return (mapheaderinfo[mapnum-1] && (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME));
}
//
// G_DoCompleted
//
@ -3696,66 +3764,74 @@ static void G_DoCompleted(void)
// nextmap is 0-based, unlike gamemap
if (nextmapoverride != 0)
nextmap = (INT16)(nextmapoverride-1);
else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext)
nextmap = (INT16)(mapheaderinfo[gamemap-1]->marathonnext-1);
else
{
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
// Remember last map for when you come out of the special stage.
if (!spec)
lastmap = nextmap;
if (marathonmode && nextmap == spmarathon_start-1)
nextmap = 1100-1; // No infinite loop for you
}
// If nextmap is actually going to get used, make sure it points to
// a map of the proper gametype -- skip levels that don't support
// the current gametype. (Helps avoid playing boss levels in Race,
// for instance).
if (!token && !spec
&& (nextmap >= 0 && nextmap < NUMMAPS))
if (!spec)
{
register INT16 cm = nextmap;
UINT32 tolflag = G_TOLFlag(gametype);
UINT8 visitedmap[(NUMMAPS+7)/8];
memset(visitedmap, 0, sizeof (visitedmap));
while (!mapheaderinfo[cm] || !(mapheaderinfo[cm]->typeoflevel & tolflag))
if (nextmap >= 0 && nextmap < NUMMAPS)
{
visitedmap[cm/8] |= (1<<(cm&7));
if (!mapheaderinfo[cm])
cm = -1; // guarantee error execution
else
cm = (INT16)(mapheaderinfo[cm]->nextlevel-1);
register INT16 cm = nextmap;
UINT32 tolflag = G_TOLFlag(gametype);
UINT8 visitedmap[(NUMMAPS+7)/8];
if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error)
memset(visitedmap, 0, sizeof (visitedmap));
while (!mapheaderinfo[cm] || !(mapheaderinfo[cm]->typeoflevel & tolflag))
{
cm = nextmap; //Start the loop again so that the error checking below is executed.
visitedmap[cm/8] |= (1<<(cm&7));
if (!mapheaderinfo[cm])
cm = -1; // guarantee error execution
else if (marathonmode && mapheaderinfo[cm]->marathonnext)
cm = (INT16)(mapheaderinfo[cm]->marathonnext-1);
else
cm = (INT16)(mapheaderinfo[cm]->nextlevel-1);
//Make sure the map actually exists before you try to go to it!
if ((W_CheckNumForName(G_BuildMapName(cm + 1)) == LUMPERROR))
if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error)
{
CONS_Alert(CONS_ERROR, M_GetText("Next map given (MAP %d) doesn't exist! Reverting to MAP01.\n"), cm+1);
cm = 0;
cm = nextmap; //Start the loop again so that the error checking below is executed.
//Make sure the map actually exists before you try to go to it!
if ((W_CheckNumForName(G_BuildMapName(cm + 1)) == LUMPERROR))
{
CONS_Alert(CONS_ERROR, M_GetText("Next map given (MAP %d) doesn't exist! Reverting to MAP01.\n"), cm+1);
cm = 0;
break;
}
}
if (visitedmap[cm/8] & (1<<(cm&7))) // smells familiar
{
// We got stuck in a loop, came back to the map we started on
// without finding one supporting the current gametype.
// Thus, print a warning, and just use this map anyways.
CONS_Alert(CONS_WARNING, M_GetText("Can't find a compatible map after map %d; using map %d anyway\n"), prevmap+1, cm+1);
break;
}
}
if (visitedmap[cm/8] & (1<<(cm&7))) // smells familiar
{
// We got stuck in a loop, came back to the map we started on
// without finding one supporting the current gametype.
// Thus, print a warning, and just use this map anyways.
CONS_Alert(CONS_WARNING, M_GetText("Can't find a compatible map after map %d; using map %d anyway\n"), prevmap+1, cm+1);
break;
}
nextmap = cm;
}
nextmap = cm;
// wrap around in race
if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN))
nextmap = (INT16)(spstage_start-1);
if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1103-1)
I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1);
lastmap = nextmap; // Remember last map for when you come out of the special stage.
}
if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1103-1)
I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1);
// wrap around in race
if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN))
nextmap = (INT16)(spstage_start-1);
if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token)))
{
token--;
@ -3793,7 +3869,10 @@ static void G_DoCompleted(void)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap);
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed))
// If the current gametype has no intermission screen set, then don't start it.
Y_DetermineIntermissionType();
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none))
{
G_UpdateVisited();
G_AfterIntermission();
@ -3804,8 +3883,32 @@ static void G_DoCompleted(void)
Y_StartIntermission();
G_UpdateVisited();
}
// do this before running the intermission or custom cutscene, mostly for the sake of marathon mode but it also massively reduces redundant file save events in f_finale.c
if (nextmap >= 1100-1)
{
if (!gamecomplete)
gamecomplete = 2; // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission
if (cursaveslot > 0)
{
if (marathonmode)
{
// don't keep a backup around when the run is done!
if (FIL_FileExists(liveeventbackup))
remove(liveeventbackup);
cursaveslot = 0;
}
else if ((!modifiedgame || savemoddata) && !(netgame || multiplayer || ultimatemode || demorecording || metalrecording || modeattacking))
G_SaveGame((UINT32)cursaveslot, spstage_start);
}
}
// and doing THIS here means you don't lose your progress if you close the game mid-intermission
else if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking)
&& (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(lastmap+1))
G_SaveGame((UINT32)cursaveslot, lastmap+1); // not nextmap+1 to route around special stages
}
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
void G_AfterIntermission(void)
{
Y_CleanupScreenBuffer();
@ -3816,9 +3919,12 @@ void G_AfterIntermission(void)
return;
}
if (gamecomplete == 2) // special temporary mode to prevent using SP level select in pause menu until the intermission is over without restricting it in every intermission
gamecomplete = 1;
HU_ClearCEcho();
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1 && (gamecomplete || !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
else
{
@ -3844,7 +3950,7 @@ static void G_DoWorldDone(void)
{
if (server)
{
if (gametype == GT_COOP)
if (gametyperules & GTR_CAMPAIGN)
// don't reset player between maps
D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
else
@ -3959,7 +4065,7 @@ void G_EndGame(void)
void G_LoadGameSettings(void)
{
// defaults
spstage_start = 1;
spstage_start = spmarathon_start = 1;
sstage_start = 50;
sstage_end = 56; // 7 special stages in vanilla SRB2
sstage_end++; // plus one weirdo
@ -4279,7 +4385,10 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
startonmapnum = mapoverride;
#endif
sprintf(savename, savegamename, slot);
if (marathonmode)
strcpy(savename, liveeventbackup);
else
sprintf(savename, savegamename, slot);
length = FIL_ReadFile(savename, &savebuffer);
if (!length)
@ -4291,7 +4400,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
save_p = savebuffer;
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, "version %d", VERSION);
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
if (strcmp((const char *)save_p, (const char *)vcheck))
{
#ifdef SAVEGAME_OTHERVERSIONS
@ -4331,6 +4440,11 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
memset(&savedata, 0, sizeof(savedata));
return;
}
if (marathonmode)
{
marathontime = READUINT32(save_p);
marathonmode |= READUINT8(save_p);
}
// done
Z_Free(savebuffer);
@ -4353,19 +4467,18 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
// G_SaveGame
// Saves your game.
//
void G_SaveGame(UINT32 slot)
void G_SaveGame(UINT32 slot, INT16 mapnum)
{
boolean saved;
char savename[256] = "";
const char *backup;
sprintf(savename, savegamename, slot);
if (marathonmode)
strcpy(savename, liveeventbackup);
else
sprintf(savename, savegamename, slot);
backup = va("%s",savename);
// save during evaluation or credits? game's over, folks!
if (gamestate == GS_ENDING || gamestate == GS_CREDITS || gamestate == GS_EVALUATION)
gamecomplete = true;
gameaction = ga_nothing;
{
char name[VERSIONSIZE];
@ -4379,10 +4492,15 @@ void G_SaveGame(UINT32 slot)
}
memset(name, 0, sizeof (name));
sprintf(name, "version %d", VERSION);
sprintf(name, (marathonmode ? "back-up %d" : "version %d"), VERSION);
WRITEMEM(save_p, name, VERSIONSIZE);
P_SaveGame();
P_SaveGame(mapnum);
if (marathonmode)
{
WRITEUINT32(save_p, marathontime);
WRITEUINT8(save_p, (marathonmode & ~MA_INIT));
}
length = save_p - savebuffer;
saved = FIL_WriteFile(backup, savebuffer, length);
@ -4395,7 +4513,7 @@ void G_SaveGame(UINT32 slot)
if (cv_debug && saved)
CONS_Printf(M_GetText("Game saved.\n"));
else if (!saved)
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename);
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
}
#define BADSAVE goto cleanup;
@ -4408,7 +4526,10 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
char savename[255];
const char *backup;
sprintf(savename, savegamename, slot);
if (marathonmode)
strcpy(savename, liveeventbackup);
else
sprintf(savename, savegamename, slot);
backup = va("%s",savename);
length = FIL_ReadFile(savename, &savebuffer);
@ -4427,7 +4548,7 @@ void G_SaveGameOver(UINT32 slot, boolean modifylives)
save_p = savebuffer;
// Version check
memset(vcheck, 0, sizeof (vcheck));
sprintf(vcheck, "version %d", VERSION);
sprintf(vcheck, (marathonmode ? "back-up %d" : "version %d"), VERSION);
if (strcmp((const char *)save_p, (const char *)vcheck)) BADSAVE
save_p += VERSIONSIZE;
@ -4494,7 +4615,7 @@ cleanup:
if (cv_debug && saved)
CONS_Printf(M_GetText("Game saved.\n"));
else if (!saved)
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, savegamename);
CONS_Alert(CONS_ERROR, M_GetText("Error while writing to %s for save slot %u, base: %s\n"), backup, slot, (marathonmode ? liveeventbackup : savegamename));
Z_Free(savebuffer);
save_p = savebuffer = NULL;
@ -4632,7 +4753,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
automapactive = false;
imcontinuing = false;
if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene.
if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer);
else
G_DoLoadLevel(resetplayer);

View File

@ -166,7 +166,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride);
void G_SaveGameData(void);
void G_SaveGame(UINT32 slot);
void G_SaveGame(UINT32 slot, INT16 mapnum);
void G_SaveGameOver(UINT32 slot, boolean modifylives);
@ -191,6 +191,7 @@ boolean G_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void);
boolean G_RingSlingerGametype(void);
boolean G_PlatformGametype(void);
boolean G_CoopGametype(void);
boolean G_TagGametype(void);
boolean G_CompetitionGametype(void);
boolean G_EnoughPlayersFinished(void);

View File

@ -1,20 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw3dsdrv.h
/// \brief 3D sound import/export prototypes for low-level hardware interface
#ifndef __HW_3DS_DRV_H__

View File

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw3sound.c
/// \brief Hardware 3D sound general code
#include "../doomdef.h"

View File

@ -1,20 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 2001 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw3sound.h
/// \brief High-level functions of hardware 3D sound
#ifndef __HW3_SOUND_H__

454
src/hardware/hw_batching.c Normal file
View File

@ -0,0 +1,454 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_batching.c
/// \brief Draw call batching and related things.
#ifdef HWRENDER
#include "hw_glob.h"
#include "hw_batching.h"
#include "../i_system.h"
// The texture for the next polygon given to HWR_ProcessPolygon.
// Set with HWR_SetCurrentTexture.
GLMipmap_t *current_texture = NULL;
boolean currently_batching = false;
FOutVector* finalVertexArray = NULL;// contains subset of sorted vertices and texture coordinates to be sent to gpu
UINT32* finalVertexIndexArray = NULL;// contains indexes for glDrawElements, taking into account fan->triangles conversion
// NOTE have this alloced as 3x finalVertexArray size
int finalVertexArrayAllocSize = 65536;
//GLubyte* colorArray = NULL;// contains color data to be sent to gpu, if needed
//int colorArrayAllocSize = 65536;
// not gonna use this for now, just sort by color and change state when it changes
// later maybe when using vertex attributes if it's needed
PolygonArrayEntry* polygonArray = NULL;// contains the polygon data from DrawPolygon, waiting to be processed
int polygonArraySize = 0;
UINT32* polygonIndexArray = NULL;// contains sorting pointers for polygonArray
int polygonArrayAllocSize = 65536;
FOutVector* unsortedVertexArray = NULL;// contains unsorted vertices and texture coordinates from DrawPolygon
int unsortedVertexArraySize = 0;
int unsortedVertexArrayAllocSize = 65536;
// Enables batching mode. HWR_ProcessPolygon will collect polygons instead of passing them directly to the rendering backend.
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
// init arrays if that has not been done yet
if (!finalVertexArray)
{
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
finalVertexIndexArray = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
polygonArray = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
}
currently_batching = true;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
// The texture selection is saved for the next HWR_ProcessPolygon call.
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
current_texture = texture;
}
else
{
HWD.pfnSetTexture(texture);
}
}
// If batching is enabled, this function collects the polygon data and the chosen texture
// for later use in HWR_RenderBatches. Otherwise the rendering backend is used to
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial)
{
if (currently_batching)
{
if (!pSurf)
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
if (polygonArraySize == polygonArrayAllocSize)
{
PolygonArrayEntry* new_array;
// ran out of space, make new array double the size
polygonArrayAllocSize *= 2;
new_array = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry));
memcpy(new_array, polygonArray, polygonArraySize * sizeof(PolygonArrayEntry));
free(polygonArray);
polygonArray = new_array;
// also need to redo the index array, dont need to copy it though
free(polygonIndexArray);
polygonIndexArray = malloc(polygonArrayAllocSize * sizeof(UINT32));
}
while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize)
{
FOutVector* new_array;
// need more space for vertices in unsortedVertexArray
unsortedVertexArrayAllocSize *= 2;
new_array = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
memcpy(new_array, unsortedVertexArray, unsortedVertexArraySize * sizeof(FOutVector));
free(unsortedVertexArray);
unsortedVertexArray = new_array;
}
// add the polygon data to the arrays
polygonArray[polygonArraySize].surf = *pSurf;
polygonArray[polygonArraySize].vertsIndex = unsortedVertexArraySize;
polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].shader = shader;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
polygonArraySize++;
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
unsortedVertexArraySize += iNumPts;
}
else
{
if (shader)
HWD.pfnSetShader(shader);
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
}
}
static int comparePolygons(const void *p1, const void *p2)
{
unsigned int index1 = *(const unsigned int*)p1;
unsigned int index2 = *(const unsigned int*)p2;
PolygonArrayEntry* poly1 = &polygonArray[index1];
PolygonArrayEntry* poly2 = &polygonArray[index2];
int diff;
INT64 diff64;
int shader1 = poly1->shader;
int shader2 = poly2->shader;
// make skywalls and horizon lines first in order
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
shader1 = -1;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
shader2 = -1;
diff = shader1 - shader2;
if (diff != 0) return diff;
// skywalls and horizon lines must retain their order for horizon lines to work
if (shader1 == -1 && shader2 == -1)
return index1 - index2;
diff64 = poly1->texture - poly2->texture;
if (diff64 != 0) return diff64;
diff = poly1->polyFlags - poly2->polyFlags;
if (diff != 0) return diff;
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
if (diff != 0) return diff;
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
return diff;
}
static int comparePolygonsNoShaders(const void *p1, const void *p2)
{
unsigned int index1 = *(const unsigned int*)p1;
unsigned int index2 = *(const unsigned int*)p2;
PolygonArrayEntry* poly1 = &polygonArray[index1];
PolygonArrayEntry* poly2 = &polygonArray[index2];
int diff;
INT64 diff64;
GLMipmap_t *texture1 = poly1->texture;
GLMipmap_t *texture2 = poly2->texture;
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
texture1 = NULL;
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
texture2 = NULL;
diff64 = texture1 - texture2;
if (diff64 != 0) return diff64;
// skywalls and horizon lines must retain their order for horizon lines to work
if (texture1 == NULL && texture2 == NULL)
return index1 - index2;
diff = poly1->polyFlags - poly2->polyFlags;
if (diff != 0) return diff;
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
return 0;
}
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
// the rendering backend to draw them.
void HWR_RenderBatches(void)
{
int finalVertexWritePos = 0;// position in finalVertexArray
int finalIndexWritePos = 0;// position in finalVertexIndexArray
int polygonReadPos = 0;// position in polygonIndexArray
int currentShader;
int nextShader = 0;
GLMipmap_t *currentTexture;
GLMipmap_t *nextTexture = NULL;
FBITFIELD currentPolyFlags = 0;
FBITFIELD nextPolyFlags = 0;
FSurfaceInfo currentSurfaceInfo;
FSurfaceInfo nextSurfaceInfo;
int i;
if (!currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
nextSurfaceInfo.LightInfo.fade_end = 0;
nextSurfaceInfo.LightInfo.fade_start = 0;
nextSurfaceInfo.LightInfo.light_level = 0;
currently_batching = false;// no longer collecting batches
if (!polygonArraySize)
{
rs_hw_numpolys = rs_hw_numcalls = rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 0;
return;// nothing to draw
}
// init stats vars
rs_hw_numpolys = polygonArraySize;
rs_hw_numcalls = rs_hw_numverts = 0;
rs_hw_numshaders = rs_hw_numtextures = rs_hw_numpolyflags = rs_hw_numcolors = 1;
// init polygonIndexArray
for (i = 0; i < polygonArraySize; i++)
{
polygonIndexArray[i] = i;
}
// sort polygons
rs_hw_batchsorttime = I_GetTimeMicros();
if (cv_grshaders.value && gr_shadersavailable)
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
else
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
rs_hw_batchsorttime = I_GetTimeMicros() - rs_hw_batchsorttime;
// sort order
// 1. shader
// 2. texture
// 3. polyflags
// 4. colors + light level
// not sure about what order of the last 2 should be, or if it even matters
rs_hw_batchdrawtime = I_GetTimeMicros();
currentShader = polygonArray[polygonIndexArray[0]].shader;
currentTexture = polygonArray[polygonIndexArray[0]].texture;
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
// and a color array could replace the color calls.
// set state for first batch
if (cv_grshaders.value && gr_shadersavailable)
{
HWD.pfnSetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
HWD.pfnSetTexture(currentTexture);
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
{
int firstIndex;
int lastIndex;
boolean stopFlag = false;
boolean changeState = false;
boolean changeShader = false;
boolean changeTexture = false;
boolean changePolyFlags = false;
boolean changeSurfaceInfo = false;
// steps:
// write vertices
// check for changes or end, otherwise go back to writing
// changes will affect the next vars and the change bools
// end could set flag for stopping
// execute draw call
// could check ending flag here
// change states according to next vars and change bools, updating the current vars and reseting the bools
// reset write pos
// repeat loop
int index = polygonIndexArray[polygonReadPos++];
int numVerts = polygonArray[index].numVerts;
// before writing, check if there is enough room
// using 'while' instead of 'if' here makes sure that there will *always* be enough room.
// probably never will this loop run more than once though
while (finalVertexWritePos + numVerts > finalVertexArrayAllocSize)
{
FOutVector* new_array;
unsigned int* new_index_array;
finalVertexArrayAllocSize *= 2;
new_array = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
memcpy(new_array, finalVertexArray, finalVertexWritePos * sizeof(FOutVector));
free(finalVertexArray);
finalVertexArray = new_array;
// also increase size of index array, 3x of vertex array since
// going from fans to triangles increases vertex count to 3x
new_index_array = malloc(finalVertexArrayAllocSize * 3 * sizeof(UINT32));
memcpy(new_index_array, finalVertexIndexArray, finalIndexWritePos * sizeof(UINT32));
free(finalVertexIndexArray);
finalVertexIndexArray = new_index_array;
}
// write the vertices of the polygon
memcpy(&finalVertexArray[finalVertexWritePos], &unsortedVertexArray[polygonArray[index].vertsIndex],
numVerts * sizeof(FOutVector));
// write the indexes, pointing to the fan vertexes but in triangles format
firstIndex = finalVertexWritePos;
lastIndex = finalVertexWritePos + numVerts;
finalVertexWritePos += 2;
while (finalVertexWritePos < lastIndex)
{
finalVertexIndexArray[finalIndexWritePos++] = firstIndex;
finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos - 1;
finalVertexIndexArray[finalIndexWritePos++] = finalVertexWritePos++;
}
if (polygonReadPos >= polygonArraySize)
{
stopFlag = true;
}
else
{
// check if a state change is required, set the change bools and next vars
int nextIndex = polygonIndexArray[polygonReadPos];
nextShader = polygonArray[nextIndex].shader;
nextTexture = polygonArray[nextIndex].texture;
nextPolyFlags = polygonArray[nextIndex].polyFlags;
nextSurfaceInfo = polygonArray[nextIndex].surf;
if (nextPolyFlags & PF_NoTexture)
nextTexture = 0;
if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable)
{
changeState = true;
changeShader = true;
}
if (currentTexture != nextTexture)
{
changeState = true;
changeTexture = true;
}
if (currentPolyFlags != nextPolyFlags)
{
changeState = true;
changePolyFlags = true;
}
if (cv_grshaders.value && gr_shadersavailable)
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
{
changeState = true;
changeSurfaceInfo = true;
}
}
else
{
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
{
changeState = true;
changeSurfaceInfo = true;
}
}
}
if (changeState || stopFlag)
{
// execute draw call
HWD.pfnDrawIndexedTriangles(&currentSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
// update stats
rs_hw_numcalls++;
rs_hw_numverts += finalIndexWritePos;
// reset write positions
finalVertexWritePos = 0;
finalIndexWritePos = 0;
}
else continue;
// if we're here then either its time to stop or time to change state
if (stopFlag) break;
// change state according to change bools and next vars, update current vars and reset bools
if (changeShader)
{
HWD.pfnSetShader(nextShader);
currentShader = nextShader;
changeShader = false;
rs_hw_numshaders++;
}
if (changeTexture)
{
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
currentTexture = nextTexture;
changeTexture = false;
rs_hw_numtextures++;
}
if (changePolyFlags)
{
currentPolyFlags = nextPolyFlags;
changePolyFlags = false;
rs_hw_numpolyflags++;
}
if (changeSurfaceInfo)
{
currentSurfaceInfo = nextSurfaceInfo;
changeSurfaceInfo = false;
rs_hw_numcolors++;
}
// and that should be it?
}
// reset the arrays (set sizes to 0)
polygonArraySize = 0;
unsortedVertexArraySize = 0;
rs_hw_batchdrawtime = I_GetTimeMicros() - rs_hw_batchdrawtime;
}
#endif // HWRENDER

View File

@ -0,0 +1,37 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file hw_batching.h
/// \brief Draw call batching and related things.
#ifndef __HWR_BATCHING_H__
#define __HWR_BATCHING_H__
#include "hw_defs.h"
#include "hw_data.h"
#include "hw_drv.h"
typedef struct
{
FSurfaceInfo surf;// surf also has its own polyflags for some reason, but it seems unused
unsigned int vertsIndex;// location of verts in unsortedVertexArray
FUINT numVerts;
FBITFIELD polyFlags;
GLMipmap_t *texture;
int shader;
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
boolean horizonSpecial;
} PolygonArrayEntry;
void HWR_StartBatching(void);
void HWR_SetCurrentTexture(GLMipmap_t *texture);
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial);
void HWR_RenderBatches(void);
#endif

View File

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_bsp.c
/// \brief convert SRB2 map
#include "../doomdef.h"

View File

@ -1,20 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw_cache.c
/// \brief load and convert graphics to the hardware format
#include "../doomdef.h"
@ -22,6 +15,7 @@
#ifdef HWRENDER
#include "hw_glob.h"
#include "hw_drv.h"
#include "hw_batching.h"
#include "../doomstat.h" //gamemode
#include "../i_video.h" //rendermode
@ -33,9 +27,6 @@
#include "../r_patch.h"
#include "../p_setup.h"
// Values set after a call to HWR_ResizeBlock()
static INT32 blocksize, blockwidth, blockheight;
INT32 patchformat = GR_TEXFMT_AP_88; // use alpha for holes
INT32 textureformat = GR_TEXFMT_P_8; // use chromakey for hole
@ -308,13 +299,13 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
if (pwidth <= 0 || pheight <= 0)
return;
ncols = (pwidth * pblockwidth) / pwidth;
ncols = pwidth;
// source advance
xfrac = 0;
xfracstep = (pwidth << FRACBITS) / pblockwidth;
yfracstep = (pheight << FRACBITS) / pblockheight;
scale_y = (pblockheight << FRACBITS) / pheight;
xfracstep = FRACUNIT;
yfracstep = FRACUNIT;
scale_y = FRACUNIT;
bpp = format2bpp[mipmap->grInfo.format];
@ -322,7 +313,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = blockwidth*bpp;
blockmodulo = pblockwidth*bpp;
// Draw each column to the block cache
for (; ncols--; block += bpp, xfrac += xfracstep)
@ -415,7 +406,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
I_Error("HWR_DrawPatchInCache: no drawer defined for this bpp (%d)\n",bpp);
// NOTE: should this actually be pblockwidth*bpp?
blockmodulo = blockwidth*bpp;
blockmodulo = pblockwidth*bpp;
// Draw each column to the block cache
for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep)
@ -433,142 +424,12 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
}
}
// resize the patch to be 3dfx compliant
// set : blocksize = blockwidth * blockheight (no bpp used)
// blockwidth
// blockheight
//note : 8bit (1 byte per pixel) palettized format
static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
GrTexInfo *grInfo)
{
#ifdef GLIDE_API_COMPATIBILITY
// Build the full textures from patches.
static const GrLOD_t gr_lods[9] =
{
GR_LOD_LOG2_256,
GR_LOD_LOG2_128,
GR_LOD_LOG2_64,
GR_LOD_LOG2_32,
GR_LOD_LOG2_16,
GR_LOD_LOG2_8,
GR_LOD_LOG2_4,
GR_LOD_LOG2_2,
GR_LOD_LOG2_1
};
typedef struct
{
GrAspectRatio_t aspect;
float max_s;
float max_t;
} booring_aspect_t;
static const booring_aspect_t gr_aspects[8] =
{
{GR_ASPECT_LOG2_1x1, 255, 255},
{GR_ASPECT_LOG2_2x1, 255, 127},
{GR_ASPECT_LOG2_4x1, 255, 63},
{GR_ASPECT_LOG2_8x1, 255, 31},
{GR_ASPECT_LOG2_1x1, 255, 255},
{GR_ASPECT_LOG2_1x2, 127, 255},
{GR_ASPECT_LOG2_1x4, 63, 255},
{GR_ASPECT_LOG2_1x8, 31, 255}
};
INT32 j,k;
INT32 max,min;
#else
(void)grInfo;
#endif
// find a power of 2 width/height
if (cv_grrounddown.value)
{
blockwidth = 256;
while (originalwidth < blockwidth)
blockwidth >>= 1;
if (blockwidth < 1)
I_Error("3D GenerateTexture : too small");
blockheight = 256;
while (originalheight < blockheight)
blockheight >>= 1;
if (blockheight < 1)
I_Error("3D GenerateTexture : too small");
}
else
{
#ifdef GLIDE_API_COMPATIBILITY
//size up to nearest power of 2
blockwidth = 1;
while (blockwidth < originalwidth)
blockwidth <<= 1;
// scale down the original graphics to fit in 256
if (blockwidth > 2048)
blockwidth = 2048;
//I_Error("3D GenerateTexture : too big");
//size up to nearest power of 2
blockheight = 1;
while (blockheight < originalheight)
blockheight <<= 1;
// scale down the original graphics to fit in 256
if (blockheight > 2048)
blockheight = 2048;
//I_Error("3D GenerateTexture : too big");
#else
blockwidth = originalwidth;
blockheight = originalheight;
#endif
}
// do the boring LOD stuff.. blech!
#ifdef GLIDE_API_COMPATIBILITY
if (blockwidth >= blockheight)
{
max = blockwidth;
min = blockheight;
}
else
{
max = blockheight;
min = blockwidth;
}
for (k = 2048, j = 0; k > max; j++)
k>>=1;
grInfo->smallLodLog2 = gr_lods[j];
grInfo->largeLodLog2 = gr_lods[j];
for (k = max, j = 0; k > min && j < 4; j++)
k>>=1;
// aspect ratio too small for 3Dfx (eg: 8x128 is 1x16 : use 1x8)
if (j == 4)
{
j = 3;
//CONS_Debug(DBG_RENDER, "HWR_ResizeBlock : bad aspect ratio %dx%d\n", blockwidth,blockheight);
if (blockwidth < blockheight)
blockwidth = max>>3;
else
blockheight = max>>3;
}
if (blockwidth < blockheight)
j += 4;
grInfo->aspectRatioLog2 = gr_aspects[j].aspect;
#endif
blocksize = blockwidth * blockheight;
//CONS_Debug(DBG_RENDER, "Width is %d, Height is %d\n", blockwidth, blockheight);
}
static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
{
UINT8 *block;
INT32 bpp, i;
UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX);
INT32 blocksize = (grMipmap->width * grMipmap->height);
bpp = format2bpp[grMipmap->grInfo.format];
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data));
@ -599,6 +460,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
texpatch_t *patch;
patch_t *realpatch;
UINT8 *pdata;
INT32 blockwidth, blockheight, blocksize;
INT32 i;
boolean skyspecial = false; //poor hack for Legacy large skies..
@ -619,11 +481,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
else
grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY;
HWR_ResizeBlock (texture->width, texture->height, &grtex->mipmap.grInfo);
grtex->mipmap.width = (UINT16)blockwidth;
grtex->mipmap.height = (UINT16)blockheight;
grtex->mipmap.width = (UINT16)texture->width;
grtex->mipmap.height = (UINT16)texture->height;
grtex->mipmap.grInfo.format = textureformat;
blockwidth = texture->width;
blockheight = texture->height;
blocksize = (blockwidth * blockheight);
block = MakeBlock(&grtex->mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
@ -692,8 +556,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
// patch may be NULL if grMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
{
INT32 newwidth, newheight;
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum);
@ -712,51 +574,32 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
grPatch->leftoffset = SHORT(patch->leftoffset);
grPatch->topoffset = SHORT(patch->topoffset);
// find the good 3dfx size (boring spec)
HWR_ResizeBlock (SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo);
grMipmap->width = (UINT16)blockwidth;
grMipmap->height = (UINT16)blockheight;
grMipmap->width = grMipmap->height = 1;
while (grMipmap->width < grPatch->width) grMipmap->width <<= 1;
while (grMipmap->height < grPatch->height) grMipmap->height <<= 1;
// no wrap around, no chroma key
grMipmap->flags = 0;
// setup the texture info
grMipmap->grInfo.format = patchformat;
}
else
{
blockwidth = grMipmap->width;
blockheight = grMipmap->height;
blocksize = blockwidth * blockheight;
//grPatch->max_s = grPatch->max_t = 1.0f;
grPatch->max_s = (float)grPatch->width / (float)grMipmap->width;
grPatch->max_t = (float)grPatch->height / (float)grMipmap->height;
}
Z_Free(grMipmap->grInfo.data);
grMipmap->grInfo.data = NULL;
// if rounddown, rounddown patches as well as textures
if (cv_grrounddown.value)
{
newwidth = blockwidth;
newheight = blockheight;
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(grPatch->width, blockwidth);
newheight = min(grPatch->height, blockheight);
}
if (makebitmap)
{
MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap,
newwidth, newheight,
grMipmap->width, grMipmap->height,
grPatch->width, grPatch->height,
patch);
}
grPatch->max_s = (float)newwidth / (float)blockwidth;
grPatch->max_t = (float)newheight / (float)blockheight;
}
@ -896,8 +739,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
HWR_GenerateTexture(tex, grtex);
// Tell the hardware driver to bind the current texture to the flat's mipmap
HWD.pfnSetTexture(&grtex->mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
@ -910,11 +756,6 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
size_t size, pflatsize;
// setup the texture info
#ifdef GLIDE_API_COMPATIBILITY
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
grMipmap->grInfo.format = GR_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
@ -957,15 +798,7 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
{
UINT8 *flat;
if (needpatchflush)
W_FlushCachedPatches();
// setup the texture info
#ifdef GLIDE_API_COMPATIBILITY
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
grMipmap->grInfo.format = GR_TEXFMT_P_8;
grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED;
@ -985,14 +818,15 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum)
if (flatlumpnum == LUMPERROR)
return;
if (needpatchflush)
W_FlushCachedPatches();
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFlat(grmip, flatlumpnum);
HWD.pfnSetTexture(grmip);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded)
HWD.pfnSetTexture(grmip);
HWR_SetCurrentTexture(grmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
@ -1026,14 +860,17 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded)
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum);
// Tell the hardware driver to bind the current texture to the flat's mipmap
HWD.pfnSetTexture(&grtex->mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grtex->mipmap.downloaded)
HWD.pfnSetTexture(&grtex->mipmap);
HWR_SetCurrentTexture(&grtex->mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED);
}
else // set no texture
HWD.pfnSetTexture(NULL);
HWR_SetCurrentTexture(NULL);
}
//
@ -1055,7 +892,11 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
Z_Free(patch);
}
HWD.pfnSetTexture(grmip);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!grmip->downloaded)
HWD.pfnSetTexture(grmip);
HWR_SetCurrentTexture(grmip);
// The system-memory data can be purged now.
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
@ -1066,9 +907,6 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
// -----------------+
void HWR_GetPatch(GLPatch_t *gpatch)
{
if (needpatchflush)
W_FlushCachedPatches();
// is it in hardware cache
if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data)
{
@ -1085,7 +923,11 @@ void HWR_GetPatch(GLPatch_t *gpatch)
Z_Free(ptr);
}
HWD.pfnSetTexture(gpatch->mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!gpatch->mipmap->downloaded)
HWD.pfnSetTexture(gpatch->mipmap);
HWR_SetCurrentTexture(gpatch->mipmap);
// The system-memory patch data can be purged now.
Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
@ -1099,9 +941,6 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
{
GLMipmap_t *grmip, *newmip;
if (needpatchflush)
W_FlushCachedPatches();
if (colormap == colormaps || colormap == NULL)
{
// Load the default (green) color in doom cache (temporary?) AND hardware cache
@ -1225,19 +1064,12 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig
// -----------------+
GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
{
GLPatch_t *grpatch;
if (needpatchflush)
W_FlushCachedPatches();
grpatch = HWR_GetCachedGLPatch(lumpnum);
GLPatch_t *grpatch = HWR_GetCachedGLPatch(lumpnum);
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
{
pic_t *pic;
UINT8 *block;
size_t len;
INT32 newwidth, newheight;
pic = W_CacheLumpNum(lumpnum, PU_CACHE);
grpatch->width = SHORT(pic->width);
@ -1247,10 +1079,8 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
grpatch->leftoffset = 0;
grpatch->topoffset = 0;
// find the good 3dfx size (boring spec)
HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap->grInfo);
grpatch->mipmap->width = (UINT16)blockwidth;
grpatch->mipmap->height = (UINT16)blockheight;
grpatch->mipmap->width = (UINT16)grpatch->width;
grpatch->mipmap->height = (UINT16)grpatch->height;
if (pic->mode == PALETTE)
grpatch->mipmap->grInfo.format = textureformat; // can be set by driver
@ -1262,30 +1092,16 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
// allocate block
block = MakeBlock(grpatch->mipmap);
// if rounddown, rounddown patches as well as textures
if (cv_grrounddown.value)
{
newwidth = blockwidth;
newheight = blockheight;
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(SHORT(pic->width),blockwidth);
newheight = min(SHORT(pic->height),blockheight);
}
if (grpatch->width == blockwidth &&
grpatch->height == blockheight &&
if (grpatch->width == SHORT(pic->width) &&
grpatch->height == SHORT(pic->height) &&
format2bpp[grpatch->mipmap->grInfo.format] == format2bpp[picmode2GR[pic->mode]])
{
// no conversion needed
M_Memcpy(grpatch->mipmap->grInfo.data, pic->data,len);
}
else
HWR_DrawPicInCache(block, newwidth, newheight,
blockwidth*format2bpp[grpatch->mipmap->grInfo.format],
HWR_DrawPicInCache(block, SHORT(pic->width), SHORT(pic->height),
SHORT(pic->width)*format2bpp[grpatch->mipmap->grInfo.format],
pic,
format2bpp[grpatch->mipmap->grInfo.format]);
@ -1293,8 +1109,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
grpatch->mipmap->flags = 0;
grpatch->max_s = (float)newwidth / (float)blockwidth;
grpatch->max_t = (float)newheight / (float)blockheight;
grpatch->max_s = grpatch->max_t = 1.0f;
}
HWD.pfnSetTexture(grpatch->mipmap);
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grpatch->mipmap.grInfo.data, grpatch->mipmap.downloaded);
@ -1330,7 +1145,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
{
INT32 i,j;
fixed_t posx, posy, stepx, stepy;
UINT8 *block = mipmap->grInfo.data; // places the data directly into here, it already has the space allocated from HWR_ResizeBlock
UINT8 *block = mipmap->grInfo.data; // places the data directly into here
UINT8 *flat;
UINT8 *dest, *src, texel;
RGBA_t col;
@ -1345,7 +1160,7 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32
for (j = 0; j < pblockheight; j++)
{
posx = 0;
dest = &block[j*blockwidth]; // 1bpp
dest = &block[j*(mipmap->width)]; // 1bpp
src = &flat[(posy>>FRACBITS)*SHORT(fmwidth)];
for (i = 0; i < pblockwidth;i++)
{
@ -1399,14 +1214,12 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
}
// Thankfully, this will still work for this scenario
HWR_ResizeBlock(fmwidth, fmheight, &grMipmap->grInfo);
grMipmap->width = blockwidth;
grMipmap->height = blockheight;
grMipmap->width = fmwidth;
grMipmap->height = fmheight;
MakeBlock(grMipmap);
HWR_DrawFadeMaskInCache(grMipmap, blockwidth, blockheight, fademasklumpnum, fmwidth, fmheight);
HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight);
// I DO need to convert this because it isn't power of 2 and we need the alpha
}
@ -1414,13 +1227,7 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{
GLMipmap_t *grmip;
if (needpatchflush)
W_FlushCachedPatches();
grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
GLMipmap_t *grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFadeMask(grmip, fademasklumpnum);

View File

@ -78,8 +78,8 @@
#include "r_opengl/r_opengl.h"
#ifdef HAVE_SPHEREFRUSTRUM
static GLfloat viewMatrix[16];
static GLfloat projMatrix[16];
static GLdouble viewMatrix[16];
static GLdouble projMatrix[16];
float frustum[6][4];
#endif
@ -320,12 +320,12 @@ void gld_clipper_Clear(void)
#define RMUL (1.6f/1.333333f)
angle_t gld_FrustumAngle(void)
angle_t gld_FrustumAngle(angle_t tiltangle)
{
double floatangle;
angle_t a1;
float tilt = (float)fabs(((double)(int)aimingangle) / ANG1);
float tilt = (float)fabs(((double)(int)tiltangle) / ANG1);
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
@ -339,7 +339,7 @@ angle_t gld_FrustumAngle(void)
}
// If the pitch is larger than this you can look all around at a FOV of 90
if (abs((signed)aimingangle) > 46 * ANG1)
if (abs((signed)tiltangle) > 46 * ANG1)
return 0xffffffff;
// ok, this is a gross hack that barely works...
@ -352,7 +352,7 @@ angle_t gld_FrustumAngle(void)
}
// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
// compiler complains about (p)glGetDoublev anyway, in case anyone wants this
// compiler complains about (p)glGetFloatv anyway, in case anyone wants this
// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
#ifdef HAVE_SPHEREFRUSTRUM
@ -381,7 +381,7 @@ void gld_FrustrumSetup(void)
float t;
float clip[16];
pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix);
pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);

View File

@ -17,7 +17,7 @@
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
void gld_clipper_Clear(void);
angle_t gld_FrustumAngle(void);
angle_t gld_FrustumAngle(angle_t tiltangle);
#ifdef HAVE_SPHEREFRUSTRUM
void gld_FrustrumSetup(void);
boolean gld_SphereInFrustum(float x, float y, float z, float radius);

View File

@ -1,21 +1,14 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \brief defines structures and exports for the standard 3D driver DLL used by Doom Legacy
/// \file hw_data.h
/// \brief defines structures and exports for the hardware interface used by Sonic Robo Blast 2
#ifndef _HWR_DATA_
#define _HWR_DATA_

View File

@ -1,24 +1,19 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_defs.h
/// \brief 3D hardware renderer definitions
#ifndef _HWR_DEFS_
#define _HWR_DEFS_
#include "../doomtype.h"
#include "../r_defs.h"
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
@ -82,16 +77,18 @@ typedef struct
// Simple 3D vector
typedef struct FVector
{
FLOAT x,y,z;
FLOAT x,y,z;
} FVector;
// 3D model vector (coords + texture coords)
typedef struct
{
//FVector Point;
FLOAT x,y,z;
FLOAT s,t,w; // texture coordinates
} v3d_t, wallVert3D;
// ======================
// wallVert3D
// ----------------------
// :crab: IS GONE! :crab:
// ======================
// -----------
// structures
// -----------
//Hurdler: Transform (coords + angles)
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
@ -123,15 +120,16 @@ typedef struct
#ifdef USE_FTRANSFORM_MIRROR
boolean mirror; // SRB2Kart: Encore Mode
#endif
boolean shearing; // 14042019
float viewaiming; // 17052019
} FTransform;
// Transformed vector, as passed to HWR API
typedef struct
{
FLOAT x,y,z;
FUINT argb; // flat-shaded color
FLOAT sow; // s texture ordinate (s over w)
FLOAT tow; // t texture ordinate (t over w)
FLOAT s; // s texture ordinate (s over w)
FLOAT t; // t texture ordinate (t over w)
} FOutVector;
@ -162,10 +160,10 @@ enum EPolyFlags
PF_Invisible = 0x00000400, // Disable write to color buffer
PF_Decal = 0x00000800, // Enable polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB)
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
// When set, pass the color constant into the FSurfaceInfo -> PolyColor
PF_NoTexture = 0x00002000, // Use the small white texture
PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona
PF_Unused = 0x00008000, // Unused
PF_Ripple = 0x00008000, // Water shader effect
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
PF_ForceWrapX = 0x00020000, // Force repeat texture on X
PF_ForceWrapY = 0x00040000, // Force repeat texture on Y
@ -178,7 +176,6 @@ enum EPolyFlags
enum ESurfFlags
{
SF_DYNLIGHT = 0x00000001,
};
enum ETextureFlags
@ -190,38 +187,36 @@ enum ETextureFlags
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
};
#ifdef TODO
struct FTextureInfo
{
FUINT Width; // Pixels
FUINT Height; // Pixels
FUBYTE *TextureData; // Image data
FUINT Format; // FORMAT_RGB, ALPHA ...
FBITFIELD Flags; // Flags to tell driver about texture (see ETextureFlags)
void DriverExtra; // (OpenGL texture object nr, ...)
// chromakey enabled,...
struct FTextureInfo *Next; // Manage list of downloaded textures.
};
#else
typedef struct GLMipmap_s FTextureInfo;
#endif
// jimita 14032019
struct FLightInfo
{
FUINT light_level;
FUINT fade_start;
FUINT fade_end;
};
typedef struct FLightInfo FLightInfo;
// Description of a renderable surface
struct FSurfaceInfo
{
FUINT PolyFlags; // Surface flags -- UNUSED YET --
RGBA_t FlatColor; // Flat-shaded color used with PF_Modulated mode
FUINT PolyFlags;
RGBA_t PolyColor;
RGBA_t TintColor;
RGBA_t FadeColor;
FLightInfo LightInfo; // jimita 14032019
};
typedef struct FSurfaceInfo FSurfaceInfo;
#define GL_DEFAULTMIX 0x00000000
#define GL_DEFAULTFOG 0xFF000000
//Hurdler: added for backward compatibility
enum hwdsetspecialstate
{
HWD_SET_MODEL_LIGHTING = 1,
HWD_SET_FOG_MODE,
HWD_SET_FOG_COLOR,
HWD_SET_FOG_DENSITY,
HWD_SET_SHADERS,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
HWD_NUMSTATE
@ -229,6 +224,15 @@ enum hwdsetspecialstate
typedef enum hwdsetspecialstate hwdspecialstate_t;
// Lactozilla: Shader info
// Generally set at the start of the frame.
enum hwdshaderinfo
{
HWD_SHADERINFO_LEVELTIME = 1,
};
typedef enum hwdshaderinfo hwdshaderinfo_t;
enum hwdfiltermode
{
HWD_SET_TEXTUREFILTER_POINTSAMPLED,

View File

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2005 by Sonic Team Junior.
//
// Copyright (C) 2005 by SRB2 Jr. Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_dll.h
/// \brief Win32 DLL and Shared Objects API definitions
#ifndef __HWR_DLL_H__
@ -54,8 +47,6 @@
#endif
#endif
typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// ==========================================================================
// MATHS
// ==========================================================================
@ -63,7 +54,7 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// Constants
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/;
void GL_DBG_Printf(const char *format, ...) /*FUNCPRINTF*/;
#ifdef _WINDOWS
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

View File

@ -1,19 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_draw.c
/// \brief miscellaneous drawing (mainly 2d)
#ifdef __GNUC__
@ -23,6 +17,7 @@
#include "../doomdef.h"
#ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h"
#include "hw_drv.h"
@ -43,9 +38,6 @@
#define O_BINARY 0
#endif
float gr_patch_scalex;
float gr_patch_scaley;
#if defined(_MSC_VER)
#pragma pack(1)
#endif
@ -65,9 +57,6 @@ typedef struct
#if defined(_MSC_VER)
#pragma pack()
#endif
typedef UINT8 GLRGB[3];
#define BLENDMODE PF_Translucent
static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255};
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
@ -121,12 +110,12 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = gpatch->max_s;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = gpatch->max_t;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = gpatch->max_s;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
@ -356,19 +345,19 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (option & V_FLIP)
{
v[0].sow = v[3].sow = gpatch->max_s;
v[2].sow = v[1].sow = 0.0f;
v[0].s = v[3].s = gpatch->max_s;
v[2].s = v[1].s = 0.0f;
}
else
{
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = gpatch->max_s;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = gpatch->max_s;
}
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = gpatch->max_t;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
@ -379,11 +368,11 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
if (alphalevel)
{
FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
@ -514,19 +503,19 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[0].s = v[3].s = ((sx )/(float)SHORT(gpatch->width) )*gpatch->max_s;
if (sx + w > SHORT(gpatch->width))
v[2].sow = v[1].sow = gpatch->max_s;
v[2].s = v[1].s = gpatch->max_s;
else
v[2].sow = v[1].sow = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[2].s = v[1].s = ((sx+w)/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[0].tow = v[1].tow = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t;
v[0].t = v[1].t = ((sy )/(float)SHORT(gpatch->height))*gpatch->max_t;
if (sy + h > SHORT(gpatch->height))
v[2].tow = v[3].tow = gpatch->max_t;
v[2].t = v[3].t = gpatch->max_t;
else
v[2].tow = v[3].tow = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t;
v[2].t = v[3].t = ((sy+h)/(float)SHORT(gpatch->height))*gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
@ -537,11 +526,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (alphalevel)
{
FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel];
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
@ -569,10 +558,10 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0;
v[2].sow = v[1].sow = patch->max_s;
v[0].tow = v[1].tow = 0;
v[2].tow = v[3].tow = patch->max_t;
v[0].s = v[3].s = 0;
v[2].s = v[1].s = patch->max_s;
v[0].t = v[1].t = 0;
v[2].t = v[3].t = patch->max_t;
//Hurdler: Boris, the same comment as above... but maybe for pics
@ -581,7 +570,7 @@ void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
// But then, the question is: why not 0 instead of PF_Masked ?
// or maybe PF_Environment ??? (like what I said above)
// BP: PF_Environment don't change anything ! and 0 is undifined
HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip);
HWD.pfnDrawPolygon(NULL, v, 4, PF_Translucent | PF_NoDepthTest | PF_Clip | PF_NoZClip);
}
// ==========================================================================
@ -644,10 +633,10 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
// flat is 64x64 lod and texture offsets are [0.0, 1.0]
v[0].sow = v[3].sow = (float)((x & flatflag)/dflatsize);
v[2].sow = v[1].sow = (float)(v[0].sow + w/dflatsize);
v[0].tow = v[1].tow = (float)((y & flatflag)/dflatsize);
v[2].tow = v[3].tow = (float)(v[0].tow + h/dflatsize);
v[0].s = v[3].s = (float)((x & flatflag)/dflatsize);
v[2].s = v[1].s = (float)(v[0].s + w/dflatsize);
v[0].t = v[1].t = (float)((y & flatflag)/dflatsize);
v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
HWR_LiterallyGetFlat(flatlumpnum);
@ -679,20 +668,20 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 1.0f;
v[2].tow = v[3].tow = 0.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 1.0f;
v[2].t = v[3].t = 0.0f;
if (color & 0xFF00) // Do COLORMAP fade.
{
Surf.FlatColor.rgba = UINT2RGBA(0x01010160);
Surf.FlatColor.s.alpha = (strength*8);
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.PolyColor.s.alpha = (strength*8);
}
else // Do TRANSMAP** fade.
{
Surf.FlatColor.rgba = V_GetColor(color).rgba;
Surf.FlatColor.s.alpha = softwaretranstogl[strength];
Surf.PolyColor.rgba = V_GetColor(color).rgba;
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
}
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@ -850,24 +839,22 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
if (actualcolor & 0xFF00) // Do COLORMAP fade.
{
Surf.FlatColor.rgba = UINT2RGBA(0x01010160);
Surf.FlatColor.s.alpha = (strength*8);
Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.PolyColor.s.alpha = (strength*8);
}
else // Do TRANSMAP** fade.
{
Surf.FlatColor.rgba = V_GetColor(actualcolor).rgba;
Surf.FlatColor.s.alpha = softwaretranstogl[strength];
Surf.PolyColor.rgba = V_GetColor(actualcolor).rgba;
Surf.PolyColor.s.alpha = softwaretranstogl[strength];
}
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@ -888,13 +875,13 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 1.0f;
v[2].tow = v[3].tow = 0.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 1.0f;
v[2].t = v[3].t = 0.0f;
Surf.FlatColor.rgba = UINT2RGBA(color);
Surf.FlatColor.s.alpha = 0x80;
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@ -904,7 +891,11 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
{
FOutVector v[4];
FSurfaceInfo Surf;
INT32 height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway
INT32 height;
if (boxheight < 0)
height = -boxheight;
else
height = (boxheight * 4) + (boxheight/2)*5; // 4 lines of space plus gaps between and some leeway
// setup some neat-o translucency effect
@ -914,13 +905,13 @@ void HWR_DrawTutorialBack(UINT32 color, INT32 boxheight)
v[2].y = v[3].y = -1.0f+((height<<1)/(float)vid.height);
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 1.0f;
v[2].tow = v[3].tow = 0.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 1.0f;
v[2].t = v[3].t = 0.0f;
Surf.FlatColor.rgba = UINT2RGBA(color);
Surf.FlatColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = (color == 0 ? 0xC0 : 0x80); // make black darker, like software
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@ -1232,17 +1223,15 @@ void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.FlatColor.rgba = UINT2RGBA(actualcolor);
Surf.FlatColor.s.alpha = 0x80;
Surf.PolyColor.rgba = UINT2RGBA(actualcolor);
Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
@ -1412,16 +1401,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.FlatColor = V_GetColor(color);
Surf.PolyColor = V_GetColor(color);
HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest);

View File

@ -1,20 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw_drv.h
/// \brief imports/exports for the 3D hardware low-level interface API
#ifndef __HWR_DRV_H__
@ -32,7 +25,7 @@
// STANDARD DLL EXPORTS
// ==========================================================================
EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction);
EXPORT boolean HWRAPI(Init) (void);
#ifndef HAVE_SDL
EXPORT void HWRAPI(Shutdown) (void);
#endif
@ -43,10 +36,12 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal);
EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl);
EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color);
EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags);
EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, UINT32 *IndexArray);
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
@ -55,14 +50,11 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void);
@ -71,6 +63,20 @@ EXPORT void HWRAPI(DrawIntermissionBG) (void);
EXPORT void HWRAPI(MakeScreenTexture) (void);
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
// jimita
EXPORT boolean HWRAPI(LoadShaders) (void);
EXPORT void HWRAPI(KillShaders) (void);
EXPORT void HWRAPI(SetShader) (int shader);
EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment);
EXPORT boolean HWRAPI(InitCustomShaders) (void);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ==========================================================================
@ -84,10 +90,12 @@ struct hwdriver_s
FinishUpdate pfnFinishUpdate;
Draw2DLine pfnDraw2DLine;
DrawPolygon pfnDrawPolygon;
DrawIndexedTriangles pfnDrawIndexedTriangles;
RenderSkyDome pfnRenderSkyDome;
SetBlend pfnSetBlend;
ClearBuffer pfnClearBuffer;
SetTexture pfnSetTexture;
UpdateTexture pfnUpdateTexture;
ReadRect pfnReadRect;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
@ -96,7 +104,6 @@ struct hwdriver_s
CreateModelVBOs pfnCreateModelVBOs;
SetTransform pfnSetTransform;
GetTextureUsed pfnGetTextureUsed;
GetRenderVersion pfnGetRenderVersion;
#ifdef _WINDOWS
GetModeList pfnGetModeList;
#endif
@ -112,13 +119,19 @@ struct hwdriver_s
MakeScreenTexture pfnMakeScreenTexture;
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
LoadShaders pfnLoadShaders;
KillShaders pfnKillShaders;
SetShader pfnSetShader;
UnSetShader pfnUnSetShader;
SetShaderInfo pfnSetShaderInfo;
LoadCustomShader pfnLoadCustomShader;
InitCustomShaders pfnInitCustomShaders;
};
extern struct hwdriver_s hwdriver;
//Hurdler: 16/10/99: added for OpenGL gamma correction
//extern RGBA_t gamma_correction;
#define HWD hwdriver
#endif //not defined _CREATE_DLL_

View File

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_glide.h
/// \brief Declaration needed by Glide renderer
/// !!! To be replaced by our own def in the future !!!
@ -25,26 +18,6 @@
typedef unsigned long FxU32;
typedef long FxI32;
typedef FxI32 GrAspectRatio_t;
#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */
#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */
#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */
#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */
#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */
#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */
#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */
typedef FxI32 GrLOD_t;
#define GR_LOD_LOG2_256 0x8
#define GR_LOD_LOG2_128 0x7
#define GR_LOD_LOG2_64 0x6
#define GR_LOD_LOG2_32 0x5
#define GR_LOD_LOG2_16 0x4
#define GR_LOD_LOG2_8 0x3
#define GR_LOD_LOG2_4 0x2
#define GR_LOD_LOG2_2 0x1
#define GR_LOD_LOG2_1 0x0
typedef FxI32 GrTextureFormat_t;
#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */
#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */
@ -59,11 +32,6 @@ typedef FxI32 GrTextureFormat_t;
typedef struct
{
#ifdef GLIDE_API_COMPATIBILITY
GrLOD_t smallLodLog2;
GrLOD_t largeLodLog2;
GrAspectRatio_t aspectRatioLog2;
#endif
GrTextureFormat_t format;
void *data;
} GrTexInfo;

View File

@ -1,20 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw_glob.h
/// \brief globals (shared data & code) for hw_ modules
#ifndef _HWR_GLOB_H_
@ -68,9 +61,6 @@ typedef struct
// equivalent of the software renderer's vissprites
typedef struct gr_vissprite_s
{
// Doubly linked list
struct gr_vissprite_s *prev;
struct gr_vissprite_s *next;
float x1, x2;
float tz, ty;
//lumpnum_t patchlumpnum;
@ -118,11 +108,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// --------
// hw_draw.c
// --------
extern float gr_patch_scalex;
extern float gr_patch_scaley;
extern consvar_t cv_grrounddown; // on/off
extern INT32 patchformat;
extern INT32 textureformat;

View File

@ -1,19 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_light.c
/// \brief Corona/Dynamic/Static lighting add on by Hurdler
/// !!! Under construction !!!
@ -879,19 +873,19 @@ void HWR_WallLighting(FOutVector *wlVerts)
#endif
for (i = 0; i < 4; i++)
{
wlVerts[i].sow = (float)(0.5f + d[i]*s);
wlVerts[i].tow = (float)(0.5f + (wlVerts[i].y-LIGHT_POS(j).y)*s*1.2f);
wlVerts[i].s = (float)(0.5f + d[i]*s);
wlVerts[i].t = (float)(0.5f + (wlVerts[i].y-LIGHT_POS(j).y)*s*1.2f);
}
HWR_SetLight();
Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color);
Surf.PolyColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color);
#ifdef DL_HIGH_QUALITY
Surf.FlatColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha);
Surf.PolyColor.s.alpha = (UINT8)((1-dist_p2d/DL_SQRRADIUS(j))*Surf.PolyColor.s.alpha);
#endif
// next state is null so fade out with alpha
if (dynlights->mo[j]->state->nextstate == S_NULL)
Surf.FlatColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha);
Surf.PolyColor.s.alpha = (UINT8)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha);
HWD.pfnDrawPolygon (&Surf, wlVerts, 4, LIGHTMAPFLAGS);
@ -948,19 +942,19 @@ void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts)
#endif
for (i = 0; i < nrClipVerts; i++)
{
clVerts[i].sow = 0.5f + (clVerts[i].x-LIGHT_POS(j).x)*s;
clVerts[i].tow = 0.5f + (clVerts[i].z-LIGHT_POS(j).z)*s*1.2f;
clVerts[i].s = 0.5f + (clVerts[i].x-LIGHT_POS(j).x)*s;
clVerts[i].t = 0.5f + (clVerts[i].z-LIGHT_POS(j).z)*s*1.2f;
}
HWR_SetLight();
Surf.FlatColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color);
Surf.PolyColor.rgba = LONG(dynlights->p_lspr[j]->dynamic_color);
#ifdef DL_HIGH_QUALITY
Surf.FlatColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.FlatColor.s.alpha);
Surf.PolyColor.s.alpha = (unsigned char)((1 - dist_p2d/DL_SQRRADIUS(j))*Surf.PolyColor.s.alpha);
#endif
// next state is null so fade out with alpha
if ((dynlights->mo[j]->state->nextstate == S_NULL))
Surf.FlatColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.FlatColor.s.alpha);
Surf.PolyColor.s.alpha = (unsigned char)(((float)dynlights->mo[j]->tics/(float)dynlights->mo[j]->state->tics)*Surf.PolyColor.s.alpha);
HWD.pfnDrawPolygon (&Surf, clVerts, nrClipVerts, LIGHTMAPFLAGS);
@ -1027,11 +1021,11 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr)
// more realistique corona !
if (cz >= 255*8+250)
return;
Surf.FlatColor.rgba = p_lspr->corona_color;
Surf.PolyColor.rgba = p_lspr->corona_color;
if (cz > 250.0f)
Surf.FlatColor.s.alpha = 0xff-((int)cz-250)/8;
Surf.PolyColor.s.alpha = 0xff-((int)cz-250)/8;
else
Surf.FlatColor.s.alpha = 0xff;
Surf.PolyColor.s.alpha = 0xff;
// do not be hide by sprite of the light itself !
cz = cz - 2.0f;
@ -1043,19 +1037,19 @@ void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr)
// car comme l'offset est minime sa ce voit pas !
light[0].x = cx-size; light[0].z = cz;
light[0].y = cy-size*1.33f+p_lspr->light_yoffset;
light[0].sow = 0.0f; light[0].tow = 0.0f;
light[0].s = 0.0f; light[0].t = 0.0f;
light[1].x = cx+size; light[1].z = cz;
light[1].y = cy-size*1.33f+p_lspr->light_yoffset;
light[1].sow = 1.0f; light[1].tow = 0.0f;
light[1].s = 1.0f; light[1].t = 0.0f;
light[2].x = cx+size; light[2].z = cz;
light[2].y = cy+size*1.33f+p_lspr->light_yoffset;
light[2].sow = 1.0f; light[2].tow = 1.0f;
light[2].s = 1.0f; light[2].t = 1.0f;
light[3].x = cx-size; light[3].z = cz;
light[3].y = cy+size*1.33f+p_lspr->light_yoffset;
light[3].sow = 0.0f; light[3].tow = 1.0f;
light[3].s = 0.0f; light[3].t = 1.0f;
HWR_GetPic(coronalumpnum); /// \todo use different coronas
@ -1101,11 +1095,11 @@ void HWR_DrawCoronas(void)
// more realistique corona !
if (cz >= 255*8+250)
continue;
Surf.FlatColor.rgba = p_lspr->corona_color;
Surf.PolyColor.rgba = p_lspr->corona_color;
if (cz > 250.0f)
Surf.FlatColor.s.alpha = (UINT8)(0xff-(UINT8)(((int)cz-250)/8));
Surf.PolyColor.s.alpha = (UINT8)(0xff-(UINT8)(((int)cz-250)/8));
else
Surf.FlatColor.s.alpha = 0xff;
Surf.PolyColor.s.alpha = 0xff;
switch (p_lspr->type)
{
@ -1113,7 +1107,7 @@ void HWR_DrawCoronas(void)
size = p_lspr->corona_radius * ((cz+120.0f)/950.0f); // d'ou vienne ces constante ?
break;
case ROCKET_SPR:
Surf.FlatColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff);
Surf.PolyColor.s.alpha = (UINT8)((M_RandomByte()>>1)&0xff);
// don't need a break
case CORONA_SPR:
size = p_lspr->corona_radius * ((cz+60.0f)/100.0f); // d'ou vienne ces constante ?
@ -1133,19 +1127,19 @@ void HWR_DrawCoronas(void)
light[0].x = cx-size; light[0].z = cz;
light[0].y = cy-size*1.33f;
light[0].sow = 0.0f; light[0].tow = 0.0f;
light[0].s = 0.0f; light[0].t = 0.0f;
light[1].x = cx+size; light[1].z = cz;
light[1].y = cy-size*1.33f;
light[1].sow = 1.0f; light[1].tow = 0.0f;
light[1].s = 1.0f; light[1].t = 0.0f;
light[2].x = cx+size; light[2].z = cz;
light[2].y = cy+size*1.33f;
light[2].sow = 1.0f; light[2].tow = 1.0f;
light[2].s = 1.0f; light[2].t = 1.0f;
light[3].x = cx-size; light[3].z = cz;
light[3].y = cy+size*1.33f;
light[3].sow = 0.0f; light[3].tow = 1.0f;
light[3].s = 0.0f; light[3].t = 1.0f;
HWD.pfnDrawPolygon (&Surf, light, 4, PF_Modulated | PF_Additive | PF_Clip | PF_NoDepthTest | PF_Corona);
}
@ -1254,11 +1248,6 @@ static void HWR_SetLight(void)
lightmappatch.height = 128;
lightmappatch.mipmap->width = 128;
lightmappatch.mipmap->height = 128;
#ifdef GLIDE_API_COMPATIBILITY
lightmappatch.mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_128;
lightmappatch.mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_128;
lightmappatch.mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
lightmappatch.mipmap->flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw !
}
HWD.pfnSetTexture(lightmappatch.mipmap);

View File

@ -1,19 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hw_light.h
/// \brief Dynamic lighting & coronas add on by Hurdler
#ifndef _HW_LIGHTS_

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,13 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \file hw_main.h
/// \brief 3D render mode functions
#ifndef __HWR_MAIN_H__
@ -73,8 +66,11 @@ void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);
// This stuff is put here so MD2's can use them
UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane);
FUNCMATH UINT8 LightLevelToLum(INT32 l);
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
void HWR_ReadShaders(UINT16 wadnum, boolean PK3);
boolean HWR_LoadShaders(void);
extern CV_PossibleValue_t granisotropicmode_cons_t[];
@ -84,21 +80,23 @@ extern consvar_t cv_grstaticlighting;
extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize;
#endif
extern consvar_t cv_grshaders;
extern consvar_t cv_grmodels;
extern consvar_t cv_grmodelinterpolation;
extern consvar_t cv_grmodellighting;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogcolor;
extern consvar_t cv_grfogdensity;
extern consvar_t cv_grsoftwarefog;
extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_fovchange;
extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grshearing;
extern consvar_t cv_grspritebillboarding;
extern consvar_t cv_grskydome;
extern consvar_t cv_grfakecontrast;
extern consvar_t cv_grslopecontrast;
extern consvar_t cv_grbatching;
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy;
@ -108,4 +106,24 @@ extern float gr_viewwindowx, gr_basewindowcentery;
extern fixed_t *hwbbox;
extern FTransform atransform;
// Render stats
extern int rs_hw_nodesorttime;
extern int rs_hw_nodedrawtime;
extern int rs_hw_spritesorttime;
extern int rs_hw_spritedrawtime;
// Render stats for batching
extern int rs_hw_numpolys;
extern int rs_hw_numverts;
extern int rs_hw_numcalls;
extern int rs_hw_numshaders;
extern int rs_hw_numtextures;
extern int rs_hw_numpolyflags;
extern int rs_hw_numcolors;
extern int rs_hw_batchsorttime;
extern int rs_hw_batchdrawtime;
extern boolean gr_shadersavailable;
#endif

View File

@ -1,23 +1,16 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \brief MD2 Handling
/// \file hw_md2.c
/// \brief 3D Model Handling
/// Inspired from md2.c by Mete Ciragan (mete@swissquake.ch)
#ifdef __GNUC__
#include <unistd.h>
#endif
@ -382,7 +375,10 @@ static void md2_loadTexture(md2_t *model)
#endif
grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->grInfo.format == 0)
{
model->notexturefile = true; // mark it so its not searched for again repeatedly
return;
}
grpatch->mipmap->downloaded = 0;
grpatch->mipmap->flags = 0;
@ -400,13 +396,6 @@ static void md2_loadTexture(md2_t *model)
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
image++;
}
#ifdef GLIDE_API_COMPATIBILITY
// not correct!
grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
}
HWD.pfnSetTexture(grpatch->mipmap);
}
@ -444,6 +433,7 @@ static void md2_loadBlendTexture(md2_t *model)
grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap->grInfo.format == 0)
{
model->noblendfile = true; // mark it so its not searched for again repeatedly
Z_Free(filename);
return;
}
@ -455,13 +445,6 @@ static void md2_loadBlendTexture(md2_t *model)
grpatch->height = (INT16)h;
grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap->height = (UINT16)h;
#ifdef GLIDE_API_COMPATIBILITY
// not correct!
grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
#endif
}
HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
@ -486,6 +469,8 @@ void HWR_InitModels(void)
md2_playermodels[s].scale = -1.0f;
md2_playermodels[s].model = NULL;
md2_playermodels[s].grpatch = NULL;
md2_playermodels[s].notexturefile = false;
md2_playermodels[s].noblendfile = false;
md2_playermodels[s].skin = -1;
md2_playermodels[s].notfound = true;
md2_playermodels[s].error = false;
@ -495,6 +480,8 @@ void HWR_InitModels(void)
md2_models[i].scale = -1.0f;
md2_models[i].model = NULL;
md2_models[i].grpatch = NULL;
md2_models[i].notexturefile = false;
md2_models[i].noblendfile = false;
md2_models[i].skin = -1;
md2_models[i].notfound = true;
md2_models[i].error = false;
@ -949,11 +936,19 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
blendcolor = V_GetColor(translation[firsti]);
if (secondi >= translen)
mul = 0;
if (mul > 0) // If it's 0, then we only need the first color.
{
if (secondi >= translen) // blend to black
#if 0
if (secondi >= translen)
{
// blend to black
nextcolor = V_GetColor(31);
}
else
#endif
nextcolor = V_GetColor(translation[secondi]);
// Find difference between points
@ -1188,15 +1183,14 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t
boolean HWR_DrawModel(gr_vissprite_t *spr)
{
FSurfaceInfo Surf;
md2_t *md2;
char filename[64];
INT32 frame = 0;
INT32 nextFrame = -1;
UINT8 spr2 = 0;
FTransform p;
md2_t *md2;
UINT8 color[4];
FSurfaceInfo Surf;
if (!cv_grmodels.value)
return false;
@ -1235,13 +1229,10 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
colormap = sector->extra_colormap;
}
if (colormap)
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
HWR_Lighting(&Surf, lightlevel, colormap);
}
else
Surf.FlatColor.rgba = 0xFFFFFFFF;
Surf.PolyColor.rgba = 0xFFFFFFFF;
// Look at HWR_ProjectSprite for more
{
@ -1251,6 +1242,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
//mdlframe_t *next = NULL;
const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE);
const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP));
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !(spr->mobj->frame & FF_HORIZONTALFLIP));
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
@ -1263,11 +1255,11 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
//durs = tics;
if (spr->mobj->flags2 & MF2_SHADOW)
Surf.FlatColor.s.alpha = 0x40;
Surf.PolyColor.s.alpha = 0x40;
else if (spr->mobj->frame & FF_TRANSMASK)
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
Surf.FlatColor.s.alpha = 0xFF;
Surf.PolyColor.s.alpha = 0xFF;
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
@ -1315,12 +1307,14 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
finalscale = md2->scale;
//Hurdler: arf, I don't like that implementation at all... too much crappy
gpatch = md2->grpatch;
if (!gpatch || !gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded)
if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !md2->notexturefile))
md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available
&& (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded))
&& (!md2->blendgrpatch
|| ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)
&& !md2->noblendfile)))
md2_loadBlendTexture(md2);
if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
@ -1512,11 +1506,6 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
}
#endif
color[0] = Surf.FlatColor.s.red;
color[1] = Surf.FlatColor.s.green;
color[2] = Surf.FlatColor.s.blue;
color[3] = Surf.FlatColor.s.alpha;
// SRB2CBTODO: MD2 scaling support
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
@ -1525,7 +1514,8 @@ boolean HWR_DrawModel(gr_vissprite_t *spr)
p.mirror = atransform.mirror; // from Kart
#endif
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color);
HWD.pfnSetShader(4); // model shader
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf);
}
return true;

View File

@ -1,21 +1,14 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2020 by Sonic Team Junior.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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
/// \brief MD2 Handling
/// \file hw_md2.h
/// \brief 3D Model Handling
/// Inspired from md2.h by Mete Ciragan (mete@swissquake.ch)
#ifndef _HW_MD2_H_
@ -35,7 +28,9 @@ typedef struct
float offset;
model_t *model;
void *grpatch;
boolean notexturefile; // true if texture file was not found
void *blendgrpatch;
boolean noblendfile; // true if blend texture file was not found
boolean notfound;
INT32 skin;
boolean error;

View File

@ -1,19 +1,12 @@
// Emacs style mode select -*- C++ -*-
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2005 by Sonic Team Junior.
//
// Copyright (C) 2005 by SRB2 Jr. Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 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
/// \file hws_data.h
/// \brief 3D sound definitions
#ifndef __HWS_DATA_H__

View File

@ -206,7 +206,7 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth
if (iLastPFD)
{
DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n");
GL_DBG_Printf("WARNING : SetPixelFormat() called twise not supported by all drivers !\n");
}
// set the pixel format only if different than the current
@ -215,17 +215,17 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth
else
iLastPFD = iPFD;
DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n",
GL_DBG_Printf("SetupPixelFormat() - %d ColorBits - %d StencilBits - %d DepthBits\n",
WantColorBits, WantStencilBits, WantDepthBits);
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if (nPixelFormat == 0)
DBG_Printf("ChoosePixelFormat() FAILED\n");
GL_DBG_Printf("ChoosePixelFormat() FAILED\n");
if (SetPixelFormat(hDC, nPixelFormat, &pfd) == 0)
{
DBG_Printf("SetPixelFormat() FAILED\n");
GL_DBG_Printf("SetPixelFormat() FAILED\n");
return 0;
}
@ -243,7 +243,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
BOOL WantFullScreen = !(lvid->u.windowed); //(lvid->u.windowed ? 0 : CDS_FULLSCREEN);
UNREFERENCED_PARAMETER(pcurrentmode);
DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n",
GL_DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n",
lvid->width, lvid->height, lvid->bpp*8,
WantFullScreen ? "fullscreen" : "windowed");
@ -301,7 +301,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
hDC = GetDC(hWnd);
if (!hDC)
{
DBG_Printf("GetDC() FAILED\n");
GL_DBG_Printf("GetDC() FAILED\n");
return 0;
}
@ -321,12 +321,12 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
hGLRC = pwglCreateContext(hDC);
if (!hGLRC)
{
DBG_Printf("pwglCreateContext() FAILED\n");
GL_DBG_Printf("pwglCreateContext() FAILED\n");
return 0;
}
if (!pwglMakeCurrent(hDC, hGLRC))
{
DBG_Printf("wglMakeCurrent() FAILED\n");
GL_DBG_Printf("wglMakeCurrent() FAILED\n");
return 0;
}
}
@ -337,15 +337,15 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
//BP: why don't we make it earlier ?
//Hurdler: we cannot do that before intialising gl context
renderer = (LPCSTR)pglGetString(GL_RENDERER);
DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR));
DBG_Printf("Renderer : %s\n", renderer);
DBG_Printf("Version : %s\n", pglGetString(GL_VERSION));
DBG_Printf("Extensions : %s\n", gl_extensions);
GL_DBG_Printf("Vendor : %s\n", pglGetString(GL_VENDOR));
GL_DBG_Printf("Renderer : %s\n", renderer);
GL_DBG_Printf("Version : %s\n", pglGetString(GL_VERSION));
GL_DBG_Printf("Extensions : %s\n", gl_extensions);
// BP: disable advenced feature that don't work on somes hardware
// Hurdler: Now works on G400 with bios 1.6 and certified drivers 6.04
if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD;
DBG_Printf("oglflags : 0x%X\n", oglflags);
GL_DBG_Printf("oglflags : 0x%X\n", oglflags);
#ifdef USE_WGL_SWAP
if (isExtAvailable("WGL_EXT_swap_control",gl_extensions))
@ -386,7 +386,7 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
// -----------------+
static void UnSetRes(void)
{
DBG_Printf("UnSetRes()\n");
GL_DBG_Printf("UnSetRes()\n");
pwglMakeCurrent(hDC, NULL);
pwglDeleteContext(hGLRC);
@ -437,7 +437,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
video_modes[iMode].misc = 0;
video_modes[iMode].name = malloc(12 * sizeof (CHAR));
sprintf(video_modes[iMode].name, "%dx%d", (INT32)Tmp.dmPelsWidth, (INT32)Tmp.dmPelsHeight);
DBG_Printf ("Mode: %s\n", video_modes[iMode].name);
GL_DBG_Printf ("Mode: %s\n", video_modes[iMode].name);
video_modes[iMode].width = Tmp.dmPelsWidth;
video_modes[iMode].height = Tmp.dmPelsHeight;
video_modes[iMode].bytesperpixel = Tmp.dmBitsPerPel/8;
@ -474,7 +474,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
HDC bpphdc;
INT32 iBitsPerPel;
DBG_Printf ("HWRAPI GetModeList()\n");
GL_DBG_Printf ("HWRAPI GetModeList()\n");
bpphdc = GetDC(NULL); // on obtient le bpp actuel
iBitsPerPel = GetDeviceCaps(bpphdc, BITSPIXEL);
@ -490,7 +490,7 @@ EXPORT void HWRAPI(GetModeList) (vmode_t** pvidmodes, INT32 *numvidmodes)
video_modes[i].misc = 0;
video_modes[i].name = malloc(12 * sizeof (CHAR));
sprintf(video_modes[i].name, "%dx%d", res[i][0], res[i][1]);
DBG_Printf ("Mode: %s\n", video_modes[i].name);
GL_DBG_Printf ("Mode: %s\n", video_modes[i].name);
video_modes[i].width = res[i][0];
video_modes[i].height = res[i][1];
video_modes[i].bytesperpixel = iBitsPerPel/8;
@ -511,9 +511,9 @@ EXPORT void HWRAPI(Shutdown) (void)
#ifdef DEBUG_TO_FILE
long nb_centiemes;
DBG_Printf ("HWRAPI Shutdown()\n");
GL_DBG_Printf ("HWRAPI Shutdown()\n");
nb_centiemes = ((clock()-my_clock)*100)/CLOCKS_PER_SEC;
DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n",
GL_DBG_Printf("Nb frames: %li; Nb sec: %2.2f -> %2.1f fps\n",
nb_frames, nb_centiemes/100.0f, (100*nb_frames)/(double)nb_centiemes);
#endif
@ -530,7 +530,7 @@ EXPORT void HWRAPI(Shutdown) (void)
}
FreeLibrary(GLU32);
FreeLibrary(OGL32);
DBG_Printf ("HWRAPI Shutdown(DONE)\n");
GL_DBG_Printf ("HWRAPI Shutdown(DONE)\n");
}
// -----------------+
@ -543,7 +543,7 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl)
#else
UNREFERENCED_PARAMETER(waitvbl);
#endif
// DBG_Printf ("FinishUpdate()\n");
// GL_DBG_Printf ("FinishUpdate()\n");
#ifdef DEBUG_TO_FILE
if ((++nb_frames)==2) // on ne commence pas <20> la premi<6D>re frame
my_clock = clock();

File diff suppressed because it is too large Load Diff

View File

@ -70,10 +70,6 @@
extern FILE *gllogstream;
#endif
#ifndef DRIVER_STRING
#define DRIVER_STRING "HWRAPI Init(): SRB2 OpenGL renderer" // Tails
#endif
// ==========================================================================
// PROTOS
// ==========================================================================
@ -81,13 +77,11 @@ extern FILE *gllogstream;
boolean LoadGL(void);
void *GetGLFunc(const char *proc);
boolean SetupGLfunc(void);
boolean SetupGLFunc13(void);
void SetupGLFunc4(void);
void Flush(void);
INT32 isExtAvailable(const char *extension, const GLubyte *start);
int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits);
void SetModelView(GLint w, GLint h);
void SetStates(void);
FUNCMATH float byteasfloat(UINT8 fbyte);
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@ -123,12 +117,15 @@ static PFNglEnableClientState pglEnableClientState;
// GLOBAL
// ==========================================================================
extern const GLubyte *gl_extensions;
extern RGBA_t myPaletteData[];
extern GLint screen_width;
extern GLint screen_height;
extern GLbyte screen_depth;
extern GLint maximumAnisotropy;
extern const GLubyte *gl_version;
extern const GLubyte *gl_renderer;
extern const GLubyte *gl_extensions;
extern RGBA_t myPaletteData[];
extern GLint screen_width;
extern GLint screen_height;
extern GLbyte screen_depth;
extern GLint maximumAnisotropy;
/** \brief OpenGL flags for video driver
*/

View File

@ -2102,7 +2102,7 @@ void HU_Drawer(void)
{
if (LUA_HudEnabled(hud_rankings))
HU_DrawRankings();
if (gametype == GT_COOP)
if (gametyperules & GTR_CAMPAIGN)
HU_DrawNetplayCoopOverlay();
}
else

View File

@ -46,6 +46,8 @@ UINT32 I_GetFreeMem(UINT32 *total);
*/
tic_t I_GetTime(void);
int I_GetTimeMicros(void);// provides microsecond counter for render stats
/** \brief The I_Sleep function
\return void

View File

@ -1430,11 +1430,13 @@ state_t states[NUMSTATES] =
{SPR_FANG, 8, 0, {A_PrepareRepeat}, 1, 0, S_FANG_PINCHPATHINGSTART2}, // S_FANG_PINCHPATHINGSTART1
{SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PINCHPATHING}, // S_FANG_PINCHPATHINGSTART2
{SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHPATHING
{SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE0}, // S_FANG_PINCHPATHING
{SPR_FANG, 8, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 2, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHBOUNCE0
{SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_PINCHBOUNCE2}, // S_FANG_PINCHBOUNCE1
{SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_PINCHBOUNCE3}, // S_FANG_PINCHBOUNCE2
{SPR_FANG, 10, 2, {A_Boss5Jump}, 0, 0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE3
{SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL1, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4
{SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4
{SPR_FANG, 12, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 1, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL0
{SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL2}, // S_FANG_PINCHFALL1
{SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL2
{SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID1
@ -3362,7 +3364,7 @@ state_t states[NUMSTATES] =
// CTF Sign
{SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG
// Finish flag
{SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG
@ -5292,7 +5294,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
0, // damage
sfx_None, // activesound
MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_BOUNCE|MF_RUNSPAWNFUNC, // flags
MF_SPECIAL|MF_SHOOTABLE|MF_ENEMY|MF_NOGRAVITY|MF_SLIDEME|MF_RUNSPAWNFUNC, // flags
S_NULL // raisestate
},
@ -18010,7 +18012,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_FINISHFLAG
-1, // doomednum
S_FINISHFLAG, // spawnstate
@ -19855,7 +19857,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
S_NULL // raisestate
},
{ // MT_FLINGNIGHTSSTAR
-1, // doomednum
S_NIGHTSSTAR, // spawnstate
@ -21691,7 +21693,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = {
{"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET
{"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC
{"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 15, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY
{"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY
{"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY
// super

View File

@ -1608,10 +1608,12 @@ typedef enum state
S_FANG_PINCHPATHINGSTART1,
S_FANG_PINCHPATHINGSTART2,
S_FANG_PINCHPATHING,
S_FANG_PINCHBOUNCE0,
S_FANG_PINCHBOUNCE1,
S_FANG_PINCHBOUNCE2,
S_FANG_PINCHBOUNCE3,
S_FANG_PINCHBOUNCE4,
S_FANG_PINCHFALL0,
S_FANG_PINCHFALL1,
S_FANG_PINCHFALL2,
S_FANG_PINCHSKID1,
@ -3498,7 +3500,7 @@ typedef enum state
// Got Flag Sign
S_GOTFLAG,
// Finish flag
S_FINISHFLAG,

View File

@ -2068,7 +2068,7 @@ msgstr ""
#: m_cheat.c:292
#, c-format
msgid "Sissy Mode %s\n"
msgid "Cheese Mode %s\n"
msgstr ""
#: m_cheat.c:315 m_cheat.c:349 m_cheat.c:514 m_cheat.c:538 m_cheat.c:557

View File

@ -2145,7 +2145,7 @@ msgstr ""
#: m_cheat.c:294
#, c-format
msgid "Sissy Mode %s\n"
msgid "Cheese Mode %s\n"
msgstr ""
#: m_cheat.c:314

View File

@ -3103,6 +3103,14 @@ static int lib_gPlatformGametype(lua_State *L)
return 1;
}
static int lib_gCoopGametype(lua_State *L)
{
//HUDSAFE
INLEVEL
lua_pushboolean(L, G_CoopGametype());
return 1;
}
static int lib_gTagGametype(lua_State *L)
{
//HUDSAFE
@ -3386,6 +3394,7 @@ static luaL_Reg lib[] = {
{"G_GametypeHasSpectators",lib_gGametypeHasSpectators},
{"G_RingSlingerGametype",lib_gRingSlingerGametype},
{"G_PlatformGametype",lib_gPlatformGametype},
{"G_CoopGametype",lib_gCoopGametype},
{"G_TagGametype",lib_gTagGametype},
{"G_CompetitionGametype",lib_gCompetitionGametype},
{"G_TicsToHours",lib_gTicsToHours},

View File

@ -58,6 +58,7 @@ enum hook {
hook_SeenPlayer,
hook_PlayerThink,
hook_ShouldJingleContinue,
hook_GameQuit,
hook_MAX // last hook
};
@ -112,3 +113,4 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_
#endif
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
void LUAh_GameQuit(void); // Hook for game quitting

View File

@ -70,6 +70,7 @@ const char *const hookNames[hook_MAX+1] = {
"SeenPlayer",
"PlayerThink",
"ShouldJingleContinue",
"GameQuit",
NULL
};
@ -1769,3 +1770,29 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname)
return keepplaying;
}
// Hook for game quitting
void LUAh_GameQuit(void)
{
hook_p hookp;
if (!gL || !(hooksAvailable[hook_GameQuit/8] & (1<<(hook_GameQuit%8))))
return;
lua_pushcfunction(gL, LUA_GetErrorMessage);
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type != hook_GameQuit)
continue;
PushHook(gL, hookp);
if (lua_pcall(gL, 0, 0, 1)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
}
}
lua_pop(gL, 1); // Pop error handler
}

View File

@ -139,6 +139,7 @@ static const char *const side_opt[] = {
"toptexture",
"bottomtexture",
"midtexture",
"line",
"sector",
"special",
"repeatcnt",
@ -2009,6 +2010,8 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel);
else if (fastcmp(field,"marathonnext"))
lua_pushinteger(L, header->marathonnext);
else if (fastcmp(field,"keywords"))
lua_pushstring(L, header->keywords);
else if (fastcmp(field,"musname"))

View File

@ -86,6 +86,7 @@ enum mobj_e {
mobj_cvmem,
mobj_standingslope,
mobj_colorized,
mobj_mirrored,
mobj_shadowscale
};
@ -152,6 +153,7 @@ static const char *const mobj_opt[] = {
"cvmem",
"standingslope",
"colorized",
"mirrored",
"shadowscale",
NULL};
@ -385,6 +387,9 @@ static int mobj_get(lua_State *L)
case mobj_colorized:
lua_pushboolean(L, mo->colorized);
break;
case mobj_mirrored:
lua_pushboolean(L, mo->mirrored);
break;
case mobj_shadowscale:
lua_pushfixed(L, mo->shadowscale);
break;
@ -713,6 +718,9 @@ static int mobj_set(lua_State *L)
case mobj_colorized:
mo->colorized = luaL_checkboolean(L, 3);
break;
case mobj_mirrored:
mo->mirrored = luaL_checkboolean(L, 3);
break;
case mobj_shadowscale:
mo->shadowscale = luaL_checkfixed(L, 3);
break;

View File

@ -167,7 +167,10 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushboolean(L, splitscreen);
return 1;
} else if (fastcmp(word,"gamecomplete")) {
lua_pushboolean(L, gamecomplete);
lua_pushboolean(L, (gamecomplete != 0));
return 1;
} else if (fastcmp(word,"marathonmode")) {
lua_pushinteger(L, marathonmode);
return 1;
} else if (fastcmp(word,"devparm")) {
lua_pushboolean(L, devparm);
@ -197,6 +200,9 @@ int LUA_PushGlobals(lua_State *L, const char *word)
} else if (fastcmp(word,"spstage_start")) {
lua_pushinteger(L, spstage_start);
return 1;
} else if (fastcmp(word,"spmarathon_start")) {
lua_pushinteger(L, spmarathon_start);
return 1;
} else if (fastcmp(word,"sstage_start")) {
lua_pushinteger(L, sstage_start);
return 1;
@ -320,6 +326,12 @@ int LUA_PushGlobals(lua_State *L, const char *word)
return 0;
LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER);
return 1;
} else if (fastcmp(word,"isserver")) {
lua_pushboolean(L, server);
return 1;
} else if (fastcmp(word,"isdedicatedserver")) {
lua_pushboolean(L, dedicated);
return 1;
// end local player variables
} else if (fastcmp(word,"server")) {
if ((!multiplayer || !netgame) && !playeringame[serverplayer])

View File

@ -288,7 +288,7 @@ void Command_CheatGod_f(void)
plyr = &players[consoleplayer];
plyr->pflags ^= PF_GODMODE;
CONS_Printf(M_GetText("Sissy Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
CONS_Printf(M_GetText("Cheese Mode %s\n"), plyr->pflags & PF_GODMODE ? M_GetText("On") : M_GetText("Off"));
G_SetGameModified(multiplayer);
}

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,9 @@
#include "r_skins.h" // for SKINNAMESIZE
#include "f_finale.h" // for ttmode_enum
// Compatibility with old-style named NiGHTS replay files.
#define OLDNREPLAYNAME
//
// MENUS
//
@ -61,6 +64,8 @@ typedef enum
MN_SP_NIGHTS_REPLAY,
MN_SP_NIGHTS_GHOST,
MN_SP_MARATHON,
// Multiplayer
MN_MP_MAIN,
MN_MP_SPLITSCREEN, // SplitServer
@ -92,8 +97,6 @@ typedef enum
MN_OP_COLOR,
MN_OP_OPENGL,
MN_OP_OPENGL_LIGHTING,
MN_OP_OPENGL_FOG,
MN_OP_OPENGL_COLOR,
MN_OP_SOUND,
@ -419,6 +422,7 @@ extern INT16 char_on, startchar;
#define MAXSAVEGAMES 31
#define NOSAVESLOT 0 //slot where Play Without Saving appears
#define MARATHONSLOT 420 // just has to be nonzero, but let's use one that'll show up as an obvious error if something goes wrong while not using our existing saves
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he

View File

@ -4950,7 +4950,7 @@ void A_ThrownRing(mobj_t *actor)
continue;
// Don't home in on teammates.
if ((gametyperules & GTR_TEAMFLAGS)
if ((gametyperules & GTR_TEAMS)
&& actor->target->player->ctfteam == player->ctfteam)
continue;
}
@ -5106,9 +5106,11 @@ void A_SignPlayer(mobj_t *actor)
INT32 locvar2 = var2;
skin_t *skin = NULL;
mobj_t *ov;
UINT16 facecolor, signcolor = (UINT16)locvar2;
UINT16 facecolor, signcolor = 0;
UINT32 signframe = states[actor->info->raisestate].frame;
facecolor = signcolor = (UINT16)locvar2;
if (LUA_CallAction("A_SignPlayer", actor))
return;
@ -5140,12 +5142,10 @@ void A_SignPlayer(mobj_t *actor)
;
else if (!skin->sprites[SPR2_SIGN].numframes)
signcolor = facecolor;
else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
else if ((facecolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
signcolor = skin->prefoppositecolor;
else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor.
signcolor = skincolors[actor->target->player->skincolor].invcolor;
else
signcolor = SKINCOLOR_NONE;
else if (facecolor) // Set the sign to be an appropriate background color for this player's skincolor.
signcolor = skincolors[facecolor].invcolor;
}
else if (locvar1 != -3) // set to a defined skin
{
@ -5209,6 +5209,7 @@ void A_SignPlayer(mobj_t *actor)
P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN
if (!signcolor)
signcolor = SKINCOLOR_CARBON;
facecolor = signcolor;
}
actor->tracer->color = signcolor;
@ -6522,7 +6523,7 @@ void A_OldRingExplode(mobj_t *actor) {
if (changecolor)
{
if (!(gametyperules & GTR_TEAMFLAGS))
if (!(gametyperules & GTR_TEAMS))
mo->color = actor->target->color; //copy color
else if (actor->target->player->ctfteam == 2)
mo->color = skincolor_bluering;
@ -6538,7 +6539,7 @@ void A_OldRingExplode(mobj_t *actor) {
if (changecolor)
{
if (!(gametyperules & GTR_TEAMFLAGS))
if (!(gametyperules & GTR_TEAMS))
mo->color = actor->target->color; //copy color
else if (actor->target->player->ctfteam == 2)
mo->color = skincolor_bluering;
@ -6553,7 +6554,7 @@ void A_OldRingExplode(mobj_t *actor) {
if (changecolor)
{
if (!(gametyperules & GTR_TEAMFLAGS))
if (!(gametyperules & GTR_TEAMS))
mo->color = actor->target->color; //copy color
else if (actor->target->player->ctfteam == 2)
mo->color = skincolor_bluering;

View File

@ -2278,7 +2278,7 @@ void P_CheckSurvivors(void)
if (!taggers) //If there are no taggers, pick a survivor at random to be it.
{
// Exception for hide and seek. If a round has started and the IT player leaves, end the round.
if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE)))
if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE)))
{
CONS_Printf(M_GetText("The IT player has left the game.\n"));
if (server)
@ -2516,7 +2516,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
}
P_RestoreMusic(target->player);
if (gametype != GT_COOP)
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
@ -2594,7 +2594,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
// allow them to try again, rather than sitting the whole thing out.
if (leveltime >= hidetime * TICRATE)
{
if (gametype == GT_TAG)//suiciding in survivor makes you IT.
if (!(gametyperules & GTR_HIDEFROZEN))//suiciding in survivor makes you IT.
{
target->player->pflags |= PF_TAGIT;
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it!
@ -3088,7 +3088,7 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
P_AddPlayerScore(source->player, 100); //award points to tagger.
P_HitDeathMessages(player, inflictor, source, 0);
if (gametype == GT_TAG) //survivor
if (!(gametyperules & GTR_HIDEFROZEN)) //survivor
{
player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors.
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it!
@ -3149,7 +3149,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
{
if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
if ((gametyperules & GTR_FRIENDLY) && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
{
if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
{
@ -3248,7 +3248,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
}
// If the player was super, tell them he/she ain't so super nomore.
if (gametype != GT_COOP && player->powers[pw_super])
if (!G_CoopGametype() && player->powers[pw_super])
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
@ -3610,7 +3610,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (source == target)
return false; // Don't hit yourself with your own paraloop, baka
if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE))
&& (gametype == GT_COOP
&& ((gametyperules & GTR_FRIENDLY)
|| (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam)))
return false; // Don't run eachother over in special stages and team games and such
}

View File

@ -1588,7 +1588,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
// Force solid players in hide and seek to avoid corner stacking.
if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
if (cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN))
{
if (tmthing->player && thing->player)
{

View File

@ -9206,10 +9206,11 @@ static void P_DragonbomberThink(mobj_t *mobj)
mobj->angle += DRAGONTURNSPEED;
else
{
boolean flip = mobj->spawnpoint->options & MTF_OBJECTFLIP;
fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale);
fixed_t x = mobj->spawnpoint->x << FRACBITS;
fixed_t y = mobj->spawnpoint->y << FRACBITS;
fixed_t z = mobj->spawnpoint->z << FRACBITS;
fixed_t z = (flip ? P_GetSectorCeilingZAt : P_GetSectorFloorZAt)(R_PointInSubsector(x, y)->sector, x, y) + (flip ? -1 : 1)*(mobj->spawnpoint->z << FRACBITS);
angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle;
if (diff > ANGLE_180)
mobj->angle -= DRAGONTURNSPEED;
@ -11309,7 +11310,7 @@ void P_SpawnPlayer(INT32 playernum)
if (!G_GametypeHasSpectators())
{
p->spectator = p->outofcoop =
(((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop
(((multiplayer || netgame) && G_CoopGametype()) // only question status in coop
&& ((leveltime > 0
&& ((G_IsSpecialStage(gamemap)) // late join special stage
|| (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop
@ -11768,7 +11769,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
case MT_EMERALD5:
case MT_EMERALD6:
case MT_EMERALD7:
if (gametype != GT_COOP) // Don't place emeralds in non-coop modes
if (!G_CoopGametype()) // Don't place emeralds in non-coop modes
return false;
if (metalrecording)
@ -11788,7 +11789,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
runemeraldmanager = true;
break;
case MT_ROSY:
if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA)))
if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA)))
return false; // she doesn't hang out here
if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3)
@ -11903,7 +11904,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i)
}
}
// Set powerup boxes to user settings for other netplay modes
else if (gametype != GT_COOP)
else if (!G_CoopGametype())
{
switch (cv_matchboxes.value)
{

View File

@ -373,6 +373,7 @@ typedef struct mobj_s
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
boolean colorized; // Whether the mobj uses the rainbow colormap
boolean mirrored; // The object's rotations will be mirrored left to right, e.g., see frame AL from the right and AR from the left
fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
// WARNING: New fields must be added separately to savegame and Lua.

View File

@ -1159,7 +1159,8 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
if (turnthings == 2 || (turnthings == 1 && !mo->player)) {
mo->angle += delta;
P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta);
if (mo->player)
P_SetPlayerAngle(mo->player, (angle_t)(mo->player->angleturn << 16) + delta);
}
}
}

View File

@ -64,8 +64,10 @@
#define FF_FULLBRIGHT 0x00100000
/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity)
#define FF_VERTICALFLIP 0x00200000
/// \brief Frame flags: Flip sprite horizontally
#define FF_HORIZONTALFLIP 0x00400000
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x00400000
#define FF_PAPERSPRITE 0x00800000
/// \brief Frame flags - Animate: Simple stateless animation
#define FF_ANIMATE 0x01000000

View File

@ -1294,8 +1294,9 @@ typedef enum
MD2_CEILINGROVER = 1<<10,
MD2_SLOPE = 1<<11,
MD2_COLORIZED = 1<<12,
MD2_ROLLANGLE = 1<<13,
MD2_SHADOWSCALE = 1<<14,
MD2_MIRRORED = 1<<13,
MD2_ROLLANGLE = 1<<14,
MD2_SHADOWSCALE = 1<<15,
} mobj_diff2_t;
typedef enum
@ -1500,6 +1501,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SLOPE;
if (mobj->colorized)
diff2 |= MD2_COLORIZED;
if (mobj->mirrored)
diff2 |= MD2_MIRRORED;
if (mobj->rollangle)
diff2 |= MD2_ROLLANGLE;
if (mobj->shadowscale)
@ -1638,6 +1641,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT16(save_p, mobj->standingslope->id);
if (diff2 & MD2_COLORIZED)
WRITEUINT8(save_p, mobj->colorized);
if (diff2 & MD2_MIRRORED)
WRITEUINT8(save_p, mobj->mirrored);
if (diff2 & MD2_ROLLANGLE)
WRITEANGLE(save_p, mobj->rollangle);
if (diff2 & MD2_SHADOWSCALE)
@ -2641,6 +2646,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->standingslope = P_SlopeById(READUINT16(save_p));
if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p);
if (diff2 & MD2_MIRRORED)
mobj->mirrored = READUINT8(save_p);
if (diff2 & MD2_ROLLANGLE)
mobj->rollangle = READANGLE(save_p);
if (diff2 & MD2_SHADOWSCALE)
@ -3785,16 +3792,15 @@ static void P_NetUnArchiveSpecials(void)
// =======================================================================
// Misc
// =======================================================================
static inline void P_ArchiveMisc(void)
static inline void P_ArchiveMisc(INT16 mapnum)
{
//lastmapsaved = mapnum;
lastmaploaded = mapnum;
if (gamecomplete)
WRITEINT16(save_p, gamemap | 8192);
else
WRITEINT16(save_p, gamemap);
//lastmapsaved = gamemap;
lastmaploaded = gamemap;
mapnum |= 8192;
WRITEINT16(save_p, mapnum);
WRITEUINT16(save_p, emeralds+357);
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
}
@ -3808,10 +3814,10 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
if (mapoverride != 0)
{
gamemap = mapoverride;
gamecomplete = true;
gamecomplete = 1;
}
else
gamecomplete = false;
gamecomplete = 0;
// gamemap changed; we assume that its map header is always valid,
// so make it so
@ -4035,9 +4041,9 @@ static inline boolean P_UnArchiveLuabanksAndConsistency(void)
return true;
}
void P_SaveGame(void)
void P_SaveGame(INT16 mapnum)
{
P_ArchiveMisc();
P_ArchiveMisc(mapnum);
P_ArchivePlayer();
P_ArchiveLuabanksAndConsistency();
}

View File

@ -21,7 +21,7 @@
// Persistent storage/archiving.
// These are the load / save game routines.
void P_SaveGame(void);
void P_SaveGame(INT16 mapnum);
void P_SaveNetGame(void);
boolean P_LoadGame(INT16 mapoverride);
boolean P_LoadNetGame(void);

View File

@ -344,6 +344,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->actnum = 0;
mapheaderinfo[num]->typeoflevel = 0;
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
mapheaderinfo[num]->marathonnext = 0;
mapheaderinfo[num]->startrings = 0;
mapheaderinfo[num]->sstimer = 90;
mapheaderinfo[num]->ssspheres = 1;
@ -3156,6 +3157,7 @@ static void P_LoadNightsGhosts(void)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
char *gpath = malloc(glen);
INT32 i;
if (!gpath)
return;
@ -3163,16 +3165,43 @@ static void P_LoadNightsGhosts(void)
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
// Best Score ghost
if (cv_ghost_bestscore.value && FIL_FileExists(va("%s-score-best.lmp", gpath)))
G_AddGhost(va("%s-score-best.lmp", gpath));
if (cv_ghost_bestscore.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_bestscore.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-score-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-score-best.lmp", gpath, skins[i].name));
}
}
// Best Time ghost
if (cv_ghost_besttime.value && FIL_FileExists(va("%s-time-best.lmp", gpath)))
G_AddGhost(va("%s-time-best.lmp", gpath));
if (cv_ghost_besttime.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_besttime.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-time-best.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-time-best.lmp", gpath, skins[i].name));
}
}
// Last ghost
if (cv_ghost_last.value && FIL_FileExists(va("%s-last.lmp", gpath)))
G_AddGhost(va("%s-last.lmp", gpath));
if (cv_ghost_last.value)
{
for (i = 0; i < numskins; ++i)
{
if (cv_ghost_last.value == 1 && players[consoleplayer].skin != i)
continue;
if (FIL_FileExists(va("%s-%s-last.lmp", gpath, skins[i].name)))
G_AddGhost(va("%s-%s-last.lmp", gpath, skins[i].name));
}
}
// Guest ghost
if (cv_ghost_guest.value && FIL_FileExists(va("%s-guest.lmp", gpath)))
@ -3296,21 +3325,6 @@ static void P_InitCamera(void)
}
}
static boolean CanSaveLevel(INT32 mapnum)
{
if (ultimatemode) // never save in ultimate (probably redundant with cursaveslot also being checked)
return false;
if (G_IsSpecialStage(mapnum) // don't save in special stages
|| mapnum == lastmaploaded) // don't save if the last map loaded was this one
return false;
// Any levels that have the savegame flag can save normally.
// If the game is complete for this save slot, then any level can save!
// On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP!
return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || gamecomplete || !lastmaploaded);
}
static void P_RunSpecialStageWipe(void)
{
tic_t starttime = I_GetTime();
@ -3473,7 +3487,7 @@ static void P_InitGametype(void)
if (G_TagGametype())
P_InitTagGametype();
else if (gametype == GT_RACE && server)
else if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && server)
CV_StealthSetValue(&cv_numlaps,
(cv_basenumlaps.value)
? cv_basenumlaps.value
@ -3747,11 +3761,19 @@ boolean P_LoadLevel(boolean fromnetsave)
P_RunCachedActions();
if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0)
&& (!modifiedgame || savemoddata) && cursaveslot > 0 && CanSaveLevel(gamemap))
G_SaveGame((UINT32)cursaveslot);
lastmaploaded = gamemap; // HAS to be set after saving!!
// Took me 3 hours to figure out why my progression kept on getting overwritten with the titlemap...
if (!titlemapinaction)
{
if (!lastmaploaded) // Start a new game?
{
// I'd love to do this in the menu code instead of here, but everything's a mess and I can't guarantee saving proper player struct info before the first act's started. You could probably refactor it, but it'd be a lot of effort. Easier to just work off known good code. ~toast 22/06/2020
if (!(ultimatemode || netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking)
&& (!modifiedgame || savemoddata) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot, gamemap);
// If you're looking for saving sp file progression (distinct from G_SaveGameOver), check G_DoCompleted.
}
lastmaploaded = gamemap; // HAS to be set after saving!!
}
if (!fromnetsave) // uglier hack
{ // to make a newly loaded level start on the second frame.

View File

@ -4078,7 +4078,7 @@ void P_SetupSignExit(player_t *player)
if (!numfound
&& !(player->mo->target && player->mo->target->type == MT_SIGN)
&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
&& !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value))
P_SetTarget(&player->mo->target, thing);
if (thing->state != &states[thing->info->spawnstate])
@ -4109,7 +4109,7 @@ void P_SetupSignExit(player_t *player)
if (!numfound
&& !(player->mo->target && player->mo->target->type == MT_SIGN)
&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
&& !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value))
P_SetTarget(&player->mo->target, thing);
if (thing->state != &states[thing->info->spawnstate])
@ -4465,7 +4465,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
continue;
if (players[i].bot)
continue;
if (gametype == GT_COOP && players[i].lives <= 0)
if (G_CoopGametype() && players[i].lives <= 0)
continue;
if (roversector)
{
@ -4691,7 +4691,7 @@ DoneSection2:
// FOF custom exits not to work.
lineindex = P_FindSpecialLineFromTag(2, sector->tag, -1);
if (gametype == GT_COOP && lineindex != -1) // Custom exit!
if (G_CoopGametype() && lineindex != -1) // Custom exit!
{
// Special goodies with the block monsters flag depending on emeralds collected
if ((lines[lineindex].flags & ML_BLOCKMONSTERS) && ALL7EMERALDS(emeralds))
@ -4925,7 +4925,7 @@ DoneSection2:
break;
case 10: // Finish Line
if (gametype == GT_RACE && !player->exiting)
if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && !player->exiting)
{
if (player->starpostnum == numstarposts) // Must have touched all the starposts
{
@ -6240,7 +6240,7 @@ void P_SpawnSpecials(boolean fromnetsave)
switch(GETSECSPECIAL(sector->special, 4))
{
case 10: // Circuit finish line
if (gametype == GT_RACE)
if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)
circuitmap = true;
break;
}

View File

@ -692,7 +692,7 @@ void P_Ticker(boolean run)
if (run)
{
if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0)
if (countdowntimer && G_PlatformGametype() && ((gametyperules & GTR_CAMPAIGN) || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0)
{
countdowntimer = 0;
countdowntimeup = true;
@ -755,6 +755,9 @@ void P_PreTicker(INT32 frames)
postimgtype = postimgtype2 = postimg_none;
if (marathonmode & MA_INGAME)
marathonmode |= MA_INIT;
for (framecnt = 0; framecnt < frames; ++framecnt)
{
P_MapStart();
@ -799,4 +802,7 @@ void P_PreTicker(INT32 frames)
P_MapEnd();
}
if (marathonmode & MA_INGAME)
marathonmode &= ~MA_INIT;
}

View File

@ -1051,7 +1051,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
// Point penalty for hitting a hazard during tag.
// Discourages players from intentionally hurting themselves to avoid being tagged.
if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT)))
if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG)
&& (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT)))
{
if (player->score >= 50)
player->score -= 50;
@ -1351,7 +1352,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
player->powers[pw_sneakers] = 0;
}
if (gametype != GT_COOP)
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
@ -1418,7 +1419,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
}
}
if (gametype == GT_COOP)
if (G_CoopGametype())
return;
}
@ -1437,7 +1438,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
}
// In team match, all awarded points are incremented to the team's running score.
if (gametype == GT_TEAMMATCH)
if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS)
{
if (player->ctfteam == 1)
redscore += amount;
@ -1471,7 +1472,7 @@ void P_StealPlayerScore(player_t *player, UINT32 amount)
if (stolen > 0)
{
// In team match, all stolen points are removed from the enemy team's running score.
if (gametype == GT_TEAMMATCH)
if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS)
{
if (player->ctfteam == 1)
bluescore -= amount;
@ -3624,7 +3625,7 @@ static boolean PIT_CheckSolidsTeeter(mobj_t *thing)
if (thing == teeterer)
return true;
if (thing->player && cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
if (thing->player && cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN))
return true;
blockdist = teeterer->radius + thing->radius;
@ -4236,7 +4237,7 @@ static void P_DoSuperStuff(player_t *player)
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
@ -4286,14 +4287,14 @@ static void P_DoSuperStuff(player_t *player)
G_GhostAddColor(GHC_NORMAL);
}
if (gametype != GT_COOP)
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
if (player->mo->sprite2 & FF_SPR2SUPER)
P_SetPlayerMobjState(player->mo, player->mo->state-states);
// Inform the netgame that the champion has fallen in the heat of battle.
if (gametype != GT_COOP)
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_s3k66); //let all players hear it.
HU_SetCEchoFlags(0);
@ -7909,7 +7910,7 @@ static void P_MovePlayer(player_t *player)
if (player->pflags & PF_TAGIT)
forcestasis = true;
}
else if (gametype == GT_HIDEANDSEEK)
else if (gametyperules & GTR_HIDEFROZEN)
{
if (!(player->pflags & PF_TAGIT))
{
@ -8582,7 +8583,7 @@ static void P_MovePlayer(player_t *player)
}
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none && cv_fovchange.value)
if (rendermode == render_opengl && cv_fovchange.value)
{
fixed_t speed;
const fixed_t runnyspeed = 20*FRACUNIT;
@ -9437,7 +9438,7 @@ static void P_DeathThink(player_t *player)
}
if ((cv_cooplives.value != 1)
&& (gametype == GT_COOP)
&& (G_GametypeUsesCoopLives())
&& (netgame || multiplayer)
&& (player->lives <= 0))
{
@ -9519,17 +9520,17 @@ static void P_DeathThink(player_t *player)
countdown2 = 1*TICRATE;
}
}
//else if (gametype == GT_COOP) -- moved to G_DoReborn
//else if (G_CoopGametype()) -- moved to G_DoReborn
}
if (gametype == GT_COOP && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))))
if (G_CoopGametype() && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))))
{
//player->spectator = true;
player->outofcoop = true;
player->playerstate = PST_REBORN;
}
if ((gametyperules & GTR_RACE) || (gametype == GT_COOP && (multiplayer || netgame)))
if ((gametyperules & GTR_RACE) || (G_CoopGametype() && (multiplayer || netgame)))
{
// Keep time rolling in race mode
if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock)
@ -9546,7 +9547,7 @@ static void P_DeathThink(player_t *player)
}
// Return to level music
if (gametype != GT_COOP && player->lives <= 0 && player->deadtimer == gameovertics)
if (!G_CoopGametype() && player->lives <= 0 && player->deadtimer == gameovertics)
P_RestoreMultiMusic(player);
}
@ -9723,7 +9724,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (player->exiting)
{
if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint
&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)
&& !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)
&& !(twodlevel || (mo->flags2 & MF2_TWOD)))
sign = mo->target;
else if ((player->powers[pw_carry] == CR_NIGHTSMODE)
@ -9992,9 +9993,11 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (camorbit) //Sev here, I'm guessing this is where orbital cam lives
{
if (rendermode == render_opengl)
#ifdef HWRENDER
if (rendermode == render_opengl && !cv_grshearing.value)
distxy = FixedMul(dist, FINECOSINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK));
else
#endif
distxy = dist;
distz = -FixedMul(dist, FINESINE((focusaiming>>ANGLETOFINESHIFT) & FINEMASK)) + slopez;
}
@ -10390,7 +10393,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
boolean P_SpectatorJoinGame(player_t *player)
{
if (gametype != GT_COOP && !cv_allowteamchange.value)
if (!G_CoopGametype() && !cv_allowteamchange.value)
{
if (P_IsLocalPlayer(player))
CONS_Printf(M_GetText("Server does not allow team change.\n"));
@ -10472,7 +10475,7 @@ boolean P_SpectatorJoinGame(player_t *player)
player->spectator = player->outofcoop = false;
player->playerstate = PST_REBORN;
if (gametype == GT_TAG)
if ((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG)
{
//Make joining players "it" after hidetime.
if (leveltime > (hidetime * TICRATE))
@ -10493,7 +10496,7 @@ boolean P_SpectatorJoinGame(player_t *player)
displayplayer = consoleplayer;
}
if (gametype != GT_COOP)
if (!G_CoopGametype())
CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]);
return true; // no more player->mo, cannot continue.
}
@ -11520,7 +11523,7 @@ void P_PlayerThink(player_t *player)
// so we can fade music
if (!exitfadestarted &&
player->exiting > 0 && player->exiting <= 1*TICRATE &&
(!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) &&
(!multiplayer || G_CoopGametype() ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) &&
// don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop
((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout
player->lives > 0 && // don't fade on game over (competition)
@ -11593,7 +11596,7 @@ void P_PlayerThink(player_t *player)
if (player->pflags & PF_FINISHED)
{
if ((gametype == GT_COOP && cv_exitmove.value) && !G_EnoughPlayersFinished())
if (((gametyperules & GTR_FRIENDLY) && cv_exitmove.value) && !G_EnoughPlayersFinished())
player->exiting = 0;
else
P_DoPlayerExit(player);
@ -11627,10 +11630,10 @@ void P_PlayerThink(player_t *player)
// Make sure spectators always have a score and ring count of 0.
if (player->spectator)
{
if (gametype != GT_COOP)
if (!(gametyperules & GTR_CAMPAIGN))
player->score = 0;
}
else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP)
else if ((netgame || multiplayer) && player->lives <= 0 && !G_CoopGametype())
{
// Outside of Co-Op, replenish a user's lives if they are depleted.
// of course, this is just a cheap hack, meh...
@ -12494,7 +12497,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->momz = tails->momz;
}
if (gametype == GT_COOP && (!tails->player || tails->player->bot != 1))
if (G_CoopGametype() && (!tails->player || tails->player->bot != 1))
{
player->mo->angle = tails->angle;

View File

@ -798,6 +798,9 @@ static void R_AddPolyObjects(subsector_t *sub)
po = (polyobj_t *)(po->link.next);
}
// for render stats
rs_numpolyobjects += numpolys;
// sort polyobjects
R_SortPolyObjects(sub);
@ -1235,6 +1238,9 @@ void R_RenderBSPNode(INT32 bspnum)
{
node_t *bsp;
INT32 side;
rs_numbspcalls++;
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
{
bsp = &nodes[bspnum];

View File

@ -242,9 +242,10 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
fullalpha = 0xFF;
alpha = (UINT8)fullalpha;
// if the background pixel is empty, match software and don't blend anything
// if the background pixel is empty,
// match software and don't blend anything
if (!background.s.alpha)
output.rgba = 0;
output.s.alpha = 0;
else
{
UINT8 beta = (0xFF - alpha);

View File

@ -33,6 +33,8 @@
#include "z_zone.h"
#include "m_random.h" // quake camera shake
#include "r_portal.h"
#include "r_main.h"
#include "i_system.h" // I_GetTimeMicros
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -97,6 +99,22 @@ lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
// Hack to support extra boom colormaps.
extracolormap_t *extra_colormaps = NULL;
// Render stats
int rs_prevframetime = 0;
int rs_rendercalltime = 0;
int rs_swaptime = 0;
int rs_bsptime = 0;
int rs_sw_portaltime = 0;
int rs_sw_planetime = 0;
int rs_sw_maskedtime = 0;
int rs_numbspcalls = 0;
int rs_numsprites = 0;
int rs_numdrawnodes = 0;
int rs_numpolyobjects = 0;
static CV_PossibleValue_t drawdist_cons_t[] = {
{256, "256"}, {512, "512"}, {768, "768"},
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
@ -147,6 +165,8 @@ consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL,
consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_renderstats = {"renderstats", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void SplitScreen_OnChange(void)
{
if (!cv_debug && netgame)
@ -900,11 +920,6 @@ void R_ExecuteSetViewSize(void)
R_InitTextureMapping();
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_InitTextureMapping();
#endif
// thing clipping
for (i = 0; i < viewwidth; i++)
screenheightarray[i] = (INT16)viewheight;
@ -1038,29 +1053,34 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y)
// R_SetupFrame
//
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) ((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)/fovtan)
// recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight).
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
static void R_SetupFreelook(void)
{
INT32 dy = 0;
// clip it in the case we are looking a hardware 90 degrees full aiming
// (lmps, network and use F12...)
if (rendermode == render_soft
#ifdef HWRENDER
|| cv_grshearing.value
#endif
)
{
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
}
if (rendermode == render_soft)
{
// clip it in the case we are looking a hardware 90 degrees full aiming
// (lmps, network and use F12...)
G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH;
dy = (AIMINGTODY(aimingangle)>>FRACBITS) * viewwidth/BASEVIDWIDTH;
yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)];
}
centery = (viewheight/2) + dy;
centeryfrac = centery<<FRACBITS;
}
#undef AIMINGTODY
void R_SetupFrame(player_t *player)
{
camera_t *thiscam;
@ -1305,6 +1325,38 @@ void R_SkyboxFrame(player_t *player)
R_SetupFreelook();
}
boolean R_ViewpointHasChasecam(player_t *player)
{
boolean chasecam = false;
if (splitscreen && player == &players[secondarydisplayplayer] && player != &players[consoleplayer])
chasecam = (cv_chasecam2.value != 0);
else
chasecam = (cv_chasecam.value != 0);
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
chasecam = true; // force chasecam on
else if (player->spectator) // no spectator chasecam
chasecam = false; // force chasecam off
return chasecam;
}
boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox)
{
boolean chasecam = R_ViewpointHasChasecam(player);
// cut-away view stuff
if (player->awayviewtics || skybox)
return chasecam;
// use outside cam view
else if (!player->spectator && chasecam)
return true;
// use the player's eyes view
return false;
}
static void R_PortalFrame(portal_t *portal)
{
viewx = portal->viewx;
@ -1410,7 +1462,11 @@ void R_RenderPlayerView(player_t *player)
mytotal = 0;
ProfZeroTimer();
#endif
rs_numbspcalls = rs_numpolyobjects = rs_numdrawnodes = 0;
rs_bsptime = I_GetTimeMicros();
R_RenderBSPNode((INT32)numnodes - 1);
rs_bsptime = I_GetTimeMicros() - rs_bsptime;
rs_numsprites = visspritecount;
#ifdef TIMING
RDMSR(0x10, &mycount);
mytotal += mycount; // 64bit add
@ -1428,6 +1484,7 @@ void R_RenderPlayerView(player_t *player)
Portal_AddSkyboxPortals();
// Portal rendering. Hijacks the BSP traversal.
rs_sw_portaltime = I_GetTimeMicros();
if (portal_base)
{
portal_t *portal;
@ -1467,15 +1524,20 @@ void R_RenderPlayerView(player_t *player)
Portal_Remove(portal);
}
}
rs_sw_portaltime = I_GetTimeMicros() - rs_sw_portaltime;
rs_sw_planetime = I_GetTimeMicros();
R_DrawPlanes();
#ifdef FLOORSPLATS
R_DrawVisibleFloorSplats();
#endif
rs_sw_planetime = I_GetTimeMicros() - rs_sw_planetime;
// draw mid texture and sprite
// And now 3D floors/sides!
rs_sw_maskedtime = I_GetTimeMicros();
R_DrawMasked(masks, nummasks);
rs_sw_maskedtime = I_GetTimeMicros() - rs_sw_maskedtime;
free(masks);
}

View File

@ -26,7 +26,10 @@ extern INT32 centerx, centery;
extern fixed_t centerxfrac, centeryfrac;
extern fixed_t projection, projectiony;
extern fixed_t fovtan; // field of view
extern fixed_t fovtan;
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160), fovtan)
extern size_t validcount, linecount, loopcount, framecount;
@ -71,6 +74,25 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y);
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
// Render stats
extern consvar_t cv_renderstats;
extern int rs_prevframetime;// time when previous frame was rendered
extern int rs_rendercalltime;
extern int rs_swaptime;
extern int rs_bsptime;
extern int rs_sw_portaltime;
extern int rs_sw_planetime;
extern int rs_sw_maskedtime;
extern int rs_numbspcalls;
extern int rs_numsprites;
extern int rs_numdrawnodes;
extern int rs_numpolyobjects;
//
// REFRESH - the actual rendering functions.
//
@ -104,10 +126,13 @@ void R_SetViewSize(void);
// do it (sometimes explicitly called)
void R_ExecuteSetViewSize(void);
void R_SetupFrame(player_t *player);
void R_SkyboxFrame(player_t *player);
void R_SetupFrame(player_t *player);
// Called by G_Drawer.
boolean R_ViewpointHasChasecam(player_t *player);
boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox);
// Called by D_Display.
void R_RenderPlayerView(player_t *player);
// add commands related to engine, at game startup

View File

@ -1367,6 +1367,8 @@ static void R_ProjectSprite(mobj_t *thing)
size_t frame, rot;
UINT16 flip;
boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP));
boolean mirrored = thing->mirrored;
boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
INT32 lindex;
@ -1477,7 +1479,11 @@ static void R_ProjectSprite(mobj_t *thing)
#endif
if (sprframe->rotate != SRF_SINGLE || papersprite)
{
ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle);
if (mirrored)
ang = InvAngle(ang);
}
if (sprframe->rotate == SRF_SINGLE)
{
@ -1537,6 +1543,8 @@ static void R_ProjectSprite(mobj_t *thing)
}
#endif
flip = !flip != !hflip;
// calculate edges of the shape
if (flip)
offset = spr_offset - spr_width;
@ -2505,6 +2513,8 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link)
node->thickseg = NULL;
node->ffloor = NULL;
node->sprite = NULL;
rs_numdrawnodes++;
return node;
}

View File

@ -622,3 +622,51 @@ void SCR_ClosedCaptions(void)
va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name)));
}
}
void SCR_DisplayMarathonInfo(void)
{
INT32 flags = V_SNAPTOBOTTOM;
static tic_t entertic, oldentertics = 0, antisplice[2] = {48,0};
const char *str;
#if 0 // eh, this probably isn't going to be a problem
if (((signed)marathontime) < 0)
{
flags |= V_REDMAP;
str = "No waiting out the clock to submit a bogus time.";
}
else
#endif
{
entertic = I_GetTime();
if (gamecomplete)
flags |= V_YELLOWMAP;
else if (marathonmode & MA_INGAME)
; // see also G_Ticker
else if (marathonmode & MA_INIT)
marathonmode &= ~MA_INIT;
else
marathontime += entertic - oldentertics;
// Create a sequence of primes such that their LCM is nice and big.
#define PRIMEV1 13
#define PRIMEV2 17 // I can't believe it! I'm on TV!
antisplice[0] += (entertic - oldentertics)*PRIMEV2;
antisplice[0] %= PRIMEV1*((vid.width/vid.dupx)+1);
antisplice[1] += (entertic - oldentertics)*PRIMEV1;
antisplice[1] %= PRIMEV1*((vid.width/vid.dupx)+1);
str = va("%i:%02i:%02i.%02i",
G_TicsToHours(marathontime),
G_TicsToMinutes(marathontime, false),
G_TicsToSeconds(marathontime),
G_TicsToCentiseconds(marathontime));
oldentertics = entertic;
}
V_DrawFill((antisplice[0]/PRIMEV1)-1, BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawFill((antisplice[0]/PRIMEV1), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTOLEFT|31);
V_DrawFill(BASEVIDWIDTH-((antisplice[1]/PRIMEV1)-1), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT);
V_DrawFill(BASEVIDWIDTH-((antisplice[1]/PRIMEV1)), BASEVIDHEIGHT-8, 1, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT|31);
#undef PRIMEV1
#undef PRIMEV2
V_DrawPromptBack(-8, cons_backcolor.value);
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-8, flags, str);
}

View File

@ -206,5 +206,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
void SCR_DisplayTicRate(void);
void SCR_ClosedCaptions(void);
void SCR_DisplayLocalPing(void);
void SCR_DisplayMarathonInfo(void);
#undef DNWH
#endif //__SCREEN_H__

View File

@ -220,6 +220,7 @@
<ClInclude Include="..\hardware\hw3dsdrv.h" />
<ClInclude Include="..\hardware\hw3sound.h" />
<ClInclude Include="..\hardware\hws_data.h" />
<ClInclude Include="..\hardware\hw_batching.h" />
<ClInclude Include="..\hardware\hw_clip.h" />
<ClInclude Include="..\hardware\hw_data.h" />
<ClInclude Include="..\hardware\hw_defs.h" />
@ -370,6 +371,7 @@
<ClCompile Include="..\g_game.c" />
<ClCompile Include="..\g_input.c" />
<ClCompile Include="..\hardware\hw3sound.c" />
<ClCompile Include="..\hardware\hw_batching.c" />
<ClCompile Include="..\hardware\hw_bsp.c" />
<ClCompile Include="..\hardware\hw_cache.c" />
<ClCompile Include="..\hardware\hw_clip.c" />

View File

@ -219,6 +219,9 @@
<ClInclude Include="..\hardware\hws_data.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_batching.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_clip.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
@ -636,6 +639,9 @@
<ClCompile Include="..\hardware\hw3sound.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_batching.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_bsp.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>

View File

@ -75,14 +75,17 @@ void *hwSym(const char *funcName,void *handle)
void *funcPointer = NULL;
#ifdef HWRENDER
if (0 == strcmp("SetPalette", funcName))
funcPointer = &OglSdlSetPalette;
funcPointer = &OglSdlSetPalette;
GETFUNC(Init);
GETFUNC(Draw2DLine);
GETFUNC(DrawPolygon);
GETFUNC(DrawIndexedTriangles);
GETFUNC(RenderSkyDome);
GETFUNC(SetBlend);
GETFUNC(ClearBuffer);
GETFUNC(SetTexture);
GETFUNC(UpdateTexture);
GETFUNC(ReadRect);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);
@ -91,7 +94,6 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(DrawModel);
GETFUNC(CreateModelVBOs);
GETFUNC(SetTransform);
GETFUNC(GetRenderVersion);
GETFUNC(PostImgRedraw);
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe);
@ -101,6 +103,16 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(MakeScreenTexture);
GETFUNC(MakeScreenFinalTexture);
GETFUNC(DrawScreenFinalTexture);
GETFUNC(LoadShaders);
GETFUNC(KillShaders);
GETFUNC(SetShader);
GETFUNC(UnSetShader);
GETFUNC(SetShaderInfo);
GETFUNC(LoadCustomShader);
GETFUNC(InitCustomShaders);
#else //HWRENDER
if (0 == strcmp("FinishUpdate", funcName))
return funcPointer; //&FinishUpdate;

View File

@ -54,6 +54,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include <fcntl.h>
#endif
#if defined (_WIN32)
DWORD TimeFunction(int requested_frequency);
#else
int TimeFunction(int requested_frequency);
#endif
#include <stdio.h>
#ifdef _WIN32
#include <conio.h>
@ -2063,9 +2069,11 @@ static p_timeGetTime pfntimeGetTime = NULL;
// but lower precision on Windows NT
// ---------
tic_t I_GetTime(void)
DWORD TimeFunction(int requested_frequency)
{
tic_t newtics = 0;
DWORD newtics = 0;
// this var acts as a multiplier if sub-millisecond precision is asked but is not available
int excess_frequency = requested_frequency / 1000;
if (!starttickcount) // high precision timer
{
@ -2085,7 +2093,7 @@ tic_t I_GetTime(void)
if (frequency.LowPart && QueryPerformanceCounter(&currtime))
{
newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * NEWTICRATE
newtics = (INT32)((currtime.QuadPart - basetime.QuadPart) * requested_frequency
/ frequency.QuadPart);
}
else if (pfntimeGetTime)
@ -2093,11 +2101,19 @@ tic_t I_GetTime(void)
currtime.LowPart = pfntimeGetTime();
if (!basetime.LowPart)
basetime.LowPart = currtime.LowPart;
newtics = ((currtime.LowPart - basetime.LowPart)/(1000/NEWTICRATE));
if (requested_frequency > 1000)
newtics = currtime.LowPart - basetime.LowPart * excess_frequency;
else
newtics = (currtime.LowPart - basetime.LowPart)/(1000/requested_frequency);
}
}
else
newtics = (GetTickCount() - starttickcount)/(1000/NEWTICRATE);
{
if (requested_frequency > 1000)
newtics = (GetTickCount() - starttickcount) * excess_frequency;
else
newtics = (GetTickCount() - starttickcount)/(1000/requested_frequency);
}
return newtics;
}
@ -2119,7 +2135,9 @@ static void I_ShutdownTimer(void)
// I_GetTime
// returns time in 1/TICRATE second tics
//
tic_t I_GetTime (void)
// millisecond precision only
int TimeFunction(int requested_frequency)
{
static Uint64 basetime = 0;
Uint64 ticks = SDL_GetTicks();
@ -2129,14 +2147,24 @@ tic_t I_GetTime (void)
ticks -= basetime;
ticks = (ticks*TICRATE);
ticks = (ticks*requested_frequency);
ticks = (ticks/1000);
return (tic_t)ticks;
return ticks;
}
#endif
tic_t I_GetTime(void)
{
return TimeFunction(NEWTICRATE);
}
int I_GetTimeMicros(void)
{
return TimeFunction(1000000);
}
//
//I_StartupTimer
//

View File

@ -73,6 +73,7 @@
#include "../console.h"
#include "../command.h"
#include "../r_main.h"
#include "../lua_hook.h"
#include "sdlmain.h"
#ifdef HWRENDER
#include "../hardware/hw_main.h"
@ -357,11 +358,7 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN;
default: break;
}
#ifdef HWRENDER
DBG_Printf("Unknown incoming scancode: %d, represented %c\n",
code,
SDL_GetKeyName(SDL_GetKeyFromScancode(code)));
#endif
return 0;
}
@ -1061,8 +1058,9 @@ void I_GetEvent(void)
M_SetupJoystickMenu(0);
break;
case SDL_QUIT:
if (Playing())
LUAh_GameQuit();
I_Quit();
M_QuitResponse('y');
break;
}
}
@ -1204,6 +1202,9 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
if (marathonmode)
SCR_DisplayMarathonInfo();
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
@ -1480,6 +1481,7 @@ void VID_CheckGLLoaded(rendermode_t oldrender)
#ifdef HWRENDER
if (vid_opengl_state == -1) // Well, it didn't work the first time anyway.
{
CONS_Alert(CONS_ERROR, "OpenGL never loaded\n");
rendermode = oldrender;
if (chosenrendermode == render_opengl) // fallback to software
rendermode = render_soft;
@ -1828,10 +1830,12 @@ void VID_StartupOpenGL(void)
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
HWD.pfnDrawIndexedTriangles = hwSym("DrawIndexedTriangles",NULL);
HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL);
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
@ -1841,7 +1845,6 @@ void VID_StartupOpenGL(void)
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
@ -1852,14 +1855,16 @@ void VID_StartupOpenGL(void)
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
{
CONS_Alert(CONS_ERROR, M_GetText("The version of the renderer doesn't match the version of the executable!\nBe sure you have installed SRB2 properly.\n"));
vid_opengl_state = -1;
}
else
vid_opengl_state = HWD.pfnInit(I_Error) ? 1 : -1; // let load the OpenGL library
HWD.pfnLoadShaders = hwSym("LoadShaders",NULL);
HWD.pfnKillShaders = hwSym("KillShaders",NULL);
HWD.pfnSetShader = hwSym("SetShader",NULL);
HWD.pfnUnSetShader = hwSym("UnSetShader",NULL);
HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL);
vid_opengl_state = HWD.pfnInit() ? 1 : -1; // let load the OpenGL library
if (vid_opengl_state == -1)
{

View File

@ -219,6 +219,28 @@ static void var_cleanup(void)
internal_volume = 100;
}
static const char* get_zlib_error(int zErr)
{
switch (zErr)
{
case Z_ERRNO:
return "Z_ERRNO";
case Z_STREAM_ERROR:
return "Z_STREAM_ERROR";
case Z_DATA_ERROR:
return "Z_DATA_ERROR";
case Z_MEM_ERROR:
return "Z_MEM_ERROR";
case Z_BUF_ERROR:
return "Z_BUF_ERROR";
case Z_VERSION_ERROR:
return "Z_VERSION_ERROR";
default:
return "unknown error";
}
}
/// ------------------------
/// Audio System
/// ------------------------
@ -475,7 +497,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
zErr = inflate(&stream, Z_FINISH);
if (zErr == Z_STREAM_END) {
// Run GME on new data
if (!gme_open_data(inflatedData, inflatedLen, &emu, 44100))
if (!gme_open_data(inflatedData, inflatedLen, &emu, SAMPLERATE))
{
short *mem;
UINT32 len;
@ -498,58 +520,18 @@ void *I_GetSfx(sfxinfo_t *sfx)
}
}
else
{
const char *errorType;
switch (zErr)
{
case Z_ERRNO:
errorType = "Z_ERRNO"; break;
case Z_STREAM_ERROR:
errorType = "Z_STREAM_ERROR"; break;
case Z_DATA_ERROR:
errorType = "Z_DATA_ERROR"; break;
case Z_MEM_ERROR:
errorType = "Z_MEM_ERROR"; break;
case Z_BUF_ERROR:
errorType = "Z_BUF_ERROR"; break;
case Z_VERSION_ERROR:
errorType = "Z_VERSION_ERROR"; break;
default:
errorType = "unknown error";
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg);
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg);
(void)inflateEnd(&stream);
}
else // Hold up, zlib's got a problem
{
const char *errorType;
switch (zErr)
{
case Z_ERRNO:
errorType = "Z_ERRNO"; break;
case Z_STREAM_ERROR:
errorType = "Z_STREAM_ERROR"; break;
case Z_DATA_ERROR:
errorType = "Z_DATA_ERROR"; break;
case Z_MEM_ERROR:
errorType = "Z_MEM_ERROR"; break;
case Z_BUF_ERROR:
errorType = "Z_BUF_ERROR"; break;
case Z_VERSION_ERROR:
errorType = "Z_VERSION_ERROR"; break;
default:
errorType = "unknown error";
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg);
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg);
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
#else
return NULL; // No zlib support
#endif
}
// Try to read it as a GME sound
else if (!gme_open_data(lump, sfx->length, &emu, 44100))
else if (!gme_open_data(lump, sfx->length, &emu, SAMPLERATE))
{
short *mem;
UINT32 len;
@ -1175,77 +1157,30 @@ boolean I_LoadSong(char *data, size_t len)
if (zErr == Z_OK) // We're good to go
{
zErr = inflate(&stream, Z_FINISH);
if (zErr == Z_STREAM_END) {
if (zErr == Z_STREAM_END)
{
// Run GME on new data
if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100))
if (!gme_open_data(inflatedData, inflatedLen, &gme, SAMPLERATE))
{
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
gme_start_track(gme, 0);
current_track = 0;
gme_set_equalizer(gme, &eq);
Mix_HookMusic(mix_gme, gme);
Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around
return true;
}
}
else
{
const char *errorType;
switch (zErr)
{
case Z_ERRNO:
errorType = "Z_ERRNO"; break;
case Z_STREAM_ERROR:
errorType = "Z_STREAM_ERROR"; break;
case Z_DATA_ERROR:
errorType = "Z_DATA_ERROR"; break;
case Z_MEM_ERROR:
errorType = "Z_MEM_ERROR"; break;
case Z_BUF_ERROR:
errorType = "Z_BUF_ERROR"; break;
case Z_VERSION_ERROR:
errorType = "Z_VERSION_ERROR"; break;
default:
errorType = "unknown error";
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg);
}
CONS_Alert(CONS_ERROR, "Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg);
(void)inflateEnd(&stream);
}
else // Hold up, zlib's got a problem
{
const char *errorType;
switch (zErr)
{
case Z_ERRNO:
errorType = "Z_ERRNO"; break;
case Z_STREAM_ERROR:
errorType = "Z_STREAM_ERROR"; break;
case Z_DATA_ERROR:
errorType = "Z_DATA_ERROR"; break;
case Z_MEM_ERROR:
errorType = "Z_MEM_ERROR"; break;
case Z_BUF_ERROR:
errorType = "Z_BUF_ERROR"; break;
case Z_VERSION_ERROR:
errorType = "Z_VERSION_ERROR"; break;
default:
errorType = "unknown error";
}
CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg);
}
CONS_Alert(CONS_ERROR, "Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg);
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
return false;
#else
CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
return true;
CONS_Alert(CONS_ERROR, "Cannot decompress VGZ; no zlib support\n");
return false;
#endif
}
else if (!gme_open_data(data, len, &gme, 44100))
{
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
gme_set_equalizer(gme, &eq);
else if (!gme_open_data(data, len, &gme, SAMPLERATE))
return true;
}
#endif
#ifdef HAVE_MIXERX
@ -1360,6 +1295,8 @@ boolean I_PlaySong(boolean looping)
#ifdef HAVE_LIBGME
if (gme)
{
gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0};
gme_set_equalizer(gme, &eq);
gme_start_track(gme, 0);
current_track = 0;
Mix_HookMusic(mix_gme, gme);

View File

@ -37,6 +37,7 @@
#ifdef HWRENDER
#include "../hardware/r_opengl/r_opengl.h"
#include "../hardware/hw_main.h"
#include "ogl_sdl.h"
#include "../i_system.h"
#include "hwsym_sdl.h"
@ -90,15 +91,15 @@ boolean LoadGL(void)
const char *OGLLibname = NULL;
const char *GLULibname = NULL;
if (M_CheckParm ("-OGLlib") && M_IsNextParm())
if (M_CheckParm("-OGLlib") && M_IsNextParm())
OGLLibname = M_GetNextParm();
if (SDL_GL_LoadLibrary(OGLLibname) != 0)
{
CONS_Alert(CONS_ERROR, "Could not load OpenGL Library: %s\n"
"Falling back to Software mode.\n", SDL_GetError());
if (!M_CheckParm ("-OGLlib"))
CONS_Alert(CONS_ERROR, "If you know what is the OpenGL library's name, use -OGLlib\n");
if (!M_CheckParm("-OGLlib"))
CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n");
return 0;
}
@ -118,7 +119,7 @@ boolean LoadGL(void)
GLULibname = NULL;
#endif
if (M_CheckParm ("-GLUlib") && M_IsNextParm())
if (M_CheckParm("-GLUlib") && M_IsNextParm())
GLULibname = M_GetNextParm();
if (GLULibname)
@ -152,31 +153,29 @@ boolean LoadGL(void)
*/
boolean OglSdlSurface(INT32 w, INT32 h)
{
INT32 cbpp;
const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL;
INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
static boolean first_init = false;
cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
glvendor = pglGetString(GL_VENDOR);
// Get info and extensions.
//BP: why don't we make it earlier ?
//Hurdler: we cannot do that before intialising gl context
glrenderer = pglGetString(GL_RENDERER);
glversion = pglGetString(GL_VERSION);
gl_extensions = pglGetString(GL_EXTENSIONS);
DBG_Printf("Vendor : %s\n", glvendor);
DBG_Printf("Renderer : %s\n", glrenderer);
DBG_Printf("Version : %s\n", glversion);
DBG_Printf("Extensions : %s\n", gl_extensions);
oglflags = 0;
if (!first_init)
{
gl_version = pglGetString(GL_VERSION);
gl_renderer = pglGetString(GL_RENDERER);
gl_extensions = pglGetString(GL_EXTENSIONS);
GL_DBG_Printf("OpenGL %s\n", gl_version);
GL_DBG_Printf("GPU: %s\n", gl_renderer);
GL_DBG_Printf("Extensions: %s\n", gl_extensions);
}
first_init = true;
if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions))
pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
else
maximumAnisotropy = 1;
SetupGLFunc13();
SetupGLFunc4();
granisotropicmode_cons_t[1].value = maximumAnisotropy;
@ -222,7 +221,7 @@ void OglSdlFinishUpdate(boolean waitvbl)
HWR_DrawScreenFinalTexture(realwidth, realheight);
}
EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette)
EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette)
{
size_t palsize = (sizeof(RGBA_t) * 256);
// on a palette change, you have to reload all of the textures

View File

@ -763,7 +763,7 @@ static void ST_drawTime(void)
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon, V_HUDTRANS); // Colon
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2, V_HUDTRANS); // Seconds
if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying!
if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking || marathonmode)
{
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod, V_HUDTRANS); // Period
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2, V_HUDTRANS); // Tics
@ -1450,7 +1450,7 @@ static void ST_drawPowerupHUD(void)
// ---------
// Let's have a power-like icon to represent finishing the level!
if (stplyr->pflags & PF_FINISHED && cv_exitmove.value)
if (stplyr->pflags & PF_FINISHED && cv_exitmove.value && multiplayer)
{
finishoffs[q] = ICONSEP;
V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, fnshico);
@ -2215,7 +2215,7 @@ static void ST_drawTextHUD(void)
if (F_GetPromptHideHud(y))
return;
if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE))
if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE))
textHUDdraw(M_GetText("\x86""Spectator mode:"))
if (circuitmap)
@ -2226,7 +2226,7 @@ static void ST_drawTextHUD(void)
textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value))
}
if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
if (!G_CoopGametype() && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
{
if (!splitscreen && !donef12)
{
@ -2243,7 +2243,7 @@ static void ST_drawTextHUD(void)
else
textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn"))
}
else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE))
else if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE))
{
if (!splitscreen && !donef12)
{
@ -2290,7 +2290,7 @@ static void ST_drawTextHUD(void)
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
}
if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED)))
if (G_CoopGametype() && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED)))
{
UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value);
if (numneeded)
@ -2339,20 +2339,19 @@ static void ST_drawTextHUD(void)
textHUDdraw(M_GetText("\x82""You are blindfolded!"))
textHUDdraw(M_GetText("Waiting for players to hide..."))
}
else if (gametype == GT_HIDEANDSEEK)
else if (gametyperules & GTR_HIDEFROZEN)
textHUDdraw(M_GetText("Hide before time runs out!"))
else
textHUDdraw(M_GetText("Flee before you are hunted!"))
}
else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT))
else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT))
{
if (!splitscreen && !donef12)
{
textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view"))
donef12 = true;
}
if (gametyperules & GTR_HIDEFROZEN)
textHUDdraw(M_GetText("You cannot move while hiding."))
textHUDdraw(M_GetText("You cannot move while hiding."))
}
}
@ -2628,11 +2627,11 @@ static void ST_overlayDrawer(void)
}
// GAME OVER hud
if ((gametype == GT_COOP)
if (G_GametypeUsesCoopLives()
&& (netgame || multiplayer)
&& (cv_cooplives.value == 0))
;
else if ((G_GametypeUsesLives() || gametype == GT_RACE) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
else if ((G_GametypeUsesLives() || ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer)))
{
INT32 i = MAXPLAYERS;
INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1));

View File

@ -418,7 +418,7 @@ void V_SetPalette(INT32 palettenum)
LoadMapPalette();
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
HWR_SetPalette(&pLocalPalette[palettenum*256]);
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
@ -432,7 +432,7 @@ void V_SetPaletteLump(const char *pal)
{
LoadPalette(pal);
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
HWR_SetPalette(pLocalPalette);
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
else
@ -529,7 +529,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
#ifdef HWRENDER
//if (rendermode != render_soft && !con_startup) // Why?
if (rendermode != render_soft)
if (rendermode == render_opengl)
{
HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap);
return;
@ -829,7 +829,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
#ifdef HWRENDER
//if (rendermode != render_soft && !con_startup) // Not this again
if (rendermode != render_soft)
if (rendermode == render_opengl)
{
HWR_DrawCroppedPatch((GLPatch_t*)patch,x,y,pscale,scrn,sx,sy,w,h);
return;
@ -1153,7 +1153,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
#ifdef HWRENDER
//if (rendermode != render_soft && !con_startup) // Not this again
if (rendermode != render_soft)
if (rendermode == render_opengl)
{
HWR_DrawFill(x, y, w, h, c);
return;
@ -1350,7 +1350,7 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
return;
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
UINT32 hwcolor = V_GetHWConsBackColor();
HWR_DrawConsoleFill(x, y, w, h, c, hwcolor); // we still use the regular color stuff but only for flags. actual draw color is "hwcolor" for this.
@ -1547,7 +1547,7 @@ void V_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c, UINT16 color, U
return;
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
// ughhhhh please can someone else do this? thanks ~toast 25/7/19 in 38 degrees centigrade w/o AC
HWR_DrawFadeFill(x, y, w, h, c, color, strength); // toast two days later - left above comment in 'cause it's funny
@ -1709,7 +1709,7 @@ void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum)
size_t size, lflatsize, flatshift;
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
HWR_DrawFlatFill(x, y, w, h, flatnum);
return;
@ -1819,7 +1819,7 @@ void V_DrawPatchFill(patch_t *pat)
void V_DrawFadeScreen(UINT16 color, UINT8 strength)
{
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
HWR_FadeScreenMenuBack(color, strength);
return;
@ -1848,7 +1848,7 @@ void V_DrawFadeConsBack(INT32 plines)
UINT8 *deststop, *buf;
#ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
UINT32 hwcolor = V_GetHWConsBackColor();
HWR_DrawConsoleBack(hwcolor, plines);
@ -1870,7 +1870,10 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color)
if (color >= 256 && color < 512)
{
boxheight = ((boxheight * 4) + (boxheight/2)*5);
if (boxheight < 0)
boxheight = -boxheight;
else // 4 lines of space plus gaps between and some leeway
boxheight = ((boxheight * 4) + (boxheight/2)*5);
V_DrawFill((BASEVIDWIDTH-(vid.width/vid.dupx))/2, BASEVIDHEIGHT-boxheight, (vid.width/vid.dupx),boxheight, (color-256)|V_SNAPTOBOTTOM);
return;
}
@ -1881,7 +1884,7 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color)
color = cons_backcolor.value;
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
UINT32 hwcolor;
switch (color)
@ -1917,8 +1920,11 @@ void V_DrawPromptBack(INT32 boxheight, INT32 color)
// heavily simplified -- we don't need to know x or y position,
// just the start and stop positions
deststop = screens[0] + vid.rowbytes * vid.height;
buf = deststop - vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5); // 4 lines of space plus gaps between and some leeway
buf = deststop = screens[0] + vid.rowbytes * vid.height;
if (boxheight < 0)
buf += vid.rowbytes * boxheight;
else // 4 lines of space plus gaps between and some leeway
buf -= vid.rowbytes * ((boxheight * 4) + (boxheight/2)*5);
for (; buf < deststop; ++buf)
*buf = promptbgmap[*buf];
}
@ -3506,8 +3512,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
INT32 height, yoffset;
#ifdef HWRENDER
// draw a hardware converted patch
if (rendermode != render_soft && rendermode != render_none)
if (rendermode != render_soft)
return;
#endif

View File

@ -848,6 +848,15 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
wadfiles[numwadfiles] = wadfile;
numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
#ifdef HWRENDER
// Read shaders from file
if (rendermode == render_opengl && (vid_opengl_state == 1))
{
HWR_ReadShaders(numwadfiles - 1, (type == RET_PK3));
HWR_LoadShaders();
}
#endif // HWRENDER
// TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now.
switch (wadfile->type)
{
@ -1632,21 +1641,6 @@ boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr)
return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
void W_FlushCachedPatches(void)
{
if (needpatchflush)
{
Z_FreeTag(PU_CACHE);
Z_FreeTag(PU_PATCH);
Z_FreeTag(PU_HUDGFX);
Z_FreeTag(PU_HWRPATCHINFO);
Z_FreeTag(PU_HWRMODELTEXTURE);
Z_FreeTag(PU_HWRCACHE);
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRMODELTEXTURE_UNLOCKED);
}
needpatchflush = false;
}
// ==========================================================================
// W_CacheLumpName
// ==========================================================================
@ -1674,9 +1668,6 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
lumpcache_t *lumpcache = NULL;
if (needpatchflush)
W_FlushCachedPatches();
if (!TestValidLump(wad, lump))
return NULL;
@ -1727,9 +1718,6 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
GLPatch_t *grPatch;
#endif
if (needpatchflush)
W_FlushCachedPatches();
if (!TestValidLump(wad, lump))
return NULL;
@ -1778,7 +1766,7 @@ void W_UnlockCachedPatch(void *patch)
// The hardware code does its own memory management, as its patches
// have different lifetimes from software's.
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
HWR_UnlockCachedPatch((GLPatch_t*)patch);
else
#endif

View File

@ -210,7 +210,6 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag);
void W_UnlockCachedPatch(void *patch);
void W_FlushCachedPatches(void);
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);

View File

@ -106,6 +106,7 @@ static loadfunc_t hwdFuncTable[] = {
{"SetBlend@4", &hwdriver.pfnSetBlend},
{"ClearBuffer@12", &hwdriver.pfnClearBuffer},
{"SetTexture@4", &hwdriver.pfnSetTexture},
{"UpdateTexture@4", &hwdriver.pfnUpdateTexture},
{"ReadRect@24", &hwdriver.pfnReadRect},
{"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
@ -120,7 +121,7 @@ static loadfunc_t hwdFuncTable[] = {
{"FlushScreenTextures@0",&hwdriver.pfnFlushScreenTextures},
{"StartScreenWipe@0", &hwdriver.pfnStartScreenWipe},
{"EndScreenWipe@0", &hwdriver.pfnEndScreenWipe},
{"DoScreenWipe@4", &hwdriver.pfnDoScreenWipe},
{"DoScreenWipe@0", &hwdriver.pfnDoScreenWipe},
{"DrawIntermissionBG@0",&hwdriver.pfnDrawIntermissionBG},
{"MakeScreenTexture@0", &hwdriver.pfnMakeScreenTexture},
{"MakeScreenFinalTexture@0", &hwdriver.pfnMakeScreenFinalTexture},
@ -137,6 +138,7 @@ static loadfunc_t hwdFuncTable[] = {
{"SetBlend", &hwdriver.pfnSetBlend},
{"ClearBuffer", &hwdriver.pfnClearBuffer},
{"SetTexture", &hwdriver.pfnSetTexture},
{"UpdateTexture", &hwdriver.pfnUpdateTexture},
{"ReadRect", &hwdriver.pfnReadRect},
{"GClipRect", &hwdriver.pfnGClipRect},
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},

View File

@ -326,7 +326,7 @@ static inline boolean I_SkipFrame(void)
if (!paused)
return false;
//case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible
#ifndef CLIENT_LOADINGSCREEN
#ifndef NONET
/* FALLTHRU */
case GS_WAITINGPLAYERS:
#endif
@ -366,6 +366,9 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
if (marathonmode)
SCR_DisplayMarathonInfo();
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();

View File

@ -227,8 +227,7 @@ static void Y_IntermissionTokenDrawer(void)
//
// Y_ConsiderScreenBuffer
//
// Can we copy the current screen
// to a buffer?
// Can we copy the current screen to a buffer?
//
void Y_ConsiderScreenBuffer(void)
{
@ -254,9 +253,7 @@ void Y_ConsiderScreenBuffer(void)
//
// Y_RescaleScreenBuffer
//
// Write the rescaled source picture,
// to the destination picture that
// has the current screen's resolutions.
// Write the rescaled source picture, to the destination picture that has the current screen's resolutions.
//
static void Y_RescaleScreenBuffer(void)
{
@ -323,16 +320,9 @@ void Y_IntermissionDrawer(void)
// Bonus loops
INT32 i;
if (rendermode == render_none)
if (intertype == int_none || rendermode == render_none)
return;
if (intertype == int_none)
{
LUAh_IntermissionHUD();
return;
}
if (!usebuffer)
// Lactozilla: Renderer switching
if (needpatchrecache)
{
@ -373,11 +363,11 @@ void Y_IntermissionDrawer(void)
{
if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400)
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch);
else
else if (bgpatch)
V_DrawScaledPatch(0, 0, 0, bgpatch);
}
}
else
else if (bgtile)
V_DrawPatchFill(bgtile);
LUAh_IntermissionHUD();
@ -392,7 +382,7 @@ dontdrawbg:
if (gottoken) // first to be behind everything else
Y_IntermissionTokenDrawer();
if (!splitscreen)
if (!splitscreen) // there's not enough room in splitscreen, don't even bother trying!
{
// draw score
ST_DrawPatchFromHud(HUD_SCORE, sboscore);
@ -414,7 +404,7 @@ dontdrawbg:
ST_DrawPatchFromHud(HUD_TIMECOLON, sbocolon); // Colon
ST_DrawPadNumFromHud(HUD_SECONDS, seconds, 2); // Seconds
if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking) // there's not enough room for tics in splitscreen, don't even bother trying!
if (cv_timetic.value == 1 || cv_timetic.value == 2 || modeattacking || marathonmode)
{
ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
@ -1004,7 +994,7 @@ void Y_Ticker(void)
{
INT32 i;
UINT32 oldscore = data.coop.score;
boolean skip = false;
boolean skip = (marathonmode) ? true : false;
boolean anybonuses = false;
if (!intertic) // first time only
@ -1080,7 +1070,7 @@ void Y_Ticker(void)
{
INT32 i;
UINT32 oldscore = data.spec.score;
boolean skip = false, super = false, anybonuses = false;
boolean skip = (marathonmode) ? true : false, super = false, anybonuses = false;
if (!intertic) // first time only
{
@ -1186,6 +1176,34 @@ void Y_Ticker(void)
}
}
//
// Y_DetermineIntermissionType
//
// Determines the intermission type from the current gametype.
//
void Y_DetermineIntermissionType(void)
{
// set to int_none initially
intertype = int_none;
if (intermissiontypes[gametype] != int_none)
intertype = intermissiontypes[gametype];
else if (gametype == GT_COOP)
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
else if (gametype == GT_TEAMMATCH)
intertype = int_teammatch;
else if (gametype == GT_MATCH
|| gametype == GT_TAG
|| gametype == GT_HIDEANDSEEK)
intertype = int_match;
else if (gametype == GT_RACE)
intertype = int_race;
else if (gametype == GT_COMPETITION)
intertype = int_comp;
else if (gametype == GT_CTF)
intertype = int_ctf;
}
//
// Y_StartIntermission
//
@ -1207,12 +1225,11 @@ void Y_StartIntermission(void)
if (!multiplayer)
{
timer = 0;
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
}
else
{
if (cv_inttime.value == 0 && gametype == GT_COOP)
if (cv_inttime.value == 0 && ((intertype == int_coop) || (intertype == int_spec)))
timer = 0;
else
{
@ -1221,23 +1238,6 @@ void Y_StartIntermission(void)
if (!timer)
timer = 1;
}
if (intermissiontypes[gametype] != int_none)
intertype = intermissiontypes[gametype];
else if (gametype == GT_COOP)
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
else if (gametype == GT_TEAMMATCH)
intertype = int_teammatch;
else if (gametype == GT_MATCH
|| gametype == GT_TAG
|| gametype == GT_HIDEANDSEEK)
intertype = int_match;
else if (gametype == GT_RACE)
intertype = int_race;
else if (gametype == GT_COMPETITION)
intertype = int_comp;
else if (gametype == GT_CTF)
intertype = int_ctf;
}
// We couldn't display the intermission even if we wanted to.

View File

@ -13,11 +13,15 @@ extern boolean usebuffer;
void Y_IntermissionDrawer(void);
void Y_Ticker(void);
void Y_StartIntermission(void);
void Y_EndIntermission(void);
void Y_ConsiderScreenBuffer(void);
void Y_CleanupScreenBuffer(void);
void Y_DetermineIntermissionType(void);
typedef enum
{
int_none,

View File

@ -499,17 +499,14 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
// Utility functions
// -----------------
// for renderer switching, free a bunch of stuff
// for renderer switching
boolean needpatchflush = false;
boolean needpatchrecache = false;
// flush all patches from memory
// (also frees memory tagged with PU_CACHE)
// (which are not necessarily patches but I don't care)
void Z_FlushCachedPatches(void)
{
CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n");
Z_FreeTag(PU_CACHE);
Z_FreeTag(PU_PATCH);
Z_FreeTag(PU_HUDGFX);
Z_FreeTag(PU_HWRPATCHINFO);
@ -808,7 +805,7 @@ static void Command_Memfree_f(void)
sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10));
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
{
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));