// // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // #include #include #include "templates.h" #include "i_system.h" #include "w_wad.h" #include "doomdef.h" #include "doomstat.h" #include "r_sky.h" #include "stats.h" #include "v_video.h" #include "a_sharedglobal.h" #include "c_console.h" #include "c_dispatch.h" #include "cmdlib.h" #include "d_net.h" #include "g_level.h" #include "r_utility.h" #include "d_player.h" #include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_viewport.h" CVAR(Bool, r_shadercolormaps, true, CVAR_ARCHIVE) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) namespace swrenderer { double r_BaseVisibility; double r_WallVisibility; double r_FloorVisibility; float r_TiltVisibility; double r_SpriteVisibility; int fixedlightlev; FSWColormap *fixedcolormap; FSpecialColormap *realfixedcolormap; namespace { double CurrentVisibility = 8.f; double MaxVisForWall; double MaxVisForFloor; } // Changes how rapidly things get dark with distance void R_SetVisibility(double vis) { // Allow negative visibilities, just for novelty's sake vis = clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio) CurrentVisibility = vis; if (FocalTangent == 0 || FocalLengthY == 0) { // If r_visibility is called before the renderer is all set up, don't // divide by zero. This will be called again later, and the proper // values can be initialized then. return; } r_BaseVisibility = vis; MaxVisForWall = (InvZtoScale * (SCREENWIDTH*r_Yaspect) / (viewwidth*SCREENHEIGHT * FocalTangent)); MaxVisForWall = 32767.0 / MaxVisForWall; MaxVisForFloor = 32767.0 / (viewheight >> 2) * FocalLengthY / 160; // Prevent overflow on walls if (r_BaseVisibility < 0 && r_BaseVisibility < -MaxVisForWall) r_WallVisibility = -MaxVisForWall; else if (r_BaseVisibility > 0 && r_BaseVisibility > MaxVisForWall) r_WallVisibility = MaxVisForWall; else r_WallVisibility = r_BaseVisibility; r_WallVisibility = (InvZtoScale * SCREENWIDTH*AspectBaseHeight(WidescreenRatio) / (viewwidth*SCREENHEIGHT * 3)) * (r_WallVisibility * FocalTangent); // Prevent overflow on floors/ceilings. Note that the calculation of // MaxVisForFloor means that planes less than two units from the player's // view could still overflow, but there is no way to totally eliminate // that while still using fixed point math. if (r_BaseVisibility < 0 && r_BaseVisibility < -MaxVisForFloor) r_FloorVisibility = -MaxVisForFloor; else if (r_BaseVisibility > 0 && r_BaseVisibility > MaxVisForFloor) r_FloorVisibility = MaxVisForFloor; else r_FloorVisibility = r_BaseVisibility; r_FloorVisibility = 160.0 * r_FloorVisibility / FocalLengthY; r_TiltVisibility = float(vis * FocalTangent * (16.f * 320.f) / viewwidth); r_SpriteVisibility = r_WallVisibility; } double R_GetVisibility() { return CurrentVisibility; } void R_SetupColormap(AActor *actor) { player_t *player = actor->player; if (camera && camera->player != 0) player = camera->player; realfixedcolormap = NULL; fixedcolormap = NULL; fixedlightlev = -1; if (player != NULL && camera == player->mo) { if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) { realfixedcolormap = &SpecialColormaps[player->fixedcolormap]; if (RenderTarget == screen && (r_swtruecolor || ((DFrameBuffer *)screen->Accel2D && r_shadercolormaps))) { // Render everything fullbright. The copy to video memory will // apply the special colormap, so it won't be restricted to the // palette. fixedcolormap = &realcolormaps; } else { fixedcolormap = &SpecialColormaps[player->fixedcolormap]; } } else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) { fixedlightlev = player->fixedlightlevel * 256; // [SP] Emulate GZDoom's light-amp goggles. if (r_fullbrightignoresectorcolor && fixedlightlev >= 0) { fixedcolormap = &FullNormalLight; } } } // [RH] Inverse light for shooting the Sigil if (fixedcolormap == NULL && extralight == INT_MIN) { fixedcolormap = &SpecialColormaps[INVERSECOLORMAP]; extralight = 0; } } // Controls how quickly light ramps across a 1/z range. Set this, and it // sets all the r_*Visibility variables (except r_SkyVisibilily, which is // currently unused). CCMD(r_visibility) { if (argv.argc() < 2) { Printf("Visibility is %g\n", R_GetVisibility()); } else if (!netgame) { R_SetVisibility(atof(argv[1])); } else { Printf("Visibility cannot be changed in net games.\n"); } } }