/[enigma]/enigma/src/laser.cc
ViewVC logotype

Diff of /enigma/src/laser.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by dheck, Thu Mar 13 18:07:39 2003 UTC revision 1.6 by reallysoft, Fri Mar 28 14:52:33 2003 UTC
# Line 5  Line 5 
5   * modify it under the terms of the GNU General Public License   * modify it under the terms of the GNU General Public License
6   * as published by the Free Software Foundation; either version 2   * as published by the Free Software Foundation; either version 2
7   * of the License, or (at your option) any later version.   * of the License, or (at your option) any later version.
8   *     *
9   * This program is distributed in the hope that it will be useful,   * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Line 38  namespace Line 38  namespace
38      public:      public:
39          static void emit_from(GridPos p, Direction d);          static void emit_from(GridPos p, Direction d);
40          static void kill_all();          static void kill_all();
41            
42          // LaserEmitter interface          // LaserEmitter interface
43          DirectionBits emission_directions() const { return directions; }          DirectionBits emission_directions() const { return directions; }
44      private:      private:
# Line 54  namespace Line 54  namespace
54    
55          Object *clone() {          Object *clone() {
56              // new LaserBeams may only created inside `emit_from'.              // new LaserBeams may only created inside `emit_from'.
57              assert(0);              assert(0);
58              return 0;              return 0;
59          }          }
60          void dispose();          void dispose();
61    
# Line 78  an incoming beam). Line 78  an incoming beam).
78  \subsection lasera Attributes  \subsection lasera Attributes
79    
80  - \b on:      1 if laser in active, 0 if not  - \b on:      1 if laser in active, 0 if not
81  - \b dir:     the Direction in which light is emitted  - \b dir:     the Direction in which light is emitted
82              (NORTH, EAST, SOUTH, WEST)              (NORTH, EAST, SOUTH, WEST)
83    
84  \subsection laserm Messages  \subsection laserm Messages
# Line 101  an incoming beam). Line 101  an incoming beam).
101      private:      private:
102          // LaserEmitter interface          // LaserEmitter interface
103          DirectionBits emission_directions() const {          DirectionBits emission_directions() const {
104              return to_bits(get_dir());              if (is_on()) {
105                    return to_bits(get_dir());
106                }
107                return NODIRBIT;
108          }          }
109    
110          // OnOffStone interface.          // OnOffStone interface.
# Line 124  an incoming beam). Line 127  an incoming beam).
127  vector<void*> PhotoCell::instances;  vector<void*> PhotoCell::instances;
128    
129  void  void
130  PhotoCell::notify_start()  PhotoCell::notify_start()
131  {  {
132      for(unsigned i=0; i<instances.size(); ++i)      for(unsigned i=0; i<instances.size(); ++i)
133      {      {
# Line 134  PhotoCell::notify_start() Line 137  PhotoCell::notify_start()
137  }  }
138    
139  void  void
140  PhotoCell::notify_finish()  PhotoCell::notify_finish()
141  {  {
142      for(unsigned i=0; i<instances.size(); ++i)      for(unsigned i=0; i<instances.size(); ++i)
143      {      {
# Line 143  PhotoCell::notify_finish() Line 146  PhotoCell::notify_finish()
146      }      }
147  }  }
148    
149  void  void
150  PhotoCell::photo_activate()  PhotoCell::photo_activate()
151  {  {
152      vector<void*>::iterator i;      vector<void*>::iterator i;
153      i = std::find(instances.begin(), instances.end(), this);      i = std::find(instances.begin(), instances.end(), this);
154      if (i != instances.end())      if (i != instances.end())
155          assert(0 || "Photocell activated twice\n");          assert(0 || "Photocell activated twice\n");
156      else      else
157          instances.push_back(this);          instances.push_back(this);
158  }  }
159    
160  void  void
161  PhotoCell::photo_deactivate()  PhotoCell::photo_deactivate()
162  {  {
163      vector<void*>::iterator i;      vector<void*>::iterator i;
164      i = std::find(instances.begin(), instances.end(), this);      i = std::find(instances.begin(), instances.end(), this);
# Line 166  PhotoCell::photo_deactivate() Line 169  PhotoCell::photo_deactivate()
169  //----------------------------------------  //----------------------------------------
170  // PhotoStone  // PhotoStone
171  //----------------------------------------  //----------------------------------------
172  void  void
173  PhotoStone::check_state()  PhotoStone::check_state()
174  {  {
175      GridPos p = get_pos();      GridPos p = get_pos();
176      bool illu = (LightFrom(p, NORTH) || LightFrom(p, EAST)      bool illu = (LightFrom(p, NORTH) || LightFrom(p, EAST)
177                   || LightFrom(p, WEST) || LightFrom(p, SOUTH));                   || LightFrom(p, WEST) || LightFrom(p, SOUTH));
178    
179      if (illu != illuminated) {      if (illu != illuminated) {
180          if (illu)          if (illu) {
181              notify_laseron();              notify_laseron();
182          else          }
183            else {
184              notify_laseroff();              notify_laseroff();
185            }
186          illuminated = illu;          illuminated = illu;
187      }      }
188  }  }
# Line 184  PhotoStone::check_state() Line 190  PhotoStone::check_state()
190    
191  //----------------------------------------  //----------------------------------------
192  // LaserBeam  // LaserBeam
193  //  //
194  // The implementation of laser beams is a little tricky because, in  // The implementation of laser beams is a little tricky because, in
195  // spite of being implemented as Items, lasers aren't localized and  // spite of being implemented as Items, lasers aren't localized and
196  // changes to any part of the beam can affect the beam elsewhere.  A  // changes to any part of the beam can affect the beam elsewhere.  A
# Line 196  PhotoStone::check_state() Line 202  PhotoStone::check_state()
202  //  //
203  // - Laser beams are static. Once calculated they do not change until  // - Laser beams are static. Once calculated they do not change until
204  //   they are completely recalculated  //   they are completely recalculated
205  //    //
206  // - LaserBeam::emit_from() is the only way to emit laser beams. A new  // - LaserBeam::emit_from() is the only way to emit laser beams. A new
207  //   beam will propagate automatically and stops only if it comes  //   beam will propagate automatically and stops only if it comes
208  //   across a stone or or item that returns `false' from  //   across a stone or or item that returns `false' from
# Line 213  PhotoStone::check_state() Line 219  PhotoStone::check_state()
219    
220  vector<void*> LaserBeam::instances;  vector<void*> LaserBeam::instances;
221    
222  void  void
223  LaserBeam::init_model()  LaserBeam::init_model()
224  {  {
225      if (directions & (EASTBIT | WESTBIT)) {      if (directions & (EASTBIT | WESTBIT)) {
226          if (directions & (NORTHBIT | SOUTHBIT))          if (directions & (NORTHBIT | SOUTHBIT))
# Line 226  LaserBeam::init_model() Line 232  LaserBeam::init_model()
232          set_model("it-laserv");          set_model("it-laserv");
233  }  }
234    
235  bool  bool
236  LaserBeam::on_laserhit(Direction dir)  LaserBeam::on_laserhit(Direction dir)
237  {  {
238      DirectionBits dirbit = to_bits(dir);      DirectionBits dirbit = to_bits(dir);
239      if (!(directions & dirbit)) {      if (!(directions & dirbit)) {
# Line 239  LaserBeam::on_laserhit(Direction dir) Line 245  LaserBeam::on_laserhit(Direction dir)
245      return false;      return false;
246  }  }
247    
248  void  void
249  LaserBeam::on_creation()  LaserBeam::on_creation()
250  {  {
251      if (directions & EASTBIT) emit_from(get_pos(), EAST);      if (directions & EASTBIT) emit_from(get_pos(), EAST);
252      if (directions & WESTBIT) emit_from(get_pos(), WEST);      if (directions & WESTBIT) emit_from(get_pos(), WEST);
253      if (directions &NORTHBIT) emit_from(get_pos(), NORTH);      if (directions &NORTHBIT) emit_from(get_pos(), NORTH);
254      if (directions &SOUTHBIT) emit_from(get_pos(), SOUTH);      if (directions &SOUTHBIT) emit_from(get_pos(), SOUTH);
255      init_model();      init_model();
256  }  }
257    
258  void  void
259  LaserBeam::emit_from(GridPos p, Direction d)  LaserBeam::emit_from(GridPos p, Direction d)
260  {  {
261      bool may_pass = true;      bool may_pass = true;
262    
# Line 269  LaserBeam::emit_from(GridPos p, Directio Line 275  LaserBeam::emit_from(GridPos p, Directio
275      }      }
276  }  }
277    
278  bool  bool
279  LaserBeam::actor_hit(Actor *actor)  LaserBeam::actor_hit(Actor *actor)
280  {  {
281      double r = actor->get_radius();      double r = actor->get_radius();
# Line 299  LaserBeam::kill_all() Line 305  LaserBeam::kill_all()
305      }      }
306  }  }
307    
308  void  void
309  LaserBeam::dispose()  LaserBeam::dispose()
310  {  {
311      instances.erase(std::find(instances.begin(), instances.end(), this));      instances.erase(std::find(instances.begin(), instances.end(), this));
312      delete this;      delete this;
# Line 322  LaserStone::reemit_all() Line 328  LaserStone::reemit_all()
328      }      }
329  }  }
330    
331  void  void
332  LaserStone::notify_onoff(bool on)  LaserStone::notify_onoff(bool on)
333  {  {
334      RecalcLight();      RecalcLight();
335      if (on)      if (on)
336          sound::PlaySound("st-laseron");          sound::PlaySound("st-laseron");
337  }  }
338    
339  void  void
340  LaserStone::emit_light()  LaserStone::emit_light()
341  {  {
342      if (is_on())      if (is_on())
# Line 338  LaserStone::emit_light() Line 344  LaserStone::emit_light()
344  }  }
345    
346  /* */  /* */
347  void  void
348  LaserStone::on_creation()  LaserStone::on_creation()
349  {  {
350      if (is_on())      if (is_on())
351          RecalcLight(); //LaserBeam::emit_from(get_pos(), get_dir());          RecalcLight(); //LaserBeam::emit_from(get_pos(), get_dir());
352      Stone::on_creation();      Stone::on_creation();
353  }  }
354    
355  void  void
356  LaserStone::init_model()  LaserStone::init_model()
357  {  {
358      string mname = is_on() ? "st-laseron" : "st-laser";      string mname = is_on() ? "st-laseron" : "st-laser";
359      mname += to_suffix(get_dir());      mname += to_suffix(get_dir());
# Line 359  LaserStone::init_model() Line 365  LaserStone::init_model()
365  //----------------------------------------  //----------------------------------------
366  namespace  namespace
367  {  {
368      class MirrorStone      class MirrorStone
369          : public MovableStone, public LaserEmitter, public PhotoCell          : public MovableStone, public LaserEmitter, public PhotoCell
370      {      {
371      protected:      protected:
# Line 383  namespace Line 389  namespace
389      private:      private:
390          // Object interface.          // Object interface.
391          void message(const string &m, const Value &);          void message(const string &m, const Value &);
392            
393          // LaserEmitter interface          // LaserEmitter interface
394          DirectionBits emission_directions() const {          DirectionBits emission_directions() const {
395              return outdirs;              return outdirs;
# Line 406  namespace Line 412  namespace
412      };      };
413  }  }
414    
415  MirrorStone::MirrorStone(const char *name)  MirrorStone::MirrorStone(const char *name)
416      : MovableStone(name)      : MovableStone(name)
417  {  {
418      set_attrib("transparent", Value());      set_attrib("transparent", Value());
# Line 414  MirrorStone::MirrorStone(const char *nam Line 420  MirrorStone::MirrorStone(const char *nam
420      set_attrib("orientation", Value(1));      set_attrib("orientation", Value(1));
421  }  }
422    
423  void  void
424  MirrorStone::init_model()  MirrorStone::init_model()
425  {  {
426      string mname = get_kind();      string mname = get_kind();
427      mname += is_movable() ? "-m" : "-s";      mname += is_movable() ? "-m" : "-s";
# Line 424  MirrorStone::init_model() Line 430  MirrorStone::init_model()
430      set_model(mname);      set_model(mname);
431  }  }
432    
433  void  void
434  MirrorStone::message(const string &m, const Value &)  MirrorStone::message(const string &m, const Value &)
435  {  {
436      if (m == "trigger" || m=="turn") {      if (m == "trigger" || m=="turn") {
# Line 434  MirrorStone::message(const string &m, co Line 440  MirrorStone::message(const string &m, co
440    
441    
442  void  void
443  MirrorStone::actor_hit(const StoneContact &sc)  MirrorStone::actor_hit(const StoneContact &sc)
444  {  {
445      if (is_movable())      if (is_movable())
446          MovableStone::actor_hit(sc);          MovableStone::actor_hit(sc);
447      rotate_right();      rotate_right();
448  }  }
449    
450  void  void
451  MirrorStone::on_creation()  MirrorStone::on_creation()
452  {  {
453      photo_activate();      photo_activate();
454      Stone::on_creation();      Stone::on_creation();
455  }  }
456    
457  void  void
458  MirrorStone::on_removal()  MirrorStone::on_removal()
459  {  {
460      photo_deactivate();      photo_deactivate();
461      Stone::on_removal();      Stone::on_removal();
462  }  }
463    
464  void  void
465  MirrorStone::rotate_right()  MirrorStone::rotate_right()
466  {  {
467      set_orientation(1+(get_orientation() % 4));      set_orientation(1+(get_orientation() % 4));
468      init_model();      init_model();
# Line 493  namespace Line 499  namespace
499      };      };
500  }  }
501    
502  bool  bool
503  PlaneMirror::on_laserhit(Direction dir)  PlaneMirror::on_laserhit(Direction dir)
504  {  {
505      switch (get_orientation()) {      switch (get_orientation()) {
# Line 501  PlaneMirror::on_laserhit(Direction dir) Line 507  PlaneMirror::on_laserhit(Direction dir)
507          if (dir==EAST || dir==WEST)          if (dir==EAST || dir==WEST)
508              emit_light(reverse(dir));              emit_light(reverse(dir));
509          break;          break;
510      case '-':      case '-':
511          if (dir==NORTH || dir==SOUTH)          if (dir==NORTH || dir==SOUTH)
512              emit_light(reverse(dir));              emit_light(reverse(dir));
513          break;          break;
514      case '/':      case '/':
515          switch(dir) {          switch(dir) {
516          case EAST: emit_light(NORTH); break;          case EAST: emit_light(NORTH); break;
517          case SOUTH: emit_light(WEST); break;          case SOUTH: emit_light(WEST); break;
# Line 514  PlaneMirror::on_laserhit(Direction dir) Line 520  PlaneMirror::on_laserhit(Direction dir)
520          case NODIR: break;          case NODIR: break;
521          }          }
522          break;          break;
523      case '\\':      case '\\':
524          switch(dir) {          switch(dir) {
525          case EAST: emit_light(SOUTH); break;          case EAST: emit_light(SOUTH); break;
526          case SOUTH: emit_light(EAST); break;          case SOUTH: emit_light(EAST); break;
# Line 545  namespace Line 551  namespace
551          TriangleMirror() : MirrorStone("st-3mirror") {}          TriangleMirror() : MirrorStone("st-3mirror") {}
552      private:      private:
553    
554          Direction get_orientation()          Direction get_orientation()
555          {          {
556              Direction a[] = {NODIR, SOUTH, WEST, NORTH, EAST};              Direction a[] = {NODIR, SOUTH, WEST, NORTH, EAST};
557              return a[MirrorStone::get_orientation()];              return a[MirrorStone::get_orientation()];
# Line 554  namespace Line 560  namespace
560      };      };
561  }  }
562    
563  bool  bool
564  TriangleMirror::on_laserhit(Direction dir)  TriangleMirror::on_laserhit(Direction dir)
565  {  {
566      Direction orient = get_orientation();      Direction orient = get_orientation();
567    
568      if (dir == orient)      if (dir == orient)
569          emit_light(reverse(dir));          emit_light(reverse(dir));
570      else if (dir == reverse(orient)) {      else if (dir == reverse(orient)) {
571          // this is the "complicated" case where the light falls          // this is the "complicated" case where the light falls
572          // on the tip of the triangle          // on the tip of the triangle
573          switch (dir) {          switch (dir) {
574          case SOUTH: case NORTH:          case SOUTH: case NORTH:
575              emit_light(EAST); emit_light(WEST); break;              emit_light(EAST); emit_light(WEST); break;
576          case WEST: case EAST:          case WEST: case EAST:
577              emit_light(SOUTH); emit_light(NORTH); break;              emit_light(SOUTH); emit_light(NORTH); break;
578          case NODIR: break;          case NODIR: break;
579          }          }
580      } else      } else
581          emit_light(orient);          emit_light(orient);
582      if (is_transparent())      if (is_transparent())
583          emit_light(dir);          emit_light(dir);
# Line 588  namespace Line 594  namespace
594      bool light_recalc_scheduled = false;      bool light_recalc_scheduled = false;
595  }  }
596    
597  void  void
598  world::laser::Init()  world::laser::Init()
599  {  {
600      Register(new LaserStone);      Register(new LaserStone);
# Line 597  world::laser::Init() Line 603  world::laser::Init()
603  }  }
604    
605    
606  void  void
607  world::laser::MaybeRecalcLight(GridPos p)  world::laser::MaybeRecalcLight(GridPos p)
608  {  {
609      light_recalc_scheduled |=      light_recalc_scheduled |=
610          (LightFrom(p, NORTH) || LightFrom(p, SOUTH) ||          (LightFrom(p, NORTH) || LightFrom(p, SOUTH) ||
611           LightFrom(p, WEST) || LightFrom(p, EAST));           LightFrom(p, WEST) || LightFrom(p, EAST));
612  }  }
613    
614  void  void
615  world::laser::RecalcLight()  world::laser::RecalcLight()
616  {  {
617      light_recalc_scheduled = true;      light_recalc_scheduled = true;

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26