]> git.mxchange.org Git - flightgear.git/blob - src/FDM/YASim/ControlMap.cpp
Initial revision of Andy Ross's YASim code. This is (Y)et (A)nother Flight
[flightgear.git] / src / FDM / YASim / ControlMap.cpp
1 #include "Jet.hpp"
2 #include "Thruster.hpp"
3 #include "Gear.hpp"
4 #include "Wing.hpp"
5 #include "Math.hpp"
6
7 #include "ControlMap.hpp"
8 namespace yasim {
9
10 ControlMap::~ControlMap()
11 {
12     for(int i=0; i<_inputs.size(); i++) {
13         Vector* v = (Vector*)_inputs.get(i);
14         for(int j=0; j<v->size(); j++)
15             delete (MapRec*)v->get(j);
16         delete v;
17     }
18
19     for(int i=0; i<_outputs.size(); i++) {
20         OutRec* o = (OutRec*)_outputs.get(i);
21         delete[] o->values;
22         delete o;
23     }
24 }
25
26 int ControlMap::newInput()
27 {
28     Vector* v = new Vector();
29     return _inputs.add(v);
30 }
31
32 void ControlMap::addMapping(int input, int type, void* object, int options)
33 {
34     // See if the output object already exists
35     OutRec* out = 0;
36     for(int i=0; i<_outputs.size(); i++) {
37         OutRec* o = (OutRec*)_outputs.get(i);
38         if(o->object == object && o->type == type) {
39             out = o;
40             break;
41         }
42     }
43
44     // Create one if it doesn't
45     if(out == 0) {
46         out = new OutRec();
47         out->type = type;
48         out->object = object;
49         out->n = 0;
50         out->values = 0;
51         _outputs.add(out);
52     }
53
54     // Make space for the new input value
55     int idx = out->n++;
56     delete[] out->values;
57     out->values = new float[out->n];
58
59     // Add the new option tag
60     out->options.add((void*)options);
61
62     // Make a new input record
63     MapRec* map = new MapRec();
64     map->out = out;
65     map->idx = idx;
66
67     // And add it to the approproate vector.
68     Vector* maps = (Vector*)_inputs.get(input);
69     maps->add(map);
70 }
71
72 void ControlMap::reset()
73 {
74     // Set all the values to zero
75     for(int i=0; i<_outputs.size(); i++) {
76         OutRec* o = (OutRec*)_outputs.get(i);
77         for(int j=0; j<o->n; j++)
78             o->values[j] = 0;
79     }
80 }
81
82 void ControlMap::setInput(int input, float value)
83 {
84     Vector* maps = (Vector*)_inputs.get(input);
85     for(int i=0; i<maps->size(); i++) {
86         MapRec* map = (MapRec*)maps->get(i);
87         map->out->values[map->idx] = value;
88     }
89 }
90
91 void ControlMap::applyControls()
92 {
93     for(int outrec=0; outrec<_outputs.size(); outrec++) {
94         OutRec* o = (OutRec*)_outputs.get(outrec);
95         
96         // Generate a summed value.  Note the check for "split"
97         // control axes like ailerons.
98         float lval = 0, rval = 0;
99         for(int i=0; i<o->n; i++) {
100             float val = o->values[i];
101             int opt = (int)o->options.get(i);
102             if(opt & OPT_SQUARE)
103                 val = val * Math::abs(val);
104             if(opt & OPT_INVERT)
105                 val = -val;
106             lval += val;
107             if(opt & OPT_SPLIT)
108                 rval -= val;
109             else
110                 rval += val;
111         }
112
113         void* obj = o->object;
114         switch(o->type) {
115         case THROTTLE: ((Thruster*)obj)->setThrottle(lval);    break;
116         case MIXTURE:  ((Thruster*)obj)->setMixture(lval);     break;
117         case PROP:     ((Thruster*)obj)->setPropAdvance(lval); break;
118         case REHEAT:   ((Jet*)obj)->setReheat(lval);           break;
119         case BRAKE:    ((Gear*)obj)->setBrake(lval);           break;
120         case STEER:    ((Gear*)obj)->setRotation(lval);        break;
121         case EXTEND:   ((Gear*)obj)->setExtension(lval);       break;
122         case SLAT:     ((Wing*)obj)->setSlat(lval);            break;
123         case FLAP0:    ((Wing*)obj)->setFlap0(lval, rval);     break;
124         case FLAP1:    ((Wing*)obj)->setFlap1(lval, rval);     break;
125         case SPOILER:  ((Wing*)obj)->setSpoiler(lval, rval);   break;
126         }
127     }
128 }
129
130 }; // namespace yasim