diff options
| author | Dave Chapman <dave@dchapman.com> | 2006-03-28 15:44:01 +0000 |
|---|---|---|
| committer | Dave Chapman <dave@dchapman.com> | 2006-03-28 15:44:01 +0000 |
| commit | 47f4a458d636a889e955e68f896708f1276febc0 (patch) | |
| tree | 99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/r_main.c | |
| parent | fff7d6157d56f233cad5c2003475e47a5ff809a7 (diff) | |
| download | rockbox-47f4a458d636a889e955e68f896708f1276febc0.zip rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.gz rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.bz2 rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.xz | |
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/doom/r_main.c')
| -rw-r--r-- | apps/plugins/doom/r_main.c | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/apps/plugins/doom/r_main.c b/apps/plugins/doom/r_main.c new file mode 100644 index 0000000..f79097a --- /dev/null +++ b/apps/plugins/doom/r_main.c @@ -0,0 +1,531 @@ +/* Emacs style mode select -*- C++ -*- + *----------------------------------------------------------------------------- + * + * + * PrBoom a Doom port merged with LxDoom and LSDLDoom + * based on BOOM, a modified and improved DOOM engine + * Copyright (C) 1999 by + * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman + * Copyright (C) 1999-2000 by + * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze + * + * 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. + * + * DESCRIPTION: + * Rendering main loop and setup functions, + * utility functions (BSP, geometry, trigonometry). + * See tables.c, too. + * + *-----------------------------------------------------------------------------*/ + +#include "doomstat.h" +#include "w_wad.h" +#include "r_main.h" +#include "r_things.h" +#include "r_plane.h" +#include "r_bsp.h" +#include "r_draw.h" +#include "m_bbox.h" +#include "r_sky.h" +#include "v_video.h" +#include "i_system.h" +//#include "lprintf.h" +#include "st_stuff.h" +#include "rockmacros.h" + +// Fineangles in the SCREENWIDTH wide window. +#define FIELDOFVIEW 2048 + +// killough: viewangleoffset is a legacy from the pre-v1.2 days, when Doom +// had Left/Mid/Right viewing. +/-ANG90 offsets were placed here on each +// node, by d_net.c, to set up a L/M/R session. + +int viewangleoffset; + +int validcount = 1; // increment every time a check is made +lighttable_t *fixedcolormap; +int centerx IBSS_ATTR; +int centery IBSS_ATTR; +fixed_t centerxfrac, centeryfrac; +fixed_t projection; +fixed_t viewx, viewy, viewz; +angle_t viewangle; +fixed_t viewcos, viewsin; +player_t *viewplayer; +extern lighttable_t **walllights; + +// +// precalculated math tables +// + +angle_t clipangle; + +// The viewangletox[viewangle + FINEANGLES/4] lookup +// maps the visible view angles to screen X coordinates, +// flattening the arc to a flat projection plane. +// There will be many angles mapped to the same X. + +int viewangletox[FINEANGLES/2]; + +// The xtoviewangleangle[] table maps a screen pixel +// to the lowest viewangle that maps back to x ranges +// from clipangle to -clipangle. + +angle_t xtoviewangle[SCREENWIDTH+1]; // killough 2/8/98 + +// killough 3/20/98: Support dynamic colormaps, e.g. deep water +// killough 4/4/98: support dynamic number of them as well + +int numcolormaps; +lighttable_t *(*c_scalelight)[LIGHTLEVELS][MAXLIGHTSCALE]; +lighttable_t *(*c_zlight)[LIGHTLEVELS][MAXLIGHTZ]; +lighttable_t *(*scalelight)[MAXLIGHTSCALE]; +lighttable_t *(*zlight)[MAXLIGHTZ]; +lighttable_t *fullcolormap; +lighttable_t **colormaps; + +// killough 3/20/98, 4/4/98: end dynamic colormaps + +int extralight; // bumped light from gun blasts + +void (*colfunc)(void); + +// +// R_PointOnSide +// Traverse BSP (sub) tree, +// check point against partition plane. +// Returns side 0 (front) or 1 (back). +// +// killough 5/2/98: reformatted +// + +int R_PointOnSide(fixed_t x, fixed_t y, const node_t *node) +{ + if (!node->dx) + return x <= node->x ? node->dy > 0 : node->dy < 0; + + if (!node->dy) + return y <= node->y ? node->dx < 0 : node->dx > 0; + + x -= node->x; + y -= node->y; + + // Try to quickly decide by looking at sign bits. + if ((node->dy ^ node->dx ^ x ^ y) < 0) + return (node->dy ^ x) < 0; // (left is negative) + return FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x); +} + +// killough 5/2/98: reformatted + +int R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) +{ + fixed_t lx = line->v1->x; + fixed_t ly = line->v1->y; + fixed_t ldx = line->v2->x - lx; + fixed_t ldy = line->v2->y - ly; + + if (!ldx) + return x <= lx ? ldy > 0 : ldy < 0; + + if (!ldy) + return y <= ly ? ldx < 0 : ldx > 0; + + x -= lx; + y -= ly; + + // Try to quickly decide by looking at sign bits. + if ((ldy ^ ldx ^ x ^ y) < 0) + return (ldy ^ x) < 0; // (left is negative) + return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x); +} + +// +// R_PointToAngle +// To get a global angle from cartesian coordinates, +// the coordinates are flipped until they are in +// the first octant of the coordinate system, then +// the y (<=x) is scaled and divided by x to get a +// tangent (slope) value which is looked up in the +// tantoangle[] table. The +1 size of tantoangle[] +// is to handle the case when x==y without additional +// checking. +// +// killough 5/2/98: reformatted, cleaned up + +angle_t R_PointToAngle(fixed_t x, fixed_t y) +{ + return (y -= viewy, (x -= viewx) || y) ? + x >= 0 ? + y >= 0 ? + (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 + ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 + x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 + ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7 + y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3 + ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2 + (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4 + ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 + 0; +} + +angle_t R_PointToAngle2(fixed_t viewx, fixed_t viewy, fixed_t x, fixed_t y) +{ + return (y -= viewy, (x -= viewx) || y) ? + x >= 0 ? + y >= 0 ? + (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 + ANG90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 + x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 + ANG270+tantoangle[SlopeDiv(x,y)] : // octant 7 + y >= 0 ? (x = -x) > y ? ANG180-1-tantoangle[SlopeDiv(y,x)] : // octant 3 + ANG90 + tantoangle[SlopeDiv(x,y)] : // octant 2 + (x = -x) > (y = -y) ? ANG180+tantoangle[ SlopeDiv(y,x)] : // octant 4 + ANG270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 + 0; +} + +// +// R_InitTextureMapping +// +// killough 5/2/98: reformatted + +static void R_InitTextureMapping (void) +{ + register int i,x; + fixed_t focallength; + + // Use tangent table to generate viewangletox: + // viewangletox will give the next greatest x + // after the view angle. + // + // Calc focallength + // so FIELDOFVIEW angles covers SCREENWIDTH. + + focallength = FixedDiv(centerxfrac, finetangent[FINEANGLES/4+FIELDOFVIEW/2]); + + for (i=0 ; i<FINEANGLES/2 ; i++) + { + int t; + if (finetangent[i] > FRACUNIT*2) + t = -1; + else + if (finetangent[i] < -FRACUNIT*2) + t = viewwidth+1; + else + { + t = FixedMul(finetangent[i], focallength); + t = (centerxfrac - t + FRACUNIT-1) >> FRACBITS; + if (t < -1) + t = -1; + else + if (t > viewwidth+1) + t = viewwidth+1; + } + viewangletox[i] = t; + } + + // Scan viewangletox[] to generate xtoviewangle[]: + // xtoviewangle will give the smallest view angle + // that maps to x. + + for (x=0; x<=viewwidth; x++) + { + for (i=0; viewangletox[i] > x; i++) + ; + xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90; + } + + // Take out the fencepost cases from viewangletox. + for (i=0; i<FINEANGLES/2; i++) + if (viewangletox[i] == -1) + viewangletox[i] = 0; + else + if (viewangletox[i] == viewwidth+1) + viewangletox[i] = viewwidth; + + clipangle = xtoviewangle[0]; +} + +// +// R_InitLightTables +// Only inits the zlight table, +// because the scalelight table changes with view size. +// + +#define DISTMAP 2 + +void R_InitLightTables (void) +{ + int i; + + // killough 4/4/98: dynamic colormaps + c_zlight = malloc(sizeof(*c_zlight) * numcolormaps); + c_scalelight = malloc(sizeof(*c_scalelight) * numcolormaps); + + // Calculate the light levels to use + // for each level / distance combination. + for (i=0; i< LIGHTLEVELS; i++) + { + int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; + for (j=0; j<MAXLIGHTZ; j++) + { + // CPhipps - use 320 here instead of SCREENWIDTH, otherwise hires is + // brighter than normal res + int scale = FixedDiv ((320/2*FRACUNIT), (j+1)<<LIGHTZSHIFT); + int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP; + + if (level < 0) + level = 0; + else + if (level >= NUMCOLORMAPS) + level = NUMCOLORMAPS-1; + + // killough 3/20/98: Initialize multiple colormaps + level *= 256; + for (t=0; t<numcolormaps; t++) // killough 4/4/98 + c_zlight[t][i][j] = colormaps[t] + level; + } + } +} + +// +// R_SetViewSize +// Do not really change anything here, +// because it might be in the middle of a refresh. +// The change will take effect next refresh. +// + +boolean setsizeneeded; +int setblocks; + +void R_SetViewSize(int blocks) +{ + setsizeneeded = true; + setblocks = blocks; +} + +// +// R_ExecuteSetViewSize +// + +void R_ExecuteSetViewSize (void) +{ + int i; + + setsizeneeded = false; + + if (setblocks == 11) + { + scaledviewwidth = SCREENWIDTH; + viewheight = SCREENHEIGHT; + } + else + { + scaledviewwidth = setblocks*32; + viewheight = (setblocks*168/10)&~7; + } + + viewwidth = scaledviewwidth; + + centery = viewheight/2; + centerx = viewwidth/2; + centerxfrac = centerx<<FRACBITS; + centeryfrac = centery<<FRACBITS; + projection = centerxfrac; + + R_InitBuffer (scaledviewwidth, viewheight); + + R_InitTextureMapping(); + + // psprite scales + pspritescale = FRACUNIT*viewwidth/SCREENWIDTH; + pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth; + + // thing clipping + for (i=0 ; i<viewwidth ; i++) + screenheightarray[i] = viewheight; + + // planes + for (i=0 ; i<viewheight ; i++) + { // killough 5/2/98: reformatted + fixed_t dy = D_abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2); + yslope[i] = FixedDiv ( (viewwidth)/2*FRACUNIT, dy); + } + + for (i=0 ; i<viewwidth ; i++) + { + fixed_t cosadj = D_abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]); + distscale[i] = FixedDiv(FRACUNIT,cosadj); + } + + // Calculate the light levels to use + // for each level / scale combination. + for (i=0; i<LIGHTLEVELS; i++) + { + int j, startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; + for (j=0 ; j<MAXLIGHTSCALE ; j++) + { + // CPhipps - use 320 here instead of SCREENWIDTH, otherwise hires is + // brighter than normal res + int scale = FixedDiv ((320/2*FRACUNIT), (j+1)<<LIGHTZSHIFT); + int t, level = startmap - (scale >>= LIGHTSCALESHIFT)/DISTMAP; + + if (level < 0) + level = 0; + + if (level >= NUMCOLORMAPS) + level = NUMCOLORMAPS-1; + + // killough 3/20/98: initialize multiple colormaps + level *= 256; + + for (t=0; t<numcolormaps; t++) // killough 4/4/98 + c_scalelight[t][i][j] = colormaps[t] + level; + } + } +} + +// +// R_Init +// + +extern int screenblocks; + +void R_Init (void) +{ + // CPhipps - R_DrawColumn isn't constant anymore, so must + // initialise in code + colfunc = R_DrawColumn; // current column draw function + if (SCREENWIDTH<320) + I_Error("R_Init: Screenwidth(%d) < 320",SCREENWIDTH); +#if 1 + printf("\nR_LoadTrigTables: "); + R_LoadTrigTables(); +#endif + printf("\nR_InitData: "); + R_InitData(); + R_SetViewSize(screenblocks); + printf("\nR_Init: R_InitPlanes "); + R_InitPlanes(); + printf("R_InitLightTables "); + R_InitLightTables(); + printf("R_InitSkyMap "); + R_InitSkyMap(); + printf("R_InitTranslationsTables "); + R_InitTranslationTables(); +} + +// +// R_PointInSubsector +// +// killough 5/2/98: reformatted, cleaned up + +subsector_t *R_PointInSubsector(fixed_t x, fixed_t y) +{ + int nodenum = numnodes-1; + while (!(nodenum & NF_SUBSECTOR)) + nodenum = nodes[nodenum].children[R_PointOnSide(x, y, nodes+nodenum)]; + return &subsectors[nodenum & ~NF_SUBSECTOR]; +} + +// +// R_SetupFrame +// + +void R_SetupFrame (player_t *player) +{ + int i, cm; + + viewplayer = player; + viewx = player->mo->x; + viewy = player->mo->y; + viewangle = player->mo->angle + viewangleoffset; + extralight = player->extralight; + + viewz = player->viewz; + + viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; + viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; + + // killough 3/20/98, 4/4/98: select colormap based on player status + + if (player->mo->subsector->sector->heightsec != -1) + { + const sector_t *s = player->mo->subsector->sector->heightsec + sectors; + cm = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ? + s->topmap : s->midmap; + if (cm < 0 || cm > numcolormaps) + cm = 0; + } + else + cm = 0; + + fullcolormap = colormaps[cm]; + zlight = c_zlight[cm]; + scalelight = c_scalelight[cm]; + + if (player->fixedcolormap) + { + // killough 3/20/98: localize scalelightfixed (readability/optimization) + static lighttable_t *scalelightfixed[MAXLIGHTSCALE]; + + fixedcolormap = fullcolormap // killough 3/20/98: use fullcolormap + + player->fixedcolormap*256*sizeof(lighttable_t); + + walllights = scalelightfixed; + + for (i=0 ; i<MAXLIGHTSCALE ; i++) + scalelightfixed[i] = fixedcolormap; + } + else + fixedcolormap = 0; + + validcount++; +} + +// +// R_RenderView +// +void R_RenderPlayerView (player_t* player) +{ + R_SetupFrame (player); + + // Clear buffers. + R_ClearClipSegs (); + R_ClearDrawSegs (); + R_ClearPlanes (); + R_ClearSprites (); + + // check for new console commands. + // NetUpdate (); + + // The head node is the last node output. + R_RenderBSPNode (numnodes-1); + + // Check for new console commands. + // NetUpdate (); + + R_DrawPlanes (); + + // Check for new console commands. + // NetUpdate (); + + R_DrawMasked (); + + // Check for new console commands. + // NetUpdate (); +} |