r_main.c (8827B)
1 #include <stdlib.h> 2 #include <math.h> 3 4 #include "doomdef.h" 5 #include "d_net.h" 6 #include "m_bbox.h" 7 #include "r_local.h" 8 9 #define FIELDOFVIEW 2048 10 #define DISTMAP 2 11 12 extern lighttable_t** walllights; 13 extern int detailLevel; 14 extern int screenblocks; 15 16 int viewangleoffset; 17 int validcount = 1; 18 lighttable_t* fixedcolormap; 19 int centerx; 20 int centery; 21 fixed_t centerxfrac; 22 fixed_t centeryfrac; 23 fixed_t projection; 24 int framecount; 25 int sscount; 26 int linecount; 27 int loopcount; 28 fixed_t viewx; 29 fixed_t viewy; 30 fixed_t viewz; 31 angle_t viewangle; 32 fixed_t viewcos; 33 fixed_t viewsin; 34 player_t* viewplayer; 35 int detailshift; 36 angle_t clipangle; 37 int viewangletox[FINEANGLES/2]; 38 angle_t xtoviewangle[SCREENWIDTH+1]; 39 fixed_t* finecosine = &finesine[FINEANGLES/4]; 40 lighttable_t* scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; 41 lighttable_t* scalelightfixed[MAXLIGHTSCALE]; 42 lighttable_t* zlight[LIGHTLEVELS][MAXLIGHTZ]; 43 int extralight; 44 boolean setsizeneeded; 45 int setblocks; 46 int setdetail; 47 int skyflatnum; 48 int skytexture; 49 int skytexturemid; 50 51 void (*colfunc) (); 52 void (*basecolfunc) (); 53 void (*fuzzcolfunc) (); 54 void (*transcolfunc) (); 55 void (*spanfunc) (); 56 57 void 58 R_AddPointToBox(int x, int y, fixed_t* box) 59 { 60 if (x< box[BOXLEFT]) box[BOXLEFT] = x; 61 if (x> box[BOXRIGHT]) box[BOXRIGHT] = x; 62 if (y< box[BOXBOTTOM]) box[BOXBOTTOM] = y; 63 if (y> box[BOXTOP]) box[BOXTOP] = y; 64 } 65 int 66 R_PointOnSide(fixed_t x, fixed_t y, node_t* node) 67 { 68 fixed_t dx, dy, left, right; 69 70 if (!node->dx) { 71 if (x <= node->x) 72 return node->dy > 0; 73 return node->dy < 0; 74 } 75 if (!node->dy) { 76 if (y <= node->y) 77 return node->dx < 0; 78 return node->dx > 0; 79 } 80 dx = (x - node->x); 81 dy = (y - node->y); 82 if ((node->dy ^ node->dx ^ dx ^ dy)&0x80000000) { 83 if ((node->dy ^ dx) & 0x80000000) 84 return 1; 85 return 0; 86 } 87 left = FixedMul(node->dy>>FRACBITS , dx); 88 right = FixedMul(dy , node->dx>>FRACBITS); 89 if (right < left) 90 return 0; 91 return 1; 92 } 93 94 int 95 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t* line) 96 { 97 fixed_t lx, ly, ldx, ldy, dx, dy, left, right; 98 99 lx = line->v1->x; 100 ly = line->v1->y; 101 ldx = line->v2->x - lx; 102 ldy = line->v2->y - ly; 103 if (!ldx) { 104 if (x <= lx) 105 return ldy > 0; 106 return ldy < 0; 107 } 108 if (!ldy) { 109 if (y <= ly) 110 return ldx < 0; 111 return ldx > 0; 112 } 113 dx = (x - lx); 114 dy = (y - ly); 115 if ((ldy ^ ldx ^ dx ^ dy)&0x80000000) { 116 if ((ldy ^ dx) & 0x80000000) 117 return 1; 118 return 0; 119 } 120 left = FixedMul(ldy>>FRACBITS , dx); 121 right = FixedMul(dy , ldx>>FRACBITS); 122 if (right < left) 123 return 0; 124 return 1; 125 } 126 127 angle_t 128 R_PointToAngle(fixed_t x, fixed_t y) 129 { 130 x -= viewx; 131 y -= viewy; 132 if ((!x) && (!y)) 133 return 0; 134 if (x>= 0) { 135 if (y>= 0) { 136 if (x>y) 137 return tantoangle[ SlopeDiv(y,x)]; 138 else return ANG90-1-tantoangle[ SlopeDiv(x,y)]; 139 } 140 else { 141 y = -y; 142 if (x>y) 143 return -tantoangle[SlopeDiv(y,x)]; 144 else return ANG270+tantoangle[ SlopeDiv(x,y)]; 145 } 146 } else { 147 x = -x; 148 if (y>= 0) { 149 if (x > y) 150 return ANG180-1-tantoangle[ SlopeDiv(y,x)]; 151 else return ANG90+ tantoangle[ SlopeDiv(x,y)]; 152 } else { 153 y = -y; 154 if (x > y) 155 return ANG180+tantoangle[ SlopeDiv(y,x)]; 156 else return ANG270-1-tantoangle[ SlopeDiv(x,y)]; 157 } 158 } 159 return 0; 160 } 161 162 angle_t 163 R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) 164 { 165 viewx = x1; 166 viewy = y1; 167 return R_PointToAngle(x2, y2); 168 } 169 170 fixed_t 171 R_PointToDist(fixed_t x, fixed_t y) 172 { 173 fixed_t dx, dy, temp, dist; 174 int angle; 175 176 dx = abs(x - viewx); 177 dy = abs(y - viewy); 178 if (dy > dx) { 179 temp = dx; 180 dx = dy; 181 dy = temp; 182 } 183 angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT; 184 dist = FixedDiv (dx, finesine[angle] ); 185 return dist; 186 } 187 188 fixed_t 189 R_ScaleFromGlobalAngle(angle_t visangle) 190 { 191 fixed_t scale, num; 192 int anglea, angleb, sinea, sineb, den; 193 anglea = ANG90 + (visangle-viewangle); 194 angleb = ANG90 + (visangle-rw_normalangle); 195 sinea = finesine[anglea>>ANGLETOFINESHIFT]; 196 sineb = finesine[angleb>>ANGLETOFINESHIFT]; 197 num = FixedMul(projection,sineb)<<detailshift; 198 den = FixedMul(rw_distance,sinea); 199 if (den > num>>16) { 200 scale = FixedDiv(num, den); 201 if (scale > 64*FRACUNIT) scale = 64*FRACUNIT; 202 if (scale < 256) scale = 256; 203 } 204 else scale = 64*FRACUNIT; 205 return scale; 206 } 207 208 void 209 R_InitTextureMapping() 210 { 211 fixed_t focallength; 212 int i, x, t; 213 214 focallength = FixedDiv(centerxfrac, finetangent[FINEANGLES/4+FIELDOFVIEW/2]); 215 for (i = 0; i < FINEANGLES/2; ++i) { 216 if (finetangent[i] > FRACUNIT * 2) 217 t = -1; 218 else if 219 (finetangent[i] < -FRACUNIT*2) t = viewwidth+1; 220 else { 221 t = FixedMul (finetangent[i], focallength); 222 t = (centerxfrac - t+FRACUNIT-1)>>FRACBITS; 223 if (t < -1) 224 t = -1; 225 if (t>viewwidth+1) 226 t = viewwidth+1; 227 } 228 viewangletox[i] = t; 229 } 230 for (x = 0; x <= viewwidth; ++x) { 231 i = 0; 232 while (viewangletox[i]>x) 233 ++i; 234 xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90; 235 } 236 for (i = 0; i < FINEANGLES/2; ++i) { 237 t = centerx - FixedMul(finetangent[i], focallength);; 238 if (viewangletox[i] == -1) 239 viewangletox[i] = 0; 240 if (viewangletox[i] == viewwidth+1) 241 viewangletox[i] = viewwidth; 242 } 243 clipangle = xtoviewangle[0]; 244 } 245 246 void 247 R_InitLightTables() 248 { 249 int i, j, level, startmap, scale; 250 251 for (i = 0; i < LIGHTLEVELS; ++i) { 252 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; 253 for (j = 0; j < MAXLIGHTZ; ++j) { 254 scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT); 255 scale >>= LIGHTSCALESHIFT; 256 level = startmap - scale/DISTMAP; 257 if (level < 0) 258 level = 0; 259 if (level >= NUMCOLORMAPS) 260 level = NUMCOLORMAPS-1; 261 zlight[i][j] = colormaps + level*256; 262 } 263 } 264 } 265 266 void 267 R_SetViewSize(int blocks, int detail) 268 { 269 setsizeneeded = true; 270 setblocks = blocks; 271 setdetail = detail; 272 } 273 274 void 275 R_ExecuteSetViewSize() 276 { 277 fixed_t cosadj, dy; 278 int i, j, level, startmap; 279 280 setsizeneeded = false; 281 if (setblocks == 11) { 282 scaledviewwidth = SCREENWIDTH; 283 viewheight = SCREENHEIGHT; 284 } else { 285 scaledviewwidth = setblocks * 32; 286 viewheight = (setblocks * 168/10) & ~7; 287 } 288 detailshift = setdetail; 289 viewwidth = scaledviewwidth>>detailshift; 290 centery = viewheight/2; 291 centerx = viewwidth/2; 292 centerxfrac = centerx<<FRACBITS; 293 centeryfrac = centery<<FRACBITS; 294 projection = centerxfrac; 295 if (!detailshift) { 296 colfunc = basecolfunc = R_DrawColumn; 297 fuzzcolfunc = R_DrawFuzzColumn; 298 transcolfunc = R_DrawTranslatedColumn; 299 spanfunc = R_DrawSpan; 300 } else { 301 colfunc = basecolfunc = R_DrawColumnLow; 302 fuzzcolfunc = R_DrawFuzzColumn; 303 transcolfunc = R_DrawTranslatedColumn; 304 spanfunc = R_DrawSpanLow; 305 } 306 R_InitBuffer(scaledviewwidth, viewheight); 307 R_InitTextureMapping(); 308 pspritescale = FRACUNIT*viewwidth/SCREENWIDTH; 309 pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth; 310 for (i = 0; i < viewwidth; ++i) 311 screenheightarray[i] = viewheight; 312 for (i = 0; i < viewheight; ++i) { 313 dy = ((i-viewheight/2)<<FRACBITS)+FRACUNIT/2; 314 dy = abs(dy); 315 yslope[i] = FixedDiv ( (viewwidth<<detailshift)/2*FRACUNIT, dy); 316 } 317 for (i = 0; i < viewwidth; ++i) { 318 cosadj = abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]); 319 distscale[i] = FixedDiv (FRACUNIT,cosadj); 320 } 321 for (i = 0; i < LIGHTLEVELS; ++i) { 322 startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; 323 for (j = 0; j <MAXLIGHTSCALE; ++j) { 324 level = startmap - j*SCREENWIDTH/(viewwidth<<detailshift)/DISTMAP; 325 if (level < 0) 326 level = 0; 327 if (level >= NUMCOLORMAPS) 328 level = NUMCOLORMAPS-1; 329 scalelight[i][j] = colormaps + level*256; 330 } 331 } 332 } 333 334 void 335 R_Init() 336 { 337 R_InitData(); 338 R_SetViewSize(screenblocks, detailLevel); 339 R_InitPlanes(); 340 R_InitLightTables(); 341 skytexturemid = 100 * FRACUNIT; 342 R_InitTranslationTables(); 343 framecount = 0; 344 } 345 346 subsector_t* 347 R_PointInSubsector(fixed_t x, fixed_t y) 348 { 349 node_t* node; 350 int side, nodenum; 351 352 if (!numnodes) 353 return subsectors; 354 nodenum = numnodes-1; 355 while (!(nodenum & NF_SUBSECTOR)) { 356 node = &nodes[nodenum]; 357 side = R_PointOnSide (x, y, node); 358 nodenum = node->children[side]; 359 } 360 return &subsectors[nodenum & ~NF_SUBSECTOR]; 361 } 362 363 void 364 R_SetupFrame(player_t* player) 365 { 366 int i; 367 368 viewplayer = player; 369 viewx = player->mo->x; 370 viewy = player->mo->y; 371 viewangle = player->mo->angle + viewangleoffset; 372 extralight = player->extralight; 373 viewz = player->viewz; 374 viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; 375 viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; 376 sscount = 0; 377 if (player->fixedcolormap) { 378 fixedcolormap = colormaps + player->fixedcolormap*256*sizeof(lighttable_t); 379 walllights = scalelightfixed; 380 for (i = 0; i < MAXLIGHTSCALE; ++i) 381 scalelightfixed[i] = fixedcolormap; 382 } else { 383 fixedcolormap = 0; 384 } 385 ++framecount; 386 ++validcount; 387 } 388 389 void 390 R_RenderPlayerView(player_t* player) 391 { 392 R_SetupFrame(player); 393 R_ClearClipSegs(); 394 R_ClearDrawSegs(); 395 R_ClearPlanes(); 396 R_ClearSprites(); 397 NetUpdate(); 398 R_RenderBSPNode(numnodes-1); 399 NetUpdate(); 400 R_DrawPlanes(); 401 NetUpdate(); 402 R_DrawMasked(); 403 NetUpdate(); 404 }