/* Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // r_sky.c #include "globaldef.h" #include "r_local.h" #include "d_local.h" int iskyspeed = 8; int iskyspeed2 = 2; float skyspeed, skyspeed2; float skytime; byte *r_skysource; byte *skyunderlay, *skyoverlay; int r_skyframe; msurface_t *r_skyfaces; mplane_t r_skyplanes[6]; mtexinfo_t r_skytexinfo[6]; mvertex_t *r_skyverts; medge_t *r_skyedges; int *r_skysurfedges; int skybox_planes[12] = {2,-128, 0,-128, 2,128, 1,128, 0,128, 1,-128}; int box_surfedges[24] = { 1,2,3,4, -1,5,6,7, 8,9,-6,10, -2,-7,-9,11, 12,-3,-11,-8, -12,-10,-5,-4}; int box_edges[24] = { 1,2, 2,3, 3,4, 4,1, 1,5, 5,6, 6,2, 7,8, 8,6, 5,7, 8,3, 7,4}; int box_faces[6] = {0,0,2,2,2,0}; vec3_t box_vecs[6][2] = { { {0,-1,0}, {-1,0,0} }, { {0,1,0}, {0,0,-1} }, { {0,-1,0}, {1,0,0} }, { {1,0,0}, {0,0,-1} }, { {0,-1,0}, {0,0,-1} }, { {-1,0,0}, {0,0,-1} } }; float box_verts[8][3] = { {-1,-1,-1}, {-1,1,-1}, {1,1,-1}, {1,-1,-1}, {-1,-1,1}, {-1,1,1}, {1,-1,1}, {1,1,1} }; // down, west, up, north, east, south // {"rt", "bk", "lf", "ft", "up", "dn"}; static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; int r_skysideimage[6] = {5, 2, 4, 1, 0, 3}; mtexinfo_t r_skytexinfo[6]; char skyname[64]; texture_t *R_LoadSkyTexture(char *name) { return NULL; } /* ================ R_LoadSkyBox ================ */ void R_LoadSkyBox (void) { int i; char pathname[MAX_QPATH]; for (i=0 ; i<6 ; i++) { // snprintf (pathname, MAX_QPATH-1, "env/%s%s.lmp", skyname, suf[r_skysideimage[i]]); // r_skytexinfo[i].texture = R_LoadSkyTexture (pathname); //preferable // if (!r_skytexinfo[i].texture) // { // break out and erase skyname so renderer won't render it skyname[0] = '\0'; return; // } } } void R_SetSky (char *name, float rotate, vec3_t axis) { int i; strncpy (skyname, name, sizeof(skyname)); for (i=0 ; i<6 ; i++) r_skytexinfo[i].texture = NULL; R_LoadSkyBox(); } /* ================ R_InitSkyBox ================ */ void R_InitSkyBox (void) { /* int i; model_t *wm; wm = cl.worldmodel; if (wm->numsurfaces+6 > MAX_MAP_FACES || wm->numvertexes+8 > MAX_MAP_VERTS || wm->numedges+12 > MAX_MAP_EDGES) Host_Error ("InitSkyBox: map overflow"); r_skyfaces = wm->surfaces + wm->numsurfaces; r_skyverts = wm->vertexes + wm->numvertexes; r_skyedges = wm->edges + wm->numedges; r_skysurfedges = wm->surfedges + wm->numsurfedges; //memset (r_skyfaces, 0, 6*sizeof(*r_skyfaces)); for (i=0 ; i<6 ; i++) { r_skyplanes[i].normal[skybox_planes[i*2]] = 1; r_skyplanes[i].dist = skybox_planes[i*2+1]; VectorCopy (box_vecs[i][0], r_skytexinfo[i].vecs[0]); VectorCopy (box_vecs[i][1], r_skytexinfo[i].vecs[1]); r_skyfaces[i].plane = &r_skyplanes[i]; r_skyfaces[i].numedges = 4; r_skyfaces[i].flags = box_faces[i] | SURF_DRAWSKYBOX; r_skyfaces[i].firstedge = wm->numsurfedges+i*4; r_skyfaces[i].texinfo = &r_skytexinfo[i]; r_skyfaces[i].texturemins[0] = -128; r_skyfaces[i].texturemins[1] = -128; r_skyfaces[i].extents[0] = 256; r_skyfaces[i].extents[1] = 256; } for (i=0 ; i<24 ; i++) if (box_surfedges[i] > 0) r_skysurfedges[i] = wm->numedges - 1 + box_surfedges[i]; else r_skysurfedges[i] = -(wm->numedges - 1 + -box_surfedges[i]); for(i=0 ; i<12 ; i++) { r_skyedges[i].v[0] = wm->numvertexes-1+box_edges[i*2+0]; r_skyedges[i].v[1] = wm->numvertexes-1+box_edges[i*2+1]; r_skyedges[i].cachededgeoffset = 0; } Hunk_Check();*/ } void R_Skyboxname_Callback(struct cvar_s *var, char *oldvalue) { strncpy (skyname, var->string, sizeof(skyname)); R_LoadSkyBox(); } /* ================ R_EmitSkyBox ================ */ qboolean R_EmitSkyBox (void) { int i, j; int oldkey; if (insubmodel) return false; if (r_skyframe == r_framecount) return true; if (!*skyname) return false; r_skyframe = r_framecount; for (i=0 ; i<8 ; i++) for (j=0 ; j<3 ; j++) r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128; for (i=0 ; i<6 ; i++) if (skybox_planes[i*2+1] > 0) r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128; else r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128; for (i=0 ; i<6 ; i++) { r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]); r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]); } oldkey = r_currentkey; r_currentkey = 0x7ffffff0; for (i=0 ; i<6 ; i++) { R_RenderFace (r_skyfaces + i, 15); } r_currentkey = oldkey; return true; } /* ============= R_InitSky A sky texture is 256*128, with the right side being a masked overlay ============== */ void R_InitSky (texture_t *mt) { skyoverlay = (byte *)mt + mt->offsets[0]; skyunderlay = skyoverlay+128; } /* ============= R_SetSkyFrame ============== */ void R_SetSkyFrame (void) { int g, s1, s2; float temp; skyspeed = iskyspeed; skyspeed2 = iskyspeed2; g = GreatestCommonDivisor (iskyspeed, iskyspeed2); s1 = iskyspeed / g; s2 = iskyspeed2 / g; temp = SKYSIZE * s1 * s2; skytime = cl.time - ((int)(cl.time / temp) * temp); }