]> 4ch.mooo.com Git - 16.git/blob - 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
1 /* Catacomb 3-D Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // C3_TRACE.C\r
20 \r
21 #include "C3_DEF.H"\r
22 #pragma hdrstop\r
23 \r
24 /*\r
25 =============================================================================\r
26 \r
27                                                  LOCAL CONSTANTS\r
28 \r
29 =============================================================================\r
30 */\r
31 \r
32 \r
33 //\r
34 // TESTWALLVISABLE will set the global variable wallvisable to 1 or 0\r
35 // depending on if tile.x,tile.y,wallon is visable from focal point\r
36 //\r
37 #define TESTWALLVISABLE {                                               \\r
38         if (tile.y<focal.y)                         \\r
39                 voffset = 0;                            \\r
40         else if (tile.y==focal.y)                   \\r
41                 voffset = 3;                            \\r
42         else                                        \\r
43                 voffset = 6;                            \\r
44         if (tile.x==focal.x)                        \\r
45                 voffset ++;                             \\r
46         else if (tile.x>focal.x)                    \\r
47                 voffset += 2;                           \\r
48         wallvisable = visable[voffset][wallon]; }\r
49 \r
50 \r
51 /*\r
52 =============================================================================\r
53 \r
54                                                  GLOBAL VARIABLES\r
55 \r
56 =============================================================================\r
57 */\r
58 \r
59 boolean aborttrace;\r
60 \r
61 /*\r
62 =============================================================================\r
63 \r
64                                                  LOCAL VARIABLES\r
65 \r
66 =============================================================================\r
67 */\r
68 \r
69 unsigned        wallvisable,voffset;\r
70 \r
71 \r
72 fixed edgex,edgey;\r
73 \r
74 int wallon;\r
75 int basecolor;\r
76 \r
77 walltype *oldwall;\r
78 \r
79 //\r
80 // offsets from upper left corner of a tile to the left and right edges of\r
81 // a given wall (NORTH-WEST)\r
82 //\r
83 fixed point1x[4] = {GLOBAL1,GLOBAL1,0      ,0       };\r
84 fixed point1y[4] = {0      ,GLOBAL1,GLOBAL1,0       };\r
85 \r
86 fixed point2x[4] = {0      ,GLOBAL1,GLOBAL1,0       };\r
87 fixed point2y[4] = {0     ,0       ,GLOBAL1 ,GLOBAL1};\r
88 \r
89 \r
90 //\r
91 // offset from tile.x,tile.y of the tile that shares wallon side\r
92 // (side is not visable if it is shared)\r
93 //\r
94 int sharex[4] = { 0, 1, 0,-1};\r
95 int sharey[4] = {-1, 0, 1, 0};\r
96 \r
97 //\r
98 // amount to move tile.x,tile.y to follow wallon to another tile\r
99 //\r
100 int followx[4] = {-1, 0, 1, 0};\r
101 int followy[4] = { 0,-1, 0, 1};\r
102 \r
103 //\r
104 // cornerwall gives the wall on the same tile to start following when the\r
105 // wall ends at an empty tile (go around an edge on same tile)\r
106 // turnwall gives the wall on tile.x+sharex,tile.y+sharey to start following\r
107 // when the wall hits another tile (right angle corner)\r
108 //\r
109 int cornerwall[4] = {WEST,NORTH,EAST,SOUTH};\r
110 int turnwall[4] = {EAST,SOUTH,WEST,NORTH};\r
111 \r
112 //\r
113 // wall visabilities in reletive locations\r
114 // -,- 0,- +,-\r
115 // -,0 0,0 +,0\r
116 // -,+ 0,+ +,+\r
117 //\r
118 int visable[9][4] =\r
119 {\r
120  {0,1,1,0}, {0,0,1,0}, {0,0,1,1},\r
121  {0,1,0,0}, {0,0,0,0}, {0,0,0,1},\r
122  {1,1,0,0}, {1,0,0,0}, {1,0,0,1}\r
123 };\r
124 \r
125 int startwall[9] =  {2,2,3, 1,0,3, 1,0,0};\r
126 int backupwall[9] = {3,3,0, 2,0,0, 2,1,1};\r
127 \r
128 \r
129 int     walllength;\r
130 \r
131 /*\r
132 =============================================================================\r
133 \r
134                                          FUNCTIONS\r
135 \r
136 =============================================================================\r
137 */\r
138 \r
139 /*\r
140 ========================\r
141 =\r
142 = FollowTrace\r
143 =\r
144 ========================\r
145 */\r
146 \r
147 int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max)\r
148 {\r
149         int tx,ty,otx,oty;\r
150         long absdx,absdy,xstep,ystep;\r
151 \r
152         tx = tracex>>TILESHIFT;\r
153         ty = tracey>>TILESHIFT;\r
154 \r
155         spotvis[tx][ty] = true;\r
156 \r
157         absdx=LABS(deltax);\r
158         absdy=LABS(deltay);\r
159 \r
160         if (absdx>absdy)\r
161         {\r
162                 ystep = (deltay<<8)/(absdx>>8);\r
163 \r
164                 if (!ystep)\r
165                         ystep = deltay>0 ? 1 : -1;\r
166 \r
167                 oty = (tracey+ystep)>>TILESHIFT;\r
168                 if (deltax>0)\r
169                 {\r
170 //###############\r
171 //\r
172 // step x by +1\r
173 //\r
174 //###############\r
175                         do\r
176                         {\r
177                                 tx++;\r
178                                 spotvis[tx][ty] = true;\r
179                                 tracey+=ystep;\r
180                                 ty = tracey>>TILESHIFT;\r
181 \r
182                                 if (ty!=oty)\r
183                                 {\r
184                                         if (tilemap[tx-1][ty])\r
185                                         {\r
186                                                 tile.x = tx-1;\r
187                                                 tile.y = ty;\r
188                                                 return 1;\r
189                                         }\r
190                                         oty = ty;\r
191                                 }\r
192                                 if (tilemap[tx][ty])\r
193                                 {\r
194                                         tile.x = tx;\r
195                                         tile.y = ty;\r
196                                         return 1;\r
197                                 }\r
198                         } while (--max);\r
199                         return 0;\r
200                 }\r
201                 else\r
202                 {\r
203 //###############\r
204 //\r
205 // step x by -1\r
206 //\r
207 //###############\r
208                         do\r
209                         {\r
210                                 tx--;\r
211                                 spotvis[tx][ty] = true;\r
212                                 tracey+=ystep;\r
213                                 ty = tracey>>TILESHIFT;\r
214 \r
215                                 if (ty!=oty)\r
216                                 {\r
217                                         if (tilemap[tx][oty])\r
218                                         {\r
219                                                 tile.x = tx;\r
220                                                 tile.y = oty;\r
221                                                 return 1;\r
222                                         }\r
223                                         oty = ty;\r
224                                 }\r
225                                 if (tilemap[tx][ty])\r
226                                 {\r
227                                         tile.x = tx;\r
228                                         tile.y = ty;\r
229                                         return 1;\r
230                                 }\r
231                         } while (--max);\r
232                         return 0;\r
233 \r
234                 }\r
235         }\r
236         else\r
237         {\r
238                 xstep = (deltax<<8)/(absdy>>8);\r
239                 if (!xstep)\r
240                         xstep = deltax>0 ? 1 : -1;\r
241 \r
242 \r
243                 otx = (tracex+xstep)>>TILESHIFT;\r
244                 if (deltay>0)\r
245                 {\r
246 //###############\r
247 //\r
248 // step y by +1\r
249 //\r
250 //###############\r
251                         do\r
252                         {\r
253                                 ty++;\r
254                                 spotvis[tx][ty] = true;\r
255                                 tracex+=xstep;\r
256                                 tx = tracex>>TILESHIFT;\r
257 \r
258                                 if (tx!=otx)\r
259                                 {\r
260                                         if (tilemap[tx][ty-1])\r
261                                         {\r
262                                                 tile.x = tx;\r
263                                                 tile.y = ty-1;\r
264                                                 return 1;\r
265                                         }\r
266                                         otx = tx;\r
267                                 }\r
268                                 if (tilemap[tx][ty])\r
269                                 {\r
270                                         tile.x = tx;\r
271                                         tile.y = ty;\r
272                                         return 1;\r
273                                 }\r
274                         } while (--max);\r
275                         return 0;\r
276                 }\r
277                 else\r
278                 {\r
279 //###############\r
280 //\r
281 // step y by -1\r
282 //\r
283 //###############\r
284                         do\r
285                         {\r
286                                 ty--;\r
287                                 spotvis[tx][ty] = true;\r
288                                 tracex+=xstep;\r
289                                 tx = tracex>>TILESHIFT;\r
290 \r
291                                 if (tx!=otx)\r
292                                 {\r
293                                         if (tilemap[otx][ty])\r
294                                         {\r
295                                                 tile.x = otx;\r
296                                                 tile.y = ty;\r
297                                                 return 1;\r
298                                         }\r
299                                         otx = tx;\r
300                                 }\r
301                                 if (tilemap[tx][ty])\r
302                                 {\r
303                                         tile.x = tx;\r
304                                         tile.y = ty;\r
305                                         return 1;\r
306                                 }\r
307                         } while (--max);\r
308                         return 0;\r
309                 }\r
310 \r
311         }\r
312 \r
313 }\r
314 \r
315 \r
316 //===========================================================================\r
317 \r
318 \r
319 /*\r
320 =================\r
321 =\r
322 = BackTrace\r
323 =\r
324 = Traces backwards from edgex,edgey to viewx,viewy to see if a closer\r
325 = tile obscures the given point.  If it does, it finishes the wall and\r
326 = starts a new one.\r
327 = Returns true if a tile is hit.\r
328 = Call with a 1 to have it automatically finish the current wall\r
329 =\r
330 =================\r
331 */\r
332 \r
333 int BackTrace (int finish)\r
334 {\r
335   fixed tracex,tracey;\r
336   long deltax,deltay,absdx,absdy;\r
337   int steps,otx,oty,testx,testheight,offset,wall;\r
338 \r
339   deltax = viewx-edgex;\r
340   deltay = viewy-edgey;\r
341 \r
342   absdx = LABS(deltax);\r
343   absdy = LABS(deltay);\r
344 \r
345   if (absdx>absdy)\r
346     steps = ABS(focal.x-(edgex>>TILESHIFT))-1;\r
347   else\r
348     steps = ABS(focal.y-(edgey>>TILESHIFT))-1;\r
349 \r
350   if (steps<=0)\r
351     return 0;\r
352 \r
353   otx = tile.x;\r
354   oty = tile.y;\r
355   if (!FollowTrace(edgex,edgey,deltax,deltay,steps))\r
356     return 0;\r
357 \r
358 //\r
359 // if the start wall is behind the focal point, the trace went too far back\r
360 //\r
361   if (ABS(tile.x-focal.x)<2 && ABS(tile.y-focal.y)<2)   // too close\r
362   {\r
363     if (tile.x == focal.x && tile.y == focal.y)\r
364     {\r
365       tile.x = otx;\r
366       tile.y = oty;\r
367       return 0;\r
368     }\r
369 \r
370     if (tile.x<focal.x)\r
371     {\r
372       if (tile.y<focal.y)\r
373         wall = SOUTH;\r
374       else\r
375         wall = EAST;\r
376     }\r
377     else if (tile.x==focal.x)\r
378     {\r
379           if (tile.y<focal.y)\r
380         wall = SOUTH;\r
381       else\r
382         wall = NORTH;\r
383     }\r
384     else\r
385         {\r
386       if (tile.y<=focal.y)\r
387         wall = WEST;\r
388       else\r
389         wall = NORTH;\r
390     }\r
391 \r
392     //\r
393     // rotate the X value to see if it is behind the view plane\r
394     //\r
395     if (TransformX (((long)tile.x<<16)+point1x[wall],\r
396                     ((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)\r
397     {\r
398       tile.x = otx;\r
399       tile.y = oty;\r
400       return 0;\r
401     }\r
402   }\r
403 \r
404 //\r
405 // if the old wall is still behind a closer wall, ignore the back trace\r
406 // and continue on (dealing with limited precision...)\r
407 //\r
408   if (finish && !FinishWall ()) // the wall is still behind a forward wall\r
409   {\r
410     tile.x = otx;\r
411     tile.y = oty;\r
412     rightwall->x1 = oldwall->x2;                // common edge with last wall\r
413     rightwall->height1 = oldwall->height2;\r
414     return 0;\r
415   }\r
416 \r
417 \r
418 //\r
419 // back up along the intersecting face to find the rightmost wall\r
420 //\r
421 \r
422   if (tile.y<focal.y)\r
423     offset = 0;\r
424   else if (tile.y==focal.y)\r
425     offset = 3;\r
426   else\r
427     offset = 6;\r
428   if (tile.x==focal.x)\r
429     offset ++;\r
430   else if (tile.x>focal.x)\r
431     offset += 2;\r
432 \r
433   wallon = backupwall[offset];\r
434 \r
435   while (tilemap[tile.x][tile.y])\r
436   {\r
437     tile.x += followx[wallon];\r
438     tile.y += followy[wallon];\r
439   };\r
440 \r
441   tile.x -= followx[wallon];\r
442   tile.y -= followy[wallon];\r
443 \r
444   wallon = cornerwall[wallon];  // turn to first visable face\r
445 \r
446   edgex = ((long)tile.x<<16);\r
447   edgey = ((long)tile.y<<16);\r
448 \r
449   TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
450     &rightwall->x1,&rightwall->height1);\r
451 \r
452   basecolor = tilemap[tile.x][tile.y];\r
453 \r
454   return 1;\r
455 }\r
456 \r
457 //===========================================================================\r
458 \r
459 \r
460 /*\r
461 =================\r
462 =\r
463 = ForwardTrace\r
464 =\r
465 = Traces forwards from edgex,edgey along the line from viewx,viewy until\r
466 = a solid tile is hit.  Sets tile.x,tile.y\r
467 =\r
468 =================\r
469 */\r
470 \r
471 void ForwardTrace (void)\r
472 {\r
473   int offset;\r
474   fixed tracex,tracey;\r
475   long deltax,deltay;\r
476 \r
477   deltax = edgex-viewx;\r
478   deltay = edgey-viewy;\r
479 \r
480   FollowTrace(edgex,edgey,deltax,deltay,0);\r
481 \r
482   if (tile.y<focal.y)\r
483     offset = 0;\r
484   else if (tile.y==focal.y)\r
485     offset = 3;\r
486   else\r
487     offset = 6;\r
488   if (tile.x==focal.x)\r
489     offset ++;\r
490   else if (tile.x>focal.x)\r
491     offset += 2;\r
492 \r
493   wallon = startwall[offset];\r
494 \r
495 //\r
496 // start the new wall\r
497 //\r
498   edgex = ((long)tile.x<<16);\r
499   edgey = ((long)tile.y<<16);\r
500 \r
501 //\r
502 // if entire first wall is invisable, corner\r
503 //\r
504   TransformPoint (edgex+point2x[wallon],edgey+point2y[wallon],\r
505     &rightwall->x2,&rightwall->height2);\r
506 \r
507   if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]]\r
508   || rightwall->x2 < (rightwall-1)->x2 )\r
509     wallon = cornerwall [wallon];\r
510 \r
511 //\r
512 // transform first point\r
513 //\r
514 \r
515   TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
516     &rightwall->x1,&rightwall->height1);\r
517 \r
518   basecolor = tilemap[tile.x][tile.y];\r
519 }\r
520 \r
521 \r
522 //===========================================================================\r
523 \r
524 \r
525 /*\r
526 =================\r
527 =\r
528 = FinishWall\r
529 =\r
530 = Transforms edgex,edgey as the next point of the current wall\r
531 = and sticks it in the wall list\r
532 =\r
533 =================\r
534 */\r
535 \r
536 int FinishWall (void)\r
537 {\r
538   char num[20];\r
539 \r
540   oldwall = rightwall;\r
541 \r
542         rightwall->color  = basecolor;\r
543 \r
544   TransformPoint (edgex,edgey,&rightwall->x2,&rightwall->height2);\r
545 \r
546   if (rightwall->x2 <= (rightwall-1)->x2+2\r
547   && rightwall->height2 < (rightwall-1)->height2 )\r
548         return 0;\r
549 \r
550   rightwall->walllength = walllength;\r
551 \r
552   switch (wallon)\r
553   {\r
554   case north:\r
555   case south:\r
556           rightwall->side = 0;\r
557           rightwall->planecoord = edgey;\r
558           break;\r
559 \r
560   case west:\r
561   case east:\r
562           rightwall->side = 1;\r
563           rightwall->planecoord = edgex;\r
564           break;\r
565   }\r
566 \r
567   walllength = 1;\r
568 \r
569   rightwall++;\r
570 \r
571   return 1;\r
572 }\r
573 \r
574 //===========================================================================\r
575 \r
576 \r
577 /*\r
578 =================\r
579 =\r
580 = InsideCorner\r
581 =\r
582 =================\r
583 */\r
584 \r
585 void InsideCorner (void)\r
586 {\r
587   int offset;\r
588 \r
589   //\r
590   // the wall turned -90 degrees, so draw what we have, move to the new tile,\r
591   // change wallon, change color, and continue following.\r
592   //\r
593   FinishWall ();\r
594 \r
595   tile.x += sharex[wallon];\r
596   tile.y += sharey[wallon];\r
597 \r
598   wallon = turnwall[wallon];\r
599 \r
600   //\r
601   // if the new wall is visable, continue following it.  Otherwise\r
602   // follow it backwards until it turns\r
603   //\r
604   TESTWALLVISABLE;\r
605 \r
606   if (wallvisable)\r
607   {\r
608   //\r
609   // just turn to the next wall and continue\r
610   //\r
611     rightwall->x1 = oldwall->x2;                // common edge with last wall\r
612     rightwall->height1 = oldwall->height2;\r
613     basecolor = tilemap[tile.x][tile.y];\r
614     return;                     // continue from here\r
615   }\r
616 \r
617   //\r
618   // back follow the invisable wall until it turns, then follow that\r
619   //\r
620   do\r
621   {\r
622         tile.x += followx[wallon];\r
623     tile.y += followy[wallon];\r
624   } while (tilemap[tile.x][tile.y]);\r
625 \r
626   tile.x -= followx[wallon];\r
627   tile.y -= followy[wallon];\r
628 \r
629   wallon = cornerwall[wallon];  // turn to first visable face\r
630 \r
631   edgex = ((long)tile.x<<16)+point1x[wallon];\r
632   edgey = ((long)tile.y<<16)+point1y[wallon];\r
633 \r
634   if (!BackTrace(0))            // backtrace without finishing a wall\r
635   {\r
636     TransformPoint (edgex,edgey,&rightwall->x1,&rightwall->height1);\r
637     basecolor = tilemap[tile.x][tile.y];\r
638   }\r
639 }\r
640 \r
641 //===========================================================================\r
642 \r
643 \r
644 /*\r
645 =================\r
646 =\r
647 = OutsideCorner\r
648 =\r
649 =================\r
650 */\r
651 \r
652 void OutsideCorner (void)\r
653 {\r
654   int offset;\r
655 \r
656   //\r
657   // edge is the outside edge of a corner, so draw the current wall and\r
658   // turn the corner (+90 degrees)\r
659   //\r
660   FinishWall ();\r
661 \r
662   tile.x -= followx[wallon];    // backup to the real tile\r
663   tile.y -= followy[wallon];\r
664   wallon = cornerwall[wallon];\r
665 \r
666   //\r
667   // if the new wall is visable, continue following it.  Otherwise\r
668   // trace a ray from the corner to find a wall in the distance to\r
669   // follow\r
670   //\r
671   TESTWALLVISABLE;\r
672 \r
673   if (wallvisable)\r
674   {\r
675   //\r
676   // the new wall is visable, so just continue on\r
677   //\r
678     rightwall->x1 = oldwall->x2;                // common edge with last wall\r
679     rightwall->height1 = oldwall->height2;\r
680     return;                     // still on same tile, so color is ok\r
681   }\r
682 \r
683 //\r
684 // start from a new tile further away\r
685 //\r
686   ForwardTrace();               // find the next wall further back\r
687 \r
688 }\r
689 \r
690 \r
691 //===========================================================================\r
692 \r
693 \r
694 /*\r
695 =================\r
696 =\r
697 = FollowWalls\r
698 =\r
699 = Starts a wall edge at the leftmost edge of tile.x,tile.y and follows it\r
700 = until something else is seen or the entire view area is covered\r
701 =\r
702 =================\r
703 */\r
704 \r
705 void FollowWalls (void)\r
706 {\r
707   int height,newcolor,offset,wall;\r
708 \r
709 //####################\r
710 //\r
711 // figure leftmost wall of new tile\r
712 //\r
713 //####################\r
714 \r
715 restart:\r
716 \r
717   walllength = 1;\r
718 \r
719   if (tile.y<focal.y)\r
720         offset = 0;\r
721   else if (tile.y==focal.y)\r
722         offset = 3;\r
723   else\r
724         offset = 6;\r
725   if (tile.x==focal.x)\r
726         offset ++;\r
727   else if (tile.x>focal.x)\r
728         offset += 2;\r
729 \r
730   wallon = startwall[offset];\r
731 \r
732 //\r
733 // if the start wall is inside a block, skip it by cornering to the second wall\r
734 //\r
735   if ( tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])\r
736         wallon = cornerwall [wallon];\r
737 \r
738 //\r
739 // transform first edge to screen coordinates\r
740 //\r
741   edgex = ((long)tile.x<<16);\r
742   edgey = ((long)tile.y<<16);\r
743 \r
744   TransformPoint (edgex+point1x[wallon],edgey+point1y[wallon],\r
745         &rightwall->x1,&rightwall->height1);\r
746 \r
747   basecolor = tilemap[tile.x][tile.y];\r
748 \r
749 //##################\r
750 //\r
751 // follow the wall as long as possible\r
752 //\r
753 //##################\r
754 \r
755 advance:\r
756 \r
757   do    // while ( tile.x != right.x || tile.y != right.y)\r
758   {\r
759 //\r
760 // check for conditions that shouldn't happed...\r
761 //\r
762         if (rightwall->x1 > VIEWXH)     // somehow missed right tile...\r
763           return;\r
764 \r
765         if (rightwall == &walls[DANGERHIGH])\r
766         {\r
767   //\r
768   // somethiing got messed up!  Correct by thrusting ahead...\r
769   //\r
770                 VW_ColorBorder(6);\r
771                 bordertime = 60;\r
772                 Thrust(player->angle,TILEGLOBAL/4);\r
773                 player->angle+=5;\r
774                 if (player->angle>ANGLES)\r
775                         player->angle-=ANGLES;\r
776                 aborttrace = true;\r
777                 return;\r
778 \r
779 #if 0\r
780           strcpy (str,"Wall list overflow at LE:");\r
781           itoa(mapon+1,str2,10);\r
782           strcat (str,str2);\r
783           strcat (str," X:");\r
784           ltoa(objlist[0].x,str2,10);\r
785           strcat (str,str2);\r
786           strcat (str," Y:");\r
787           ltoa(objlist[0].y,str2,10);\r
788           strcat (str,str2);\r
789           strcat (str," AN:");\r
790           itoa(objlist[0].angle,str2,10);\r
791           strcat (str,str2);\r
792 \r
793           Quit (str);\r
794 #endif\r
795         }\r
796 \r
797 //\r
798 // proceed along wall\r
799 //\r
800 \r
801         edgex = ((long)tile.x<<16)+point2x[wallon];\r
802         edgey = ((long)tile.y<<16)+point2y[wallon];\r
803 \r
804         if (BackTrace(1))               // went behind a closer wall\r
805           continue;\r
806 \r
807         //\r
808         // advance to next tile along wall\r
809         //\r
810         tile.x += followx[wallon];\r
811         tile.y += followy[wallon];\r
812 \r
813         if (tilemap [tile.x+sharex[wallon]] [tile.y+sharey[wallon]])\r
814         {\r
815           InsideCorner ();              // turn at a corner\r
816           continue;\r
817         }\r
818 \r
819         newcolor = tilemap[tile.x][tile.y];\r
820 \r
821         if (!newcolor)          // turn around an edge\r
822         {\r
823           OutsideCorner ();\r
824           continue;\r
825         }\r
826 \r
827         if (newcolor != basecolor)\r
828         {\r
829           //\r
830           // wall changed color, so draw what we have and continue following\r
831           //\r
832           FinishWall ();\r
833           rightwall->x1 = oldwall->x2;  // new wall shares this edge\r
834           rightwall->height1 = oldwall->height2;\r
835           basecolor = newcolor;\r
836 \r
837           continue;\r
838         }\r
839         walllength++;\r
840   } while (tile.x != right.x || tile.y != right.y);\r
841 \r
842 \r
843 \r
844 //######################\r
845 //\r
846 // draw the last tile\r
847 //\r
848 //######################\r
849 \r
850   edgex = ((long)tile.x<<16)+point2x[wallon];\r
851   edgey = ((long)tile.y<<16)+point2y[wallon];\r
852   FinishWall();\r
853 \r
854   wallon = cornerwall[wallon];\r
855 \r
856   //\r
857   // if the corner wall is visable, draw it\r
858   //\r
859   TESTWALLVISABLE;\r
860 \r
861   if (wallvisable)\r
862   {\r
863     rightwall->x1 = oldwall->x2;                // common edge with last wall\r
864     rightwall->height1 = oldwall->height2;\r
865     edgex = ((long)tile.x<<16)+point2x[wallon];\r
866     edgey = ((long)tile.y<<16)+point2y[wallon];\r
867     FinishWall();\r
868   }\r
869 \r
870 }\r
871 \r
872 //===========================================================================\r