Subversion Repositories DIN Is Noise

Rev

Rev 1768 | Rev 1805 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
* drone.h
* DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/


#ifndef __drone__
#define __drone__

#include "fader.h"
#include "solver.h"
#include "play.h"
#include "trail.h"
#include "alarm.h"
#include "modulator.h"
#include "noiser.h"
#include "container.h"
#include "vector2d.h"
#include "angle.h"

#include <string>
#include <map>
#include <ostream>

#define RESETCHUCKTRAILS(d) if (drone::chuckt::autoresettrails) resetchucktrails(d);

extern int TRAILSIZE;
extern int BOTTOM;
extern float DELTA_VOLUME;
extern float ARROW_U, ARROW_V;

struct din;
struct drone;

typedef std::list<drone*>::iterator drone_iterator;

struct attractee {
  int id;
  drone* d;
  attractee (int _id = -1, drone* _d = 0) {id = _id; d = _d;}
  bool operator== (const attractee& ae) {return (d == ae.d);}
};

struct drone {

  static float mastervolume;

  static int UID; // unique id
  int id; // this drone id

  play player;
  solver sol;

  float step; // determines pitch (see note.h)

  float vol; // actual volume
 
  int range; // range number on microtonal-keyboard
  float pos; // position in range (0 - left, 1 - right, can go < 0 & > 1 too)

  int sel; // selected?

  float cx, cy; // unmodulated position
  float x, y; // current position

  int snap; // snap to range edge?
  float sx; // snapped x (used for note snap)
  int note_num; // 0 = left note, 1 = right note of range

  float dy; // height from microtonal-keyboard bottom

  float r, g, b; // color
  void setcolor ();

  // visuals
  //
  trail_t trail; // trail points

  box<float> handle; // for picking
  static int HANDLESIZE; // default size
  int handle_size;

  struct arrowt {
    static float U, V, T, CAP;
    float u, v, t;
    int cap;
    arrowt () {reset ();}
    void reset ();
  } arrow;

  void calc_handle ();

  struct posafxvelt {
    int yes; // drone position affects velocity vector?
    point<float> pt;
    static double minmag;
    posafxvelt() : yes(0), pt (0.0f,0.0f) {}
  } posafxvel;

  // connections
  static float STIFFNESS;
  static std::map<drone*,bool> proc_conn;
  int nconn;
  std::list<drone*> connections;
  std::list<double> mags;
  enum {LINK=0, CHAIN=1};
  int type;
  drone* eval_conns ();
  void remagconns ();

  // states
  enum {DEAD=0, RISING, FALLING, ACTIVE};
  int state; // current
  fader fdr; // for rising/falling -> fade in/out

  int frozen; // frozen?
  double froze_at; // time when frozen
  int freeze ();
  int thaw ();
  void handle_time_pass ();

  //
  // mute/unmute ; drone <> noise
  fader gab;
  float tovol;
  static double gabt;

  // modulation
  modulator mod;

  // orbitals & rocketry
  //
  int attractor; // attractor?
  int orbiting; // orbiting?
  std::list<attractee> attractees; // list of drones attracted by this drone

  static struct defvelaccel { // default velocity/acceleration

    std::string name;

    struct magt {
      float val;
      int rndrd;
      rnd<float> rd;
      magt () {
        val = 1.0f;
        rndrd = 0;
      }
      float operator()() {if (rndrd) return rd() * val; else return val;}
    } mag;

    // direction
    int dir;
    enum {HORIZONTAL, VERTICAL, MOUSE};
    int neg;

    // random rotation
    int rndrot;
    rnd<float> rotrd;
    void setrotrd ();
    anglet clock, anticlock;

    defvelaccel (const std::string& n);

  } v0, a0;

  float V; // speed
  float vx, vy; // current velocity vector
  float v_mult; // multiplier for velocity vector used in orbit insertion

  float A; // acceleration
  float ax, ay; // acceleration unit vector
  float xi, yi; // interim position
  double insert; // time to insert into orbit

  float xv, yv; // position of velocity vector tip
  float xa, ya; // position of acceleration vector tip

  int gravity; // accelerated by gravity?

  int bounces; // number of bounces from bottom of microtonal-keyboard

  static int anchored;
  int launcher; // launches drones?
  alarm_t launch_every; // alarm time in seconds
  float dpm; // drones per minute
  drone* launched_by;

  // targets for launchers to launch drones to
  std::vector<drone*> targets;
  int cur_target;
  int num_targets;
  void clear_targets ();
  drone* target;

  static double LIFETIME;
  double birth; // time at birth
  double life; // lifetime
  int reincarnate;

