From 7d67c9f789a3dc33da4b3da10edba4b3df2b179a Mon Sep 17 00:00:00 2001 From: jndean Date: Sat, 26 Aug 2023 15:22:55 +0000 Subject: [PATCH] Make non-recursive version of RenderBSPNode for IPU, add all angular calculations --- Makefile | 2 + src/ipu/ipu_interface.h | 5 + src/ipu/ipu_transfer.c | 11 + src/ipu/ipu_transfer.h | 1 + src/ipu/ipu_vertices.cpp | 3 + src/ipu/p_setup_codelets.cpp | 11 +- src/ipu/r_bsp.c | 96 +++++- src/ipu/r_bsp.h | 1 + src/ipu/r_codelets.cpp | 18 + src/ipu/r_draw.c | 11 +- src/ipu/r_main.c | 18 +- src/ipu/r_segs.c | 646 +++++++++++++++++++++++++++++++++++ src/ipu_host.cpp | 60 +++- src/ipu_host.h | 1 + src/ipu_transfer.c | 11 + src/ipu_transfer.h | 1 + src/r_bsp.c | 1 + src/r_main.c | 3 + 18 files changed, 862 insertions(+), 38 deletions(-) create mode 100644 src/ipu/r_segs.c diff --git a/Makefile b/Makefile index 6d2a0d2..3f932ed 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,9 @@ IPU_OBJ = $(addprefix build/ipu_obj/, \ p_mobj.gp \ r_bsp.gp \ r_codelets.gp \ + r_draw.gp \ r_main.gp \ + r_segs.gp \ tables.gp \ v_video.gp \ doomstat.gp \ diff --git a/src/ipu/ipu_interface.h b/src/ipu/ipu_interface.h index 239a660..e0138e1 100644 --- a/src/ipu/ipu_interface.h +++ b/src/ipu/ipu_interface.h @@ -59,6 +59,11 @@ typedef struct { } R_RenderPlayerView_MiscValues_t; +typedef struct { + int setblocks; + int setdetail; +} R_ExecuteSetViewSize_MiscValues_t; + #ifdef __cplusplus } diff --git a/src/ipu/ipu_transfer.c b/src/ipu/ipu_transfer.c index fe9ca64..24db13b 100644 --- a/src/ipu/ipu_transfer.c +++ b/src/ipu/ipu_transfer.c @@ -7,6 +7,11 @@ #include "ipu_transfer.h" #include "print.h" +extern int setblocks; // r_main.c +extern int setdetail; // r_main.c + + + int gamelumpnum; void IPU_G_LoadLevel_UnpackMiscValues(G_LoadLevel_MiscValues_t* pack) { @@ -59,4 +64,10 @@ void IPU_Setup_UnpackMarkNums(const unsigned char* buf) { void IPU_R_RenderPlayerView_UnpackMiscValues(R_RenderPlayerView_MiscValues_t* pack) { // Nothing to unpack +} + + +void IPU_R_ExecuteSetViewSize_UnpackMiscValues(R_ExecuteSetViewSize_MiscValues_t* pack) { + setblocks = pack->setblocks; + setdetail = pack->setdetail; } \ No newline at end of file diff --git a/src/ipu/ipu_transfer.h b/src/ipu/ipu_transfer.h index a145e64..4a948ad 100644 --- a/src/ipu/ipu_transfer.h +++ b/src/ipu/ipu_transfer.h @@ -16,6 +16,7 @@ extern unsigned char markbuf[IPUAMMARKBUFSIZE]; void IPU_G_LoadLevel_UnpackMiscValues(G_LoadLevel_MiscValues_t* pack); void IPU_G_Ticker_UnpackMiscValues(G_Ticker_MiscValues_t* pack); void IPU_R_RenderPlayerView_UnpackMiscValues(R_RenderPlayerView_MiscValues_t* pack); +void IPU_R_ExecuteSetViewSize_UnpackMiscValues(R_ExecuteSetViewSize_MiscValues_t* pack); #ifdef __cplusplus } diff --git a/src/ipu/ipu_vertices.cpp b/src/ipu/ipu_vertices.cpp index 214e4e5..17f7e52 100644 --- a/src/ipu/ipu_vertices.cpp +++ b/src/ipu/ipu_vertices.cpp @@ -1,7 +1,9 @@ #include +#include #include "doomtype.h" +#include "i_video.h" #include "ipu_print.h" @@ -28,6 +30,7 @@ class AM_Drawer_Vertex : public poplar::Vertex { poplar::InOut> frame; bool compute() { + assert(&frame[0] == I_VideoBuffer); AM_Drawer(&frame[0]); return true; } diff --git a/src/ipu/p_setup_codelets.cpp b/src/ipu/p_setup_codelets.cpp index c2eac06..d7b5826 100644 --- a/src/ipu/p_setup_codelets.cpp +++ b/src/ipu/p_setup_codelets.cpp @@ -1,9 +1,10 @@ #include -#include "poplar/StackSizeDefs.hpp" +#include #include #include "doomdata.h" +#include "i_video.h" #include "ipu_transfer.h" @@ -91,9 +92,15 @@ class P_SetupLevel_Vertex : public poplar::Vertex { class IPU_Setup_UnpackMarknumSprites_Vertex : public poplar::Vertex { poplar::Input> buf; + poplar::InOut> frame; + public: bool compute() { - IPU_Setup_UnpackMarkNums(&buf[0]); + IPU_Setup_UnpackMarkNums(&buf[0]); + + // Initialise I_VideoBuffer here for now :) + I_VideoBuffer = &frame[0]; + return true; } }; \ No newline at end of file diff --git a/src/ipu/r_bsp.c b/src/ipu/r_bsp.c index 44a6482..a333e18 100644 --- a/src/ipu/r_bsp.c +++ b/src/ipu/r_bsp.c @@ -35,6 +35,8 @@ //#include "r_local.h" +#include + seg_t *curline; side_t *sidedef; line_t *linedef; @@ -75,8 +77,13 @@ typedef struct { cliprange_t *newend; cliprange_t solidsegs[MAXSEGS]; +// JOSEF: !!!!!!!!!!!!!!!!!!!!! +// JOSEF: TMP to see if BSP is working +// JOSEF: !!!!!!!!!!!!!!!!!!!!! +void R_StoreWallRange(int start, int stop) { + // ACTUAL func in r_segs.c +} -/* // // R_ClipSolidWallSegment // Does handle solid walls, @@ -209,9 +216,7 @@ void R_ClearClipSegs(void) { solidsegs[1].last = 0x7fffffff; newend = solidsegs + 2; } -*/ -/* // // R_AddLine // Clips the given segment @@ -243,7 +248,7 @@ void R_AddLine(seg_t *line) { rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; - + tspan = angle1 + clipangle; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; @@ -291,6 +296,7 @@ void R_AddLine(seg_t *line) { backsector->floorheight != frontsector->floorheight) goto clippass; + /* LATER // Reject empty lines used for triggers // and special events. // Identical floor and ceiling on both sides, @@ -302,6 +308,7 @@ void R_AddLine(seg_t *line) { curline->sidedef->midtexture == 0) { return; } + */ clippass: R_ClipPassWallSegment(x1, x2 - 1); @@ -434,8 +441,10 @@ void R_Subsector(int num) { seg_t *line; subsector_t *sub; - if (num >= numsubsectors) - I_Error("R_Subsector: ss %i with numss = %i", num, numsubsectors); + if (num >= numsubsectors) { + // I_Error("R_Subsector: ss %i with numss = %i", num, numsubsectors); // JOSEF + printf("ERROR: R_Subsector: ss %d with numss = %d", num, numsubsectors); // JOSEF + } sscount++; sub = &subsectors[num]; @@ -443,6 +452,7 @@ void R_Subsector(int num) { count = sub->numlines; line = &segs[sub->firstline]; + /* LATER if (frontsector->floorheight < viewz) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, frontsector->lightlevel); @@ -458,6 +468,7 @@ void R_Subsector(int num) { ceilingplane = NULL; R_AddSprites(frontsector); + */ while (count--) { R_AddLine(line); @@ -465,11 +476,13 @@ void R_Subsector(int num) { } // check for solidsegs overflow - extremely unsatisfactory! - if (newend > &solidsegs[32]) - I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n"); + if (newend > &solidsegs[32]) { + // I_Error("R_Subsector: solidsegs overflow (vanilla may crash here)\n"); // JOSEF + printf("ERROR: R_Subsector: solidsegs overflow (vanilla may crash here)\n"); + } } -*/ +/* // // RenderBSPNode // Renders all subsectors below a given node, @@ -478,7 +491,7 @@ void R_Subsector(int num) { void R_RenderBSPNode(int bspnum) { node_t *bsp; int side; -/* + // Found a subsector? if (bspnum & NF_SUBSECTOR) { if (bspnum == -1) @@ -499,5 +512,66 @@ void R_RenderBSPNode(int bspnum) { // Possibly divide back space. if (R_CheckBBox(bsp->bbox[side ^ 1])) R_RenderBSPNode(bsp->children[side ^ 1]); - */ +} +*/ + +// +// RenderBSPNode +// Renders all subsectors below a given node, +// traversing subtree recursively. +// Just call with BSP root. +void R_RenderBSPNodeNonRecursive() { + node_t *bsp; + int side; + + const int maxRecursion = 30; + node_t* bspstack[maxRecursion]; + int sidestack[maxRecursion]; + + int depth = 0; + int bspnum = numnodes - 1; + + while (1) { + // Loop that descends tree, taking the front side of each node until it + // stops at a subsector to render + while (1) { + if (bspnum & NF_SUBSECTOR) { + if (bspnum == -1) + R_Subsector(0); + else + R_Subsector(bspnum & (~NF_SUBSECTOR)); + break; + } + + // Decide which side the view point is on. + bsp = &nodes[bspnum]; + side = R_PointOnSide(viewx, viewy, bsp); + + // Recurse to divide the front space. + bspnum = bsp->children[side]; + if (depth >= maxRecursion) { + printf("ERROR: R_RenderBSPNode exceeded max recursion\n"); + break; + } + bspstack[depth] = bsp; + sidestack[depth] = side; + depth++; + } + + // Loop that ascends up the tree until it finds a node where the 'other' + // branch is worth descending into. + while (1) { + depth--; + bsp = bspstack[depth]; + side = sidestack[depth]; + + bspnum = bsp->children[side ^ 1]; + // Recurse with new bspnum + if (R_CheckBBox(bsp->bbox[side ^ 1])) + break; + + if (depth == 0) + return; + } + } } diff --git a/src/ipu/r_bsp.h b/src/ipu/r_bsp.h index 0981680..735d351 100644 --- a/src/ipu/r_bsp.h +++ b/src/ipu/r_bsp.h @@ -52,5 +52,6 @@ void R_ClearClipSegs(void); void R_ClearDrawSegs(void); void R_RenderBSPNode(int bspnum); +void R_RenderBSPNodeNonRecursive(void); // Nonrecursive verion for IPU #endif diff --git a/src/ipu/r_codelets.cpp b/src/ipu/r_codelets.cpp index eaeefbe..a0f0d4e 100644 --- a/src/ipu/r_codelets.cpp +++ b/src/ipu/r_codelets.cpp @@ -1,14 +1,17 @@ +#include #include #include #include "doomstat.h" +#include "i_video.h" #include "ipu_transfer.h" extern "C" { void R_RenderPlayerView(player_t *player); + void R_ExecuteSetViewSize(void); }; @@ -19,6 +22,8 @@ struct R_RenderPlayerView_Vertex : public poplar::Vertex { poplar::InOut> frame; void compute() { + assert(&frame[0] == I_VideoBuffer); + for (int i = 0; i < 100; ++i){ frame[i + 320 * i ] = 1; frame[i + 320 * i + 1] = 1; @@ -30,3 +35,16 @@ struct R_RenderPlayerView_Vertex : public poplar::Vertex { return ; } }; + + +class R_ExecuteSetViewSize_Vertex : public poplar::Vertex { + public: + poplar::Input> miscValues; + bool compute() { + IPU_R_ExecuteSetViewSize_UnpackMiscValues( + (R_ExecuteSetViewSize_MiscValues_t*) &miscValues[0] + ); + R_ExecuteSetViewSize(); + return true; + } +}; \ No newline at end of file diff --git a/src/ipu/r_draw.c b/src/ipu/r_draw.c index 482ab3d..fa8e79d 100644 --- a/src/ipu/r_draw.c +++ b/src/ipu/r_draw.c @@ -21,16 +21,17 @@ // #include // JOSEF #include "d_mode.h" -// State. #include "doomstat.h" #include "doomtype.h" -/* -#include "i_system.h" -#include "i_video.h" #include "m_fixed.h" #include "r_defs.h" #include "r_main.h" #include "r_state.h" + +/* +// State. +#include "i_system.h" +#include "i_video.h" #include "v_patch.h" // Needs access to LFB (guess what). #include "v_video.h" @@ -672,6 +673,7 @@ void R_DrawSpanLow(void) { } while (count--); } +*/ // // R_InitBuffer @@ -703,6 +705,7 @@ void R_InitBuffer(int width, int height) { ylookup[i] = I_VideoBuffer + (i + viewwindowy) * SCREENWIDTH; } +/* // // R_FillBackScreen // Fills the back screen with a pattern diff --git a/src/ipu/r_main.c b/src/ipu/r_main.c index 3c13df1..d829592 100644 --- a/src/ipu/r_main.c +++ b/src/ipu/r_main.c @@ -118,7 +118,6 @@ void (*fuzzcolfunc)(void); void (*transcolfunc)(void); void (*spanfunc)(void); -/* // // R_AddPointToBox // Expand a given bbox @@ -182,6 +181,7 @@ int R_PointOnSide(fixed_t x, fixed_t y, node_t *node) { // back side return 1; } +/* int R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) { fixed_t lx; @@ -234,6 +234,7 @@ int R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) { // back side return 1; } +*/ // // R_PointToAngle @@ -313,6 +314,7 @@ angle_t R_PointToAngle2(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) { return R_PointToAngle(x2, y2); } +/* fixed_t R_PointToDist(fixed_t x, fixed_t y) { int angle; fixed_t dx; @@ -452,6 +454,7 @@ void R_InitTables(void) { } #endif } +*/ // // R_InitTextureMapping @@ -512,6 +515,7 @@ void R_InitTextureMapping(void) { clipangle = xtoviewangle[0]; } +/* // // R_InitLightTables // Only inits the zlight table, @@ -545,6 +549,7 @@ void R_InitLightTables(void) { } } } +*/ // // R_SetViewSize @@ -592,6 +597,7 @@ void R_ExecuteSetViewSize(void) { centeryfrac = centery << FRACBITS; projection = centerxfrac; + /* LATER if (!detailshift) { colfunc = basecolfunc = R_DrawColumn; fuzzcolfunc = R_DrawFuzzColumn; @@ -603,11 +609,14 @@ void R_ExecuteSetViewSize(void) { transcolfunc = R_DrawTranslatedColumnLow; spanfunc = R_DrawSpanLow; } + */ R_InitBuffer(scaledviewwidth, viewheight); R_InitTextureMapping(); + /* LATER + // psprite scales pspritescale = FRACUNIT * viewwidth / SCREENWIDTH; pspriteiscale = FRACUNIT * SCREENWIDTH / viewwidth; @@ -644,8 +653,10 @@ void R_ExecuteSetViewSize(void) { scalelight[i][j] = colormaps + level * 256; } } + */ } +/* // // R_Init // @@ -738,7 +749,7 @@ void R_RenderPlayerView(player_t *player) { R_SetupFrame(player); // Clear buffers. - // R_ClearClipSegs(); // TODO + R_ClearClipSegs(); // R_ClearDrawSegs(); // TODO // R_ClearPlanes(); // TODO // R_ClearSprites(); // TODO @@ -747,7 +758,8 @@ void R_RenderPlayerView(player_t *player) { // NetUpdate(); // TODO // The head node is the last node output. - R_RenderBSPNode(numnodes - 1); + // R_RenderBSPNode(numnodes - 1); + R_RenderBSPNodeNonRecursive(); // JOSEF: non-recursive version for IPU // Check for new console commands. // NetUpdate(); // TODO diff --git a/src/ipu/r_segs.c b/src/ipu/r_segs.c new file mode 100644 index 0000000..f8917a4 --- /dev/null +++ b/src/ipu/r_segs.c @@ -0,0 +1,646 @@ +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 2005-2014 Simon Howard +// +// 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. +// +// DESCRIPTION: +// All the clipping: columns, horizontal spans, sky columns. +// + +#include +// #include // JOSEF +// #include +// #include + +#include "doomdata.h" +#include "doomstat.h" +#include "doomtype.h" +#include "i_system.h" +#include "m_fixed.h" +#include "r_bsp.h" +#include "r_data.h" +#include "r_defs.h" +#include "r_draw.h" +#include "r_main.h" +#include "r_plane.h" +#include "r_state.h" +#include "r_things.h" +#include "tables.h" +#include "v_patch.h" + + +// OPTIMIZE: closed two sided lines as single sided + +// True if any of the segs textures might be visible. +boolean segtextured; + +// False if the back side is the same plane. +boolean markfloor; +boolean markceiling; + +boolean maskedtexture; +int toptexture; +int bottomtexture; +int midtexture; + +angle_t rw_normalangle; +// angle to line origin +int rw_angle1; + +// +// regular wall +// +int rw_x; +int rw_stopx; +angle_t rw_centerangle; +fixed_t rw_offset; +fixed_t rw_distance; +fixed_t rw_scale; +fixed_t rw_scalestep; +fixed_t rw_midtexturemid; +fixed_t rw_toptexturemid; +fixed_t rw_bottomtexturemid; + +int worldtop; +int worldbottom; +int worldhigh; +int worldlow; + +fixed_t pixhigh; +fixed_t pixlow; +fixed_t pixhighstep; +fixed_t pixlowstep; + +fixed_t topfrac; +fixed_t topstep; + +fixed_t bottomfrac; +fixed_t bottomstep; + +lighttable_t **walllights; + +short *maskedtexturecol; + +/* +// +// R_RenderMaskedSegRange +// +void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2) { + unsigned index; + column_t *col; + int lightnum; + int texnum; + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = texturetranslation[curline->sidedef->midtexture]; + + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT) + extralight; + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + + maskedtexturecol = ds->maskedtexturecol; + + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1) * rw_scalestep; + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + + // find positioning + if (curline->linedef->flags & ML_DONTPEGBOTTOM) { + dc_texturemid = frontsector->floorheight > backsector->floorheight + ? frontsector->floorheight + : backsector->floorheight; + dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; + } else { + dc_texturemid = frontsector->ceilingheight < backsector->ceilingheight + ? frontsector->ceilingheight + : backsector->ceilingheight; + dc_texturemid = dc_texturemid - viewz; + } + dc_texturemid += curline->sidedef->rowoffset; + + if (fixedcolormap) + dc_colormap = fixedcolormap; + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) { + // calculate lighting + if (maskedtexturecol[dc_x] != SHRT_MAX) { + if (!fixedcolormap) { + index = spryscale >> LIGHTSCALESHIFT; + + if (index >= MAXLIGHTSCALE) + index = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[index]; + } + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = + (column_t *)((byte *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + + R_DrawMaskedColumn(col); + maskedtexturecol[dc_x] = SHRT_MAX; + } + spryscale += rw_scalestep; + } +} + +// +// R_RenderSegLoop +// Draws zero, one, or two textures (and possibly a masked +// texture) for walls. +// Can draw or mark the starting pixel of floor and ceiling +// textures. +// CALLED: CORE LOOPING ROUTINE. +// +#define HEIGHTBITS 12 +#define HEIGHTUNIT (1 << HEIGHTBITS) + +void R_RenderSegLoop(void) { + angle_t angle; + unsigned index; + int yl; + int yh; + int mid; + fixed_t texturecolumn; + int top; + int bottom; + + for (; rw_x < rw_stopx; rw_x++) { + // mark floor / ceiling areas + yl = (topfrac + HEIGHTUNIT - 1) >> HEIGHTBITS; + + // no space above wall? + if (yl < ceilingclip[rw_x] + 1) + yl = ceilingclip[rw_x] + 1; + + if (markceiling) { + top = ceilingclip[rw_x] + 1; + bottom = yl - 1; + + if (bottom >= floorclip[rw_x]) + bottom = floorclip[rw_x] - 1; + + if (top <= bottom) { + ceilingplane->top[rw_x] = top; + ceilingplane->bottom[rw_x] = bottom; + } + } + + yh = bottomfrac >> HEIGHTBITS; + + if (yh >= floorclip[rw_x]) + yh = floorclip[rw_x] - 1; + + if (markfloor) { + top = yh + 1; + bottom = floorclip[rw_x] - 1; + if (top <= ceilingclip[rw_x]) + top = ceilingclip[rw_x] + 1; + if (top <= bottom) { + floorplane->top[rw_x] = top; + floorplane->bottom[rw_x] = bottom; + } + } + + // texturecolumn and lighting are independent of wall tiers + if (segtextured) { + // calculate texture offset + angle = (rw_centerangle + xtoviewangle[rw_x]) >> ANGLETOFINESHIFT; + texturecolumn = rw_offset - FixedMul(finetangent[angle], rw_distance); + texturecolumn >>= FRACBITS; + // calculate lighting + index = rw_scale >> LIGHTSCALESHIFT; + + if (index >= MAXLIGHTSCALE) + index = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[index]; + dc_x = rw_x; + dc_iscale = 0xffffffffu / (unsigned)rw_scale; + } else { + // purely to shut up the compiler + + texturecolumn = 0; + } + + // draw the wall tiers + if (midtexture) { + // single sided line + dc_yl = yl; + dc_yh = yh; + dc_texturemid = rw_midtexturemid; + dc_source = R_GetColumn(midtexture, texturecolumn); + colfunc(); + ceilingclip[rw_x] = viewheight; + floorclip[rw_x] = -1; + } else { + // two sided line + if (toptexture) { + // top wall + mid = pixhigh >> HEIGHTBITS; + pixhigh += pixhighstep; + + if (mid >= floorclip[rw_x]) + mid = floorclip[rw_x] - 1; + + if (mid >= yl) { + dc_yl = yl; + dc_yh = mid; + dc_texturemid = rw_toptexturemid; + dc_source = R_GetColumn(toptexture, texturecolumn); + colfunc(); + ceilingclip[rw_x] = mid; + } else + ceilingclip[rw_x] = yl - 1; + } else { + // no top wall + if (markceiling) + ceilingclip[rw_x] = yl - 1; + } + + if (bottomtexture) { + // bottom wall + mid = (pixlow + HEIGHTUNIT - 1) >> HEIGHTBITS; + pixlow += pixlowstep; + + // no space above wall? + if (mid <= ceilingclip[rw_x]) + mid = ceilingclip[rw_x] + 1; + + if (mid <= yh) { + dc_yl = mid; + dc_yh = yh; + dc_texturemid = rw_bottomtexturemid; + dc_source = R_GetColumn(bottomtexture, texturecolumn); + colfunc(); + floorclip[rw_x] = mid; + } else + floorclip[rw_x] = yh + 1; + } else { + // no bottom wall + if (markfloor) + floorclip[rw_x] = yh + 1; + } + + if (maskedtexture) { + // save texturecol + // for backdrawing of masked mid texture + maskedtexturecol[rw_x] = texturecolumn; + } + } + + rw_scale += rw_scalestep; + topfrac += topstep; + bottomfrac += bottomstep; + } +} + + +// +// R_StoreWallRange +// A wall segment will be drawn +// between start and stop pixels (inclusive). +// +void R_StoreWallRange(int start, int stop) { + fixed_t hyp; + fixed_t sineval; + angle_t distangle, offsetangle; + fixed_t vtop; + int lightnum; + + // don't overflow and crash + if (ds_p == &drawsegs[MAXDRAWSEGS]) + return; + + if (start >= viewwidth || start > stop) + I_Error("Bad R_RenderWallRange: %i to %i", start, stop); + + sidedef = curline->sidedef; + linedef = curline->linedef; + + // mark the segment as visible for auto map + linedef->flags |= ML_MAPPED; + + // calculate rw_distance for scale calculation + rw_normalangle = curline->angle + ANG90; + offsetangle = abs((int)(rw_normalangle - rw_angle1)); + + if (offsetangle > ANG90) + offsetangle = ANG90; + + distangle = ANG90 - offsetangle; + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + sineval = finesine[distangle >> ANGLETOFINESHIFT]; + rw_distance = FixedMul(hyp, sineval); + + ds_p->x1 = rw_x = start; + ds_p->x2 = stop; + ds_p->curline = curline; + rw_stopx = stop + 1; + + // calculate scale at both ends and step + ds_p->scale1 = rw_scale = + R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); + + if (stop > start) { + ds_p->scale2 = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[stop]); + ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (stop - start); + } else { +// UNUSED: try to fix the stretched line bug +#if 0 + if (rw_distance < FRACUNIT/2) + { + fixed_t trx,try; + fixed_t gxt,gyt; + + trx = curline->v1->x - viewx; + try = curline->v1->y - viewy; + + gxt = FixedMul(trx,viewcos); + gyt = -FixedMul(try,viewsin); + ds_p->scale1 = FixedDiv(projection, gxt-gyt)<scale2 = ds_p->scale1; + } + + // calculate texture boundaries + // and decide if floor / ceiling marks are needed + worldtop = frontsector->ceilingheight - viewz; + worldbottom = frontsector->floorheight - viewz; + + midtexture = toptexture = bottomtexture = maskedtexture = 0; + ds_p->maskedtexturecol = NULL; + + if (!backsector) { + // single sided line + midtexture = texturetranslation[sidedef->midtexture]; + // a single sided line is terminal, so it must mark ends + markfloor = markceiling = true; + if (linedef->flags & ML_DONTPEGBOTTOM) { + vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; + // bottom of texture at bottom + rw_midtexturemid = vtop - viewz; + } else { + // top of texture at top + rw_midtexturemid = worldtop; + } + rw_midtexturemid += sidedef->rowoffset; + + ds_p->silhouette = SIL_BOTH; + ds_p->sprtopclip = screenheightarray; + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT_MAX; + ds_p->tsilheight = INT_MIN; + } else { + // two sided line + ds_p->sprtopclip = ds_p->sprbottomclip = NULL; + ds_p->silhouette = 0; + + if (frontsector->floorheight > backsector->floorheight) { + ds_p->silhouette = SIL_BOTTOM; + ds_p->bsilheight = frontsector->floorheight; + } else if (backsector->floorheight > viewz) { + ds_p->silhouette = SIL_BOTTOM; + ds_p->bsilheight = INT_MAX; + // ds_p->sprbottomclip = negonearray; + } + + if (frontsector->ceilingheight < backsector->ceilingheight) { + ds_p->silhouette |= SIL_TOP; + ds_p->tsilheight = frontsector->ceilingheight; + } else if (backsector->ceilingheight < viewz) { + ds_p->silhouette |= SIL_TOP; + ds_p->tsilheight = INT_MIN; + // ds_p->sprtopclip = screenheightarray; + } + + if (backsector->ceilingheight <= frontsector->floorheight) { + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT_MAX; + ds_p->silhouette |= SIL_BOTTOM; + } + + if (backsector->floorheight >= frontsector->ceilingheight) { + ds_p->sprtopclip = screenheightarray; + ds_p->tsilheight = INT_MIN; + ds_p->silhouette |= SIL_TOP; + } + + worldhigh = backsector->ceilingheight - viewz; + worldlow = backsector->floorheight - viewz; + + // hack to allow height changes in outdoor areas + if (frontsector->ceilingpic == skyflatnum && + backsector->ceilingpic == skyflatnum) { + worldtop = worldhigh; + } + + if (worldlow != worldbottom || + backsector->floorpic != frontsector->floorpic || + backsector->lightlevel != frontsector->lightlevel) { + markfloor = true; + } else { + // same plane on both sides + markfloor = false; + } + + if (worldhigh != worldtop || + backsector->ceilingpic != frontsector->ceilingpic || + backsector->lightlevel != frontsector->lightlevel) { + markceiling = true; + } else { + // same plane on both sides + markceiling = false; + } + + if (backsector->ceilingheight <= frontsector->floorheight || + backsector->floorheight >= frontsector->ceilingheight) { + // closed door + markceiling = markfloor = true; + } + + if (worldhigh < worldtop) { + // top texture + toptexture = texturetranslation[sidedef->toptexture]; + if (linedef->flags & ML_DONTPEGTOP) { + // top of texture at top + rw_toptexturemid = worldtop; + } else { + vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; + + // bottom of texture + rw_toptexturemid = vtop - viewz; + } + } + if (worldlow > worldbottom) { + // bottom texture + bottomtexture = texturetranslation[sidedef->bottomtexture]; + + if (linedef->flags & ML_DONTPEGBOTTOM) { + // bottom of texture at bottom + // top of texture at top + rw_bottomtexturemid = worldtop; + } else // top of texture at top + rw_bottomtexturemid = worldlow; + } + rw_toptexturemid += sidedef->rowoffset; + rw_bottomtexturemid += sidedef->rowoffset; + + // allocate space for masked texture tables + if (sidedef->midtexture) { + // masked midtexture + maskedtexture = true; + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + } + } + + // calculate rw_offset (only needed for textured lines) + segtextured = midtexture | toptexture | bottomtexture | maskedtexture; + + if (segtextured) { + offsetangle = rw_normalangle - rw_angle1; + + if (offsetangle > ANG180) + offsetangle = -offsetangle; + + if (offsetangle > ANG90) + offsetangle = ANG90; + + sineval = finesine[offsetangle >> ANGLETOFINESHIFT]; + rw_offset = FixedMul(hyp, sineval); + + if (rw_normalangle - rw_angle1 < ANG180) + rw_offset = -rw_offset; + + rw_offset += sidedef->textureoffset + curline->offset; + rw_centerangle = ANG90 + viewangle - rw_normalangle; + + // calculate light table + // use different light tables + // for horizontal / vertical / diagonal + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + if (!fixedcolormap) { + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT) + extralight; + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + } + + // if a floor / ceiling plane is on the wrong side + // of the view plane, it is definitely invisible + // and doesn't need to be marked. + + if (frontsector->floorheight >= viewz) { + // above view plane + markfloor = false; + } + + if (frontsector->ceilingheight <= viewz && + frontsector->ceilingpic != skyflatnum) { + // below view plane + markceiling = false; + } + + // calculate incremental stepping values for texture edges + worldtop >>= 4; + worldbottom >>= 4; + + topstep = -FixedMul(rw_scalestep, worldtop); + topfrac = (centeryfrac >> 4) - FixedMul(worldtop, rw_scale); + + bottomstep = -FixedMul(rw_scalestep, worldbottom); + bottomfrac = (centeryfrac >> 4) - FixedMul(worldbottom, rw_scale); + + if (backsector) { + worldhigh >>= 4; + worldlow >>= 4; + + if (worldhigh < worldtop) { + pixhigh = (centeryfrac >> 4) - FixedMul(worldhigh, rw_scale); + pixhighstep = -FixedMul(rw_scalestep, worldhigh); + } + + if (worldlow > worldbottom) { + pixlow = (centeryfrac >> 4) - FixedMul(worldlow, rw_scale); + pixlowstep = -FixedMul(rw_scalestep, worldlow); + } + } + + // render it + if (markceiling) + ceilingplane = R_CheckPlane(ceilingplane, rw_x, rw_stopx - 1); + + if (markfloor) + floorplane = R_CheckPlane(floorplane, rw_x, rw_stopx - 1); + + R_RenderSegLoop(); + + // save sprite clipping info + if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) { + memcpy(lastopening, ceilingclip + start, + sizeof(*lastopening) * (rw_stopx - start)); + ds_p->sprtopclip = lastopening - start; + lastopening += rw_stopx - start; + } + + if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && + !ds_p->sprbottomclip) { + memcpy(lastopening, floorclip + start, + sizeof(*lastopening) * (rw_stopx - start)); + ds_p->sprbottomclip = lastopening - start; + lastopening += rw_stopx - start; + } + + if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) { + ds_p->silhouette |= SIL_TOP; + ds_p->tsilheight = INT_MIN; + } + if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) { + ds_p->silhouette |= SIL_BOTTOM; + ds_p->bsilheight = INT_MAX; + } + ds_p++; +} +*/ \ No newline at end of file diff --git a/src/ipu_host.cpp b/src/ipu_host.cpp index 8a24b37..9e28eda 100644 --- a/src/ipu_host.cpp +++ b/src/ipu_host.cpp @@ -43,6 +43,7 @@ class IpuDoom { void buildIpuGraph(); void run_AM_Drawer(); void run_R_RenderPlayerView(); + void run_R_ExecuteSetViewSize(); void run_IPU_Setup(); void run_G_DoLoadLevel(); void run_G_Ticker(); @@ -185,7 +186,7 @@ void IpuDoom::buildIpuGraph() { poplar::ComputeSet IPU_Setup_UnpackMarknumSprites_CS = m_ipuGraph.addComputeSet("IPU_Setup_UnpackMarknumSprites_CS"); vtx = m_ipuGraph.addVertex(IPU_Setup_UnpackMarknumSprites_CS, "IPU_Setup_UnpackMarknumSprites_Vertex", - {{"buf", marknumSpriteBuf}}); + {{"buf", marknumSpriteBuf}, {"frame", ipuFrame}}); m_ipuGraph.setTileMapping(vtx, 0); m_ipuGraph.setPerfEstimate(vtx, IPUAMMARKBUFSIZE * 100); @@ -198,25 +199,32 @@ void IpuDoom::buildIpuGraph() { // -------- R_RenderPlayerView_CS ------ // - - poplar::Tensor R_RenderPlayerView_MiscValsBuf = m_ipuGraph.addVariable(poplar::UNSIGNED_CHAR, {sizeof(R_RenderPlayerView_MiscValues_t)}, "R_RenderPlayerView_MiscValsBuf"); - m_ipuGraph.setTileMapping(R_RenderPlayerView_MiscValsBuf, 0); - auto R_RenderPlayerView_MiscValsBufStream = - m_ipuGraph.addHostToDeviceFIFO("R_RenderPlayerView_MiscValsBuf-stream", poplar::UNSIGNED_CHAR, sizeof(R_RenderPlayerView_MiscValues_t)); - poplar::ComputeSet R_RenderPlayerView_CS = m_ipuGraph.addComputeSet("R_RenderPlayerView_CS"); vtx = m_ipuGraph.addVertex(R_RenderPlayerView_CS, "R_RenderPlayerView_Vertex", - {{"frame", ipuFrame}, {"miscValues", R_RenderPlayerView_MiscValsBuf}}); + {{"frame", ipuFrame}, {"miscValues", m_miscValuesBuf}}); m_ipuGraph.setTileMapping(vtx, 0); m_ipuGraph.setPerfEstimate(vtx, 10000000); poplar::program::Sequence R_RenderPlayerView_prog({ - poplar::program::Copy(R_RenderPlayerView_MiscValsBufStream, R_RenderPlayerView_MiscValsBuf), + poplar::program::Copy(miscValuesStream, m_miscValuesBuf), poplar::program::Copy(frameInStream, ipuFrame), poplar::program::Execute(R_RenderPlayerView_CS), poplar::program::Copy(ipuFrame, frameOutStream), }); + // -------- R_ExecuteSetViewSize_CS ------ // + + poplar::ComputeSet R_ExecuteSetViewSize_CS = m_ipuGraph.addComputeSet("R_ExecuteSetViewSize_CS"); + vtx = m_ipuGraph.addVertex(R_ExecuteSetViewSize_CS, "R_ExecuteSetViewSize_Vertex", {{"miscValues", m_miscValuesBuf}}); + m_ipuGraph.setTileMapping(vtx, 0); + m_ipuGraph.setPerfEstimate(vtx, 100); + + poplar::program::Sequence R_ExecuteSetViewSize_prog({ + poplar::program::Copy(miscValuesStream, m_miscValuesBuf), + poplar::program::Execute(R_ExecuteSetViewSize_CS), + GetPrintbuf_prog // Remove? + }); + // ---------------- Final prog --------------// printf("Creating engine...\n"); @@ -227,7 +235,8 @@ void IpuDoom::buildIpuGraph() { G_Ticker_prog, G_Responder_prog, AM_Drawer_prog, - R_RenderPlayerView_prog + R_RenderPlayerView_prog, + R_ExecuteSetViewSize_prog, }))); m_ipuEngine->connectStream("frame-instream", I_VideoBuffer); @@ -245,23 +254,37 @@ void IpuDoom::buildIpuGraph() { m_ipuEngine->connectStreamToCallback("marknumSpriteBuf-stream", [this](void* p) { IPU_Setup_PackMarkNums(p); }); - m_ipuEngine->connectStreamToCallback("R_RenderPlayerView_MiscValsBuf-stream", [this](void* p) { - IPU_R_RenderPlayerView_PackMiscValues(p); - }); m_ipuEngine->load(m_ipuDevice); } // --- Internal interface from class IpuDoom to m_ipuEngine --- // -void IpuDoom::run_IPU_Setup() { m_ipuEngine->run(0); } -void IpuDoom::run_G_DoLoadLevel() { IPU_G_LoadLevel_PackMiscValues(m_miscValuesBuf_h); m_ipuEngine->run(1); } -void IpuDoom::run_G_Ticker() { IPU_G_Ticker_PackMiscValues(m_miscValuesBuf_h); m_ipuEngine->run(2); } +void IpuDoom::run_IPU_Setup() { + m_ipuEngine->run(0); +} +void IpuDoom::run_G_DoLoadLevel() { + IPU_G_LoadLevel_PackMiscValues(m_miscValuesBuf_h); + m_ipuEngine->run(1); +} +void IpuDoom::run_G_Ticker() { + IPU_G_Ticker_PackMiscValues(m_miscValuesBuf_h); + m_ipuEngine->run(2); +} void IpuDoom::run_G_Responder(G_Responder_MiscValues_t* src_buf) { IPU_G_Responder_PackMiscValues(src_buf, m_miscValuesBuf_h); m_ipuEngine->run(3); } -void IpuDoom::run_AM_Drawer() { m_ipuEngine->run(4); } -void IpuDoom::run_R_RenderPlayerView() { m_ipuEngine->run(5); } +void IpuDoom::run_AM_Drawer() { + m_ipuEngine->run(4); +} +void IpuDoom::run_R_RenderPlayerView() { + IPU_R_RenderPlayerView_PackMiscValues(m_miscValuesBuf_h); + m_ipuEngine->run(5); +} +void IpuDoom::run_R_ExecuteSetViewSize() { + IPU_R_ExecuteSetViewSize_PackMiscValues(m_miscValuesBuf_h); + m_ipuEngine->run(6); +} static std::unique_ptr ipuDoomInstance = nullptr; @@ -277,4 +300,5 @@ void IPU_R_RenderPlayerView() { ipuDoomInstance->run_R_RenderPlayerView(); } void IPU_G_DoLoadLevel() { ipuDoomInstance->run_G_DoLoadLevel(); } void IPU_G_Ticker() { ipuDoomInstance->run_G_Ticker(); } void IPU_G_Responder(G_Responder_MiscValues_t* buf) { ipuDoomInstance->run_G_Responder(buf); } +void IPU_R_ExecuteSetViewSize() { ipuDoomInstance->run_R_ExecuteSetViewSize(); } } diff --git a/src/ipu_host.h b/src/ipu_host.h index 19e9e72..dd089a8 100644 --- a/src/ipu_host.h +++ b/src/ipu_host.h @@ -12,6 +12,7 @@ void IPU_Init(void); void IPU_AM_Drawer(void); void IPU_R_RenderPlayerView(void); +void IPU_R_ExecuteSetViewSize(void); void IPU_G_DoLoadLevel(void); void IPU_G_Ticker(void); diff --git a/src/ipu_transfer.c b/src/ipu_transfer.c index 0fb8872..cb6de0c 100644 --- a/src/ipu_transfer.c +++ b/src/ipu_transfer.c @@ -16,6 +16,10 @@ #include "ipu/ipu_interface.h" +extern int setblocks; // r_main.c +extern int setdetail; // r_main.c + + void IPU_G_LoadLevel_PackMiscValues(void* buf) { assert(sizeof(G_LoadLevel_MiscValues_t) <= IPUMISCVALUESSIZE); @@ -97,6 +101,13 @@ void IPU_R_RenderPlayerView_PackMiscValues(void* buf) { // Nothing to pack } +void IPU_R_ExecuteSetViewSize_PackMiscValues(void* buf) { + assert(sizeof(R_ExecuteSetViewSize_MiscValues_t) <= IPUMISCVALUESSIZE); + R_ExecuteSetViewSize_MiscValues_t* pack = buf; + pack->setblocks = setblocks; + pack->setdetail = setdetail; +} + void IPU_Setup_PackMarkNums(void* buf) { int bufpos = 10 * sizeof(short); char namebuf[9] = "AMMNUM0\0"; diff --git a/src/ipu_transfer.h b/src/ipu_transfer.h index 82b4949..aa76f62 100644 --- a/src/ipu_transfer.h +++ b/src/ipu_transfer.h @@ -13,6 +13,7 @@ void IPU_G_LoadLevel_PackMiscValues(void* buf); void IPU_G_Ticker_PackMiscValues(void* buf); void IPU_G_Responder_PackMiscValues(void* src_buf, void* dst_buf); void IPU_R_RenderPlayerView_PackMiscValues(void* buf); +void IPU_R_ExecuteSetViewSize_PackMiscValues(void* buf); void IPU_LoadLumpForTransfer(int lumpnum, byte* buf); void IPU_Setup_PackMarkNums(void* buf); void IPU_NotifyLineMapped(line_t *line); diff --git a/src/r_bsp.c b/src/r_bsp.c index 961ed4a..aec1211 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -296,6 +296,7 @@ void R_AddLine(seg_t *line) { backsector->floorpic == frontsector->floorpic && backsector->lightlevel == frontsector->lightlevel && curline->sidedef->midtexture == 0) { + printf(" NOTE: Reject empty lines used for triggers\n"); return; } diff --git a/src/r_main.c b/src/r_main.c index e4a4453..803f089 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -558,6 +558,9 @@ void R_SetViewSize(int blocks, int detail) { // R_ExecuteSetViewSize // void R_ExecuteSetViewSize(void) { + + IPU_R_ExecuteSetViewSize(); + fixed_t cosadj; fixed_t dy; int i;