1 // Emacs style mode select	 -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // $Log:$
18 //
19 // DESCRIPTION:
20 //	Sky rendering. The DOOM sky is a texture map like any
21 //	wall, wrapping around. 1024 columns equal 360 degrees.
22 //	The default sky map is 256 columns and repeats 4 times
23 //	on a 320 screen.
24 //
25 //
26 //-----------------------------------------------------------------------------
27 
28 
29 // Needed for FRACUNIT.
30 #include "m_fixed.h"
31 #include "c_cvars.h"
32 #include "g_level.h"
33 #include "r_sky.h"
34 #include "r_utility.h"
35 #include "v_text.h"
36 #include "gi.h"
37 
38 //
39 // sky mapping
40 //
41 FTextureID	skyflatnum;
42 FTextureID	sky1texture,	sky2texture;
43 fixed_t		skytexturemid;
44 fixed_t		skyscale;
45 fixed_t		skyiscale;
46 bool		skystretch;
47 
48 fixed_t		sky1cyl,		sky2cyl;
49 double		sky1pos,		sky2pos;
50 
51 // [RH] Stretch sky texture if not taller than 128 pixels?
CUSTOM_CVAR(Bool,r_stretchsky,true,CVAR_ARCHIVE)52 CUSTOM_CVAR (Bool, r_stretchsky, true, CVAR_ARCHIVE)
53 {
54 	R_InitSkyMap ();
55 }
56 
57 fixed_t			freelookviewheight;
58 
59 //==========================================================================
60 //
61 // R_InitSkyMap
62 //
63 // Called whenever the view size changes.
64 //
65 //==========================================================================
66 
R_InitSkyMap()67 void R_InitSkyMap ()
68 {
69 	int skyheight;
70 	FTexture *skytex1, *skytex2;
71 
72 	skytex1 = TexMan(sky1texture, true);
73 	skytex2 = TexMan(sky2texture, true);
74 
75 	if (skytex1 == NULL)
76 		return;
77 
78 	if ((level.flags & LEVEL_DOUBLESKY) && skytex1->GetHeight() != skytex2->GetHeight())
79 	{
80 		Printf (TEXTCOLOR_BOLD "Both sky textures must be the same height." TEXTCOLOR_NORMAL "\n");
81 		sky2texture = sky1texture;
82 	}
83 
84 	// There are various combinations for sky rendering depending on how tall the sky is:
85 	//        h <  128: Unstretched and tiled, centered on horizon
86 	// 128 <= h <  200: Can possibly be stretched. When unstretched, the baseline is
87 	//                  28 rows below the horizon so that the top of the texture
88 	//                  aligns with the top of the screen when looking straight ahead.
89 	//                  When stretched, it is scaled to 228 pixels with the baseline
90 	//                  in the same location as an unstretched 128-tall sky, so the top
91 	//					of the texture aligns with the top of the screen when looking
92 	//                  fully up.
93 	//        h == 200: Unstretched, baseline is on horizon, and top is at the top of
94 	//                  the screen when looking fully up.
95 	//        h >  200: Unstretched, but the baseline is shifted down so that the top
96 	//                  of the texture is at the top of the screen when looking fully up.
97 	skyheight = skytex1->GetScaledHeight();
98 	skystretch = false;
99 	skytexturemid = 0;
100 	if (skyheight >= 128 && skyheight < 200)
101 	{
102 		skystretch = (r_stretchsky
103 					  && skyheight >= 128
104 					  && level.IsFreelookAllowed()
105 					  && !(level.flags & LEVEL_FORCENOSKYSTRETCH)) ? 1 : 0;
106 		skytexturemid = -28*FRACUNIT;
107 	}
108 	else if (skyheight > 200)
109 	{
110 		skytexturemid = FixedMul((200 - skyheight) << FRACBITS, skytex1->yScale);
111 	}
112 
113 	if (viewwidth != 0 && viewheight != 0)
114 	{
115 		skyiscale = (r_Yaspect*FRACUNIT) / ((freelookviewheight * viewwidth) / viewwidth);
116 		skyscale = (((freelookviewheight * viewwidth) / viewwidth) << FRACBITS) /
117 					(r_Yaspect);
118 
119 		skyiscale = Scale (skyiscale, FieldOfView, 2048);
120 		skyscale = Scale (skyscale, 2048, FieldOfView);
121 	}
122 
123 	if (skystretch)
124 	{
125 		skyscale = Scale(skyscale, SKYSTRETCH_HEIGHT, skyheight);
126 		skyiscale = Scale(skyiscale, skyheight, SKYSTRETCH_HEIGHT);
127 		skytexturemid = Scale(skytexturemid, skyheight, SKYSTRETCH_HEIGHT);
128 	}
129 
130 	// The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees,
131 	// giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024,
132 	// we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of
133 	// the texture as the cylinder's circumfrence.
134 	sky1cyl = MAX(skytex1->GetWidth(), skytex1->xScale >> (16 - 10));
135 	sky2cyl = MAX(skytex2->GetWidth(), skytex2->xScale >> (16 - 10));
136 }
137 
138 
139 //==========================================================================
140 //
141 // R_UpdateSky
142 //
143 // Performs sky scrolling
144 //
145 //==========================================================================
146 
R_UpdateSky(DWORD mstime)147 void R_UpdateSky (DWORD mstime)
148 {
149 	// Scroll the sky
150 	double ms = (double)mstime * FRACUNIT;
151 	sky1pos = ms * level.skyspeed1;
152 	sky2pos = ms * level.skyspeed2;
153 }
154 
155