private void HovDrawInitialise() { // as: bugfix - Extended sintable length by 1, BuildTables writes one element past the end of the array sintable = new fixed_t[ANGLES + ANGLES / 4 + 1]; costable = new costable_t(sintable); for(short i = 0; i < walls.Length; i++) walls[i] = new walltype(i); }
/// <summary>Copies the walltype to another.</summary> /// <remarks>For struct assignment.</remarks> /// <param name="destination">The destination walltype.</param> public void CopyTo(walltype destination) { destination._index = _index; destination.x1 = x1; destination.x2 = x2; destination.leftclip = leftclip; destination.rightclip = rightclip; destination.height1 = height1; destination.height2 = height2; destination.color = color; }
//========================================================================== /* ================= = = StartView = = Called by player think = ================= */ private void StartView() { // // set up variables for this view // viewangle = objlist[0].angle; viewsin = sintable[viewangle]; viewcos = costable[viewangle]; viewx = FixedAdd(objlist[0].x, FixedByFrac(FOCALLENGTH, viewcos) ^ SIGNBIT); viewy = FixedAdd(objlist[0].y, FixedByFrac(FOCALLENGTH, viewsin)); focal.x = (short) (viewx >> TILESHIFT); focal.y = (short) (viewy >> TILESHIFT); // // find the rightmost visable tile in view // short tracedir = (short) (viewangle + lastangle); if(tracedir < 0) tracedir += ANGLES; else if(tracedir >= ANGLES) tracedir -= ANGLES; TraceRay((ushort) tracedir); right.x = tile.x; right.y = tile.y; // // find the leftmost visable tile in view // tracedir = (short) (viewangle + firstangle); if(tracedir < 0) tracedir += ANGLES; else if(tracedir >= ANGLES) tracedir -= ANGLES; TraceRay((ushort) tracedir); // // follow the walls from there to the right // rightwall = walls[1]; #if DEBUG_IGNORE_RENDER_FAILS // FIXME as: Prevent rendering errors crashing the game try { FollowWalls(); } catch { } #else FollowWalls(); #endif }
/* =================== = = DrawWall = = Special polygon with vertical edges and symetrical top / bottom = Clips horizontally to clipleft/clipright = Clips vertically to VIEWY/VIEWYH = Should only be called if the wall is at least partially visable = ================== */ private void DrawWall(walltype wallptr) { wallptr.CopyTo(drawWall_wall); short i = (short) (drawWall_wall.height1 / 2); drawWall_y1l = (short) (CENTERY - i); drawWall_y1h = (short) (CENTERY + i); i = (short) (drawWall_wall.height2 / 2); drawWall_y2l = (short) (CENTERY - i); drawWall_y2h = (short) (CENTERY + i); if(drawWall_wall.x1 > drawWall_wall.leftclip) drawWall_wall.leftclip = drawWall_wall.x1; if(drawWall_wall.x2 < drawWall_wall.rightclip) drawWall_wall.rightclip = drawWall_wall.x2; // // fill in the zbuffer // int height = (int) drawWall_wall.height1 << 16; int heightstep; if(drawWall_wall.x2 != drawWall_wall.x1) heightstep = ((int) (drawWall_wall.height2 - drawWall_wall.height1) << 16) / (short) (drawWall_wall.x2 - drawWall_wall.x1); else heightstep = 0; i = (short) (drawWall_wall.leftclip - drawWall_wall.x1); if(i != 0) height += heightstep * i; // adjust for clipped area for(short x = drawWall_wall.leftclip; x <= drawWall_wall.rightclip; x++) { zbuffer[x] = (short) (height >> 16); height += heightstep; } // // draw the wall to the line buffer // if(drawWall_y1l == drawWall_y2l) { // // rectangle, no slope // if(drawWall_y1l < VIEWY) drawWall_y1l = VIEWY; if(drawWall_y1h > VIEWYH) drawWall_y1h = VIEWYH; for(short y = drawWall_y1l; y <= drawWall_y1h; y++) ADDLINE(drawWall_wall.leftclip, drawWall_wall.rightclip, y, (short) drawWall_wall.color); return; } if(drawWall_y1l < drawWall_y2l) { // // slopes down to the right // short slope = (short) (((int) (drawWall_wall.x2 - drawWall_wall.x1) << 6) / (drawWall_y2l - drawWall_y1l)); // in 128ths short ysteps = (short) (drawWall_y2l - drawWall_y1l); if(drawWall_y1l < VIEWY) ysteps -= (short) (VIEWY - drawWall_y1l); short endfrac = (short) (drawWall_wall.x2 << 6); for(short y = 1; y < ysteps; y++) // top and bottom slopes { endfrac -= slope; short end = (short) (endfrac >> 6); if(end > drawWall_wall.rightclip) end = drawWall_wall.rightclip; else if(end < drawWall_wall.leftclip) // the rest is hidden break; ADDLINE(drawWall_wall.leftclip, end, (short) (drawWall_y2l - y), (short) drawWall_wall.color); ADDLINE(drawWall_wall.leftclip, end, (short) (drawWall_y2h + y), (short) drawWall_wall.color); } if(drawWall_y2l < VIEWY) drawWall_y2l = VIEWY; if(drawWall_y2h > VIEWYH) drawWall_y2h = VIEWYH; for(short y = drawWall_y2l; y <= drawWall_y2h; y++) // middle ADDLINE(drawWall_wall.leftclip, drawWall_wall.rightclip, y, (short) drawWall_wall.color); } else { // // slopes down to the left // short slope = (short) (((int) (drawWall_wall.x2 - drawWall_wall.x1) << 6) / (drawWall_y1l - drawWall_y2l)); // in 128ths short ysteps = (short) (drawWall_y1l - drawWall_y2l); if(drawWall_y2l < VIEWY) ysteps -= (short) (VIEWY - drawWall_y2l); short endfrac = (short) (drawWall_wall.x1 << 6); for(short y = 1; y < ysteps; y++) // top and bottom slopes { endfrac += slope; short end = (short) (endfrac >> 6); if(end < drawWall_wall.leftclip) end = drawWall_wall.leftclip; else if(end > drawWall_wall.rightclip) // the rest is hidden break; ADDLINE(end, drawWall_wall.rightclip, (short) (drawWall_y1l - y), (short) drawWall_wall.color); ADDLINE(end, drawWall_wall.rightclip, (short) (drawWall_y1h + y), (short) drawWall_wall.color); } if(drawWall_y1l < VIEWY) drawWall_y1l = VIEWY; if(drawWall_y1h > VIEWYH) drawWall_y1h = VIEWYH; for(short y = drawWall_y1l; y <= drawWall_y1h; y++) // middle ADDLINE(drawWall_wall.leftclip, drawWall_wall.rightclip, y, (short) drawWall_wall.color); } }
//=========================================================================== /* ================= = = FinishWall = = Transforms edgex,edgey as the next point of the current wall = and sticks it in the wall list = ================= */ private bool FinishWall() { oldwall = rightwall; if((wallon & 1) != 0) rightwall.color = (ushort) (basecolor + 8); // high intensity walls else rightwall.color = (ushort) basecolor; TransformPoint(edgex, edgey, ref rightwall.x2, ref rightwall.height2); walltype rightwall_1 = walls[rightwall.index - 1]; if(rightwall.x2 <= rightwall_1.x2 + 2 && rightwall.height2 < rightwall_1.height2) return false; rightwall = walls[rightwall.index + 1]; return true; }