home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Jeux / demos / crystalPPC.lha / sector.cpp < prev    next >
C/C++ Source or Header  |  1998-02-05  |  33KB  |  1,352 lines

  1. #include <math.h>
  2. #include <time.h>
  3. #include "system.h"
  4.  
  5. #ifndef DEF_H
  6. #include "def.h"
  7. #endif
  8.  
  9. #ifndef SECTOR_H
  10. #include "sector.h"
  11. #endif
  12.  
  13. #ifndef THING_H
  14. #include "thing.h"
  15. #endif
  16.  
  17. //#ifndef OCCLUS_H
  18. //#include "occlus.h"
  19. //#endif
  20.  
  21. #ifndef POLYGON_H
  22. #include "polygon.h"
  23. #endif
  24.  
  25. #ifndef LIGHT_H
  26. #include "light.h"
  27. #endif
  28.  
  29. #ifndef TOKEN_H
  30. #include "token.h"
  31. #endif
  32.  
  33. #ifndef SCAN_H
  34. #include "scan.h"
  35. #endif
  36.  
  37. #ifndef CAMERA_H
  38. #include "camera.h"
  39. #endif
  40.  
  41. #ifndef TEXTURE_H
  42. #include "texture.h"
  43. #endif
  44.  
  45. #ifndef WORLD_H
  46. #include "world.h"
  47. #endif
  48.  
  49. //---------------------------------------------------------------------------
  50.  
  51. Sector::Sector (char* name, int max_v, int max_p) : PolygonSet (name, CS_SECTOR, max_v, max_p)
  52. {
  53.   first_thing = NULL;
  54. #if USE_OCCLUSION
  55.   first_occlusion = NULL;
  56. #endif
  57.   num_lights = 0;
  58.   sector = this;
  59.   draw_done = FALSE;
  60.   beam_done = FALSE;
  61.   level1 = level2 = level3 = 0;
  62. }
  63.  
  64. Sector::~Sector ()
  65. {
  66.   int i;
  67.   while (first_thing)
  68.   {
  69.     Thing* n = (Thing*)(first_thing->get_next ());
  70.     delete first_thing;
  71.     first_thing = n;
  72.   }
  73. #if USE_OCCLUSION
  74.   while (first_occlusion)
  75.   {
  76.     Occlusion* n = first_occlusion->get_next ();
  77.     delete first_occlusion;
  78.     first_occlusion = n;
  79.   }
  80. #endif
  81.   for (i = 0 ; i < num_lights ; i++)
  82.   {
  83.     delete lights[i];
  84.   }
  85. }
  86.  
  87. void Sector::add_thing (Thing* thing)
  88. {
  89.   thing->set_next ((PolygonSet*)first_thing);
  90.   first_thing = thing;
  91. }
  92.  
  93. #if USE_OCCLUSION
  94. void Sector::add_occlusion (Occlusion* occlusion)
  95. {
  96.   occlusion->set_next (first_occlusion);
  97.   first_occlusion = occlusion;
  98. }
  99. #endif
  100.  
  101. void Sector::add_light (Light* light)
  102. {
  103.   lights[num_lights++] = light;
  104.   light->set_sector (this);
  105. }
  106.  
  107. Polygon3D* Sector::hit_beam (Vector3& start, Vector3& end)
  108. {
  109.   Vector3 isect;
  110.   Polygon3D* p;
  111.  
  112.   // First check the things of this sector and return the one with
  113.   // the closest distance.
  114.   Thing* sp = first_thing;
  115.   float sq_dist, min_sq_dist = 100000000.;
  116.   Polygon3D* min_poly = NULL;
  117.   while (sp)
  118.   {
  119.     p = sp->intersect_segment (start, end, isect);
  120.     if (p)
  121.     {
  122.       sq_dist = (isect.x-start.x)*(isect.x-start.x) +
  123.     (isect.y-start.y)*(isect.y-start.y) +
  124.     (isect.z-start.z)*(isect.z-start.z);
  125.       if (sq_dist < min_sq_dist) { min_sq_dist = sq_dist; min_poly = p; }
  126.     }
  127.     sp = (Thing*)(sp->get_next ());
  128.   }
  129.  
  130.   if (min_poly) return min_poly;
  131.  
  132.   p = intersect_segment (start, end, isect);
  133.   if (p)
  134.   {
  135.     if (p->get_portal ()) return p->get_portal ()->hit_beam (start, end);
  136.     else return p;
  137.   }
  138.   else return NULL;
  139. }
  140.  
  141. int Sector::hit_beam (Vector3& start, Vector3& end, Polygon3D* poly)
  142. {
  143.   int rc = FALSE;
  144.   Polygon3D* p;
  145.   Vector3 isect;
  146.  
  147.   if (this == poly->get_sector ()) rc = TRUE;
  148.   else
  149.   {
  150.     beam_done = TRUE;
  151.  
  152.     p = intersect_segment (start, end, isect);
  153.     if (p)
  154.     {
  155.       // If the two polygons are on the same plane there is a hit.
  156.       if (p->same_plane (poly))
  157.         rc = TRUE;
  158.       else
  159.       {
  160.         Sector* s = p->get_portal ();
  161.         if (!s) rc = FALSE;
  162.         else if (s->beam_done) rc = FALSE;
  163.         else rc = s->hit_beam (start, end, poly);
  164.       }
  165.     }
  166.  
  167.     beam_done = FALSE;
  168.   }
  169.  
  170.   // If rc == TRUE the beam of light hits the polygon. In
  171.   // that case we check if there are no things in between the
  172.   // light and the polygon that could still block that beam.
  173.   if (rc)
  174.   {
  175.     Thing* sp = first_thing;
  176.     while (sp)
  177.     {
  178.       p = sp->intersect_segment (start, end, isect);
  179.       if (p && p->get_poly_set () != poly->get_poly_set ()) return FALSE;
  180.       sp = (Thing*)(sp->get_next ());
  181.     }
  182.   }
  183.  
  184.   return rc;
  185. }
  186.  
  187. void Sector::shine_lights ()
  188. {
  189.   int i;
  190.   for (i = 0 ; i < num_lights ; i++)
  191.   {
  192.     printf ("Shining light %d (%2.2f,%2.2f,%2.2f) %2.2f in sector '%s'\n",
  193.         i, lights[i]->get_center ().x, lights[i]->get_center ().y, lights[i]->get_center ().z,
  194.         lights[i]->get_dist (),
  195.         get_name ());
  196.     lights[i]->shine ();
  197.   }
  198. }
  199.  
  200. void Sector::clear_shine_done ()
  201. {
  202.   int i;
  203.   draw_done = TRUE;
  204.   for (i = 0 ; i < num_polygon ; i++)
  205.   {
  206.     Sector* s = polygon[i]->get_portal ();
  207.     if (s)
  208.     {
  209.       if (!s->draw_done) s->clear_shine_done ();
  210.     }
  211.     else
  212.     {
  213.       polygon[i]->clear_shine_done ();
  214.     }
  215.   }
  216.   draw_done = FALSE;
  217.  
  218.   Thing* sp = first_thing;
  219.   while (sp)
  220.   {
  221.     sp->clear_shine_done ();
  222.     sp = (Thing*)(sp->get_next ());
  223.   }
  224. }
  225.  
  226. void Sector::mipmap_settings (int setting)
  227. {
  228.   int i;
  229.   for (i = 0 ; i < num_polygon ; i++)
  230.   {
  231.     Sector* s = polygon[i]->get_portal ();
  232.     if (!s)
  233.     {
  234.       polygon[i]->mipmap_settings (setting);
  235.     }
  236.   }
  237.  
  238.   Thing* sp = first_thing;
  239.   while (sp)
  240.   {
  241.     sp->mipmap_settings (setting);
  242.     sp = (Thing*)(sp->get_next ());
  243.   }
  244. }
  245.  
  246. void Sector::shine (Light* light)
  247. {
  248.   int i;
  249.   draw_done = TRUE;
  250.   for (i = 0 ; i < num_polygon ; i++)
  251.   {
  252.     if (polygon[i]->visible_from_point (light->get_center ()))
  253.     {
  254.       if (polygon[i]->sq_distance (light->get_center ()) < light->get_sq_dist ())
  255.       {
  256.     Sector* s = polygon[i]->get_portal ();
  257.     if (s)
  258.     {
  259.       if (!s->draw_done) s->shine (light);
  260.     }
  261.     else
  262.     {
  263.       polygon[i]->shine (light);
  264.     }
  265.       }
  266.     }
  267.   }
  268.   draw_done = FALSE;
  269.  
  270.   Thing* sp = first_thing;
  271.   while (sp)
  272.   {
  273.     sp->shine (light);
  274.     sp = (Thing*)(sp->get_next ());
  275.   }
  276. }
  277.  
  278. void Sector::setup_dyn_light (DynLight* light)
  279. {
  280.   int i;
  281.   float sq_dist;
  282.  
  283.   draw_done = TRUE;
  284.   for (i = 0 ; i < num_polygon ; i++)
  285.   {
  286.     if (polygon[i]->visible_from_point (light->get_center ()))
  287.     {
  288.       sq_dist = polygon[i]->sq_distance (light->get_center ());
  289.       if (sq_dist < light->get_sq_dist ())
  290.       {
  291.     Sector* s = polygon[i]->get_portal ();
  292.     if (s)
  293.     {
  294.       if (!s->draw_done) s->setup_dyn_light (light);
  295.     }
  296.     else
  297.     {
  298.       polygon[i]->setup_dyn_light (light, sq_dist);
  299.     }
  300.       }
  301.     }
  302.   }
  303.   draw_done = FALSE;
  304. }
  305.  
  306. DynLight* Sector::add_dyn_light (float x, float y, float z, float dist, float strength,
  307.                  float red_strength, float blue_strength)
  308. {
  309.   DynLight* l = new DynLight (x, y, z, dist, strength, red_strength, blue_strength);
  310.   l->set_sector (this);
  311.   l->setup ();
  312.   return l;
  313. }
  314.  
  315. void Sector::draw (ViewPolygon* view, Matrix3& m_w2c, Matrix3& m_c2w, Vector3& v_w2c)
  316. {
  317.   int i;
  318.   draw_done = TRUE;
  319.  
  320. #if USE_OCCLUSION
  321.   // First compute the convex hulls for all occlusion objects.
  322.   // These can then be used to 
  323.   Occlusion* o = first_occlusion;
  324.   while (o)
  325.   {
  326.     if (o->transform_world2cam (m_w2c, m_c2w, v_w2c))
  327.     {
  328.       o->convex_hull ();
  329.       if (Scan::c->edit_mode != MODE_NONE) o->edit_draw_vertices ();
  330.     }
  331.     else o->clear_hull ();
  332.     o = o->get_next ();
  333.   }
  334. #endif /*USE_OCCLUSION*/
  335.  
  336.   transform_world2cam (m_w2c, m_c2w, v_w2c);
  337.  
  338.   for (i = 0 ; i < num_polygon ; i++)
  339.   {
  340.     if (polygon[i]->do_perspective (m_w2c, m_c2w, v_w2c, &Polygon2D::clipped))
  341.     {
  342.       if (Polygon2D::clipped.clip_poly_variant (view))
  343.       {
  344. #       if USE_OCCLUSION
  345.     o = first_occlusion;
  346.     while (o)
  347.     {
  348.       if (!Polygon2D::clipped.clip_to_occlusion (o)) break;
  349.       o = o->get_next ();
  350.     }
  351.     if (o) continue; // Polygon has been completely clipped away
  352. #       endif /*USE_OCCLUSION*/
  353.  
  354.     Sector* s = polygon[i]->get_portal ();
  355.     if (s)
  356.     {
  357.       //if (!s->draw_done)
  358.       {
  359.         ViewPolygon* new_view = Polygon2D::clipped.create_view ();
  360.         if (new_view)
  361.         {
  362.           int filtered =
  363.         Scan::textures->get_texture (polygon[i]->get_texnr ())->get_transparent () != -1 ||
  364.         Scan::textures->get_texture (polygon[i]->get_texnr ())->get_filtered ();
  365.  
  366.           Polygon2D* keep_clipped = NULL;
  367.           if (filtered)
  368.         keep_clipped = new Polygon2D (Polygon2D::clipped);
  369.  
  370.           if (polygon[i]->is_space_warped ())
  371.           {
  372.         Matrix3 mw_w2c = m_w2c;
  373.         Matrix3 mw_c2w = m_c2w;
  374.         Vector3 vw_w2c = v_w2c;
  375.         polygon[i]->warp_space (mw_w2c, mw_c2w, vw_w2c);
  376.         s->draw (new_view, mw_w2c, mw_c2w, vw_w2c);
  377.           }
  378.           else s->draw (new_view, m_w2c, m_c2w, v_w2c);
  379.           delete new_view;
  380.  
  381.           if (filtered)
  382.           {
  383.         keep_clipped->draw_filled (polygon[i]);
  384.         delete keep_clipped;
  385.           }
  386.         }
  387.       }
  388.       //else printf ("This should not happen!\n");
  389.     }
  390.     else Polygon2D::clipped.draw_filled (polygon[i]);
  391.  
  392.     if (Scan::c->edit_mode != MODE_NONE && Scan::c->sel_polygon == polygon[i])
  393.       Polygon2D::clipped.draw (Scan::textures->red ());
  394.     else if (Scan::c->edit_mode == MODE_POLYGON) Polygon2D::clipped.draw (Scan::textures->white ());
  395.       }
  396.     }
  397.   }
  398.  
  399.   if (Scan::c->edit_mode != MODE_NONE) edit_draw_vertices ();
  400.  
  401.   Thing* sp = first_thing;
  402.   while (sp)
  403.   {
  404.     sp->draw (view, m_w2c, m_c2w, v_w2c);
  405.     sp = (Thing*)(sp->get_next ());
  406.   }
  407.  
  408.   draw_done = FALSE;
  409. }
  410.  
  411. void Sector::save (FILE* fp, int indent, Textures* textures)
  412. {
  413.   char sp[100]; strcpy (sp, spaces); sp[indent] = 0;
  414.   PolygonSet::save (fp, indent, textures, "SECTOR");
  415. #if USE_OCCLUSION
  416.   Occlusion* o = first_occlusion;
  417.   while (o)
  418.   {
  419.     o->save (fp, indent+2);
  420.     o = o->get_next ();
  421.   }
  422. #endif
  423.   Thing* s = first_thing;
  424.   while (s)
  425.   {
  426.     s->save (fp, indent+2, textures);
  427.     s = (Thing*)(s->get_next ());
  428.   }
  429.   int i;
  430.   for (i = 0 ; i < num_lights ; i++)
  431.     lights[i]->save (fp, indent+2);
  432.  
  433.   fprintf (fp, "%s)\n", sp);
  434. }
  435.  
  436. typedef char ObName[30];
  437.  
  438. void Sector::load_room (World* w, char** buf, Textures* textures)
  439. {
  440.   char* t;
  441.   char* old_buf;
  442.   int i, j, k, l;
  443.   int i1, i2, i3, i4;
  444.  
  445.   level1 = textures->get_level1 ();
  446.   level2 = textures->get_level2 ();
  447.   level3 = textures->get_level3 ();
  448.  
  449.   set_max (200, 100);
  450.  
  451.   num_vertices = 0;
  452.   num_polygon = 0;
  453.   for (i = 0 ; i < num_lights ; i++) delete lights[i];
  454.   num_lights = 0;
  455.   while (first_thing)
  456.   {
  457.     Thing* n = (Thing*)(first_thing->get_next ());
  458.     delete first_thing;
  459.     first_thing = n;
  460.   }
  461.  
  462.   skip_token (buf, "ROOM");
  463.   t = get_token (buf);
  464.   strcpy (name, t);
  465.   skip_token (buf, "(", "Expected '%s' instead of '%s' after the name of a ROOM!\n");
  466.  
  467.   Matrix3 mm; mm.identity ();
  468.   Vector3 vm (0, 0, 0);
  469.   int texnr;
  470.   float tscale;
  471.   int no_mipmap = FALSE, no_lighting = FALSE;
  472.   texnr = 0;
  473.   tscale = 1;
  474.  
  475.   int num_portals = 0;
  476.   struct Portal
  477.   {
  478.     ObName poly;
  479.     ObName sector;
  480.     int is_warp;
  481.     Matrix3 m_warp;
  482.     Vector3 v_warp;
  483.   };
  484.   Portal portals[30];
  485.  
  486.   int num_splits = 0;
  487.   struct Split
  488.   {
  489.     ObName poly;
  490.     float pctA[20];
  491.     float widA[20];
  492.     int dir;
  493.     int cnt;
  494.   };
  495.   Split to_split[60];
  496.   struct Color
  497.   {
  498.     ObName poly;
  499.     ObName plane;
  500.     int texnr;
  501.   };
  502.   Color colors[100];
  503.   int num_colors = 0;
  504.  
  505.   Vector3 v0, v1, v2, v3, v4, v5, v6, v7;
  506.   v0.x = -1; v0.y =  1; v0.z =  1;
  507.   v1.x =  1; v1.y =  1; v1.z =  1;
  508.   v2.x = -1; v2.y = -1; v2.z =  1;
  509.   v3.x =  1; v3.y = -1; v3.z =  1;
  510.   v4.x = -1; v4.y =  1; v4.z = -1;
  511.   v5.x =  1; v5.y =  1; v5.z = -1;
  512.   v6.x = -1; v6.y = -1; v6.z = -1;
  513.   v7.x =  1; v7.y = -1; v7.z = -1;
  514.   float r;
  515.  
  516.   while (TRUE)
  517.   {
  518.     old_buf = *buf;
  519.     t = get_token (buf);
  520.     if (*t == ')' || *t == 0) break;
  521.     if (!strcmp (t, "MOVE"))
  522.     {
  523.       skip_token (buf, "(", "Expected '%s' instead of '%s' after MOVE!\n");
  524.       mm.load (buf);
  525.       vm.load (buf);
  526.       skip_token (buf, ")", "Expected '%s' instead of '%s' to finish MOVE!\n");
  527.     }
  528.     else if (!strcmp (t, "TEXTURE"))
  529.     {
  530.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE!\n");
  531.       t = get_token (buf);
  532.       texnr = textures->get_texture_idx (t);
  533.       if (texnr == -1)
  534.       {
  535.         printf ("Couldn't find texture named '%s'!\n", t);
  536.     exit (0);
  537.       }
  538.     }
  539.     else if (!strcmp (t, "TEXTURE_LIGHTING"))
  540.     {
  541.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE_LIGHTING!\n");
  542.       t = get_token (buf);
  543.       no_lighting = !!strcmp (t, "yes");
  544.     }
  545.     else if (!strcmp (t, "TEXTURE_MIPMAP"))
  546.     {
  547.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE_MIPMAP!\n");
  548.       t = get_token (buf);
  549.       no_mipmap = !!strcmp (t, "yes");
  550.     }
  551.     else if (!strcmp (t, "CEIL_TEXTURE"))
  552.     {
  553.       skip_token (buf, "=", "Expected '%s' instead of '%s' after CEIL_TEXTURE!\n");
  554.       t = get_token (buf);
  555.       colors[num_colors].texnr = textures->get_texture_idx (t);
  556.       if (colors[num_colors].texnr == -1)
  557.       {
  558.         printf ("Couldn't find texture named '%s'!\n", t);
  559.     exit (0);
  560.       }
  561.       strcpy (colors[num_colors].poly, "up");
  562.       colors[num_colors].plane[0] = 0;
  563.       num_colors++;
  564.     }
  565.     else if (!strcmp (t, "FLOOR_TEXTURE"))
  566.     {
  567.       skip_token (buf, "=", "Expected '%s' instead of '%s' after FLOOR_TEXTURE!\n");
  568.       t = get_token (buf);
  569.       colors[num_colors].texnr = textures->get_texture_idx (t);
  570.       if (colors[num_colors].texnr == -1)
  571.       {
  572.         printf ("Couldn't find texture named '%s'!\n", t);
  573.     exit (0);
  574.       }
  575.       strcpy (colors[num_colors].poly, "down");
  576.       colors[num_colors].plane[0] = 0;
  577.       num_colors++;
  578.     }
  579.     else if (!strcmp (t, "TEX"))
  580.     {
  581.       t = get_token (buf);
  582.       strcpy (colors[num_colors].poly, t);
  583.       skip_token (buf, "=", "Expected '%s' instead of '%s' in TEX!\n");
  584.       skip_token (buf, "(", "Expected '%s' instead of '%s' in TEX!\n");
  585.       colors[num_colors].plane[0] = 0;
  586.       colors[num_colors].texnr = -1;
  587.  
  588.       while (TRUE)
  589.       {
  590.     old_buf = *buf;
  591.     t = get_token (buf);
  592.     if (*t == ')' || *t == 0) break;
  593.     if (!strcmp (t, "TEXTURE"))
  594.     {
  595.       t = get_token (buf);
  596.       colors[num_colors].texnr = textures->get_texture_idx (t);
  597.       if (colors[num_colors].texnr == -1)
  598.       {
  599.         printf ("Couldn't find texture named '%s'!\n", t);
  600.         exit (0);
  601.       }
  602.     }
  603.     else if (!strcmp (t, "PLANE"))
  604.     {
  605.       t = get_token (buf);
  606.       strcpy (colors[num_colors].plane, t);
  607.     }
  608.     else
  609.     {
  610.       printf ("What is '%s' doing in a ROOM/TEX statement?\n", t);
  611.       exit (0);
  612.     }
  613.       }
  614.       num_colors++;
  615.     }
  616.     else if (!strcmp (t, "TEXTURE_SCALE"))
  617.     {
  618.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE_SCALE!\n");
  619.       tscale = get_token_float (buf);
  620.     }
  621.     else if (!strcmp (t, "DIMX"))
  622.     {
  623.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMX!\n");
  624.       r = get_token_float (buf);
  625.       r /= 2;
  626.       v0.x = -r;
  627.       v1.x = r;
  628.       v2.x = -r;
  629.       v3.x = r;
  630.       v4.x = -r;
  631.       v5.x = r;
  632.       v6.x = -r;
  633.       v7.x = r;
  634.     }
  635.     else if (!strcmp (t, "DIMY"))
  636.     {
  637.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMY!\n");
  638.       r = get_token_float (buf);
  639.       r /= 2;
  640.       v0.y = r;
  641.       v1.y = r;
  642.       v2.y = -r;
  643.       v3.y = -r;
  644.       v4.y = r;
  645.       v5.y = r;
  646.       v6.y = -r;
  647.       v7.y = -r;
  648.     }
  649.     else if (!strcmp (t, "DIMZ"))
  650.     {
  651.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMZ!\n");
  652.       r = get_token_float (buf);
  653.       r /= 2;
  654.       v0.z = r;
  655.       v1.z = r;
  656.       v2.z = r;
  657.       v3.z = r;
  658.       v4.z = -r;
  659.       v5.z = -r;
  660.       v6.z = -r;
  661.       v7.z = -r;
  662.     }
  663.     else if (!strcmp (t, "FLOOR_HEIGHT"))
  664.     {
  665.       skip_token (buf, "=", "Expected '%s' instead of '%s' after FLOOR_HEIGHT!\n");
  666.       r = get_token_float (buf);
  667.       v0.y = r+v0.y-v2.y;
  668.       v1.y = r+v1.y-v3.y;
  669.       v4.y = r+v4.y-v6.y;
  670.       v5.y = r+v5.y-v7.y;
  671.       v2.y = r;
  672.       v3.y = r;
  673.       v6.y = r;
  674.       v7.y = r;
  675.     }
  676.     else if (!strcmp (t, "HEIGHT"))
  677.     {
  678.       skip_token (buf, "=", "Expected '%s' instead of '%s' after HEIGHT!\n");
  679.       r = get_token_float (buf);
  680.       v0.y = r+v2.y;
  681.       v1.y = r+v3.y;
  682.       v4.y = r+v6.y;
  683.       v5.y = r+v7.y;
  684.     }
  685.     else if (!strcmp (t, "FLOOR") || !strcmp (t, "FLOOR_CEIL"))
  686.     {
  687.       int floor_ceil = !strcmp (t, "FLOOR_CEIL");
  688.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  689.       v2.x = get_token_float (buf);
  690.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  691.       v2.z = get_token_float (buf);
  692.       t = get_token (buf);
  693.       if (*t == ',')
  694.       {
  695.         v2.y = v2.z;
  696.         v2.z = get_token_float (buf);
  697.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  698.       }
  699.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  700.  
  701.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  702.       v3.x = get_token_float (buf);
  703.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  704.       v3.z = get_token_float (buf);
  705.       t = get_token (buf);
  706.       if (*t == ',')
  707.       {
  708.         v3.y = v3.z;
  709.         v3.z = get_token_float (buf);
  710.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  711.       }
  712.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  713.  
  714.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  715.       v7.x = get_token_float (buf);
  716.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  717.       v7.z = get_token_float (buf);
  718.       t = get_token (buf);
  719.       if (*t == ',')
  720.       {
  721.         v7.y = v7.z;
  722.         v7.z = get_token_float (buf);
  723.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  724.       }
  725.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  726.  
  727.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  728.       v6.x = get_token_float (buf);
  729.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  730.       v6.z = get_token_float (buf);
  731.       t = get_token (buf);
  732.       if (*t == ',')
  733.       {
  734.         v6.y = v6.z;
  735.         v6.z = get_token_float (buf);
  736.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  737.       }
  738.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  739.       if (floor_ceil)
  740.       {
  741.         v0 = v2;
  742.     v1 = v3;
  743.     v5 = v7;
  744.     v4 = v6;
  745.       }
  746.     }
  747.     else if (!strcmp (t, "CEILING"))
  748.     {
  749.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  750.       v0.x = get_token_float (buf);
  751.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  752.       v0.z = get_token_float (buf);
  753.       t = get_token (buf);
  754.       if (*t == ',')
  755.       {
  756.         v0.y = v0.z;
  757.         v0.z = get_token_float (buf);
  758.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  759.       }
  760.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  761.  
  762.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  763.       v1.x = get_token_float (buf);
  764.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  765.       v1.z = get_token_float (buf);
  766.       t = get_token (buf);
  767.       if (*t == ',')
  768.       {
  769.         v1.y = v1.z;
  770.         v1.z = get_token_float (buf);
  771.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  772.       }
  773.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  774.  
  775.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  776.       v5.x = get_token_float (buf);
  777.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  778.       v5.z = get_token_float (buf);
  779.       t = get_token (buf);
  780.       if (*t == ',')
  781.       {
  782.         v5.y = v5.z;
  783.         v5.z = get_token_float (buf);
  784.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  785.       }
  786.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  787.  
  788.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  789.       v4.x = get_token_float (buf);
  790.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  791.       v4.z = get_token_float (buf);
  792.       t = get_token (buf);
  793.       if (*t == ',')
  794.       {
  795.         v4.y = v4.z;
  796.         v4.z = get_token_float (buf);
  797.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  798.       }
  799.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  800.     }
  801.     else if (!strcmp (t, "LIGHT"))
  802.     {
  803.       *buf = old_buf;
  804.       Light* l = new Light (0, 0, 0, 4, 1, 0, 0);
  805.       l->load (buf);
  806.       add_light (l);
  807.     }
  808.     else if (!strcmp (t, "SIXFACE"))
  809.     {
  810.       // Not an object but it is translated to a special thing.
  811.       t = get_token (buf);
  812.       Thing* sp = new Thing (t, 100, 100);
  813.       sp->set_sector (this);
  814.       *buf = old_buf;
  815.       sp->load_sixface (w, buf, textures);
  816.       add_thing (sp);
  817.     }
  818.     else if (!strcmp (t, "THING"))
  819.     {
  820.       // A thing.
  821.       t = get_token (buf);
  822.       Thing* sp = new Thing (t, 100, 100);
  823.       sp->set_sector (this);
  824.       *buf = old_buf;
  825.       sp->load (w, buf, textures);
  826.       add_thing (sp);
  827.     }
  828. #if USE_OCCLUSION
  829.     else if (!strcmp (t, "OCCLUSION"))
  830.     {
  831.       // An occlusion object.
  832.       t = get_token (buf);
  833.       Occlusion* sp = new Occlusion (t, 100);
  834.       sp->set_sector (this);
  835.       *buf = old_buf;
  836.       sp->load (w, buf);
  837.       add_occlusion (sp);
  838.     }
  839. #endif
  840.     else if (!strcmp (t, "PORTAL"))
  841.     {
  842.       skip_token (buf, "=", "Expected '%s' instead of '%s' after PORTAL!\n");
  843.       skip_token (buf, "(", "Expected '%s' instead of '%s' after PORTAL!\n");
  844.       t = get_token (buf);
  845.       strcpy (portals[num_portals].poly, t);
  846.       skip_token (buf, ",", "Expected '%s' instead of '%s' in PORTAL statement!\n");
  847.       t = get_token (buf);
  848.       strcpy (portals[num_portals].sector, t);
  849.       t = get_token (buf);
  850.       portals[num_portals].is_warp = FALSE;
  851.       if (*t == ',')
  852.       {
  853.     portals[num_portals].is_warp = TRUE;
  854.     portals[num_portals].m_warp.load (buf);
  855.     portals[num_portals].v_warp.load (buf);
  856.     skip_token (buf, ")", "Expected '%s' instead of '%s' to end PORTAL statement!\n");
  857.       }
  858.       else if (*t != ')')
  859.       {
  860.     printf ("Expected ')' or ',' to end PORTAL statement!\n");
  861.     exit (0);
  862.       }
  863.       num_portals++;
  864.     }
  865.     else if (!strcmp (t, "SPLIT"))
  866.     {
  867.       t = get_token (buf);
  868.       strcpy (to_split[num_splits].poly, t);
  869.       t = get_token (buf);
  870.       if (!strcmp (t, "VER")) to_split[num_splits].dir = 0;
  871.       else if (!strcmp (t, "HOR")) to_split[num_splits].dir = 1;
  872.       else
  873.       {
  874.         printf ("Expected 'VER' or 'HOR' in SPLIT statement!\n");
  875.         to_split[num_splits].dir = 0;
  876.       }
  877.       t = get_token (buf);
  878.       int cnt = 0;
  879.       if (*t == '%')
  880.       {
  881.         to_split[num_splits].pctA[cnt] = get_token_float (buf);
  882.     cnt++;
  883.       }
  884.       else if (*t == '[')
  885.       {
  886.     while (*t && *t != ']')
  887.     {
  888.       if (*t != '[' && *t != ',')
  889.       {
  890.         printf ("Expected '[' or ',' instead of '%s' in list of sizes!\n", t);
  891.       }
  892.       t = get_token (buf);
  893.       if (*t == '%')
  894.       {
  895.         to_split[num_splits].pctA[cnt] = get_token_float (buf);
  896.         cnt++;
  897.       }
  898.       else
  899.       {
  900.         to_split[num_splits].pctA[cnt] = -1;
  901.         sscanf (t, "%f", &to_split[num_splits].widA[cnt]);
  902.         cnt++;
  903.       }
  904.       t = get_token (buf);
  905.     }
  906.       }
  907.       else
  908.       {
  909.         to_split[num_splits].pctA[cnt] = -1;
  910.         sscanf (t, "%f", &to_split[num_splits].widA[cnt]);
  911.     cnt++;
  912.       }
  913.       to_split[num_splits].cnt = cnt;
  914.       num_splits++;
  915.     }
  916.     else if (!strcmp (t, "TRIGGER"))
  917.     {
  918.       t = get_token (buf);
  919.       if (!strcmp (t, "activate"))
  920.       {
  921.     skip_token (buf, ":", "Expected '%s' instead of '%s' in TRIGGER!\n");
  922.     t = get_token (buf);
  923.     Script* s = w->get_script (t);
  924.     if (!s)
  925.     {
  926.       printf ("Don't know script '%s'!\n", t);
  927.       exit (0);
  928.     }
  929.     new_activate_trigger (s);
  930.       }
  931.       else
  932.       {
  933.     printf ("Trigger '%s' not supported or known for object '%s'!\n", t, name);
  934.     exit (0);
  935.       }
  936.     }
  937.     else
  938.     {
  939.       printf ("What is '%s' doing in a ROOM statement?\n", t);
  940.       exit (0);
  941.     }
  942.   }
  943.  
  944.   Vector3 v, vv;
  945.   j = 0;
  946.   mm.transform (v0, vv); vv += vm; set_vertex (j++, vv);
  947.   mm.transform (v1, vv); vv += vm; set_vertex (j++, vv);
  948.   mm.transform (v2, vv); vv += vm; set_vertex (j++, vv);
  949.   mm.transform (v3, vv); vv += vm; set_vertex (j++, vv);
  950.   mm.transform (v4, vv); vv += vm; set_vertex (j++, vv);
  951.   mm.transform (v5, vv); vv += vm; set_vertex (j++, vv);
  952.   mm.transform (v6, vv); vv += vm; set_vertex (j++, vv);
  953.   mm.transform (v7, vv); vv += vm; set_vertex (j++, vv);
  954.  
  955.   Polygon3D* p;
  956.  
  957.   struct Todo
  958.   {
  959.     ObName poly;
  960.     int v1, v2, v3, v4;
  961.     int tv1, tv2;
  962.     int texnr;
  963.     int col_idx;    // Idx in colors table if there was an override.
  964.   };
  965.   Todo todo[100];
  966.   int done = 0;
  967.   int todo_end = 0;
  968.  
  969.   strcpy (todo[todo_end].poly, "north");
  970.   todo[todo_end].v1 = 0;
  971.   todo[todo_end].v2 = 1;
  972.   todo[todo_end].v3 = 3;
  973.   todo[todo_end].v4 = 2;
  974.   todo[todo_end].tv1 = 0;
  975.   todo[todo_end].tv2 = 1;
  976.   todo[todo_end].texnr = texnr;
  977.   todo[todo_end].col_idx = -1;
  978.   for (i = 0 ; i < num_colors ; i++)
  979.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  980.     {
  981.       todo[todo_end].col_idx = i;
  982.       break;
  983.     }
  984.   todo_end++;
  985.  
  986.   strcpy (todo[todo_end].poly, "east");
  987.   todo[todo_end].v1 = 1;
  988.   todo[todo_end].v2 = 5;
  989.   todo[todo_end].v3 = 7;
  990.   todo[todo_end].v4 = 3;
  991.   todo[todo_end].tv1 = 1;
  992.   todo[todo_end].tv2 = 5;
  993.   todo[todo_end].texnr = texnr;
  994.   todo[todo_end].col_idx = -1;
  995.   for (i = 0 ; i < num_colors ; i++)
  996.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  997.     {
  998.       todo[todo_end].col_idx = i;
  999.       break;
  1000.     }
  1001.   todo_end++;
  1002.  
  1003.   strcpy (todo[todo_end].poly, "south");
  1004.   todo[todo_end].v1 = 5;
  1005.   todo[todo_end].v2 = 4;
  1006.   todo[todo_end].v3 = 6;
  1007.   todo[todo_end].v4 = 7;
  1008.   todo[todo_end].tv1 = 5;
  1009.   todo[todo_end].tv2 = 4;
  1010.   todo[todo_end].texnr = texnr;
  1011.   todo[todo_end].col_idx = -1;
  1012.   for (i = 0 ; i < num_colors ; i++)
  1013.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  1014.     {
  1015.       todo[todo_end].col_idx = i;
  1016.       break;
  1017.     }
  1018.   todo_end++;
  1019.  
  1020.   strcpy (todo[todo_end].poly, "west");
  1021.   todo[todo_end].v1 = 4;
  1022.   todo[todo_end].v2 = 0;
  1023.   todo[todo_end].v3 = 2;
  1024.   todo[todo_end].v4 = 6;
  1025.   todo[todo_end].tv1 = 4;
  1026.   todo[todo_end].tv2 = 0;
  1027.   todo[todo_end].texnr = texnr;
  1028.   todo[todo_end].col_idx = -1;
  1029.   for (i = 0 ; i < num_colors ; i++)
  1030.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  1031.     {
  1032.       todo[todo_end].col_idx = i;
  1033.       break;
  1034.     }
  1035.   todo_end++;
  1036.  
  1037.   strcpy (todo[todo_end].poly, "up");
  1038.   todo[todo_end].v1 = 4;
  1039.   todo[todo_end].v2 = 5;
  1040.   todo[todo_end].v3 = 1;
  1041.   todo[todo_end].v4 = 0;
  1042.   todo[todo_end].tv1 = 4;
  1043.   todo[todo_end].tv2 = 5;
  1044.   todo[todo_end].texnr = texnr;
  1045.   todo[todo_end].col_idx = -1;
  1046.   for (i = 0 ; i < num_colors ; i++)
  1047.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  1048.     {
  1049.       todo[todo_end].col_idx = i;
  1050.       break;
  1051.     }
  1052.   todo_end++;
  1053.  
  1054.   strcpy (todo[todo_end].poly, "down");
  1055.   todo[todo_end].v1 = 2;
  1056.   todo[todo_end].v2 = 3;
  1057.   todo[todo_end].v3 = 7;
  1058.   todo[todo_end].v4 = 6;
  1059.   todo[todo_end].tv1 = 2;
  1060.   todo[todo_end].tv2 = 3;
  1061.   todo[todo_end].texnr = texnr;
  1062.   todo[todo_end].col_idx = -1;
  1063.   for (i = 0 ; i < num_colors ; i++)
  1064.     if (!strcmp (todo[todo_end].poly, colors[i].poly))
  1065.     {
  1066.       todo[todo_end].col_idx = i;
  1067.       break;
  1068.     }
  1069.   todo_end++;
  1070.  
  1071.   int split;
  1072.   while (done < todo_end)
  1073.   {
  1074.     split = FALSE;
  1075.     for (i = 0 ; i < num_splits ; i++)
  1076.       if (!strcmp (todo[done].poly, to_split[i].poly))
  1077.       {
  1078.         split = TRUE;
  1079.     break;
  1080.       }
  1081.  
  1082.     if (split)
  1083.     {
  1084.       if (to_split[i].dir)
  1085.       {
  1086.     // Horizontal
  1087.     i1 = todo[done].v1;
  1088.     i2 = todo[done].v2;
  1089.     i3 = todo[done].v3;
  1090.     i4 = todo[done].v4;
  1091.  
  1092.     for (l = 0 ; l < to_split[i].cnt ; l++)
  1093.     {
  1094.       Vector3::between (vtex (i1).get_v (), vtex (i2).get_v (),
  1095.                 v, to_split[i].pctA[l], to_split[i].widA[l]);
  1096.       set_vertex (j++, v);
  1097.       Vector3::between (vtex (i4).get_v (), vtex (i3).get_v (),
  1098.                 v, to_split[i].pctA[l], to_split[i].widA[l]);
  1099.       set_vertex (j++, v);
  1100.  
  1101.       sprintf (todo[todo_end].poly, "%s%c", todo[done].poly, l+'A');
  1102.       todo[todo_end].v1 = i1;
  1103.       todo[todo_end].v2 = j-2;
  1104.       todo[todo_end].v3 = j-1;
  1105.       todo[todo_end].v4 = i4;
  1106.       todo[todo_end].tv1 = todo[done].tv1;
  1107.       todo[todo_end].tv2 = todo[done].tv2;
  1108.       todo[todo_end].texnr = todo[done].texnr;
  1109.       todo[todo_end].col_idx = todo[done].col_idx;
  1110.       for (k = 0 ; k < num_colors ; k++)
  1111.         if (!strcmp (todo[todo_end].poly, colors[k].poly))
  1112.         {
  1113.           todo[todo_end].col_idx = k;
  1114.           break;
  1115.         }
  1116.       todo_end++;
  1117.  
  1118.       i1 = j-2;
  1119.       i4 = j-1;
  1120.     }
  1121.  
  1122.     sprintf (todo[todo_end].poly, "%s%c", todo[done].poly, l+'A');
  1123.         todo[todo_end].v1 = i1;
  1124.         todo[todo_end].v2 = i2;
  1125.         todo[todo_end].v3 = i3;
  1126.         todo[todo_end].v4 = i4;
  1127.         todo[todo_end].tv1 = todo[done].tv1;
  1128.         todo[todo_end].tv2 = todo[done].tv2;
  1129.         todo[todo_end].texnr = todo[done].texnr;
  1130.     todo[todo_end].col_idx = todo[done].col_idx;
  1131.     for (k = 0 ; k < num_colors ; k++)
  1132.       if (!strcmp (todo[todo_end].poly, colors[k].poly))
  1133.       {
  1134.         todo[todo_end].col_idx = k;
  1135.         break;
  1136.       }
  1137.         todo_end++;
  1138.       }
  1139.       else
  1140.       {
  1141.     // Vertical
  1142.     i1 = todo[done].v1;
  1143.     i2 = todo[done].v2;
  1144.     i3 = todo[done].v3;
  1145.     i4 = todo[done].v4;
  1146.  
  1147.     for (l = 0 ; l < to_split[i].cnt ; l++)
  1148.     {
  1149.       Vector3::between (vtex (i4).get_v (), vtex (i1).get_v (),
  1150.                 v, to_split[i].pctA[l], to_split[i].widA[l]);
  1151.       set_vertex (j++, v);
  1152.       Vector3::between (vtex (i3).get_v (), vtex (i2).get_v (),
  1153.                 v, to_split[i].pctA[l], to_split[i].widA[l]);
  1154.       set_vertex (j++, v);
  1155.  
  1156.       sprintf (todo[todo_end].poly, "%s%d", todo[done].poly, l+1);
  1157.       todo[todo_end].v1 = j-2;
  1158.       todo[todo_end].v2 = j-1;
  1159.       todo[todo_end].v3 = i3;
  1160.       todo[todo_end].v4 = i4;
  1161.       todo[todo_end].tv1 = todo[done].tv1;
  1162.       todo[todo_end].tv2 = todo[done].tv2;
  1163.       todo[todo_end].texnr = todo[done].texnr;
  1164.       todo[todo_end].col_idx = todo[done].col_idx;
  1165.       for (k = 0 ; k < num_colors ; k++)
  1166.         if (!strcmp (todo[todo_end].poly, colors[k].poly))
  1167.         {
  1168.           todo[todo_end].col_idx = k;
  1169.           break;
  1170.         }
  1171.       todo_end++;
  1172.  
  1173.       i3 = j-1;
  1174.       i4 = j-2;
  1175.     }
  1176.  
  1177.     sprintf (todo[todo_end].poly, "%s%d", todo[done].poly, l+1);
  1178.         todo[todo_end].v1 = i1;
  1179.         todo[todo_end].v2 = i2;
  1180.         todo[todo_end].v3 = i3;
  1181.         todo[todo_end].v4 = i4;
  1182.         todo[todo_end].tv1 = todo[done].tv1;
  1183.         todo[todo_end].tv2 = todo[done].tv2;
  1184.         todo[todo_end].texnr = todo[done].texnr;
  1185.     todo[todo_end].col_idx = todo[done].col_idx;
  1186.     for (k = 0 ; k < num_colors ; k++)
  1187.       if (!strcmp (todo[todo_end].poly, colors[k].poly))
  1188.       {
  1189.         todo[todo_end].col_idx = k;
  1190.         break;
  1191.       }
  1192.         todo_end++;
  1193.       }
  1194.     }
  1195.     else
  1196.     {
  1197.       int idx = todo[done].col_idx;
  1198.       if (idx == -1 || colors[idx].texnr == -1) texnr = todo[done].texnr;
  1199.       else texnr = colors[idx].texnr;
  1200.  
  1201.       p = new_polygon (todo[done].poly, 10, textures, texnr);
  1202.       p->add_vertex (todo[done].v1);
  1203.       p->add_vertex (todo[done].v2);
  1204.       p->add_vertex (todo[done].v3);
  1205.       p->add_vertex (todo[done].v4);
  1206.       if (idx == -1 || colors[idx].plane[0] == 0)
  1207.     p->set_texture_space (vtex (todo[done].tv1), vtex (todo[done].tv2), tscale);
  1208.       else
  1209.     p->set_texture_space (w->get_plane (colors[idx].plane));
  1210.       p->set_no_mipmap (no_mipmap);
  1211.       p->set_no_lighting (no_lighting);
  1212.     }
  1213.     done++;
  1214.   }
  1215.  
  1216.   Sector* portal;
  1217.  
  1218.   for (i = 0 ; i < num_portals ; i++)
  1219.   {
  1220.     p = get_polygon (portals[i].poly);
  1221.     if (!p)
  1222.     {
  1223.       printf ("Error locating polygon '%s' in room '%s'!\n", portals[i].poly, name);
  1224.       return;
  1225.     }
  1226.  
  1227.     portal = w->get_sector (portals[i].sector);
  1228.     if (!portal)
  1229.       portal = w->new_sector (portals[i].sector, 10, 10);  // This will later be defined correctly
  1230.     p->set_portal (portal);
  1231.     if (portals[i].is_warp)
  1232.       p->set_warp (portals[i].m_warp, portals[i].v_warp);
  1233.   }
  1234. }
  1235.  
  1236. void Sector::load (World* w, char** buf, Textures* textures)
  1237. {
  1238.   char* t;
  1239.   char* old_buf;
  1240.   PolygonSet::load (w, buf, textures, "SECTOR");
  1241.   int i;
  1242.  
  1243.   level1 = textures->get_level1 ();
  1244.   level2 = textures->get_level2 ();
  1245.   level3 = textures->get_level3 ();
  1246.  
  1247.   for (i = 0 ; i < num_lights ; i++) delete lights[i];
  1248.   num_lights = 0;
  1249.  
  1250.   while (first_thing)
  1251.   {
  1252.     Thing* n = (Thing*)(first_thing->get_next ());
  1253.     delete first_thing;
  1254.     first_thing = n;
  1255.   }
  1256.  
  1257.   while (TRUE)
  1258.   {
  1259.     old_buf = *buf;
  1260.     t = get_token (buf);
  1261.     if (*t == ')' || *t == 0) break;
  1262.     if (!strcmp (t, "THING"))
  1263.     {
  1264.       t = get_token (buf);
  1265.       Thing* sp = new Thing (t, 100, 100);
  1266.       sp->set_sector (this);
  1267.       *buf = old_buf;
  1268.       sp->load (w, buf, textures);
  1269.       add_thing (sp);
  1270.     }
  1271. #if USE_OCCLUSION
  1272.     else if (!strcmp (t, "OCCLUSION"))
  1273.     {
  1274.       t = get_token (buf);
  1275.       Occlusion* sp = new Occlusion (t, 100);
  1276.       sp->set_sector (this);
  1277.       *buf = old_buf;
  1278.       sp->load (w, buf);
  1279.       add_occlusion (sp);
  1280.     }
  1281. #endif
  1282.     else if (!strcmp (t, "SIXFACE"))
  1283.     {
  1284.       t = get_token (buf);
  1285.       Thing* sp = new Thing (t, 100, 100);
  1286.       sp->set_sector (this);
  1287.       *buf = old_buf;
  1288.       sp->load_sixface (w, buf, textures);
  1289.       add_thing (sp);
  1290.     }
  1291.     else if (!strcmp (t, "LIGHT"))
  1292.     {
  1293.       *buf = old_buf;
  1294.       Light* l = new Light (0, 0, 0, 4, 1, 0, 0);
  1295.       l->load (buf);
  1296.       add_light (l);
  1297.     }
  1298.     else
  1299.     {
  1300.       printf ("What is '%s' doing in a THING statement?\n", t);
  1301.     }
  1302.   }
  1303. }
  1304.  
  1305. Thing* Sector::get_thing (char* name)
  1306. {
  1307.   Thing* s = first_thing;
  1308.   while (s)
  1309.   {
  1310.     if (!strcmp (name, s->get_name ())) return s;
  1311.     s = (Thing*)(s->get_next ());
  1312.   }
  1313.   return NULL;
  1314. }
  1315.  
  1316. Polygon3D* Sector::select_polygon (Camera* c, ViewPolygon* view, int xx, int yy)
  1317. {
  1318.   // First check the things.
  1319.   Thing* sp = first_thing;
  1320.   Polygon3D* p, * min_p = NULL;
  1321.   Vector2 vs;
  1322.   Vector3 vc;
  1323.   vs.x = (float)xx;
  1324.   vs.y = (float)yy;
  1325.   float min_z = 1000000000.;
  1326.  
  1327.   while (sp)
  1328.   {
  1329.     p = sp->select_polygon (c, view, xx, yy);
  1330.     if (p)
  1331.     {
  1332.       // Directly after a ::select_polygon, Polygon2D::clipped still contains
  1333.       // the clipped polygon.
  1334. #if 0
  1335.       //@@@DOES NOT WORK ANYMORE! I HAVE TO CHANGE IT
  1336.       Polygon2D::clipped.get_3d_point (vs, vc);
  1337. #endif
  1338.       if (vc.z < min_z)
  1339.       {
  1340.     min_z = vc.z;
  1341.     min_p = p;
  1342.       }
  1343.     }
  1344.     sp = (Thing*)(sp->get_next ());
  1345.   }
  1346.  
  1347.   if (min_p) return min_p;
  1348.   else return PolygonSet::select_polygon (c, view, xx, yy);
  1349. }
  1350.  
  1351. //---------------------------------------------------------------------------
  1352.