summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/r_main.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
committerDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
commit47f4a458d636a889e955e68f896708f1276febc0 (patch)
tree99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/r_main.c
parentfff7d6157d56f233cad5c2003475e47a5ff809a7 (diff)
downloadrockbox-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.c531
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 ();
+}