📄 r_sky.c
字号:
// Emacs style mode select -*- C++ -*-//-----------------------------------------------------------------------------//// $Id: r_sky.c,v 1.7 2001/04/02 18:54:32 bpereira Exp $//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// 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.////// $Log: r_sky.c,v $// Revision 1.7 2001/04/02 18:54:32 bpereira// no message//// Revision 1.6 2001/03/21 18:24:39 stroggonmeth// Misc changes and fixes. Code cleanup//// Revision 1.5 2001/03/13 22:14:20 stroggonmeth// Long time no commit. 3D floors, FraggleScript, portals, ect.//// Revision 1.4 2001/01/25 22:15:44 bpereira// added heretic support//// Revision 1.3 2000/09/21 16:45:08 bpereira// no message//// Revision 1.2 2000/02/27 00:42:10 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:32 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// Sky rendering. The DOOM sky is a texture map like any// wall, wrapping around. A 1024 columns equal 360 degrees.// The default sky map is 256 columns and repeats 4 times// on a 320 screen?// ////-----------------------------------------------------------------------------#include "doomdef.h"#include "r_sky.h"#include "r_local.h"#include "w_wad.h"#include "z_zone.h"#include "p_maputl.h" // P_PointOnLineSide// SoM: I know I should be moving portals out of r_sky.c and as soon// as I have time and a I will... But for now, they are mostly used// for sky boxes anyway so they have a mostly appropriate home here.//// sky mapping//int skyflatnum;int skytexture;int skytexturemid;fixed_t skyscale;int skymode=0; // old (0), new (1) (quick fix!)//// R_InitSkyMap called at startup, once.//void R_InitSkyMap (void){ // set at P_LoadSectors //skyflatnum = R_FlatNumForName ( SKYFLATNAME );}// Setup sky draw for old or new skies (new skies = freelook 256x240)//// Call at loadlevel after skytexture is set//// NOTE: skycolfunc should be set at R_ExecuteSetViewSize ()// I dont bother because we don't use low detail no more//void R_SetupSkyDraw (void){ texpatch_t* patches; patch_t wpatch; int count; int height; int i; // parse the patches composing sky texture for the tallest one // patches are usually RSKY1,RSKY2... and unique // note: the TEXTURES lump doesn't have the taller size of Legacy // skies, but the patches it use will give the right size count = textures[skytexture]->patchcount; patches = &textures[skytexture]->patches[0]; for (height=0,i=0;i<count;i++,patches++) { W_ReadLumpHeader (patches->patch, &wpatch, sizeof(patch_t)); wpatch.height = SHORT(wpatch.height); if (wpatch.height>height) height = wpatch.height; } // DIRTY : should set the routine depending on colormode in screen.c if (height>128) { // horizon line on 256x240 freelook textures of Legacy or heretic skytexturemid = 200<<FRACBITS; skymode = 1; } else { // the horizon line in a 256x128 sky texture skytexturemid = 100<<FRACBITS; skymode = 0; } // get the right drawer, it was set by screen.c, depending on the // current video mode bytes per pixel (quick fix) skycolfunc = skydrawerfunc[skymode]; R_SetSkyScale ();}// set the correct scale for the sky at setviewsizevoid R_SetSkyScale (void){ //fix this quick mess if (skytexturemid>100<<FRACBITS) { // normal aspect ratio corrected scale skyscale = FixedDiv (FRACUNIT, pspriteyscale); } else { // double the texture vertically, bleeergh!! skyscale = FixedDiv (FRACUNIT, pspriteyscale)>>1; }}//////////////////////////////////// PORTALS. I'm too lazy to make// another file so I'm putting// the portal code in here for// now.//////////////////////////////////portal_t portalhead;void R_InitPortals(){ portalhead.next = portalhead.prev = &portalhead;}portal_t* R_CreatePortal(portaltype_e type, line_t* mline, sector_t* msector, portal_t* parent){ portal_t* ret; int i; ret = (portal_t *)Z_Malloc(sizeof(portal_t), PU_LEVEL, 0); ret->type = type; if(type == PRTL_QUAKESKY) { ret->alphaheight = msector->ceilingheight; ret->target.plane = (visplane_t *)Z_Malloc(sizeof(visplane_t), PU_LEVEL, 0); ret->target.plane->height = msector->ceilingheight; ret->target.plane->lightlevel = msector->lightlevel; ret->target.plane->picnum = msector->ceilingpic; ret->target.plane->minx = -1; ret->target.plane->maxx = viewwidth; ret->target.plane->extra_colormap = msector->extra_colormap; ret->target.plane->xoffs = ret->target.plane->yoffs = 0; ret->target.plane->ffloor = NULL; memset(ret->target.plane->top, 0xff, sizeof(short) * viewwidth); } else if(type == PRTL_SKYBOX) { ret->target.lvl = (lvlportal_t *)Z_Malloc(sizeof(lvlportal_t), PU_LEVEL, 0); ret->target.lvl->viewx = msector->soundorg.x; ret->target.lvl->viewy = msector->soundorg.y; ret->target.lvl->viewz = msector->floorheight + ((msector->ceilingheight - msector->floorheight) / 2); for(i = 0; i < viewwidth; i++) { memcpy(&ret->target.lvl->topclip[i], &viewheight, sizeof(short)); ret->target.lvl->botclip[i] = -1; } } else if(type == PRTL_MIRROR) { ret->target.lvl = (lvlportal_t *)Z_Malloc(sizeof(lvlportal_t), PU_LEVEL, 0); ret->target.lvl->viewx = (mline->v1->x + mline->v2->x) / 2; ret->target.lvl->viewy = (mline->v1->y + mline->v2->y) / 2; ret->target.lvl->viewz = 0; for(i = 0; i < viewwidth; i++) { memcpy(&ret->target.lvl->topclip[i], &viewheight, sizeof(short)); ret->target.lvl->botclip[i] = -1; } } else if(type == PRTL_PORTAL) { ret->target.lvl = (lvlportal_t *)Z_Malloc(sizeof(lvlportal_t), PU_LEVEL, 0); ret->target.lvl->viewx = (mline->v1->x + mline->v2->x) / 2; ret->target.lvl->viewy = (mline->v1->y + mline->v2->y) / 2; ret->target.lvl->viewz = 0; for(i = 0; i < viewwidth; i++) { memcpy(&ret->target.lvl->topclip[i], &viewheight, sizeof(short)); ret->target.lvl->botclip[i] = -1; } } ret->mline = mline; ret->msector = msector; ret->parent = parent; ret->child = NULL; if(!parent) { (ret->prev = portalhead.prev)->next = ret; (ret->next = &portalhead)->prev = ret; ret->render = false; } else { ret->next = ret->prev = NULL; parent->child = ret; ret->render = true; } return ret;}// SoM: This function acts as a column drawer substitute. Insted of actually// drawing pixels, it sets clipping values in a portal. If the clipping// values conflict with values allready set in the portal, it will create// a child portal. If a child portal allready exists, it will search// down the line until a suitable child is found. In the event that no,// suitable children are found, it will create another child.// Confused yet? >:)portal_t* dc_portal;void R_StorePortalRange(void){ visplane_t* plane; portal_t* portal; lvlportal_t* lvl=NULL; register int x; x = dc_x; portal = dc_portal;/* if(x == 160) CONS_Printf("Portal: yl = %i, yh = %i\n", dc_yl, dc_yh);*/ if(portal->type == PRTL_QUAKESKY) { plane = portal->target.plane; // check the existing bounds... if(plane->top[x] == 0xffff) { plane->top[x] = dc_yl; plane->bottom[x] = dc_yh; if(plane->maxx <= x) plane->maxx = x; if(plane->minx >= x) plane->minx = x; portal->render = true; } else { if(dc_yl < plane->top[x] && dc_yh >= plane->top[x] - 1) { plane->top[x] = dc_yl; portal->render = true; } else if(dc_yh > plane->bottom[x] && dc_yl <= plane->bottom[x] + 1) { plane->bottom[x] = dc_yh; portal->render = true; } else if(dc_yh <= plane->bottom[x] && dc_yl >= plane->top[x]) return; else { while(portal->child) { portal = portal->child; plane = portal->target.plane; if(plane->top[x] == 0xffff) { plane->top[x] = dc_yl; plane->bottom[x] = dc_yh; if(plane->maxx <= x) plane->maxx = x; if(plane->minx >= x) plane->minx = x; portal->render = true; return; } else { if(dc_yl < plane->top[x] && dc_yh >= plane->top[x] - 1) { plane->top[x] = dc_yl; portal->render = true; } else if(dc_yh > plane->bottom[x] && dc_yl <= plane->bottom[x] + 1) { plane->bottom[x] = dc_yh; portal->render = true; } else if(dc_yh <= plane->bottom[x] && dc_yl >= plane->top[x]) return; else continue; return; } } CONS_Printf("Create child\n"); portal = R_CreatePortal(PRTL_QUAKESKY, portal->mline, portal->msector, portal); plane = portal->target.plane; plane->top[x] = dc_yl; plane->bottom[x] = dc_yh; plane->minx = x; plane->maxx = x; return; } } } else if(portal->type == PRTL_SKYBOX || portal->type == PRTL_MIRROR || portal->type == PRTL_PORTAL) { int yl = dc_yl - 1; int yh = dc_yh + 1; lvl = portal->target.lvl; if(lvl->topclip[x] > lvl->botclip[x]) { lvl->topclip[x] = yl; lvl->botclip[x] = yh; if(!portal->render) goto setrender; return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -