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

This commit is contained in:
Zachary McAlpin 2020-06-24 19:47:52 -05:00
commit 5ef8c95cdb
68 changed files with 3847 additions and 2600 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

@ -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

@ -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;
}
@ -9364,8 +9400,6 @@ static const char *const MENUTYPES_LIST[] = {
"OP_COLOR",
"OP_OPENGL",
"OP_OPENGL_LIGHTING",
"OP_OPENGL_FOG",
"OP_OPENGL_COLOR",
"OP_SOUND",
@ -9998,6 +10032,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
@ -638,17 +639,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

@ -1330,10 +1330,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 +1525,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 +1541,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 +1681,9 @@ void F_GameEvaluationTicker(void)
return;
}
if (!goodending)
if (!useBlackRock)
;
else if (!goodending)
{
if (sparklloop)
sparklloop--;
@ -1841,10 +1840,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 +3954,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;
@ -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.
@ -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);
@ -2963,7 +2978,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();
@ -3696,8 +3711,14 @@ 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);
if (marathonmode && nextmap == spmarathon_start-1)
nextmap = 1100-1; // No infinite loop for you
}
// Remember last map for when you come out of the special stage.
if (!spec)
@ -3721,10 +3742,12 @@ static void G_DoCompleted(void)
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);
if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error)
if (cm >= NUMMAPS || cm < 0) // out of range (either 1100ish or error)
{
cm = nextmap; //Start the loop again so that the error checking below is executed.
@ -3793,6 +3816,25 @@ static void G_DoCompleted(void)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap);
// do this before going to the intermission or starting a 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))
G_SaveGame((UINT32)cursaveslot);
}
}
if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed))
{
G_UpdateVisited();
@ -3806,6 +3848,7 @@ static void G_DoCompleted(void)
}
}
// See also F_EndCutscene, the only other place which handles intra-map/ending transitions
void G_AfterIntermission(void)
{
Y_CleanupScreenBuffer();
@ -3816,9 +3859,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 && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
else
{
@ -3959,7 +4005,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 +4325,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 +4340,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 +4380,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);
@ -4359,13 +4413,12 @@ void G_SaveGame(UINT32 slot)
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 +4432,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();
if (marathonmode)
{
WRITEUINT32(save_p, marathontime);
WRITEUINT8(save_p, (marathonmode & ~MA_INIT));
}
length = save_p - savebuffer;
saved = FIL_WriteFile(backup, savebuffer, length);
@ -4395,7 +4453,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 +4466,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 +4488,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 +4555,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 +4693,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

@ -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, 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_
@ -118,11 +111,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
@ -400,13 +393,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);
}
@ -455,13 +441,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
@ -949,11 +928,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 +1175,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 +1221,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
{
@ -1263,11 +1246,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
@ -1512,11 +1495,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 +1503,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, &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_

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

@ -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

@ -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

@ -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;

View File

@ -183,6 +183,7 @@ static tic_t keydown = 0;
static void M_GoBack(INT32 choice);
static void M_StopMessage(INT32 choice);
static boolean stopstopmessage = false;
#ifndef NONET
static void M_HandleServerPage(INT32 choice);
@ -253,6 +254,7 @@ static void M_ConfirmTeamScramble(INT32 choice);
static void M_ConfirmTeamChange(INT32 choice);
static void M_SecretsMenu(INT32 choice);
static void M_SetupChoosePlayer(INT32 choice);
static UINT8 M_SetupChoosePlayerDirect(INT32 choice);
static void M_QuitSRB2(INT32 choice);
menu_t SP_MainDef, OP_MainDef;
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
@ -273,9 +275,14 @@ static void M_ModeAttackEndGame(INT32 choice);
static void M_SetGuestReplay(INT32 choice);
static void M_HandleChoosePlayerMenu(INT32 choice);
static void M_ChoosePlayer(INT32 choice);
static void M_MarathonLiveEventBackup(INT32 choice);
static void M_Marathon(INT32 choice);
static void M_HandleMarathonChoosePlayer(INT32 choice);
static void M_StartMarathon(INT32 choice);
menu_t SP_LevelStatsDef;
static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef;
static menu_t SP_MarathonDef;
// Multiplayer
static void M_SetupMultiPlayer(INT32 choice);
@ -317,8 +324,11 @@ static void M_VideoOptions(INT32 choice);
menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef;
#ifdef HWRENDER
static void M_OpenGLOptionsMenu(void);
menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef;
#endif
menu_t OP_OpenGLOptionsDef;
#ifdef ALAM_LIGHTING
menu_t OP_OpenGLLightingDef;
#endif // ALAM_LIGHTING
#endif // HWRENDER
menu_t OP_SoundOptionsDef;
menu_t OP_SoundAdvancedDef;
@ -355,6 +365,7 @@ static void M_DrawLoad(void);
static void M_DrawLevelStats(void);
static void M_DrawTimeAttackMenu(void);
static void M_DrawNightsAttackMenu(void);
static void M_DrawMarathon(void);
static void M_DrawSetupChoosePlayerMenu(void);
static void M_DrawControlsDefMenu(void);
static void M_DrawCameraOptionsMenu(void);
@ -365,9 +376,6 @@ static void M_DrawVideoMode(void);
static void M_DrawColorMenu(void);
static void M_DrawScreenshotMenu(void);
static void M_DrawMonitorToggles(void);
#ifdef HWRENDER
static void M_OGL_DrawFogMenu(void);
#endif
#ifndef NONET
static void M_DrawConnectMenu(void);
static void M_DrawMPMainMenu(void);
@ -391,9 +399,6 @@ static boolean M_CancelConnect(void);
static void M_HandleConnectIP(INT32 choice);
#endif
static void M_HandleSetupMultiPlayer(INT32 choice);
#ifdef HWRENDER
static void M_HandleFogColor(INT32 choice);
#endif
static void M_HandleVideoMode(INT32 choice);
static void M_ResetCvars(void);
@ -477,6 +482,13 @@ static consvar_t cv_dummylives = {"dummylives", "0", CV_HIDEN, liveslimit_cons_t
static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, contlimit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dummymares_cons_t, Dummymares_OnChange, 0, NULL, NULL, 0, 0, NULL};
CV_PossibleValue_t marathon_cons_t[] = {{0, "Standard"}, {1, "Live Event Backup"}, {2, "Ultimate"}, {0, NULL}};
CV_PossibleValue_t loadless_cons_t[] = {{0, "Realtime"}, {1, "In-game"}, {0, NULL}};
consvar_t cv_dummymarathon = {"dummymarathon", "Standard", CV_HIDEN, marathon_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_dummycutscenes = {"dummycutscenes", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_dummyloadless = {"dummyloadless", "Realtime", CV_HIDEN, loadless_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// ==========================================================================
// ORGANIZATION START.
// ==========================================================================
@ -747,9 +759,10 @@ static menuitem_t SR_EmblemHintMenu[] =
// Single Player Main
static menuitem_t SP_MainMenu[] =
{
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 84},
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 92},
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 100},
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 76},
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 84},
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 92},
{IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Marathon Run", M_Marathon, 100},
{IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 108},
{IT_CALL | IT_STRING | IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 116}
};
@ -759,6 +772,7 @@ enum
sploadgame,
sprecordattack,
spnightsmode,
spmarathon,
sptutorial,
spstatistics
};
@ -904,6 +918,25 @@ enum
nastart
};
// Marathon
static menuitem_t SP_MarathonMenu[] =
{
{IT_STRING|IT_KEYHANDLER, NULL, "Character", M_HandleMarathonChoosePlayer, 90},
{IT_STRING|IT_CVAR, NULL, "Category", &cv_dummymarathon, 100},
{IT_STRING|IT_CVAR, NULL, "Timer", &cv_dummyloadless, 110},
{IT_STRING|IT_CVAR, NULL, "Cutscenes", &cv_dummycutscenes, 120},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_StartMarathon, 130},
};
enum
{
marathonplayer,
marathonultimate,
marathonloadless,
marathoncutscenes,
marathonstart
};
// Statistics
static menuitem_t SP_LevelStatsMenu[] =
{
@ -1413,22 +1446,23 @@ static menuitem_t OP_OpenGLOptionsMenu[] =
{
{IT_HEADER, NULL, "3D Models", NULL, 0},
{IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 12},
{IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 22},
{IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32},
{IT_STRING|IT_CVAR, NULL, "Frame interpolation", &cv_grmodelinterpolation, 22},
{IT_STRING|IT_CVAR, NULL, "Ambient lighting", &cv_grmodellighting, 32},
{IT_HEADER, NULL, "General", NULL, 51},
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93},
{IT_STRING|IT_CVAR, NULL, "Shaders", &cv_grshaders, 63},
{IT_STRING|IT_CVAR, NULL, "Lack of perspective", &cv_grshearing, 73},
{IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 83},
{IT_HEADER, NULL, "Miscellaneous", NULL, 112},
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 124},
{IT_HEADER, NULL, "Miscellaneous", NULL, 102},
{IT_STRING|IT_CVAR, NULL, "Bit depth", &cv_scr_depth, 114},
{IT_STRING|IT_CVAR, NULL, "Texture filter", &cv_grfiltermode, 124},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 134},
#ifdef ALAM_LIGHTING
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 134},
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 144},
#endif
#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)))
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 144},
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 154},
#endif
};
@ -1440,15 +1474,8 @@ static menuitem_t OP_OpenGLLightingMenu[] =
{IT_STRING|IT_CVAR, NULL, "Dynamic lighting", &cv_grdynamiclighting, 20},
{IT_STRING|IT_CVAR, NULL, "Static lighting", &cv_grstaticlighting, 30},
};
#endif
#endif // ALAM_LIGHTING
static menuitem_t OP_OpenGLFogMenu[] =
{
{IT_STRING|IT_CVAR, NULL, "Fog", &cv_grfog, 10},
{IT_STRING|IT_KEYHANDLER, NULL, "Fog color", M_HandleFogColor, 20},
{IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30},
{IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40},
};
#endif
static menuitem_t OP_SoundOptionsMenu[] =
@ -1911,6 +1938,18 @@ static menu_t SP_NightsGhostDef =
NULL
};
static menu_t SP_MarathonDef =
{
MTREE2(MN_SP_MAIN, MN_SP_MARATHON),
"M_ATTACK", // temporary
sizeof(SP_MarathonMenu)/sizeof(menuitem_t),
&MainDef, // Doesn't matter.
SP_MarathonMenu,
M_DrawMarathon,
32, 40,
0,
NULL
};
menu_t SP_PlayerDef =
{
@ -2195,20 +2234,9 @@ menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(
menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE(
MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_LIGHTING),
"M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40);
#endif
menu_t OP_OpenGLFogDef =
{
MTREE4(MN_OP_MAIN, MN_OP_VIDEO, MN_OP_OPENGL, MN_OP_OPENGL_FOG),
"M_VIDEO",
sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef,
OP_OpenGLFogMenu,
M_OGL_DrawFogMenu,
60, 40,
0,
NULL
};
#endif
#endif // ALAM_LIGHTING
#endif // HWRENDER
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE(
MTREE2(MN_OP_MAIN, MN_OP_DATA),
"M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
@ -2527,6 +2555,8 @@ void M_InitMenuPresTables(void)
strncpy(menupres[i].musname, "_recat", 7);
else if (i == MN_SP_NIGHTSATTACK)
strncpy(menupres[i].musname, "_nitat", 7);
else if (i == MN_SP_MARATHON)
strncpy(menupres[i].musname, "spec8", 6);
else if (i == MN_SP_PLAYER || i == MN_SR_PLAYER)
strncpy(menupres[i].musname, "_chsel", 7);
else if (i == MN_SR_SOUNDTEST)
@ -3021,7 +3051,7 @@ static void M_GoBack(INT32 choice)
netgame = multiplayer = false;
}
if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef))
if ((currentMenu->prevMenu == &MainDef) && (currentMenu == &SP_TimeAttackDef || currentMenu == &SP_NightsAttackDef || currentMenu == &SP_MarathonDef))
{
// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
@ -3406,11 +3436,14 @@ boolean M_Responder(event_t *ev)
{
if (currentMenu->menuitems[itemOn].alphaKey != MM_EVENTHANDLER)
{
if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER)
if (ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE || ch == KEY_ENTER || ch == KEY_DEL)
{
if (routine)
routine(ch);
M_StopMessage(0);
if (stopstopmessage)
stopstopmessage = false;
else
M_StopMessage(0);
noFurtherInput = true;
return true;
}
@ -3660,7 +3693,7 @@ void M_StartControlPanel(void)
{
INT32 numlives = 2;
SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA)) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
SPauseMenu[spause_pandora].status = (M_SecretUnlocked(SECRET_PANDORA) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
if (&players[consoleplayer])
{
@ -3678,10 +3711,10 @@ void M_StartControlPanel(void)
}
// We can always use level select though. :33
SPauseMenu[spause_levelselect].status = (gamecomplete) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
SPauseMenu[spause_levelselect].status = (gamecomplete == 1) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
// And emblem hints.
SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS)) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
SPauseMenu[spause_hints].status = (M_SecretUnlocked(SECRET_EMBLEMHINTS) && !marathonmode) ? (IT_STRING | IT_CALL) : (IT_DISABLED);
// Shift up Pandora's Box if both pandora and levelselect are active
/*if (SPauseMenu[spause_pandora].status != (IT_DISABLED)
@ -3862,6 +3895,9 @@ void M_Init(void)
CV_RegisterVar(&cv_dummylives);
CV_RegisterVar(&cv_dummycontinues);
CV_RegisterVar(&cv_dummymares);
CV_RegisterVar(&cv_dummymarathon);
CV_RegisterVar(&cv_dummyloadless);
CV_RegisterVar(&cv_dummycutscenes);
quitmsg[QUITMSG] = M_GetText("Eggman's tied explosives\nto your girlfriend, and\nwill activate them if\nyou press the 'Y' key!\nPress 'N' to save her!\n\n(Press 'Y' to quit)");
quitmsg[QUITMSG1] = M_GetText("What would Tails say if\nhe saw you quitting the game?\n\n(Press 'Y' to quit)");
@ -6324,8 +6360,8 @@ static char *M_AddonsHeaderPath(void)
static void M_AddonsClearName(INT32 choice)
{
(void)choice;
CLEARNAME;
M_StopMessage(choice);
}
// returns whether to do message draw
@ -6357,7 +6393,7 @@ static boolean M_AddonsRefresh(void)
if (message)
{
M_StartMessage(message,M_AddonsClearName,MM_EVENTHANDLER);
M_StartMessage(message,M_AddonsClearName,MM_NOTHING);
return true;
}
@ -6862,6 +6898,11 @@ static void M_RetryResponse(INT32 ch)
static void M_Retry(INT32 choice)
{
(void)choice;
if (marathonmode)
{
M_RetryResponse(KEY_ENTER);
return;
}
M_StartMessage(M_GetText("Retry this act from the last starpost?\n\n(Press 'Y' to confirm)\n"),M_RetryResponse,MM_YESNO);
}
@ -8016,6 +8057,16 @@ static void M_SinglePlayerMenu(INT32 choice)
SP_MainMenu[sptutorial].status = tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
// If the FIRST stage immediately leads to the ending, or itself (which gets converted to the title screen in G_DoCompleted for marathonmode only), there's no point in having this option on the menu. You should use Record Attack in that circumstance, although if marathonnext is set this behaviour can be overridden if you make some weird mod that requires multiple playthroughs of the same map in sequence and has some in-level mechanism to break the cycle.
if (!M_SecretUnlocked(SECRET_RECORDATTACK) // also if record attack is locked
|| (mapheaderinfo[spmarathon_start-1]
&& !mapheaderinfo[spmarathon_start-1]->marathonnext
&& (mapheaderinfo[spmarathon_start-1]->nextlevel == spmarathon_start
|| mapheaderinfo[spmarathon_start-1]->nextlevel >= 1100)))
SP_MainMenu[spmarathon].status = IT_NOTHING|IT_DISABLED;
else
SP_MainMenu[spmarathon].status = IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED;
M_SetupNextMenu(&SP_MainDef);
}
@ -8106,7 +8157,7 @@ static void M_StartTutorial(INT32 choice)
emeralds = 0;
memset(&luabanks, 0, sizeof(luabanks));
M_ClearMenus(true);
gamecomplete = false;
gamecomplete = 0;
cursaveslot = 0;
G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false);
}
@ -8869,7 +8920,7 @@ static void M_CacheCharacterSelect(void)
{
INT32 i, skinnum;
for (i = 0; i < 32; i++)
for (i = 0; i < MAXSKINS; i++)
{
if (!description[i].used)
continue;
@ -8881,7 +8932,7 @@ static void M_CacheCharacterSelect(void)
}
}
static void M_SetupChoosePlayer(INT32 choice)
static UINT8 M_SetupChoosePlayerDirect(INT32 choice)
{
INT32 skinnum;
UINT8 i;
@ -8892,7 +8943,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (!mapheaderinfo[startmap-1] || mapheaderinfo[startmap-1]->forcecharacter[0] == '\0')
{
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
for (i = 0; i < MAXSKINS; i++) // Handle charsels, availability, and unlocks.
{
if (description[i].used) // If the character's disabled through SOC, there's nothing we can do for it.
{
@ -8900,7 +8951,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (and)
{
char firstskin[SKINNAMESIZE+1];
if (mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels
if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->typeoflevel & TOL_NIGHTS) // skip tagteam characters for NiGHTS levels
continue;
strncpy(firstskin, description[i].skinname, (and - description[i].skinname));
firstskin[(and - description[i].skinname)] = '\0';
@ -8937,14 +8988,36 @@ static void M_SetupChoosePlayer(INT32 choice)
if (firstvalid == lastvalid) // We're being forced into a specific character, so might as well just skip it.
{
M_ChoosePlayer(firstvalid);
return;
return firstvalid;
}
// One last bit of order we can't do in the iteration above.
description[firstvalid].prev = lastvalid;
description[lastvalid].next = firstvalid;
if (!allowed)
{
char_on = firstvalid;
if (startchar > 0 && startchar < MAXSKINS)
{
INT16 workchar = startchar;
while (workchar--)
char_on = description[char_on].next;
}
}
return MAXSKINS;
}
static void M_SetupChoosePlayer(INT32 choice)
{
UINT8 skinset = M_SetupChoosePlayerDirect(choice);
if (skinset != MAXSKINS)
{
M_ChoosePlayer(skinset);
return;
}
M_ChangeMenuMusic("_chsel", true);
/* the menus suck -James */
@ -8959,16 +9032,6 @@ static void M_SetupChoosePlayer(INT32 choice)
SP_PlayerDef.prevMenu = currentMenu;
M_SetupNextMenu(&SP_PlayerDef);
if (!allowed)
{
char_on = firstvalid;
if (startchar > 0 && startchar < 32)
{
INT16 workchar = startchar;
while (workchar--)
char_on = description[char_on].next;
}
}
// finish scrolling the menu
char_scroll = 0;
@ -9027,6 +9090,10 @@ static void M_HandleChoosePlayerMenu(INT32 choice)
case KEY_ENTER:
S_StartSound(NULL, sfx_menu1);
char_scroll = 0; // finish scrolling the menu
M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout
// Is this a hack?
charseltimer = 0;
M_ChoosePlayer(char_on);
break;
@ -9266,7 +9333,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Chose the player you want to use Tails 03-02-2002
static void M_ChoosePlayer(INT32 choice)
{
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
boolean ultmode = (currentMenu == &SP_MarathonDef) ? (cv_dummymarathon.value == 2) : (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
UINT8 skinnum;
// skip this if forcecharacter or no characters available
@ -9278,11 +9345,6 @@ static void M_ChoosePlayer(INT32 choice)
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
else
{
char_scroll = 0; // finish scrolling the menu
M_DrawSetupChoosePlayerMenu(); // draw the finally selected character one last time for the fadeout
// Is this a hack?
charseltimer = 0;
skinnum = description[choice].skinnum[0];
if ((botingame = (description[choice].skinnum[1] != -1))) {
@ -9296,11 +9358,11 @@ static void M_ChoosePlayer(INT32 choice)
M_ClearMenus(true);
if (startmap != spstage_start)
if (!marathonmode && startmap != spstage_start)
cursaveslot = 0;
//lastmapsaved = 0;
gamecomplete = false;
gamecomplete = 0;
G_DeferedInitNew(ultmode, G_BuildMapName(startmap), skinnum, false, fromlevelselect);
COM_BufAddText("dummyconsvar 1\n"); // G_DeferedInitNew doesn't do this
@ -10299,6 +10361,368 @@ static void M_ModeAttackEndGame(INT32 choice)
Nextmap_OnChange();
}
static void M_MarathonLiveEventBackup(INT32 choice)
{
if (choice == 'y' || choice == KEY_ENTER)
{
marathonmode = MA_INIT;
G_LoadGame(MARATHONSLOT, 0);
cursaveslot = MARATHONSLOT;
if (!(marathonmode & MA_RUNNING))
marathonmode = 0;
return;
}
M_StopMessage(0);
stopstopmessage = true;
if (choice == KEY_DEL)
{
if (FIL_FileExists(liveeventbackup)) // just in case someone deleted it while we weren't looking.
remove(liveeventbackup);
BwehHehHe();
M_StartMessage("Live event backup erased.\n",M_Marathon,MM_NOTHING);
return;
}
M_Marathon(-1);
}
// Going to Marathon menu...
static void M_Marathon(INT32 choice)
{
UINT8 skinset;
INT32 mapnum = 0;
if (choice != -1 && FIL_FileExists(liveeventbackup))
{
M_StartMessage(\
"\x82Live event backup detected.\n\x80\
Do you want to resurrect the last run?\n\
(Fs in chat if we crashed on stream.)\n\
\n\
Press 'Y' or 'Enter' to resume,\n\
'Del' to delete, or any other\n\
key to continue to Marathon Run.",M_MarathonLiveEventBackup,MM_YESNO);
return;
}
fromlevelselect = false;
startmap = spmarathon_start;
CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004
skinset = M_SetupChoosePlayerDirect(-1);
SP_MarathonMenu[marathonplayer].status = (skinset == MAXSKINS) ? IT_KEYHANDLER|IT_STRING : IT_NOTHING|IT_DISABLED;
while (mapnum < NUMMAPS)
{
if (mapheaderinfo[mapnum])
{
if (mapheaderinfo[mapnum]->cutscenenum || mapheaderinfo[mapnum]->precutscenenum)
break;
}
mapnum++;
}
SP_MarathonMenu[marathoncutscenes].status = (mapnum < NUMMAPS) ? IT_CVAR|IT_STRING : IT_NOTHING|IT_DISABLED;
M_ChangeMenuMusic("spec8", true);
SP_MarathonDef.prevMenu = &MainDef;
G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching
titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
M_SetupNextMenu(&SP_MarathonDef);
itemOn = marathonstart; // "Start" is selected.
recatkdrawtimer = 50-8;
char_scroll = 0;
}
static void M_HandleMarathonChoosePlayer(INT32 choice)
{
INT32 selectval;
if (keydown > 1)
return;
switch (choice)
{
case KEY_DOWNARROW:
M_NextOpt();
break;
case KEY_UPARROW:
M_PrevOpt();
break;
case KEY_LEFTARROW:
if ((selectval = description[char_on].prev) == char_on)
return;
char_on = selectval;
break;
case KEY_RIGHTARROW:
if ((selectval = description[char_on].next) == char_on)
return;
char_on = selectval;
break;
case KEY_ESCAPE:
noFurtherInput = true;
M_GoBack(0);
return;
default:
return;
}
S_StartSound(NULL, sfx_menu1);
}
static void M_StartMarathon(INT32 choice)
{
(void)choice;
marathontime = 0;
marathonmode = MA_RUNNING|MA_INIT;
if (cv_dummymarathon.value == 1)
cursaveslot = MARATHONSLOT;
if (!cv_dummycutscenes.value)
marathonmode |= MA_NOCUTSCENES;
if (cv_dummyloadless.value)
marathonmode |= MA_INGAME;
M_ChoosePlayer(char_on);
}
// Drawing function for Marathon menu
void M_DrawMarathon(void)
{
INT32 i, x, y, cursory = 0, cnt, soffset = 0, w;
UINT16 dispstatus;
consvar_t *cv;
const char *cvstring;
char *work;
angle_t fa;
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy), xspan = (vid.width/dupz), yspan = (vid.height/dupz), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy;
// lactozilla: the renderer changed so recache patches
if (needpatchrecache)
M_CacheCharacterSelect();
curbgxspeed = 0;
curbgyspeed = 18;
M_ChangeMenuMusic("spec8", true); // Eww, but needed for when user hits escape during demo playback
V_DrawFill(-diffx, -diffy, diffx+(BASEVIDWIDTH-190)/2, yspan, 158);
V_DrawFill((BASEVIDWIDTH-190)/2, -diffy, 190, yspan, 31);
V_DrawFill((BASEVIDWIDTH+190)/2, -diffy, diffx+(BASEVIDWIDTH-190)/2, yspan, 158);
//M_DrawRecordAttackForeground();
if (curfadevalue)
V_DrawFadeScreen(0xFF00, curfadevalue);
x = (((BASEVIDWIDTH-82)/2)+11)<<FRACBITS;
y = (((BASEVIDHEIGHT-82)/2)+12-10)<<FRACBITS;
cnt = (36*(recatkdrawtimer<<FRACBITS))/TICRATE;
fa = (FixedAngle(cnt)>>ANGLETOFINESHIFT) & FINEMASK;
y -= (10*FINECOSINE(fa));
recatkdrawtimer++;
soffset = cnt = (recatkdrawtimer%50);
if (!useBlackRock)
{
if (cnt > 8)
cnt = 8;
V_DrawFixedPatch(x+(6<<FRACBITS), y, FRACUNIT/2, (cnt&~1)<<(V_ALPHASHIFT-1), W_CachePatchName("RECCLOCK", PU_PATCH), NULL);
}
else if (cnt > 8)
{
cnt = 8;
V_DrawFixedPatch(x, y, FRACUNIT, V_TRANSLUCENT, W_CachePatchName("ENDEGRK5", PU_PATCH), NULL);
}
else
{
V_DrawFixedPatch(x, y, FRACUNIT, cnt<<V_ALPHASHIFT, W_CachePatchName("ROID0000", PU_PATCH), NULL);
V_DrawFixedPatch(x, y, FRACUNIT, V_TRANSLUCENT, W_CachePatchName("ENDEGRK5", PU_PATCH), NULL);
V_DrawFixedPatch(x, y, FRACUNIT, cnt<<V_ALPHASHIFT, W_CachePatchName("ENDEGRK0", PU_PATCH), NULL);
}
{
UINT8 col;
i = 0;
w = (((8-cnt)+1)/3)+1;
w *= w;
cursory = 0;
while (i < cnt)
{
i++;
col = 158+((cnt-i)/3);
if (col >= 160)
col = 253;
V_DrawFill(((BASEVIDWIDTH-190)/2)-cursory-w, -diffy, w, yspan, col);
V_DrawFill(((BASEVIDWIDTH+190)/2)+cursory, -diffy, w, yspan, col);
cursory += w;
w *= 2;
}
}
w = char_scroll + (((8-cnt)*(8-cnt))<<(FRACBITS-5));
if (soffset == 50-1)
w += FRACUNIT/2;
{
patch_t *fg = W_CachePatchName("RECATKFG", PU_PATCH);
INT32 trans = V_60TRANS+((cnt&~3)<<(V_ALPHASHIFT-2));
INT32 height = (SHORT(fg->height)/2);
char patchname[7] = "CEMGx0";
dupz = (w*7)/6; //(w*42*120)/(360*6); -- I don't know why this works but I'm not going to complain.
dupz = ((dupz>>FRACBITS) % height);
y = height/2;
while (y+dupz >= -diffy)
y -= height;
while (y-2-dupz < maxy)
{
V_DrawFixedPatch(((BASEVIDWIDTH-190)<<(FRACBITS-1)), (y-2-dupz)<<FRACBITS, FRACUNIT/2, trans, fg, NULL);
V_DrawFixedPatch(((BASEVIDWIDTH+190)<<(FRACBITS-1)), (y+dupz)<<FRACBITS, FRACUNIT/2, trans|V_FLIP, fg, NULL);
y += height;
}
trans = V_40TRANS+((cnt&~1)<<(V_ALPHASHIFT-1));
for (i = 0; i < 7; ++i)
{
fa = (FixedAngle(w)>>ANGLETOFINESHIFT) & FINEMASK;
x = (BASEVIDWIDTH<<(FRACBITS-1)) + (60*FINESINE(fa));
y = ((BASEVIDHEIGHT+16-20)<<(FRACBITS-1)) - (60*FINECOSINE(fa));
w += (360<<FRACBITS)/7;
patchname[4] = 'A'+(char)i;
V_DrawFixedPatch(x, y, FRACUNIT, trans, W_CachePatchName(patchname, PU_PATCH), NULL);
}
height = 18; // prevents the need for the next line
//dupz = (w*height)/18;
dupz = ((w>>FRACBITS) % height);
y = dupz+(height/4);
x = 105+dupz;
while (y >= -diffy)
{
x -= height;
y -= height;
}
while (y-dupz < maxy && x < (xspan/2))
{
V_DrawFill((BASEVIDWIDTH/2)-x-height, -diffy, height, diffy+y+height, 153);
V_DrawFill((BASEVIDWIDTH/2)+x, (maxy-y)-height, height, height+y, 153);
y += height;
x += height;
}
}
if (!soffset)
{
char_scroll += (360<<FRACBITS)/42; // like a clock, ticking at 42bpm!
if (char_scroll >= 360<<FRACBITS)
char_scroll -= 360<<FRACBITS;
if (recatkdrawtimer > (10*TICRATE))
recatkdrawtimer -= (10*TICRATE);
}
//M_DrawMenuTitle();
// draw menu (everything else goes on top of it)
// Sadly we can't just use generic mode menus because we need some extra hacks
x = currentMenu->x;
y = currentMenu->y;
dispstatus = (currentMenu->menuitems[marathonplayer].status & IT_DISPLAY);
if (dispstatus == IT_STRING || dispstatus == IT_WHITESTRING)
{
soffset = 68;
if (description[char_on].charpic->width >= 256)
V_DrawTinyScaledPatch(224, 120, 0, description[char_on].charpic);
else
V_DrawSmallScaledPatch(224, 120, 0, description[char_on].charpic);
}
else
soffset = 0;
for (i = 0; i < currentMenu->numitems; ++i)
{
dispstatus = (currentMenu->menuitems[i].status & IT_DISPLAY);
if (dispstatus != IT_STRING && dispstatus != IT_WHITESTRING)
continue;
y = currentMenu->y+currentMenu->menuitems[i].alphaKey;
if (i == itemOn)
cursory = y;
V_DrawString(x, y, (dispstatus == IT_WHITESTRING) ? V_YELLOWMAP : 0 , currentMenu->menuitems[i].text);
cv = NULL;
cvstring = NULL;
work = NULL;
if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_CVAR)
{
cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
cvstring = cv->string;
}
else if (i == marathonplayer)
{
if (description[char_on].displayname[0])
{
work = Z_StrDup(description[char_on].displayname);
cnt = 0;
while (work[cnt])
{
if (work[cnt] == '\n')
work[cnt] = ' ';
cnt++;
}
cvstring = work;
}
else
cvstring = description[char_on].skinname;
}
// Cvar specific handling
if (cvstring)
{
INT32 flags = V_YELLOWMAP;
if (cv == &cv_dummymarathon && cv->value == 2) // ultimate_selectable
flags = V_REDMAP;
// Should see nothing but strings
if (cv == &cv_dummymarathon && cv->value == 1)
{
w = V_ThinStringWidth(cvstring, 0);
V_DrawThinString(BASEVIDWIDTH - x - soffset - w, y+1, flags, cvstring);
}
else
{
w = V_StringWidth(cvstring, 0);
V_DrawString(BASEVIDWIDTH - x - soffset - w, y, flags, cvstring);
}
if (i == itemOn)
{
V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - w - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false);
}
if (work)
Z_Free(work);
}
}
// DRAW THE SKULL CURSOR
V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_PATCH));
V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text);
// Draw press ESC to exit string on main record attack menu
V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit"));
}
// ========
// END GAME
// ========
@ -12780,6 +13204,7 @@ void M_QuitResponse(INT32 ch)
if (!(netgame || cv_debug))
{
S_ResetCaptions();
marathonmode = 0;
mrand = M_RandomKey(sizeof(quitsounds)/sizeof(INT32));
if (quitsounds[mrand]) S_StartSound(NULL, quitsounds[mrand]);
@ -12803,85 +13228,3 @@ static void M_QuitSRB2(INT32 choice)
(void)choice;
M_StartMessage(quitmsg[M_RandomKey(NUM_QUITMESSAGES)], M_QuitResponse, MM_YESNO);
}
#ifdef HWRENDER
// =====================================================================
// OpenGL specific options
// =====================================================================
#define FOG_COLOR_ITEM 1
// ===================
// M_OGL_DrawFogMenu()
// ===================
static void M_OGL_DrawFogMenu(void)
{
INT32 mx, my;
mx = currentMenu->x;
my = currentMenu->y;
M_DrawGenericMenu(); // use generic drawer for cursor, items and title
V_DrawString(BASEVIDWIDTH - mx - V_StringWidth(cv_grfogcolor.string, 0),
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, V_YELLOWMAP, cv_grfogcolor.string);
// blink cursor on FOG_COLOR_ITEM if selected
if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4)
V_DrawCharacter(BASEVIDWIDTH - mx,
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false);
}
//===================
// M_HandleFogColor()
//===================
static void M_HandleFogColor(INT32 choice)
{
size_t i, l;
char temp[8];
boolean exitmenu = false; // exit to previous menu and send name change
switch (choice)
{
case KEY_DOWNARROW:
S_StartSound(NULL, sfx_menu1);
itemOn++;
break;
case KEY_UPARROW:
S_StartSound(NULL, sfx_menu1);
itemOn--;
break;
case KEY_ESCAPE:
exitmenu = true;
break;
case KEY_BACKSPACE:
S_StartSound(NULL, sfx_menu1);
strcpy(temp, cv_grfogcolor.string);
strcpy(cv_grfogcolor.zstring, "000000");
l = strlen(temp)-1;
for (i = 0; i < l; i++)
cv_grfogcolor.zstring[i + 6 - l] = temp[i];
break;
default:
if ((choice >= '0' && choice <= '9') || (choice >= 'a' && choice <= 'f')
|| (choice >= 'A' && choice <= 'F'))
{
S_StartSound(NULL, sfx_menu1);
strcpy(temp, cv_grfogcolor.string);
strcpy(cv_grfogcolor.zstring, "000000");
l = strlen(temp);
for (i = 0; i < l; i++)
cv_grfogcolor.zstring[5 - i] = temp[l - i];
cv_grfogcolor.zstring[5] = (char)choice;
}
break;
}
if (exitmenu)
{
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
}
}
#endif

View File

@ -61,6 +61,8 @@ typedef enum
MN_SP_NIGHTS_REPLAY,
MN_SP_NIGHTS_GHOST,
MN_SP_MARATHON,
// Multiplayer
MN_MP_MAIN,
MN_MP_SPLITSCREEN, // SplitServer
@ -92,8 +94,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 +419,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

@ -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;

View File

@ -3808,10 +3808,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

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;
@ -3308,7 +3309,7 @@ static boolean CanSaveLevel(INT32 mapnum)
// 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);
return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || (gamecomplete != 0) || marathonmode || !lastmaploaded);
}
static void P_RunSpecialStageWipe(void)

View File

@ -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

@ -8578,7 +8578,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;
@ -9988,9 +9988,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;
}

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

@ -2505,6 +2505,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

@ -358,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;
}
@ -1206,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();
@ -1482,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;
@ -1830,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);
@ -1843,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);
@ -1854,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

@ -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);

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

@ -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

@ -392,7 +392,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 +414,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 +1004,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 +1080,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
{

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));