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