diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index adce10023..7d84323bc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -470,6 +470,7 @@ if(${SRB2_CONFIG_HWRENDER}) ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_portal.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c @@ -487,6 +488,7 @@ if(${SRB2_CONFIG_HWRENDER}) ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h + ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_portal.c ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h diff --git a/src/Makefile b/src/Makefile index e3e764210..63239dfbe 100644 --- a/src/Makefile +++ b/src/Makefile @@ -293,7 +293,7 @@ ifdef NOHW else OPTS+=-DHWRENDER OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \ + $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_portal.o\ $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o $(OBJDIR)/hw_shaders.o endif @@ -563,6 +563,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/r_splats.o \ $(OBJDIR)/r_patch.o \ $(OBJDIR)/r_things.o \ + $(OBJDIR)/r_portal.o \ $(OBJDIR)/screen.o \ $(OBJDIR)/v_video.o \ $(OBJDIR)/s_sound.o \ @@ -738,7 +739,7 @@ ifdef MINGW $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ - hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h\ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h @@ -747,7 +748,7 @@ else $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \ - hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ + hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h hardware/hw_portal.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h diff --git a/src/command.c b/src/command.c index b7e1e01de..fa84626fb 100644 --- a/src/command.c +++ b/src/command.c @@ -628,7 +628,7 @@ static void COM_ExecuteString(char *ptext) // check cvars // Hurdler: added at Ebola's request ;) - // (don't flood the console in software mode with bad gr_xxx command) + // (don't flood the console in software mode with bad gl_xxx command) if (!CV_Command() && con_destlines) CONS_Printf(M_GetText("Unknown command '%s'\n"), COM_Argv(0)); } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f230ab190..2a7b9f761 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4464,7 +4464,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (server && multiplayer && motd[0] != '\0') COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); - D_AddAutoloadFiles(); + D_AddPostloadFiles(); LUAh_PlayerJoin(newplayernum); diff --git a/src/d_main.c b/src/d_main.c index 1dfe3eafa..ef3a09b8d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -99,7 +99,6 @@ UINT8 window_notinfocus = false; // DEMO LOOP // //static INT32 demosequence; -static const char *pagename = "MAP1PIC"; static char *startupwadfiles[MAX_WADFILES]; static char *startuppwads[MAX_WADFILES]; @@ -116,7 +115,6 @@ boolean devparm = false; // started game with -devparm boolean singletics = false; // timedemo boolean lastdraw = false; -postimg_t postimgtype[MAXSPLITSCREENPLAYERS]; INT32 postimgparam[MAXSPLITSCREENPLAYERS]; // These variables are only true if @@ -513,15 +511,12 @@ static boolean D_Display(void) if (rendermode == render_soft) { - if (!splitscreen) - R_ApplyViewMorph(); + if (!splitscreen) + R_ApplyViewMorph(); for (i = 0; i <= splitscreen; i++) { - if (!postimgtype[i]) - continue; - - V_DoPostProcessor(i, postimgtype[i], postimgparam[i]); + V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]); } } @@ -1072,8 +1067,7 @@ static void D_FindAddonsToAutoload(void) const char *autoloadpath; boolean postload; - INT32 i, len; - boolean hasprefix = false; + INT32 i; char wadsToAutoload[256] = ""; // does it exist tho @@ -1095,7 +1089,8 @@ static void D_FindAddonsToAutoload(void) || (wadsToAutoload[0] == '#')) continue; // this marks it so that it loads after loading server addons - else if (fastncmp(wadsToAutoload, "postload ", 9)) { + else if (fastncmp(wadsToAutoload, "postload ", 9)) + { strremove(wadsToAutoload, "postload "); postload = true; } @@ -1107,34 +1102,10 @@ static void D_FindAddonsToAutoload(void) wadsToAutoload[i] = '\0'; } - len = strlen(wadsToAutoload); - hasprefix = false; - - for (i = 0; i < len; ++i) + if (!postload && W_CheckPostLoadList(wadsToAutoload)) { - if (wadsToAutoload[i] == '_') - { - hasprefix = true; - break; - } - } - - // Lets just hope no one adds bonuschars in autoload - if (hasprefix) - { - // We searching for c in prefix, which stands for "character" and doesn't work well with - // autoload atm, only fine for postload - for (i = 0; i < len; ++i) - { - if (wadsToAutoload[i] == '_') break; // Prefix end - - if (wadsToAutoload[i] == 'c' || wadsToAutoload[i] == 'C') - { - CONS_Alert(CONS_WARNING, "forcing postload for %s as local skin\n", wadsToAutoload); - postload = true; - break; // Found it - } - } + CONS_Printf("forcing postload for file %s\n", wadsToAutoload); + postload = true; } // LOAD IT @@ -1152,30 +1123,30 @@ static void D_FindAddonsToAutoload(void) fclose(autoloadconfigfile); } -void D_AddAutoloadFiles(void) +static void D_AddAutoloadFiles(void) { - if (wasautoloaded && postautoloaded) + if (wasautoloaded) return; - if (!wasautoloaded && !modeattacking) - { - CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n"); - if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0) - CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n"); - D_CleanFile(autoloadwadfiles); + CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n"); + if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0) + CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n"); + D_CleanFile(autoloadwadfiles); - wasautoloaded = true; - } + wasautoloaded = true; +} - if ((!postautoloaded) && netgame) - { - CONS_Printf("D_AutoloadFile(): Loading postloaded addons...\n"); - if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0) - CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n"); - D_CleanFile(autoloadwadfilespost); +void D_AddPostloadFiles(void) +{ + if (postautoloaded || !netgame) + return; - postautoloaded = true; - } + CONS_Printf("D_AddPostloadFiles(): Loading postloaded addons...\n"); + if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0) + CONS_Printf("D_AddPostloadFiles(): Are you sure you put in valid files or what?\n"); + D_CleanFile(autoloadwadfilespost); + + postautoloaded = true; } void D_CleanFile(char **filearray) @@ -1870,6 +1841,8 @@ void D_SRB2Main(void) CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); + D_AddAutoloadFiles(); + // Set up splitscreen players before joining! if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm())) { @@ -2071,7 +2044,6 @@ void D_SRB2Main(void) if (dedicated && server) { - pagename = "TITLESKY"; levelstarttic = gametic; G_SetGamestate(GS_LEVEL); if (!P_SetupLevel(false, false)) diff --git a/src/d_main.h b/src/d_main.h index 851eaa8b5..ddd6c3ab4 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -45,12 +45,12 @@ extern boolean statdp; // stat display for extended player setup extern boolean nametaggfx; // Nametag stuffs extern boolean driftgaugegfx; -void D_AddAutoloadFiles(void); - +// autoload stuff extern boolean autoloading; extern boolean autoloaded; extern boolean postautoloaded; -extern boolean wasautoloaded; + +void D_AddPostloadFiles(void); extern char *autoloadwadfilespost[MAX_WADFILES]; extern char *autoloadwadfiles[MAX_WADFILES]; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e54251125..281fb8856 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2983,6 +2983,14 @@ static void Command_Map_f(void) // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer else { + if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL) + { + CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum)); + Z_Free(realmapname); + Z_Free(mapname); + return; + } + if (!(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype))) { CONS_Alert(CONS_WARNING, M_GetText("Course %s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum), diff --git a/src/d_player.h b/src/d_player.h index c2a5d32ce..09400fa9b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -413,6 +413,8 @@ typedef struct player_s // See pflags_t, above. pflags_t pflags; + UINT16 postimgflags; + // playing animation. panim_t panim; diff --git a/src/dehacked.c b/src/dehacked.c index e1f3adba2..dc4288be5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9149,7 +9149,6 @@ int LUA_EnumLib(lua_State *L) PUSHGETTER(globalweather, u8); PUSHGETTER(levelskynum, i32); PUSHGETTER(globallevelskynum, i32); - PUSHGETTER((*mapmusname), str); PUSHGETTER(mapmusflags, u16); PUSHGETTER(mapmusposition, u32); PUSHGETTER(gravity, fxp); @@ -9166,6 +9165,11 @@ int LUA_EnumLib(lua_State *L) PUSHGETTER(racecountdown, u32); PUSHGETTER(exitcountdown, u32); + lua_pushcfunction(L, lua_glib_new_getter); + lua_pushliteral(L, "mapmusname"); + lua_glib_push_str_getter(L, mapmusname); + lua_call(L, 2, 0); + lua_pushcfunction(L, lua_glib_new_getter); lua_pushliteral(L, "mariomode"); lua_pushcfunction(L, lua_enumlib_mariomode_get); diff --git a/src/doomdef.h b/src/doomdef.h index 046cd6897..c426e64e1 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -127,8 +127,8 @@ extern char logfilename[1024]; #else #define VERSION 1 // Game version #define SUBVERSION 6 // more precise version number -#define VERSIONSTRING "Saturn v7.1" -#define VERSIONSTRINGW L"Saturn v7.1" +#define VERSIONSTRING "Saturn v7.2" +#define VERSIONSTRINGW L"Saturn v7.2" // Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates! // And change CMakeLists.txt (not src/, but in root), for CMake users! // AND appveyor.yml, for the build bots! diff --git a/src/doomstat.h b/src/doomstat.h index 01d98fd4e..f70f97059 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -112,7 +112,6 @@ extern UINT8 window_notinfocus; // are we in focus? (backend independant -- hand extern boolean nodrawers; extern boolean noblit; extern boolean lastdraw; -extern postimg_t postimgtype[MAXSPLITSCREENPLAYERS]; extern INT32 postimgparam[MAXSPLITSCREENPLAYERS]; extern INT32 viewwindowx, viewwindowy; diff --git a/src/doomtype.h b/src/doomtype.h index 1dcf47ea7..d7ad320c8 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -344,14 +344,12 @@ typedef union FColorRGBA RGBA_t; typedef enum { - postimg_none, - postimg_water, - postimg_motion, - postimg_flip, - postimg_heat, - postimg_mirror, - postimg_mirrorflip -} postimg_t; + POSTIMG_WATER = 1, // Underwater screen effect. + POSTIMG_MOTION = 1<<1, // Unused motion blur effect. + POSTIMG_FLIP = 1<<2, // Flipcam screen effect. + POSTIMG_HEAT = 1<<3, // Heatwave screen effect. + POSTIMG_MIRROR = 1<<4, // encore screen effect. +} postimgflag_t; typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) #define LUMPERROR UINT32_MAX diff --git a/src/g_game.c b/src/g_game.c index 2d2fe7bb6..1cf6f2ddb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1492,7 +1492,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) //Reset away view if a command is given. if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayers[0] != consoleplayer && ssplayer == 1) + { displayplayers[0] = consoleplayer; + // i dont like this lmao + if (cv_director.value) + CV_SetValue(&cv_director, 0); + } } @@ -4542,8 +4547,7 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep, break; } } - else - if (apromapnum == 0 || wanttable) + else if (apromapnum == 0 || wanttable) { /* LEVEL 1--match keywords verbatim */ if (( aprop = strcasestr(realmapname, mapname) )) @@ -4634,8 +4638,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) { if (mapname[0] == '*') // current map return gamemap; - else if (mapname[0] == '?') - return G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL); + else if (mapname[0] == '?' && mapheaderinfo[gamemap-1]) + return G_RandMap(G_TOLFlag(gametype), gamemap-1, false, 0, false, NULL)+1; else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map { newmapnum = mapheaderinfo[gamemap-1]->nextlevel; diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index a4984a905..75b29b697 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -46,12 +46,12 @@ int unsortedVertexArrayAllocSize = 65536; // Call HWR_RenderBatches to render all the collected geometry. void HWR_StartBatching(void) { - if (currently_batching) + if (currently_batching) { - I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches"); + I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches"); } - // init arrays if that has not been done yet + // init arrays if that has not been done yet if (!finalVertexArray) { finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector)); @@ -61,7 +61,7 @@ void HWR_StartBatching(void) unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector)); } - currently_batching = true; + currently_batching = true; } // This replaces the direct calls to pfnSetTexture in cases where batching is available. @@ -69,14 +69,14 @@ void HWR_StartBatching(void) // 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 (currently_batching) + { + current_texture = texture; + } + else + { + HWD.pfnSetTexture(texture); + } } // If batching is enabled, this function collects the polygon data and the chosen texture @@ -84,7 +84,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture) // render the polygon immediately. void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial) { - if (currently_batching) + 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 @@ -220,7 +220,7 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2) // the rendering backend to draw them. void HWR_RenderBatches(void) { - int finalVertexWritePos = 0;// position in finalVertexArray + int finalVertexWritePos = 0;// position in finalVertexArray int finalIndexWritePos = 0;// position in finalVertexIndexArray int polygonReadPos = 0;// position in polygonArraySorted @@ -236,7 +236,7 @@ void HWR_RenderBatches(void) int i; - if (!currently_batching) + if (!currently_batching) I_Error("HWR_RenderBatches called without starting batching"); nextSurfaceInfo.LightInfo.fade_end = 0; @@ -256,6 +256,7 @@ void HWR_RenderBatches(void) ps_hw_numcalls.value.i = ps_hw_numverts.value.i = 0; ps_hw_numshaders.value.i = ps_hw_numtextures.value.i = ps_hw_numpolyflags.value.i = ps_hw_numcolors.value.i = 1; + // init polygonArraySorted for (i = 0; i < polygonArraySize; i++) { @@ -264,11 +265,12 @@ void HWR_RenderBatches(void) // sort polygons PS_START_TIMING(ps_hw_batchsorttime); - if (cv_grshaders.value && gr_shadersavailable) + if (cv_glshaders.value && gl_shadersavailable) qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygons); else qs22j(polygonArraySorted, polygonArraySize, sizeof(PolygonArrayEntry *), comparePolygonsNoShaders); PS_STOP_TIMING(ps_hw_batchsorttime); + // sort order // 1. shader // 2. texture @@ -287,14 +289,14 @@ void HWR_RenderBatches(void) // set state for first batch - if (cv_grshaders.value && gr_shadersavailable) + if (cv_glshaders.value && gl_shadersavailable) { HWD.pfnSetShader(currentShader); } if (currentPolyFlags & PF_NoTexture) currentTexture = NULL; - else + else HWD.pfnSetTexture(currentTexture); while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons) @@ -369,7 +371,7 @@ void HWR_RenderBatches(void) nextSurfaceInfo = nextEntry->surf; if (nextPolyFlags & PF_NoTexture) nextTexture = 0; - if (currentShader != nextShader && cv_grshaders.value && gr_shadersavailable) + if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable) { changeState = true; changeShader = true; @@ -384,7 +386,7 @@ void HWR_RenderBatches(void) changeState = true; changePolyFlags = true; } - if (cv_grshaders.value && gr_shadersavailable) + if (cv_glshaders.value && gl_shadersavailable) { if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba || currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba || @@ -457,6 +459,7 @@ void HWR_RenderBatches(void) ps_hw_numcolors.value.i++; } + // and that should be it? } } // reset the arrays (set sizes to 0) @@ -466,5 +469,4 @@ void HWR_RenderBatches(void) PS_STOP_TIMING(ps_hw_batchdrawtime); } - #endif // HWRENDER diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index a5f76df06..88ef77320 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -46,7 +46,7 @@ typedef struct // when loading the map, this is set to true if portals are found. // if no portals are found, the portal scanning phase can be skipped while rendering, saving a bit of time. -boolean gr_maphasportals = false; +boolean gl_maphasportals = false; // ========================================================================== // FLOOR & CEILING CONVEX POLYS GENERATION @@ -371,14 +371,14 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly) line_t *line = lseg->linedef; // portal check - if (!gr_maphasportals && line->special == 40 && lseg->side == 0) + if (!gl_maphasportals && line->special == 40 && lseg->side == 0) { // Find the other side! INT32 line2 = P_FindSpecialLineFromTag(40, line->tag, -1); if (line == &lines[line2]) line2 = P_FindSpecialLineFromTag(40, line->tag, line2); if (line2 >= 0) // found it! - gr_maphasportals = 1; + gl_maphasportals = 1; } p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x); @@ -768,7 +768,7 @@ static INT32 SolveTProblem(void) INT32 i; size_t l; - if (cv_grsolvetjoin.value == 0) + if (cv_glsolvetjoin.value == 0) return 0; CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n"); @@ -905,7 +905,7 @@ void HWR_CreatePlanePolygons(INT32 bspnum) #endif // reset the portal flag - gr_maphasportals = 0; + gl_maphasportals = 0; // find min/max boundaries of map //CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n"); @@ -923,9 +923,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum) I_Error("couldn't malloc extrasubsectors totsubsectors %s\n", sizeu1(totsubsectors)); // allocate table for back to front drawing of subsectors - /*gr_drawsubsectors = (INT16 *)malloc(sizeof (*gr_drawsubsectors) * totsubsectors); - if (!gr_drawsubsectors) - I_Error("couldn't malloc gr_drawsubsectors\n");*/ + /*gl_drawsubsectors = (INT16 *)malloc(sizeof (*gl_drawsubsectors) * totsubsectors); + if (!gl_drawsubsectors) + I_Error("couldn't malloc gl_drawsubsectors\n");*/ // number of the first new subsector that might be added addsubsector = numsubsectors; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 9f02007d4..1182348c9 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -166,7 +166,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, if (pwidth <= 0 || pheight <= 0) return; - + palette = HWR_GetTexturePalette(); ncols = pwidth; @@ -216,7 +216,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (texture->width <= 0 || texture->height <= 0) return; - + palette = HWR_GetTexturePalette(); x1 = patch->originx; @@ -275,15 +275,15 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, } } -static UINT8 *MakeBlock(GLMipmap_t *grMipmap) +static UINT8 *MakeBlock(GLMipmap_t *glMipmap) { UINT8 *block; INT32 bpp, i; UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); - INT32 blocksize = (grMipmap->width * grMipmap->height); + INT32 blocksize = (glMipmap->width * glMipmap->height); - bpp = format2bpp(grMipmap->format); - block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->data)); + bpp = format2bpp(glMipmap->format); + block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(glMipmap->data)); switch (bpp) { @@ -303,7 +303,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) // Create a composite texture from patches, adapt the texture size to a power of 2 // height and width for the hardware texture cache. // -static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noencore) +static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noencore) { UINT8 *block; texture_t *texture; @@ -313,7 +313,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe INT32 i; boolean skyspecial = false; //poor hack for Legacy large skies.. - + RGBA_t *palette; palette = HWR_GetTexturePalette(); @@ -328,30 +328,30 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe ) { skyspecial = true; - grtex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky + gltex->mipmap.flags = TF_WRAPXY; // don't use the chromakey for sky } else - grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; + gltex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; - grtex->mipmap.width = (UINT16)texture->width; - grtex->mipmap.height = (UINT16)texture->height; + gltex->mipmap.width = (UINT16)texture->width; + gltex->mipmap.height = (UINT16)texture->height; if (skyspecial) - grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... + gltex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... else - grtex->mipmap.format = textureformat; + gltex->mipmap.format = textureformat; - grtex->mipmap.colormap = colormaps; + gltex->mipmap.colormap = colormaps; #ifdef GLENCORE if (encoremap && !noencore) - grtex->mipmap.colormap += COLORMAP_REMAPOFFSET; + gltex->mipmap.colormap += COLORMAP_REMAPOFFSET; #endif - + blockwidth = texture->width; blockheight = texture->height; blocksize = (blockwidth * blockheight); - block = MakeBlock(&grtex->mipmap); + block = MakeBlock(&gltex->mipmap); if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) { @@ -375,7 +375,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); - HWR_DrawTexturePatchInCache(&grtex->mipmap, + HWR_DrawTexturePatchInCache(&gltex->mipmap, blockwidth, blockheight, texture, patch, realpatch); @@ -383,78 +383,78 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, boolean noe } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( - if (format2bpp(grtex->mipmap.format)==4) + if (format2bpp(gltex->mipmap.format)==4) { for (i = 3; i < blocksize*4; i += 4) // blocksize*4 because blocksize doesn't include the bpp { if (block[i] != 0) continue; - grtex->mipmap.flags |= TF_TRANSPARENT; + gltex->mipmap.flags |= TF_TRANSPARENT; break; } } - grtex->scaleX = 1.0f/(texture->width*FRACUNIT); - grtex->scaleY = 1.0f/(texture->height*FRACUNIT); + gltex->scaleX = 1.0f/(texture->width*FRACUNIT); + gltex->scaleY = 1.0f/(texture->height*FRACUNIT); } -// patch may be NULL if grMipmap has been initialised already and makebitmap is false -void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) +// patch may be NULL if glMipmap has been initialised already and makebitmap is false +void HWR_MakePatch (patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap) { // don't do it twice (like a cache) - if (grMipmap->width == 0) + if (glMipmap->width == 0) { // save the original patch header so that the GLPatch can be casted // into a standard patch_t struct and the existing code can get the // orginal patch dimensions and offsets. - grPatch->width = SHORT(patch->width); - grPatch->height = SHORT(patch->height); - grPatch->leftoffset = SHORT(patch->leftoffset); - grPatch->topoffset = SHORT(patch->topoffset); + glPatch->width = SHORT(patch->width); + glPatch->height = SHORT(patch->height); + glPatch->leftoffset = SHORT(patch->leftoffset); + glPatch->topoffset = SHORT(patch->topoffset); - //grMipmap->width = (UINT16)SHORT(patch->width); - //grMipmap->height = (UINT16)SHORT(patch->height); - grMipmap->width = grMipmap->height = 1; - while (grMipmap->width < grPatch->width) grMipmap->width <<= 1; - while (grMipmap->height < grPatch->height) grMipmap->height <<= 1; + //glMipmap->width = (UINT16)SHORT(patch->width); + //glMipmap->height = (UINT16)SHORT(patch->height); + glMipmap->width = glMipmap->height = 1; + while (glMipmap->width < glPatch->width) glMipmap->width <<= 1; + while (glMipmap->height < glPatch->height) glMipmap->height <<= 1; // no wrap around, no chroma key - grMipmap->flags = 0; + glMipmap->flags = 0; // setup the texture info - grMipmap->format = patchformat; - - //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; + glMipmap->format = patchformat; + + //glPatch->max_s = glPatch->max_t = 1.0f; + glPatch->max_s = (float)glPatch->width / (float)glMipmap->width; + glPatch->max_t = (float)glPatch->height / (float)glMipmap->height; } - Z_Free(grMipmap->data); - grMipmap->data = NULL; + Z_Free(glMipmap->data); + glMipmap->data = NULL; if (makebitmap) { - MakeBlock(grMipmap); - HWR_DrawPatchInCache(grMipmap, - grMipmap->width, grMipmap->height, - grPatch->width, grPatch->height, + MakeBlock(glMipmap); + HWR_DrawPatchInCache(glMipmap, + glMipmap->width, glMipmap->height, + glPatch->width, glPatch->height, patch); } - //grPatch->max_s = grPatch->max_t = 1.0f; + //glPatch->max_s = glPatch->max_t = 1.0f; } // ================================================= // CACHING HANDLING // ================================================= -static size_t gr_numtextures; -static GLMapTexture_t *gr_textures; // For all textures +static size_t gl_numtextures; +static GLMapTexture_t *gl_textures; // For all textures void HWR_InitTextureCache(void) { - gr_numtextures = 0; - gr_textures = NULL; + gl_numtextures = 0; + gl_textures = NULL; } // Callback function for HWR_FreeTextureCache. @@ -526,10 +526,10 @@ void HWR_FreeTextureCache(void) // now the heap don't have any 'user' pointing to our // texturecache info, we can free it - if (gr_textures) - free(gr_textures); - gr_textures = NULL; - gr_numtextures = 0; + if (gl_textures) + free(gl_textures); + gl_textures = NULL; + gl_numtextures = 0; } void HWR_LoadTextures(size_t pnumtextures) @@ -537,13 +537,13 @@ void HWR_LoadTextures(size_t pnumtextures) // we must free it since numtextures changed HWR_FreeTextureCache(); - gr_numtextures = pnumtextures; + gl_numtextures = pnumtextures; #ifdef GLENCORE - gr_textures = calloc(pnumtextures, sizeof (*gr_textures)*2); // *2 - 1 for encore-remapped texture and another for noencore texture (unused when not in encore) + gl_textures = calloc(pnumtextures, sizeof (*gl_textures)*2); // *2 - 1 for encore-remapped texture and another for noencore texture (unused when not in encore) #else - gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); + gl_textures = calloc(pnumtextures, sizeof (*gl_textures)); #endif - if (gr_textures == NULL) + if (gl_textures == NULL) I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!"); } @@ -552,9 +552,9 @@ void HWR_LoadTextures(size_t pnumtextures) // -------------------------------------------------------------------------- GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore) { - GLMapTexture_t *grtex; + GLMapTexture_t *gltex; - if (tex < 0 || tex >= (signed)gr_numtextures) + if (tex < 0 || tex >= (signed)gl_numtextures) { #ifdef PARANOIA I_Error("HWR_GetTexture: Invalid texture ID %d", tex); @@ -563,25 +563,25 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore) #endif } #ifdef GLENCORE - grtex = &gr_textures[tex*2 + (encoremap && !noencore ? 0 : 1)]; + gltex = &gl_textures[tex*2 + (encoremap && !noencore ? 0 : 1)]; #else - grtex = &gr_textures[tex]; + gltex = &gl_textures[tex]; #endif - if (!grtex->mipmap.data && !grtex->mipmap.downloaded) - HWR_GenerateTexture(tex, grtex, noencore); + if (!gltex->mipmap.data && !gltex->mipmap.downloaded) + HWR_GenerateTexture(tex, gltex, noencore); // 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); + if (!gltex->mipmap.downloaded) + HWD.pfnSetTexture(&gltex->mipmap); + HWR_SetCurrentTexture(&gltex->mipmap); // The system-memory data can be purged now. - Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(gltex->mipmap.data, PU_HWRCACHE_UNLOCKED); - return grtex; + return gltex; } -static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) +static void HWR_CacheFlat(GLMipmap_t *glMipmap, lumpnum_t flatlumpnum) { #ifdef GLENCORE UINT8 *flat; @@ -590,8 +590,8 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) size_t size, pflatsize; // setup the texture info - grMipmap->format = GL_TEXFMT_P_8; - grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; + glMipmap->format = GL_TEXFMT_P_8; + glMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; size = W_LumpLength(flatlumpnum); @@ -619,21 +619,21 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) pflatsize = 64; break; } - grMipmap->width = (UINT16)pflatsize; - grMipmap->height = (UINT16)pflatsize; + glMipmap->width = (UINT16)pflatsize; + glMipmap->height = (UINT16)pflatsize; // the flat raw data needn't be converted with palettized textures W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum), - PU_HWRCACHE, &grMipmap->data)); + PU_HWRCACHE, &glMipmap->data)); #ifdef GLENCORE - flat = grMipmap->data; + flat = glMipmap->data; for (steppy = 0; steppy < size; steppy++) { if (flat[steppy] == HWR_PATCHES_CHROMAKEY_COLORINDEX) continue; - flat[steppy] = grMipmap->colormap[flat[steppy]]; + flat[steppy] = glMipmap->colormap[flat[steppy]]; } #endif } @@ -641,44 +641,44 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) // Download a Doom 'flat' to the hardware cache and make it ready for use void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap) { - GLMipmap_t *grmip; - + GLMipmap_t *glmip; + if (flatlumpnum == LUMPERROR) return; - grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap; + glmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap; - grmip->colormap = colormaps; + glmip->colormap = colormaps; #ifdef GLENCORE if (!noencoremap && encoremap) - grmip->colormap += COLORMAP_REMAPOFFSET; + glmip->colormap += COLORMAP_REMAPOFFSET; #endif - if (!grmip->downloaded && !grmip->data) - HWR_CacheFlat(grmip, flatlumpnum); + if (!glmip->downloaded && !glmip->data) + HWR_CacheFlat(glmip, flatlumpnum); // If hardware does not have the texture, then call pfnSetTexture to upload it - if (!grmip->downloaded) - HWD.pfnSetTexture(grmip); - HWR_SetCurrentTexture(grmip); + if (!glmip->downloaded) + HWD.pfnSetTexture(glmip); + HWR_SetCurrentTexture(glmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED); } // // HWR_LoadMappedPatch(): replace the skin color of the sprite in cache // : load it first in doom cache if not already // -static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) +static void HWR_LoadMappedPatch(GLMipmap_t *glmip, GLPatch_t *gpatch) { - if (!grmip->downloaded && !grmip->data) + if (!glmip->downloaded && !glmip->data) { patch_t *patch = gpatch->rawpatch; if (!patch) patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); - HWR_MakePatch(patch, gpatch, grmip, true); + HWR_MakePatch(patch, gpatch, glmip, true); // You can't free rawpatch for some reason? // (Obviously I can't, sprite rotation needs that...) @@ -688,12 +688,12 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) } // If hardware does not have the texture, then call pfnSetTexture to upload it - if (!grmip->downloaded) - HWD.pfnSetTexture(grmip); - HWR_SetCurrentTexture(grmip); + if (!glmip->downloaded) + HWD.pfnSetTexture(glmip); + HWR_SetCurrentTexture(glmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED); } // -----------------+ @@ -732,7 +732,7 @@ void HWR_GetPatch(GLPatch_t *gpatch) // -------------------+ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { - GLMipmap_t *grmip, *newmip; + GLMipmap_t *glmip, *newmip; // Blatant hack for encore colormapping aside... if (colormap == colormaps || colormap == NULL || colormap == (const UINT8*)(COLORMAP_REMAPOFFSET)) @@ -744,14 +744,14 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) // search for the mimmap // skip the first (no colormap translated) - for (grmip = gpatch->mipmap; grmip->nextcolormap; ) + for (glmip = gpatch->mipmap; glmip->nextcolormap; ) { - grmip = grmip->nextcolormap; + glmip = glmip->nextcolormap; - if (grmip->colormap != colormap) + if (glmip->colormap != colormap) continue; - HWR_LoadMappedPatch(grmip, gpatch); + HWR_LoadMappedPatch(glmip, gpatch); return; } // not found, create it! @@ -764,7 +764,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) newmip = calloc(1, sizeof (*newmip)); if (newmip == NULL) I_Error("%s: Out of memory", "HWR_GetMappedPatch"); - grmip->nextcolormap = newmip; + glmip->nextcolormap = newmip; newmip->colormap = colormap; HWR_LoadMappedPatch(newmip, gpatch); @@ -781,18 +781,18 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch) GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) { aatree_t *hwrcache = wadfiles[wadnum]->hwrcache; - GLPatch_t *grpatch; + GLPatch_t *glpatch; - if (!(grpatch = M_AATreeGet(hwrcache, lumpnum))) + if (!(glpatch = M_AATreeGet(hwrcache, lumpnum))) { - grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grpatch->wadnum = wadnum; - grpatch->lumpnum = lumpnum; - grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - M_AATreeSet(hwrcache, lumpnum, grpatch); + glpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); + glpatch->wadnum = wadnum; + glpatch->lumpnum = lumpnum; + glpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); + M_AATreeSet(hwrcache, lumpnum, glpatch); } - return grpatch; + return glpatch; } GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum) @@ -840,14 +840,14 @@ static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 Z_Free(flat); } -static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) +static void HWR_CacheFadeMask(GLMipmap_t *glMipmap, lumpnum_t fademasklumpnum) { size_t size; UINT16 fmheight = 0, fmwidth = 0; // setup the texture info - grMipmap->format = GL_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later - grMipmap->flags = 0; + glMipmap->format = GL_TEXFMT_ALPHA_8; // put the correct alpha levels straight in so I don't need to convert it later + glMipmap->flags = 0; size = W_LumpLength(fademasklumpnum); @@ -876,28 +876,28 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum) } // Thankfully, this will still work for this scenario - grMipmap->width = fmwidth; - grMipmap->height = fmheight; + glMipmap->width = fmwidth; + glMipmap->height = fmheight; - MakeBlock(grMipmap); + MakeBlock(glMipmap); - HWR_DrawFadeMaskInCache(grMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight); + HWR_DrawFadeMaskInCache(glMipmap, fmwidth, fmheight, fademasklumpnum, fmwidth, fmheight); // I DO need to convert this because it isn't power of 2 and we need the alpha } void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { - GLMipmap_t *grmip; + GLMipmap_t *glmip; - grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; + glmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; - if (!grmip->downloaded && !grmip->data) - HWR_CacheFadeMask(grmip, fademasklumpnum); + if (!glmip->downloaded && !glmip->data) + HWR_CacheFadeMask(glmip, fademasklumpnum); - HWD.pfnSetTexture(grmip); + HWD.pfnSetTexture(glmip); // The system-memory data can be purged now. - Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED); } // ================================================= @@ -909,15 +909,15 @@ void HWR_SetPalette(RGBA_t *palette) if (HWR_ShouldUsePaletteRendering()) { // set the palette for palette postprocessing - if (cv_grpalettedepth.value == 16) + if (cv_glpalettedepth.value == 16) { // crush to 16-bit rgb565, like software currently does in the standard configuration // Note: Software's screenshots have the 24-bit palette, but the screen gets // the 16-bit version! For making comparison screenshots either use an external screenshot // tool or set the palette depth to 24 bits. RGBA_t crushed_palette[256]; - int i; - for (i = 0; i < 256; i++) + + for (int i = 0; i < 256; i++) { float fred = (float)(palette[i].s.red >> 3); float fgreen = (float)(palette[i].s.green >> 2); @@ -935,7 +935,7 @@ void HWR_SetPalette(RGBA_t *palette) } // this part is responsible for keeping track of the palette OUTSIDE of a level. - if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN)) + if (gamestate != GS_LEVEL || gamestate == GS_TITLESCREEN) HWR_SetMapPalette(); } else @@ -987,11 +987,9 @@ void HWR_SetMapPalette(void) RGBA_t *palette; int i; - if ((!(gamestate == GS_LEVEL)) || (gamestate == GS_TITLESCREEN)) + if (gamestate != GS_LEVEL || gamestate == GS_TITLESCREEN) { - // outside of a level, pMasterPalette should have PLAYPAL ready for us - //palette = pMasterPalette; // we dont have this in kart so just use pLocalPalette as before - + // outside of a level, pLocalPalette should have PLAYPAL ready for us palette = pLocalPalette; } else @@ -1001,8 +999,10 @@ void HWR_SetMapPalette(void) lumpnum_t lumpnum = W_GetNumForName(GetPalette()); size_t palsize = W_LumpLength(lumpnum); UINT8 *RGB_data; + if (palsize < 768) // 256 * 3 I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n"); + RGB_data = W_CacheLumpNum(lumpnum, PU_CACHE); // we got the RGB palette now, but we need it in RGBA format. for (i = 0; i < 256; i++) @@ -1050,7 +1050,6 @@ UINT32 HWR_CreateLightTable(UINT8 *lighttable) return id; } - // get hwr lighttable id for colormap, create it if it doesn't already exist UINT32 HWR_GetLightTableID(extracolormap_t *colormap) { diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index dc8d44ca8..85261c859 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -121,8 +121,6 @@ typedef struct poly_t *planepoly; // the generated convex polygon } extrasubsector_t; -//here lies gr_vissprite - // Kart features #define USE_FTRANSFORM_ANGLEZ #define USE_FTRANSFORM_MIRROR @@ -289,9 +287,6 @@ typedef struct FSurfaceInfo FSurfaceInfo; enum hwdsetspecialstate { -#ifdef USE_FBO_OGL - HWD_SET_FRAMEBUFFER, -#endif HWD_SET_SHADERS, HWD_SET_TEXTUREFILTERMODE, diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index ee0fd0b85..e39398ff2 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -569,7 +569,7 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) if (color & 0xFF00) // Do COLORMAP fade. { - if (HWR_ShouldUsePaletteRendering() && cv_grscreentextures.value) + if (HWR_ShouldUsePaletteRendering() && cv_glscreentextures.value) { const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2; @@ -593,12 +593,12 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) { RGBA_t *palette = HWR_GetTexturePalette(); Surf.PolyColor.rgba = palette[color&0xFF].rgba; - + if (HWR_ShouldUsePaletteRendering()) Surf.PolyColor.s.alpha = softwaretranstogl[strength]; else Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f); - + poly_flags |= PF_Translucent; } @@ -652,17 +652,17 @@ void HWR_DrawViewBorder(INT32 clearlines) INT32 basewindowx, basewindowy; GLPatch_t *patch; -// if (gr_viewwidth == vid.width) +// if (gl_viewwidth == vid.width) // return; if (!clearlines) clearlines = BASEVIDHEIGHT; // refresh all // calc view size based on original game resolution - baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7; - baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewheight), vid.fdupy)); - top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowy), vid.fdupy)); - side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowx), vid.fdupx)); + baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7; + baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_viewheight), vid.fdupy)); + top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowy), vid.fdupy)); + side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gl_baseviewwindowx), vid.fdupx)); // top HWR_DrawFlatFill(0, 0, @@ -776,9 +776,9 @@ void HWR_drawAMline(const fline_t *fl, INT32 color) F2DCoord v1, v2; RGBA_t color_rgba; RGBA_t *palette = HWR_GetTexturePalette(); - + color_rgba = palette[color&0xFF]; - + v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width); v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height); diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 4a8a5dd9c..fe346f4c9 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -23,7 +23,7 @@ // needed for sprite rendering // equivalent of the software renderer's vissprites -typedef struct gr_vissprite_s +typedef struct gl_vissprite_s { float x1, x2; float z1, z2; @@ -32,7 +32,6 @@ typedef struct gr_vissprite_s float scale; float spritexscale, spriteyscale; float spritexoffset, spriteyoffset; - UINT32 renderflags; GLPatch_t *gpatch; boolean flip; UINT8 translucency; //alpha level 0-255 @@ -42,7 +41,7 @@ typedef struct gr_vissprite_s //Hurdler: 25/04/2000: now support colormap in hardware mode UINT8 *colormap; INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing -} gr_vissprite_t; +} gl_vissprite_t; // -------- // hw_bsp.c @@ -64,7 +63,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap); GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore); void HWR_GetPatch(GLPatch_t *gpatch); void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); -void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); +void HWR_MakePatch(patch_t *patch, GLPatch_t *glPatch, GLMipmap_t *glMipmap, boolean makebitmap); void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_SetPalette(RGBA_t *palette); @@ -82,14 +81,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); extern INT32 patchformat; extern INT32 textureformat; -// -------- -// hw_main.c // originally hw_drawnodes.c from HWPortal branch -// -------- -void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); - // -------- // hw_shaders.c // -------- diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5d243d4c3..b02730814 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -24,103 +24,75 @@ #include "hw_batching.h" #include "hw_md2.h" #include "hw_clip.h" +#include "hw_portal.h" #include "r_opengl/r_opengl.h" -#include "../i_video.h" // for rendermode == render_glide -#include "../v_video.h" +#include "../d_clisrv.h" +#include "../g_game.h" +#include "../m_argv.h" // parm functions for msaa +#include "../m_cheat.h" +#include "../m_menu.h" // ogl menu updating + +#include "../r_bsp.h" // R_NoEncore +#include "../r_data.h" +#include "../r_fps.h" +#include "../r_local.h" +#include "../r_main.h" // cv_fov +#include "../r_patch.h" // a mystery as to what this is for +#include "../r_portal.h" +#ifdef WALLSPLATS +#include "../r_splats.h" +#endif +#include "../r_state.h" + +#include "../i_system.h" +#include "../i_video.h" #include "../p_local.h" #include "../p_setup.h" -#include "../r_fps.h" -#include "../r_state.h" -#include "../r_local.h" -#include "../r_data.h" -#include "../r_patch.h" // a mystery as to what this is for -#include "../r_bsp.h" // R_NoEncore -#include "../r_main.h" // cv_fov -#include "../d_clisrv.h" +#include "../p_slopes.h" +#include "../st_stuff.h" +#include "../v_video.h" #include "../w_wad.h" #include "../z_zone.h" -#include "../r_splats.h" -#include "../g_game.h" -#include "../st_stuff.h" -#include "../i_system.h" -#include "../m_cheat.h" -#include "../m_argv.h" // parm functions for msaa -#include "../p_slopes.h" + +// ========================================================================== +// Globals +// ========================================================================== #define ABS(x) ((x) < 0 ? -(x) : (x)) - #define SOFTLIGHT(llevel) HWR_ShouldUsePaletteRendering() ? ((llevel) >> LIGHTSEGSHIFT) << LIGHTSEGSHIFT : (llevel) -// ========================================================================== -// the hardware driver object -// ========================================================================== struct hwdriver_s hwdriver; // false if shaders have not been initialized yet, or if shaders are not available -boolean gr_shadersavailable = false; +boolean gl_shadersavailable = false; // Whether the internal state is set to palette rendering or not. -static boolean gr_palette_rendering_state = false; +static boolean gl_palette_rendering_state = false; -// ========================================================================== -// Commands and console variables -// ========================================================================== +boolean gl_drawing_stencil = false; -static void HWR_RollTransform(FTransform *tr, angle_t roll); +static INT32 current_bsp_culling_distance = 0; -#ifdef USE_FBO_OGL -static void CV_grframebuffer_OnChange(void); -#endif -static void CV_filtermode_ONChange(void); -static void CV_anisotropic_ONChange(void); -static void CV_screentextures_ONChange(void); -static void CV_grshaders_OnChange(void); -static void CV_grpaletterendering_OnChange(void); -static void CV_grpalettedepth_OnChange(void); +// base values set at SetViewSize +float gl_baseviewwindowy, gl_baseviewwindowx; +static float gl_viewwindowy, gl_viewwindowx; // top left corner of view window +float gl_viewwidth, gl_viewheight; // viewport clipping boundaries (screen coords) -static void CV_grlightdithering_OnChange(void); +FTransform atransform; -static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}}; +// Float variants of viewx, viewy, viewz, etc. +static float gl_viewx, gl_viewy, gl_viewz; +float gl_viewsin, gl_viewcos; +static float gl_viewludsin, gl_viewludcos; +static angle_t gl_aimingangle; -static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, - {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, - {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, - {HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"}, - {HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"}, - {0, NULL}}; -CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; - -consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, grfiltermode_cons_t, - CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, granisotropicmode_cons_t, - CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -#ifdef USE_FBO_OGL -consvar_t cv_grframebuffer = {"gr_framebuffer", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, CV_grframebuffer_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#endif - -consvar_t cv_splitwallfix = {"splitwallfix", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -static CV_PossibleValue_t grrenderdistance_cons_t[] = { - {0, "Max"}, {1, "1024"}, {2, "2048"}, {3, "4096"}, {4, "6144"}, {5, "8192"}, - {6, "12288"}, {7, "16384"}, {0, NULL}}; -consvar_t cv_grrenderdistance = {"gr_renderdistance", "Max", CV_SAVE, grrenderdistance_cons_t, - NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grportals = {"gr_portals", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}}; -consvar_t cv_secbright = {"secbright", "0", CV_SAVE, secbright_cons_t, - NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +seg_t *gl_curline; +side_t *gl_sidedef; +line_t *gl_linedef; +sector_t *gl_frontsector; +sector_t *gl_backsector; // values for the far clipping plane static float clipping_distances[] = {1024.0f, 2048.0f, 4096.0f, 6144.0f, 8192.0f, 12288.0f, 16384.0f}; @@ -129,157 +101,6 @@ static float clipping_distances[] = {1024.0f, 2048.0f, 4096.0f, 6144.0f, 8192.0f static INT32 bsp_culling_distances[] = {(1024+512)*FRACUNIT, (2048+512)*FRACUNIT, (4096+512)*FRACUNIT, (6144+512)*FRACUNIT, (8192+512)*FRACUNIT, (12288+512)*FRACUNIT, (16384+512)*FRACUNIT}; -static INT32 current_bsp_culling_distance = 0; - -// The current screen texture implementation is inefficient and disabling it can result in significant -// performance gains on lower end hardware. The game is still quite playable without this functionality. -// Features that break when disabling this: -// - water and heat wave effects -// - intermission background -// - full screen scaling (use native resolution or windowed mode to avoid this) -static CV_PossibleValue_t grscreentextures_cons_t[] = {{0, "Off"}, {1, "Wipes Only"}, {2, "All"}, {0, NULL}}; -consvar_t cv_grscreentextures = {"gr_screentextures", "All", CV_CALL|CV_SAVE, grscreentextures_cons_t, - CV_screentextures_ONChange, 0, NULL, NULL, 0, 0, NULL}; - -static CV_PossibleValue_t grshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}}; -consvar_t cv_grshaders = {"gr_shaders", "On", CV_CALL|CV_SAVE, grshaders_cons_t, CV_grshaders_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grpaletterendering = {"gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_grpaletterendering_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}}; -consvar_t cv_grpalettedepth = {"gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_grpalettedepth_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_lightdither = {"gr_lightdithering", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_grlightdithering_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grflashpal = {"gr_flashpal", "On", CV_CALL|CV_SAVE, CV_OnOff, CV_grpaletterendering_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grmdls = {"gr_mdls", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfallbackplayermodel = {"gr_fallbackplayermodel", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Standard", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grhorizonlines = {"gr_horizonlines", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -#define ONLY_IF_GL_LOADED if (vid.glstate != VID_GL_LIBRARY_LOADED) return; - -static void CV_filtermode_ONChange(void) -{ - ONLY_IF_GL_LOADED - HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value); -} - -static void CV_anisotropic_ONChange(void) -{ - ONLY_IF_GL_LOADED - HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); -} - -static void CV_screentextures_ONChange(void) -{ - ONLY_IF_GL_LOADED - if (cv_grscreentextures.value != 2) - { -#ifdef USE_FBO_OGL - CV_Set(&cv_grframebuffer, "Off"); -#endif - CV_Set(&cv_grpaletterendering, "Off"); - } - HWD.pfnSetSpecialState(HWD_SET_SCREEN_TEXTURES, cv_grscreentextures.value); -} - -static void CV_grshaders_OnChange(void) -{ - ONLY_IF_GL_LOADED - HWR_SetShaderState(); - if (cv_grpaletterendering.value) - { - // can't do palette rendering without shaders, so update the state if needed - HWR_TogglePaletteRendering(); - } -} - -static void CV_grpaletterendering_OnChange(void) -{ - ONLY_IF_GL_LOADED - if (cv_grscreentextures.value != 2) // can't do palette rendering without screen textures - CV_Set(&cv_grpaletterendering, "Off"); - - if (gr_shadersavailable) - { - HWR_CompileShaders(); - HWR_TogglePaletteRendering(); - } -} - -static void CV_grlightdithering_OnChange(void) -{ - ONLY_IF_GL_LOADED - if (gr_shadersavailable) - { - HWR_CompileShaders(); - } -} - -static void CV_grpalettedepth_OnChange(void) -{ - ONLY_IF_GL_LOADED - if (HWR_ShouldUsePaletteRendering()) - HWR_SetPalette(pLocalPalette); -} - -#ifdef USE_FBO_OGL -static void CV_grframebuffer_OnChange(void) -{ - ONLY_IF_GL_LOADED - if (cv_grscreentextures.value != 2) // screen FBO needs screen textures - CV_Set(&cv_grframebuffer, "Off"); - HWD.pfnSetSpecialState(HWD_SET_FRAMEBUFFER, cv_grframebuffer.value); - I_DownSample(); - RefreshOGLSDLSurface(); -} -#endif - -// -// Sets the shader state. -// -void HWR_SetShaderState(void) -{ - HWD.pfnSetSpecialState(HWD_SET_SHADERS, HWR_UseShader() ? 1 : 0); -} - -// ========================================================================== -// Globals -// ========================================================================== - -// base values set at SetViewSize -static float gr_basecentery; -static float gr_basecenterx; - -float gr_baseviewwindowy, gr_basewindowcentery; -float gr_baseviewwindowx, gr_basewindowcenterx; -float gr_viewwidth, gr_viewheight; // viewport clipping boundaries (screen coords) - -static float gr_centerx; -static float gr_viewwindowx; -static float gr_windowcenterx; // center of view window, for projection - -static float gr_centery; -static float gr_viewwindowy; // top left corner of view window -static float gr_windowcentery; - -static float gr_pspritexscale, gr_pspriteyscale; - -static seg_t *gr_curline; -static side_t *gr_sidedef; -static line_t *gr_linedef; -static sector_t *gr_frontsector; -static sector_t *gr_backsector; - -static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, boolean noencore, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags); - // Performance stats ps_metric_t ps_hw_nodesorttime = {0}; ps_metric_t ps_hw_nodedrawtime = {0}; @@ -297,200 +118,199 @@ ps_metric_t ps_hw_numcolors = {0}; ps_metric_t ps_hw_batchsorttime = {0}; ps_metric_t ps_hw_batchdrawtime = {0}; +static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, boolean noencore, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags); +static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); + +static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); +static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +static void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); + +static void HWR_AddSprites(sector_t *sec); +static void HWR_ProjectSprite(mobj_t *thing); static void HWR_AddPrecipitationSprites(void); static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); -// ========================================================================== -// View position -// ========================================================================== - -FTransform atransform; - -// Float variants of viewx, viewy, viewz, etc. -static float gr_viewx, gr_viewy, gr_viewz; -float gr_viewsin, gr_viewcos; -static float gr_viewludsin, gr_viewludcos; - -static angle_t gr_aimingangle; static void HWR_SetTransformAiming(FTransform *trans); +static void HWR_RollTransform(FTransform *tr, angle_t roll); + +static void HWR_DoPostProcessor(player_t *player); + +static void HWR_SetShaderState(void); +static void HWR_TogglePaletteRendering(void); // ========================================================================== -// Visual portals (attr. Hannu Hanhi) +// Commands and console variables // ========================================================================== -static boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y); -static boolean HWR_PortalCheckBBox(const fixed_t *bspcoord); +// +// Onchanges +// -enum +static void CV_screentextures_OnChange(void); +#ifdef USE_FBO_OGL +static void CV_glframebuffer_OnChange(void); +#endif +static void CV_glshaders_OnChange(void); +static void CV_gllightdithering_OnChange(void); +static void CV_filtermode_OnChange(void); +static void CV_anisotropic_OnChange(void); +static void CV_glpaletterendering_OnChange(void); +static void CV_glpalettedepth_OnChange(void); + +// +// CV_PossibleValue_t +// + +static CV_PossibleValue_t glscreentextures_cons_t[] = {{0, "Off"}, {1, "Wipes Only"}, {2, "All"}, {0, NULL}}; +static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "Standard"}, {2, "Smooth"}, {0, NULL}}; +static CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}}; +static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}}; + +static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, + {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, + {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, {HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"}, + {HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"}, {0, NULL}}; +CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; + +static CV_PossibleValue_t glrenderdistance_cons_t[] = { + {0, "Max"}, {1, "1024"}, {2, "2048"}, {3, "4096"}, {4, "6144"}, {5, "8192"}, + {6, "12288"}, {7, "16384"}, {0, NULL}}; + +static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}}; + +// +// console variables +// + +// The current screen texture implementation is inefficient and disabling it can result in significant +// performance gains on lower end hardware. The game is still quite playable without this functionality. +// Features that break when disabling this: +// - water and heat wave effects +// - intermission background +// - full screen scaling (use native resolution or windowed mode to avoid this) +consvar_t cv_glscreentextures = {"gr_screentextures", "All", CV_CALL|CV_SAVE, glscreentextures_cons_t, CV_screentextures_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +#ifdef USE_FBO_OGL +consvar_t cv_glframebuffer = {"gr_framebuffer", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, CV_glframebuffer_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#endif + +consvar_t cv_glmdls = {"gr_mdls", "Off", CV_SAVE|CV_CALL, CV_OnOff, M_UpdateOGLMenu, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glfallbackplayermodel = {"gr_fallbackplayermodel", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glshearing = {"gr_shearing", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glfakecontrast = {"gr_fakecontrast", "Standard", CV_SAVE, glfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glshaders = {"gr_shaders", "On", CV_CALL|CV_SAVE, glshaders_cons_t, CV_glshaders_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_gllightdither = {"gr_lightdithering", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_gllightdithering_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glsecbright = {"secbright", "0", CV_SAVE, secbright_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, glfiltermode_cons_t, CV_filtermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glanisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, glanisotropicmode_cons_t, CV_anisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glrenderdistance = {"gr_renderdistance", "Max", CV_SAVE, glrenderdistance_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glhorizonlines = {"gr_horizonlines", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glportals = {"gr_portals", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_glpaletterendering = {"gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_glpaletterendering_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glpalettedepth = {"gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_glflashpal = {"gr_flashpal", "On", CV_CALL|CV_SAVE, CV_OnOff, CV_glpaletterendering_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +#define ONLY_IF_GL_LOADED if (vid.glstate != VID_GL_LIBRARY_LOADED) return; + +static void CV_screentextures_OnChange(void) { - GRPORTAL_OFF, - GRPORTAL_SEARCH, - GRPORTAL_STENCIL, - GRPORTAL_DEPTH, - GRPORTAL_INSIDE, -}; + ONLY_IF_GL_LOADED + if (cv_glscreentextures.value != 2) + { + if (cv_glpaletterendering.value != 0) + CV_SetValue(&cv_glpaletterendering, 0); -static int gr_portal = GRPORTAL_OFF; -static boolean gl_drawing_stencil = false; -typedef struct gl_portal_s -{ - struct gl_portal_s *next; - - // Viewport. - fixed_t viewx; - fixed_t viewy; - fixed_t viewz; - angle_t viewangle; - - UINT8 pass; /**< Keeps track of the portal's recursion depth. */ - INT32 startline; - INT32 clipline; /**< Optional clipline for line-based portals. */ - INT32 drawcount; /**< For OpenGL. */ - - seg_t *seg; -} gl_portal_t; - -typedef struct gl_portallist_s -{ - gl_portal_t *base; - gl_portal_t *cap; -} gl_portallist_t; - -// new thing -gl_portallist_t *currentportallist; - -// More precise version of R_PointToAngle2 using floats and atan2. -static angle_t R_PointToAngle2Precise(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) -{ - fixed_t dx = x - pviewx; - fixed_t dy = y - pviewy; - float radians; - - if (!dx && !dy) - return 0; - - // no need for correct scale with FIXED_TO_FLOAT here - // since we're just calculating the angle - radians = atan2(dy, dx); - - return (angle_t)(radians / M_PI * ANGLE_180); +#ifdef USE_FBO_OGL + if (cv_glframebuffer.value != 0) + CV_SetValue(&cv_glframebuffer, 0); +#endif + } + HWD.pfnSetSpecialState(HWD_SET_SCREEN_TEXTURES, cv_glscreentextures.value); + M_UpdateOGLMenu(); } -// More precise version of R_PointToDist2 using floats and sqrt. -static fixed_t R_PointToDist2Precise(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1) +#ifdef USE_FBO_OGL +static void CV_glframebuffer_OnChange(void) { - // float-fixed conversions can be omitted here - // because they cancel each other out in this case + ONLY_IF_GL_LOADED + if ((cv_glframebuffer.value != 0 && cv_glscreentextures.value != 2) || (!supportFBO && cv_glframebuffer.value != 0)) // screen FBO needs screen textures + CV_SetValue(&cv_glframebuffer, 0); - float dx = px1 - px2; - float dy = py1 - py2; - double result = sqrt(dx*dx + dy*dy); + I_DownSample(); + RefreshOGLSDLSurface(); + M_UpdateOGLMenu(); +} +#endif - return (fixed_t)result; +static void CV_glshaders_OnChange(void) +{ + ONLY_IF_GL_LOADED + HWR_SetShaderState(); + if (cv_glpaletterendering.value) + { + // can't do palette rendering without shaders, so update the state if needed + HWR_TogglePaletteRendering(); + } + M_UpdateOGLMenu(); } -static void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg) +static void CV_gllightdithering_OnChange(void) { - line_t *start, *dest; - - angle_t dangle; - - fixed_t disttopoint; - angle_t angtopoint; - - vertex_t dest_c, start_c; - - gl_portal_t *portal; - - portal = Z_Malloc(sizeof(gl_portal_t), PU_STATIC, NULL); - - // Linked list. - if (!currentportallist->base) + ONLY_IF_GL_LOADED + if (gl_shadersavailable) { - currentportallist->base = portal; - currentportallist->cap = portal; + HWR_CompileShaders(); } - else - { - currentportallist->cap->next = portal; - currentportallist->cap = portal; - } - portal->next = NULL; - - // Increase recursion level. - portal->pass = portalrender+1; - - portal->seg = seg; - - // Offset the portal view by the linedef centers - start = &lines[line1]; - dest = &lines[line2]; - - // Most fixed-point calculations and trigonometric function tables are replaced by - // floats and cmath library calls in this part to improve the precision of the - // location and angle of the new viewpoint. - // - // This reduces artefacts on the edges of portals, showing thin lines/pixels - // of the underlying graphics. (for example the sky texture) It's not 100% - // perfectly aligned and artefact-free, but looks noticeably - // better than the original code. I'm not even sure if it's this - // code or the nodebuilder or hw_map or something else causing the remaining issues.. - - dangle = R_PointToAngle2Precise(0,0,dest->dx,dest->dy) - R_PointToAngle2Precise(start->dx,start->dy,0,0); - - // looking glass center - start_c.x = start->v1->x/2 + start->v2->x/2; - start_c.y = start->v1->y/2 + start->v2->y/2; - - // other side center - dest_c.x = dest->v1->x/2 + dest->v2->x/2; - dest_c.y = dest->v1->y/2 + dest->v2->y/2; - - disttopoint = R_PointToDist2Precise(start_c.x, start_c.y, viewx, viewy); - angtopoint = R_PointToAngle2Precise(start_c.x, start_c.y, viewx, viewy); - angtopoint += dangle; - - float fang = ((float)angtopoint / 4294967296.0f) * 2.0f * M_PI; - - if (dangle == 0) - { - portal->viewx = viewx + dest_c.x - start_c.x; - portal->viewy = viewy + dest_c.y - start_c.y; - } - else - { - portal->viewx = dest_c.x + (fixed_t)(cos(fang) * disttopoint); - portal->viewy = dest_c.y + (fixed_t)(sin(fang) * disttopoint); - } - portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; - portal->viewangle = viewangle + dangle; - - portal->startline = line1; - portal->clipline = line2; } -static void HWR_PortalFrame(gl_portal_t* portal) +static void CV_filtermode_OnChange(void) { - viewx = portal->viewx; - viewy = portal->viewy; - viewz = portal->viewz; + ONLY_IF_GL_LOADED + HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value); +} - viewangle = portal->viewangle; - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); +static void CV_anisotropic_OnChange(void) +{ + ONLY_IF_GL_LOADED + HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value); +} - if (portal->clipline != -1) +static void CV_glpaletterendering_OnChange(void) +{ + ONLY_IF_GL_LOADED + if (cv_glpaletterendering.value != 0 && cv_glscreentextures.value != 2) // can't do palette rendering without screen textures + CV_SetValue(&cv_glpaletterendering, 0); + + if (gl_shadersavailable) { - portalclipline = &lines[portal->clipline]; - portalcullsector = portalclipline->frontsector; - viewsector = portalclipline->frontsector; - } - else - { - portalclipline = NULL; - portalcullsector = NULL; - viewsector = R_PointInSubsector(viewx, viewy)->sector; + HWR_CompileShaders(); + HWR_TogglePaletteRendering(); } + M_UpdateOGLMenu(); +} + +static void CV_glpalettedepth_OnChange(void) +{ + ONLY_IF_GL_LOADED + if (HWR_ShouldUsePaletteRendering()) + HWR_SetPalette(pLocalPalette); } // ========================================================================== @@ -499,17 +319,22 @@ static void HWR_PortalFrame(gl_portal_t* portal) boolean HWR_UseShader(void) { - return (cv_grshaders.value && gr_shadersavailable); + return (cv_glshaders.value && gl_shadersavailable); +} + +static void HWR_SetShaderState(void) +{ + HWD.pfnSetSpecialState(HWD_SET_SHADERS, HWR_UseShader() ? 1 : 0); } boolean HWR_ShouldUsePaletteRendering(void) { - return (cv_grpaletterendering.value && HWR_UseShader()); + return (cv_glpaletterendering.value && HWR_UseShader()); } boolean HWR_PalRenderFlashpal(void) { - return (HWR_ShouldUsePaletteRendering() && cv_grflashpal.value); + return (HWR_ShouldUsePaletteRendering() && cv_glflashpal.value); } void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap) @@ -558,7 +383,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col } // Clamp the light level, since it can sometimes go out of the 0-255 range from animations - light_level = CLAMP(SOFTLIGHT(light_level), cv_secbright.value, 255); + light_level = CLAMP(SOFTLIGHT(light_level), cv_glsecbright.value, 255); // in palette rendering mode, this is not needed since it properly takes the changes to the palette itself if (!HWR_ShouldUsePaletteRendering()) @@ -575,7 +400,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col Surface->LightTableId = HWR_ShouldUsePaletteRendering() ? HWR_GetLightTableID(colormap) : 0; } -UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work +static UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work { RGBA_t realcolor, surfcolor; INT32 alpha; @@ -604,11 +429,11 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg) { INT16 finallight = lightnum; - if (seg != NULL && cv_grfakecontrast.value != 0) + if (seg != NULL && cv_glfakecontrast.value != 0) { fixed_t extralight = 0; - if (cv_grfakecontrast.value == 2) // Smooth setting + if (cv_glfakecontrast.value == 2) // Smooth setting extralight += seg->hwLightOffset; else extralight += seg->lightOffset * 8; @@ -627,11 +452,11 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope) { INT16 finallight = lightnum; - if (slope != NULL && cv_grfakecontrast.value != 0 && cv_grslopecontrast.value != 0) + if (slope != NULL && cv_glfakecontrast.value != 0 && cv_glslopecontrast.value != 0) { fixed_t extralight = 0; - if (cv_grfakecontrast.value == 2) // Smooth setting + if (cv_glfakecontrast.value == 2) // Smooth setting extralight += slope->hwLightOffset; else extralight += slope->lightOffset * 8; @@ -652,7 +477,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope) // HWR_RenderPlane // Render a floor or ceiling convex polygon -void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) +static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { FSurfaceInfo Surf; FOutVector *v3d; @@ -679,7 +504,7 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc // no convex poly were generated for this subsector if (!xsub->planepoly) return; - + pv = xsub->planepoly->pts; nrPlaneVerts = xsub->planepoly->numpts; @@ -696,10 +521,10 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc } else { - if (gr_frontsector->f_slope && !isceiling) - slope = gr_frontsector->f_slope; - else if (gr_frontsector->c_slope && isceiling) - slope = gr_frontsector->c_slope; + if (gl_frontsector->f_slope && !isceiling) + slope = gl_frontsector->f_slope; + else if (gl_frontsector->c_slope && isceiling) + slope = gl_frontsector->c_slope; } // Set fixedheight to the slope's height from our viewpoint, if we have a slope @@ -769,19 +594,19 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc angle = FOFsector->ceilingpic_angle; } } - else if (gr_frontsector) + else if (gl_frontsector) { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; - angle = gr_frontsector->floorpic_angle; + scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatsize; + angle = gl_frontsector->floorpic_angle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; - angle = gr_frontsector->ceilingpic_angle; + scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatsize; + angle = gl_frontsector->ceilingpic_angle; } } @@ -838,20 +663,20 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc PolyFlags |= PF_Masked|PF_Modulated; if (HWR_UseShader()) - { + { if (PolyFlags & PF_Fog) shader = SHADER_FOG; else if (cv_ripplewater.value && (PolyFlags & PF_Ripple)) shader = SHADER_WATER; else shader = SHADER_FLOOR; - + PolyFlags |= PF_ColorMapped; } HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); - if (subsector && cv_grhorizonlines.value) + if (subsector && cv_glhorizonlines.value) { // Horizon lines FOutVector horizonpts[6]; @@ -908,9 +733,9 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc vy = y1 + yd * j / numplanes; SETUP3DVERT((&horizonpts[1]), vx, vy); - dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); - vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; - vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2)); + vx = (vx - gl_viewx) * renderdist / dist + gl_viewx; + vy = (vy - gl_viewy) * renderdist / dist + gl_viewy; SETUP3DVERT((&horizonpts[0]), vx, vy); // Right side @@ -918,21 +743,21 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc vy = y1 + yd * (j+1) / numplanes; SETUP3DVERT((&horizonpts[2]), vx, vy); - dist = sqrtf(powf(vx - gr_viewx, 2) + powf(vy - gr_viewy, 2)); - vx = (vx - gr_viewx) * renderdist / dist + gr_viewx; - vy = (vy - gr_viewy) * renderdist / dist + gr_viewy; + dist = sqrtf(powf(vx - gl_viewx, 2) + powf(vy - gl_viewy, 2)); + vx = (vx - gl_viewx) * renderdist / dist + gl_viewx; + vy = (vy - gl_viewy) * renderdist / dist + gl_viewy; SETUP3DVERT((&horizonpts[3]), vx, vy); // Horizon fills - vx = (horizonpts[0].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; - vy = (horizonpts[0].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + vx = (horizonpts[0].x - gl_viewx) * farrenderdist / renderdist + gl_viewx; + vy = (horizonpts[0].z - gl_viewy) * farrenderdist / renderdist + gl_viewy; SETUP3DVERT((&horizonpts[5]), vx, vy); - horizonpts[5].y = gr_viewz; + horizonpts[5].y = gl_viewz; - vx = (horizonpts[3].x - gr_viewx) * farrenderdist / renderdist + gr_viewx; - vy = (horizonpts[3].z - gr_viewy) * farrenderdist / renderdist + gr_viewy; + vx = (horizonpts[3].x - gl_viewx) * farrenderdist / renderdist + gl_viewx; + vy = (horizonpts[3].z - gl_viewy) * farrenderdist / renderdist + gl_viewy; SETUP3DVERT((&horizonpts[4]), vx, vy); - horizonpts[4].y = gr_viewz; + horizonpts[4].y = gl_viewz; // Draw HWR_ProcessPolygon(&Surf, horizonpts, 6, PolyFlags, shader, true); @@ -950,18 +775,18 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) fixed_t i; // seg bbox fixed_t segbbox[4]; - + INT32 shader = SHADER_NONE; M_ClearBox(segbbox); M_AddToBox(segbbox, - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y)); + FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y)); M_AddToBox(segbbox, - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x), - FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y)); + FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x), + FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y)); - splat = (wallsplat_t *)gr_curline->linedef->splats; + splat = (wallsplat_t *)gl_curline->linedef->splats; for (; splat; splat = splat->next) { //BP: don't draw splat extern to this seg @@ -1005,7 +830,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) if (HWR_UseShader()) shader = SHADER_WALL; - + HWR_ProcessPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal, shader, false); } } @@ -1035,10 +860,10 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf) // // HWR_ProjectWall // -void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) +static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) { INT32 shader = SHADER_NONE; - + HWR_Lighting(pSurf, lightlevel, wallcolormap); if (HWR_UseShader()) @@ -1057,7 +882,7 @@ void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, shader, false); #ifdef WALLSPLATS - if (gr_curline->linedef->splats && cv_splats.value) + if (gl_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); #endif } @@ -1077,43 +902,49 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; + float diff; + fixed_t v1x = FloatToFixed(wallVerts[0].x); fixed_t v1y = FloatToFixed(wallVerts[0].z); fixed_t v2x = FloatToFixed(wallVerts[1].x); fixed_t v2y = FloatToFixed(wallVerts[1].z); const UINT8 alpha = Surf->PolyColor.s.alpha; - FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gr_curline); + FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline); extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; realbot = bot = wallVerts[0].y; + diff = top - bot; + pegt = wallVerts[3].t; pegb = wallVerts[0].t; // Lactozilla: If both heights of a side lay on the same position, then this wall is a triangle. // To avoid division by zero, which would result in a NaN, we check if the vertical difference // between the two vertices is not zero. - if (fpclassify(top - bot) == FP_ZERO && cv_splitwallfix.value) + if (fpclassify(diff) == FP_ZERO) pegmul = 0.0; else - pegmul = (pegb - pegt) / (top - bot); + pegmul = (pegb - pegt) / diff; endrealtop = endtop = wallVerts[2].y; endrealbot = endbot = wallVerts[1].y; + diff = endtop - endbot; + endpegt = wallVerts[2].t; endpegb = wallVerts[1].t; - if (fpclassify(endtop - endbot) == FP_ZERO && cv_splitwallfix.value) + if (fpclassify(diff) == FP_ZERO) endpegmul = 0.0; else - endpegmul = (endpegb - endpegt) / (endtop - endbot); + endpegmul = (endpegb - endpegt) / diff; for (INT32 i = 0; i < sector->numlights; i++) { if (endtop < endrealbot && top < realbot) return; - + lightlist_t *list = sector->lightlist; if (!(list[i].flags & FF_NOSHADE)) @@ -1122,13 +953,13 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, { lightnum = pfloor->master->frontsector->lightlevel; colormap = pfloor->master->frontsector->extra_colormap; - lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline); + lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); } else { lightnum = *list[i].lightlevel; colormap = list[i].extra_colormap; - lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline); + lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); } } @@ -1176,14 +1007,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, bheight = realbot; endbheight = endrealbot; } - - if (cv_splitwallfix.value) - { - if (endbheight > endtop) - endbot = endtop; - } - if ((endbheight >= endtop && bheight >= top && !cv_splitwallfix.value) || (bheight >= top && cv_splitwallfix.value)) + if (endbheight > endtop) + endbot = endtop; + + if (bheight >= top) continue; // Found a break @@ -1193,15 +1021,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, if (bot < realbot) bot = realbot; - if (cv_splitwallfix.value) - endbot = min(max(endbheight, endrealbot), endtop); - else - { - endbot = endbheight; - - if (endbot < endrealbot) - endbot = endrealbot; - } + endbot = min(max(endbheight, endrealbot), endtop); Surf->PolyColor.s.alpha = alpha; @@ -1263,7 +1083,7 @@ FOutVector* skyWallVertexArray = NULL; int skyWallVertexArraySize = 0; int skyWallVertexArrayAllocSize = 65536;// what a mouthful -boolean gr_collect_skywalls = false; +boolean gl_collect_skywalls = false; static void HWR_SkyWallList_Clear(void) { @@ -1306,7 +1126,7 @@ static void HWR_DrawSkyWallList(void) // HWR_DrawSkyWalls // Draw walls into the depth buffer so that anything behind is culled properly -void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) +static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) { //HWR_SetCurrentTexture(NULL); // no texture @@ -1315,7 +1135,7 @@ void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf) wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - if (gr_collect_skywalls) + if (gl_collect_skywalls) { HWR_SkyWallList_Add(wallVerts); } @@ -1336,10 +1156,10 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) pSurf->PolyColor.s.alpha = 0xFF; - if (!gr_curline->polyseg) + if (!gl_curline->polyseg) { // set alpha for transparent walls - switch (gr_linedef->special) + switch (gl_linedef->special) { case 900: blendmode = HWR_TranstableToAlpha(tr_trans10, pSurf); @@ -1392,15 +1212,15 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf) break; } } - else if (gr_curline->polyseg->translucency > 0) + else if (gl_curline->polyseg->translucency > 0) { // Polyobject translucency is shared between all of its lines - if (gr_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn + if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn return false; //Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode //blendmode = PF_Masked; else - blendmode = HWR_TranstableToAlpha(gr_curline->polyseg->translucency, pSurf); + blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, pSurf); } if (blendmode != PF_Masked && pSurf->PolyColor.s.alpha == 0x00) @@ -1429,38 +1249,33 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom fixed_t worldhighslope = 0, worldlowslope = 0; fixed_t v1x, v1y, v2x, v2y; - float cliplow = 0.0f, cliphigh = 0.0f; fixed_t h, l; // 3D sides and 2s middle textures fixed_t hS, lS; - FUINT lightnum = 0; // shut up compiler - extracolormap_t *colormap; - FSurfaceInfo Surf; + gl_sidedef = gl_curline->sidedef; + gl_linedef = gl_curline->linedef; - boolean noencore = false; + const boolean noencore = (gl_linedef->flags & ML_TFERLINE); - gr_sidedef = gr_curline->sidedef; - gr_linedef = gr_curline->linedef; - - if (gr_curline->pv1) + if (gl_curline->pv1) { - vs.x = ((polyvertex_t *)gr_curline->pv1)->x; - vs.y = ((polyvertex_t *)gr_curline->pv1)->y; + vs.x = ((polyvertex_t *)gl_curline->pv1)->x; + vs.y = ((polyvertex_t *)gl_curline->pv1)->y; } else { - vs.x = FIXED_TO_FLOAT(gr_curline->v1->x); - vs.y = FIXED_TO_FLOAT(gr_curline->v1->y); + vs.x = FIXED_TO_FLOAT(gl_curline->v1->x); + vs.y = FIXED_TO_FLOAT(gl_curline->v1->y); } - if (gr_curline->pv2) + if (gl_curline->pv2) { - ve.x = ((polyvertex_t *)gr_curline->pv2)->x; - ve.y = ((polyvertex_t *)gr_curline->pv2)->y; + ve.x = ((polyvertex_t *)gl_curline->pv2)->x; + ve.y = ((polyvertex_t *)gl_curline->pv2)->y; } else { - ve.x = FIXED_TO_FLOAT(gr_curline->v2->x); - ve.y = FIXED_TO_FLOAT(gr_curline->v2->y); + ve.x = FIXED_TO_FLOAT(gl_curline->v2->x); + ve.y = FIXED_TO_FLOAT(gl_curline->v2->y); } v1x = FLOAT_TO_FIXED(vs.x); @@ -1475,8 +1290,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else \ end1 = end2 = normalheight; - SLOPEPARAMS(gr_frontsector->c_slope, worldtop, worldtopslope, gr_frontsector->ceilingheight) - SLOPEPARAMS(gr_frontsector->f_slope, worldbottom, worldbottomslope, gr_frontsector->floorheight) + SLOPEPARAMS(gl_frontsector->c_slope, worldtop, worldtopslope, gl_frontsector->ceilingheight) + SLOPEPARAMS(gl_frontsector->f_slope, worldbottom, worldbottomslope, gl_frontsector->floorheight) // remember vertices ordering // 3--2 @@ -1491,44 +1306,44 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].z = wallVerts[1].z = ve.y; // x offset the texture - fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset; - cliplow = (float)texturehpeg; - cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); + fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset; + float cliplow = (float)texturehpeg; + float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT)); - lightnum = gr_frontsector->lightlevel; - colormap = gr_frontsector->extra_colormap; - lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline); - - if (gr_linedef->flags & ML_TFERLINE) - noencore = true; + FUINT lightnum = gl_frontsector->lightlevel; + extracolormap_t *colormap = gl_frontsector->extra_colormap; + lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); + FSurfaceInfo Surf; Surf.PolyColor.s.alpha = 255; - - INT32 gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture); - GLMapTexture_t *grTex = NULL; + + INT32 gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); + GLMapTexture_t *glTex = NULL; // two sided line - if (gr_backsector) + if (gl_backsector) { - INT32 gr_toptexture = 0, gr_bottomtexture = 0; + INT32 gl_toptexture = 0, gl_bottomtexture = 0; - SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) - SLOPEPARAMS(gr_backsector->f_slope, worldlow, worldlowslope, gr_backsector->floorheight) + fixed_t texturevpeg; + + SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) + SLOPEPARAMS(gl_backsector->f_slope, worldlow, worldlowslope, gl_backsector->floorheight) // Sky culling - if (!gr_curline->polyseg) // Don't do it for polyobjects + if (!gl_curline->polyseg) // Don't do it for polyobjects { // Sky Ceilings wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX); - if (gr_frontsector->ceilingpic == skyflatnum) + if (gl_frontsector->ceilingpic == skyflatnum) { - if (gr_backsector->ceilingpic == skyflatnum) + if (gl_backsector->ceilingpic == skyflatnum) { // Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the // backsector is lower - if ((worldhigh <= worldtop && worldhighslope <= worldtopslope)// Assuming ESLOPE is always on with my changes - && (worldhigh != worldtop || worldhighslope != worldtopslope)) + if ((worldhigh <= worldtop && worldhighslope <= worldtopslope) // Assuming ESLOPE is always on with my changes + && (worldhigh != worldtop || worldhighslope != worldtopslope)) // Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race { wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); @@ -1544,7 +1359,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom HWR_DrawSkyWall(wallVerts, &Surf); } } - else if (gr_backsector->ceilingpic == skyflatnum) + else if (gl_backsector->ceilingpic == skyflatnum) { // Only the backsector is sky, just draw a skywall from the front ceiling wallVerts[0].y = FIXED_TO_FLOAT(worldtop); @@ -1555,9 +1370,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // Sky Floors wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); - if (gr_frontsector->floorpic == skyflatnum) + if (gl_frontsector->floorpic == skyflatnum) { - if (gr_backsector->floorpic == skyflatnum) + if (gl_backsector->floorpic == skyflatnum) { // Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the // it's higher, also needs to check for bottomtexture as the floors don't usually move down @@ -1565,7 +1380,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope) && (worldlow != worldbottom || worldlowslope != worldbottomslope) // Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race - && !(gr_sidedef->bottomtexture)) + && !(gl_sidedef->bottomtexture)) { wallVerts[3].y = FIXED_TO_FLOAT(worldlow); wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); @@ -1580,7 +1395,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom HWR_DrawSkyWall(wallVerts, &Surf); } } - else if ((gr_backsector->floorpic == skyflatnum) && !(gr_sidedef->bottomtexture)) + else if ((gl_backsector->floorpic == skyflatnum) && !(gl_sidedef->bottomtexture)) { // Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture wallVerts[3].y = FIXED_TO_FLOAT(worldlow); @@ -1591,64 +1406,60 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky - if (gr_frontsector->ceilingpic == skyflatnum - && gr_backsector->ceilingpic == skyflatnum) + if (gl_frontsector->ceilingpic == skyflatnum + && gl_backsector->ceilingpic == skyflatnum) { worldtop = worldhigh; worldtopslope = worldhighslope; } - gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); - gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture); + gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture); // check TOP TEXTURE - if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gr_toptexture) + if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) { + // PEGGING + if (gl_linedef->flags & ML_DONTPEGTOP) + texturevpeg = 0; + else if (gl_linedef->flags & ML_EFFECT1) + texturevpeg = worldhigh + textureheight[gl_toptexture] - worldtop; + else + texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight; + + texturevpeg += gl_sidedef->rowoffset; + + // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway + texturevpeg %= textureheight[gl_toptexture]; + + glTex = HWR_GetTexture(gl_toptexture, noencore); + + wallVerts[3].t = wallVerts[2].t = texturevpeg * glTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * glTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; + + // Adjust t value for sloped walls + if (!(gl_linedef->flags & ML_EFFECT1)) { - fixed_t texturevpegtop; // top - - grTex = HWR_GetTexture(gr_toptexture, gr_linedef->flags & ML_TFERLINE); - - // PEGGING - if (gr_linedef->flags & ML_DONTPEGTOP) - texturevpegtop = 0; - else if (gr_linedef->flags & ML_EFFECT1) - texturevpegtop = worldhigh + textureheight[gr_sidedef->toptexture] - worldtop; - else - texturevpegtop = gr_backsector->ceilingheight + textureheight[gr_sidedef->toptexture] - gr_frontsector->ceilingheight; - - texturevpegtop += gr_sidedef->rowoffset; - - // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegtop %= SHORT(textures[gr_toptexture]->height)<scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; - - // Adjust t value for sloped walls - if (!(gr_linedef->flags & ML_EFFECT1)) - { - // Unskewed - wallVerts[3].t -= (worldtop - gr_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[2].t -= (worldtopslope - gr_frontsector->ceilingheight) * grTex->scaleY; - wallVerts[0].t -= (worldhigh - gr_backsector->ceilingheight) * grTex->scaleY; - wallVerts[1].t -= (worldhighslope - gr_backsector->ceilingheight) * grTex->scaleY; - } - else if (gr_linedef->flags & ML_DONTPEGTOP) - { - // Skewed by top - wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY; - wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY; - } - else - { - // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY; - wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY; - } + // Unskewed + wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * glTex->scaleY; + wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * glTex->scaleY; + wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * glTex->scaleY; + wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * glTex->scaleY; + } + else if (gl_linedef->flags & ML_DONTPEGTOP) + { + // Skewed by top + wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * glTex->scaleY; + wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * glTex->scaleY; + } + else + { + // Skewed by bottom + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * glTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * glTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * glTex->scaleY; } // set top/bottom coords @@ -1657,60 +1468,57 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope); - if (!gl_drawing_stencil && gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0); - else if (!gl_drawing_stencil && grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap); + if (!gl_drawing_stencil && gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0); + else if (!gl_drawing_stencil && glTex->mipmap.flags & TF_TRANSPARENT) + HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, noencore, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } // check BOTTOM TEXTURE - if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!! + if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) { - fixed_t texturevpegbottom = 0; // bottom - - grTex = HWR_GetTexture(gr_bottomtexture, gr_linedef->flags & ML_TFERLINE); - // PEGGING - if (!(gr_linedef->flags & ML_DONTPEGBOTTOM)) - texturevpegbottom = 0; - else if (gr_linedef->flags & ML_EFFECT1) - texturevpegbottom = worldbottom - worldlow; + if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) + texturevpeg = 0; + else if (gl_linedef->flags & ML_EFFECT1) + texturevpeg = worldbottom - worldlow; else - texturevpegbottom = gr_frontsector->floorheight - gr_backsector->floorheight; + texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight; - texturevpegbottom += gr_sidedef->rowoffset; + texturevpeg += gl_sidedef->rowoffset; // This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway - texturevpegbottom %= SHORT(textures[gr_bottomtexture]->height)<scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + glTex = HWR_GetTexture(gl_bottomtexture, noencore); + + wallVerts[3].t = wallVerts[2].t = texturevpeg * glTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * glTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; // Adjust t value for sloped walls - if (!(gr_linedef->flags & ML_EFFECT1)) + if (!(gl_linedef->flags & ML_EFFECT1)) { // Unskewed - wallVerts[0].t -= (worldbottom - gr_frontsector->floorheight) * grTex->scaleY; - wallVerts[1].t -= (worldbottomslope - gr_frontsector->floorheight) * grTex->scaleY; - wallVerts[3].t -= (worldlow - gr_backsector->floorheight) * grTex->scaleY; - wallVerts[2].t -= (worldlowslope - gr_backsector->floorheight) * grTex->scaleY; + wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * glTex->scaleY; + wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * glTex->scaleY; + wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * glTex->scaleY; + wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * glTex->scaleY; } - else if (gr_linedef->flags & ML_DONTPEGBOTTOM) + else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { // Skewed by bottom - wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY; - //wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this - wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * glTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * glTex->scaleY; } else { // Skewed by top - wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY; - wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY; + wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * glTex->scaleY; + wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * glTex->scaleY; } // set top/bottom coords @@ -1719,32 +1527,32 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); - if (!gl_drawing_stencil && gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0); - else if (!gl_drawing_stencil && grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap); + if (!gl_drawing_stencil && gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0); + else if (!gl_drawing_stencil && glTex->mipmap.flags & TF_TRANSPARENT) + HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, noencore, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } - if ((gr_midtexture && HWR_BlendMidtextureSurface(&Surf)) || gr_portal == GRPORTAL_STENCIL || gr_portal == GRPORTAL_DEPTH || gl_drawing_stencil) + if ((gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) || gl_portal_state == GLPORTAL_STENCIL || gl_portal_state == GLPORTAL_DEPTH || gl_drawing_stencil) { sector_t *front, *back; INT32 repeats; - if (gr_linedef->frontsector->heightsec != -1) - front = §ors[gr_linedef->frontsector->heightsec]; + if (gl_linedef->frontsector->heightsec != -1) + front = §ors[gl_linedef->frontsector->heightsec]; else - front = gr_linedef->frontsector; + front = gl_linedef->frontsector; - if (gr_linedef->backsector->heightsec != -1) - back = §ors[gr_linedef->backsector->heightsec]; + if (gl_linedef->backsector->heightsec != -1) + back = §ors[gl_linedef->backsector->heightsec]; else - back = gr_linedef->backsector; + back = gl_linedef->backsector; - if (gr_sidedef->repeatcnt) - repeats = 1 + gr_sidedef->repeatcnt; - else if (gr_linedef->flags & ML_EFFECT5 || gr_portal == GRPORTAL_STENCIL || gr_portal == GRPORTAL_DEPTH) + if (gl_sidedef->repeatcnt) + repeats = 1 + gl_sidedef->repeatcnt; + else if (gl_linedef->flags & ML_EFFECT5 || gl_portal_state == GLPORTAL_STENCIL || gl_portal_state == GLPORTAL_DEPTH) { fixed_t high, low; @@ -1758,28 +1566,26 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else low = back->floorheight; - repeats = (high - low)/textureheight[gr_sidedef->midtexture]; - if ((high-low)%textureheight[gr_sidedef->midtexture]) + repeats = (high - low) / textureheight[gl_midtexture]; + if ((high - low) % textureheight[gl_midtexture]) repeats++; // tile an extra time to fill the gap -- Monster Iestyn } else repeats = 1; - fixed_t midtexheight = textureheight[gr_midtexture] * repeats; - fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; - fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; - // SoM: a little note: This code re-arranging will // fix the bug in Nimrod map02. popentop and popenbottom // record the limits the texture can be displayed in. // polytop and polybottom, are the ideal (i.e. unclipped) // heights of the polygon, and h & l, are the final (clipped) // poly coords. + fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut; + fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope; // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct // From CB - if (gr_curline->polyseg) + if (gl_curline->polyseg) { popentop = popentopslope = back->ceilingheight; popenbottom = popenbottomslope = back->floorheight; @@ -1788,48 +1594,49 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { popentop = min(worldtop, worldhigh); popenbottom = max(worldbottom, worldlow); - popentopslope = min(worldtopslope, worldhighslope); popenbottomslope = max(worldbottomslope, worldlowslope); } - if (gr_linedef->flags & ML_EFFECT2) + // Find the wall's coordinates + fixed_t midtexheight = textureheight[gl_midtexture] * repeats; + + if (gl_linedef->flags & ML_EFFECT2) { - if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) + if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) // Peg it to the floor { - polybottom = max(front->floorheight, back->floorheight) + gr_sidedef->rowoffset; - polybottomslope = polybottom; + polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset; polytop = polybottom + midtexheight; - polytopslope = polytop; } - else + else // Peg it to the ceiling { - polytop = min(front->ceilingheight, back->ceilingheight) + gr_sidedef->rowoffset; - polytopslope = polytop; + polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset; polybottom = polytop - midtexheight; - polybottomslope = polybottom; } + + // The right side's coordinates are the the same as the left side + polytopslope = polytop; + polybottomslope = polybottom; } - else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) + else if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) // Skew the texture, but peg it to the floor { - polybottom = popenbottom + gr_sidedef->rowoffset; + polybottom = popenbottom + gl_sidedef->rowoffset; polytop = polybottom + midtexheight; - polybottomslope = popenbottomslope + gr_sidedef->rowoffset; + polybottomslope = popenbottomslope + gl_sidedef->rowoffset; polytopslope = polybottomslope + midtexheight; } - else + else // Skew it according to the ceiling's slope { - polytop = popentop + gr_sidedef->rowoffset; - polybottom = polytop - textureheight[gr_midtexture]*repeats; + polytop = popentop + gl_sidedef->rowoffset; polybottom = polytop - midtexheight; - polytopslope = popentopslope + gr_sidedef->rowoffset; + polytopslope = popentopslope + gl_sidedef->rowoffset; polybottomslope = polytopslope - midtexheight; } // CB // NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to, // you must use the linedef's backsector to be correct - if (gr_curline->polyseg) + if (gl_curline->polyseg) { lowcut = polybottom; highcut = polytop; @@ -1851,11 +1658,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lS = max(polybottomslope, lowcutslope); // PEGGING - fixed_t texturevpeg, texturevpegslope; + fixed_t texturevpegslope; - grTex = HWR_GetTexture(gr_midtexture, gr_linedef->flags & ML_TFERLINE); - - if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) + if (!!(gl_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gl_linedef->flags & ML_EFFECT3)) { texturevpeg = midtexheight - h + polybottom; texturevpegslope = midtexheight - hS + polybottomslope; @@ -1866,12 +1671,17 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom texturevpegslope = polytopslope - hS; } - wallVerts[3].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[2].t = texturevpegslope * grTex->scaleY; - wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + glTex = HWR_GetTexture(gl_midtexture, noencore); + + // Left side + wallVerts[3].t = texturevpeg * glTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * glTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + + // Right side + wallVerts[2].t = texturevpegslope * glTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpegslope) * glTex->scaleY; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; // set top/bottom coords // Take the texture peg into account, rather than changing the offsets past @@ -1888,10 +1698,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // This will cause the midtexture appear on top, if a FOF overlaps with it. blendmode |= PF_Decal; - if (!gl_drawing_stencil && gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, gr_linedef->flags & ML_TFERLINE, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, PF_Decal); + if (!gl_drawing_stencil && gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, noencore, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, PF_Decal); else if (!gl_drawing_stencil && !(blendmode & PF_Masked)) - HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, gr_linedef->flags & ML_TFERLINE, blendmode, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, noencore, blendmode, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap); } @@ -1899,42 +1709,42 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { // Single sided line... Deal only with the middletexture (if one exists) - if (gr_midtexture && gr_linedef->special != HORIZONSPECIAL) // Ignore horizon line for OGL + if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // Ignore horizon line for OGL { fixed_t texturevpeg; // PEGGING - if ((gr_linedef->flags & (ML_DONTPEGBOTTOM|ML_EFFECT2)) == (ML_DONTPEGBOTTOM|ML_EFFECT2)) - texturevpeg = gr_frontsector->floorheight + textureheight[gr_sidedef->midtexture] - gr_frontsector->ceilingheight + gr_sidedef->rowoffset; - else if (gr_linedef->flags & ML_DONTPEGBOTTOM) - texturevpeg = worldbottom + textureheight[gr_sidedef->midtexture] - worldtop + gr_sidedef->rowoffset; + if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_EFFECT2)) == (ML_DONTPEGBOTTOM|ML_EFFECT2)) + texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset; + else if (gl_linedef->flags & ML_DONTPEGBOTTOM) + texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset; else - texturevpeg = gr_sidedef->rowoffset; // top of texture at top + texturevpeg = gl_sidedef->rowoffset; // top of texture at top - grTex = HWR_GetTexture(gr_midtexture, gr_linedef->flags & ML_TFERLINE); + glTex = HWR_GetTexture(gl_midtexture, noencore); - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (texturevpeg + gr_frontsector->ceilingheight - gr_frontsector->floorheight) * grTex->scaleY; - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[3].t = wallVerts[2].t = texturevpeg * glTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * glTex->scaleY; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; // Texture correction for slopes - if (gr_linedef->flags & ML_EFFECT2) + if (gl_linedef->flags & ML_EFFECT2) { - wallVerts[3].t += (gr_frontsector->ceilingheight - worldtop) * grTex->scaleY; - wallVerts[2].t += (gr_frontsector->ceilingheight - worldtopslope) * grTex->scaleY; - wallVerts[0].t += (gr_frontsector->floorheight - worldbottom) * grTex->scaleY; - wallVerts[1].t += (gr_frontsector->floorheight - worldbottomslope) * grTex->scaleY; + wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * glTex->scaleY; + wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * glTex->scaleY; + wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * glTex->scaleY; + wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * glTex->scaleY; } - else if (gr_linedef->flags & ML_DONTPEGBOTTOM) + else if (gl_linedef->flags & ML_DONTPEGBOTTOM) { - wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY; + wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * glTex->scaleY; + wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * glTex->scaleY; } else { - wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY; - wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY; + wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * glTex->scaleY; + wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * glTex->scaleY; } //Set textures properly on single sided walls that are sloped @@ -1943,12 +1753,12 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); - if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0); + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0); else // I don't think that solid walls can use translucent linedef types... { - if (grTex->mipmap.flags & TF_TRANSPARENT) - HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap); + if (glTex->mipmap.flags & TF_TRANSPARENT) + HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, noencore, PF_Environment, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } @@ -1965,22 +1775,21 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom HWR_DrawSkyWall(wallVerts, &Surf); } - // Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's - // a sky flat - if (!gr_curline->polyseg) + if (!gl_curline->polyseg) { - if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector + if (gl_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector { - wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX); + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space wallVerts[0].y = FIXED_TO_FLOAT(worldtop); wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); + HWR_DrawSkyWall(wallVerts, &Surf); } - if (gr_frontsector->floorpic == skyflatnum) + if (gl_frontsector->floorpic == skyflatnum) { wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space HWR_DrawSkyWall(wallVerts, &Surf); } @@ -1988,7 +1797,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } //Hurdler: 3d-floors test - if (!gl_drawing_stencil && gr_frontsector && gr_backsector && gr_frontsector->tag != gr_backsector->tag && (gr_backsector->ffloors || gr_frontsector->ffloors)) + if (!gl_drawing_stencil && gl_backsector && gl_frontsector->tag != gl_backsector->tag && (gl_backsector->ffloors || gl_frontsector->ffloors)) { ffloor_t * rover; fixed_t highcut = 0, lowcut = 0; @@ -2005,9 +1814,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lowcutslope = max(worldbottomslope, worldlowslope); highcutslope = min(worldtopslope, worldhighslope); - if (gr_backsector->ffloors) + if (gl_backsector->ffloors) { - for (rover = gr_backsector->ffloors; rover; rover = rover->next) + for (rover = gl_backsector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || (rover->flags & FF_INVERTSIDES)) continue; @@ -2022,7 +1831,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = min((size_t)(gr_curline->linedef-gr_backsector->lines[0]), rover->master->frontsector->linecount); + size_t linenum = min((size_t)(gl_curline->linedef-gl_backsector->lines[0]), rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } @@ -2078,39 +1887,39 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom else { texturevpeg = sides[rover->master->sidenum[0]].rowoffset; - attachtobottom = !!(gr_linedef->flags & ML_DONTPEGBOTTOM); + attachtobottom = !!(gl_linedef->flags & ML_DONTPEGBOTTOM); slopeskew = !!(rover->master->flags & ML_DONTPEGTOP); } - grTex = HWR_GetTexture(texnum, noencore); + glTex = HWR_GetTexture(texnum, noencore); if (!slopeskew) // no skewing { if (attachtobottom) texturevpeg -= *rover->topheight - *rover->bottomheight; - wallVerts[3].t = (*rover->topheight - h + texturevpeg) * grTex->scaleY; - wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * grTex->scaleY; - wallVerts[0].t = (*rover->topheight - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * grTex->scaleY; + wallVerts[3].t = (*rover->topheight - h + texturevpeg) * glTex->scaleY; + wallVerts[2].t = (*rover->topheight - hS + texturevpeg) * glTex->scaleY; + wallVerts[0].t = (*rover->topheight - l + texturevpeg) * glTex->scaleY; + wallVerts[1].t = (*rover->topheight - lS + texturevpeg) * glTex->scaleY; } else { if (!attachtobottom) // skew by top { - wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; - wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY; - wallVerts[1].t = (hS - lS + texturevpeg) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = texturevpeg * glTex->scaleY; + wallVerts[0].t = (h - l + texturevpeg) * glTex->scaleY; + wallVerts[1].t = (hS - lS + texturevpeg) * glTex->scaleY; } else // skew by bottom { - wallVerts[0].t = wallVerts[1].t = texturevpeg * grTex->scaleY; - wallVerts[3].t = wallVerts[0].t - (h - l) * grTex->scaleY; - wallVerts[2].t = wallVerts[1].t - (hS - lS) * grTex->scaleY; + wallVerts[0].t = wallVerts[1].t = texturevpeg * glTex->scaleY; + wallVerts[3].t = wallVerts[0].t - (h - l) * glTex->scaleY; + wallVerts[2].t = wallVerts[1].t - (hS - lS) * glTex->scaleY; } } - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; } if (rover->flags & FF_FOG) { @@ -2120,12 +1929,13 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; - lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline); - Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap); - if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0); + lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); + + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0); else HWR_AddTransparentWall(wallVerts, &Surf, 0, false, blendmode, true, lightnum, colormap); } @@ -2139,12 +1949,12 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = CLAMP(rover->alpha, 0, 255); } - if (gr_frontsector->numlights) - HWR_SplitWall(gr_frontsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0); + if (gl_frontsector->numlights) + HWR_SplitWall(gl_frontsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0); else { if (blendmode != PF_Masked) - HWR_AddTransparentWall(wallVerts, &Surf, texnum, gr_linedef->flags & ML_TFERLINE, blendmode, false, lightnum, colormap); + HWR_AddTransparentWall(wallVerts, &Surf, texnum, noencore, blendmode, false, lightnum, colormap); else HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } @@ -2152,9 +1962,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } - if (gr_frontsector->ffloors) // Putting this seperate should allow 2 FOF sectors to be connected without too many errors? I think? + if (gl_frontsector->ffloors) // Putting this seperate should allow 2 FOF sectors to be connected without too many errors? I think? { - for (rover = gr_frontsector->ffloors; rover; rover = rover->next) + for (rover = gl_frontsector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_ALLSIDES)) continue; @@ -2169,7 +1979,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom if (rover->master->flags & ML_TFERLINE) { - size_t linenum = min((size_t)(gr_curline->linedef-gr_backsector->lines[0]), rover->master->frontsector->linecount); + size_t linenum = min((size_t)(gl_curline->linedef-gl_backsector->lines[0]), rover->master->frontsector->linecount); newline = rover->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); } @@ -2190,7 +2000,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom l = lowcut; lS = lowcutslope; } - + //Hurdler: HW code starts here //FIXME: check if peging is correct // set top/bottom coords @@ -2209,21 +2019,21 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } else { - grTex = HWR_GetTexture(texnum, noencore); + glTex = HWR_GetTexture(texnum, noencore); if (newline) { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset)) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset) * glTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[newline->sidenum[0]].rowoffset)) * glTex->scaleY; } else { - wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * grTex->scaleY; - wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * grTex->scaleY; + wallVerts[3].t = wallVerts[2].t = (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset) * glTex->scaleY; + wallVerts[0].t = wallVerts[1].t = (h - l + (*rover->topheight - h + sides[rover->master->sidenum[0]].rowoffset)) * glTex->scaleY; } - wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX; - wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX; + wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX; + wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX; } if (rover->flags & FF_FOG) @@ -2234,12 +2044,13 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom lightnum = rover->master->frontsector->lightlevel; colormap = rover->master->frontsector->extra_colormap; - lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline); - Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); + Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap); - if (gr_backsector->numlights) - HWR_SplitWall(gr_backsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0); + lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline); + + if (gl_backsector->numlights) + HWR_SplitWall(gl_backsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0); else HWR_AddTransparentWall(wallVerts, &Surf, 0, false, blendmode, true, lightnum, colormap); } @@ -2253,8 +2064,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom Surf.PolyColor.s.alpha = CLAMP(rover->alpha, 0, 255); } - if (gr_backsector->numlights) - HWR_SplitWall(gr_backsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0); + if (gl_backsector->numlights) + HWR_SplitWall(gl_backsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0); else { if (blendmode != PF_Masked) @@ -2288,28 +2099,28 @@ static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector) if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope) { fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t - - if (gr_curline->pv1) + + if (gl_curline->pv1) { - v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); - v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y); } else { - v1x = gr_curline->v1->x; - v1y = gr_curline->v1->y; + v1x = gl_curline->v1->x; + v1y = gl_curline->v1->y; } - if (gr_curline->pv2) + if (gl_curline->pv2) { - v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); - v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y); } else { - v2x = gr_curline->v2->x; - v2y = gr_curline->v2->y; + v2x = gl_curline->v2->x; + v2y = gl_curline->v2->y; } - + #define SLOPEPARAMS(slope, end1, end2, normalheight) \ if (slope) { \ end1 = P_GetZAt(slope, v1x, v1y); \ @@ -2337,8 +2148,6 @@ static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector) fixed_t viewf1, viewf2, viewc1, viewc2; if (afrontsector == viewsector) { - //if (printportals) - // CONS_Printf("CheckClip frontsector is viewsector\n"); viewf1 = frontf1; viewf2 = frontf2; viewc1 = frontc1; @@ -2346,8 +2155,6 @@ static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector) } else { - //if (printportals) - // CONS_Printf("CheckClip backsector is viewsector\n"); viewf1 = backf1; viewf2 = backf2; viewc1 = backc1; @@ -2432,27 +2239,27 @@ static void HWR_AddLine(seg_t *line) if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; - gr_curline = line; + gl_curline = line; - if (gr_curline->pv1) + if (gl_curline->pv1) { - v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x); - v1y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->y); + v1x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->x); + v1y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv1)->y); } else { - v1x = gr_curline->v1->x; - v1y = gr_curline->v1->y; + v1x = gl_curline->v1->x; + v1y = gl_curline->v1->y; } - if (gr_curline->pv2) + if (gl_curline->pv2) { - v2x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->x); - v2y = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv2)->y); + v2x = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->x); + v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y); } else { - v2x = gr_curline->v2->x; - v2y = gr_curline->v2->y; + v2x = gl_curline->v2->x; + v2y = gl_curline->v2->y; } // OPTIMIZE: quickly reject orthogonal back sides. @@ -2460,7 +2267,7 @@ static void HWR_AddLine(seg_t *line) angle2 = R_PointToAngle64(v2x, v2y); // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! - if (angle2 - angle1 < ANGLE_180 || !gr_curline->linedef) + if (angle2 - angle1 < ANGLE_180 || !gl_curline->linedef) return; // PrBoom: use REAL clipping math YAYYYYYYY!!! @@ -2469,7 +2276,7 @@ static void HWR_AddLine(seg_t *line) checkforemptylines = true; - gr_backsector = line->backsector; + gl_backsector = line->backsector; // do extra checks on the seg when rendering portals: // don't render segs that are behind the portal destination line @@ -2480,7 +2287,7 @@ static void HWR_AddLine(seg_t *line) return; } - if (gr_portal == GRPORTAL_STENCIL || gr_portal == GRPORTAL_DEPTH) + if (gl_portal_state == GLPORTAL_STENCIL || gl_portal_state == GLPORTAL_DEPTH) goto doaddline; if (line->linedef->special == 40) @@ -2489,13 +2296,15 @@ static void HWR_AddLine(seg_t *line) { // Find the other side! INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1); + if (line->linedef == &lines[line2]) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); + if (line2 >= 0) // found it! { - if (gr_portal == GRPORTAL_SEARCH) + if (gl_portal_state == GLPORTAL_SEARCH) HWR_Portal_Add2Lines(line->linedef-lines, line2, line); - else if (gr_portal == GRPORTAL_INSIDE) + else if (gl_portal_state == GLPORTAL_INSIDE) dont_draw = true; } } @@ -2511,9 +2320,9 @@ doaddline: } else { - gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true); - if (CheckClip(gr_frontsector, gr_backsector)) + if (CheckClip(gl_frontsector, gl_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); checkforemptylines = false; @@ -2523,11 +2332,11 @@ doaddline: // Identical floor and ceiling on both sides, // identical light levels on both sides, // and no middle texture. - if (checkforemptylines && R_IsEmptyLine(line, gr_frontsector, gr_backsector)) + if (checkforemptylines && R_IsEmptyLine(line, gl_frontsector, gl_backsector)) return; } - if (gr_portal != GRPORTAL_SEARCH && !dont_draw)// no need to do this during the portal check + if (gl_portal_state != GLPORTAL_SEARCH && !dont_draw)// no need to do this during the portal check HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D return; @@ -2663,7 +2472,7 @@ static inline void HWR_AddPolyObjectSegs(void) } } -void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) +static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { float height; //constant y for all points on the convex flat polygon FOutVector *v3d; @@ -2680,7 +2489,7 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - + INT32 shader = SHADER_NONE; nrPlaneVerts = polysector->numVertices; @@ -2763,19 +2572,19 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } - else if (gr_frontsector) + else if (gl_frontsector) { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; - angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT; + scrollx = FIXED_TO_FLOAT(gl_frontsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gl_frontsector->floor_yoffs)/fflatsize; + angle = gl_frontsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; - angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; + scrollx = FIXED_TO_FLOAT(gl_frontsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gl_frontsector->ceiling_yoffs)/fflatsize; + angle = gl_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -2826,11 +2635,11 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t blendmode |= PF_Masked|PF_Modulated; if (HWR_UseShader()) - { + { shader = SHADER_FLOOR; blendmode |= PF_ColorMapped; } - + HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, shader, false); } @@ -2853,11 +2662,11 @@ static void HWR_AddPolyObjectPlanes(void) if (po_ptrs[i]->translucency >= NUMTRANSMAPS) continue; - if (polyobjsector->floorheight <= gr_frontsector->ceilingheight - && polyobjsector->floorheight >= gr_frontsector->floorheight + if (polyobjsector->floorheight <= gl_frontsector->ceilingheight + && polyobjsector->floorheight >= gl_frontsector->floorheight && (viewz < polyobjsector->floorheight)) { - light = R_GetPlaneLight(gr_frontsector, polyobjsector->floorheight, true); + light = R_GetPlaneLight(gl_frontsector, polyobjsector->floorheight, true); if (po_ptrs[i]->translucency > 0) { FSurfaceInfo Surf; @@ -2865,22 +2674,22 @@ static void HWR_AddPolyObjectPlanes(void) memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap)); } else { HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum, R_NoEncore(polyobjsector, false)); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, - polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, + polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap)); } } - if (polyobjsector->ceilingheight >= gr_frontsector->floorheight - && polyobjsector->ceilingheight <= gr_frontsector->ceilingheight + if (polyobjsector->ceilingheight >= gl_frontsector->floorheight + && polyobjsector->ceilingheight <= gl_frontsector->ceilingheight && (viewz > polyobjsector->ceilingheight)) { - light = R_GetPlaneLight(gr_frontsector, polyobjsector->ceilingheight, true); + light = R_GetPlaneLight(gl_frontsector, polyobjsector->ceilingheight, true); if (po_ptrs[i]->translucency > 0) { FSurfaceInfo Surf; @@ -2888,14 +2697,14 @@ static void HWR_AddPolyObjectPlanes(void) memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), Surf.PolyColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap)); } else { HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum, R_NoEncore(polyobjsector, true)); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->ceilingpic].lumpnum, - polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : gr_frontsector->lightlist[light].extra_colormap)); + (light == -1 ? gl_frontsector->lightlevel : *gl_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->ceilingpic].lumpnum, + polyobjsector, 255, (light == -1 ? gl_frontsector->extra_colormap : gl_frontsector->lightlist[light].extra_colormap)); } } } @@ -2942,6 +2751,29 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; } +static inline void HWR_PortalSubsector(seg_t *line, subsector_t *sub, INT16 count) +{ + if (line) + { + //Hurdler: at this point validcount must be the same, but is not because + // gl_frontsector doesn't point anymore to sub->sector due to + // the call gl_frontsector = R_FakeFlat(...) + // if it's not done, the sprite is drawn more than once, + // what looks really bad with translucency or dynamic light, + // without talking about the overdraw of course. + sub->sector->validcount = validcount;/// \todo fix that in a better way + + while (count--) + { + if (!line->polyseg) // ignore segs that belong to polyobjects + HWR_AddLine(line); + line++; + } + } + + sub->validcount = validcount; +} + // -----------------+ // HWR_Subsector : Determine floor/ceiling planes. // : Add sprites of things in sector. @@ -2961,7 +2793,6 @@ static void HWR_Subsector(size_t num) extracolormap_t *floorcolormap; extracolormap_t *ceilingcolormap; ffloor_t *rover; - boolean skipSprites = false; #ifdef PARANOIA //no risk while developing, enough debugging nights! if (num >= addsubsector) @@ -2974,7 +2805,7 @@ static void HWR_Subsector(size_t num) // subsector sub = &subsectors[num]; // sector - gr_frontsector = sub->sector; + gl_frontsector = sub->sector; // how many linedefs count = sub->numlines; // first line seg @@ -2984,35 +2815,35 @@ static void HWR_Subsector(size_t num) { // there are no segs but only planes sub = &subsectors[0]; - gr_frontsector = sub->sector; + gl_frontsector = sub->sector; count = 0; line = NULL; } //SoM: 4/7/2000: Test to make Boom water work in Hardware mode. - gr_frontsector = R_FakeFlat(gr_frontsector, &tempsec, &floorlightlevel, + gl_frontsector = R_FakeFlat(gl_frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false); - if (gr_portal == GRPORTAL_SEARCH) + if (gl_portal_state == GLPORTAL_SEARCH) { - skipSprites = true; - goto skip_stuff_for_portals;// hopefully this goto is okay + HWR_PortalSubsector(line, sub, count); + return; } - floorcolormap = ceilingcolormap = gr_frontsector->extra_colormap; + floorcolormap = ceilingcolormap = gl_frontsector->extra_colormap; - cullFloorHeight = P_GetSectorFloorZAt (gr_frontsector, viewx, viewy); - cullCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, viewx, viewy); - locFloorHeight = P_GetSectorFloorZAt (gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); - locCeilingHeight = P_GetSectorCeilingZAt(gr_frontsector, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); + cullFloorHeight = P_GetSectorFloorZAt (gl_frontsector, viewx, viewy); + cullCeilingHeight = P_GetSectorCeilingZAt(gl_frontsector, viewx, viewy); + locFloorHeight = P_GetSectorFloorZAt (gl_frontsector, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); + locCeilingHeight = P_GetSectorCeilingZAt(gl_frontsector, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); - if (gr_frontsector->ffloors) + if (gl_frontsector->ffloors) { - boolean anyMoved = gr_frontsector->moved; + boolean anyMoved = gl_frontsector->moved; if (anyMoved == false) { - for (rover = gr_frontsector->ffloors; rover; rover = rover->next) + for (rover = gl_frontsector->ffloors; rover; rover = rover->next) { sector_t *controlSec = §ors[rover->secnum]; @@ -3026,64 +2857,64 @@ static void HWR_Subsector(size_t num) if (anyMoved == true) { - gr_frontsector->numlights = sub->sector->numlights = 0; - R_Prep3DFloors(gr_frontsector); - sub->sector->lightlist = gr_frontsector->lightlist; - sub->sector->numlights = gr_frontsector->numlights; - sub->sector->moved = gr_frontsector->moved = false; + gl_frontsector->numlights = sub->sector->numlights = 0; + R_Prep3DFloors(gl_frontsector); + sub->sector->lightlist = gl_frontsector->lightlist; + sub->sector->numlights = gl_frontsector->numlights; + sub->sector->moved = gl_frontsector->moved = false; } - light = R_GetPlaneLight(gr_frontsector, locFloorHeight, false); - if (gr_frontsector->floorlightsec == -1) - floorlightlevel = *gr_frontsector->lightlist[light].lightlevel; - floorcolormap = gr_frontsector->lightlist[light].extra_colormap; + light = R_GetPlaneLight(gl_frontsector, locFloorHeight, false); + if (gl_frontsector->floorlightsec == -1) + floorlightlevel = *gl_frontsector->lightlist[light].lightlevel; + floorcolormap = gl_frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(gr_frontsector, locCeilingHeight, false); - if (gr_frontsector->ceilinglightsec == -1) - ceilinglightlevel = *gr_frontsector->lightlist[light].lightlevel; - ceilingcolormap = gr_frontsector->lightlist[light].extra_colormap; + light = R_GetPlaneLight(gl_frontsector, locCeilingHeight, false); + if (gl_frontsector->ceilinglightsec == -1) + ceilinglightlevel = *gl_frontsector->lightlist[light].lightlevel; + ceilingcolormap = gl_frontsector->lightlist[light].extra_colormap; } - sub->sector->extra_colormap = gr_frontsector->extra_colormap; + sub->sector->extra_colormap = gl_frontsector->extra_colormap; // render floor ? // yeah, easy backface cull! :) if (cullFloorHeight < viewz) { - if (gr_frontsector->floorpic != skyflatnum) + if (gl_frontsector->floorpic != skyflatnum) { if (sub->validcount != validcount) { - HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum, R_NoEncore(gr_frontsector, false)); + HWR_GetFlat(levelflats[gl_frontsector->floorpic].lumpnum, R_NoEncore(gl_frontsector, false)); HWR_RenderPlane(sub, &extrasubsectors[num], false, // Hack to make things continue to work around slopes. - locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, + locFloorHeight == cullFloorHeight ? locFloorHeight : gl_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap); + PF_Occlude, floorlightlevel, levelflats[gl_frontsector->floorpic].lumpnum, NULL, 255, floorcolormap); } } } if (cullCeilingHeight > viewz) { - if (gr_frontsector->ceilingpic != skyflatnum) + if (gl_frontsector->ceilingpic != skyflatnum) { if (sub->validcount != validcount) { - HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum, R_NoEncore(gr_frontsector, true)); + HWR_GetFlat(levelflats[gl_frontsector->ceilingpic].lumpnum, R_NoEncore(gl_frontsector, true)); HWR_RenderPlane(sub, &extrasubsectors[num], true, // Hack to make things continue to work around slopes. - locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, + locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gl_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap); + PF_Occlude, ceilinglightlevel, levelflats[gl_frontsector->ceilingpic].lumpnum,NULL, 255, ceilingcolormap); } } } - if (gr_frontsector->ffloors) + if (gl_frontsector->ffloors) { /// \todo fix light, xoffs, yoffs, extracolormap ? - for (rover = gr_frontsector->ffloors; + for (rover = gl_frontsector->ffloors; rover; rover = rover->next) { fixed_t bottomCullHeight, topCullHeight, centerHeight; @@ -3092,20 +2923,20 @@ static void HWR_Subsector(size_t num) continue; if (sub->validcount == validcount) continue; - + // rendering heights for bottom and top planes // yes there were functions for this stuff, no idea why it wasnt used but bleh bottomCullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy); - if (gr_frontsector->cullheight) + if (gl_frontsector->cullheight) { - if (HWR_DoCulling(gr_frontsector->cullheight, viewsector->cullheight, gr_viewz, FIXED_TO_FLOAT(*rover->bottomheight), FIXED_TO_FLOAT(*rover->topheight))) + if (HWR_DoCulling(gl_frontsector->cullheight, viewsector->cullheight, gl_viewz, FIXED_TO_FLOAT(*rover->bottomheight), FIXED_TO_FLOAT(*rover->topheight))) continue; } // bottom plane - centerHeight = P_GetFFloorBottomZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); + centerHeight = P_GetFFloorBottomZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && ((viewz < bottomCullHeight && !(rover->flags & FF_INVERTPLANES)) || @@ -3115,40 +2946,42 @@ static void HWR_Subsector(size_t num) { UINT8 alpha; - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); + alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, &extrasubsectors[num], false, *rover->bottomheight, - *gr_frontsector->lightlist[light].lightlevel, + *gl_frontsector->lightlist[light].lightlevel, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient { - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); + HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum, &extrasubsectors[num], false, *rover->bottomheight, - *gr_frontsector->lightlist[light].lightlevel, + *gl_frontsector->lightlist[light].lightlevel, CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, - false, gr_frontsector->lightlist[light].extra_colormap); + false, gl_frontsector->lightlist[light].extra_colormap); } else { - HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gr_frontsector, false)); - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); - HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); + HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gl_frontsector, false)); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false); + + HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, + rover->master->frontsector, 255, gl_frontsector->lightlist[light].extra_colormap); } } // top plane - centerHeight = P_GetFFloorTopZAt(rover, gr_frontsector->soundorg.x, gr_frontsector->soundorg.y); + centerHeight = P_GetFFloorTopZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && @@ -3159,35 +2992,37 @@ static void HWR_Subsector(size_t num) { UINT8 alpha; - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < topCullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false); - alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); + alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, &extrasubsectors[num], true, *rover->topheight, - *gr_frontsector->lightlist[light].lightlevel, + *gl_frontsector->lightlist[light].lightlevel, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, true, rover->master->frontsector->extra_colormap); } else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) { - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < topCullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false); + HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum, &extrasubsectors[num], true, *rover->topheight, - *gr_frontsector->lightlist[light].lightlevel, + *gl_frontsector->lightlist[light].lightlevel, CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, - false, gr_frontsector->lightlist[light].extra_colormap); + false, gl_frontsector->lightlist[light].extra_colormap); } else { - HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gr_frontsector, true)); - light = R_GetPlaneLight(gr_frontsector, centerHeight, viewz < topCullHeight ? true : false); - HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, - rover->master->frontsector, 255, gr_frontsector->lightlist[light].extra_colormap); + HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gl_frontsector, true)); + light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false); + + HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, + rover->master->frontsector, 255, gl_frontsector->lightlist[light].extra_colormap); } } } @@ -3223,22 +3058,19 @@ static void HWR_Subsector(size_t num) } } -skip_stuff_for_portals: - -// Hurder ici se passe les choses INT32�essantes! -// on vient de tracer le sol et le plafond -// on trace �pr�ent d'abord les sprites et ensuite les murs -// hurdler: faux: on ajoute seulement les sprites, le murs sont trac� d'abord + // Hurdler: here interesting things are happening! + // we have just drawn the floor and ceiling + // we now draw the sprites first and then the walls + // hurdler: false: we only add the sprites, the walls are drawn first if (line) { // draw sprites first, coz they are clipped to the solidsegs of // subsectors more 'in front' - if (!skipSprites) - HWR_AddSprites(gr_frontsector); + HWR_AddSprites(gl_frontsector); //Hurdler: at this point validcount must be the same, but is not because - // gr_frontsector doesn't point anymore to sub->sector due to - // the call gr_frontsector = R_FakeFlat(...) + // gl_frontsector doesn't point anymore to sub->sector due to + // the call gl_frontsector = R_FakeFlat(...) // if it's not done, the sprite is drawn more than once, // what looks really bad with translucency or dynamic light, // without talking about the overdraw of course. @@ -3247,7 +3079,7 @@ skip_stuff_for_portals: while (count--) { if (!line->polyseg) // ignore segs that belong to polyobjects - HWR_AddLine(line); + HWR_AddLine(line); line++; } } @@ -3255,60 +3087,6 @@ skip_stuff_for_portals: sub->validcount = validcount; } -// idea for fixing fakery map: one portal pillar works, 2 pillars have left/right bug wall, 1 pillar has both sides bugged. -// bounding box is probably right on the edge, maybe could check for this with P_ClosestPointOnLine -// so: for each side check, if it passes then also check distance to line, -// if its zero (or very close?) then dont return true, instead continue to next side check -// it helped with center pillars! but other parts still have issues, probably because some of bounding box is on correct side. - -// idea for further clipping improvement: -// have a separate xyz coordinate for portal view side checking: one that is derived by moving the viewxyz forward -// the new coords would be at the intersection of line_a and line_b, where -// line_a = line of view, pointing forward from the center of the camera -// line_b = a line orthogonal to line_a, defined so that the nearest vertex of portalclipline lies within it -// maybe if the seg to be drawn has these new coords on one side and the normal viewxyz on the other side then it can be culled? - -// looks like P_Thrust in p_user.c has code for moving point forward towards a direction -// maybe P_InterceptVector could be used for intersect point -// use returned value as multiplier for the added values from p_thrust thing -// P_InterceptVector needs divlines which need dx and dy, dx=x2-x1 dy=y2-y1 - -// returns true if the point is on the correct (viewable) side of the -// portal destination line -static boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y) -{ - // we are checking if the point is on the viewable side of the portal exit. - // being exactly on the portal exit line is not enough to pass the test. - // P_PointOnLineSide could behave differently from this expectation on this case, - // so first check if the point is precisely on the line, and then if not, check the side. - - vertex_t closest_point; - P_ClosestPointOnLine(x, y, portalclipline, &closest_point); - if (closest_point.x != x || closest_point.y != y) - { - if (P_PointOnLineSide(x, y, portalclipline) != 1) - return true; - } - return false; -} - -static boolean HWR_PortalCheckBBox(const fixed_t *bspcoord) -{ - if (!portalclipline) - return true; - - if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) || - HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) || - HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) || - HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM])) - { - return true; - } - - // we did not find any reason to pass the check, so return failure - return false; -} - // // Renders all subsectors below a given node, // traversing subtree recursively. @@ -3331,9 +3109,9 @@ static void HWR_RenderBSPNode(INT32 bspnum) if (HWR_PortalCheckBBox(bsp->bbox[side])) HWR_RenderBSPNode(bsp->children[side]); - // Possibly divide back space - if (!(HWR_CheckBBox(bsp->bbox[side^1]) && HWR_PortalCheckBBox(bsp->bbox[side^1]))) - return; + // Possibly divide back space + if (!(HWR_CheckBBox(bsp->bbox[side^1]) && HWR_PortalCheckBBox(bsp->bbox[side^1]))) + return; bspnum = bsp->children[side^1]; } @@ -3341,6 +3119,8 @@ static void HWR_RenderBSPNode(INT32 bspnum) // PORTAL CULLING if (portalclipline && portalcullsector) { + // skip all subsectors encountered before the portal + // destination's front sector if (portalcullsector != subsectors[bspnum & ~NF_SUBSECTOR].sector) return; else @@ -3352,14 +3132,14 @@ static void HWR_RenderBSPNode(INT32 bspnum) } // ========================================================================== -// gr_things.c +// gl_things.c // ========================================================================== // sprites are drawn after all wall and planes are rendered, so that // sprite translucency effects apply on the rendered view (instead of the background sky!!) -static UINT32 gr_visspritecount; -static gr_vissprite_t *gr_visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; +static UINT32 gl_visspritecount; +static gl_vissprite_t *gl_visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL}; // -------------------------------------------------------------------------- // HWR_ClearSprites @@ -3367,31 +3147,31 @@ static gr_vissprite_t *gr_visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = // -------------------------------------------------------------------------- static void HWR_ClearSprites(void) { - gr_visspritecount = 0; + gl_visspritecount = 0; } // -------------------------------------------------------------------------- // HWR_NewVisSprite // -------------------------------------------------------------------------- -static gr_vissprite_t gr_overflowsprite; +static gl_vissprite_t gl_overflowsprite; -static gr_vissprite_t *HWR_GetVisSprite(UINT32 num) +static gl_vissprite_t *HWR_GetVisSprite(UINT32 num) { UINT32 chunk = num >> VISSPRITECHUNKBITS; // Allocate chunk if necessary - if (!gr_visspritechunks[chunk]) - Z_Malloc(sizeof(gr_vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &gr_visspritechunks[chunk]); + if (!gl_visspritechunks[chunk]) + Z_Malloc(sizeof(gl_vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &gl_visspritechunks[chunk]); - return gr_visspritechunks[chunk] + (num & VISSPRITEINDEXMASK); + return gl_visspritechunks[chunk] + (num & VISSPRITEINDEXMASK); } -static gr_vissprite_t *HWR_NewVisSprite(void) +static gl_vissprite_t *HWR_NewVisSprite(void) { - if (gr_visspritecount == MAXVISSPRITES) - return &gr_overflowsprite; + if (gl_visspritecount == MAXVISSPRITES) + return &gl_overflowsprite; - return HWR_GetVisSprite(gr_visspritecount++); + return HWR_GetVisSprite(gl_visspritecount++); } // Finds a floor through which light does not pass. @@ -3428,7 +3208,7 @@ static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t hei return floorz; } -static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch) +static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, GLPatch_t *gpatch) { float this_scale = 1.0f; FOutVector swallVerts[4]; @@ -3518,10 +3298,10 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch) swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->gzt - gpatch->topoffset * this_scale - (floorheight+3); // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin; + swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gl_viewcos; + swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gl_viewcos; + swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gl_viewsin; + swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gl_viewsin; } else { @@ -3529,19 +3309,19 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch) swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->gzt - gpatch->topoffset - (floorheight+3); // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin; + swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gl_viewcos; + swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gl_viewcos; + swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gl_viewsin; + swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gl_viewsin; } // We also need to move the bottom ones away when shadowoffs is on if (cv_shadowoffs.value) { - swallVerts[0].x = spr->x1 + offset * gr_viewcos; - swallVerts[1].x = spr->x2 + offset * gr_viewcos; - swallVerts[0].z = spr->z1 + offset * gr_viewsin; - swallVerts[1].z = spr->z2 + offset * gr_viewsin; + swallVerts[0].x = spr->x1 + offset * gl_viewcos; + swallVerts[1].x = spr->x2 + offset * gl_viewcos; + swallVerts[0].z = spr->z1 + offset * gl_viewsin; + swallVerts[1].z = spr->z2 + offset * gl_viewsin; } if (floorslope) @@ -3608,20 +3388,20 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch) } // This is expecting a pointer to an array containing 4 wallVerts for a sprite -static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) +static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip) { - if (cv_grspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) && wallVerts) + if (cv_glspritebillboarding.value && spr && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE) && wallVerts) { // uncapped/interpolation interpmobjstate_t interp = {0}; float basey, lowy; INT32 dist = -1; - if (cv_grmaxinterpdist.value) + if (cv_maxinterpdist.value) dist = R_QuickCamDist(spr->mobj->x, spr->mobj->y); // do interpolation - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value)) { if (precip) { @@ -3658,24 +3438,24 @@ static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts // X, Y, AND Z need to be manipulated for the polys to rotate around the // origin, because of how the origin setting works I believe that should // be mobj->z or mobj->z + mobj->height - wallVerts[2].y = wallVerts[3].y = (spr->gzt - basey) * gr_viewludsin + basey; - wallVerts[0].y = wallVerts[1].y = (lowy - basey) * gr_viewludsin + basey; + wallVerts[2].y = wallVerts[3].y = (spr->gzt - basey) * gl_viewludsin + basey; + wallVerts[0].y = wallVerts[1].y = (lowy - basey) * gl_viewludsin + basey; // translate back to be around 0 before translating back - wallVerts[3].x += ((spr->gzt - basey) * gr_viewludcos) * gr_viewcos; - wallVerts[2].x += ((spr->gzt - basey) * gr_viewludcos) * gr_viewcos; + wallVerts[3].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos; + wallVerts[2].x += ((spr->gzt - basey) * gl_viewludcos) * gl_viewcos; - wallVerts[0].x += ((lowy - basey) * gr_viewludcos) * gr_viewcos; - wallVerts[1].x += ((lowy - basey) * gr_viewludcos) * gr_viewcos; + wallVerts[0].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos; + wallVerts[1].x += ((lowy - basey) * gl_viewludcos) * gl_viewcos; - wallVerts[3].z += ((spr->gzt - basey) * gr_viewludcos) * gr_viewsin; - wallVerts[2].z += ((spr->gzt - basey) * gr_viewludcos) * gr_viewsin; + wallVerts[3].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin; + wallVerts[2].z += ((spr->gzt - basey) * gl_viewludcos) * gl_viewsin; - wallVerts[0].z += ((lowy - basey) * gr_viewludcos) * gr_viewsin; - wallVerts[1].z += ((lowy - basey) * gr_viewludcos) * gr_viewsin; + wallVerts[0].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin; + wallVerts[1].z += ((lowy - basey) * gl_viewludcos) * gl_viewsin; } } -static void HWR_SplitSprite(gr_vissprite_t *spr) +static void HWR_SplitSprite(gl_vissprite_t *spr) { FOutVector wallVerts[4]; FOutVector baseWallVerts[4]; // This is what the verts should end up as @@ -3759,13 +3539,13 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) HWR_RotateSpritePolyToAim(spr, baseWallVerts, false); // push it toward the camera to mitigate floor-clipping sprites - float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz)); + float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz)); float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; for (i = 0; i < 4; i++) { - baseWallVerts[i].x += (gr_viewx - baseWallVerts[i].x)*distfact; - baseWallVerts[i].z += (gr_viewy - baseWallVerts[i].z)*distfact; - baseWallVerts[i].y += (gr_viewz - baseWallVerts[i].y)*distfact; + baseWallVerts[i].x += (gl_viewx - baseWallVerts[i].x)*distfact; + baseWallVerts[i].z += (gl_viewy - baseWallVerts[i].z)*distfact; + baseWallVerts[i].y += (gl_viewz - baseWallVerts[i].y)*distfact; } realtop = top = baseWallVerts[3].y; @@ -3811,7 +3591,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) } alpha = Surf.PolyColor.s.alpha; - + // Start with the lightlevel and colormap from the top of the sprite lightlevel = *list[sector->numlights - 1].lightlevel; @@ -3884,7 +3664,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) wallVerts[1].y = endbot; // The x and y only need to be adjusted in the case that it's not a papersprite - if (cv_grspritebillboarding.value && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) + if (cv_glspritebillboarding.value && spr->mobj && !(spr->mobj->frame & FF_PAPERSPRITE)) { // Get the x and z of the vertices so billboarding draws correctly realheight = realbot - realtop; @@ -3945,13 +3725,13 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) // : (monsters, bonuses, weapons, lights, ...) // Returns : // -----------------+ -static void HWR_DrawSprite(gr_vissprite_t *spr) +static void HWR_DrawSprite(gl_vissprite_t *spr) { FOutVector wallVerts[4]; GLPatch_t *gpatch; // sprite patch converted to hardware FSurfaceInfo Surf; FBITFIELD blend = 0; - + INT32 shader = SHADER_NONE; if (!spr->mobj) @@ -4033,14 +3813,14 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) HWR_RotateSpritePolyToAim(spr, wallVerts, false); // push it toward the camera to mitigate floor-clipping sprites - float sprdist = sqrtf((spr->x1 - gr_viewx)*(spr->x1 - gr_viewx) + (spr->z1 - gr_viewy)*(spr->z1 - gr_viewy) + (spr->gzt - gr_viewz)*(spr->gzt - gr_viewz)); + float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz)); float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist; size_t i; for (i = 0; i < 4; i++) { - wallVerts[i].x += (gr_viewx - wallVerts[i].x)*distfact; - wallVerts[i].z += (gr_viewy - wallVerts[i].z)*distfact; - wallVerts[i].y += (gr_viewz - wallVerts[i].y)*distfact; + wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact; + wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact; + wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact; } // This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black. @@ -4089,7 +3869,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) } // Sprite drawer for precipitation -static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) +static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) { FBITFIELD blend = 0; FOutVector wallVerts[4]; @@ -4190,14 +3970,14 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // Sort vissprites by distance // -------------------------------------------------------------------------- -gr_vissprite_t* gr_vsprorder[MAXVISSPRITES]; +gl_vissprite_t* gl_vsprorder[MAXVISSPRITES]; // For more correct transparency the transparent sprites would need to be // sorted and drawn together with transparent surfaces. static int CompareVisSprites(const void *p1, const void *p2) { - gr_vissprite_t* spr1 = *(gr_vissprite_t*const*)p1; - gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2; + gl_vissprite_t* spr1 = *(gl_vissprite_t*const*)p1; + gl_vissprite_t* spr2 = *(gl_vissprite_t*const*)p2; int idiff; float fdiff; @@ -4222,12 +4002,12 @@ static int CompareVisSprites(const void *p1, const void *p2) static void HWR_SortVisSprites(void) { UINT32 i; - for (i = 0; i < gr_visspritecount; i++) + for (i = 0; i < gl_visspritecount; i++) { - gr_vsprorder[i] = HWR_GetVisSprite(i); + gl_vsprorder[i] = HWR_GetVisSprite(i); } - qs22j(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites); + qs22j(gl_vsprorder, gl_visspritecount, sizeof(gl_vissprite_t*), CompareVisSprites); } // A drawnode is something that points to a 3D floor, 3D side, or masked @@ -4276,37 +4056,37 @@ typedef enum DRAWNODE_PLANE, DRAWNODE_POLYOBJECT_PLANE, DRAWNODE_WALL -} gr_drawnode_type_t; +} gl_drawnode_type_t; typedef struct { - gr_drawnode_type_t type; + gl_drawnode_type_t type; union { planeinfo_t plane; polyplaneinfo_t polyplane; wallinfo_t wall; } u; -} gr_drawnode_t; +} gl_drawnode_t; // initial size of drawnode array #define DRAWNODES_INIT_SIZE 64 -gr_drawnode_t *drawnodes = NULL; +gl_drawnode_t *drawnodes = NULL; INT32 numdrawnodes = 0; INT32 alloceddrawnodes = 0; -static void *HWR_CreateDrawNode(gr_drawnode_type_t type) +static void *HWR_CreateDrawNode(gl_drawnode_type_t type) { - gr_drawnode_t *drawnode; + gl_drawnode_t *drawnode; if (!drawnodes) { alloceddrawnodes = DRAWNODES_INIT_SIZE; - drawnodes = Z_Malloc(alloceddrawnodes * sizeof(gr_drawnode_t), PU_LEVEL, &drawnodes); + drawnodes = Z_Malloc(alloceddrawnodes * sizeof(gl_drawnode_t), PU_LEVEL, &drawnodes); } else if (numdrawnodes >= alloceddrawnodes) { alloceddrawnodes *= 2; - Z_Realloc(drawnodes, alloceddrawnodes * sizeof(gr_drawnode_t), PU_LEVEL, &drawnodes); + Z_Realloc(drawnodes, alloceddrawnodes * sizeof(gl_drawnode_t), PU_LEVEL, &drawnodes); } @@ -4326,7 +4106,7 @@ static void *HWR_CreateDrawNode(gr_drawnode_type_t type) return NULL; } -void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) +static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { wallinfo_t *wallinfo = HWR_CreateDrawNode(DRAWNODE_WALL); @@ -4340,7 +4120,7 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 te wallinfo->wallcolormap = wallcolormap; } -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) +static void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) { planeinfo_t *planeinfo = HWR_CreateDrawNode(DRAWNODE_PLANE); @@ -4358,7 +4138,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean // Adding this for now until I can create extrasubsector info for polyobjects // When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) +static void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) { polyplaneinfo_t *polyplaneinfo = HWR_CreateDrawNode(DRAWNODE_POLYOBJECT_PLANE); @@ -4445,14 +4225,14 @@ static void HWR_RenderDrawNodes(void) for (i = 0; i < numdrawnodes; i++) { - gr_drawnode_t *drawnode = &drawnodes[sortindex[i]]; + gl_drawnode_t *drawnode = &drawnodes[sortindex[i]]; if (drawnode->type == DRAWNODE_PLANE) { planeinfo_t *plane = &drawnode->u.plane; - // We aren't traversing the BSP tree, so make gr_frontsector null to avoid crashes. - gr_frontsector = NULL; + // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. + gl_frontsector = NULL; if (!(plane->blend & PF_NoTexture)) HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling)); @@ -4464,8 +4244,8 @@ static void HWR_RenderDrawNodes(void) { polyplaneinfo_t *polyplane = &drawnode->u.polyplane; - // We aren't traversing the BSP tree, so make gr_frontsector null to avoid crashes. - gr_frontsector = NULL; + // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. + gl_frontsector = NULL; if (!(polyplane->blend & PF_NoTexture)) HWR_GetFlat(polyplane->lumpnum, R_NoEncore(polyplane->FOFSector, polyplane->isceiling)); @@ -4484,7 +4264,7 @@ static void HWR_RenderDrawNodes(void) wall->lightlevel, wall->wallcolormap); } } - + PS_STOP_TIMING(ps_hw_nodedrawtime); numdrawnodes = 0; @@ -4496,12 +4276,13 @@ static void HWR_RenderDrawNodes(void) // -------------------------------------------------------------------------- // Draw all vissprites // -------------------------------------------------------------------------- -void HWR_DrawSprites(void) +static void HWR_DrawSprites(void) { UINT32 i; - for (i = 0; i < gr_visspritecount; i++) + + for (i = 0; i < gl_visspritecount; i++) { - gr_vissprite_t *spr = gr_vsprorder[i]; + gl_vissprite_t *spr = gl_vsprorder[i]; if (spr->precip) { @@ -4523,14 +4304,14 @@ void HWR_DrawSprites(void) md2 = &md2_playermodels[(skin_t *)spr->mobj->skin - skins]; // 8/1/19: Only don't display player models if no default SPR_PLAY is found. - if (!cv_grmdls.value || ((md2->notfound || md2->scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)) || spr->mobj->state == &states[S_PLAY_SIGN]) + if (!cv_glmdls.value || ((md2->notfound || md2->scale < 0.0f) && ((!cv_glfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)) || spr->mobj->state == &states[S_PLAY_SIGN]) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); } else { - if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + if (!cv_glmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); else HWR_DrawMD2(spr); @@ -4542,7 +4323,7 @@ void HWR_DrawSprites(void) // HWR_AddSprites // During BSP traversal, this adds sprites by sector. // -------------------------------------------------------------------------- -void HWR_AddSprites(sector_t *sec) +static void HWR_AddSprites(sector_t *sec) { mobj_t *thing; fixed_t limit_dist; @@ -4595,7 +4376,7 @@ static void HWR_AddPrecipitationSprites(void) INT32 xl, xh, yl, yh, bx, by; precipmobj_t *th; - + if (current_bsp_culling_distance) drawdist = min((fixed_t)current_bsp_culling_distance, (fixed_t)(cv_drawdist_precip.value) * precipscale); else @@ -4629,9 +4410,9 @@ static void HWR_AddPrecipitationSprites(void) // Generates a vissprite for a thing if it might be visible. // -------------------------------------------------------------------------- // BP why not use xtoviexangle/viewangletox like in bsp ?.... -void HWR_ProjectSprite(mobj_t *thing) +static void HWR_ProjectSprite(mobj_t *thing) { - gr_vissprite_t *vis; + gl_vissprite_t *vis; float tr_x, tr_y; float tz; float x1, x2; @@ -4666,21 +4447,21 @@ void HWR_ProjectSprite(mobj_t *thing) angle_t sliptiderollangle = 0; #endif - // uncapped/interpolation - interpmobjstate_t interp = {0}; - if (!thing) return; + // uncapped/interpolation + interpmobjstate_t interp = {0}; + vflip = (thing->eflags & MFE_VERTICALFLIP); mirrored = thing->mirrored; hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored); papersprite = (thing->frame & FF_PAPERSPRITE); - if (cv_grmaxinterpdist.value) + if (cv_maxinterpdist.value) dist = R_QuickCamDist(thing->x, thing->y); - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value)) { R_InterpolateMobjState(thing, rendertimefrac, &interp); } @@ -4697,14 +4478,14 @@ void HWR_ProjectSprite(mobj_t *thing) spriteyscale = FIXED_TO_FLOAT(interp.spriteyscale); // transform the origin point - tr_x = FIXED_TO_FLOAT(interp.x) - gr_viewx; - tr_y = FIXED_TO_FLOAT(interp.y) - gr_viewy; + tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy; // rotation around vertical axis - tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); + tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear + if (tz < ZCLIP_PLANE && !papersprite && (!cv_glmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear return; // The above can stay as it works for cutting sprites that are too close @@ -4776,9 +4557,9 @@ void HWR_ProjectSprite(mobj_t *thing) else { // choose a different rotation based on player view - if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -4802,9 +4583,9 @@ void HWR_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE if (cv_spriteroll.value) { - rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll) + rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll) + FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), interp.pitch) - + FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll) + + FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll) + FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), interp.slopepitch) + thing->rollangle; @@ -4823,12 +4604,12 @@ void HWR_ProjectSprite(mobj_t *thing) if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; spr_topoffset += FEETADJUST; - + // flip -> rotate, not rotate -> flip flip = 0; } @@ -4836,21 +4617,8 @@ void HWR_ProjectSprite(mobj_t *thing) } #endif - if (thing->renderflags & RF_ABSOLUTEOFFSETS) - { - spr_offset = interp.spritexoffset; - spr_topoffset = interp.spriteyoffset; - } - else - { - SINT8 flipoffset = 1; - - if ((thing->renderflags & RF_FLIPOFFSETS) && flip) - flipoffset = -1; - - spr_offset += interp.spritexoffset * flipoffset; - spr_topoffset += interp.spriteyoffset * flipoffset; - } + spr_offset += interp.spritexoffset; + spr_topoffset += interp.spriteyoffset; if (papersprite) { @@ -4865,7 +4633,7 @@ void HWR_ProjectSprite(mobj_t *thing) spritexscale *= this_scale; spriteyscale *= this_scale; - + flip = !flip != !hflip; if (flip) @@ -4897,7 +4665,7 @@ void HWR_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->cullheight) { - if (HWR_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, gr_viewz, gz, gzt)) + if (HWR_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, gl_viewz, gz, gzt)) return; } @@ -4909,14 +4677,13 @@ void HWR_ProjectSprite(mobj_t *thing) if (heightsec != -1 && phs != -1) // only clip things which are in special sectors { - if (gr_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ? - FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) : - gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight)) + if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ? + FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) : + gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight)) return; - - if (gr_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ? - gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gr_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) : - FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight)) + if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ? + gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) : + FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight)) return; } @@ -4926,7 +4693,9 @@ void HWR_ProjectSprite(mobj_t *thing) vis->x2 = x2; vis->z1 = z1; vis->z2 = z2; + vis->tz = tz; // Keep tz for the simple sprite sorting that happens + vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->flip = flip; @@ -4989,7 +4758,7 @@ void HWR_ProjectSprite(mobj_t *thing) // Precipitation projector for hardware mode static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) { - gr_vissprite_t *vis; + gl_vissprite_t *vis; float tr_x, tr_y; float tz; float x1, x2; @@ -5015,11 +4784,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) return; } - if (cv_grmaxinterpdist.value) + if (cv_maxinterpdist.value) dist = R_QuickCamDist(thing->x, thing->y); // do interpolation - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value)) { R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp); } @@ -5031,11 +4800,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) this_scale = FIXED_TO_FLOAT(interp.scale); // transform the origin point - tr_x = FIXED_TO_FLOAT(interp.x) - gr_viewx; - tr_y = FIXED_TO_FLOAT(interp.y) - gr_viewy; + tr_x = FIXED_TO_FLOAT(interp.x) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interp.y) - gl_viewy; // rotation around vertical axis - tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); + tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); // thing is behind view plane? if (tz < ZCLIP_PLANE) @@ -5120,7 +4889,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) static boolean drewsky = false; -void HWR_DrawSkyBackground(float fpov) +static void HWR_DrawSkyBackground(float fpov) { FTransform dometransform; @@ -5130,7 +4899,7 @@ void HWR_DrawSkyBackground(float fpov) memset(&dometransform, 0x00, sizeof(FTransform)); //04/01/2000: Hurdler: added for T&L - // It should replace all other gr_viewxxx when finished + // It should replace all other gl_viewxxx when finished HWR_SetTransformAiming(&dometransform); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); @@ -5158,10 +4927,10 @@ void HWR_DrawSkyBackground(float fpov) // -----------------+ static inline void HWR_ClearView(void) { - HWD.pfnGClipRect((INT32)gr_viewwindowx, - (INT32)gr_viewwindowy, - (INT32)(gr_viewwindowx + gr_viewwidth), - (INT32)(gr_viewwindowy + gr_viewheight), + HWD.pfnGClipRect((INT32)gl_viewwindowx, + (INT32)gl_viewwindowy, + (INT32)(gl_viewwindowx + gl_viewwidth), + (INT32)(gl_viewwindowy + gl_viewheight), ZCLIP_PLANE, FAR_ZCLIP_DEFAULT); HWD.pfnClearBuffer(false, true, true, NULL); } @@ -5173,26 +4942,17 @@ static inline void HWR_ClearView(void) void HWR_SetViewSize(void) { // setup view size - gr_viewwidth = (float)vid.width; - gr_viewheight = (float)vid.height; + gl_viewwidth = (float)vid.width; + gl_viewheight = (float)vid.height; if (splitscreen) - gr_viewheight /= 2; + gl_viewheight /= 2; if (splitscreen > 1) - gr_viewwidth /= 2; + gl_viewwidth /= 2; - gr_basecenterx = gr_viewwidth / 2; - gr_basecentery = gr_viewheight / 2; - - gr_baseviewwindowy = 0; - gr_basewindowcentery = (float)(gr_viewheight / 2); - - gr_baseviewwindowx = 0; - gr_basewindowcenterx = (float)(gr_viewwidth / 2); - - gr_pspritexscale = ((vid.width*gr_pspriteyscale*BASEVIDHEIGHT)/BASEVIDWIDTH)/vid.height; - gr_pspriteyscale = ((vid.height*gr_pspritexscale*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width; + gl_baseviewwindowy = 0; + gl_baseviewwindowx = 0; HWD.pfnFlushScreenTextures(); } @@ -5201,38 +4961,35 @@ void HWR_SetViewSize(void) // and the normal view, all with a single function. static void HWR_SetTransformAiming(FTransform *trans) { - if (cv_grshearing.value) + if (cv_glshearing.value) { fixed_t fixedaiming = AIMINGTODY(aimingangle); trans->viewaiming = FIXED_TO_FLOAT(fixedaiming); trans->shearing = true; - gr_aimingangle = 0; + gl_aimingangle = 0; } else { trans->shearing = false; - gr_aimingangle = aimingangle; + gl_aimingangle = aimingangle; } - trans->anglex = (float)(gr_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + trans->anglex = (float)(gl_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); } void HWR_SetTransform(float fpov, player_t *player) { - postimg_t *postprocessor = &postimgtype[0]; - INT32 i; - - gr_viewx = FIXED_TO_FLOAT(viewx); - gr_viewy = FIXED_TO_FLOAT(viewy); - gr_viewz = FIXED_TO_FLOAT(viewz); - gr_viewsin = FIXED_TO_FLOAT(viewsin); - gr_viewcos = FIXED_TO_FLOAT(viewcos); + gl_viewx = FIXED_TO_FLOAT(viewx); + gl_viewy = FIXED_TO_FLOAT(viewy); + gl_viewz = FIXED_TO_FLOAT(viewz); + gl_viewsin = FIXED_TO_FLOAT(viewsin); + gl_viewcos = FIXED_TO_FLOAT(viewcos); memset(&atransform, 0x00, sizeof(FTransform)); // Set T&L transform - atransform.x = gr_viewx; - atransform.y = gr_viewy; - atransform.z = gr_viewz; + atransform.x = gl_viewx; + atransform.y = gl_viewy; + atransform.z = gl_viewz; atransform.scalex = 1; atransform.scaley = (float)vid.width/vid.height; @@ -5241,32 +4998,24 @@ void HWR_SetTransform(float fpov, player_t *player) HWR_SetTransformAiming(&atransform); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - gr_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gr_aimingangle>>ANGLETOFINESHIFT)); - gr_viewludcos = FIXED_TO_FLOAT(-FINESINE(gr_aimingangle>>ANGLETOFINESHIFT)); + gl_viewludsin = FIXED_TO_FLOAT(FINECOSINE(gl_aimingangle>>ANGLETOFINESHIFT)); + gl_viewludcos = FIXED_TO_FLOAT(-FINESINE(gl_aimingangle>>ANGLETOFINESHIFT)); atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails HWR_RollTransform(&atransform, viewroll); atransform.splitscreen = splitscreen; - for (i = 0; i <= splitscreen; i++) - { - if (player != &players[displayplayers[i]]) - continue; - - postprocessor = &postimgtype[i]; - } - atransform.flip = false; - if (*postprocessor == postimg_flip) + if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR)) atransform.flip = true; atransform.mirror = false; - if (*postprocessor == postimg_mirror) + if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP)) atransform.mirror = true; atransform.mirrorflip = false; - if (*postprocessor == postimg_mirrorflip) + if ((player->postimgflags & POSTIMG_FLIP) && (player->postimgflags & POSTIMG_MIRROR)) atransform.mirrorflip = true; // Set transform. @@ -5275,7 +5024,7 @@ void HWR_SetTransform(float fpov, player_t *player) void HWR_ClearClipper(void) { - angle_t a1 = gld_FrustumAngle(gr_aimingangle); + angle_t a1 = gld_FrustumAngle(gl_aimingangle); gld_clipper_Clear(); gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM @@ -5283,114 +5032,35 @@ void HWR_ClearClipper(void) #endif } -// Adds an entry to the clipper for portal rendering -static void HWR_PortalClipping(gl_portal_t *portal) -{ - angle_t angle1, angle2; - - line_t *line = &lines[portal->clipline]; - - angle1 = R_PointToAngle64(line->v1->x, line->v1->y); - angle2 = R_PointToAngle64(line->v2->x, line->v2->y); - - // clip things that are not inside the portal window from our viewpoint - gld_clipper_SafeAddClipRange(angle2, angle1); -} - -enum -{ - HWR_STENCIL_NORMAL, - HWR_STENCIL_BEGIN, - HWR_STENCIL_REVERSE, - HWR_STENCIL_DEPTH, - HWR_STENCIL_SKY -}; - // Changes the current stencil state. -static void HWR_SetStencilState(int state, int level) +void HWR_SetStencilState(int state, int level) { if (level > -1) HWD.pfnSetSpecialState(HWD_SET_STENCIL_LEVEL, level); HWD.pfnSetSpecialState(HWD_SET_PORTAL_MODE, state); } -// Renders a portal segment. -static void HWR_RenderPortalSeg(gl_portal_t* portal, int state) -{ - gl_drawing_stencil = true; // do not draw outside of the stencil buffer, idiot. - // set our portal state and prepare to render the seg - gr_portal = state; - gr_curline = portal->seg; - gr_frontsector = portal->seg->frontsector; - gr_backsector = portal->seg->backsector; - HWR_ProcessSeg(); - gl_drawing_stencil = false; - // need to work around the r_opengl PF_Invisible bug with this call - // similarly as in the linkdraw hack in HWR_DrawSprites - HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Masked); -} - // Renders the current viewpoint, though takes portal arguments for recursive portals. -static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals); - -// Renders a single portal from the current viewpoint. -static void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level) -{ - // draw portal seg to stencil buffer with increment - HWR_SetTransform(fpov, player); - HWR_ClearClipper(); - - HWR_SetStencilState(HWR_STENCIL_BEGIN, stencil_level); - HWR_RenderPortalSeg(portal, GRPORTAL_STENCIL); - - // go to portal frame lmao - HWR_PortalFrame(portal); - // call HWR_RenderViewpoint - HWR_RenderViewpoint(portal, fpov, player, stencil_level + 1, true); - // return to current frame - if (rootportal) - HWR_PortalFrame(rootportal); - else // current frame is not a portal frame but the main view! - { - R_SetupFrame(player, false); - portalclipline = NULL; - } - - // remove portal seg from stencil buffer - HWR_SetTransform(fpov, player); - HWR_ClearClipper(); - - HWR_SetStencilState(HWR_STENCIL_REVERSE, stencil_level); - HWR_RenderPortalSeg(portal, GRPORTAL_STENCIL); - - // draw portal seg to depth buffer - HWR_ClearClipper(); - HWR_SetStencilState(HWR_STENCIL_DEPTH, stencil_level); - HWR_RenderPortalSeg(portal, GRPORTAL_DEPTH); -} - -// Renders the current viewpoint, though takes portal arguments for recursive portals. -static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals) +void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals) { gl_portallist_t portallist; - gl_portal_t *portal; - gl_portal_t *gl_portal_temp; + const boolean skybox = (skyboxmo[0] && cv_skybox.value); - const boolean useportals = cv_grportals.value && gr_maphasportals && allow_portals; + const boolean useportals = cv_glportals.value && gl_maphasportals && allow_portals; portallist.base = portallist.cap = NULL; if (useportals && stencil_level < cv_maxportals.value) // if recursion limit is not reached { + gl_portal_t *portal; + // search for portals in current frame currentportallist = &portallist; - gr_portal = GRPORTAL_SEARCH; + HWR_SetPortalState(GLPORTAL_SEARCH); HWR_ClearClipper(); - if (!rootportal) - portalclipline = NULL; - else + if (rootportal) HWR_PortalClipping(rootportal); validcount++; @@ -5403,10 +5073,10 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe { HWR_RenderPortal(portal, rootportal, fpov, player, stencil_level); } - gr_portal = GRPORTAL_INSIDE;// when portal walls are encountered in following bsp traversal, nothing should be drawn + HWR_SetPortalState(GLPORTAL_INSIDE); // when portal walls are encountered in following bsp traversal, nothing should be drawn } else - gr_portal = GRPORTAL_OFF;// there may be portals and they need to be drawn as regural walls + HWR_SetPortalState(GLPORTAL_OFF); // there may be portals and they need to be drawn as regural walls // draw normal things in current frame in current incremented stencil buffer area HWR_SetStencilState(HWR_STENCIL_NORMAL, stencil_level); @@ -5416,19 +5086,12 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe HWR_ClearSprites(); HWR_ClearClipper(); - if (useportals) + if (useportals && rootportal) { - if (!rootportal) - portalclipline = NULL; - else - { - HWR_PortalFrame(rootportal);// for portalclipsector, it could have gone null from search - HWR_PortalClipping(rootportal); - } + HWR_PortalFrame(rootportal);// for portalclipsector, it could have gone null from search + HWR_PortalClipping(rootportal); } - else - portalclipline = NULL; - + // Set transform. HWD.pfnSetTransform(&atransform); @@ -5438,31 +5101,31 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe ps_numpolyobjects.value.i = 0; PS_START_TIMING(ps_bsptime); - if (cv_grbatching.value) + if (cv_glbatching.value) HWR_StartBatching(); if (useportals && !rootportal && portallist.base && !skybox) // if portals have been drawn in the main view, then render skywalls differently - gr_collect_skywalls = true; + gl_collect_skywalls = true; // HAYA: Save the old portal state, and turn portals off while normally rendering the BSP tree. // This fixes specific effects not working, such as horizon lines. - int oldgl_portal_state = gr_portal; + SINT8 oldgl_portal_state = gl_portal_state; - if (gr_portal != GRPORTAL_OFF) // if we already haven't hit the recursion limit or we already ended our portal shenanigans - gr_portal = GRPORTAL_INSIDE; // TURN IT OFF + if (gl_portal_state != GLPORTAL_OFF) // if we already haven't hit the recursion limit or we already ended our portal shenanigans + HWR_SetPortalState(GLPORTAL_INSIDE); // TURN IT OFF // Recursively "render" the BSP tree. HWR_RenderBSPNode((INT32)numnodes-1); // woo we back - gr_portal = oldgl_portal_state; + HWR_SetPortalState(oldgl_portal_state); if (allow_portals) // looks weird, but this is only true when its not skybox rendering skipping precip in skyboxes like software does HWR_AddPrecipitationSprites(); PS_STOP_TIMING(ps_bsptime); - if (cv_grbatching.value) + if (cv_glbatching.value) HWR_RenderBatches(); if (skyWallVertexArraySize) // if there are skywalls to draw using the alternate method @@ -5477,9 +5140,9 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe HWD.pfnClearBuffer(false, false, true, 0);// clear skywall markings from the stencil buffer HWR_SetTransform(fpov, player);// restore transform } - gr_collect_skywalls = false; - - ps_numsprites.value.i = gr_visspritecount; + gl_collect_skywalls = false; + + ps_numsprites.value.i = gl_visspritecount; PS_START_TIMING(ps_hw_spritesorttime); HWR_SortVisSprites(); PS_STOP_TIMING(ps_hw_spritesorttime); @@ -5492,42 +5155,29 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe ps_hw_nodedrawtime.value.p = 0; HWR_RenderDrawNodes(); - // free memory from portal list allocated by calls to Add2Lines - gl_portal_temp = portallist.base; - while (gl_portal_temp) - { - gl_portal_t *nextportal = gl_portal_temp->next; - Z_Free(gl_portal_temp); - gl_portal_temp = nextportal; - } + HWR_FreePortalList(portallist); } // ========================================================================== // Render the current frame. // ========================================================================== -void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox) +static void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox) { const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); // set window position - gr_centerx = gr_basecenterx; - gr_viewwindowx = gr_baseviewwindowx; - gr_windowcenterx = gr_basewindowcenterx; - gr_centery = gr_basecentery; - gr_viewwindowy = gr_baseviewwindowy; - gr_windowcentery = gr_basewindowcentery; + gl_viewwindowx = gl_baseviewwindowx; + gl_viewwindowy = gl_baseviewwindowy; if ((splitscreen == 1 && viewnumber == 1) || (splitscreen > 1 && viewnumber > 1)) { - gr_viewwindowy += gr_viewheight; - gr_windowcentery += gr_viewheight; + gl_viewwindowy += gl_viewheight; } if (splitscreen > 1 && viewnumber & 1) { - gr_viewwindowx += gr_viewwidth; - gr_windowcenterx += gr_viewwidth; + gl_viewwindowx += gl_viewwidth; } if (splitscreen == 2 && player == &players[displayplayers[2]]) @@ -5556,14 +5206,14 @@ void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox) current_bsp_culling_distance = 0; - if (!skybox && cv_grrenderdistance.value) + if (!skybox && cv_glrenderdistance.value) { - HWD.pfnGClipRect((INT32)gr_viewwindowx, - (INT32)gr_viewwindowy, - (INT32)(gr_viewwindowx + gr_viewwidth), - (INT32)(gr_viewwindowy + gr_viewheight), - ZCLIP_PLANE, clipping_distances[cv_grrenderdistance.value - 1]); - current_bsp_culling_distance = bsp_culling_distances[cv_grrenderdistance.value - 1]; + HWD.pfnGClipRect((INT32)gl_viewwindowx, + (INT32)gl_viewwindowy, + (INT32)(gl_viewwindowx + gl_viewwidth), + (INT32)(gl_viewwindowy + gl_viewheight), + ZCLIP_PLANE, clipping_distances[cv_glrenderdistance.value - 1]); + current_bsp_culling_distance = bsp_culling_distances[cv_glrenderdistance.value - 1]; } portalclipline = NULL; @@ -5599,18 +5249,20 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on - FRGBAFloat ClearColor; - - ClearColor.red = 0.0f; - ClearColor.green = 0.0f; - ClearColor.blue = 0.0f; - ClearColor.alpha = 1.0f; - // Clear the color buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. if (viewnumber == 0) // Only do it if it's the first screen being rendered - HWD.pfnClearBuffer(true, false, false, &ClearColor); + { + FRGBAFloat ClearColor; - if (cv_grshaders.value) + ClearColor.red = 0.0f; + ClearColor.green = 0.0f; + ClearColor.blue = 0.0f; + ClearColor.alpha = 1.0f; + + HWD.pfnClearBuffer(true, false, false, &ClearColor); + } + + if (HWR_UseShader() && cv_ripplewater.value) HWD.pfnSetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime. if (viewnumber > 3) @@ -5653,15 +5305,15 @@ void HWR_LoadLevel(void) // enable or disable palette rendering state depending on settings and availability // called when relevant settings change // shader recompilation is done in the cvar callback -void HWR_TogglePaletteRendering(void) +static void HWR_TogglePaletteRendering(void) { // which state should we go to? if (HWR_ShouldUsePaletteRendering()) { // are we not in that state already? - if (!gr_palette_rendering_state) + if (!gl_palette_rendering_state) { - gr_palette_rendering_state = true; + gl_palette_rendering_state = true; // The textures will still be converted to RGBA by r_opengl. // This however makes hw_cache use paletted blending for composite textures! @@ -5680,9 +5332,9 @@ void HWR_TogglePaletteRendering(void) else { // are we not in that state already? - if (gr_palette_rendering_state) + if (gl_palette_rendering_state) { - gr_palette_rendering_state = false; + gl_palette_rendering_state = false; textureformat = GL_TEXFMT_RGBA; HWR_SetPalette(pLocalPalette); // If the r_opengl "texture palette" stays the same during this switch, these textures @@ -5696,46 +5348,43 @@ void HWR_TogglePaletteRendering(void) //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grfiltermode); - CV_RegisterVar(&cv_granisotropicmode); - CV_RegisterVar(&cv_grsolvetjoin); - - CV_RegisterVar(&cv_grbatching); - - CV_RegisterVar(&cv_splitwallfix); - - CV_RegisterVar(&cv_grrenderdistance); - - CV_RegisterVar(&cv_grfakecontrast); - CV_RegisterVar(&cv_grslopecontrast); - CV_RegisterVar(&cv_grhorizonlines); - - CV_RegisterVar(&cv_grfovchange); - - CV_RegisterVar(&cv_grmdls); - CV_RegisterVar(&cv_grfallbackplayermodel); - - CV_RegisterVar(&cv_grspritebillboarding); - - CV_RegisterVar(&cv_grshearing); - - CV_RegisterVar(&cv_grshaders); - - CV_RegisterVar(&cv_grportals); - - CV_RegisterVar(&cv_secbright); - - CV_RegisterVar(&cv_grpaletterendering); - CV_RegisterVar(&cv_grpalettedepth); - CV_RegisterVar(&cv_grflashpal); - - CV_RegisterVar(&cv_lightdither); + CV_RegisterVar(&cv_glscreentextures); #ifdef USE_FBO_OGL - CV_RegisterVar(&cv_grframebuffer); + CV_RegisterVar(&cv_glframebuffer); #endif - CV_RegisterVar(&cv_grscreentextures); + CV_RegisterVar(&cv_glmdls); + CV_RegisterVar(&cv_glfallbackplayermodel); + + CV_RegisterVar(&cv_glspritebillboarding); + CV_RegisterVar(&cv_glshearing); + + CV_RegisterVar(&cv_glfakecontrast); + CV_RegisterVar(&cv_glslopecontrast); + + CV_RegisterVar(&cv_glshaders); + + CV_RegisterVar(&cv_gllightdither); + CV_RegisterVar(&cv_glsecbright); + + CV_RegisterVar(&cv_glfiltermode); + CV_RegisterVar(&cv_glanisotropicmode); + + CV_RegisterVar(&cv_glsolvetjoin); + + CV_RegisterVar(&cv_glbatching); + + CV_RegisterVar(&cv_glrenderdistance); + + CV_RegisterVar(&cv_glhorizonlines); + CV_RegisterVar(&cv_glportals); + + CV_RegisterVar(&cv_glfovchange); + + CV_RegisterVar(&cv_glpaletterendering); + CV_RegisterVar(&cv_glpalettedepth); + CV_RegisterVar(&cv_glflashpal); } // -------------------------------------------------------------------------- @@ -5750,20 +5399,16 @@ void HWR_Startup(void) { CONS_Printf("HWR_Startup()...\n"); textureformat = patchformat = GL_TEXFMT_RGBA; - + HWR_InitTextureCache(); HWR_InitMD2(); - gr_shadersavailable = HWR_InitShaders(); + gl_shadersavailable = HWR_InitShaders(); HWR_SetShaderState(); HWR_LoadAllCustomShaders(); HWR_TogglePaletteRendering(); -#ifdef USE_FBO_OGL - HWD.pfnSetSpecialState(HWD_SET_FRAMEBUFFER, cv_grframebuffer.value); -#endif - if (msaa) HWD.pfnSetSpecialState(HWD_SET_MSAA, a2c ? 2 : 1); } @@ -5785,11 +5430,11 @@ void HWR_Shutdown(void) #endif } -void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) +static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { FBITFIELD blendmode = blend; UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha - + INT32 shader = SHADER_NONE; // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting @@ -5809,15 +5454,15 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, blendmode |= PF_ColorMapped; } - + if (fogwall) blendmode |= PF_Fog; - + blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false); #ifdef WALLSPLATS - if (gr_curline->linedef->splats && cv_splats.value) + if (gl_curline->linedef->splats && cv_splats.value) HWR_DrawSegsSplats(pSurf); #endif } @@ -5827,22 +5472,10 @@ INT32 HWR_GetTextureUsed(void) return HWD.pfnGetTextureUsed(); } -void HWR_DoPostProcessor(player_t *player) +static void HWR_DoPostProcessor(player_t *player) { - postimg_t *type = &postimgtype[0]; - UINT8 i; - HWD.pfnUnSetShader(); - for (i = splitscreen; i > 0; i--) - { - if (player != &players[displayplayers[i]]) - continue; - - type = &postimgtype[i]; - break; - } - // Armageddon Blast Flash! // Could this even be considered postprocessor? if (!HWR_PalRenderFlashpal() && player->flashcount) @@ -5868,7 +5501,7 @@ void HWR_DoPostProcessor(player_t *player) HWD.pfnDrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest); } - if (cv_grscreentextures.value != 2) // screen textures are needed for the rest of the effects + if (cv_glscreentextures.value != 2) // screen textures are needed for the rest of the effects return; // Capture the screen for intermission and screen waving @@ -5879,7 +5512,7 @@ void HWR_DoPostProcessor(player_t *player) return; // Drunken vision! WooOOooo~ - if (*type == postimg_water || *type == postimg_heat) + if (player->postimgflags & POSTIMG_WATER || player->postimgflags & POSTIMG_HEAT) { // 10 by 10 grid. 2 coordinates (xy) float v[SCREENVERTS][SCREENVERTS][2]; @@ -5891,7 +5524,7 @@ void HWR_DoPostProcessor(player_t *player) INT32 FREQUENCY; // Modifies the wave. - if (*type == postimg_water) + if (player->postimgflags & POSTIMG_WATER) { WAVELENGTH = 5; AMPLITUDE = 20; @@ -5943,7 +5576,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) lumpnum_t lumpnum; size_t lsize; - if (cv_grscreentextures.value == 0) + if (cv_glscreentextures.value == 0) { V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // just draw a black screen instead of flashing and crap return; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index bd6258ef4..daa837e10 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -23,6 +23,7 @@ #include "hw_glob.h" #include "hw_data.h" #include "hw_defs.h" +#include "hw_portal.h" #include "../am_map.h" #include "../d_player.h" @@ -35,15 +36,32 @@ void HWR_Startup(void); void HWR_Shutdown(void); -extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy; +extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowx, gl_baseviewwindowy; -extern float gr_basewindowcenterx, gr_basewindowcentery; +extern float gl_basewindowcenterx, gl_basewindowcentery; extern unsigned msaa; extern boolean a2c; extern FTransform atransform; -extern float gr_viewsin, gr_viewcos; +extern float gl_viewsin, gl_viewcos; + +extern boolean gl_drawing_stencil; + +extern seg_t *gl_curline; +extern side_t *gl_sidedef; +extern line_t *gl_linedef; +extern sector_t *gl_frontsector; +extern sector_t *gl_backsector; + +enum +{ + HWR_STENCIL_NORMAL, + HWR_STENCIL_BEGIN, + HWR_STENCIL_REVERSE, + HWR_STENCIL_DEPTH, + HWR_STENCIL_SKY +}; // Performance stats extern ps_metric_t ps_hw_nodesorttime; @@ -62,7 +80,7 @@ extern ps_metric_t ps_hw_numcolors; extern ps_metric_t ps_hw_batchsorttime; extern ps_metric_t ps_hw_batchdrawtime; -extern boolean gr_shadersavailable; +extern boolean gl_shadersavailable; // hw_draw.c void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); @@ -81,24 +99,25 @@ UINT8 *HWR_GetScreenshot(void); boolean HWR_Screenshot(const char *lbmname); // hw_main.c -void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox); -void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); void HWR_SetViewSize(void); void HWR_AddCommands(void); + +void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); +void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, player_t *player, int stencil_level, boolean allow_portals); + void HWR_SetTransform(float fpov, player_t *player); void HWR_ClearClipper(void); +void HWR_SetStencilState(int state, int level); boolean HWR_UseShader(void); boolean HWR_ShouldUsePaletteRendering(void); boolean HWR_PalRenderFlashpal(void); -void HWR_TogglePaletteRendering(void); // My original intention was to split hw_main.c // into files like hw_bsp.c, hw_sprites.c... // hw_main.c: Lighting and fog 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 FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); @@ -106,7 +125,6 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); INT32 HWR_GetTextureUsed(void); // hw_main.c: Post-rendering -void HWR_DoPostProcessor(player_t *player); void HWR_StartScreenWipe(void); void HWR_EndScreenWipe(void); void HWR_DrawIntermissionBG(void); @@ -115,70 +133,55 @@ void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(INT32 width, INT32 height); -// hw_main.c: Planes -void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); - -void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); - // hw_main.c: Segs void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom -void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); -void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap); -void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); -// moved HWR_SplitWall to hw_main.c -void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf); -void HWR_DrawSkyBackground(float fpov); - -// hw_main.c: Sprites -void HWR_AddSprites(sector_t *sec); -void HWR_ProjectSprite(mobj_t *thing); -//void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); -void HWR_DrawSprites(void); // hw_bsp.c void HWR_CreatePlanePolygons(INT32 bspnum); -extern boolean gr_maphasportals; +extern boolean gl_maphasportals; // hw_cache.c void HWR_LoadTextures(size_t pnumtextures); RGBA_t *HWR_GetTexturePalette(void); -void HWR_SetShaderState(void); - // Console variables -extern consvar_t cv_grshaders; +extern CV_PossibleValue_t glanisotropicmode_cons_t[]; + +extern consvar_t cv_glscreentextures; #ifdef USE_FBO_OGL -extern consvar_t cv_grframebuffer; +extern consvar_t cv_glframebuffer; #endif -extern consvar_t cv_splitwallfix; -extern consvar_t cv_grshearing; -extern consvar_t cv_grfov; -extern consvar_t cv_grmdls; -extern consvar_t cv_grfog; -extern consvar_t cv_grfogdensity; -extern consvar_t cv_grfiltermode; -extern consvar_t cv_granisotropicmode; -extern consvar_t cv_grcorrecttricks; -extern consvar_t cv_grfovchange; -extern consvar_t cv_grsolvetjoin; -extern consvar_t cv_grspritebillboarding; -extern consvar_t cv_grfakecontrast; -extern consvar_t cv_grslopecontrast; -extern consvar_t cv_grhorizonlines; -extern consvar_t cv_grfallbackplayermodel; -extern consvar_t cv_grbatching; -extern consvar_t cv_grrenderdistance; -extern consvar_t cv_grpaletterendering; -extern consvar_t cv_grpalettedepth; -extern consvar_t cv_grflashpal; -extern consvar_t cv_lightdither; -extern consvar_t cv_grscreentextures; -extern consvar_t cv_grportals; -extern consvar_t cv_nostencil; -extern consvar_t cv_secbright; -extern CV_PossibleValue_t granisotropicmode_cons_t[]; +extern consvar_t cv_glmdls; +extern consvar_t cv_glfallbackplayermodel; + +extern consvar_t cv_glspritebillboarding; +extern consvar_t cv_glshearing; + +extern consvar_t cv_glfakecontrast; +extern consvar_t cv_glslopecontrast; + +extern consvar_t cv_glshaders; + +extern consvar_t cv_gllightdither; +extern consvar_t cv_glsecbright; + +extern consvar_t cv_glfiltermode; +extern consvar_t cv_glanisotropicmode; + +extern consvar_t cv_glsolvetjoin; + +extern consvar_t cv_glbatching; + +extern consvar_t cv_glrenderdistance; + +extern consvar_t cv_glhorizonlines; +extern consvar_t cv_glportals; + +extern consvar_t cv_glfovchange; + +extern consvar_t cv_glpaletterendering; +extern consvar_t cv_glpalettedepth; +extern consvar_t cv_glflashpal; #endif diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index c71f47185..485836cf2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -147,7 +147,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext) CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); } -static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch) +static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *glpatch) { png_structp png_ptr; png_infop png_info_ptr; @@ -201,7 +201,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); fclose(png_FILE); - Z_Free(grpatch->mipmap->data); + Z_Free(glpatch->mipmap->data); return 0; } #ifdef USE_FAR_KEYWORD @@ -242,7 +242,7 @@ static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ { png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); - png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->data); + png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &glpatch->mipmap->data); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); for (i = 0; i < height; i++) row_pointers[i] = PNG_image + i*pitch; @@ -282,7 +282,7 @@ typedef struct } PcxHeader; static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, - GLPatch_t *grpatch) + GLPatch_t *glpatch) { PcxHeader header; #define PALSIZE 768 @@ -322,7 +322,7 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, pw = *w = header.xmax - header.xmin + 1; ph = *h = header.ymax - header.ymin + 1; - image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->data); + image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &glpatch->mipmap->data); if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) { @@ -364,43 +364,43 @@ static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h, // -----------------+ static void md2_loadTexture(md2_t *model) { - GLPatch_t *grpatch; + GLPatch_t *glpatch; const char *filename = model->filename; - if (model->grpatch) + if (model->glpatch) { - grpatch = model->grpatch; - Z_Free(grpatch->mipmap->data); + glpatch = model->glpatch; + Z_Free(glpatch->mipmap->data); } else { - grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, - &(model->grpatch)); - grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); + glpatch = Z_Calloc(sizeof *glpatch, PU_HWRPATCHINFO, + &(model->glpatch)); + glpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); } - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) + if (!glpatch->mipmap->downloaded && !glpatch->mipmap->data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + glpatch->mipmap->format = PNG_Load(filename, &w, &h, glpatch); + if (glpatch->mipmap->format == 0) #endif - grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + glpatch->mipmap->format = PCX_Load(filename, &w, &h, glpatch); + if (glpatch->mipmap->format == 0) { - grpatch->notfound = true;// mark it so its not searched for again repeatedly + glpatch->notfound = true;// mark it so its not searched for again repeatedly return; } - grpatch->mipmap->downloaded = 0; - grpatch->mipmap->flags = 0; + glpatch->mipmap->downloaded = 0; + glpatch->mipmap->flags = 0; - grpatch->width = (INT16)w; - grpatch->height = (INT16)h; - grpatch->mipmap->width = (UINT16)w; - grpatch->mipmap->height = (UINT16)h; + glpatch->width = (INT16)w; + glpatch->height = (INT16)h; + glpatch->mipmap->width = (UINT16)w; + glpatch->mipmap->height = (UINT16)h; // for palette rendering, color cube is applied in post-processing instead of here if (!HWR_ShouldUsePaletteRendering()) @@ -408,7 +408,7 @@ static void md2_loadTexture(md2_t *model) UINT32 size; RGBA_t *image; // Lactozilla: Apply colour cube - image = grpatch->mipmap->data; + image = glpatch->mipmap->data; size = w*h; while (size--) { @@ -417,8 +417,8 @@ static void md2_loadTexture(md2_t *model) } } } - HWD.pfnSetTexture(grpatch->mipmap); - HWR_UnlockCachedPatch(grpatch); + HWD.pfnSetTexture(glpatch->mipmap); + HWR_UnlockCachedPatch(glpatch); } // -----------------+ @@ -426,49 +426,49 @@ static void md2_loadTexture(md2_t *model) // -----------------+ static void md2_loadBlendTexture(md2_t *model) { - GLPatch_t *grpatch; + GLPatch_t *glpatch; char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL); strcpy(filename, model->filename); FIL_ForceExtension(filename, "_blend.png"); - if (model->blendgrpatch) + if (model->blendglpatch) { - grpatch = model->blendgrpatch; - Z_Free(grpatch->mipmap->data); + glpatch = model->blendglpatch; + Z_Free(glpatch->mipmap->data); } else { - grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, - &(model->blendgrpatch)); - grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); + glpatch = Z_Calloc(sizeof *glpatch, PU_HWRPATCHINFO, + &(model->blendglpatch)); + glpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL); } - if (!grpatch->mipmap->downloaded && !grpatch->mipmap->data) + if (!glpatch->mipmap->downloaded && !glpatch->mipmap->data) { int w = 0, h = 0; #ifdef HAVE_PNG - grpatch->mipmap->format = PNG_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + glpatch->mipmap->format = PNG_Load(filename, &w, &h, glpatch); + if (glpatch->mipmap->format == 0) #endif - grpatch->mipmap->format = PCX_Load(filename, &w, &h, grpatch); - if (grpatch->mipmap->format == 0) + glpatch->mipmap->format = PCX_Load(filename, &w, &h, glpatch); + if (glpatch->mipmap->format == 0) { - grpatch->notfound = true;// mark it so its not searched for again repeatedly + glpatch->notfound = true;// mark it so its not searched for again repeatedly Z_Free(filename); return; } - grpatch->mipmap->downloaded = 0; - grpatch->mipmap->flags = 0; + glpatch->mipmap->downloaded = 0; + glpatch->mipmap->flags = 0; - grpatch->width = (INT16)w; - grpatch->height = (INT16)h; - grpatch->mipmap->width = (UINT16)w; - grpatch->mipmap->height = (UINT16)h; + glpatch->width = (INT16)w; + glpatch->height = (INT16)h; + glpatch->mipmap->width = (UINT16)w; + glpatch->mipmap->height = (UINT16)h; } - HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary - HWR_UnlockCachedPatch(grpatch); + HWD.pfnSetTexture(glpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary + HWR_UnlockCachedPatch(glpatch); Z_Free(filename); } @@ -489,7 +489,7 @@ void HWR_InitMD2(void) { md2_playermodels[s].scale = -1.0f; md2_playermodels[s].model = NULL; - md2_playermodels[s].grpatch = NULL; + md2_playermodels[s].glpatch = NULL; md2_playermodels[s].skin = -1; md2_playermodels[s].notfound = true; md2_playermodels[s].error = false; @@ -498,7 +498,7 @@ void HWR_InitMD2(void) { md2_localplayermodels[s].scale = -1.0f; md2_localplayermodels[s].model = NULL; - md2_localplayermodels[s].grpatch = NULL; + md2_localplayermodels[s].glpatch = NULL; md2_localplayermodels[s].skin = -1; md2_localplayermodels[s].notfound = true; md2_localplayermodels[s].error = false; @@ -507,7 +507,7 @@ void HWR_InitMD2(void) { md2_models[i].scale = -1.0f; md2_models[i].model = NULL; - md2_models[i].grpatch = NULL; + md2_models[i].glpatch = NULL; md2_models[i].skin = -1; md2_models[i].notfound = true; md2_models[i].error = false; @@ -680,7 +680,7 @@ spritemd2found: #define SETBRIGHTNESS(brightness,r,g,b) \ brightness = (UINT8)(((1063*(UINT32)(r))/5000) + ((3576*(UINT32)(g))/5000) + ((361*(UINT32)(b))/5000)) -static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) +static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *glmip, INT32 skinnum, skincolors_t color) { UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; @@ -696,24 +696,24 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, memset(translation, 0, sizeof(translation)); memset(cutoff, 0, sizeof(cutoff)); - if (grmip->width == 0) + if (glmip->width == 0) { - grmip->width = gpatch->width; - grmip->height = gpatch->height; + glmip->width = gpatch->width; + glmip->height = gpatch->height; // no wrap around, no chroma key - grmip->flags = 0; + glmip->flags = 0; // setup the texture info - grmip->format = GL_TEXFMT_RGBA; + glmip->format = GL_TEXFMT_RGBA; } - if (grmip->data) + if (glmip->data) { - Z_Free(grmip->data); - grmip->data = NULL; + Z_Free(glmip->data); + glmip->data = NULL; } - cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->data); + cur = Z_Malloc(size*4, PU_HWRCACHE, &glmip->data); memset(cur, 0x00, size*4); image = gpatch->mipmap->data; @@ -1044,7 +1044,7 @@ skippixel: static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT32 skinnum, const UINT8 *colormap, skincolors_t color) { // mostly copied from HWR_GetMappedPatch, hence the similarities and comment - GLMipmap_t *grmip, *newmip; + GLMipmap_t *glmip, *newmip; if (colormap == colormaps || colormap == NULL) { @@ -1055,15 +1055,15 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // search for the mimmap // skip the first (no colormap translated) - for (grmip = gpatch->mipmap; grmip->nextcolormap; ) + for (glmip = gpatch->mipmap; glmip->nextcolormap; ) { - grmip = grmip->nextcolormap; - if (grmip->colormap == colormap) + glmip = glmip->nextcolormap; + if (glmip->colormap == colormap) { - if (grmip->downloaded && grmip->data) + if (glmip->downloaded && glmip->data) { - HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture - Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); + HWD.pfnSetTexture(glmip); // found the colormap, set it to the correct texture + Z_ChangeTag(glmip->data, PU_HWRCACHE_UNLOCKED); return; } } @@ -1079,7 +1079,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT newmip = calloc(1, sizeof (*newmip)); if (newmip == NULL) I_Error("%s: Out of memory", "HWR_GetMappedPatch"); - grmip->nextcolormap = newmip; + glmip->nextcolormap = newmip; newmip->colormap = colormap; HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); @@ -1095,7 +1095,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // Returns : // -----------------+ -void HWR_DrawMD2(gr_vissprite_t *spr) +void HWR_DrawMD2(gl_vissprite_t *spr) { md2_t *md2; @@ -1105,7 +1105,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) FTransform p; FSurfaceInfo Surf; - if (!cv_grmdls.value) + if (!cv_glmdls.value) return; if (spr->precip) @@ -1164,7 +1164,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) angle_t ang; interpmobjstate_t interp; - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || R_QuickCamDist(spr->mobj->x, spr->mobj->y) < cv_maxinterpdist.value)) { R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp); } @@ -1244,22 +1244,22 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } } //Hurdler: arf, I don't like that implementation at all... too much crappy - gpatch = md2->grpatch; + gpatch = md2->glpatch; if (!gpatch || ((!gpatch->mipmap->format || !gpatch->mipmap->downloaded) && !gpatch->notfound)) md2_loadTexture(md2); - gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... + gpatch = md2->glpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... if ((gpatch && gpatch->mipmap->format) // don't load the blend texture if the base texture isn't available - && (!md2->blendgrpatch - || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) - && !((GLPatch_t *)md2->blendgrpatch)->notfound))) + && (!md2->blendglpatch + || ((!((GLPatch_t *)md2->blendglpatch)->mipmap->format || !((GLPatch_t *)md2->blendglpatch)->mipmap->downloaded) + && !((GLPatch_t *)md2->blendglpatch)->notfound))) md2_loadBlendTexture(md2); if (gpatch && gpatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && - md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->format - && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) + md2->blendglpatch && ((GLPatch_t *)md2->blendglpatch)->mipmap->format + && gpatch->width == ((GLPatch_t *)md2->blendglpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendglpatch)->height) { INT32 tcskinnum = TC_DEFAULT; if ((spr->mobj->flags & MF_BOSS) && (spr->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" @@ -1284,7 +1284,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) } else tcskinnum = TC_DEFAULT; } - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color); + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendglpatch, tcskinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { @@ -1313,7 +1313,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) // Interpolate the model interpolation. (lol) tics -= FixedToFloat(rendertimefrac); - if (cv_grmdls.value == 1 && tics <= durs) + if (cv_glmdls.value == 1 && tics <= durs) { // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation if (spr->mobj->frame & FF_ANIMATE) @@ -1478,8 +1478,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr) float oy = ys * flipfactor*FIXED_TO_FLOAT(interp.spriteyoffset); // offset perpendicular to the camera angle - p.x -= ox * gr_viewsin; - p.y += ox * gr_viewcos; + p.x -= ox * gl_viewsin; + p.y += ox * gl_viewcos; p.z += oy; HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf); diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 7b58a6f97..e9eafd387 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -28,8 +28,8 @@ typedef struct float scale; float offset; model_t *model; - void *grpatch; - void *blendgrpatch; + void *glpatch; + void *blendglpatch; boolean notfound; INT32 skin; boolean error; @@ -40,7 +40,7 @@ extern md2_t md2_playermodels[MAXSKINS]; extern md2_t md2_localplayermodels[MAXLOCALSKINS]; void HWR_InitMD2(void); -void HWR_DrawMD2(gr_vissprite_t *spr); +void HWR_DrawMD2(gl_vissprite_t *spr); void HWR_AddPlayerMD2(INT32 skin, boolean local); void HWR_AddSpriteMD2(size_t spritenum); diff --git a/src/hardware/hw_portal.c b/src/hardware/hw_portal.c new file mode 100644 index 000000000..96a1b300a --- /dev/null +++ b/src/hardware/hw_portal.c @@ -0,0 +1,227 @@ +// SONIC ROBO BLAST 2 KART +//----------------------------------------------------------------------------- +// Copyright (C) 2024 by Kart Krew. +// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2000 by DooM Legacy Team. +// Copyright (C) 1996 by id Software, Inc. +// +// 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_portal.c +/// \brief OpenGL renderer portals. + +// ========================================================================== +// Visual portals (attr. Hannu Hanhi) +// ========================================================================== + +#ifdef HWRENDER + +#include "../r_portal.h" + +#include "../z_zone.h" + +#include "hw_clip.h" +#include "hw_drv.h" +#include "hw_defs.h" +#include "hw_main.h" +#include "hw_portal.h" + +SINT8 gl_portal_state = GLPORTAL_OFF; + +gl_portallist_t *currentportallist; + +// clip the area outside the portal destination window +void HWR_PortalClipping(gl_portal_t *portal) +{ + gld_clipper_SafeAddClipRange(portal->angle1, portal->angle2); +} + +static gl_portal_t* HWR_Portal_Add (seg_t *seg) +{ + gl_portal_t *portal = Z_Malloc(sizeof(gl_portal_t), PU_STATIC, NULL); + + // Linked list. + if (!currentportallist->base) + { + currentportallist->base = portal; + currentportallist->cap = portal; + } + else + { + currentportallist->cap->next = portal; + currentportallist->cap = portal; + } + portal->next = NULL; + + portal->seg = seg; + + return portal; +} + +void HWR_FreePortalList(gl_portallist_t freelist) +{ + portalcullsector = NULL; + + // free memory from portal list allocated by calls to Add2Lines + gl_portal_t *gl_portal_temp = freelist.base; + while (gl_portal_temp) + { + gl_portal_t *nextportal = gl_portal_temp->next; + Z_Free(gl_portal_temp); + gl_portal_temp = nextportal; + } +} + +void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg) +{ + gl_portal_t *portal = HWR_Portal_Add(seg); + + // Offset the portal view by the linedef centers + line_t* start = &lines[line1]; + line_t* dest = &lines[line2]; + + angle_t dangle = R_PointToAngle2(0, 0, dest->dx, dest->dy) - R_PointToAngle2(start->dx, start->dy, 0, 0); + + fixed_t disttopoint; + angle_t angtopoint; + + vertex_t dest_c, start_c; + + // looking glass center + start_c.x = start->v1->x/2 + start->v2->x/2; + start_c.y = start->v1->y/2 + start->v2->y/2; + + // other side center + dest_c.x = dest->v1->x/2 + dest->v2->x/2; + dest_c.y = dest->v1->y/2 + dest->v2->y/2; + + disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + angtopoint += dangle; + + portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; + portal->viewangle = viewangle + dangle; + + portal->angle1 = R_PointToAngle64(seg->v1->x, seg->v1->y) + dangle; + portal->angle2 = R_PointToAngle64(seg->v2->x, seg->v2->y) + dangle; + + portal->clipline = line2; +} + +void HWR_PortalFrame(gl_portal_t* portal) +{ + viewx = portal->viewx; + viewy = portal->viewy; + viewz = portal->viewz; + + viewangle = portal->viewangle; + //viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); + //viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); + + if (portal->clipline != -1) + { + portalclipline = &lines[portal->clipline]; + portalcullsector = portalclipline->frontsector; + viewsector = portalclipline->frontsector; + } + else + { + portalclipline = NULL; + portalcullsector = NULL; + viewsector = R_PointInSubsector(viewx, viewy)->sector; + } +} + +// Renders a portal segment. +static void HWR_RenderPortalSeg(gl_portal_t* portal, SINT8 state) +{ + gl_drawing_stencil = true; // do not draw outside of the stencil buffer, idiot. + // set our portal state and prepare to render the seg + HWR_SetPortalState(state); + gl_curline = portal->seg; + gl_frontsector = portal->seg->frontsector; + gl_backsector = portal->seg->backsector; + HWR_ProcessSeg(); + gl_drawing_stencil = false; + // need to work around the r_opengl PF_Invisible bug with this call + // similarly as in the linkdraw hack in HWR_DrawSprites + HWD.pfnSetBlend(PF_Translucent|PF_Occlude|PF_Masked); +} + +// Renders a single portal from the current viewpoint. +void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level) +{ + // draw portal seg to stencil buffer with increment + HWR_SetTransform(fpov, player); + HWR_ClearClipper(); + + HWR_SetStencilState(HWR_STENCIL_BEGIN, stencil_level); + HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL); + + // go to portal frame lmao + HWR_PortalFrame(portal); + // call HWR_RenderViewpoint + HWR_RenderViewpoint(portal, fpov, player, stencil_level + 1, true); + // return to current frame + if (rootportal) + HWR_PortalFrame(rootportal); + else // current frame is not a portal frame but the main view! + { + R_SetupFrame(player, false); + portalclipline = NULL; + } + + // remove portal seg from stencil buffer + HWR_SetTransform(fpov, player); + HWR_ClearClipper(); + + HWR_SetStencilState(HWR_STENCIL_REVERSE, stencil_level); + HWR_RenderPortalSeg(portal, GLPORTAL_STENCIL); + + // draw portal seg to depth buffer + HWR_ClearClipper(); + HWR_SetStencilState(HWR_STENCIL_DEPTH, stencil_level); + HWR_RenderPortalSeg(portal, GLPORTAL_DEPTH); +} + +// returns true if the point is on the correct (viewable) side of the +// portal destination line +boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y) +{ + // we are checking if the point is on the viewable side of the portal exit. + // being exactly on the portal exit line is not enough to pass the test. + // P_PointOnLineSide could behave differently from this expectation on this case, + // so first check if the point is precisely on the line, and then if not, check the side. + + vertex_t closest_point; + P_ClosestPointOnLine(x, y, portalclipline, &closest_point); + if (closest_point.x != x || closest_point.y != y) + { + if (P_PointOnLineSide(x, y, portalclipline) != 1) + return true; + } + return false; +} + +boolean HWR_PortalCheckBBox(const fixed_t *bspcoord) +{ + if (!portalclipline) + return true; + + if (HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXTOP]) || + HWR_PortalCheckPointSide(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]) || + HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXTOP]) || + HWR_PortalCheckPointSide(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM])) + { + return true; + } + + // we did not find any reason to pass the check, so return failure + return false; +} + +#endif diff --git a/src/hardware/hw_portal.h b/src/hardware/hw_portal.h new file mode 100644 index 000000000..f42d2f61c --- /dev/null +++ b/src/hardware/hw_portal.h @@ -0,0 +1,81 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 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_portal.h +/// \brief OpenGL renderer portal struct, functions, linked list extern. + +#ifndef __HW_PORTAL__ +#define __HW_PORTAL__ + +#ifdef HWRENDER + +#include "../doomstat.h" +#include "../r_data.h" +#include "../r_bsp.h" + +/** Portal structure. + */ +enum +{ + GLPORTAL_OFF, + GLPORTAL_SEARCH, + GLPORTAL_STENCIL, + GLPORTAL_DEPTH, + GLPORTAL_INSIDE, +}; + +typedef struct gl_portal_s +{ + struct gl_portal_s *next; + + // Viewport. + fixed_t viewx; + fixed_t viewy; + fixed_t viewz; + angle_t viewangle; + + seg_t *seg; // seg that is used for drawing to the stencil buffer + INT32 clipline; // Optional clipline for line-based portals + + // angles for the left and right edges of the portal + // relative to the viewpoint + angle_t angle1; + angle_t angle2; +} gl_portal_t; + +typedef struct gl_portallist_s +{ + gl_portal_t *base; + gl_portal_t *cap; +} gl_portallist_t; + +extern SINT8 gl_portal_state; + +// new thing +extern gl_portallist_t *currentportallist; + +static inline void HWR_SetPortalState (SINT8 state) +{ + gl_portal_state = state; +} + +// Adds an entry to the clipper for portal rendering +void HWR_PortalClipping(gl_portal_t *portal); + +void HWR_Portal_Add2Lines(const INT32 line1, const INT32 line2, seg_t *seg); +void HWR_PortalFrame(gl_portal_t* portal); +void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const float fpov, player_t *player, int stencil_level); +void HWR_FreePortalList(gl_portallist_t portallist); + +boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y); +boolean HWR_PortalCheckBBox(const fixed_t *bspcoord); + +#endif +#endif diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index d7924a675..3046b902e 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -25,7 +25,7 @@ static struct { const char *vertex; const char *fragment; } const gl_shadersources[] = { - + // Floor shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_FLOOR_FRAGMENT_SHADER}, @@ -52,7 +52,7 @@ static struct { // Palette postprocess shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER}, - + // UI colormap fade shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER}, @@ -279,11 +279,11 @@ static char *HWR_PreprocessShader(char *original) // Calculate length of modified shader. new_len = original_len; - - if (cv_grpaletterendering.value) + + if (cv_glpaletterendering.value) ADD_TO_LEN(PALETTE_RENDERING_DEFINE) - if (cv_lightdither.value) + if (cv_gllightdither.value) ADD_TO_LEN(LIGHT_DITHERING_DEFINE) #undef ADD_TO_LEN @@ -324,10 +324,10 @@ static char *HWR_PreprocessShader(char *original) } // Write the defines. - if (cv_grpaletterendering.value) + if (cv_glpaletterendering.value) WRITE_DEFINE(PALETTE_RENDERING_DEFINE) - if (cv_lightdither.value) + if (cv_gllightdither.value) WRITE_DEFINE(LIGHT_DITHERING_DEFINE) #undef WRITE_DEFINE @@ -410,7 +410,7 @@ int HWR_GetShaderFromTarget(int shader_target) // - custom shaders are enabled // - custom shaders are allowed by the server if (custom_shader != -1 && gl_shaders[custom_shader].compiled && - cv_grshaders.value == 1) + cv_glshaders.value == 1) return custom_shader; else return gl_shadertargets[shader_target].base_shader; @@ -565,7 +565,7 @@ void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3) int i; boolean modified_shaders[NUMSHADERTARGETS] = {0}; - if (!gr_shadersavailable) + if (!gl_shadersavailable) return; lump = HWR_FindShaderDefs(wadnum); diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h index 714b004b1..77a93eb2e 100644 --- a/src/hardware/hw_shaders.h +++ b/src/hardware/hw_shaders.h @@ -171,7 +171,7 @@ "gl_FragColor = final_color;\n" \ "}\n" \ "#endif\0" - + #define GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL \ "uniform sampler2D tex;\n" \ "uniform vec4 poly_color;\n" \ @@ -210,7 +210,7 @@ #define GLSL_WALL_FRAGMENT_SHADER \ GLSL_WALL_FUDGES \ GLSL_SOFTWARE_FRAGMENT_SHADER - + #define GLSL_SHADOW_FRAGMENT_SHADER \ GLSL_FLOOR_FUDGES \ GLSL_SOFTWARE_FRAGMENT_SHADER_NOPAL diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 4be4d4c27..4b98f332d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -24,6 +24,7 @@ #include #include #include "../../r_local.h" // For rendertimefrac, used for the leveltime shader uniform +#include "../../i_video.h" // for UseScreenFBO #include "r_opengl.h" #include "r_vbo.h" #include "../hw_shaders.h" @@ -121,9 +122,9 @@ static GLint viewport[4]; #ifdef USE_FBO_OGL GLuint FramebufferObject, FramebufferTexture, RenderbufferObject; -GLboolean FrameBufferEnabled = GL_FALSE, RenderToFramebuffer = GL_FALSE; boolean supportFBO = false; +static boolean fboinit = false; #endif // Sryder: NextTexAvail is broken for these because palette changes or changes to the texture filter or antialiasing @@ -706,7 +707,15 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f}; #ifdef USE_FBO_OGL -static boolean GLFramebuffer_IsFuncAvailible(void); +static boolean GLFramebuffer_CheckExt(void) +{ + //this stuff needs atleast OGL 3.0 + if (majorGL < 3) + return false; + + // check if all needed gl extensions are available + return (isExtAvailable("GL_ARB_framebuffer_no_attachments", gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object", gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB", gl_extensions)); +} #endif void SetupGLFunc4(void) @@ -753,7 +762,7 @@ void SetupGLFunc4(void) pglGetUniformLocation = GetGLFunc("glGetUniformLocation"); #ifdef USE_FBO_OGL - if (GLFramebuffer_IsFuncAvailible()) + if (GLFramebuffer_CheckExt()) { pglGenFramebuffers = GetGLFunc("glGenFramebuffers"); pglBindFramebuffer = GetGLFunc("glBindFramebuffer"); @@ -766,24 +775,17 @@ void SetupGLFunc4(void) pglRenderbufferStorage = GetGLFunc("glRenderbufferStorage"); pglFramebufferRenderbuffer = GetGLFunc("glFramebufferRenderbuffer"); + // check if ALL functions are availible + if (pglGenFramebuffers && pglBindFramebuffer && + pglDeleteFramebuffers && pglFramebufferTexture2D && + pglCheckFramebufferStatus && pglGenRenderbuffers && + pglBindRenderbuffer && pglDeleteRenderbuffers && + pglRenderbufferStorage && pglFramebufferRenderbuffer) supportFBO = true; } #endif } -#ifdef USE_FBO_OGL -static boolean GLFramebuffer_IsFuncAvailible(void) -{ - //this stuff needs atleast OGL 3.0 - if (majorGL < 3) - return false; - - return (isExtAvailable("GL_ARB_framebuffer_no_attachments",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_object",gl_extensions) && isExtAvailable("GL_ARB_framebuffer_sRGB",gl_extensions)); - - return false; -} -#endif - EXPORT boolean HWRAPI(InitShaders) (void) { if (!pglUseProgram) @@ -951,7 +953,6 @@ static void GLPerspective(GLfloat fovy, GLfloat aspect) pglMultMatrixf(&m[0][0]); } - // -----------------+ // SetModelView : // -----------------+ @@ -1046,7 +1047,7 @@ EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo) #ifdef USE_FBO_OGL static void GLFramebuffer_GenerateAttachments(void) { - if (!supportFBO) + if (!supportFBO || !UseScreenFBO()) return; // Bind the framebuffer @@ -1083,11 +1084,16 @@ static void GLFramebuffer_GenerateAttachments(void) // Unbind the framebuffer pglBindFramebuffer(GL_FRAMEBUFFER, 0); + + fboinit = true; } void GLFramebuffer_DeleteAttachments(void) { - if (!supportFBO) + if (!supportFBO || fboinit == false) + return; + + if (FramebufferObject == 0 && RenderbufferObject == 0 && FramebufferTexture == 0) return; // Unbind the framebuffer @@ -1102,11 +1108,12 @@ void GLFramebuffer_DeleteAttachments(void) FramebufferTexture = 0; RenderbufferObject = 0; + fboinit = false; } static void GLFramebuffer_Generate(void) { - if (!supportFBO) + if (!supportFBO || !UseScreenFBO()) return; // Generate the framebuffer @@ -1119,7 +1126,7 @@ static void GLFramebuffer_Generate(void) static void GLFramebuffer_Delete(void) { - if (!supportFBO) + if (!supportFBO || fboinit == false) return; if (FramebufferObject) @@ -1131,7 +1138,10 @@ static void GLFramebuffer_Delete(void) inline void GLFramebuffer_Unbind(void) { - if (!supportFBO) + if (!supportFBO || fboinit == false) + return; + + if (FramebufferObject == 0 && RenderbufferObject == 0) return; pglBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1140,7 +1150,7 @@ inline void GLFramebuffer_Unbind(void) inline void GLFramebuffer_Enable(void) { - if (!supportFBO) + if (!supportFBO || !UseScreenFBO()) return; if (FramebufferObject == 0) @@ -1154,7 +1164,10 @@ inline void GLFramebuffer_Enable(void) void GLFramebuffer_Disable(void) { - if (!supportFBO) + if (!supportFBO || fboinit == false) + return; + + if (FramebufferObject == 0 && RenderbufferObject == 0) return; pglBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1170,8 +1183,6 @@ void GLFramebuffer_Disable(void) // -----------------+ void Flush(void) { - //GL_DBG_Printf ("HWR_Flush()\n"); - while (TexCacheHead) { FTextureInfo *pTexInfo = TexCacheHead; @@ -1198,7 +1209,6 @@ void Flush(void) textureBufferSize = 0; } - // -----------------+ // isExtAvailable : Look if an OpenGL extension is available // Returns : true if extension available @@ -1226,7 +1236,6 @@ INT32 isExtAvailable(const char *extension, const GLubyte *start) return 0; } - // -----------------+ // Init : Initialise the OpenGL interface API // Returns : @@ -1236,7 +1245,6 @@ EXPORT boolean HWRAPI(Init) (void) return LoadGL(); } - // -----------------+ // SetupGLInfo : Retreive and store currently loaded OpenGL version // -----------------+ @@ -1398,7 +1406,6 @@ static void Clamp2D(GLenum pname) #endif } - // -----------------+ // SetBlend : Set render mode // -----------------+ @@ -2247,12 +2254,6 @@ static void gld_BuildSky(int row_count, int col_count) } } -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - static void RenderDome(INT32 skytexnum) { int i, j; @@ -2350,17 +2351,6 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) case HWD_SET_SHADERS: gl_allowshaders = Value; break; -#ifdef USE_FBO_OGL - case HWD_SET_FRAMEBUFFER: - FrameBufferEnabled = Value ? GL_TRUE : GL_FALSE; - - if (!supportFBO) - { - FrameBufferEnabled = GL_FALSE; - CV_Set(&cv_grframebuffer, "Off"); - } - break; -#endif case HWD_SET_TEXTUREFILTERMODE: switch (Value) { diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index baab44637..c461258d0 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -98,10 +98,6 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params); extern PFNglGetIntegerv pglGetIntegerv; typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name); extern PFNglGetString pglGetString; -#if 0 -typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c -static PFNglEnableClientState pglEnableClientState; -#endif #endif #ifdef USE_FBO_OGL diff --git a/src/hu_stuff.c b/src/hu_stuff.c index d8e345ba7..e68888c84 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2617,7 +2617,8 @@ static void HU_DrawRankings(void) boolean completed[MAXPLAYERS]; UINT32 whiteplayer = MAXPLAYERS; - V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances. + if (!automapactive) + V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances. if (cons_menuhighlight.value) hilicol = cons_menuhighlight.value; diff --git a/src/i_video.h b/src/i_video.h index 6a60f8036..fc71df557 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -146,6 +146,7 @@ extern boolean xwaylandcrap; void RefreshOGLSDLSurface(void); void I_DownSample(void); +boolean UseScreenFBO(void); extern boolean downsample; #endif diff --git a/src/k_director.c b/src/k_director.c index fc6e211f6..dafea6072 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -69,7 +69,7 @@ static fixed_t ScaleFromMap(fixed_t n, fixed_t scale) static boolean K_DirectorIsEnabled(void) { - return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (((stplyr && !stplyr->spectator) && (!playeringame[consoleplayer] || players[consoleplayer].spectator)) || (demo.playback && !demo.freecam && (!demo.title || !modeattacking))) && !K_DirectorIsPlayerAlone()); + return cv_director.value && !splitscreen && (gamestate == GS_LEVEL && (((!playeringame[consoleplayer] || players[consoleplayer].spectator)) || (demo.playback && !demo.freecam && (!demo.title || !modeattacking))) && !K_DirectorIsPlayerAlone()); } void K_InitDirector(void) diff --git a/src/k_kart.c b/src/k_kart.c index f71ceb049..c27ffec4c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -725,34 +725,34 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_showinput); CV_RegisterVar(&cv_showlaptimes); CV_RegisterVar(&cv_newspeedometer); - + CV_RegisterVar(&cv_battlespeedo); - + CV_RegisterVar(&cv_saltyhop); CV_RegisterVar(&cv_saltyhopsfx); CV_RegisterVar(&cv_saltysquish); - + //Colourized HUD CV_RegisterVar(&cv_colorizedhud); CV_RegisterVar(&cv_colorizedhudcolor); CV_RegisterVar(&cv_colorizeditembox); - + CV_RegisterVar(&cv_darkitembox); - + CV_RegisterVar(&cv_biglaps); - + CV_RegisterVar(&cv_highresportrait); - + CV_RegisterVar(&cv_slamsound); - + CV_RegisterVar(&cv_minihead); CV_RegisterVar(&cv_showminimapnames); CV_RegisterVar(&cv_showlapemblem); - - CV_RegisterVar(&cv_stagetitle); - + + CV_RegisterVar(&cv_stagetitle); + CV_RegisterVar(&cv_lessflicker); - + CV_RegisterVar(&cv_mouseturn); } @@ -2779,16 +2779,9 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 TVector v; TVector *res; fixed_t finalx, finaly, finalz, dist; - //mobj_t hoopcenter; angle_t degrees, fa, closestangle; fixed_t mobjx, mobjy, mobjz; - //hoopcenter.x = x; - //hoopcenter.y = y; - //hoopcenter.z = z; - - //hoopcenter.z = z - mobjinfo[type].height/2; - degrees = FINEANGLES/number; closestangle = 0; @@ -3174,17 +3167,19 @@ static void K_SpawnAIZDust(player_t *player) static void K_StretchPlayerGravity(player_t *p) { - fixed_t mos = FRACUNIT; - fixed_t rzs = abs(p->mo->momz); - fixed_t zspd = abs(rzs/mos); + I_Assert(p != NULL); + I_Assert(p->mo != NULL); + I_Assert(!P_MobjWasRemoved(p->mo)); + + fixed_t mos = FRACUNIT; + fixed_t rzs = abs(p->mo->momz); + fixed_t zspd = abs(rzs/mos); fixed_t stretchScaleFactor = 0; fixed_t rzsDiv = 1; fixed_t slamDiv = 1; - fixed_t dxs = p->mo->realxscale; - fixed_t dys = p->mo->realyscale; - //boolean gravSlamming = false; - //fixed_t impactFactor = 0; + fixed_t dxs = p->mo->realxscale; + fixed_t dys = p->mo->realyscale; stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value); if (stretchScaleFactor > 17476977) @@ -3194,10 +3189,6 @@ static void K_StretchPlayerGravity(player_t *p) //CONS_Printf(M_GetText("div: %d, scale factor: %d, stretch value: %d\n"), rzsDiv, stretchScaleFactor, cv_gravstretch.value); - I_Assert(p != NULL); - I_Assert(p->mo != NULL); - I_Assert(!P_MobjWasRemoved(p->mo)); - if (p->mo->slamsoundtimer) p->mo->slamsoundtimer--; @@ -3207,43 +3198,43 @@ static void K_StretchPlayerGravity(player_t *p) p->mo->slamsoundtimer = TICRATE; } - if (!P_IsObjectOnGround(p->mo)) - { - if (zspd != 0) - { - if (((dxs-(rzsDiv))) > (dxs/5)) - { - p->mo->spritexscale = ((dxs-(rzsDiv))); - p->mo->stretchslam = rzs; - } - else - p->mo->spritexscale = (dxs/5); + if (!P_IsObjectOnGround(p->mo)) + { + if (zspd != 0) + { + if (((dxs-(rzsDiv))) > (dxs/5)) + { + p->mo->spritexscale = ((dxs-(rzsDiv))); + p->mo->stretchslam = rzs; + } + else + p->mo->spritexscale = (dxs/5); - p->mo->spriteyscale = (dys+((rzsDiv*2)/3)); - } - else - { - p->mo->spritexscale = (dxs); - p->mo->spriteyscale = (dys); - } - } - else - { + p->mo->spriteyscale = (dys+((rzsDiv*2)/3)); + } + else + { + p->mo->spritexscale = (dxs); + p->mo->spriteyscale = (dys); + } + } + else + { if (stretchScaleFactor > 17476977) slamDiv = 0; else slamDiv = FixedDiv(p->mo->stretchslam, stretchScaleFactor); - - p->mo->spritexscale = (dxs+(((slamDiv*2)/3)*2)); - p->mo->spriteyscale = (dys-(slamDiv)); - if (p->mo->stretchslam > 0) - p->mo->stretchslam -= (4*mos); - else - p->mo->stretchslam = 0; - } + + p->mo->spritexscale = (dxs+(((slamDiv*2)/3)*2)); + p->mo->spriteyscale = (dys-(slamDiv)); + if (p->mo->stretchslam > 0) + p->mo->stretchslam -= (4*mos); + else + p->mo->stretchslam = 0; + } } -static void K_QuiteSaltyHop(player_t *p) +static void K_QuiteSaltyHop(player_t *p) { // what the fuck is this haya fixed_t mos = FRACUNIT; // doesnt work correctly if it isnt :/ @@ -3265,7 +3256,7 @@ static void K_QuiteSaltyHop(player_t *p) p->mo->salty_zoffset = 0; p->mo->salty_momz = 0; p->mo->init_salty = true; - } + } else if ((p->mo->salty_jump)) { if (p->mo->eflags & MFE_JUSTHITFLOOR) { p->mo->salty_zoffset = 0; @@ -3299,7 +3290,7 @@ static void K_QuiteSaltyHop(player_t *p) p->mo->salty_jump = true; p->mo->salty_zoffset = 0; p->mo->salty_momz = 6*mos; - if (cv_saltyhopsfx.value) + if (cv_saltyhopsfx.value) S_StartSound(p->mo, sfx_s25a); } } @@ -3308,56 +3299,55 @@ static void K_QuiteSaltyHop(player_t *p) void K_RollMobjBySlopes(mobj_t* mo, boolean usedistance) { - I_Assert(mo->subsector != NULL); - I_Assert(mo->subsector->sector != NULL); + I_Assert(mo->subsector != NULL); + I_Assert(mo->subsector->sector != NULL); - angle_t an; - boolean flip = mo->eflags & MFE_VERTICALFLIP; - fixed_t m_dist = R_PointToDist(mo->x, mo->y); - fixed_t rolldist = cv_sloperolldist.value * mapobjectscale; + angle_t an; + const boolean flip = mo->eflags & MFE_VERTICALFLIP; + const fixed_t m_dist = usedistance ? R_PointToDist(mo->x, mo->y) : 0; + const fixed_t rolldist = cv_sloperolldist.value * mapobjectscale; - // lifted from hw_md2 - if (mo->standingslope) - { - fixed_t tempz = mo->standingslope->normal.z; - fixed_t tempy = mo->standingslope->normal.y; - fixed_t tempx = mo->standingslope->normal.x; - fixed_t tempangle = -(R_PointToAngle2( - 0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); + // lifted from hw_md2 + if (mo->standingslope) + { + fixed_t tempz = mo->standingslope->normal.z; + fixed_t tempy = mo->standingslope->normal.y; + fixed_t tempx = mo->standingslope->normal.x; + fixed_t tempangle = -(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); - // admittedly this is a very hacky way to do the pitch and roll easing + // admittedly this is a very hacky way to do the pitch and roll easing - // pitch - if ((!usedistance) || (m_dist <= (rolldist))) - { - an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV; + // pitch + if ((!usedistance) || (m_dist <= (rolldist))) + { + an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV; - mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle; - } - else - mo->pitch_sprite = FixedAngle(0); + mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle; + } + else + mo->pitch_sprite = FixedAngle(0); - mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite; + mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite; - // roll - tempangle = (R_PointToAngle2(0, 0, tempz, tempy)); + // roll + tempangle = (R_PointToAngle2(0, 0, tempz, tempy)); - if ((!usedistance) || (m_dist <= (rolldist))) - { - an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV; + if (!usedistance || (m_dist <= (rolldist))) + { + an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV; - mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle; - } - else - mo->roll_sprite = FixedAngle(0); + mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle; + } + else + mo->roll_sprite = FixedAngle(0); - mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite; - } - else if (P_IsObjectOnGround(mo)) - { - mo->sloperoll = FixedAngle(0); - mo->slopepitch = FixedAngle(0); - } + mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite; + } + else if (P_IsObjectOnGround(mo)) + { + mo->sloperoll = FixedAngle(0); + mo->slopepitch = FixedAngle(0); + } } void K_SpawnBoostTrail(player_t *player) @@ -4460,7 +4450,6 @@ void K_RepairOrbitChain(mobj_t *orbit) if (orbit->target && orbit->target->player) { player_t *player = orbit->target->player; - INT32 num = 0; mobj_t *cur = orbit->target->hnext; @@ -6504,14 +6493,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) player->mo->spriteyscale = player->mo->realyscale; } - boolean usedist = false; - - if (cv_sloperolldist.value > 0) - usedist = true; - if ((cv_spriteroll.value) && (cv_sloperoll.value)) + if (cv_spriteroll.value && cv_sloperoll.value) { if ((!player->mo->salty_jump)) // seeing a character rotate mid-hop looks really janky - K_RollMobjBySlopes(player->mo, usedist); + K_RollMobjBySlopes(player->mo, (cv_sloperolldist.value && !splitscreen)); } else { @@ -7111,7 +7096,7 @@ void K_LoadKartHUDGraphics(void) kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX); kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX); kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX); - + if (xtra_speedo) // snowy speedometer { skp_smallsticker = W_CachePatchName("SP_SMSTC", PU_HUDGFX); @@ -7126,8 +7111,8 @@ void K_LoadKartHUDGraphics(void) { skp_smallsticker3 = W_CachePatchName("SP_SM3TC", PU_HUDGFX); } - - if (achi_speedo) + + if (achi_speedo) { skp_smallstickerachi = W_CachePatchName("SP_AMSTC", PU_HUDGFX); skp_speedpatchesachi[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd @@ -7137,7 +7122,7 @@ void K_LoadKartHUDGraphics(void) skp_speedpatchesachi[4] = W_CachePatchName("SP_APERC", PU_HUDGFX); } - if (big_lap){ + if (big_lap){ kp_lapstickerbig = W_CachePatchName("K_STLAPB", PU_HUDGFX); kp_lapstickerbig2 = W_CachePatchName("K_STLA2B", PU_HUDGFX); } @@ -7159,8 +7144,8 @@ void K_LoadKartHUDGraphics(void) kp_itembgclr[3] = W_CachePatchName("K_ISBCD", PU_HUDGFX); kp_itemmulstickerclr[1] = W_CachePatchName("K_ISMULC", PU_HUDGFX); kp_itemmulstickerclr[0] = W_CachePatchName("K_ITMULC", PU_HUDGFX); - - if (big_lap_color){ + + if (big_lap_color){ kp_lapstickerbigclr = W_CachePatchName("K_SCLAPB", PU_HUDGFX); kp_lapstickerbig2clr = W_CachePatchName("K_SCLA2B", PU_HUDGFX); } @@ -7170,8 +7155,8 @@ void K_LoadKartHUDGraphics(void) if (xtra_speedo3 && xtra_speedo_clr3) // 80x11 patch scaled to size skp_smallstickerclr3 = W_CachePatchName("SC_SM3TC", PU_HUDGFX); - - if (achi_speedo && achi_speedo_clr) + + if (achi_speedo && achi_speedo_clr) { skp_smallstickerachiclr = W_CachePatchName("SC_AMSTC", PU_HUDGFX); skp_speedpatchesachiclr[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd @@ -7202,13 +7187,13 @@ void K_LoadKartHUDGraphics(void) // Nametags if (nametaggfx) { - + nametagpic = W_CachePatchName("NTLINE", PU_HUDGFX); nametagline = W_CachePatchName("NTLINEV", PU_HUDGFX); nametagspeed = W_CachePatchName("NTSP", PU_HUDGFX); nametagweight = W_CachePatchName("NTWH", PU_HUDGFX); } - + if (driftgaugegfx){ driftgauge = W_CachePatchName("K_DGAU", PU_HUDGFX); driftgaugecolor = W_CachePatchName("K_DCAU", PU_HUDGFX); @@ -7775,7 +7760,7 @@ static void K_drawKartStats(void) flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT; UINT8 splitnum = 0; - + for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum) { if (stplyr == &players[displayplayers[splitnum]]) @@ -7784,7 +7769,7 @@ static void K_drawKartStats(void) if (!LUA_HudEnabled(hud_statdisplay)) return; - + //Internal offset for speedometer if (cv_kartspeedometer.value) { @@ -8348,7 +8333,7 @@ static void K_DrawKartPositionNum(INT32 num) scale *= 2; overtake = true; // this is used for splitscreen stuff in conjunction with flipdraw. } - + if (splitscreen || (cv_showinput.value && !splitscreen)) scale /= 2; @@ -8640,7 +8625,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I p = &players[tab[i].num]; if (cv_highresportrait.value) V_DrawSmallMappedPatch(x, y-4, 0, R_GetSkinFaceWant(p), colormap); - else + else V_DrawMappedPatch(x, y-4, 0, R_GetSkinFaceRank(p), colormap); } /*if (G_BattleGametype() && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this @@ -8782,7 +8767,7 @@ static void K_drawKartSpeedometer(void) //KartZ speedo fixed_t fuspeed = 0; INT32 spdpatch = 0; - + INT32 speedtype = 0; INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT); @@ -8810,7 +8795,7 @@ static void K_drawKartSpeedometer(void) } // man. - if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3)) + if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3)) { switch (speedtype) { case 1: @@ -8859,8 +8844,8 @@ static void K_drawKartSpeedometer(void) V_DrawScaledPatch(SPDM_X + 1, SPDM_Y + 4, (V_HUDTRANS|splitflags), (skp_smallstickerachi)); V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL); V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatchesachi[cv_kartspeedometer.value]); - } - } + } + } else if (cv_newspeedometer.value == 5 && xtra_speedo3) // why bother if we dont? { if (K_UseColorHud() && xtra_speedo_clr3) //Colourized hud @@ -8874,19 +8859,19 @@ static void K_drawKartSpeedometer(void) V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL); V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatches[cv_kartspeedometer.value]); } - + // Kart Z speedo bullshit... // Draw the Speed counter. else if (cv_newspeedometer.value == 4 && kartzspeedo) { fuspeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT; - + #define NUM_INTERVALS 22 const int speedIntervals[NUM_INTERVALS] = {2, 5, 7, 10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50, 52, 55}; - for (int i = 0; i < NUM_INTERVALS; ++i) + for (int i = 0; i < NUM_INTERVALS; ++i) { - if (fuspeed < speedIntervals[i]) + if (fuspeed < speedIntervals[i]) { spdpatch = i; break; @@ -9030,7 +9015,7 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe #ifdef HWRENDER // NOW we can get the angle differnce - if (rendermode == render_opengl && cv_grshearing.value == 0) + if (rendermode == render_opengl && cv_glshearing.value == 0) { angle_t yang = R_PointToAngle2(0, 0, dist, y); // not perspective x = FixedMul(x, FINECOSINE((yang>>ANGLETOFINESHIFT) & FINEMASK)); // perspective @@ -9076,9 +9061,9 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe // project the angle to get our final X coordinate x = FixedMul(FINETANGENT(((x+ANGLE_90)>>ANGLETOFINESHIFT) & 4095), fov); if (splitscreen == 1) // divide by 320/200 (1.6) on 2P splitscreen - x = (x/2) + (x/8); + x = (x/2) + (x/8); x = x + xres; - + // now clip in screen-space if (!dontclip && (x < 0 || x > xres*2 || y < 0 || y > yres*2)) return false; @@ -9141,7 +9126,7 @@ static void K_drawNameTags(void) fixed_t maxdistance = (10*cv_nametagdist.value)* mapobjectscale; flipped = 0; fixed_t z; - + if (i > PLAYERSMASK) continue; if (!players[i].mo || P_MobjWasRemoved(players[i].mo) || players[i].spectator || !playeringame[i]) @@ -9180,7 +9165,7 @@ static void K_drawNameTags(void) trans = V_40TRANS; else if (distance > (maxdistance*3/5)) trans = V_20TRANS; - else + else trans = 0; break; case 3: @@ -9380,7 +9365,7 @@ skipcrap: if (!K_GetScreenCoords(&pos, stplyr, stplyr->mo, FixedMul(cv_driftgaugeofs.value, cv_driftgaugeofs.value > 0 ? stplyr->mo->scale : mapobjectscale), false)) return; - basex = pos.x>>FRACBITS; + basex = pos.x>>FRACBITS; basey = pos.y>>FRACBITS; fixed_t barx; @@ -9631,7 +9616,8 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags) boolean skinlocal = mo->skinlocal; fixed_t amnumxpos, amnumypos; - INT32 amxpos, amypos; + INT32 amxpos, amypos, wntdamxpos, wntdamypos; + fixed_t scale = FRACUNIT; if (mo->skin) skin = ((skin_t*)(mo->localskin ? mo->localskin : mo->skin))-(skinlocal ? localskins : skins); @@ -9642,11 +9628,28 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags) if (encoremode) amnumxpos = -amnumxpos; - amxpos = amnumxpos + ((x + (SHORT(minimapinfo.minimap_pic->width)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->width))/2)<height)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->height))/2)<width)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->width)) / 2)<height)-SHORT((skinlocal ? localfacemmapprefix : facemmapprefix)[skin]->height)) / 2)<player && !(modeattacking || gamestate == GS_TIMEATTACK)) + { + const char *player_name = va("%c%s", (mo->color) ? V_GetSkincolorChar(mo->color) : 0, player_names[mo->player - players]); + V_DrawCenteredSmallStringAtFixed(amxpos + (4*FRACUNIT), amypos - (3*FRACUNIT), V_ALLOWLOWERCASE|flags, player_name); + } + + // thx wanted reticle for having weird offsets very cool + wntdamxpos = cv_minihead.value ? amxpos + (1<width) / 4)<height) / 4)<color) // 'default' color - V_DrawSciencePatch(amxpos, amypos, flags, ( (skinlocal) ? localfacemmapprefix : facemmapprefix )[skin], FRACUNIT); + V_DrawSciencePatch(amxpos, amypos, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], scale); else { UINT8 *colormap; @@ -9654,25 +9657,14 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags) colormap = R_GetTranslationColormap(TC_RAINBOW, mo->color, GTC_CACHE); else colormap = R_GetLocalTranslationColormap(mo->skin, mo->localskin, mo->color, GTC_CACHE, skinlocal); - - if (cv_minihead.value) - V_DrawFixedPatch(amxpos + (2*FRACUNIT), amypos + (2*FRACUNIT), FRACUNIT/2, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap); - else - V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap); - - if (cv_showminimapnames.value && !(modeattacking || gamestate == GS_TIMEATTACK)) - { - const char *player_name = va("%c%s", V_GetSkincolorChar(mo->color), player_names[mo->player - players]); - V_DrawCenteredSmallStringAtFixed(amxpos + (4*FRACUNIT), amypos - (3*FRACUNIT), V_ALLOWLOWERCASE|flags, player_name); - } + + V_DrawFixedPatch(amxpos, amypos, scale, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap); + if (mo->player && ((G_RaceGametype() && mo->player->kartstuff[k_position] == spbplace) || (G_BattleGametype() && K_IsPlayerWanted(mo->player)))) { - if (cv_minihead.value) - V_DrawFixedPatch(amxpos, amypos, FRACUNIT/2, flags, kp_wantedreticle, NULL); - else - V_DrawFixedPatch(amxpos - (4<width/2); - my = MM_Y - (AutomapPic->height/2); + // Handle offsets and stuff. + mm_x = MM_X - (SHORT(AutomapPic->width)/2); + mm_y = MM_Y - (SHORT(AutomapPic->height)/2); // let offsets transfer to the heads, too! if (encoremode) - mx += SHORT(AutomapPic->leftoffset); + { + mm_x += SHORT(AutomapPic->leftoffset); + } else - mx -= SHORT(AutomapPic->leftoffset); - my -= SHORT(AutomapPic->topoffset); + { + mm_x -= SHORT(AutomapPic->leftoffset); + } - // now that we have replicated this behavior, we can draw an icon from our supplied x, y coordinates by replicating k_kart.c's totally understandable uncommented code!!! - - // get map boundaries using nodes - maxx = maxy = INT32_MAX; - minx = miny = INT32_MIN; - minx = bsp->bbox[0][BOXLEFT]; - maxx = bsp->bbox[0][BOXRIGHT]; - miny = bsp->bbox[0][BOXBOTTOM]; - maxy = bsp->bbox[0][BOXTOP]; - - if (bsp->bbox[1][BOXLEFT] < minx) - minx = bsp->bbox[1][BOXLEFT]; - if (bsp->bbox[1][BOXRIGHT] > maxx) - maxx = bsp->bbox[1][BOXRIGHT]; - if (bsp->bbox[1][BOXBOTTOM] < miny) - miny = bsp->bbox[1][BOXBOTTOM]; - if (bsp->bbox[1][BOXTOP] > maxy) - maxy = bsp->bbox[1][BOXTOP]; - - // You might be wondering why these are being bitshift here - // it's because mapwidth and height would otherwise overflow for maps larger than half the size possible... - // map boundaries and sizes will ALWAYS be whole numbers thankfully - // later calculations take into consideration that these are actually not in terms of FRACUNIT though - minx >>= FRACBITS; - maxx >>= FRACBITS; - miny >>= FRACBITS; - maxy >>= FRACBITS; - - // these are our final map boundaries: - mapwidth = maxx - minx; - mapheight = maxy - miny; - - // These should always be small enough to be bitshift back right now - xoffset = (minx + mapwidth/2)<width, mapwidth); - yscale = FixedDiv(AutomapPic->height, mapheight); - zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20); - - amnumxpos = (FixedMul(x, zoom) - FixedMul(xoffset, zoom)); - amnumypos = -(FixedMul(y, zoom) - FixedMul(yoffset, zoom)); - - if (encoremode) - amnumxpos = -amnumxpos; + mm_y -= SHORT(AutomapPic->topoffset); // scale patch coords - patchw = patch->width*scale /2; - patchh = patch->height*scale /2; + patchw = (SHORT(patch->width) * scale / 2); + patchh = (SHORT(patch->height) * scale / 2); if (centered) + { patchw = patchh = 0; // patch is supposedly already centered, don't butt in. + } - amxpos = amnumxpos + ((mx + AutomapPic->width/2)<height/2)<width) / 2)<height) / 2)<snext; } diff --git a/src/lzf.c b/src/lzf.c index d5a837888..f81c3ee0a 100644 --- a/src/lzf.c +++ b/src/lzf.c @@ -37,8 +37,9 @@ /* * Sacrifice very little compression quality in favour of compression speed. * This gives almost the same compression as the default code, and is - * (very roughly) 15% faster. This is the preferred mode of operation. + * (very roughly) 15% faster. This is the preferable mode of operation. */ + #ifndef VERY_FAST # define VERY_FAST 1 #endif @@ -47,7 +48,7 @@ * Sacrifice some more compression quality in favour of compression speed. * (roughly 1-2% worse compression for large blocks and * 9-10% for small, redundant, blocks and >>20% better speed in both cases) - * In short: when in need for speed, enable this for binary data, + * In INT16: when in need for speed, enable this for binary data, * possibly disable this for text data. */ #ifndef ULTRA_FAST @@ -65,10 +66,21 @@ #endif #endif +/* + * Use string functions to copy memory. + * this is usually a loss, even with glibc's optimized memcpy + */ +#ifndef USE_MEMCPY +#ifdef _MSC_VER +# define USE_MEMCPY 0 +#else +# define USE_MEMCPY 1 +#endif +#endif + /* * You may choose to pre-set the hash table (might be faster on some - * modern cpus and large (>>64k) blocks, and also makes compression - * deterministic/repeatable when the configuration otherwise is the same). + * modern cpus and large (>>64k) blocks) */ #ifndef INIT_HTAB # define INIT_HTAB 1 @@ -76,15 +88,15 @@ /* * Avoid assigning values to errno variable? for some embedding purposes - * (linux kernel for example), this is necessary. NOTE: this breaks - * the documentation in lzf.h. Avoiding errno has no speed impact. + * (linux kernel for example), this is neccessary. NOTE: this breaks + * the documentation in lzf.h. */ #ifndef AVOID_ERRNO # define AVOID_ERRNO 0 #endif /* - * Whether to pass the LZF_STATE variable as argument, or allocate it + * Wether to pass the LZF_STATE variable as argument, or allocate it * on the stack. For small-stack environments, define this to 1. * NOTE: this breaks the prototype in lzf.h. */ @@ -93,108 +105,50 @@ #endif /* - * Whether to add extra checks for input validity in lzf_decompress + * Wether to add extra checks for input validity in lzf_decompress * and return EINVAL if the input stream has been corrupted. This * only shields against overflowing the input buffer and will not * detect most corrupted streams. - * This check is not normally noticeable on modern hardware + * This check is not normally noticable on modern hardware * (<1% slowdown), but might slow down older cpus considerably. */ #ifndef CHECK_INPUT # define CHECK_INPUT 1 #endif -/* - * Whether the target CPU has a slow multiplication. This affects - * the default hash function for the compressor, and enables a slightly - * worse hash function that needs only shifts. - */ -#ifndef MULTIPLICATION_IS_SLOW -# define MULTIPLICATION_IS_SLOW 0 -#endif - -/* - * If defined, then this data type will be used for storing offsets. - * This can be useful if you want to use a huge hashtable, want to - * conserve memory, or both, and your data fits into e.g. 64kb. - * If instead you want to compress data > 4GB, then it's better to - * to "#define LZF_USE_OFFSETS 0" instead. - */ -/*#define LZF_HSLOT unsigned short*/ - -/* - * Whether to store pointers or offsets inside the hash table. On - * 64 bit architetcures, pointers take up twice as much space, - * and might also be slower. Default is to autodetect. - */ -/*#define LZF_USE_OFFSETS autodetect */ - -/* - * Whether to optimise code for size, at the expense of speed. Use - * this when you are extremely tight on memory, perhaps in combination - * with AVOID_ERRNO 1 and CHECK_INPUT 0. - */ -#ifndef OPTIMISE_SIZE -# ifdef __OPTIMIZE_SIZE__ -# define OPTIMISE_SIZE 1 -# else -# define OPTIMISE_SIZE 0 -# endif -#endif - /*****************************************************************************/ /* nothing should be changed below */ -# include -# include - -#if ULTRA_FAST -# undef VERY_FAST -#endif - -#ifndef LZF_USE_OFFSETS -# ifdef _WIN32 -# define LZF_USE_OFFSETS defined(_M_X64) -# else -# include -# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU) -# endif -#endif - typedef unsigned char u8; -#ifdef LZF_HSLOT -# define LZF_HSLOT_BIAS ((const u8 *)in_data) -#else -# ifdef LZF_USE_OFFSETS -# define LZF_HSLOT_BIAS ((const u8 *)in_data) - typedef unsigned int LZF_HSLOT; +typedef const u8 *LZF_STATE[1 << (HLOG)]; + +#if !STRICT_ALIGN +/* for unaligned accesses we need a 16 bit datatype. */ +# include +# if USHRT_MAX == 65535 + typedef unsigned short u16; +# elif UINT_MAX == 65535 + typedef unsigned int u16; # else -# define LZF_HSLOT_BIAS 0 - typedef const u8 *LZF_HSLOT; +# undef STRICT_ALIGN +# define STRICT_ALIGN 1 # endif #endif -#if USHRT_MAX == 65535 - typedef unsigned short u16; -#elif UINT_MAX == 65535 - typedef unsigned int u16; -#else -# undef STRICT_ALIGN -# define STRICT_ALIGN 1 +#if ULTRA_FAST +# if defined(VERY_FAST) +# undef VERY_FAST +# endif #endif -#define LZF_MAX_LIT (1 << 5) -#define LZF_MAX_OFF (1 << 13) -#define LZF_MAX_REF ((1 << 8) + (1 << 3)) - -typedef LZF_HSLOT LZF_STATE[1 << (HLOG)]; - -typedef struct -{ - const u8 *first [1 << (6+8)]; /* most recent occurance of a match */ - u16 prev [LZF_MAX_OFF]; /* how many bytes to go backwards for the next match */ -} LZF_STATE_BEST[1]; +#if USE_MEMCPY || INIT_HTAB +# ifdef __cplusplus +# include +# else +# include +# endif +#endif #endif @@ -210,31 +164,14 @@ typedef struct # define SET_ERRNO(n) errno = (n) #endif -#ifndef USE_REP_MOVSB -#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3 -#define USE_REP_MOVSB 1 -#else -#define USE_REP_MOVSB 0 // Default to 0 if not defined elsewhere -#endif -#endif - -#if USE_REP_MOVSB /* small win on amd, big loss on intel */ -#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3 -# define lzf_movsb(dst, src, len) \ - asm ("rep movsb" \ - : "=D" (dst), "=S" (src), "=c" (len) \ - : "0" (dst), "1" (src), "2" (len)); -#endif -#endif - size_t lzf_decompress (const void *const in_data, size_t in_len, - void *out_data, size_t out_len) + void *out_data, size_t out_len) { u8 const *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; + u8 *op = (u8 *)out_data; u8 const *const in_end = ip + in_len; - u8 *const out_end = op + out_len; + u8 *const out_end = op + out_len; do { @@ -258,23 +195,14 @@ lzf_decompress (const void *const in_data, size_t in_len, } #endif -#ifdef lzf_movsb - lzf_movsb (op, ip, ctrl); -#elif OPTIMISE_SIZE - while (ctrl--) - *op++ = *ip++; +#if USE_MEMCPY + M_Memcpy (op, ip, ctrl); + op += ctrl; + ip += ctrl; #else - switch (ctrl) - { - case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++; - case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++; - case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++; - case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++; - case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++; - case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++; - case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++; - case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++; - } + do + *op++ = *ip++; + while (--ctrl); #endif } else /* back reference */ @@ -316,49 +244,12 @@ lzf_decompress (const void *const in_data, size_t in_len, return 0; } -#ifdef lzf_movsb - len += 2; - lzf_movsb (op, ref, len); -#elif OPTIMISE_SIZE - len += 2; + *op++ = *ref++; + *op++ = *ref++; do *op++ = *ref++; while (--len); -#else - switch (len) - { - default: - len += 2; - - if (op >= ref + len) - { - /* disjunct areas */ - memcpy (op, ref, len); - op += len; - } - else - { - /* overlapping, use octet by octet copying */ - do - *op++ = *ref++; - while (--len); - } - break; - - case 9: *op++ = *ref++; - case 8: *op++ = *ref++; - case 7: *op++ = *ref++; - case 6: *op++ = *ref++; - case 5: *op++ = *ref++; - case 4: *op++ = *ref++; - case 3: *op++ = *ref++; - case 2: *op++ = *ref++; - case 1: *op++ = *ref++; - case 0: *op++ = *ref++; /* two octets more */ - *op++ = *ref++; - } -#endif } } while (ip < in_end); @@ -375,29 +266,23 @@ lzf_decompress (const void *const in_data, size_t in_len, /* * don't play with this unless you benchmark! - * the data format is not dependent on the hash function. - * the hash function might seem strange, just believe me, + * decompression is not dependent on the hash function + * the hashing function might seem strange, just believe me * it works ;) */ #ifndef FRST # define FRST(p) (((p[0]) << 8) | p[1]) # define NEXT(v,p) (((v) << 8) | p[2]) -# if MULTIPLICATION_IS_SLOW -# if ULTRA_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) -# elif VERY_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# else -# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# endif -# else -/* this one was developed with sesse, - * and is very similar to the one in snappy. - * it does need a modern enough cpu with a fast multiplication. - */ -# define IDX(h) (((h * 0x1e35a7bdU) >> (32 - HLOG - 8)) & (HSIZE - 1)) -# endif +# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) #endif +/* + * IDX works because it is very similar to a multiplicative hash, e.g. + * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1)) + * the latter is also quite fast on newer CPUs, and sligthly better + * + * the next one is also quite good, albeit slow ;) + * (int)(cos(h & 0xffffff) * 1e6) + */ #if 0 /* original lzv-like hash function, much worse and thus slower */ @@ -406,214 +291,177 @@ lzf_decompress (const void *const in_data, size_t in_len, # define IDX(h) ((h) & (HSIZE - 1)) #endif -#if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -# define inline inline -#else -# define expect(expr,value) (expr) -# define inline static -#endif - -#define expect_false(expr) expect ((expr) != 0, 0) -#define expect_true(expr) expect ((expr) != 0, 1) +#define MAX_LIT (1 << 5) +#define MAX_OFF (1 << 13) +#define MAX_REF ((1 << 8) + (1 << 3)) /* * compressed format * - * 000LLLLL ; literal, L+1=1..33 octets - * LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset - * 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset + * 000LLLLL ; literal + * LLLooooo oooooooo ; backref L + * 111ooooo LLLLLLLL oooooooo ; backref L+7 * */ size_t -lzf_compress (const void *const in_data, size_t in_len, - void *out_data, size_t out_len +lzf_compress (const void *const in_data,size_t in_len, + void *out_data, size_t out_len #if LZF_STATE_ARG - , LZF_STATE htab + , LZF_STATE *htab #endif - ) + ) { #if !LZF_STATE_ARG LZF_STATE htab; #endif + const u8 **hslot; const u8 *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; + u8 *op = (u8 *)out_data; const u8 *in_end = ip + in_len; - u8 *out_end = op + out_len; - const u8 *ref; - - /* - * off requires a type wide enough to hold a general pointer difference. - * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only - * works for differences within a single object). We also assume that - * no bit pattern traps. Since the only platform that is both non-POSIX - * and fails to support both assumptions is windows 64 bit, we make a - * special workaround for it. - */ + u8 *out_end = op + out_len; + const u8 *ref = NULL; + unsigned int hval = FRST (ip); size_t off; - unsigned int hval; - int lit; - - if (!in_len || !out_len) - return 0; + int lit = 0; #if INIT_HTAB +# if USE_MEMCPY memset (htab, 0, sizeof (htab)); +# else + for (hslot = htab; hslot < htab + HSIZE; hslot++) + *hslot++ = ip; +# endif #endif - lit = 0; op++; /* start run */ - - hval = FRST (ip); - while (ip < in_end - 2) + for (;;) { - LZF_HSLOT *hslot; - - hval = NEXT (hval, ip); - hslot = htab + IDX (hval); - ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS; - - if (1 -#if INIT_HTAB - && ref < ip /* the next test will actually take care of this, but this is faster */ -#endif - && (off = ip - ref - 1) < LZF_MAX_OFF - && ref > (const u8 *)in_data - && ref[2] == ip[2] -#if STRICT_ALIGN - && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]) -#else - && *(const u16 *)ref == *(const u16 *)ip -#endif - ) + if (ip < in_end - 2) { - /* match found at *ref++ */ - unsigned int len = 2; - size_t maxlen = in_end - ip - len; - maxlen = maxlen > LZF_MAX_REF ? LZF_MAX_REF : maxlen; + hval = NEXT (hval, ip); + hslot = htab + IDX (hval); + ref = *hslot; *hslot = ip; - if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */ - if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */ - return 0; - - op [- lit - 1] = lit - 1; /* stop run */ - op -= !lit; /* undo run if length is zero */ - - for (;;) + if ( +#if INIT_HTAB && !USE_MEMCPY + ref < ip /* the next test will actually take care of this, but this is faster */ + && +#endif + (off = ip - ref - 1) < MAX_OFF + && ip + 4 < in_end + && ref > (const u8 *)in_data +#if STRICT_ALIGN + && ref[0] == ip[0] + && ref[1] == ip[1] + && ref[2] == ip[2] +#else + && *(const u16 *)ref == *(const u16 *)ip + && ref[2] == ip[2] +#endif + ) { - if (expect_true (maxlen > 16)) - { - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; + /* match found at *ref++ */ + unsigned int len = 2; + size_t maxlen = in_end - ip - len; + maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - } + if (op + lit + 1 + 3 >= out_end) + return 0; do len++; while (len < maxlen && ref[len] == ip[len]); - break; - } + if (lit) + { + *op++ = (u8)(lit - 1); + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); + } - len -= 2; /* len is now #octets - 1 */ - ip++; + len -= 2; + ip++; - if (len < 7) - { - *op++ = (off >> 8) + (len << 5); - } - else - { - *op++ = (off >> 8) + ( 7 << 5); - *op++ = len - 7; - } + if (len < 7) + { + *op++ = (u8)((off >> 8) + (len << 5)); + } + else + { + *op++ = (u8)((off >> 8) + ( 7 << 5)); + *op++ = (u8)(len - 7); + } - *op++ = off; - - lit = 0; op++; /* start run */ - - ip += len + 1; - - if (expect_false (ip >= in_end - 2)) - break; + *op++ = (u8)off; #if ULTRA_FAST || VERY_FAST - --ip; -# if VERY_FAST && !ULTRA_FAST - --ip; -# endif - hval = FRST (ip); - - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - -# if VERY_FAST && !ULTRA_FAST - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; -# endif -#else - ip -= len + 1; - - do - { - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip - LZF_HSLOT_BIAS; - ip++; - } - while (len--); + ip += len; +#if VERY_FAST && !ULTRA_FAST + --ip; #endif + hval = FRST (ip); + + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; + +#if VERY_FAST && !ULTRA_FAST + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; +#endif +#else + do + { + hval = NEXT (hval, ip); + htab[IDX (hval)] = ip; + ip++; + } + while (len--); +#endif + continue; + } } - else + else if (ip == in_end) + break; + + /* one more literal byte we must copy */ + lit++; + ip++; + + if (lit == MAX_LIT) { - /* one more literal byte we must copy */ - if (expect_false (op >= out_end)) + if (op + 1 + MAX_LIT >= out_end) return 0; - lit++; *op++ = *ip++; - - if (expect_false (lit == LZF_MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } + *op++ = MAX_LIT - 1; +#if USE_MEMCPY + M_Memcpy (op, ip - MAX_LIT, MAX_LIT); + op += MAX_LIT; + lit = 0; +#else + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); +#endif } } - if (op + 3 > out_end) /* at most 3 bytes can be missing here */ - return 0; - - while (ip < in_end) + if (lit) { - lit++; *op++ = *ip++; + if (op + lit + 1 >= out_end) + return 0; - if (expect_false (lit == LZF_MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } + *op++ = (u8)(lit - 1); + lit = -lit; + do + *op++ = ip[lit]; + while (++lit); } - op [- lit - 1] = lit - 1; /* end run */ - op -= !lit; /* undo run if length is zero */ - - return op - (u8 *)out_data; + return op - (u8 *) out_data; } diff --git a/src/lzf.h b/src/lzf.h index dae8b131c..85daf255e 100644 --- a/src/lzf.h +++ b/src/lzf.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (c) 2000-2010 Marc Alexander Lehmann +// Copyright (C) 2000-2005 by Marc Alexander Lehmann // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -22,7 +22,7 @@ ** ***********************************************************************/ -#define LZF_VERSION 0x0106 /* 1.6 */ +#define LZF_VERSION 0x0105 /* 1.5 */ /* * Compress in_len bytes stored at the memory block starting at diff --git a/src/m_menu.c b/src/m_menu.c index 94b5f8f3b..4e215a9a9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1160,7 +1160,7 @@ static menuitem_t OP_ControlsMenu[] = {IT_CALL | IT_STRING, NULL, "Player 3 Controls...", &M_Setup3PControlsMenu, 30}, {IT_CALL | IT_STRING, NULL, "Player 4 Controls...", &M_Setup4PControlsMenu, 40}, - + {IT_SUBMENU | IT_STRING, NULL, "Mouse Options...", &OP_MouseOptionsDef, 60}, {IT_STRING | IT_CVAR, NULL, "Controls per key", &cv_controlperkey, 80}, @@ -1372,7 +1372,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_globalsaturation , 40}, - + {IT_SUBMENU|IT_STRING, NULL, "Advanced Color Settings...", &OP_ColorOptionsDef, 50}, {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 65}, @@ -1484,7 +1484,7 @@ static menuitem_t OP_ColorOptionsMenu[] = static menuitem_t OP_ExpOptionsMenu[] = { {IT_HEADER, NULL, "Advanced Video Options", NULL, 10}, - {IT_STRING|IT_CVAR, NULL, "Interpolation Distance", &cv_grmaxinterpdist, 30}, + {IT_STRING|IT_CVAR, NULL, "Interpolation Distance", &cv_maxinterpdist, 30}, {IT_STRING | IT_CVAR, NULL, "Weather Interpolation", &cv_precipinterp, 40}, {IT_STRING | IT_CVAR, NULL, "Scale Weather with Mobjscale", &cv_mobjscaleprecip, 60}, @@ -1492,15 +1492,15 @@ static menuitem_t OP_ExpOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 80}, -#ifdef HWRENDER - {IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_grscreentextures, 100}, -#ifdef USE_FBO_OGL - {IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_grframebuffer, 110}, -#endif - {IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_grpalettedepth, 130}, + {IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 90}, - {IT_STRING | IT_CVAR, NULL, "Splitwall/Slope texture fix", &cv_splitwallfix, 150}, -#endif +#ifdef HWRENDER + {IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 110}, +#ifdef USE_FBO_OGL + {IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 120}, +#endif + {IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 140}, +#endif }; static const char* OP_ExpTooltips[] = @@ -1511,13 +1511,13 @@ static const char* OP_ExpTooltips[] = "Should weather be scaled with Mapobjectscale?.", "When weather is on this will cut the object amount used in half.", "Toggle being able to see the sky.", + "Change the FPS counter sampling method\nInaccurate updates slower and might miss frame drops and such\nAccurate updates faster and is more accurate, but might be less readable", // how to ingles?? #ifdef HWRENDER "Should the game do Screen Textures? Provides a good boost to frames\nat the cost of some visual effects not working when disabled.", #ifdef USE_FBO_OGL "Allows the game to downsample from a higher resolution than your display\nin OpenGL renderer mode. Requires a GPU with atleast OpenGL 3.0 support.", #endif "Change the depth of the Palette in Palette rendering mode\n 16 bits is like software looks ingame\nwhile 24 bits is how software looks in screenshots.", - "Fixes issues that resulted in Textures sticking from the ground sometimes.\n This may be CPU heavy and result in worse performance in some cases.", #endif }; @@ -1529,13 +1529,13 @@ enum op_exp_precipmoscale, op_exp_lessprecip, op_exp_skybox, + op_exp_accuratefps, #ifdef HWRENDER - op_exp_grscrtx, + op_exp_glscrtx, #ifdef USE_FBO_OGL op_exp_fbo, #endif op_exp_paldepth, - op_exp_spltwal, #endif }; @@ -1543,24 +1543,24 @@ enum #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "3D Models", &cv_grmdls, 15}, - {IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 20}, - {IT_STRING | IT_CVAR, NULL, "Shaders", &cv_grshaders, 25}, - {IT_STRING | IT_CVAR, NULL, "Palette Rendering", &cv_grpaletterendering, 30}, - {IT_STRING | IT_CVAR, NULL, "Flashpals in Palette Renderer", &cv_grflashpal, 35}, - {IT_STRING | IT_CVAR, NULL, "Min Shader Brightness", &cv_secbright, 40}, + {IT_STRING | IT_CVAR, NULL, "3D Models", &cv_glmdls, 15}, + {IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_glfallbackplayermodel, 20}, + {IT_STRING | IT_CVAR, NULL, "Shaders", &cv_glshaders, 25}, + {IT_STRING | IT_CVAR, NULL, "Palette Rendering", &cv_glpaletterendering, 30}, + {IT_STRING | IT_CVAR, NULL, "Palette Rendering Flashpals",&cv_glflashpal, 35}, + {IT_STRING | IT_CVAR, NULL, "Min Shader Brightness", &cv_glsecbright, 40}, - {IT_STRING|IT_CVAR, NULL, "Texture Quality", &cv_scr_depth, 50}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 55}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 60}, - {IT_STRING|IT_CVAR, NULL, "Visual Portals", &cv_grportals, 65}, + {IT_STRING | IT_CVAR, NULL, "Texture Quality", &cv_scr_depth, 50}, + {IT_STRING | IT_CVAR, NULL, "Texture Filter", &cv_glfiltermode, 55}, + {IT_STRING | IT_CVAR, NULL, "Anisotropic", &cv_glanisotropicmode, 60}, + {IT_STRING | IT_CVAR, NULL, "Visual Portals", &cv_glportals, 65}, - {IT_STRING|IT_CVAR, NULL, "Wall Contrast Style", &cv_grfakecontrast, 75}, - {IT_STRING|IT_CVAR, NULL, "Slope Contrast", &cv_grslopecontrast, 80}, - {IT_STRING | IT_CVAR, NULL, "Dithered Lightning", &cv_lightdither, 85}, - {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", &cv_grspritebillboarding, 90}, - {IT_STRING|IT_CVAR, NULL, "Software Perspective", &cv_grshearing, 95}, - {IT_STRING|IT_CVAR, NULL, "Rendering Distance", &cv_grrenderdistance, 100}, + {IT_STRING | IT_CVAR, NULL, "Wall Contrast Style", &cv_glfakecontrast, 75}, + {IT_STRING | IT_CVAR, NULL, "Slope Contrast", &cv_glslopecontrast, 80}, + {IT_STRING | IT_CVAR, NULL, "Dithered Lightning", &cv_gllightdither, 85}, + {IT_STRING | IT_CVAR, NULL, "Sprite Billboarding", &cv_glspritebillboarding, 90}, + {IT_STRING | IT_CVAR, NULL, "Software Perspective", &cv_glshearing, 95}, + {IT_STRING | IT_CVAR, NULL, "Rendering Distance", &cv_glrenderdistance, 100}, }; static const char* OP_OpenGLTooltips[] = @@ -1577,11 +1577,32 @@ static const char* OP_OpenGLTooltips[] = "Recreates an effect from software mode that is used on some maps.", "The look of the wall contrast effect.", "Wall contrast but for slopes.", - "Should OpenGL lightning be dithered?", + "Should shader lightning be dithered?", "Should sprites always face the camera?", "Recreates the look of software mode camera perspective.", "How far the game world should be drawn.", }; + +enum +{ + op_gl_mdls, + op_gl_falbckmdls, + op_gl_shader, + op_gl_palrender, + op_gl_flashpal, + op_gl_secbright, + op_gl_scrdepth, + op_gl_filter, + op_gl_anis, + op_gl_portal, + op_gl_wallcont, + op_gl_slopecont, + op_gl_lightdither, + op_gl_bill, + op_gl_shearing, + op_gl_renderdist, +}; + #endif static menuitem_t OP_SoundOptionsMenu[] = @@ -1608,7 +1629,7 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 75}, {IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 85}, {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95}, - + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 105}, {IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 115}, @@ -1622,7 +1643,7 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 85}, {IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 95}, {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 105}, - + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 115}, {IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 125}, @@ -1683,7 +1704,7 @@ static const char* OP_SoundAdvancedTooltips[] = { #ifdef HAVE_OPENMPT NULL, - + "Filter used to resample tracker instruments.", "Resample tracker modules to sound similar to Paula hardware.", #if OPENMPT_API_VERSION_MAJOR < 1 && OPENMPT_API_VERSION_MINOR > 4 @@ -1796,7 +1817,7 @@ static menuitem_t OP_HUDOptionsMenu[] = { {IT_STRING | IT_CVAR, NULL, "Show HUD (F3)", &cv_showhud, 10}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "HUD Visibility", &cv_translucenthud, 20}, + NULL, "HUD Visibility", &cv_translucenthud, 20}, {IT_STRING | IT_SUBMENU, NULL, "Online HUD options...", &OP_ChatOptionsDef, 35}, {IT_STRING | IT_CVAR, NULL, "Background Glass", &cons_backcolor, 45}, @@ -1812,9 +1833,9 @@ static menuitem_t OP_HUDOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Console Text Size", &cv_constextsize, 120}, {IT_STRING | IT_CVAR, NULL, "Show Track Addon Name", &cv_showtrackaddon, 135}, - + {IT_STRING | IT_CVAR, NULL, "Show All Maps", &cv_showallmaps, 145}, - + {IT_STRING | IT_CVAR, NULL, "Show \"FOCUS LOST\"", &cv_showfocuslost, 155}, {IT_STRING | IT_CVAR, NULL, "2D character select", &cv_skinselectmenu, 165}, @@ -2066,7 +2087,7 @@ static menuitem_t OP_AdvServerOptionsMenu[] = }; static const char* OP_AdvServerOptionsTooltips[] = -{ +{ "Server used for master server.", "Attempts to resynchronise player to server.", #ifdef SATURNSYNCH @@ -2330,7 +2351,6 @@ enum sh_hudoffsets, }; - static menuitem_t OP_HudOffsetMenu[] = { {IT_HEADER, NULL, "Kart Hud Offsets", NULL, 0}, @@ -2384,7 +2404,7 @@ static menuitem_t OP_SaturnCreditsMenu[] = {IT_STRING2+IT_SPACE, NULL, "xyzzy", NULL, 70}, {IT_STRING2+IT_SPACE, NULL, "Chearii", NULL, 80}, - {IT_STRING+IT_SPACE, NULL, "", NULL, 83}, // dummy text + {IT_STRING+IT_SPACE, NULL, "", NULL, 83}, // dummy text {IT_STRING2+IT_SPACE, NULL, "Sunflower aka AnimeSonic", NULL, 90}, {IT_STRING2+IT_SPACE, NULL, "Yuz aka Yuzler", NULL, 100}, @@ -3392,7 +3412,7 @@ void PDistort_menu_Onchange(void) OP_PlayerDistortMenu[slrotatedist].status = IT_STRING | IT_CVAR; else OP_PlayerDistortMenu[slrotatedist].status = IT_GRAYEDOUT; - + if ((cv_sloperoll.value == 2) && (cv_spriteroll.value)) //enable/disable sparkroll depending on which setting OP_PlayerDistortMenu[sparkrotate].status = IT_STRING | IT_CVAR; else @@ -3421,7 +3441,7 @@ void Bird_menu_Onchange(void) OP_AdvancedBirdMenu[fadegrow].status = status; OP_AdvancedBirdMenu[respawnfadeout].status = status; OP_AdvancedBirdMenu[respawnfadein].status = status; - + if (cv_birdmusic.value) { OP_BirdMenu[lvlresum].status = IT_STRING | IT_CVAR; @@ -3433,7 +3453,7 @@ void Bird_menu_Onchange(void) OP_BirdMenu[lvlresum].status = IT_GRAYEDOUT; OP_BirdMenu[spclresum].status = IT_GRAYEDOUT; OP_BirdMenu[advmusic].status = IT_GRAYEDOUT; - } + } } //menu code is nice @@ -3445,11 +3465,28 @@ void SaturnHud_menu_Onchange(void) status = IT_STRING | IT_CVAR; else status = IT_GRAYEDOUT; - + OP_SaturnHudMenu[sh_coloritem].status = status; OP_SaturnHudMenu[sh_colorhud_customcolor].status = status; } +#ifdef HWRENDER +void M_UpdateOGLMenu(void) +{ + OP_ExpOptionsMenu[op_exp_fbo].status = (!supportFBO || cv_glscreentextures.value != 2) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + OP_ExpOptionsMenu[op_exp_paldepth].status = (!HWR_ShouldUsePaletteRendering()) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + + OP_OpenGLOptionsMenu[op_gl_falbckmdls].status = (!cv_glmdls.value) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + + OP_OpenGLOptionsMenu[op_gl_lightdither].status = (!HWR_UseShader()) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + OP_OpenGLOptionsMenu[op_gl_secbright].status = (!HWR_UseShader()) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + + OP_OpenGLOptionsMenu[op_gl_palrender].status = (cv_glscreentextures.value != 2 || !HWR_UseShader()) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; + OP_OpenGLOptionsMenu[op_gl_flashpal].status = (!HWR_ShouldUsePaletteRendering()) ? IT_GRAYEDOUT : IT_STRING | IT_CVAR; +} +#endif + + // ========================================================================== // END ORGANIZATION STUFF. // ========================================================================== @@ -4320,9 +4357,9 @@ void M_Drawer(void) #ifdef HWRENDER if (rendermode == render_opengl) V_DrawThinString(0, 0, V_GREENMAP|V_SNAPTOTOP|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("Opengl")); -#endif +#endif if (rendermode == render_soft) - V_DrawThinString(0, 0, V_REDMAP|V_SNAPTOTOP|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("Software")); + V_DrawThinString(0, 0, V_REDMAP|V_SNAPTOTOP|V_SNAPTOLEFT|V_TRANSLUCENT|V_ALLOWLOWERCASE, ("Software")); } } } @@ -4413,18 +4450,18 @@ void M_StartControlPanel(void) MPauseMenu[mpause_psetup].status = IT_DISABLED; MISC_ChangeTeamMenu[0].status = IT_DISABLED; MISC_ChangeSpectateMenu[0].status = IT_DISABLED; - + MPauseMenu[mpause_addlocalskins].status = IT_STRING | IT_CALL; MPauseMenu[mpause_localskin].status = IT_STRING | IT_CALL; // Reset these in case splitscreen messes things up MPauseMenu[mpause_addons].alphaKey = 8; - + if (IsPlayerAdmin(consoleplayer)) MPauseMenu[mpause_addlocalskins].alphaKey = 16; else MPauseMenu[mpause_addlocalskins].alphaKey = 24; - + MPauseMenu[mpause_scramble].alphaKey = 8; MPauseMenu[mpause_switchmap].alphaKey = 24; @@ -4445,17 +4482,17 @@ void M_StartControlPanel(void) if (G_GametypeHasTeams()) MPauseMenu[mpause_scramble].status = IT_STRING | IT_SUBMENU; } - + if (server || (!cv_showlocalskinmenus.value)) { MPauseMenu[mpause_addlocalskins].status = IT_DISABLED; MPauseMenu[mpause_localskin].status = IT_DISABLED; - + MPauseMenu[mpause_options].alphaKey = 64; MPauseMenu[mpause_title].alphaKey = 80; MPauseMenu[mpause_quit].alphaKey = 88; } - + if (splitscreen) { @@ -4720,11 +4757,12 @@ void M_Init(void) if (rendermode == render_soft) { OP_VideoOptionsMenu[op_video_ogl].status = IT_DISABLED; - OP_ExpOptionsMenu[op_exp_grscrtx].status = IT_DISABLED; + + OP_ExpOptionsMenu[op_exp_glscrtx].status = IT_DISABLED; #ifdef USE_FBO_OGL OP_ExpOptionsMenu[op_exp_fbo].status = IT_DISABLED; #endif - OP_ExpOptionsMenu[op_exp_spltwal].status = IT_DISABLED; + OP_ExpOptionsMenu[op_exp_paldepth].status = IT_DISABLED; } if (rendermode == render_opengl) @@ -4733,15 +4771,25 @@ void M_Init(void) if (!supportFBO) OP_ExpOptionsMenu[op_exp_fbo].status = IT_GRAYEDOUT; #endif + if (!gl_shadersavailable) + { + OP_OpenGLOptionsMenu[op_gl_shader].status = IT_GRAYEDOUT; + OP_OpenGLOptionsMenu[op_gl_lightdither].status = IT_GRAYEDOUT; + OP_OpenGLOptionsMenu[op_gl_secbright].status = IT_GRAYEDOUT; + OP_OpenGLOptionsMenu[op_gl_palrender].status = IT_GRAYEDOUT; + OP_OpenGLOptionsMenu[op_gl_flashpal].status = IT_GRAYEDOUT; + + OP_ExpOptionsMenu[op_exp_paldepth].status = IT_GRAYEDOUT; + } } #endif if (!xtra_speedo && !kartzspeedo && !achi_speedo) // why bother? OP_SaturnHudMenu[sh_speedometer].status = IT_GRAYEDOUT; - + //if (!xtra_speedo && kartzspeedo) //OP_SaturnMenu[sm_speedometer].text = "Speedometer (No Small)"; - + //if (xtra_speedo && !kartzspeedo) //OP_SaturnMenu[sm_speedometer].text = "Speedometer (No PMeter)"; // idk i dont wanna bother with this tbh lmao @@ -5077,7 +5125,7 @@ static void M_DrawSplitText(INT32 x, INT32 y, INT32 option, const char* str, INT yoffset = (((5*10 - num_lines*10))); // Draw BG first,,, - for (int i = 0; i < num_lines; i++) + for (int i = 0; i < num_lines; i++) { V_DrawFill(0, (y + yoffset - 6)+5, vid.width, 11, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); yoffset += 11; @@ -5086,7 +5134,7 @@ static void M_DrawSplitText(INT32 x, INT32 y, INT32 option, const char* str, INT yoffset = (((5*10 - num_lines*10))); // THEN the text - for (int i = 0; i < num_lines; i++) + for (int i = 0; i < num_lines; i++) { V_DrawCenteredThinString(x, y + yoffset, option, clines[i]); V_DrawCenteredThinString(x, y + yoffset, option|V_YELLOWMAP|((9 - alpha) << V_ALPHASHIFT), clines[i]); @@ -5102,7 +5150,7 @@ static void M_DrawSplitText(INT32 x, INT32 y, INT32 option, const char* str, INT static void M_DrawGenericMenu(void) { INT32 x, y, w, i, cursory = 0; - + INT32 lowercase = !cv_menucaps.value ? V_ALLOWLOWERCASE : 0; // DRAW MENU @@ -5318,7 +5366,7 @@ static void M_DrawGenericScrollMenu(void) // draw title (or big pic) M_DrawMenuTitle(); - + INT32 lowercase = !cv_menucaps.value ? V_ALLOWLOWERCASE : 0; for (; i < max; i++) @@ -5440,7 +5488,7 @@ static void M_DrawCenteredMenu(void) // draw title (or big pic) M_DrawMenuTitle(); - + INT32 lowercase = !cv_menucaps.value ? V_ALLOWLOWERCASE : 0; for (i = 0; i < currentMenu->numitems; i++) @@ -6369,7 +6417,7 @@ static void M_AddonAutoLoad(INT32 ch) S_StartSound(NULL, sfx_s26d); return; } - + // first, find the file // path = va("%s"PATHSEP"%s", srb2home, AUTOLOADCONFIGFILENAME); autoloadconfigfile = fopen(path, "a"); @@ -6384,7 +6432,7 @@ static void M_AddonAutoLoad(INT32 ch) case EXT_CFG: CONS_Printf("Added the \x82%s\x80 console script to the autoload configuration list.\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); fprintf(autoloadconfigfile, "%s\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); - + S_StartSound(NULL, sfx_s221); break; case EXT_LUA: @@ -6397,7 +6445,7 @@ static void M_AddonAutoLoad(INT32 ch) { CONS_Printf("Added \x82%s\x80 to the autoload configuration list.\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); fprintf(autoloadconfigfile, "%s\n", dirmenu[dir_on[menudepthleft]]+DIR_STRING); - + S_StartSound(NULL, sfx_s221); } else @@ -6407,7 +6455,7 @@ static void M_AddonAutoLoad(INT32 ch) } break; } - + // lastly, do some last things and close the autoload config file // fclose(autoloadconfigfile); } @@ -6611,7 +6659,7 @@ static void M_HandleAddons(INT32 choice) || (strcmp(dirmenu[dir_on[menudepthleft]]+DIR_STRING, AUTOLOADCONFIGFILENAME) == 0) || (strcmp(dirmenu[dir_on[menudepthleft]]+DIR_STRING, "kartserv.cfg") == 0) || (strcmp(dirmenu[dir_on[menudepthleft]]+DIR_STRING, "kartexec.cfg") == 0)) - { + { M_StartMessage(va("%c%s\x80\nYou can't autoload this builds' base console scripts, silly!\n They're already autoloaded on startup! \n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), dirmenu[dir_on[menudepthleft]]+DIR_STRING),NULL,MM_NOTHING); S_StartSound(NULL, sfx_s26d); } @@ -7882,7 +7930,7 @@ static void M_Options(INT32 choice) OP_MainMenu[5].status = OP_MainMenu[6].status = (Playing() && !(server || IsPlayerAdmin(consoleplayer))) ? (IT_GRAYEDOUT) : (IT_STRING|IT_SUBMENU); OP_MainMenu[10].status = (Playing()) ? (IT_GRAYEDOUT) : (IT_STRING|IT_CALL); // Play credits - + OP_MainMenu[13].status = (!cv_showlocalskinmenus.value) ? (IT_DISABLED) : (IT_CALL|IT_STRING); #ifdef HAVE_DISCORDRPC @@ -8456,14 +8504,14 @@ static void M_DrawMusicTest(void) if (curplaying && curplaying->authors[0]) V_DrawRightAlignedThinString(BASEVIDWIDTH-16, 46, V_ALLOWLOWERCASE, curplaying->authors); - + if (curplaying) { if (!curplaying->usage[0]) V_DrawString(vid.dupx, vid.height - 10*vid.dupy, V_NOSCALESTART|V_ALLOWLOWERCASE, va("%.6s", curplaying->name)); else V_DrawSmallString(vid.dupx, vid.height - 5*vid.dupy, V_NOSCALESTART|V_ALLOWLOWERCASE, va("%.6s - %.255s\n", curplaying->name, curplaying->usage)); - + if (cv_showmusicfilename.value) V_DrawSmallString(0, 0, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, curplaying->filename); } @@ -8609,7 +8657,7 @@ static void M_HandleMusicTest(INT32 choice) case KEY_ENTER: S_StopSounds(); S_StopMusic(); - curplaying = soundtestdefs[st_sel]; + curplaying = soundtestdefs[st_sel]; S_ChangeMusicInternal(curplaying->name, true); break; @@ -9474,10 +9522,10 @@ static void M_Connect(INT32 choice) { // do not call menuexitfunc M_ClearMenus(false); - + CV_Set(&cv_lastserver, I_GetNodeAddress(serverlist[choice-FIRSTSERVERLINE + serverlistpage * SERVERS_PER_PAGE].node)); - - COM_BufAddText(va("connect node %d\n", serverlist[choice-FIRSTSERVERLINE + serverlistpage * SERVERS_PER_PAGE].node)); + + COM_BufAddText(va("connect node %d\n", serverlist[choice-FIRSTSERVERLINE + serverlistpage * SERVERS_PER_PAGE].node)); } static void M_Refresh(INT32 choice) @@ -9723,7 +9771,7 @@ void M_SortServerList(void) #ifndef NONET #ifdef UPDATE_ALERT -#ifdef MASTERSERVER +#ifdef MASTERSERVER static void M_CheckMODVersion(int id) { char updatestring[500]; @@ -9998,9 +10046,9 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) const char *item2 = gamecontrol[gc_fire][1] != 0 ? G_KeynumToString(gamecontrol[gc_fire][1]) : NULL; if (item1 != NULL && item2 != NULL) - snprintf(encoretoggle, 32, "%s/%s: Toggle Encore", item1, item2); + snprintf(encoretoggle, 32, "%s/%s - Toggle Encore", item1, item2); else - snprintf(encoretoggle, 32, "%s: Toggle Encore", item1 != NULL ? item1 : item2 != NULL ? item2 : "Item"); + snprintf(encoretoggle, 32, "%s - Toggle Encore", item1 != NULL ? item1 : item2 != NULL ? item2 : "Item"); V_DrawThinString(1, BASEVIDHEIGHT-8-1, V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_TRANSLUCENT|V_ALLOWLOWERCASE, encoretoggle); } @@ -10223,7 +10271,7 @@ static void M_DrawMPMainMenu(void) // use generic drawer for cursor, items and title M_DrawGenericMenu(); - + INT32 lowercase = !cv_menucaps.value ? V_ALLOWLOWERCASE : 0; #ifndef NONET @@ -10430,7 +10478,7 @@ static void M_ConnectLastServer(INT32 choice) } M_ClearMenus(true); - COM_BufAddText(va("connect \"%s\"\n", cv_lastserver.string)); + COM_BufAddText(va("connect \"%s\"\n", cv_lastserver.string)); } // Tails 11-19-2002 @@ -10601,11 +10649,11 @@ static void M_DrawSetupMultiPlayerMenu(void) statoffset = 0; tw = V_StringWidth("Character", 0);//V_StringWidth(GETSELECTEDSKINNAME, 0); st = V_StringWidth(GETSELECTEDSKINNAME, 0); - + INT32 selectedskin = (itemOn == 1 && setupm_skinselect < numskins ? skinsorted[setupm_skinselect] : setupm_fakeskin); speed = skins[selectedskin].kartspeed; - weight = skins[selectedskin].kartweight; - + weight = skins[selectedskin].kartweight; + V_DrawString((mx+(tw/2)) - (st/2), my + 37, ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0) | highlightflags | V_ALLOWLOWERCASE, GETSELECTEDSKINNAME); @@ -10613,7 +10661,7 @@ static void M_DrawSetupMultiPlayerMenu(void) statoffset = 50; else statoffset = 113; - + V_DrawString(statx - statoffset, staty - 10, V_6WIDTHSPACE, va("\x84%dS \x87%dW", GETSELECTEDSPEED, GETSELECTEDWEIGHT)); #undef GETSELECTEDSKINNAME #undef GETSELECTEDSPEED @@ -10678,7 +10726,7 @@ static void M_DrawSetupMultiPlayerMenu(void) V_DrawCharacter(mx + 2 + st + (skullAnimCounter/5), my + 164, '\x1D' | highlightflags, false); // right arrow } - break; + break; case SKINMENUTYPE_GRID: case SKINMENUTYPE_2D: V_DrawString(mx, my + 152, highlightflags | V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart @@ -10722,8 +10770,8 @@ static void M_DrawSetupMultiPlayerMenu(void) { //Background V_DrawScaledPatch(statx - 50, staty + 4, 0, W_CachePatchName("K_STATNB", PU_CACHE)); - - //Speed + + //Speed for (i = 0; i < GETSELECTEDSPEED; i++) // draw the stat bars { if (i == 0) @@ -10733,11 +10781,11 @@ static void M_DrawSetupMultiPlayerMenu(void) else V_DrawScaledPatch(statx - 45, staty + 63 -(5 *i), 0, W_CachePatchName("K_STATN2", PU_CACHE)); } - + //Weight for (i = 0; i < GETSELECTEDWEIGHT; i++) // draw the stat bars { - + if (i == 0) V_DrawScaledPatch(statx - 30, staty + 63, 0, W_CachePatchName("K_STATN4", PU_CACHE)); else if (i == GETSELECTEDWEIGHT -1) @@ -11013,10 +11061,10 @@ static void M_DrawSetupMultiPlayerMenu(void) #define indexwidth 8 { INT32 colwidth = ((BASEVIDWIDTH-(2*mx))-charw)/(2*indexwidth); - + if (cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED) colwidth = colwidth - 10; - + INT32 j = -colwidth; INT16 col = setupm_fakecolor - colwidth; INT32 x = mx; @@ -11150,7 +11198,7 @@ static void M_DrawSetupMultiPlayerMenu(void) frame = 0; // Try to use standing frame sprframe = &sprdef->spriteframes[frame]; - + //minenice's speen css, it's a piece of shit but hey //patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE); speenframe = (I_GetTime()*cv_skinselectspin.value/TICRATE + 1)%8; @@ -11220,7 +11268,7 @@ static void M_HandleSetupMultiPlayer(INT32 choice) if (setupm_skinselect < ROUNDSKINSUPTO8 - SKINGRIDWIDTH) //if we arent at the bottom of the menu { setupm_skinselect += SKINGRIDWIDTH; - + if (cv_skinselectmenu.value == SKINMENUTYPE_GRID){ if (setupm_skinselect >= ((setupm_skinypos-1)+SKINGRIDHEIGHT)*8 && setupm_skinypos < (ROUNDSKINSUPTO8/8)-SKINGRIDHEIGHT) setupm_skinypos++; @@ -11293,9 +11341,9 @@ static void M_HandleSetupMultiPlayer(INT32 choice) else if (cv_skinselectmenu.value == SKINMENUTYPE_EXTENDED){ setupm_skinypos = (((numskins / SKINGRIDWIDTH) - (SKINGRIDHEIGHT-1)-2) > 0 ? ((numskins / SKINGRIDWIDTH) - (SKINGRIDHEIGHT-1)-2) : 0); M_PrevOpt(); - + } - + } else M_PrevOpt(); @@ -11756,7 +11804,7 @@ static boolean M_QuitMultiPlayerMenu(void) } // you know what? always putting these in the buffer won't hurt anything. COM_BufAddText (va("%s \"%s\"\n",setupm_cvskin->name,skins[setupm_fakeskin].name)); - COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor)); + COM_BufAddText (va("%s %d\n",setupm_cvcolor->name,setupm_fakecolor)); return true; } @@ -12581,7 +12629,7 @@ static void M_VideoModeMenu(INT32 choice) static void M_DrawVideoMenu(void) { M_DrawGenericMenu(); - + INT32 lowercase = !cv_menucaps.value ? V_ALLOWLOWERCASE : 0; V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + OP_VideoOptionsMenu[0].alphaKey, @@ -12674,7 +12722,7 @@ static void M_DrawLocalSkinMenu(void) else multi_tics += multi_state->tics * FRACUNIT; } - + // skin 0 is default player sprite if (R_AnySkinAvailable(cv_fakelocalskin.string) != -1) { @@ -12683,7 +12731,7 @@ static void M_DrawLocalSkinMenu(void) } else { - // ATTEMPT TO FIND REAL SKIN + // ATTEMPT TO FIND REAL SKIN if (R_AnySkinAvailable(cv_skin.string) != -1) { sprdef = &allskins[R_AnySkinAvailable(cv_skin.string)].spritedef; diff --git a/src/m_menu.h b/src/m_menu.h index 486b5b869..9806773b4 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -299,6 +299,10 @@ void Bird_menu_Onchange(void); // Saturn Hud menu updating void SaturnHud_menu_Onchange(void); +#ifdef HWRENDER +void M_UpdateOGLMenu(void); +#endif + void M_ReplayHut(INT32 choice); void M_SetPlaybackMenuPointer(void); diff --git a/src/m_perfstats.c b/src/m_perfstats.c index 30640b21c..3c5526678 100644 --- a/src/m_perfstats.c +++ b/src/m_perfstats.c @@ -301,7 +301,7 @@ static boolean PS_IsRowValid(perfstatrow_t *row) || (row->flags & PS_SW && rendermode != render_soft) || (row->flags & PS_HW && rendermode != render_opengl) #ifdef HWRENDER - || (row->flags & PS_BATCHING && !cv_grbatching.value) + || (row->flags & PS_BATCHING && !cv_glbatching.value) #endif ); } @@ -518,7 +518,7 @@ static void PS_UpdateFrameStats(void) ps_hw_spritesorttime.value.p + ps_hw_spritedrawtime.value.p; - if (cv_grbatching.value) + if (cv_glbatching.value) { ps_otherrendertime.value.p -= ps_hw_batchsorttime.value.p + @@ -547,7 +547,7 @@ static void PS_UpdateFrameStats(void) PS_UpdateRowHistories(interpolation_rows, true);*/ #ifdef HWRENDER - if (rendermode == render_opengl && cv_grbatching.value) + if (rendermode == render_opengl && cv_glbatching.value) { PS_UpdateRowHistories(batchcount_rows, true); PS_UpdateRowHistories(batchcalls_rows, true); @@ -760,7 +760,7 @@ static void PS_DrawRenderStats(void) /*cy = */PS_DrawPerfRows(x, 10, V_BLUEMAP, commoncounter_rows);// + half_row; #ifdef HWRENDER - if (rendermode == render_opengl && cv_grbatching.value) + if (rendermode == render_opengl && cv_glbatching.value) { x = hires ? 200 : 155; y = PS_DrawPerfRows(x, 10, V_PURPLEMAP, batchcount_rows); diff --git a/src/m_textinput.c b/src/m_textinput.c index a73511f77..83adbf8bf 100644 --- a/src/m_textinput.c +++ b/src/m_textinput.c @@ -118,6 +118,15 @@ static void M_TextInputToWordBegin(textinput_t *input, boolean move_sel) if (move_sel) input->select = input->cursor; } +static void M_TextInputPaste(textinput_t *input) +{ + const char *paste = I_ClipboardPaste(); + if (input->select != input->cursor) + M_TextInputDelSelection(input); + if (paste != NULL) + M_TextInputAddString(input, paste); +} + void M_TextInputInit(textinput_t *input, char *buffer, size_t buffer_size) { input->buffer = buffer; @@ -147,6 +156,12 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key) || key == KEY_LALT || key == KEY_RALT) return false; + if (shiftdown && key == KEY_INS) + { + M_TextInputPaste(input); + return true; + } + if ((cv_keyboardlayout.value != 3 && ctrldown) || (cv_keyboardlayout.value == 3 && ctrldown && !altdown)) { if (key == 'x' || key == 'X') @@ -168,11 +183,7 @@ boolean M_TextInputHandle(textinput_t *input, INT32 key) } else if (key == 'v' || key == 'V') { - const char *paste = I_ClipboardPaste(); - if (input->select != input->cursor) - M_TextInputDelSelection(input); - if (paste != NULL) - M_TextInputAddString(input, paste); + M_TextInputPaste(input); return true; } else if (key == 'w' || key == 'W') diff --git a/src/p_inter.c b/src/p_inter.c index ca1d88ba2..29d7e4739 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2400,8 +2400,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage); if (P_MobjWasRemoved(target)) return (shouldForce == 1); // mobj was removed - if (P_MobjWasRemoved(source)) - source = NULL; if (shouldForce == 1) force = true; else if (shouldForce == 2) @@ -2638,6 +2636,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_ResetPlayer(target->player); } else + { switch (target->type) { case MT_EGGMOBILE2: // egg slimer @@ -2651,9 +2650,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_SetMobjState(target, target->info->painstate); break; } - - if (P_MobjWasRemoved(target)) - return false; + } if (!P_MobjWasRemoved(target)) { diff --git a/src/p_local.h b/src/p_local.h index 0902c8b3d..fe1d10d73 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -298,7 +298,14 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype #define P_SpawnNameFinder(s,t) P_SPMAngle(s,t,s->angle,true,0) #endif void P_ColorTeamMissile(mobj_t *missile, player_t *source); -SINT8 P_MobjFlip(const mobj_t *mobj); + +// P_MobjFlip +// Special utility to return +1 or -1 depending on mobj's gravity +FUNCINLINE static ATTRINLINE SINT8 P_MobjFlip(const mobj_t *mobj) +{ + return (mobj && mobj->eflags & MFE_VERTICALFLIP) ? -1 : 1; +} + fixed_t P_GetMobjGravity(mobj_t *mo); FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type); diff --git a/src/p_mobj.c b/src/p_mobj.c index 0fc870045..ad296c576 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -91,6 +91,7 @@ FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) // var2 determines delay between animation frames if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0) return; + mobj->anim_duration = (UINT16)mobj->state->var2; // compare the current sprite frame to the one we started from @@ -351,18 +352,6 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state) return true; } -// -// P_MobjFlip -// -// Special utility to return +1 or -1 depending on mobj's gravity -// -SINT8 P_MobjFlip(const mobj_t *mobj) -{ - if (mobj && mobj->eflags & MFE_VERTICALFLIP) - return -1; - return 1; -} - // // P_WeaponOrPanel // @@ -408,7 +397,7 @@ void P_ExplodeMissile(mobj_t *mo) P_RadiusAttack(mo, mo, 96*FRACUNIT); explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - if (!P_MobjWasRemoved(explodemo)) + if (explodemo) { P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; @@ -417,7 +406,7 @@ void P_ExplodeMissile(mobj_t *mo) S_StartSound(explodemo, sfx_pop); } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - if (!P_MobjWasRemoved(explodemo)) + if (explodemo) { P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; @@ -426,7 +415,7 @@ void P_ExplodeMissile(mobj_t *mo) S_StartSound(explodemo, sfx_dmpain); } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - if (!P_MobjWasRemoved(explodemo)) + if (explodemo) { P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; @@ -435,7 +424,7 @@ void P_ExplodeMissile(mobj_t *mo) S_StartSound(explodemo, sfx_pop); } explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE); - if (!P_MobjWasRemoved(explodemo)) + if (explodemo) { P_SetScale(explodemo, mo->scale); explodemo->destscale = mo->destscale; @@ -3242,100 +3231,92 @@ void P_DestroyRobots(void) } } -// P_CameraThinker -// -// Process the mobj-ish required functions of the camera -boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled) +// the below is chasecam only, if you're curious. check out P_CalcPostImg in p_user.c for first person +static void P_CalcChasePostImg(player_t *player, camera_t *thiscam) { - boolean itsatwodlevel = false; - boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP); - postimg_t postimg = postimg_none; + const boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP); + UINT16 postimgflags = 0; UINT8 i; - // This can happen when joining - if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL) - return true; + if (encoremode) + postimgflags |= POSTIMG_MIRROR; + if (flipcam) + postimgflags |= POSTIMG_FLIP; - if (twodlevel) - itsatwodlevel = true; - else - { - for (i = 0; i <= splitscreen; i++) - { - if (thiscam == &camera[i] && players[displayplayers[i]].mo - && (players[displayplayers[i]].mo->flags2 & MF2_TWOD)) - { - itsatwodlevel = true; - break; - } - } - } - - if (encoremode && !flipcam) - postimg = postimg_mirror; - else if (!encoremode && flipcam) - postimg = postimg_flip; - else if (encoremode && flipcam) - postimg = postimg_mirrorflip; - else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist + if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist { camera_t dummycam; + dummycam.subsector = player->awayviewmobj->subsector; dummycam.x = player->awayviewmobj->x; dummycam.y = player->awayviewmobj->y; dummycam.z = player->awayviewmobj->z; //dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT dummycam.height = 0; // Why? Remote viewpoint cameras have no height. + // Are we in water? if (P_CameraCheckWater(&dummycam)) - postimg = postimg_water; - else if (P_CameraCheckHeat(&dummycam)) - postimg = postimg_heat; + postimgflags |= POSTIMG_WATER; + if (P_CameraCheckHeat(&dummycam)) + postimgflags |= POSTIMG_HEAT; } else { // Are we in water? if (P_CameraCheckWater(thiscam)) - postimg = postimg_water; - else if (P_CameraCheckHeat(thiscam)) - postimg = postimg_heat; + postimgflags |= POSTIMG_WATER; + if (P_CameraCheckHeat(thiscam)) + postimgflags |= POSTIMG_HEAT; } - if (postimg != postimg_none) + for (i = 0; i <= splitscreen; i++) { - for (i = 0; i <= splitscreen; i++) - { - if (player != &players[displayplayers[i]]) - continue; + if (player != &players[displayplayers[i]]) + continue; - postimgtype[i] = postimg; - } + players[displayplayers[i]].postimgflags = postimgflags; + break; } +} + +// P_CameraThinker +// +// Process the mobj-ish required functions of the camera +boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled) +{ + // This can happen when joining + if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL) + return true; + + P_CalcChasePostImg(player, thiscam); if (thiscam->momx || thiscam->momy) { - if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam)) - { // Never fails for 2D mode. + if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam)) // Never fails for 2D mode. + { mobj_t dummy; + dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker; dummy.subsector = thiscam->subsector; dummy.x = thiscam->x; dummy.y = thiscam->y; dummy.z = thiscam->z; dummy.height = thiscam->height; + if (player->pflags & PF_TIMEOVER) player->kartstuff[k_timeovercam] = (2*TICRATE)+1; + if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead. P_ResetCamera(player, thiscam); else P_SlideCameraMove(thiscam); + if (resetcalled) // Okay this means the camera is fully reset. return true; } } - if (!itsatwodlevel) - P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam); + P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam); thiscam->subsector = R_PointInSubsector(thiscam->x, thiscam->y); thiscam->floorz = tmfloorz; @@ -3347,7 +3328,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled thiscam->z += thiscam->momz + player->mo->pmomz; #ifndef NOCLIPCAM - if (!itsatwodlevel && !(player->pflags & PF_NOCLIP || leveltime < introtime)) + if (!(player->pflags & PF_NOCLIP || leveltime < introtime)) { // clip movement if (thiscam->z <= thiscam->floorz) // hit the floor @@ -3390,13 +3371,13 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled #endif } - if (itsatwodlevel - || (thiscam->ceilingz - thiscam->z < thiscam->height - && thiscam->ceilingz >= thiscam->z)) + if (thiscam->ceilingz - thiscam->z < thiscam->height + && thiscam->ceilingz >= thiscam->z) { thiscam->ceilingz = thiscam->z + thiscam->height; thiscam->floorz = thiscam->z; } + return false; } @@ -3410,8 +3391,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(mobj->player != NULL); I_Assert(!P_MobjWasRemoved(mobj)); - - if (P_MobjWasRemoved(mobj)) + + if (!mobj) return; P_MobjCheckWater(mobj); @@ -6030,41 +6011,36 @@ static void P_KoopaThinker(mobj_t *koopa) // void P_RollPitchMobj(mobj_t* mobj) { - boolean usedist = false; - - if (P_MobjWasRemoved(mobj)) - return; + if (!mobj || P_MobjWasRemoved(mobj)) + return; - if (cv_sloperolldist.value > 0) - usedist = true; - - if (cv_spriteroll.value && cv_sloperoll.value == 2) - { - K_RollMobjBySlopes(mobj, usedist); - } - else - { - mobj->sloperoll = FixedAngle(0); - mobj->slopepitch = FixedAngle(0); - } + if (cv_spriteroll.value && cv_sloperoll.value == 2) + { + K_RollMobjBySlopes(mobj, cv_sloperolldist.value && !splitscreen); + } + else + { + mobj->sloperoll = FixedAngle(0); + mobj->slopepitch = FixedAngle(0); + } } angle_t P_MobjPitchAndRoll(mobj_t *mobj) { - spritedef_t *sprdef; - spriteframe_t *sprframe; - angle_t ang = 0; + spritedef_t *sprdef; + spriteframe_t *sprframe; + angle_t ang = 0; angle_t camang = 0; angle_t return_angle = 0; - + if (!cv_spriteroll.value) return 0; - if (P_MobjWasRemoved(mobj)) - return 0; + if (P_MobjWasRemoved(mobj)) + return 0; - size_t rot = mobj->frame & FF_FRAMEMASK; - boolean papersprite = (mobj->frame & FF_PAPERSPRITE); + size_t rot = mobj->frame & FF_FRAMEMASK; + boolean papersprite = (mobj->frame & FF_PAPERSPRITE); if (mobj->skin && mobj->sprite == SPR_PLAY) { @@ -6095,12 +6071,12 @@ angle_t P_MobjPitchAndRoll(mobj_t *mobj) camang = R_PointToAngle(mobj->x, mobj->y); } - return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll) + return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll) + FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), mobj->pitch); if (cv_sloperoll.value) { - return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll) + return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll) + FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), mobj->slopepitch); } @@ -6263,7 +6239,7 @@ void P_MobjThinker(mobj_t *mobj) P_RemoveMobj(mobj); return; } - + if (cv_sloperoll.value == 2 && mobj->state == &states[S_SHADOW]) { mobj->slopepitch = mobj->target->slopepitch; @@ -6286,6 +6262,7 @@ void P_MobjThinker(mobj_t *mobj) P_RemoveMobj(mobj); return; } + P_RollPitchMobj(mobj); break; case MT_SMOLDERING: @@ -6916,7 +6893,7 @@ void P_MobjThinker(mobj_t *mobj) // separate thinker if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) { - if (P_MobjWasRemoved(mobj)) + if (!mobj) return; P_MobjCheckWater(mobj); @@ -9434,11 +9411,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->destscale = mapobjectscale; mobj->scalespeed = mapobjectscale/12; } - + // Sprite rendering - mobj->realxscale = mobj->realyscale = mobj->scale; + mobj->realxscale = mobj->realyscale = mobj->scale; mobj->spritexscale = mobj->realxscale; - mobj->spriteyscale = mobj->realyscale; + mobj->spriteyscale = mobj->realyscale; mobj->spritexoffset = mobj->spriteyoffset = 0; // Funni slam sound when landing @@ -9892,11 +9869,11 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) mobj->destscale = mapobjectscale; mobj->scalespeed = mapobjectscale/12; } - + // Sprite rendering - mobj->spritexscale = mobj->spriteyscale = mobj->scale; + mobj->spritexscale = mobj->spriteyscale = mobj->scale; mobj->spritexoffset = mobj->spriteyoffset = 0; - + // set subsector and/or block links P_SetThingPosition(mobj); I_Assert(mobj->subsector != NULL); @@ -9994,10 +9971,13 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype if (mobj->floorz != starting_floorz) mobj->precipflags |= PCF_FOF; - else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7 - || GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6 - || mobj->subsector->sector->floorpic == skyflatnum) - mobj->precipflags |= PCF_PIT; + else + { + INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1); + + if (special == 7 || special == 6 || mobj->subsector->sector->floorpic == skyflatnum) + mobj->precipflags |= PCF_PIT; + } R_ResetPrecipitationMobjInterpolationState(mobj); @@ -10100,7 +10080,7 @@ void P_RemoveMobj(mobj_t *mobj) P_SetTarget(&mobj->hprev->hnext, cachenext); P_SetTarget(&mobj->hprev, NULL); } - + // clear the reference from the mapthing if (mobj->spawnpoint) mobj->spawnpoint->mobj = NULL; @@ -10291,7 +10271,7 @@ void P_PrecipitationEffects(void) INT32 volume; size_t i; - boolean sounds_rain = true; + boolean rainsfx = true; boolean sounds_thunder = true; boolean effects_lightning = true; boolean lightningStrike = false; @@ -10324,7 +10304,7 @@ void P_PrecipitationEffects(void) effects_lightning = false; break; case PRECIP_STORM_NORAIN: // no rain, lightning and thunder allowed - sounds_rain = false; + rainsfx = false; case PRECIP_STORM: // everything. break; default: @@ -10332,6 +10312,8 @@ void P_PrecipitationEffects(void) return; } + boolean sounds_rain = ((cv_drawdist_precip.value != 0) && rainsfx && (!leveltime || leveltime % 80 == 1)); + // Currently thunderstorming with lightning, and we're sounding the thunder... // and where there's thunder, there's gotta be lightning! if (effects_lightning && lightningStrike) @@ -10351,38 +10333,57 @@ void P_PrecipitationEffects(void) if (sound_disabled) return; // Sound off? D'aw, no fun. + if (!sounds_rain && !sounds_thunder) + return; // no need to calculate volume at ALL + if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum) volume = 255; // Sky above? We get it full blast. else { /* GCC is optimizing away y >= yl, FUCK YOU */ - volatile fixed_t x, y, yl, yh, xl, xh; + INT64 x, y, yl, yh, xl, xh; fixed_t closedist, newdist; // Essentially check in a 1024 unit radius of the player for an outdoor area. - yl = players[displayplayers[0]].mo->y - 1024*FRACUNIT; - yh = players[displayplayers[0]].mo->y + 1024*FRACUNIT; - xl = players[displayplayers[0]].mo->x - 1024*FRACUNIT; - xh = players[displayplayers[0]].mo->x + 1024*FRACUNIT; - closedist = 2048*FRACUNIT; +#define RADIUSSTEP (64*FRACUNIT) +#define SEARCHRADIUS (16*RADIUSSTEP) + yl = yh = players[displayplayers[0]].mo->y; + yl -= SEARCHRADIUS; + while (yl < INT32_MIN) + yl += RADIUSSTEP; + yh += SEARCHRADIUS; + while (yh > INT32_MAX) + yh -= RADIUSSTEP; - for (y = yl; y >= yl && y <= yh; y += FRACUNIT*64) - for (x = xl; x >= xl && x <= xh; x += FRACUNIT*64) + xl = xh = players[displayplayers[0]].mo->x; + xl -= SEARCHRADIUS; + while (xl < INT32_MIN) + xl += RADIUSSTEP; + xh += SEARCHRADIUS; + while (xh > INT32_MAX) + xh -= RADIUSSTEP; + + closedist = SEARCHRADIUS*2; +#undef SEARCHRADIUS + for (y = yl; y <= yh; y += RADIUSSTEP) + for (x = xl; x <= xh; x += RADIUSSTEP) { - if (R_PointInSubsector(x, y)->sector->ceilingpic != skyflatnum) // Found the outdoors! + if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors! continue; - newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, x, y, 0); + newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0); + if (newdist < closedist) closedist = newdist; } volume = 255 - (closedist>>(FRACBITS+2)); } +#undef RADIUSSTEP volume = CLAMP(volume, 0, 255); - if (sounds_rain && (!leveltime || leveltime % 80 == 1)) + if (sounds_rain) S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume); if (!sounds_thunder) @@ -11250,7 +11251,8 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj = P_SpawnMobj(x, y, z, i); - if (!mobj || P_MobjWasRemoved(mobj)) { + if (!mobj || P_MobjWasRemoved(mobj)) + { CONS_Alert(CONS_ERROR, "Failed to spawn map thing #%d at %d, %d. This will crash vanilla clients!\n", mthing->type, x>>FRACBITS, y>>FRACBITS); return; } diff --git a/src/p_mobj.h b/src/p_mobj.h index 7a8151dc3..cd7c64dc1 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -261,6 +261,7 @@ typedef enum { PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over PCF_THUNK = 1<<5, // Ran the thinker this tic. } precipflag_t; + // Map Object definition. typedef struct mobj_s { @@ -287,8 +288,7 @@ typedef struct mobj_s spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT16 anim_duration; // for FF_ANIMATE states - - UINT32 renderflags; // render flags + fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; fixed_t old_spritexscale, old_spriteyscale; @@ -440,8 +440,7 @@ typedef struct precipmobj_s spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT16 anim_duration; // for FF_ANIMATE states - - UINT32 renderflags; // render flags + fixed_t spritexscale, spriteyscale; fixed_t spritexoffset, spriteyoffset; fixed_t old_spritexscale, old_spriteyscale; @@ -450,7 +449,7 @@ typedef struct precipmobj_s fixed_t realxscale, realyscale; // funn-E streeetch fixed_t stretchslam; // "squish" effect when you land - + //sloperollangle angle_t sloperoll, slopepitch; angle_t old_sloperoll, old_slopepitch; diff --git a/src/p_setup.c b/src/p_setup.c index 672b1b347..ce1dd6efb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -510,7 +510,7 @@ void P_UpdateSegLightOffset(seg_t *li) // Loads the SEGS resource from a level. static void P_LoadRawSegs(UINT8 *data) { - INT32 linedef, side; + INT32 rawlinedef, rawside; mapseg_t *ml = (mapseg_t*)data; seg_t *li = segs; line_t *ldef; @@ -530,14 +530,14 @@ static void P_LoadRawSegs(UINT8 *data) li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); - ldef = &lines[linedef]; + rawlinedef = SHORT(ml->linedef); + ldef = &lines[rawlinedef]; li->linedef = ldef; - li->side = side = SHORT(ml->side); - li->sidedef = &sides[ldef->sidenum[side]]; - li->frontsector = sides[ldef->sidenum[side]].sector; + li->side = rawside = SHORT(ml->side); + li->sidedef = &sides[ldef->sidenum[rawside]]; + li->frontsector = sides[ldef->sidenum[rawside]].sector; if (ldef->flags & ML_TWOSIDED) - li->backsector = sides[ldef->sidenum[side^1]].sector; + li->backsector = sides[ldef->sidenum[rawside^1]].sector; else li->backsector = 0; @@ -2494,6 +2494,9 @@ static void P_InitMinimapInfo(void) fixed_t a; fixed_t b; node_t *bsp = &nodes[numnodes-1]; + + minimapinfo.minimap_pic = NULL; + lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap))); if (lumpnum != -1) @@ -2505,6 +2508,7 @@ static void P_InitMinimapInfo(void) minimapinfo.max_x = bsp->bbox[0][BOXRIGHT]; minimapinfo.min_y = bsp->bbox[0][BOXBOTTOM]; minimapinfo.max_y = bsp->bbox[0][BOXTOP]; + if (bsp->bbox[1][BOXLEFT] < minimapinfo.min_x) minimapinfo.min_x = bsp->bbox[1][BOXLEFT]; if (bsp->bbox[1][BOXRIGHT] > minimapinfo.max_x) @@ -2513,15 +2517,19 @@ static void P_InitMinimapInfo(void) minimapinfo.min_y = bsp->bbox[1][BOXBOTTOM]; if (bsp->bbox[1][BOXTOP] > minimapinfo.max_y) minimapinfo.max_y = bsp->bbox[1][BOXTOP]; + // You might be wondering why these are being bitshift here // it's because mapwidth and height would otherwise overflow for maps larger than half the size possible... // map boundaries and sizes will ALWAYS be whole numbers thankfully // later calculations take into consideration that these are actually not in terms of FRACUNIT though minimapinfo.map_w = (minimapinfo.max_x >>= FRACBITS) - (minimapinfo.min_x >>= FRACBITS); minimapinfo.map_h = (minimapinfo.max_y >>= FRACBITS) - (minimapinfo.min_y >>= FRACBITS); + minimapinfo.minimap_w = minimapinfo.minimap_h = 100; + a = FixedDiv(minimapinfo.minimap_w<>(FRACBITS-4); @@ -2535,8 +2543,10 @@ static void P_InitMinimapInfo(void) } minimapinfo.zoom = b; } + minimapinfo.zoom >>= (FRACBITS-4); minimapinfo.zoom -= (minimapinfo.zoom/20); + // These should always be small enough to be bitshift back right now minimapinfo.offs_x = FixedMul((minimapinfo.min_x + minimapinfo.map_w/2) << FRACBITS, minimapinfo.zoom); minimapinfo.offs_y = FixedMul((minimapinfo.min_y + minimapinfo.map_h/2) << FRACBITS, minimapinfo.zoom); @@ -2587,9 +2597,6 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate) P_LevelInitStuff(reloadinggamestate); - for (i = 0; i <= splitscreen; i++) - postimgtype[i] = postimg_none; - if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0' && atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255) P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter); diff --git a/src/p_tick.c b/src/p_tick.c index 7405792d0..989d27108 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -469,9 +469,6 @@ void P_Ticker(boolean run) return; } - for (i = 0; i <= splitscreen; i++) - postimgtype[i] = postimg_none; - P_MapStart(); if (run) @@ -708,9 +705,6 @@ void P_PreTicker(INT32 frames) INT32 i; ticcmd_t temptic; - for (i = 0; i <= splitscreen; i++) - postimgtype[i] = postimg_none; - hook_defrosting = frames; while (hook_defrosting) diff --git a/src/p_user.c b/src/p_user.c index 7c57fb107..31287e904 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2498,7 +2498,7 @@ static void P_MovePlayer(player_t *player) } #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value) + if (rendermode == render_opengl && cv_glfovchange.value) { fixed_t speed; const fixed_t runnyspeed = 20*FRACUNIT; @@ -4103,11 +4103,12 @@ boolean P_SpectatorJoinGame(player_t *player) return false; } +// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam static void P_CalcPostImg(player_t *player) { sector_t *sector = player->mo->subsector->sector; - postimg_t *type = NULL; - INT32 *param; + INT16 typeflag = 0; + //INT32 *param; fixed_t pviewheight; UINT8 i; @@ -4122,20 +4123,19 @@ static void P_CalcPostImg(player_t *player) pviewheight = player->awayviewmobj->z + 20*FRACUNIT; } - for (i = 0; i <= splitscreen; i++) + /*for (i = 0; i <= splitscreen; i++) { if (player == &players[displayplayers[i]]) { - type = &postimgtype[i]; param = &postimgparam[i]; break; } - } + }*/ // see if we are in heat (no, not THAT kind of heat...) if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1) - *type = postimg_heat; + typeflag |= POSTIMG_HEAT; else if (sector->ffloors) { ffloor_t *rover; @@ -4154,7 +4154,7 @@ static void P_CalcPostImg(player_t *player) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) - *type = postimg_heat; + typeflag |= POSTIMG_HEAT; } } @@ -4176,36 +4176,35 @@ static void P_CalcPostImg(player_t *player) if (pviewheight >= topheight || pviewheight <= bottomheight) continue; - *type = postimg_water; + typeflag |= POSTIMG_WATER; } } - if (!encoremode) // srb2kart - { - if (player->mo->eflags & MFE_VERTICALFLIP) - *type = postimg_flip; - } - else - { - if (player->mo->eflags & MFE_VERTICALFLIP) - *type = postimg_mirrorflip; - else - *type = postimg_mirror; - } + if (encoremode) // srb2kart + typeflag |= POSTIMG_MIRROR; + + if (player->mo->eflags & MFE_VERTICALFLIP) + typeflag |= POSTIMG_FLIP; -#if 1 - (void)param; -#else // Motion blur - if (player->speed > (35<speed > (35<speed - 32)/4; if (*param > 5) *param = 5; + }*/ + + for (i = 0; i <= splitscreen; i++) + { + if (player != &players[displayplayers[i]]) + continue; + + players[displayplayers[i]].postimgflags = typeflag; + break; } -#endif } void P_DoTimeOver(player_t *player) diff --git a/src/r_bsp.c b/src/r_bsp.c index 586aa3799..500a58035 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -15,6 +15,8 @@ #include "g_game.h" #include "r_local.h" #include "r_state.h" +#include "r_portal.h" // Add seg portals + #include "r_splats.h" #include "p_local.h" // camera @@ -28,7 +30,6 @@ side_t *sidedef; line_t *linedef; sector_t *frontsector; sector_t *backsector; -portal_pair *g_portal; // is curline a portal seg? // very ugly realloc() of drawsegs at run-time, I upped it to 512 // instead of 256.. and someone managed to send me a level with @@ -486,7 +487,7 @@ static void R_AddLine(seg_t *line) line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2); if (line2 >= 0) // found it! { - R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering + Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering //return; // Don't fill in that space now! goto clipsolid; } diff --git a/src/r_bsp.h b/src/r_bsp.h index 0d73c2bc4..f93541d7b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -25,7 +25,8 @@ extern side_t *sidedef; extern line_t *linedef; extern sector_t *frontsector; extern sector_t *backsector; -extern portal_pair *g_portal; // is curline a portal seg? +typedef struct portal_s portal_t; +extern portal_t *g_portal; // is curline a portal seg? // drawsegs are allocated on the fly... see r_segs.c @@ -41,7 +42,6 @@ void R_ClearClipSegs(void); void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); void R_RenderBSPNode(INT32 bspnum); -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); // determines when a given sector shouldn't abide by the encoremap's palette. // no longer a static since this is used for encore in hw_main.c as well now: diff --git a/src/r_defs.h b/src/r_defs.h index 71e13e4d4..bc95649bb 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -687,14 +687,6 @@ typedef struct #pragma pack() #endif -typedef enum // trimmed since its only real use here is for xscale/yscale -{ - RF_HORIZONTALFLIP = 0x0001, // Flip sprite horizontally - RF_VERTICALFLIP = 0x0002, // Flip sprite vertically - RF_ABSOLUTEOFFSETS = 0x0004, // Sprite uses the object's offsets absolutely, instead of relatively - RF_FLIPOFFSETS = 0x0008, // Relative object offsets are flipped with the sprite -} renderflags_t; - typedef enum { SRF_SINGLE = 0, // 0-angle for all rotations diff --git a/src/r_draw.c b/src/r_draw.c index fa19a6ac2..faa9ba638 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -78,6 +78,7 @@ fixed_t dc_iscale, dc_texturemid; UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit, // soo lets make it a byte on all system for the ASM code UINT8 *dc_source; +INT32 dc_sourcelength; // ----------------------- // translucency stuff here diff --git a/src/r_draw.h b/src/r_draw.h index 58775fe1d..7dbeda7c9 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -62,6 +62,7 @@ extern lighttable_t *ds_colormap; extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern INT32 ds_waterofs, ds_bgofs; extern UINT8 *ds_source; // start of a 64*64 tile image +extern INT32 dc_sourcelength; extern UINT8 *ds_transmap; extern INT32 ds_bgofs; diff --git a/src/r_draw8.c b/src/r_draw8.c index 6aabdb6dd..3c7562beb 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -28,6 +28,8 @@ void R_DrawColumn_8(void) register UINT8 *dest; register fixed_t frac; fixed_t fracstep; + INT32 npow2min; + INT32 npow2max; count = dc_yh - dc_yl; @@ -51,13 +53,26 @@ void R_DrawColumn_8(void) fracstep = dc_iscale; frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); - // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { register const UINT8 *source = dc_source; register const lighttable_t *colormap = dc_colormap; register INT32 heightmask = dc_texheight-1; + + if (dc_sourcelength <= 0) + { + // Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch + // This is to just render it effectively the identity function. + npow2min = INT32_MIN; + npow2max = INT32_MAX; + } + else + { + npow2min = -1; + npow2max = dc_sourcelength; + } + if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -74,7 +89,10 @@ void R_DrawColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = colormap[source[frac>>FRACBITS]]; + + // -1 is the lower clamp bound because column posts have a "safe" byte before the real data + // and a few bytes after as well + *dest = colormap[source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]]; dest += vid.width; // Avoid overflow. @@ -115,6 +133,8 @@ void R_Draw2sMultiPatchColumn_8(void) register UINT8 *dest; register fixed_t frac; fixed_t fracstep; + INT32 npow2min; + INT32 npow2max; count = dc_yh - dc_yl; @@ -147,6 +167,20 @@ void R_Draw2sMultiPatchColumn_8(void) register const lighttable_t *colormap = dc_colormap; register INT32 heightmask = dc_texheight-1; register UINT8 val; + + if (dc_sourcelength <= 0) + { + // Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch + // This is to just render it effectively the identity function. + npow2min = INT32_MIN; + npow2max = INT32_MAX; + } + else + { + npow2min = -1; + npow2max = dc_sourcelength; + } + if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -163,7 +197,10 @@ void R_Draw2sMultiPatchColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - val = source[frac>>FRACBITS]; + + // -1 is the lower clamp bound because column posts have a "safe" byte before the real data + // and a few bytes after as well + val = source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]; if (val != TRANSPARENTPIXEL) { @@ -223,6 +260,8 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) register UINT8 *dest; register fixed_t frac; fixed_t fracstep; + INT32 npow2min; + INT32 npow2max; count = dc_yh - dc_yl; @@ -256,6 +295,20 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) register const lighttable_t *colormap = dc_colormap; register INT32 heightmask = dc_texheight-1; register UINT8 val; + + if (dc_sourcelength <= 0) + { + // Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch + // This is to just render it effectively the identity function. + npow2min = INT32_MIN; + npow2max = INT32_MAX; + } + else + { + npow2min = -1; + npow2max = dc_sourcelength; + } + if (dc_texheight & heightmask) // not a power of 2 -- killough { heightmask++; @@ -272,7 +325,10 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - val = source[frac>>FRACBITS]; + + // -1 is the lower clamp bound because column posts have a "safe" byte before the real data + // and a few bytes after as well + val = source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]; if (val != TRANSPARENTPIXEL) { @@ -376,6 +432,8 @@ void R_DrawTranslucentColumn_8(void) register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; + INT32 npow2min; + INT32 npow2max; count = dc_yh - dc_yl + 1; @@ -403,6 +461,20 @@ void R_DrawTranslucentColumn_8(void) register const UINT8 *transmap = dc_transmap; register const lighttable_t *colormap = dc_colormap; register INT32 heightmask = dc_texheight - 1; + + if (dc_sourcelength <= 0) + { + // Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch + // This is to just render it effectively the identity function. + npow2min = INT32_MIN; + npow2max = INT32_MAX; + } + else + { + npow2min = -1; + npow2max = dc_sourcelength; + } + if (dc_texheight & heightmask) { heightmask++; @@ -420,7 +492,11 @@ void R_DrawTranslucentColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest)); + + // -1 is the lower clamp bound because column posts have a "safe" byte before the real data + // and a few bytes after as well + *dest = *(transmap + (colormap[source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]]<<8) + (*dest)); + dest += vid.width; if ((frac += fracstep) >= heightmask) @@ -458,6 +534,8 @@ void R_DrawTranslatedTranslucentColumn_8(void) register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; + INT32 npow2min; + INT32 npow2max; count = dc_yh - dc_yl + 1; @@ -477,6 +555,20 @@ void R_DrawTranslatedTranslucentColumn_8(void) // This is as fast as it gets. { register INT32 heightmask = dc_texheight - 1; + + if (dc_sourcelength <= 0) + { + // Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch + // This is to just render it effectively the identity function. + npow2min = INT32_MIN; + npow2max = INT32_MAX; + } + else + { + npow2min = -1; + npow2max = dc_sourcelength; + } + if (dc_texheight & heightmask) { heightmask++; @@ -494,7 +586,10 @@ void R_DrawTranslatedTranslucentColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + + // -1 is the lower clamp bound because column posts have a "safe" byte before the real data + // and a few bytes after as well + *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]]]<<8) + (*dest)); dest += vid.width; if ((frac += fracstep) >= heightmask) @@ -586,14 +681,14 @@ void R_DrawSpan_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; - UINT32 bit; + register UINT32 bit; UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + register size_t count = (ds_x2 - ds_x1 + 1); size_t i; xposition = ds_xfrac; yposition = ds_yfrac; @@ -681,13 +776,13 @@ void R_DrawTiltedSpan_8(void) UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; double startz, startu, startv; double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; - UINT32 bit; + register UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -822,13 +917,13 @@ void R_DrawTiltedTranslucentSpan_8(void) UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; double startz, startu, startv; double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; - UINT32 bit; + register UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -964,14 +1059,14 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; UINT8 *dsrc; double startz, startu, startv; double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; - UINT32 bit; + register UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -1105,7 +1200,7 @@ void R_DrawTiltedSplat_8(void) UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; UINT8 val; @@ -1113,7 +1208,7 @@ void R_DrawTiltedSplat_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; - UINT32 bit; + register UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -1257,13 +1352,13 @@ void R_DrawSplat_8 (void) UINT32 xposition; UINT32 yposition; UINT32 xstep, ystep; - UINT32 bit; + register UINT32 bit; UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; - size_t count; + register size_t count; size_t i; UINT32 val; @@ -1327,13 +1422,13 @@ void R_DrawTranslucentSplat_8 (void) UINT32 xposition; UINT32 yposition; UINT32 xstep, ystep; - UINT32 bit; + register UINT32 bit; UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; - size_t count; + register size_t count; size_t i; UINT8 val; @@ -1392,14 +1487,14 @@ void R_DrawTranslucentSpan_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; - UINT32 bit; + register UINT32 bit; UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + register size_t count = (ds_x2 - ds_x1 + 1); size_t i; xposition = ds_xfrac; yposition = ds_yfrac; @@ -1451,14 +1546,14 @@ void R_DrawTranslucentWaterSpan_8(void) UINT32 xposition; UINT32 yposition; UINT32 xstep, ystep; - UINT32 bit; + register UINT32 bit; UINT8 *source; UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; UINT8 *dsrc; - size_t count; + register size_t count; size_t i; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest @@ -1510,9 +1605,9 @@ void R_DrawTranslucentWaterSpan_8(void) void R_DrawFogSpan_8(void) { UINT8 *colormap; - UINT8 *dest; + register UINT8 *dest; - size_t count; + register size_t count; colormap = ds_colormap; //dest = ylookup[ds_y] + columnofs[ds_x1]; @@ -1543,8 +1638,8 @@ void R_DrawFogSpan_8(void) */ void R_DrawFogColumn_8(void) { - INT32 count; - UINT8 *dest; + register INT32 count; + register UINT8 *dest; count = dc_yh - dc_yl; @@ -1579,7 +1674,8 @@ void R_DrawFogColumn_8(void) */ void R_DrawColumnShadowed_8(void) { - INT32 count, realyh, i, height, bheight = 0, solid = 0; + register INT32 count; + INT32 realyh, i, height, bheight = 0, solid = 0; realyh = dc_yh; diff --git a/src/r_fps.c b/src/r_fps.c index 9ccba8a7b..c981fa726 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -129,7 +129,7 @@ static void R_SetupFreelook(void) // (lmps, network and use F12...) if (rendermode == render_soft #ifdef HWRENDER - || cv_grshearing.value + || cv_glshearing.value #endif ) { @@ -323,7 +323,7 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out) out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac); #ifdef HWRENDER - if (cv_grmdls.value) + if (cv_glmdls.value) { // pitch roll stuff out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac); diff --git a/src/r_main.c b/src/r_main.c index 75ff41126..1c45d4112 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -31,6 +31,7 @@ #include "p_spec.h" // skyboxmo #include "z_zone.h" #include "m_random.h" // quake camera shake +#include "r_portal.h" #include "doomstat.h" // MAXSPLITSCREENPLAYERS #include "r_fps.h" // Frame interpolation/uncapped #include "tables.h" @@ -66,14 +67,6 @@ boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisibl sector_t *viewsector; player_t *viewplayer; -// PORTALS! -// You can thank and/or curse JTE for these. -UINT8 portalrender; -sector_t *portalcullsector; -portal_pair *portal_base, *portal_cap; -line_t *portalclipline; -INT32 portalclipstart, portalclipend; - fixed_t rendertimefrac; fixed_t rendertimefrac_unpaused; fixed_t renderdeltatics; @@ -194,7 +187,7 @@ consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE|CV_CALL|CV_NO consvar_t cv_lessprecip = {"lessweathereffects", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Precipstuff_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_mobjscaleprecip = {"scaleprecipmobjscale", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, Precipstuff_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grmaxinterpdist = {"gr_maxinterpdist", "Infinite", CV_SAVE, maxinterpdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_maxinterpdist = {"maxinterpdist", "Infinite", CV_SAVE, maxinterpdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ripplewater = {"waterripples", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -325,29 +318,6 @@ PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *restrict node) (~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x))); } -// killough 5/2/98: reformatted -PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) -{ - fixed_t lx = line->v1->x; - fixed_t ly = line->v1->y; - fixed_t ldx = line->v2->x - lx; - fixed_t ldy = line->v2->y - ly; - - if (!ldx) - return x <= lx ? ldy > 0 : ldy < 0; - - if (!ldy) - return y <= ly ? ldx < 0 : ldx > 0; - - x -= lx; - y -= ly; - - // Try to quickly decide by looking at sign bits. - if ((ldy ^ ldx ^ x ^ y) < 0) - return (ldy ^ x) < 0; // (left is negative) - return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x); -} - // // R_PointToAngle // To get a global angle from cartesian coordinates, @@ -1504,112 +1474,30 @@ void R_SetupFrame(player_t *player, boolean skybox) R_InterpolateView(R_UsingFrameInterpolation() ? (demo.playback && demo.freecam) ? rendertimefrac_unpaused : rendertimefrac : FRACUNIT, false); } -#define ANGLED_PORTALS - -static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal) +static void R_PortalFrame(portal_t *portal) { - vertex_t dest_c, start_c; -#ifdef ANGLED_PORTALS - // delta angle - angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); -#endif - - //R_SetupFrame(player, false); viewx = portal->viewx; viewy = portal->viewy; viewz = portal->viewz; viewangle = portal->viewangle; - // newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT); - // newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT); + // viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); + // viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - portalcullsector = dest->frontsector; - viewsector = dest->frontsector; - portalclipline = dest; portalclipstart = portal->start; portalclipend = portal->end; - // Offset the portal view by the linedef centers - - // looking glass center - start_c.x = (start->v1->x + start->v2->x) / 2; - start_c.y = (start->v1->y + start->v2->y) / 2; - - // other side center - dest_c.x = (dest->v1->x + dest->v2->x) / 2; - dest_c.y = (dest->v1->y + dest->v2->y) / 2; - - // Heights! - viewz += dest->frontsector->floorheight - start->frontsector->floorheight; - - // calculate the difference in position and rotation! -#ifdef ANGLED_PORTALS - if (dangle == 0) -#endif - { // the entrance goes straight opposite the exit, so we just need to mess with the offset. - viewx += dest_c.x - start_c.x; - viewy += dest_c.y - start_c.y; - return; - } - -#ifdef ANGLED_PORTALS - viewangle += dangle; - // newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT); - // newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT); - //CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS); - - // ???? + if (portal->clipline != -1) { - fixed_t disttopoint; - angle_t angtopoint; - - disttopoint = R_PointToDist2(start_c.x, start_c.y, newview->x, newview->y); - angtopoint = R_PointToAngle2(start_c.x, start_c.y, newview->x, newview->y); - angtopoint += dangle; - - viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); - } -#endif -} - -void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) -{ - portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL); - INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL); - - portal->line1 = line1; - portal->line2 = line2; - portal->pass = portalrender+1; - portal->next = NULL; - - R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave); - - portal->ceilingclip = ceilingclipsave; - portal->floorclip = floorclipsave; - portal->frontscale = frontscalesave; - - portal->start = x1; - portal->end = x2; - - g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg - - portal->viewx = viewx; - portal->viewy = viewy; - portal->viewz = viewz; - portal->viewangle = viewangle; - - if (!portal_base) - { - portal_base = portal; - portal_cap = portal; + portalclipline = &lines[portal->clipline]; + portalcullsector = portalclipline->frontsector; + viewsector = portalclipline->frontsector; } else { - portal_cap->next = portal; - portal_cap = portal; + portalclipline = NULL; + portalcullsector = NULL; + viewsector = R_PointInSubsector(viewx, viewy)->sector; } } @@ -1625,7 +1513,6 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2) void R_RenderPlayerView(player_t *player) { - portal_pair *portal; const boolean skybox = (skyboxmo[0] && cv_skybox.value); UINT8 i; @@ -1662,8 +1549,7 @@ void R_RenderPlayerView(player_t *player) break; } - portalrender = 0; - portal_base = portal_cap = NULL; + Portal_InitList(); PS_START_TIMING(ps_skyboxtime); if (skybox && skyVisible) @@ -1706,7 +1592,7 @@ void R_RenderPlayerView(player_t *player) else { portalclipstart = 0; - portalclipend = viewwidth-1; + portalclipend = viewwidth; R_ClearClipSegs(); } R_ClearDrawSegs(); @@ -1728,37 +1614,41 @@ void R_RenderPlayerView(player_t *player) ps_numsprites.value.i = numvisiblesprites; - // PORTAL RENDERING PS_START_TIMING(ps_sw_portaltime); - for(portal = portal_base; portal; portal = portal_base) + // Portal rendering. Hijacks the BSP traversal. + if (portal_base) { - // render the portal - CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2); - portalrender = portal->pass; + portal_t *portal; - R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal); + for (portal = portal_base; portal; portal = portal_base) + { + portalrender = portal->pass; // Recursiveness depth. - R_PortalClearClipSegs(portal->start, portal->end); + R_ClearFFloorClips(); - R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale); + // Apply the viewpoint stored for the portal. + R_PortalFrame(portal); - validcount++; + // Hack in the clipsegs to delimit the starting + // clipping for sprites and possibly other similar + // future items. + R_PortalClearClipSegs(portal->start, portal->end); - R_RenderBSPNode((INT32)numnodes - 1); - R_ClipSprites(); - //R_DrawPlanes(); - //R_DrawMasked(); + // Hack in the top/bottom clip values for the window + // that were previously stored. + Portal_ClipApply(portal); - // okay done. free it. - portalcullsector = NULL; // Just in case... - portal_base = portal->next; - Z_Free(portal->ceilingclip); - Z_Free(portal->floorclip); - Z_Free(portal->frontscale); - Z_Free(portal); + // Render the BSP from the new viewpoint, and clip + // any sprites with the new clipsegs and window. + R_RenderBSPNode((INT32)numnodes - 1); + R_ClipSprites(); + + Portal_Remove(portal); + + validcount++; + } } PS_STOP_TIMING(ps_sw_portaltime); - // END PORTAL RENDERING PS_START_TIMING(ps_sw_planetime); R_DrawPlanes(); @@ -1870,7 +1760,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); - CV_RegisterVar(&cv_grmaxinterpdist); + CV_RegisterVar(&cv_maxinterpdist); CV_RegisterVar(&cv_ripplewater); diff --git a/src/r_main.h b/src/r_main.h index 2d7503ea7..cfca7e1a4 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -73,7 +73,18 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // Utility functions. INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *node); -INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line); + +FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) +{ + fixed_t lx = line->v1->x; + fixed_t ly = line->v1->y; + fixed_t ldx = line->v2->x - lx; + fixed_t ldy = line->v2->y - ly; + + // use cross product to determine side quickly + return (INT64)(y - ly) * ldx - (INT64)(x - lx) * ldy > 0; +} + angle_t R_PointToAngle(fixed_t x, fixed_t y); angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); @@ -90,27 +101,6 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y); boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph); void R_GetRenderBlockMapDimensions(fixed_t drawdist, INT32 *xl, INT32 *xh, INT32 *yl, INT32 *yh); - -typedef struct portal_pair -{ - INT32 line1; - INT32 line2; - UINT8 pass; - struct portal_pair *next; - - fixed_t viewx; - fixed_t viewy; - fixed_t viewz; - angle_t viewangle; - - INT32 start; - INT32 end; - INT16 *ceilingclip; - INT16 *floorclip; - fixed_t *frontscale; -} portal_pair; - - // Performance stats extern precise_t ps_prevframetime;// time when previous frame was rendered extern ps_metric_t ps_rendercalltime; @@ -146,7 +136,7 @@ extern consvar_t cv_drawdist, cv_drawdist_precip, cv_lessprecip, cv_mobjscalepre extern consvar_t cv_fov; extern consvar_t cv_skybox; extern consvar_t cv_tailspickup; -extern consvar_t cv_grmaxinterpdist; +extern consvar_t cv_maxinterpdist; extern consvar_t cv_ripplewater; // Called by startup code. diff --git a/src/r_patch.c b/src/r_patch.c index eea97cfbb..c9ff704a7 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -775,11 +775,11 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) #ifdef HWRENDER static patch_t *R_CreateHardwarePatch(patch_t *patch) { - GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - grPatch->rawpatch = patch; - HWR_MakePatch(patch, grPatch, grPatch->mipmap, false); - return (patch_t *)grPatch; + GLPatch_t *glPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); + glPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); + glPatch->rawpatch = patch; + HWR_MakePatch(patch, glPatch, glPatch->mipmap, false); + return (patch_t *)glPatch; } #endif diff --git a/src/r_plane.c b/src/r_plane.c index 208478440..d8d77457f 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -28,6 +28,7 @@ #include "z_zone.h" #include "p_tick.h" #include "r_fps.h" +#include "r_portal.h" // // opening @@ -39,12 +40,6 @@ // good night sweet prince //#define SHITPLANESPARENCY -//SoM: 3/23/2000: Use Boom visplane hashing. -#define VISPLANEHASHBITS 9 -#define VISPLANEHASHMASK ((1<start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + INT32 i; + for (i = 0; i < end-start; i++) + { + *ceil = ceilingclip[start+i]; + ceil++; + *floor = floorclip[start+i]; + floor++; + *scale = frontscale[start+i]; + scale++; + } +} + + +/** Apply the clipping window from a portal. + */ +void Portal_ClipApply (const portal_t* portal) +{ + INT32 i; + INT32 start = portal->start; + INT32 end = portal->end; + INT16 *ceil = portal->ceilingclip; + INT16 *floor = portal->floorclip; + fixed_t *scale = portal->frontscale; + + for (i = 0; i < end-start; i++) + { + ceilingclip[start+i] = *ceil; + ceil++; + floorclip[start+i] = *floor; + floor++; + frontscale[start+i] = *scale; + scale++; + } + + // HACKS FOLLOW + for (i = 0; i < start; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } + for (i = end; i < vid.width; i++) + { + floorclip[i] = -1; + ceilingclip[i] = (INT16)viewheight; + } +} + +static portal_t* Portal_Add (const INT16 x1, const INT16 x2) +{ + portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); + INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL); + + // Linked list. + if (!portal_base) + { + portal_base = portal; + portal_cap = portal; + } + else + { + portal_cap->next = portal; + portal_cap = portal; + } + portal->next = NULL; + + // Store clipping values so they can be restored once the portal is rendered. + portal->ceilingclip = ceilingclipsave; + portal->floorclip = floorclipsave; + portal->frontscale = frontscalesave; + portal->start = x1; + portal->end = x2; + + // Increase recursion level. + portal->pass = portalrender+1; + + return portal; +} + +void Portal_Remove (portal_t* portal) +{ + portalcullsector = NULL; + portal_base = portal->next; + Z_Free(portal->ceilingclip); + Z_Free(portal->floorclip); + Z_Free(portal->frontscale); + Z_Free(portal); +} + +/** Creates a portal out of two lines and a determined screen range. + * + * line1 determines the entrance, and line2 the exit. + * x1 and x2 determine the screen's column bounds. + + * The view's offset from the entry line center is obtained, + * and then rotated&translated to the exit line's center. + * When the portal renders, it will create the illusion of + * the two lines being seamed together. + */ +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2) +{ + portal_t* portal = Portal_Add(x1, x2); + + // Offset the portal view by the linedef centers + line_t* start = &lines[line1]; + line_t* dest = &lines[line2]; + + angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0); + + fixed_t disttopoint; + angle_t angtopoint; + + vertex_t dest_c, start_c; + + // looking glass center + start_c.x = (start->v1->x + start->v2->x) / 2; + start_c.y = (start->v1->y + start->v2->y) / 2; + + // other side center + dest_c.x = (dest->v1->x + dest->v2->x) / 2; + dest_c.y = (dest->v1->y + dest->v2->y) / 2; + + disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy); + angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy); + angtopoint += dangle; + + portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint); + portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight; + portal->viewangle = viewangle + dangle; + + portal->clipline = line2; + + Portal_ClipRange(portal); + + g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg +} + + diff --git a/src/r_portal.h b/src/r_portal.h new file mode 100644 index 000000000..c944f46d0 --- /dev/null +++ b/src/r_portal.h @@ -0,0 +1,57 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2018 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 r_portal.h +/// \brief Software renderer portal struct, functions, linked list extern. + +#ifndef __R_PORTAL__ +#define __R_PORTAL__ + +#include "r_data.h" + + +/** Portal structure. + */ +typedef struct portal_s +{ + struct portal_s *next; + + // Viewport. + fixed_t viewx; + fixed_t viewy; + fixed_t viewz; + angle_t viewangle; + + UINT8 pass; /**< Keeps track of the portal's recursion depth. */ + INT32 clipline; /**< Optional clipline for line-based portals. */ + + // Clipping information. + INT32 start; /**< First horizontal pixel coordinate to draw at. */ + INT32 end; /**< Last horizontal pixel coordinate to draw at. */ + INT16 *ceilingclip; /**< Temporary screen top clipping array. */ + INT16 *floorclip; /**< Temporary screen bottom clipping array. */ + fixed_t *frontscale;/**< Temporary screen bottom clipping array. */ +} portal_t; + +extern portal_t* portal_base; +extern portal_t* portal_cap; +extern UINT8 portalrender; + +extern line_t *portalclipline; +extern sector_t *portalcullsector; +extern INT32 portalclipstart, portalclipend; + +void Portal_InitList (void); +void Portal_Remove (portal_t* portal); +void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); + +void Portal_ClipApply (const portal_t* portal); + +#endif diff --git a/src/r_segs.c b/src/r_segs.c index e89a10780..3b2c7d512 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -15,6 +15,7 @@ #include "r_local.h" #include "r_sky.h" +#include "r_portal.h" #include "r_splats.h" #include "w_wad.h" @@ -275,6 +276,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) { dc_source = (UINT8 *)column + 3; + dc_sourcelength = 0; if (colfunc == wallcolfunc) twosmultipatchfunc(); @@ -1446,6 +1448,7 @@ static void R_RenderSegLoop (void) dc_texturemid = rw_midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); dc_texheight = textureheight[midtexture]>>FRACBITS; + dc_sourcelength = 0; colfunc(); // dont draw anything more for this column, since @@ -1493,6 +1496,7 @@ static void R_RenderSegLoop (void) dc_texturemid = rw_toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); dc_texheight = textureheight[toptexture]>>FRACBITS; + dc_sourcelength = 0; colfunc(); ceilingclip[rw_x] = (INT16)mid; } @@ -1530,6 +1534,7 @@ static void R_RenderSegLoop (void) dc_source = R_GetColumn(bottomtexture, texturecolumn); dc_texheight = textureheight[bottomtexture]>>FRACBITS; + dc_sourcelength = 0; colfunc(); floorclip[rw_x] = (INT16)mid; } @@ -1605,6 +1610,12 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } } +static inline INT32 get_flat_tex (INT32 texnum) +{ + texnum = R_GetTextureNum(texnum); + return textures[texnum]->holes ? 0 : texnum; // R_DrawWallColumn cannot render holey textures +} + // // R_StoreWallRange // A wall segment will be drawn @@ -1862,7 +1873,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { fixed_t texheight; // single sided line - midtexture = R_GetTextureNum(sidedef->midtexture); + midtexture = get_flat_tex(sidedef->midtexture); texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; @@ -2045,15 +2056,15 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // Special case... use offsets from 2nd side but only if it has a texture. side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); + toptexture = get_flat_tex(def->toptexture); if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); + toptexture = get_flat_tex(sidedef->toptexture); texheight = textureheight[toptexture]; } else { - toptexture = R_GetTextureNum(sidedef->toptexture); + toptexture = get_flat_tex(sidedef->toptexture); texheight = textureheight[toptexture]; } if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked @@ -2078,7 +2089,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldlow > worldbottom || worldlowslope > worldbottomslope) // Only if VISIBLE!!! { // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + bottomtexture = get_flat_tex(sidedef->bottomtexture); if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) diff --git a/src/r_state.h b/src/r_state.h index 5234d1d62..b48f0268d 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -94,10 +94,6 @@ extern boolean viewsky, skyVisible; extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player extern sector_t *viewsector; extern player_t *viewplayer; -extern UINT8 portalrender; -extern sector_t *portalcullsector; -extern line_t *portalclipline; -extern INT32 portalclipstart, portalclipend; extern consvar_t cv_allowmlook; extern consvar_t cv_maxportals; diff --git a/src/r_things.c b/src/r_things.c index 7c1b7d9b5..f3c698b9d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -31,6 +31,7 @@ #include "dehacked.h" // get_number (for thok) #include "d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace +#include "r_portal.h" #include "k_kart.h" // SRB2kart #include "p_local.h" // stplyr #ifdef HWRENDER @@ -43,7 +44,7 @@ CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2]; static void R_InitSkins(void); -#define MINZ (FRACUNIT*4) +#define MINZ (FRACUNIT*16) #define BASEYCENTER (BASEVIDHEIGHT/2) typedef struct @@ -522,7 +523,7 @@ void R_InitSprites(void) // it can be is do before loading config for skin cvar possible value R_InitSkins(); - for (i = 0; i < numwadfiles; i++) + for (i = 0; i < numwadfiles; i++) { R_AddSkins((UINT16)i, false); R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps); @@ -583,6 +584,9 @@ void R_DrawMaskedColumn(column_t *column) basetexturemid = dc_texturemid; + if (!column || column == 0) + return; + for (; column->topdelta != 0xff ;) { // calculate unclipped screen coordinates @@ -618,6 +622,7 @@ void R_DrawMaskedColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh > 0 && column->length != 0) { dc_source = (UINT8 *)column + 3; + dc_sourcelength = column->length; dc_texturemid = basetexturemid - (topdelta< 0 && column->length != 0) { dc_source = ZZ_Alloc(column->length); + dc_sourcelength = column->length; for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) *d++ = *s; dc_texturemid = basetexturemid - (topdelta<texturemid; - dc_texheight = 0; + dc_texheight = SHORT(patch->height); frac = vis->startfrac; windowtop = windowbottom = sprbotscreen = INT32_MAX; @@ -808,8 +814,10 @@ static void R_DrawVisSprite(vissprite_t *vis) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->localskin)->highresscale); else if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); + if (this_scale <= 0) this_scale = 1; + if (this_scale != FRACUNIT) { if (!vis->isScaled) @@ -875,12 +883,10 @@ static void R_DrawVisSprite(vissprite_t *vis) } else { - pwidth = SHORT(patch->width); - // Non-paper drawing loop for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) - { - texturecolumn = CLAMP(frac >> FRACBITS, 0, pwidth - 1); + { + texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); localcolfunc (column); @@ -926,7 +932,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = FixedDiv(vis->texturemid, this_scale); - dc_texheight = 0; + dc_texheight = SHORT(patch->height); frac = vis->startfrac; spryscale = vis->scale; @@ -941,7 +947,14 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { - texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1); + texturecolumn = frac>>FRACBITS; + + if (texturecolumn < 0 || texturecolumn >= patch->width) + { + CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n"); + break; + } + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); R_DrawMaskedColumn(column); @@ -1154,17 +1167,17 @@ static void R_ProjectSprite(mobj_t *thing) angle_t pitchnroll = 0; angle_t sliptiderollangle = 0; #endif - + INT32 dist = -1; - if (cv_grmaxinterpdist.value) + if (cv_maxinterpdist.value) dist = R_QuickCamDist(thing->x, thing->y); // uncapped/interpolation interpmobjstate_t interp = {0}; // do interpolation - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value)) { R_InterpolateMobjState(oldthing, rendertimefrac, &interp); } @@ -1256,7 +1269,7 @@ static void R_ProjectSprite(mobj_t *thing) { ang = R_PointToAngle (interp.x, interp.y) - interp.angle; camang = R_PointToAngle (interp.x, interp.y); - + if (mirrored) ang = InvAngle(ang); } @@ -1273,9 +1286,9 @@ static void R_ProjectSprite(mobj_t *thing) // choose a different rotation based on player view //ang = R_PointToAngle (interp.x, interp.y) - interpangle; - if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right + if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot - else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left + else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -1286,7 +1299,7 @@ static void R_ProjectSprite(mobj_t *thing) } I_Assert(lump < max_spritelumps); - + if (thing->localskin && ((skin_t *)thing->localskin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)thing->localskin)->highresscale); else if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) @@ -1299,7 +1312,7 @@ static void R_ProjectSprite(mobj_t *thing) #ifdef ROTSPRITE pitchnroll = 0; // set this to 0, non-paper sprites will affect this value - + if (cv_spriteroll.value) { if (papersprite) @@ -1345,10 +1358,10 @@ static void R_ProjectSprite(mobj_t *thing) if (rotsprite != NULL) { - spr_width = rotsprite->width << FRACBITS; - spr_height = rotsprite->height << FRACBITS; - spr_offset = rotsprite->leftoffset << FRACBITS; - spr_topoffset = rotsprite->topoffset << FRACBITS; + spr_width = SHORT(rotsprite->width) << FRACBITS; + spr_height = SHORT(rotsprite->height) << FRACBITS; + spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS; + spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS; spr_topoffset += FEETADJUST; // flip -> rotate, not rotate -> flip @@ -1366,21 +1379,8 @@ static void R_ProjectSprite(mobj_t *thing) if (spritexscale < 1 || spriteyscale < 1) return; - if (thing->renderflags & RF_ABSOLUTEOFFSETS) - { - spr_offset = interp.spritexoffset; - spr_topoffset = interp.spriteyoffset; - } - else - { - SINT8 flipoffset = 1; - - if ((thing->renderflags & RF_FLIPOFFSETS) && flip) - flipoffset = -1; - - spr_offset += interp.spritexoffset * flipoffset; - spr_topoffset += interp.spriteyoffset * flipoffset; - } + spr_offset += interp.spritexoffset; + spr_topoffset += interp.spriteyoffset; if (flip) offset = spr_offset - spr_width; @@ -1457,7 +1457,7 @@ static void R_ProjectSprite(mobj_t *thing) tx2 += FixedDiv(tx-tx2, div); tz2 = FixedMul(MINZ, this_scale); } - + if ((tx2 / 4) < -(FixedMul(tz2, fovtan)) || (tx / 4) > FixedMul(tz, fovtan)) // too far off the side? return; @@ -1485,7 +1485,7 @@ static void R_ProjectSprite(mobj_t *thing) return; range++; // fencepost problem - + if (range > 32767) { // If the range happens to be too large for fixed_t, @@ -1528,7 +1528,7 @@ static void R_ProjectSprite(mobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0) @@ -1600,7 +1600,6 @@ static void R_ProjectSprite(mobj_t *thing) // store information in a vissprite vis = R_NewVisSprite(); - vis->renderflags = thing->renderflags; vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; vis->scale = yscale; //<mobj = thing; // Easy access! Tails 06-07-2002 - vis->x1 = x1 < 0 ? 0 : x1; - vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; - - // PORTAL SEMI-CLIPPING - if (portalrender && portalclipline) - { - if (vis->x1 < portalclipstart) - vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; - } + vis->x1 = x1 < portalclipstart ? portalclipstart : x1; + vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; vis->sector = thing->subsector->sector; vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); @@ -1749,7 +1739,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) INT32 dist = 1; - if (cv_grmaxinterpdist.value) + if (cv_maxinterpdist.value) dist = R_QuickCamDist(thing->x, thing->y); // uncapped/interpolation @@ -1762,7 +1752,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) } // do interpolation - if (R_UsingFrameInterpolation() && !paused && (!cv_grmaxinterpdist.value || dist < cv_grmaxinterpdist.value)) + if (R_UsingFrameInterpolation() && !paused && (!cv_maxinterpdist.value || dist < cv_maxinterpdist.value)) { R_InterpolatePrecipMobjState(thing, rendertimefrac, &interp); } @@ -1841,7 +1831,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // PORTAL SPRITE CLIPPING if (portalrender && portalclipline) { - if (x2 < portalclipstart || x1 > portalclipend) + if (x2 < portalclipstart || x1 >= portalclipend) return; if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0) @@ -1875,17 +1865,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->scalestep = 0; vis->paperdistance = 0; - vis->x1 = x1 < 0 ? 0 : x1; - vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; - - // PORTAL SEMI-CLIPPING - if (portalrender && portalclipline) - { - if (vis->x1 < portalclipstart) - vis->x1 = portalclipstart; - if (vis->x2 > portalclipend) - vis->x2 = portalclipend; - } + vis->x1 = x1 < portalclipstart ? portalclipstart : x1; + vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2; vis->xscale = xscale; //SoM: 4/17/2000 vis->sector = thing->subsector->sector; @@ -2389,7 +2370,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) node->thickseg = NULL; node->ffloor = NULL; node->sprite = NULL; - + ps_numdrawnodes.value.i++; return node; } @@ -2666,7 +2647,7 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2) if (spr->cliptop[x] == -2) spr->cliptop[x] = -1; } - + // Check if it'll be visible // Not done for floorsprites. if (cv_spriteclip.value) @@ -2741,7 +2722,7 @@ void R_ClipSprites(void) for (; clippedvissprites < visspritecount; clippedvissprites++) { vissprite_t *spr = R_GetVisSprite(clippedvissprites); - + if (cv_spriteclip.value && (spr->szt > vid.height || spr->sz < 0)) { @@ -2766,7 +2747,7 @@ void R_ClipSprites(void) } R_ClipVisSprite(spr, spr->x1, spr->x2); - + if ((spr->cut & SC_NOTVISIBLE) == 0) numvisiblesprites++; } @@ -2783,10 +2764,10 @@ boolean R_ThingVisible (mobj_t *thing) if (splitscreen) { - if ((viewssnum == 0 && (thing->renderflags & MFE_DRAWONLYFORP1)) - || (viewssnum == 1 && (thing->renderflags & MFE_DRAWONLYFORP2)) - || (viewssnum == 2 && (thing->renderflags & MFE_DRAWONLYFORP2)) - || (viewssnum == 3 && (thing->renderflags & MFE_DRAWONLYFORP4))) + if ((viewssnum == 0 && (thing->eflags & MFE_DRAWONLYFORP1)) + || (viewssnum == 1 && (thing->eflags & MFE_DRAWONLYFORP2)) + || (viewssnum == 2 && (thing->eflags & MFE_DRAWONLYFORP2)) + || (viewssnum == 3 && (thing->eflags & MFE_DRAWONLYFORP4))) return true; } @@ -3293,7 +3274,7 @@ static int skinSortFunc(const void *a, const void *b) //tbh i have no clue what void sortSkinGrid(void) { //CONS_Printf("Sorting skin list (%d)...\n", cv_skinselectgridsort.value); - qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc); + qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc); } // @@ -3319,12 +3300,12 @@ void R_AddSkins(UINT16 wadnum, boolean local) // advance by default lastlump = lump + 1; - if (numskins >= MAXSKINS) + if (!local && numskins >= MAXSKINS) { CONS_Alert(CONS_WARNING, M_GetText("Unable to add skin, too many characters are loaded (%d maximum)\n"), MAXSKINS); continue; // so we know how many skins couldn't be added } - if (numlocalskins >= MAXLOCALSKINS) + if (local && numlocalskins >= MAXLOCALSKINS) { CONS_Alert(CONS_WARNING, M_GetText("Unable to add localskin, too many localskins are loaded (%d maximum)\n"), MAXLOCALSKINS); continue; // so we know how many skins couldn't be added @@ -3577,7 +3558,7 @@ next_token: Forceskin_cons_t[numskins+1].value = numskins; Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name; } - + skin->localskin = local; // so we dont have to guess @@ -3604,7 +3585,7 @@ next_token: CONS_Debug(DBG_SETUP, M_GetText("Incremented %d, %d to %d\n"), skin->kartspeed, skin->kartweight, skinstatscount[skin->kartspeed - 1][skin->kartweight - 1]); skinsorted[numskins] = numskins; } - + allskins[numallskins] = ( (local) ? localskins : skins )[( (local) ? numlocalskins : numskins )]; local ? numlocalskins++ : numskins++; diff --git a/src/r_things.h b/src/r_things.h index 0e99c490c..898cc7ecd 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -55,6 +55,7 @@ extern fixed_t sprtopscreen; extern fixed_t sprbotscreen; extern fixed_t windowtop; extern fixed_t windowbottom; +extern INT32 lengthcol; fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope); diff --git a/src/screen.c b/src/screen.c index 22ce5e8f1..e1f6fe93e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -82,7 +82,8 @@ static void SCR_ChangeFullscreen (void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_accuratefps = {"accuratefpscounter", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t accuratefps_cons_t[] = {{0, "Inaccurate"}, {1, "Accurate"}, {0, NULL}}; +consvar_t cv_accuratefps = {"fpssampling", "1", CV_SAVE, accuratefps_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // ========================================================================= // SCREEN VARIABLES @@ -354,11 +355,7 @@ void SCR_ChangeFullscreen(void) boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { - return - ( width % BASEVIDWIDTH == 0 - && height % BASEVIDHEIGHT == 0 - && width / BASEVIDWIDTH == height / BASEVIDHEIGHT - ); + return (width % BASEVIDWIDTH == 0 && height % BASEVIDHEIGHT == 0 && width / BASEVIDWIDTH == height / BASEVIDHEIGHT); } double averageFPS = 0.0f; @@ -411,7 +408,6 @@ void SCR_CalculateFPS(void) if (total_frame_time >= MAX_FRAME_TIME) { static int sampleIndex = 0; - int i; fps_samples[sampleIndex] = frameElapsed; @@ -420,7 +416,7 @@ void SCR_CalculateFPS(void) sampleIndex = 0; averageFPS = 0.0; - for (i = 0; i < NUM_FPS_SAMPLES; i++) + for (int i = 0; i < NUM_FPS_SAMPLES; i++) { averageFPS += fps_samples[i]; } @@ -458,7 +454,7 @@ void SCR_DisplayTicRate(void) return; // new kart counter - if ((cv_ticrate.value == 1) || (cv_ticrate.value == 2)) + if (cv_ticrate.value == 1 || cv_ticrate.value == 2) { // draw "FPS" if (cv_ticrate.value == 1) @@ -492,7 +488,7 @@ void SCR_DisplayTicRate(void) // draw our actual framerate V_DrawPingNum(x, 190, fpsflags, fps, ticcntcolor); } - else if ((cv_ticrate.value == 3)||(cv_ticrate.value == 4)) // kart v1.0/srb2 counter + else if (cv_ticrate.value == 3 || cv_ticrate.value == 4) // kart v1.0/srb2 counter { if (fps > (benchmark - 5)) ticcntcolor2 = V_GREENMAP; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 241f09e05..73a1f992d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -758,7 +758,7 @@ static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which) #ifdef USE_FBO_OGL void I_DownSample(void) { - if (!cv_grframebuffer.value || !supportFBO) //no sense to do this crap if we cant benefit from it + if (!cv_glframebuffer.value || !supportFBO) //no sense to do this crap if we cant benefit from it { downsample = false; return; @@ -781,8 +781,11 @@ void I_DownSample(void) } else { - downsample = false; // its not so no need to do crap - RefreshOGLSDLSurface(); + if (downsample == true) + { + downsample = false; // its not so no need to do crap + RefreshOGLSDLSurface(); + } } } diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 4adc3dae8..2b94669ed 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -68,10 +68,19 @@ PFNglGetIntegerv pglGetIntegerv; PFNglGetString pglGetString; #endif -#if defined (__unix__) #ifdef USE_FBO_OGL +#if defined (__unix__) static boolean isnvidiagpu = false; #endif + +boolean UseScreenFBO(void) +{ + return ((supportFBO && cv_glframebuffer.value && downsample) +#if defined (__unix__) + || (supportFBO && isnvidiagpu && xwaylandcrap) +#endif + ); +} #endif /** \brief SDL video display surface @@ -112,10 +121,11 @@ boolean LoadGL(void) \return if true, changed video mode */ +static boolean first_init = false; + boolean OglSdlSurface(INT32 w, INT32 h) { INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; - static boolean first_init = false; const char *gllogdir = NULL; oglflags = 0; @@ -171,7 +181,7 @@ boolean OglSdlSurface(INT32 w, INT32 h) else maximumAnisotropy = 1; - granisotropicmode_cons_t[1].value = maximumAnisotropy; + glanisotropicmode_cons_t[1].value = maximumAnisotropy; #if defined (__unix__) #ifdef USE_FBO_OGL @@ -180,7 +190,6 @@ boolean OglSdlSurface(INT32 w, INT32 h) #endif #endif } - first_init = true; SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0); @@ -202,21 +211,25 @@ boolean OglSdlSurface(INT32 w, INT32 h) pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); #ifdef USE_FBO_OGL - RenderToFramebuffer = ((FrameBufferEnabled && supportFBO && downsample) -#if defined (__unix__) - || (isnvidiagpu && xwaylandcrap) -#endif - ); - if (RenderToFramebuffer) + if (!supportFBO) + { + if (cv_glframebuffer.value) + CV_SetValue(&cv_glframebuffer, 0); + } + + if (UseScreenFBO()) GLFramebuffer_Enable(); else GLFramebuffer_Disable(); #endif - HWR_Startup(); + if (!first_init) + HWR_Startup(); textureformatGL = cbpp > 16 ? GL_RGBA : GL_RGB5_A1; + first_init = true; + return true; } @@ -241,20 +254,14 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_MakeScreenFinalTexture(); #ifdef USE_FBO_OGL - RenderToFramebuffer = ((FrameBufferEnabled && supportFBO && downsample) -#if defined (__unix__) - || (isnvidiagpu && xwaylandcrap) -#endif - ); - - if (RenderToFramebuffer) + if (UseScreenFBO()) GLFramebuffer_Unbind(); #endif HWR_DrawScreenFinalTexture(sdlw, sdlh); #ifdef USE_FBO_OGL - if (RenderToFramebuffer) + if (UseScreenFBO()) GLFramebuffer_Enable(); #endif diff --git a/src/st_stuff.c b/src/st_stuff.c index 8b15e711a..de89fa6e3 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -15,6 +15,7 @@ #include "doomdef.h" #include "g_game.h" +#include "g_input.h" #include "r_local.h" #include "p_local.h" #include "f_finale.h" @@ -773,10 +774,33 @@ static void ST_overlayDrawer(void) } else { - V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -")); - V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt); - V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float")); - V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink")); + if (cv_showdirectorhud.value) + { + V_DrawString(2, BASEVIDHEIGHT-50, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -")); + V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt); + V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float")); + V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink")); + + char directortoggle[32] = {0}; + const char *item1 = gamecontrol[gc_director][0] != 0 ? G_KeynumToString(gamecontrol[gc_director][0]) : NULL; + const char *item2 = gamecontrol[gc_director][1] != 0 ? G_KeynumToString(gamecontrol[gc_director][1]) : NULL; + + if (item1 != NULL && item2 != NULL) + snprintf(directortoggle, 32, "%s/%s - Toggle Director", item1, item2); + else + snprintf(directortoggle, 32, "%s - Toggle Director", item1 != NULL ? item1 : item2 != NULL ? item2 : "Not Bound"); + + V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, directortoggle); + + directortextactive = true; + } + else + { + V_DrawString(2, BASEVIDHEIGHT-40, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -")); + V_DrawString(2, BASEVIDHEIGHT-30, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, itemtxt); + V_DrawString(2, BASEVIDHEIGHT-20, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Accelerate - Float")); + V_DrawString(2, BASEVIDHEIGHT-10, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_HUDTRANSHALF, M_GetText("Brake - Sink")); + } } } } diff --git a/src/v_video.c b/src/v_video.c index fb5fb7a90..d2604b5e8 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1112,7 +1112,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) if (x >= vid.width || y >= vid.height) return; // off the screen - + if (x < 0) { w += x; @@ -1126,7 +1126,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) if (w <= 0 || h <= 0) return; // zero width/height wouldn't draw anything - + if (x + w > vid.width) w = vid.width-x; if (y + h > vid.height) @@ -1149,7 +1149,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) } c &= 255; - + if (alphalevel) { const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)< 3 || view > splitscreen) return; + if (!player->postimgflags) + return; + if ((view == 1 && splitscreen == 1) || view >= 2) yoffset = viewheight; else @@ -3217,10 +3221,11 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) else xoffset = 0; - if (type == postimg_water) + UINT8 *tmpscr = screens[4]; + UINT8 *srcscr = screens[0]; + + if (player->postimgflags & POSTIMG_WATER) { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; INT32 y; // Set disStart to a range from 0 to FINEANGLE, incrementing by 128 per tic angle_t disStart = (((leveltime-1)*128) + (rendertimefrac / (FRACUNIT/128))) & FINEMASK; @@ -3257,29 +3262,30 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) } /* - Unoptimized version - for (x = 0; x < vid.width*vid.bpp; x++) - { - newpix = (x + sine); + Unoptimized version + for (x = 0; x < vid.width*vid.bpp; x++) + { + newpix = (x + sine); - if (newpix < 0) - newpix = 0; - else if (newpix >= vid.width) - newpix = vid.width-1; + if (newpix < 0) + newpix = 0; + else if (newpix >= vid.width) + newpix = vid.width-1; + + tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]); + }*/ - tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]); - }*/ disStart += 22;//the offset into the displacement map, increment each game loop disStart &= FINEMASK; //clip it to FINEMASK } - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); + UINT8 *tmp = tmpscr; + tmpscr = srcscr; + srcscr = tmp; } - else if (type == postimg_motion) // Motion Blur! - { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; + + /*if (player->postimgflags & POSTIMG_MOTION) // Motion Blur! + { INT32 x, y; // TODO: Add a postimg_param so that we can pick the translucency level... @@ -3288,30 +3294,12 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) for (y = yoffset; y < yoffset+viewheight; y++) { for (x = xoffset; x < xoffset+viewwidth; x++) - { - tmpscr[y*vid.width + x] - = colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))]; - } + tmpscr[y*vid.width + x] = colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))]; } - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); - } - else if (type == postimg_flip) // Flip the screen upside-down - { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; - INT32 y, y2; + }*/ - for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--) - M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth); - - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); - } - else if (type == postimg_heat) // Heat wave + if (player->postimgflags & POSTIMG_HEAT) // Heat wave { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; INT32 y; // Make sure table is built @@ -3352,40 +3340,53 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) heatindex[view] %= vid.height; } - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); + UINT8 *tmp = tmpscr; + tmpscr = srcscr; + srcscr = tmp; } - else if (type == postimg_mirror) // Flip the screen on the x axis + + if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR)) // Flip the screen upside-down + { + INT32 y, y2; + + for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--) + M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth); + + UINT8 *tmp = tmpscr; + tmpscr = srcscr; + srcscr = tmp; + } + else if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP)) // Flip the screen on the x axis { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; INT32 y, x, x2; for (y = yoffset; y < yoffset+viewheight; y++) - { for (x = xoffset, x2 = xoffset+((viewwidth*vid.bpp)-1); x < xoffset+(viewwidth*vid.bpp); x++, x2--) tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x]; - } - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); + UINT8 *tmp = tmpscr; + tmpscr = srcscr; + srcscr = tmp; } - else if (type == postimg_mirrorflip) // Flip the screen upside-down and on the x axis + else if ((player->postimgflags & POSTIMG_MIRROR) && (player->postimgflags & POSTIMG_FLIP)) // Flip the screen upside-down and on the x axis { - UINT8 *tmpscr = screens[4]; - UINT8 *srcscr = screens[0]; INT32 y, x; for (y = yoffset; y < yoffset + viewheight; y++) for (x = xoffset; x < xoffset + viewwidth; x++) tmpscr[((yoffset + viewheight - 1 - y) * vid.width) + xoffset + viewwidth - (x - xoffset) - 1] = srcscr[(y * vid.width) + x]; - VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, - viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); + UINT8 *tmp = tmpscr; + tmpscr = srcscr; + srcscr = tmp; } + + VID_BlitLinearScreen(srcscr+vid.width*vid.bpp*yoffset+xoffset, tmpscr+vid.width*vid.bpp*yoffset+xoffset, + viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); #endif } + // Taken from my videos-in-SRB2 project // Generates a color look-up table // which has up to 64 colors at each channel diff --git a/src/v_video.h b/src/v_video.h index bc1e8c546..a06760215 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -251,7 +251,9 @@ INT32 V_SubStringLengthToFit(const char *string, INT32 width, INT32 option); char V_GetSkincolorChar(INT32 color); -void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param); +typedef struct player_s player_t; + +void V_DoPostProcessor(INT32 view, player_t *player, INT32 param); void V_DrawPatchFill(patch_t *pat); diff --git a/src/w_wad.c b/src/w_wad.c index a24686e28..ad506240d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1699,7 +1699,7 @@ void *W_CacheLumpName(const char *name, INT32 tag) #ifdef HWRENDER FUNCINLINE static ATTRINLINE void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { - GLPatch_t *grPatch; + GLPatch_t *glPatch; if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); @@ -1707,29 +1707,29 @@ FUNCINLINE static ATTRINLINE void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, if (!TestValidLump(wad, lump)) return NULL; - grPatch = HWR_GetCachedGLPatchPwad(wad, lump); + glPatch = HWR_GetCachedGLPatchPwad(wad, lump); - if (grPatch->mipmap->data) + if (glPatch->mipmap->data) { if (tag == PU_CACHE) tag = PU_HWRCACHE; - Z_ChangeTag(grPatch->mipmap->data, tag); + Z_ChangeTag(glPatch->mipmap->data, tag); } else { patch_t *ptr = NULL; - // Only load the patch if we haven't initialised the grPatch yet - if (grPatch->mipmap->width == 0) - ptr = W_CacheLumpNumPwad(grPatch->wadnum, grPatch->lumpnum, PU_STATIC); + // Only load the patch if we haven't initialised the glPatch yet + if (glPatch->mipmap->width == 0) + ptr = W_CacheLumpNumPwad(glPatch->wadnum, glPatch->lumpnum, PU_STATIC); // Run HWR_MakePatch in all cases, to recalculate some things - HWR_MakePatch(ptr, grPatch, grPatch->mipmap, false); + HWR_MakePatch(ptr, glPatch, glPatch->mipmap, false); Z_Free(ptr); } // return GLPatch_t, which can be casted to (patch_t) with valid patch header info - return (void *)grPatch; + return (void *)glPatch; } void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag) @@ -2120,6 +2120,225 @@ int W_VerifyNMUSlumps(const char *filename) return W_VerifyFile(filename, NMUSlist, false); } +static int W_NameStartsWith(const char *name, lumpchecklist_t *checklist) +{ + size_t j; + for (j = 0; checklist[j].len && checklist[j].name; ++j) + { + if (strncasecmp(name, checklist[j].name, checklist[j].len) == 0) + return true; + } + return false; +} + +// Checks if file contains at least one lump which name starts with one of strings in checklist +static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist) +{ + size_t i, j; + // if we're here it's a WAD file + wadinfo_t header; + filelump_t lumpinfo; + + // read the header + if (fread(&header, 1, sizeof header, fp) == sizeof header + && header.numlumps < INT16_MAX + && strncmp(header.identification, "ZWAD", 4) + && strncmp(header.identification, "IWAD", 4) + && strncmp(header.identification, "PWAD", 4) + && strncmp(header.identification, "SDLL", 4)) + { + return true; + } + + header.numlumps = LONG(header.numlumps); + header.infotableofs = LONG(header.infotableofs); + + // let seek to the lumpinfo list + if (fseek(fp, header.infotableofs, SEEK_SET) == -1) + return true; + + for (i = 0; i < header.numlumps; i++) + { + // fill in lumpinfo for this wad file directory + if (fread(&lumpinfo, sizeof (lumpinfo), 1 , fp) != 1) + return -1; + + lumpinfo.filepos = LONG(lumpinfo.filepos); + lumpinfo.size = LONG(lumpinfo.size); + + if (lumpinfo.size == 0) + continue; + + for (j = 0; j < NUMSPRITES; j++) + if (!strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites + continue; + + if (W_NameStartsWith(lumpinfo.name, checklist)) + return true; + } + return false; +} + +static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist) +{ + zend_t zend; + zlentry_t zlentry; + + long file_size;/* size of zip file */ + long data_size;/* size of data inside zip file */ + + UINT16 numlumps; + size_t i; + + char pat_central[] = {0x50, 0x4b, 0x01, 0x02, 0x00}; + char pat_end[] = {0x50, 0x4b, 0x05, 0x06, 0x00}; + + char lumpname[9]; + + // Haha the ResGetLumpsZip function doesn't + // check for file errors, so neither will I. + + // Central directory bullshit + + fseek(fp, 0, SEEK_END); + file_size = ftell(fp); + + if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536)))) + return true; + + fseek(fp, -4, SEEK_CUR); + if (fread(&zend, 1, sizeof zend, fp) < sizeof zend) + return true; + + data_size = sizeof zend; + + numlumps = SHORT(zend.entries); + + fseek(fp, LONG(zend.cdiroffset), SEEK_SET); + + char *cdir = (char*)(malloc(LONG(zend.cdirsize))); + + if (fread(cdir, 1, LONG(zend.cdirsize), fp) < (UINT32)(LONG(zend.cdirsize))) + return true; + + size_t offset = 0; + + for (i = 0; i < numlumps; i++) + { + zentry_t *zentry = (zentry_t*)(cdir + offset); + char* fullname; + char* trimname; + char* dotpos; + + if (memcmp(zentry->signature, pat_central, 4) != 0) + return false; + + fullname = (char*)(malloc(SHORT(zentry->namelen) + 1)); + strlcpy(fullname, (char*)(zentry + 1), SHORT(zentry->namelen) + 1); + + // Strip away file address and extension for the 8char name. + if ((trimname = strrchr(fullname, '/')) != 0) + trimname++; + else + trimname = fullname; // Care taken for root files. + + if (*trimname) // Ignore directories, well kinda + { + if ((dotpos = strrchr(trimname, '.')) == 0) + dotpos = fullname + strlen(fullname); // Watch for files without extension. + + memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary? + strncpy(lumpname, trimname, min(8, dotpos - trimname)); + + if (W_NameStartsWith(lumpname, checklist)) + return true; + } + + if (W_NameStartsWith(fullname, checklist)) + return true; + + free(fullname); + + offset += sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen); + + data_size += + sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen); + + if (fseek(fp, LONG(zentry->offset), SEEK_SET) != 0) + return false; + + if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t)) + return false; + + data_size += + sizeof zlentry + SHORT(zlentry.namelen) + SHORT(zlentry.xtralen) + LONG(zlentry.compsize); + } + + free(cdir); + + if (data_size < file_size) + { + const char * error = "ZIP file has holes (%ld extra bytes)\n"; + CONS_Alert(CONS_ERROR, error, (file_size - data_size)); + return -1; + } + else if (data_size > file_size) + { + const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n"; + CONS_Alert(CONS_ERROR, error, (data_size - file_size)); + return -1; + } + else + { + return false; + } +} + +static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist) +{ + FILE *handle; + int contains = false; + + if (!checklist) + I_Error("No checklist for %s\n", filename); + // open wad file + if ((handle = W_OpenWadFile(&filename, false)) == NULL) + return -1; + + if (stricmp(&filename[strlen(filename) - 4], ".pk3") == 0) + contains = W_CheckPK3Contains(handle, checklist); + else + { + // detect wad file by the absence of the other supported extensions + if (stricmp(&filename[strlen(filename) - 4], ".soc") + && stricmp(&filename[strlen(filename) - 4], ".lua")) + { + contains = W_CheckWADContains(handle, checklist); + } + } + fclose(handle); + return contains; +} + +int W_CheckPostLoadList(const char *filename) +{ + static lumpchecklist_t postloadlist[] = + { + {"Lua/", 4}, + {"SOC/", 4}, + {"Skins/", 6}, + {"S_SKIN", 6}, + {"LUA_", 4}, + {"SOC_", 4}, + {"MAINCFG", 7}, + {"OBJCTCFG", 8}, + {"MAP", 3}, + + {NULL, 0}, + }; + return W_CheckFileContains(filename, postloadlist); +} + /** \brief Generates a virtual resource used for level data loading. * * \param lumpnum_t reference diff --git a/src/w_wad.h b/src/w_wad.h index 4e84ea0e4..fd2038db2 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -226,4 +226,6 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); int W_VerifyNMUSlumps(const char *filename); +int W_CheckPostLoadList(const char *filename); + #endif // __W_WAD__ diff --git a/src/y_inter.c b/src/y_inter.c index b62566e0a..75a705e60 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -388,7 +388,7 @@ void Y_IntermissionDrawer(void) if (cv_betainterscreen.value == 1 #ifdef HWRENDER - || (rendermode == render_opengl && cv_grscreentextures.value != 2) // use the neato kart bg for intermission on disabled screen textures + || (rendermode == render_opengl && cv_glscreentextures.value != 2) // use the neato kart bg for intermission on disabled screen textures #endif ) V_DrawPatchFill(bgtile); // use the neato kart bg for intermission on disabled screen textures