  static double INSERTTIME; // time for insert into orbit

  enum {NONE, POINT, USE};
  int tracking;
  drone* tracked_drone; // the tracked drone

  // wanding
  static struct wandt {
    int dist;
    int dist2;
    wandt (int d) {set (d);}
    void set (int d) {
      dist = d;
      dist2 = d * d;
    }
  } wand;

  enum {UNSET=0, INTERPOLATE, EMPLACE};
  int update_pv;
  void update_pitch_volume ();

  drone (float bottom = 0.0f);

  static int ref; // for debug
  ~drone();

  void set_pos (float x, float y);
  void set_center (float _cx, float _cy, int e = 1);
  void move_center ();

  void change_depth (int i, int what, float delta);
  void change_bpm (int i, int what, float delta);
  void change_bpm (mod_params& mp, float delta);

  enum {DRONE, NOISE};
  static int IS;
  int is;
  noiser nsr;
  void setnoise ();

  enum {IMMORTAL, MORTAL, REINCARNATE};
  static int ARE;


  // for drone <> noise conversions
  struct fin {
    virtual void finished (din& d, drone* pd) = 0;
  } *finl;

  static struct drone2noise : fin {
    void finished (din& mkb, drone* pd);
  } dnl;

  static struct noise2drone : fin {
    void finished (din& mkb, drone* pd);
  } ndl;

  static fin* fins [3]; // 0 = null, 1 = drone2noise, 2 = noise2drone, init @ main.cc

  struct chuckt { // virtual geometric chuck

    static anglet apt; // angle per turn
    static int outline; // draw outline?
    static int autoresettrails; // auto reset trails when chuck params changed?

    int yes;
    drone* sun; // this drone aka planet orbits around sun
    drone* sat; // planet's satellite
    float ux, uy; // unit vector of sun -> planet vector
    float len; // length of sun -> planet vector
    float speed; // angular speed, scales apt
    float speed0; // for toggling speed, 0
    int dir; // -1 = clockwise; +1 = clockwise
    float cx, cy; // center b4 chucked

    chuckt () {
      yes = 0;
      sun = sat = 0;
      ux = uy = 0.0f;
      len = 0.0f;
      speed = 1.0f;
      speed0 = 0.0f;
      dir = 1;
      cx = cy = 0.0f;
    }

    void set (int y, drone* n) {
      yes = y;
      sun = n;
    }

    void calc (drone* planet) {
      len = unit_vector (ux, uy, sun->cx, sun->cy, planet->cx, planet->cy);
      if (sat) sat->chuck.calc (sat);
    }

    void de () {
      if (sat) {
        sat->chuck.sun = sun;
        if (sun) {
          sun->chuck.sat = sat;
          sat->chuck.calc (sat);
        }
      } else {
        if (sun) sun->chuck.sat = 0;
      }
      yes = 0;
    }

    void re (drone& p);

    void print ();

    void resettrail (drone* p);

  } chuck;

};

std::ostream& operator<< (std::ostream& f, drone::arrowt& aw);
std::istream& operator>> (std::istream&, drone::arrowt& aw);
std::ostream& operator<< (std::ostream&, drone::chuckt& ch);
std::istream& operator>> (std::istream&, drone::chuckt& ch);
std::ostream& operator<< (std::ostream& f, drone::defvelaccel& dva);
std::istream& operator>> (std::istream& f, drone::defvelaccel& dva);
std::istream& operator>> (std::istream&, drone::defvelaccel::magt&);
std::ostream& operator<< (std::ostream&, drone::defvelaccel::magt&);

struct group {
  int n;
  std::vector<drone*> drones;
  group () {n = 0;}
  group (std::vector<drone*> mem, int n);
  int member (drone* d) {
    std::vector<drone*>::iterator db = drones.begin (), de = drones.end();
    if (find (db, de, d) == de) return 0; else return 1;
  }
  int remove (drone* d) {
    if (erase (drones, d)) {
      --n;
      return 1;
    }
    return 0;
  }
};

struct drone_pendulum_group : group {
  int orient;
  int depth;
  drone_pendulum_group (int o = 0, int d = 0) { orient = o; depth = d;}
  drone_pendulum_group (int o, int d, std::vector<drone*> mem, int n) : group (mem, n), orient(o), depth(d)  {}
};



/*struct connect {
  int dirty;
  drone* d1;
  drone* d2;
  point<float> p1, p2;
  double mag;
  connect (drone* _d1, drone* _d2);
  int eval (drone** ret);
  void draw ();
  void align_vel ();
};*/


#endif