A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 548 lines 15 kB view raw
1/* Emacs style mode select -*- C++ -*- 2 *----------------------------------------------------------------------------- 3 * 4 * 5 * PrBoom a Doom port merged with LxDoom and LSDLDoom 6 * based on BOOM, a modified and improved DOOM engine 7 * Copyright (C) 1999 by 8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman 9 * Copyright (C) 1999-2000 by 10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 25 * 02111-1307, USA. 26 * 27 * DESCRIPTION: 28 * Rendering main loop and setup functions, 29 * utility functions (BSP, geometry, trigonometry). 30 * See tables.c, too. 31 * 32 *-----------------------------------------------------------------------------*/ 33 34#include "doomstat.h" 35#include "w_wad.h" 36#include "r_main.h" 37#include "r_things.h" 38#include "r_plane.h" 39#include "r_bsp.h" 40#include "r_draw.h" 41#include "m_bbox.h" 42#include "r_sky.h" 43#include "v_video.h" 44#include "i_system.h" 45//#include "lprintf.h" 46#include "st_stuff.h" 47#include "rockmacros.h" 48 49// Fineangles in the SCREENWIDTH wide window. 50#define FIELDOFVIEW 2048 51 52// killough: viewangleoffset is a legacy from the pre-v1.2 days, when Doom 53// had Left/Mid/Right viewing. +/-ANG90 offsets were placed here on each 54// node, by d_net.c, to set up a L/M/R session. 55 56int viewangleoffset; 57 58int validcount = 1; // increment every time a check is made 59lighttable_t *fixedcolormap; 60int centerx IBSS_ATTR; 61int centery IBSS_ATTR; 62fixed_t centerxfrac, centeryfrac; 63fixed_t projection; 64// proff 11/06/98: Added for high-res 65fixed_t projectiony; 66fixed_t viewx, viewy, viewz; 67angle_t viewangle; 68fixed_t viewcos, viewsin; 69player_t *viewplayer; 70extern lighttable_t **walllights; 71 72// 73// precalculated math tables 74// 75 76angle_t clipangle; 77 78// The viewangletox[viewangle + FINEANGLES/4] lookup 79// maps the visible view angles to screen X coordinates, 80// flattening the arc to a flat projection plane. 81// There will be many angles mapped to the same X. 82 83int *viewangletox=0; 84 85// The xtoviewangleangle[] table maps a screen pixel 86// to the lowest viewangle that maps back to x ranges 87// from clipangle to -clipangle. 88 89angle_t xtoviewangle[MAX_SCREENWIDTH+1]; // killough 2/8/98 90 91// killough 3/20/98: Support dynamic colormaps, e.g. deep water 92// killough 4/4/98: support dynamic number of them as well 93 94int numcolormaps; 95lighttable_t *(*c_scalelight)[LIGHTLEVELS][MAXLIGHTSCALE]; 96lighttable_t *(*c_zlight)[LIGHTLEVELS][MAXLIGHTZ]; 97lighttable_t *(*scalelight)[MAXLIGHTSCALE]; 98lighttable_t *(*zlight)[MAXLIGHTZ]; 99lighttable_t *fullcolormap; 100lighttable_t **colormaps; 101 102// killough 3/20/98, 4/4/98: end dynamic colormaps 103 104int extralight; // bumped light from gun blasts 105 106void (*colfunc)(void); 107 108// 109// R_PointOnSide 110// Traverse BSP (sub) tree, 111// check point against partition plane. 112// Returns side 0 (front) or 1 (back). 113// 114// killough 5/2/98: reformatted 115// 116 117int R_PointOnSide(fixed_t x, fixed_t y, const node_t *node) 118{ 119 if (!node->dx) 120 return x <= node->x ? node->dy > 0 : node->dy < 0; 121 122 if (!node->dy) 123 return y <= node->y ? node->dx < 0 : node->dx > 0; 124 125 x -= node->x; 126 y -= node->y; 127 128 // Try to quickly decide by looking at sign bits. 129 if ((node->dy ^ node->dx ^ x ^ y) < 0) 130 return (node->dy ^ x) < 0; // (left is negative) 131 return FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x); 132} 133 134// killough 5/2/98: reformatted 135 136int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) 137{ 138 fixed_t lx = line->v1->x; 139 fixed_t ly = line->v1->y; 140 fixed_t ldx = line->v2->x - lx; 141 fixed_t ldy = line->v2->y - ly; 142 143 if (!ldx) 144 return x <= lx ? ldy > 0 : ldy < 0; 145 146 if (!ldy) 147 return y <= ly ? ldx < 0 : ldx > 0; 148 149 x -= lx; 150 y -= ly; 151 152 // Try to quickly decide by looking at sign bits. 153 if ((ldy ^ ldx ^ x ^ y) < 0) 154 return (ldy ^ x) < 0; // (left is negative) 155 return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x); 156} 157 158// 159// R_PointToAngle 160// To get a global angle from cartesian coordinates, 161// the coordinates are flipped until they are in 162// the first octant of the coordinate system, then 163// the y (<=x) is scaled and divided by x to get a 164// tangent (slope) value which is looked up in the 165// tantoangle[] table. The +1 size of tantoangle[] 166// is to handle the case when x==y without additional 167// checking. 168// 169// killough 5/2/98: reformatted, cleaned up 170 171angle_t R_PointToAngle(fixed_t x, fixed_t y) 172{ 173 return (y -= viewy, (x -= viewx) || y) ? 174 x >= 0 ? 175 y >= 0 ? 176 (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 177 ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 178 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 179 ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7 180 y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3 181 ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2 182 (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4 183 ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 184 0; 185} 186 187angle_t R_PointToAngle2(fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y) 188{ 189 return (y -= viewy, (x -= viewx) || y) ? 190 x >= 0 ? 191 y >= 0 ? 192 (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 193 ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 194 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 195 ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7 196 y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3 197 ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2 198 (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4 199 ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 200 0; 201} 202 203// 204// R_InitTextureMapping 205// 206// killough 5/2/98: reformatted 207 208static void R_InitTextureMapping (void) 209{ 210 register int i,x; 211 fixed_t focallength; 212 213 // Use tangent table to generate viewangletox: 214 // viewangletox will give the next greatest x 215 // after the view angle. 216 // 217 // Calc focallength 218 // so FIELDOFVIEW angles covers SCREENWIDTH. 219 220 if(viewangletox==NULL) 221 viewangletox=malloc(sizeof(int)*FINEANGLES/2); 222 223 focallength = FixedDiv(centerxfrac, finetangent[FINEANGLES/4+FIELDOFVIEW/2]); 224 225 for (i=0 ; i<FINEANGLES/2 ; i++) 226 { 227 int t; 228 if (finetangent[i] > FRACUNIT*2) 229 t = -1; 230 else 231 if (finetangent[i] < -FRACUNIT*2) 232 t = viewwidth+1; 233 else 234 { 235 t = FixedMul(finetangent[i], focallength); 236 t = (centerxfrac - t + FRACUNIT-1) >> FRACBITS; 237 if (t < -1) 238 t = -1; 239 else 240 if (t > viewwidth+1) 241 t = viewwidth+1; 242 } 243 viewangletox[i] = t; 244 } 245 246 // Scan viewangletox[] to generate xtoviewangle[]: 247 // xtoviewangle will give the smallest view angle 248 // that maps to x. 249 250 for (x=0; x<=viewwidth; x++) 251 { 252 for (i=0; viewangletox[i] > x; i++) 253 ; 254 xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90; 255 } 256 257 // Take out the fencepost cases from viewangletox. 258 for (i=0; i<FINEANGLES/2; i++) 259 if (viewangletox[i] == -1) 260 viewangletox[i] = 0; 261 else 262 if (viewangletox[i] == viewwidth+1) 263 viewangletox[i] = viewwidth; 264 265 clipangle = xtoviewangle[0]; 266} 267 268// 269// R_InitLightTables 270// Only inits the zlight table, 271// because the scalelight table changes with view size. 272// 273 274#define DISTMAP 2 275 276void R_InitLightTables (void) 277{ 278 int i; 279 280 // killough 4/4/98: dynamic colormaps 281 c_zlight = malloc(sizeof(*c_zlight) * numcolormaps); 282 c_scalelight = malloc(sizeof(*c_scalelight) * numcolormaps); 283 284 // Calculate the light levels to use 285 // for each level / distance combination. 286 for (i=0; i< LIGHTLEVELS; i++) 287 { 288 int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; 289 for (j=0; j<MAXLIGHTZ; j++) 290 { 291 // CPhipps - use 320 here instead of SCREENWIDTH, otherwise hires is 292 // brighter than normal res 293 int scale = FixedDiv ((320/2*FRACUNIT), (j+1)<<LIGHTZSHIFT); 294 int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP; 295 296 if (level < 0) 297 level = 0; 298 else 299 if (level >= NUMCOLORMAPS) 300 level = NUMCOLORMAPS-1; 301 302 // killough 3/20/98: Initialize multiple colormaps 303 level *= 256; 304 for (t=0; t<numcolormaps; t++) // killough 4/4/98 305 c_zlight[t][i][j] = colormaps[t] + level; 306 } 307 } 308} 309 310// 311// R_SetViewSize 312// Do not really change anything here, 313// because it might be in the middle of a refresh. 314// The change will take effect next refresh. 315// 316 317boolean setsizeneeded; 318int setblocks; 319 320void R_SetViewSize(int blocks) 321{ 322 setsizeneeded = true; 323 setblocks = blocks; 324} 325 326// 327// R_ExecuteSetViewSize 328// 329 330void R_ExecuteSetViewSize (void) 331{ 332 int i; 333 334 setsizeneeded = false; 335 336 if (setblocks == 11) 337 { 338 scaledviewwidth = SCREENWIDTH; 339 viewheight = SCREENHEIGHT; 340 } 341 // proff 09/24/98: Added for high-res 342 else if (setblocks == 10) 343 { 344 scaledviewwidth = SCREENWIDTH; 345 viewheight = SCREENHEIGHT-ST_SCALED_HEIGHT; 346 } 347 else 348 { 349 // proff 08/17/98: Changed for high-res 350 scaledviewwidth = setblocks*SCREENWIDTH/10; 351 viewheight = (setblocks*(SCREENHEIGHT-ST_SCALED_HEIGHT)/10) & ~7; 352 } 353 354 viewwidth = scaledviewwidth; 355 356 centery = viewheight/2; 357 centerx = viewwidth/2; 358 centerxfrac = centerx<<FRACBITS; 359 centeryfrac = centery<<FRACBITS; 360 projection = centerxfrac; 361 // proff 11/06/98: Added for high-res 362 projectiony = ((SCREENHEIGHT * centerx * 320) / 200) / SCREENWIDTH * FRACUNIT; 363 364 R_InitBuffer (scaledviewwidth, viewheight); 365 366 R_InitTextureMapping(); 367 368 // psprite scales 369 // proff 08/17/98: Changed for high-res 370 pspritescale = FRACUNIT*viewwidth/320; 371 pspriteiscale = FRACUNIT*320/viewwidth; 372 // proff 11/06/98: Added for high-res 373 pspriteyscale = (((SCREENHEIGHT*viewwidth)/SCREENWIDTH) << FRACBITS) / 200; 374 375 // thing clipping 376 for (i=0 ; i<viewwidth ; i++) 377 screenheightarray[i] = viewheight; 378 379 // planes 380 for (i=0 ; i<viewheight ; i++) 381 { // killough 5/2/98: reformatted 382 fixed_t dy = D_abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2); 383 // proff 08/17/98: Changed for high-res 384 yslope[i] = FixedDiv(projectiony, dy); 385 } 386 387 for (i=0 ; i<viewwidth ; i++) 388 { 389 fixed_t cosadj = D_abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]); 390 distscale[i] = FixedDiv(FRACUNIT,cosadj); 391 } 392 393 // Calculate the light levels to use 394 // for each level / scale combination. 395 for (i=0; i<LIGHTLEVELS; i++) 396 { 397 int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; 398 for (j=0 ; j<MAXLIGHTSCALE ; j++) 399 { 400 int t, level = startmap - j*320/viewwidth/DISTMAP; 401 402 if (level < 0) 403 level = 0; 404 405 if (level >= NUMCOLORMAPS) 406 level = NUMCOLORMAPS-1; 407 408 // killough 3/20/98: initialize multiple colormaps 409 level *= 256; 410 411 for (t=0; t<numcolormaps; t++) // killough 4/4/98 412 c_scalelight[t][i][j] = colormaps[t] + level; 413 } 414 } 415} 416 417// 418// R_Init 419// 420 421extern int screenblocks; 422 423void R_Init (void) 424{ 425 // CPhipps - R_DrawColumn isn't constant anymore, so must 426 // initialise in code 427 colfunc = R_DrawColumn; // current column draw function 428// if (SCREENWIDTH<320) 429// I_Error("R_Init: Screenwidth(%d) < 320",SCREENWIDTH); 430#if 1 431 432 printf("\nR_LoadTrigTables: "); 433 R_LoadTrigTables(); 434#endif 435 436 printf("\nR_InitData: "); 437 R_InitData(); 438 R_SetViewSize(screenblocks); 439 printf("\nR_Init: R_InitPlanes "); 440 R_InitPlanes(); 441 printf("R_InitLightTables "); 442 R_InitLightTables(); 443 printf("R_InitSkyMap "); 444 R_InitSkyMap(); 445 printf("R_InitTranslationsTables "); 446 R_InitTranslationTables(); 447} 448 449// 450// R_PointInSubsector 451// 452// killough 5/2/98: reformatted, cleaned up 453 454subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) 455{ 456 int nodenum = numnodes-1; 457 while (!(nodenum & NF_SUBSECTOR)) 458 nodenum = nodes[nodenum].children[R_PointOnSide(x, y, nodes+nodenum)]; 459 return &subsectors[nodenum & ~NF_SUBSECTOR]; 460} 461 462// 463// R_SetupFrame 464// 465 466void R_SetupFrame (player_t *player) 467{ 468 int i, cm; 469 470 viewplayer = player; 471 viewx = player->mo->x; 472 viewy = player->mo->y; 473 viewangle = player->mo->angle + viewangleoffset; 474 extralight = player->extralight; 475 476 viewz = player->viewz; 477 478 viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; 479 viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; 480 481 // killough 3/20/98, 4/4/98: select colormap based on player status 482 483 if (player->mo->subsector->sector->heightsec != -1) 484 { 485 const sector_t *s = player->mo->subsector->sector->heightsec + sectors; 486 cm = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ? 487 s->topmap : s->midmap; 488 if (cm < 0 || cm > numcolormaps) 489 cm = 0; 490 } 491 else 492 cm = 0; 493 494 fullcolormap = colormaps[cm]; 495 zlight = c_zlight[cm]; 496 scalelight = c_scalelight[cm]; 497 498 if (player->fixedcolormap) 499 { 500 // killough 3/20/98: localize scalelightfixed (readability/optimization) 501 static lighttable_t *scalelightfixed[MAXLIGHTSCALE]; 502 503 fixedcolormap = fullcolormap // killough 3/20/98: use fullcolormap 504 + player->fixedcolormap*256*sizeof(lighttable_t); 505 506 walllights = scalelightfixed; 507 508 for (i=0 ; i<MAXLIGHTSCALE ; i++) 509 scalelightfixed[i] = fixedcolormap; 510 } 511 else 512 fixedcolormap = 0; 513 514 validcount++; 515} 516 517// 518// R_RenderView 519// 520void R_RenderPlayerView (player_t* player) 521{ 522 R_SetupFrame (player); 523 524 // Clear buffers. 525 R_ClearClipSegs (); 526 R_ClearDrawSegs (); 527 R_ClearPlanes (); 528 R_ClearSprites (); 529 530 // check for new console commands. 531 // NetUpdate (); 532 533 // The head node is the last node output. 534 R_RenderBSPNode (numnodes-1); 535 536 // Check for new console commands. 537 // NetUpdate (); 538 539 R_DrawPlanes (); 540 541 // Check for new console commands. 542 // NetUpdate (); 543 544 R_DrawMasked (); 545 546 // Check for new console commands. 547 // NetUpdate (); 548}