]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/hb/c3_trace.c
[16_ca needs huge amounts of work and I should remember what needs to be done soon...
[16.git] / src / lib / hb / c3_trace.c
diff --git a/src/lib/hb/c3_trace.c b/src/lib/hb/c3_trace.c
new file mode 100755 (executable)
index 0000000..45cb1bc
--- /dev/null
@@ -0,0 +1,872 @@
+/* Catacomb 3-D Source Code\r
+ * Copyright (C) 1993-2014 Flat Rock Software\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License along\r
+ * with this program; if not, write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+ */\r
+\r
+// C3_TRACE.C\r
+\r
+#include "C3_DEF.H"\r
+#pragma hdrstop\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+//\r
+// TESTWALLVISABLE will set the global variable wallvisable to 1 or 0\r
+// depending on if tile.x,tile.y,wallon is visable from focal point\r
+//\r
+#define TESTWALLVISABLE {                                              \\r
+       if (tile.y<focal.y)                         \\r
+               voffset = 0;                            \\r
+       else if (tile.y==focal.y)                   \\r
+               voffset = 3;                            \\r
+       else                                        \\r
+               voffset = 6;                            \\r
+       if (tile.x==focal.x)                        \\r
+               voffset ++;                             \\r
+       else if (tile.x>focal.x)                    \\r
+               voffset += 2;                           \\r
+       wallvisable = visable[voffset][wallon]; }\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+boolean        aborttrace;\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+unsigned       wallvisable,voffset;\r
+\r
+\r
+fixed edgex,edgey;\r
+\r
+int wallon;\r
+int basecolor;\r
+\r
+walltype *oldwall;\r
+\r
+//\r
+// offsets from upper left corner of a tile to the left and right edges of\r
+// a given wall (NORTH-WEST)\r
+//\r
+fixed point1x[4] = {GLOBAL1,GLOBAL1,0      ,0       };\r
+fixed point1y[4] = {0      ,GLOBAL1,GLOBAL1,0       };\r
+\r
+fixed point2x[4] = {0      ,GLOBAL1,GLOBAL1,0       };\r
+fixed point2y[4] = {0     ,0      ,GLOBAL1 ,GLOBAL1};\r
+\r
+\r
+//\r
+// offset from tile.x,tile.y of the tile that shares wallon side\r
+// (side is not visable if it is shared)\r
+//\r
+int sharex[4] = { 0, 1, 0,-1};\r
+int sharey[4] = {-1, 0, 1, 0};\r
+\r
+//\r
+// amount to move tile.x,tile.y to follow wallon to another tile\r
+//\r
+int followx[4] = {-1, 0, 1, 0};\r
+int followy[4] = { 0,-1, 0, 1};\r
+\r
+//\r
+// cornerwall gives the wall on the same tile to start following when the\r
+// wall ends at an empty tile (go around an edge on same tile)\r
+// turnwall gives the wall on tile.x+sharex,tile.y+sharey to start following\r
+// when the wall hits another tile (right angle corner)\r
+//\r
+int cornerwall[4] = {WEST,NORTH,EAST,SOUTH};\r
+int turnwall[4] = {EAST,SOUTH,WEST,NORTH};\r
+\r
+//\r
+// wall visabilities in reletive locations\r
+// -,- 0,- +,-\r
+// -,0 0,0 +,0\r
+// -,+ 0,+ +,+\r
+//\r
+int visable[9][4] =\r
+{\r
+ {0,1,1,0}, {0,0,1,0}, {0,0,1,1},\r
+ {0,1,0,0}, {0,0,0,0}, {0,0,0,1},\r
+ {1,1,0,0}, {1,0,0,0}, {1,0,0,1}\r
+};\r
+\r
+int startwall[9] =  {2,2,3, 1,0,3, 1,0,0};\r
+int backupwall[9] = {3,3,0, 2,0,0, 2,1,1};\r
+\r
+\r
+int    walllength;\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                        FUNCTIONS\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+========================\r
+=\r
+= FollowTrace\r
+=\r
+========================\r
+*/\r
+\r
+int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max)\r
+{\r
+       int tx,ty,otx,oty;\r
+       long absdx,absdy,xstep,ystep;\r
+\r
+       tx = tracex>>TILESHIFT;\r
+       ty = tracey>>TILESHIFT;\r
+\r
+       spotvis[tx][ty] = true;\r
+\r
+       absdx=LABS(deltax);\r
+       absdy=LABS(deltay);\r
+\r
+       if (absdx>absdy)\r
+       {\r
+               ystep = (deltay<<8)/(absdx>>8);\r
+\r
+               if (!ystep)\r
+                       ystep = deltay>0 ? 1 : -1;\r
+\r
+               oty = (tracey+ystep)>>TILESHIFT;\r
+               if (deltax>0)\r
+               {\r
+//###############\r
+//\r
+// step x by +1\r
+//\r
+//###############\r
+                       do\r
+                       {\r
+                               tx++;\r
+                               spotvis[tx][ty] = true;\r
+                               tracey+=ystep;\r
+                               ty = tracey>>TILESHIFT;\r
+\r
+                               if (ty!=oty)\r
+                               {\r
+                                       if (tilemap[tx-1][ty])\r
+                                       {\r
+                                               tile.x = tx-1;\r
+                                               tile.y = ty;\r
+                                               return 1;\r
+                                       }\r
+                                       oty = ty;\r
+                               }\r
+                               if (tilemap[tx][ty])\r
+                               {\r
+                                       tile.x = tx;\r
+                                       tile.y = ty;\r
+                                       return 1;\r
+                               }\r
+                       } while (--max);\r
+                       return 0;\r
+               }\r
+               else\r
+               {\r
+//###############\r
+//\r
+// step x by -1\r
+//\r
+//###############\r
+                       do\r
+                       {\r
+                               tx--;\r
+                               spotvis[tx][ty] = true;\r
+                               tracey+=ystep;\r
+                               ty = tracey>>TILESHIFT;\r
+\r
+                               if (ty!=oty)\r
+                               {\r
+                                       if (tilemap[tx][oty])\r
+                                       {\r
+                                               tile.x = tx;\r
+                                               tile.y = oty;\r
+                                               return 1;\r
+                                       }\r
+                                       oty = ty;\r
+                               }\r
+                               if (tilemap[tx][ty])\r
+                               {\r
+                                       tile.x = tx;\r
+                                       tile.y = ty;\r
+                                       return 1;\r
+                               }\r
+                       } while (--max);\r
+                       return 0;\r
+\r
+               }\r
+       }\r
+       else\r
+       {\r
+               xstep = (deltax<<8)/(absdy>>8);\r
+               if (!xstep)\r
+                       xstep = deltax>0 ? 1 : -1;\r
+\r
+\r
+               otx = (tracex+xstep)>>TILESHIFT;\r
+               if (deltay>0)\r
+               {\r
+//###############\r
+//\r
+// step y by +1\r
+//\r
+//###############\r
+                       do\r
+                       {\r
+                               ty++;\r
+                               spotvis[tx][ty] = true;\r
+                               tracex+=xstep;\r
+                               tx = tracex>>TILESHIFT;\r
+\r
+                               if (tx!=otx)\r
+                               {\r
+                                       if (tilemap[tx][ty-1])\r
+                                       {\r
+                                               tile.x = tx;\r
+                                               tile.y = ty-1;\r
+                                               return 1;\r
+                                       }\r
+                                       otx = tx;\r
+                               }\r
+                               if (tilemap[tx][ty])\r
+                               {\r
+                                       tile.x = tx;\r
+                                       tile.y = ty;\r
+                                       return 1;\r
+                               }\r
+                       } while (--max);\r
+                       return 0;\r
+               }\r
+               else\r
+               {\r
+//###############\r
+//\r
+// step y by -1\r
+//\r
+//###############\r
+                       do\r
+                       {\r
+                               ty--;\r
+                               spotvis[tx][ty] = true;\r
+                               tracex+=xstep;\r
+                               tx = tracex>>TILESHIFT;\r
+\r
+                               if (tx!=otx)\r
+                               {\r
+                                       if (tilemap[otx][ty])\r
+                                       {\r
+                                               tile.x = otx;\r
+                                               tile.y = ty;\r
+                                               return 1;\r
+                                       }\r
+                                       otx = tx;\r
+                               }\r
+                               if (tilemap[tx][ty])\r
+                               {\r
+                                       tile.x = tx;\r
+                                       tile.y = ty;\r
+                                       return 1;\r
+                               }\r
+                       } while (--max);\r
+                       return 0;\r
+               }\r
+\r
+       }\r
+\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= BackTrace\r
+=\r
+= Traces backwards from edgex,edgey to viewx,viewy to see if a closer\r
+= tile obscures the given point.  If it does, it finishes the wall and\r
+= starts a new one.\r
+= Returns true if a tile is hit.\r
+= Call with a 1 to have it automatically finish the current wall\r
+=\r
+=================\r
+*/\r
+\r
+int BackTrace (int finish)\r
+{\r
+  fixed tracex,tracey;\r
+  long deltax,deltay,absdx,absdy;\r
+  int steps,otx,oty,testx,testheight,offset,wall;\r
+\r
+  deltax = viewx-edgex;\r
+  deltay = viewy-edgey;\r
+\r
+  absdx = LABS(deltax);\r
+  absdy = LABS(deltay);\r
+\r
+  if (absdx>absdy)\r
+    steps = ABS(focal.x-(edgex>>TILESHIFT))-1;\r
+  else\r
+    steps = ABS(focal.y-(edgey>>TILESHIFT))-1;\r
+\r
+  if (steps<=0)\r
+    return 0;\r
+\r
+  otx = tile.x;\r
+  oty = tile.y;\r
+  if (!FollowTrace(edgex,edgey,deltax,deltay,steps))\r
+    return 0;\r
+\r
+//\r
+// if the start wall is behind the focal point, the trace went too far back\r
+//\r
+  if (ABS(tile.x-focal.x)<2 && ABS(tile.y-focal.y)<2)  // too close\r
+  {\r
+    if (tile.x == focal.x && tile.y == focal.y)\r
+    {\r
+      tile.x = otx;\r
+      tile.y = oty;\r
+      return 0;\r
+    }\r
+\r
+    if (tile.x<focal.x)\r
+    {\r
+      if (tile.y<focal.y)\r
+       wall = SOUTH;\r
+      else\r
+       wall = EAST;\r
+    }\r
+    else if (tile.x==focal.x)\r
+    {\r
+         if (tile.y<focal.y)\r
+       wall = SOUTH;\r
+      else\r
+       wall = NORTH;\r
+    }\r
+    else\r
+       {\r
+      if (tile.y<=focal.y)\r
+       wall = WEST;\r
+      else\r
+       wall = NORTH;\r
+    }\r
+\r
+    //\r
+    // rotate the X value to see if it is behind the view plane\r
+    //\r
+    if (TransformX (((long)tile.x<<16)+point1x[wall],\r
+                   ((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)\r
+    {\r
+      tile.x = otx;\r
+      tile.y = oty;\r
+      return 0;\r
+    }\r
+  }\r
+\r
+//\r
+// if the old wall is still behind a closer wall, ignore the back trace\r
+// and continue on (dealing with limited precision...)\r
+//\r
+  if (finish && !FinishWall ())        // the wall is still behind a forward wall\r
+  {\r
+    tile.x = otx;\r
+    tile.y = oty;\r
+    rightwall->x1 = oldwall->x2;               // common edge with last wall\r
+    rightwall->height1 = oldwall->height2;\r
+    return 0;\r
+  }\r
+\r
+\r
+//\r
+// back up along the intersecting face to find the rightmost wall\r
+//\r
+\r
+  if (tile.y<focal.y)\r
+    offset = 0;\r
+  else if (tile.y==focal.y)\r
+    offset = 3;\r
+  else\r
+    offset = 6;\r
+  if (tile.x==focal.x)\r
+    offset ++;\r
+  else if (tile.x>focal.x)\r
+    offset += 2;\r
+\r
+  wallon = backupwall[offset];\r
+\r
+  while (tilemap[tile.x][tile.y])\r
+  {\r
+    tile.x += followx[wallon];\r
+    tile.y += followy[wallon];\r
+  };\r
+\r
+  tile.x -= followx[wallon];\r
+  tile.y -= followy[wallon];\r
+\r
+  wallon = cornerwall[wallon]; // turn to first visable face\r
+\r
+  edgex = ((long)tile.x<<16);\r
+  edgey = ((long)tile.y<<16);\r
+\r
+  TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
+    &rightwall->x1,&rightwall->height1);\r
+\r
+  basecolor = tilemap[tile.x][tile.y];\r
+\r
+  return 1;\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= ForwardTrace\r
+=\r
+= Traces forwards from edgex,edgey along the line from viewx,viewy until\r
+= a solid tile is hit.  Sets tile.x,tile.y\r
+=\r
+=================\r
+*/\r
+\r
+void ForwardTrace (void)\r
+{\r
+  int offset;\r
+  fixed tracex,tracey;\r
+  long deltax,deltay;\r
+\r
+  deltax = edgex-viewx;\r
+  deltay = edgey-viewy;\r
+\r
+  FollowTrace(edgex,edgey,deltax,deltay,0);\r
+\r
+  if (tile.y<focal.y)\r
+    offset = 0;\r
+  else if (tile.y==focal.y)\r
+    offset = 3;\r
+  else\r
+    offset = 6;\r
+  if (tile.x==focal.x)\r
+    offset ++;\r
+  else if (tile.x>focal.x)\r
+    offset += 2;\r
+\r
+  wallon = startwall[offset];\r
+\r
+//\r
+// start the new wall\r
+//\r
+  edgex = ((long)tile.x<<16);\r
+  edgey = ((long)tile.y<<16);\r
+\r
+//\r
+// if entire first wall is invisable, corner\r
+//\r
+  TransformPoint (edgex+point2x[wallon],edgey+point2y[wallon],\r
+    &rightwall->x2,&rightwall->height2);\r
+\r
+  if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]]\r
+  || rightwall->x2 < (rightwall-1)->x2 )\r
+    wallon = cornerwall [wallon];\r
+\r
+//\r
+// transform first point\r
+//\r
+\r
+  TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
+    &rightwall->x1,&rightwall->height1);\r
+\r
+  basecolor = tilemap[tile.x][tile.y];\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= FinishWall\r
+=\r
+= Transforms edgex,edgey as the next point of the current wall\r
+= and sticks it in the wall list\r
+=\r
+=================\r
+*/\r
+\r
+int FinishWall (void)\r
+{\r
+  char num[20];\r
+\r
+  oldwall = rightwall;\r
+\r
+       rightwall->color  = basecolor;\r
+\r
+  TransformPoint (edgex,edgey,&rightwall->x2,&rightwall->height2);\r
+\r
+  if (rightwall->x2 <= (rightwall-1)->x2+2\r
+  && rightwall->height2 < (rightwall-1)->height2 )\r
+       return 0;\r
+\r
+  rightwall->walllength = walllength;\r
+\r
+  switch (wallon)\r
+  {\r
+  case north:\r
+  case south:\r
+         rightwall->side = 0;\r
+         rightwall->planecoord = edgey;\r
+         break;\r
+\r
+  case west:\r
+  case east:\r
+         rightwall->side = 1;\r
+         rightwall->planecoord = edgex;\r
+         break;\r
+  }\r
+\r
+  walllength = 1;\r
+\r
+  rightwall++;\r
+\r
+  return 1;\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= InsideCorner\r
+=\r
+=================\r
+*/\r
+\r
+void InsideCorner (void)\r
+{\r
+  int offset;\r
+\r
+  //\r
+  // the wall turned -90 degrees, so draw what we have, move to the new tile,\r
+  // change wallon, change color, and continue following.\r
+  //\r
+  FinishWall ();\r
+\r
+  tile.x += sharex[wallon];\r
+  tile.y += sharey[wallon];\r
+\r
+  wallon = turnwall[wallon];\r
+\r
+  //\r
+  // if the new wall is visable, continue following it.  Otherwise\r
+  // follow it backwards until it turns\r
+  //\r
+  TESTWALLVISABLE;\r
+\r
+  if (wallvisable)\r
+  {\r
+  //\r
+  // just turn to the next wall and continue\r
+  //\r
+    rightwall->x1 = oldwall->x2;               // common edge with last wall\r
+    rightwall->height1 = oldwall->height2;\r
+    basecolor = tilemap[tile.x][tile.y];\r
+    return;                    // continue from here\r
+  }\r
+\r
+  //\r
+  // back follow the invisable wall until it turns, then follow that\r
+  //\r
+  do\r
+  {\r
+       tile.x += followx[wallon];\r
+    tile.y += followy[wallon];\r
+  } while (tilemap[tile.x][tile.y]);\r
+\r
+  tile.x -= followx[wallon];\r
+  tile.y -= followy[wallon];\r
+\r
+  wallon = cornerwall[wallon]; // turn to first visable face\r
+\r
+  edgex = ((long)tile.x<<16)+point1x[wallon];\r
+  edgey = ((long)tile.y<<16)+point1y[wallon];\r
+\r
+  if (!BackTrace(0))           // backtrace without finishing a wall\r
+  {\r
+    TransformPoint (edgex,edgey,&rightwall->x1,&rightwall->height1);\r
+    basecolor = tilemap[tile.x][tile.y];\r
+  }\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= OutsideCorner\r
+=\r
+=================\r
+*/\r
+\r
+void OutsideCorner (void)\r
+{\r
+  int offset;\r
+\r
+  //\r
+  // edge is the outside edge of a corner, so draw the current wall and\r
+  // turn the corner (+90 degrees)\r
+  //\r
+  FinishWall ();\r
+\r
+  tile.x -= followx[wallon];   // backup to the real tile\r
+  tile.y -= followy[wallon];\r
+  wallon = cornerwall[wallon];\r
+\r
+  //\r
+  // if the new wall is visable, continue following it.  Otherwise\r
+  // trace a ray from the corner to find a wall in the distance to\r
+  // follow\r
+  //\r
+  TESTWALLVISABLE;\r
+\r
+  if (wallvisable)\r
+  {\r
+  //\r
+  // the new wall is visable, so just continue on\r
+  //\r
+    rightwall->x1 = oldwall->x2;               // common edge with last wall\r
+    rightwall->height1 = oldwall->height2;\r
+    return;                    // still on same tile, so color is ok\r
+  }\r
+\r
+//\r
+// start from a new tile further away\r
+//\r
+  ForwardTrace();              // find the next wall further back\r
+\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+=================\r
+=\r
+= FollowWalls\r
+=\r
+= Starts a wall edge at the leftmost edge of tile.x,tile.y and follows it\r
+= until something else is seen or the entire view area is covered\r
+=\r
+=================\r
+*/\r
+\r
+void FollowWalls (void)\r
+{\r
+  int height,newcolor,offset,wall;\r
+\r
+//####################\r
+//\r
+// figure leftmost wall of new tile\r
+//\r
+//####################\r
+\r
+restart:\r
+\r
+  walllength = 1;\r
+\r
+  if (tile.y<focal.y)\r
+       offset = 0;\r
+  else if (tile.y==focal.y)\r
+       offset = 3;\r
+  else\r
+       offset = 6;\r
+  if (tile.x==focal.x)\r
+       offset ++;\r
+  else if (tile.x>focal.x)\r
+       offset += 2;\r
+\r
+  wallon = startwall[offset];\r
+\r
+//\r
+// if the start wall is inside a block, skip it by cornering to the second wall\r
+//\r
+  if ( tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])\r
+       wallon = cornerwall [wallon];\r
+\r
+//\r
+// transform first edge to screen coordinates\r
+//\r
+  edgex = ((long)tile.x<<16);\r
+  edgey = ((long)tile.y<<16);\r
+\r
+  TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
+       &rightwall->x1,&rightwall->height1);\r
+\r
+  basecolor = tilemap[tile.x][tile.y];\r
+\r
+//##################\r
+//\r
+// follow the wall as long as possible\r
+//\r
+//##################\r
+\r
+advance:\r
+\r
+  do   // while ( tile.x != right.x || tile.y != right.y)\r
+  {\r
+//\r
+// check for conditions that shouldn't happed...\r
+//\r
+       if (rightwall->x1 > VIEWXH)     // somehow missed right tile...\r
+         return;\r
+\r
+       if (rightwall == &walls[DANGERHIGH])\r
+       {\r
+  //\r
+  // somethiing got messed up!  Correct by thrusting ahead...\r
+  //\r
+               VW_ColorBorder(6);\r
+               bordertime = 60;\r
+               Thrust(player->angle,TILEGLOBAL/4);\r
+               player->angle+=5;\r
+               if (player->angle>ANGLES)\r
+                       player->angle-=ANGLES;\r
+               aborttrace = true;\r
+               return;\r
+\r
+#if 0\r
+         strcpy (str,"Wall list overflow at LE:");\r
+         itoa(mapon+1,str2,10);\r
+         strcat (str,str2);\r
+         strcat (str," X:");\r
+         ltoa(objlist[0].x,str2,10);\r
+         strcat (str,str2);\r
+         strcat (str," Y:");\r
+         ltoa(objlist[0].y,str2,10);\r
+         strcat (str,str2);\r
+         strcat (str," AN:");\r
+         itoa(objlist[0].angle,str2,10);\r
+         strcat (str,str2);\r
+\r
+         Quit (str);\r
+#endif\r
+       }\r
+\r
+//\r
+// proceed along wall\r
+//\r
+\r
+       edgex = ((long)tile.x<<16)+point2x[wallon];\r
+       edgey = ((long)tile.y<<16)+point2y[wallon];\r
+\r
+       if (BackTrace(1))               // went behind a closer wall\r
+         continue;\r
+\r
+       //\r
+       // advance to next tile along wall\r
+       //\r
+       tile.x += followx[wallon];\r
+       tile.y += followy[wallon];\r
+\r
+       if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])\r
+       {\r
+         InsideCorner ();              // turn at a corner\r
+         continue;\r
+       }\r
+\r
+       newcolor = tilemap[tile.x][tile.y];\r
+\r
+       if (!newcolor)          // turn around an edge\r
+       {\r
+         OutsideCorner ();\r
+         continue;\r
+       }\r
+\r
+       if (newcolor != basecolor)\r
+       {\r
+         //\r
+         // wall changed color, so draw what we have and continue following\r
+         //\r
+         FinishWall ();\r
+         rightwall->x1 = oldwall->x2;  // new wall shares this edge\r
+         rightwall->height1 = oldwall->height2;\r
+         basecolor = newcolor;\r
+\r
+         continue;\r
+       }\r
+       walllength++;\r
+  } while (tile.x != right.x || tile.y != right.y);\r
+\r
+\r
+\r
+//######################\r
+//\r
+// draw the last tile\r
+//\r
+//######################\r
+\r
+  edgex = ((long)tile.x<<16)+point2x[wallon];\r
+  edgey = ((long)tile.y<<16)+point2y[wallon];\r
+  FinishWall();\r
+\r
+  wallon = cornerwall[wallon];\r
+\r
+  //\r
+  // if the corner wall is visable, draw it\r
+  //\r
+  TESTWALLVISABLE;\r
+\r
+  if (wallvisable)\r
+  {\r
+    rightwall->x1 = oldwall->x2;               // common edge with last wall\r
+    rightwall->height1 = oldwall->height2;\r
+    edgex = ((long)tile.x<<16)+point2x[wallon];\r
+    edgey = ((long)tile.y<<16)+point2y[wallon];\r
+    FinishWall();\r
+  }\r
+\r
+}\r
+\r
+//===========================================================================\r