0
|
1 |
#include "stdafx.h"
|
|
2 |
#include "airport.h"
|
|
3 |
|
|
4 |
AirportFTAClass *CountryAirport;
|
|
5 |
AirportFTAClass *CityAirport;
|
|
6 |
AirportFTAClass *Heliport, *Oilrig;
|
|
7 |
AirportFTAClass *MetropolitanAirport;
|
|
8 |
AirportFTAClass *InternationalAirport;
|
|
9 |
|
|
10 |
static void AirportFTAClass_Constructor(AirportFTAClass *Airport,
|
|
11 |
const byte nofterminals, const byte nofterminalgroups,
|
|
12 |
const byte nofhelipads, const byte nofhelipadgroups,
|
|
13 |
const byte entry_point, const byte acc_planes,
|
|
14 |
const AirportFTAbuildup *FA,
|
|
15 |
const TileIndex *depots);
|
|
16 |
static void AirportFTAClass_Destructor(AirportFTAClass *Airport);
|
|
17 |
|
|
18 |
static uint16 AirportGetNofElements(const AirportFTAbuildup *FA);
|
|
19 |
static void AirportBuildAutomata(AirportFTAClass *Airport, const AirportFTAbuildup *FA);
|
|
20 |
static byte AirportTestFTA(const AirportFTAClass *Airport);
|
|
21 |
/*static void AirportPrintOut(const AirportFTAClass *Airport, const bool full_report);
|
|
22 |
static byte AirportBlockToString(uint32 block);*/
|
|
23 |
|
|
24 |
void InitializeAirports()
|
|
25 |
{
|
|
26 |
// country airport
|
|
27 |
CountryAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
|
28 |
AirportFTAClass_Constructor(CountryAirport, 2, 1, 0, 0, 16, ALL, _airport_fta_country, _airport_depots_country);
|
|
29 |
|
|
30 |
// city airport
|
|
31 |
CityAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
|
32 |
AirportFTAClass_Constructor(CityAirport, 3, 1, 0, 0, 19, ALL, _airport_fta_city, _airport_depots_city);
|
|
33 |
|
|
34 |
// metropolitan airport
|
|
35 |
MetropolitanAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
|
36 |
AirportFTAClass_Constructor(MetropolitanAirport, 3, 1, 0, 0, 20, ALL, _airport_fta_metropolitan, _airport_depots_metropolitan);
|
|
37 |
|
|
38 |
// international airport
|
|
39 |
InternationalAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
|
40 |
AirportFTAClass_Constructor(InternationalAirport, 6, 2, 2, 1, 37, ALL, _airport_fta_international, _airport_depots_international);
|
|
41 |
|
|
42 |
// heliport, oilrig
|
|
43 |
Heliport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass));
|
|
44 |
AirportFTAClass_Constructor(Heliport, 0, 0, 1, 1, 7, HELICOPTERS_ONLY, _airport_fta_heliport_oilrig, _airport_depots_heliport_oilrig);
|
|
45 |
Oilrig = Heliport; // exactly the same structure for heliport/oilrig, so share state machine
|
|
46 |
}
|
|
47 |
|
|
48 |
void UnInitializeAirports()
|
|
49 |
{
|
|
50 |
AirportFTAClass_Destructor(CountryAirport);
|
|
51 |
AirportFTAClass_Destructor(CityAirport);
|
|
52 |
AirportFTAClass_Destructor(Heliport);
|
|
53 |
AirportFTAClass_Destructor(MetropolitanAirport);
|
|
54 |
AirportFTAClass_Destructor(InternationalAirport);
|
|
55 |
}
|
|
56 |
|
|
57 |
static void AirportFTAClass_Constructor(AirportFTAClass *Airport,
|
|
58 |
const byte nofterminals, const byte nofterminalgroups,
|
|
59 |
const byte nofhelipads, const byte nofhelipadgroups,
|
|
60 |
const byte entry_point, const byte acc_planes,
|
|
61 |
const AirportFTAbuildup *FA,
|
|
62 |
const TileIndex *depots)
|
|
63 |
{
|
|
64 |
// if there are more terminals than 6, internal variables have to be changed, so don't allow that
|
|
65 |
// same goes for helipads
|
|
66 |
if (nofterminals > MAX_TERMINALS) { printf("Currently only maximum of %2d terminals are supported (you wanted %2d)\n", MAX_TERMINALS, nofterminals);}
|
|
67 |
if (nofhelipads > MAX_HELIPADS) { printf("Currently only maximum of %2d helipads are supported (you wanted %2d)\n", MAX_HELIPADS, nofhelipads);}
|
|
68 |
// terminals/helipads are divided into groups. Groups are computed by dividing the number
|
|
69 |
// of terminals by the number of groups. Half in half. If #terminals is uneven, first group
|
|
70 |
// will get the less # of terminals
|
|
71 |
if (nofterminalgroups > nofterminals) { printf("# of terminalgroups (%2d) must be less or equal to terminals (%2d)", nofterminals, nofterminalgroups);}
|
|
72 |
if (nofhelipadgroups > nofhelipads) { printf("# of helipadgroups (%2d) must be less or equal to helipads (%2d)", nofhelipads, nofhelipadgroups);}
|
|
73 |
|
|
74 |
assert(nofterminals <= MAX_TERMINALS);
|
|
75 |
assert(nofhelipads <= MAX_HELIPADS);
|
|
76 |
assert(nofterminalgroups <= nofterminals);
|
|
77 |
assert(nofhelipadgroups <= nofhelipads);
|
|
78 |
|
|
79 |
Airport->nofelements = AirportGetNofElements(FA);
|
|
80 |
// check
|
|
81 |
if (entry_point >= Airport->nofelements) {printf("Entry point (%2d) must be within the airport positions (which is max %2d)\n", entry_point, Airport->nofelements);}
|
|
82 |
assert(entry_point < Airport->nofelements);
|
|
83 |
|
|
84 |
Airport->nofterminals = nofterminals;
|
|
85 |
Airport->nofterminalgroups = nofterminalgroups;
|
|
86 |
Airport->nofhelipads = nofhelipads;
|
|
87 |
Airport->nofhelipadgroups = nofhelipadgroups;
|
|
88 |
Airport->acc_planes = acc_planes;
|
|
89 |
Airport->entry_point = entry_point;
|
|
90 |
Airport->airport_depots = (uint16*)depots;
|
|
91 |
|
|
92 |
|
|
93 |
// build the state machine
|
|
94 |
AirportBuildAutomata(Airport, FA);
|
|
95 |
//#ifdef _DEBUG
|
|
96 |
// {printf("#Elements %2d; #Terminals %2d in %d group(s); #Helipads %2d in %d group(s)\n", Airport->nofelements,
|
|
97 |
// Airport->nofterminals, Airport->nofterminalgroups, Airport->nofhelipads, Airport->nofhelipadgroups);}
|
|
98 |
//#endif
|
|
99 |
|
|
100 |
|
|
101 |
{
|
|
102 |
byte _retval = AirportTestFTA(Airport);
|
|
103 |
if (_retval != MAX_ELEMENTS) {printf("ERROR with element: %d\n", _retval-1);}
|
|
104 |
assert(_retval == MAX_ELEMENTS);
|
|
105 |
}
|
|
106 |
// print out full information
|
|
107 |
// true -- full info including heading, block, etc
|
|
108 |
// false -- short info, only position and next position
|
|
109 |
//AirportPrintOut(Airport, false);
|
|
110 |
}
|
|
111 |
|
|
112 |
static void AirportFTAClass_Destructor(AirportFTAClass *Airport)
|
|
113 |
{
|
|
114 |
int i;
|
|
115 |
AirportFTA *current, *next;
|
|
116 |
|
|
117 |
for (i = 0; i < Airport->nofelements; i++) {
|
|
118 |
current = Airport->layout[i].next_in_chain;
|
|
119 |
while (current != NULL) {
|
|
120 |
next = current->next_in_chain;
|
|
121 |
free(current);
|
|
122 |
current = next;
|
|
123 |
};
|
|
124 |
}
|
|
125 |
free(Airport->layout);
|
|
126 |
free(Airport);
|
|
127 |
}
|
|
128 |
|
|
129 |
static uint16 AirportGetNofElements(const AirportFTAbuildup *FA)
|
|
130 |
{
|
|
131 |
int i;
|
|
132 |
uint16 nofelements = 0;
|
|
133 |
int temp = FA[0].position;
|
|
134 |
for (i = 0; i < MAX_ELEMENTS; i++) {
|
|
135 |
if (temp != FA[i].position) {
|
|
136 |
nofelements++;
|
|
137 |
temp = FA[i].position;
|
|
138 |
}
|
|
139 |
if (FA[i].position == MAX_ELEMENTS) {break;}
|
|
140 |
}
|
|
141 |
return nofelements;
|
|
142 |
}
|
|
143 |
|
|
144 |
static void AirportBuildAutomata(AirportFTAClass *Airport, const AirportFTAbuildup *FA)
|
|
145 |
{
|
|
146 |
AirportFTA *FAutomata;
|
|
147 |
AirportFTA *current;
|
|
148 |
uint16 internalcounter, i;
|
|
149 |
FAutomata = (AirportFTA *)malloc(sizeof(AirportFTA) * Airport->nofelements);
|
|
150 |
Airport->layout = FAutomata;
|
|
151 |
internalcounter = 0;
|
|
152 |
|
|
153 |
for (i = 0; i < Airport->nofelements; i++) {
|
|
154 |
current = &Airport->layout[i];
|
|
155 |
current->position = FA[internalcounter].position;
|
|
156 |
current->heading = FA[internalcounter].heading;
|
|
157 |
current->block = FA[internalcounter].block;
|
|
158 |
current->next_position = FA[internalcounter].next_in_chain;
|
|
159 |
|
|
160 |
// outgoing nodes from the same position, create linked list
|
|
161 |
while (current->position == FA[internalcounter+1].position) {
|
|
162 |
AirportFTA *newNode = (AirportFTA *)malloc(sizeof(AirportFTA));
|
|
163 |
newNode->position = FA[internalcounter+1].position;
|
|
164 |
newNode->heading = FA[internalcounter+1].heading;
|
|
165 |
newNode->block = FA[internalcounter+1].block;
|
|
166 |
newNode->next_position = FA[internalcounter+1].next_in_chain;
|
|
167 |
// create link
|
|
168 |
current->next_in_chain = newNode;
|
|
169 |
current = current->next_in_chain;
|
|
170 |
internalcounter++;
|
|
171 |
} // while
|
|
172 |
current->next_in_chain = NULL;
|
|
173 |
internalcounter++;
|
|
174 |
}
|
|
175 |
}
|
|
176 |
|
|
177 |
static byte AirportTestFTA(const AirportFTAClass *Airport)
|
|
178 |
{
|
|
179 |
byte position, i, next_element;
|
|
180 |
AirportFTA *temp;
|
|
181 |
next_element = 0;
|
|
182 |
|
|
183 |
for (i = 0; i < Airport->nofelements; i++) {
|
|
184 |
position = Airport->layout[i].position;
|
|
185 |
if (position != next_element) {return i;}
|
|
186 |
temp = &Airport->layout[i];
|
|
187 |
|
|
188 |
do {
|
|
189 |
if (temp->heading > MAX_HEADINGS && temp->heading != 255) {return i;}
|
|
190 |
if (temp->heading == 0 && temp->next_in_chain != 0) {return i;}
|
|
191 |
if (position != temp->position) {return i;}
|
|
192 |
if (temp->next_position >= Airport->nofelements) {return i;}
|
|
193 |
temp = temp->next_in_chain;
|
|
194 |
} while (temp != NULL);
|
|
195 |
next_element++;
|
|
196 |
}
|
|
197 |
return MAX_ELEMENTS;
|
|
198 |
}
|
|
199 |
|
|
200 |
static const char* const _airport_heading_strings[MAX_HEADINGS+2] = {
|
|
201 |
"TO_ALL",
|
|
202 |
"HANGAR",
|
|
203 |
"TERM1",
|
|
204 |
"TERM2",
|
|
205 |
"TERM3",
|
|
206 |
"TERM4",
|
|
207 |
"TERM5",
|
|
208 |
"TERM6",
|
|
209 |
"HELIPAD1",
|
|
210 |
"HELIPAD2",
|
|
211 |
"TAKEOFF",
|
|
212 |
"STARTTAKEOFF",
|
|
213 |
"ENDTAKEOFF",
|
|
214 |
"HELITAKEOFF",
|
|
215 |
"FLYING",
|
|
216 |
"LANDING",
|
|
217 |
"ENDLANDING",
|
|
218 |
"HELILANDING",
|
|
219 |
"HELIENDLANDING",
|
|
220 |
"DUMMY" // extra heading for 255
|
|
221 |
};
|
|
222 |
|
|
223 |
/*
|
|
224 |
static void AirportPrintOut(const AirportFTAClass *Airport, const bool full_report)
|
|
225 |
{
|
|
226 |
AirportFTA *temp;
|
|
227 |
uint16 i;
|
|
228 |
byte heading;
|
|
229 |
|
|
230 |
printf("(P = Current Position; NP = Next Position)\n");
|
|
231 |
for (i = 0; i < Airport->nofelements; i++) {
|
|
232 |
temp = &Airport->layout[i];
|
|
233 |
if (full_report) {
|
|
234 |
heading = (temp->heading == 255) ? MAX_HEADINGS+1 : temp->heading;
|
|
235 |
printf("Pos:%2d NPos:%2d Heading:%15s Block:%2d\n", temp->position, temp->next_position,
|
|
236 |
_airport_heading_strings[heading], AirportBlockToString(temp->block));
|
|
237 |
}
|
|
238 |
else { printf("P:%2d NP:%2d", temp->position, temp->next_position);}
|
|
239 |
while (temp->next_in_chain != NULL) {
|
|
240 |
temp = temp->next_in_chain;
|
|
241 |
if (full_report) {
|
|
242 |
heading = (temp->heading == 255) ? MAX_HEADINGS+1 : temp->heading;
|
|
243 |
printf("Pos:%2d NPos:%2d Heading:%15s Block:%2d\n", temp->position, temp->next_position,
|
|
244 |
_airport_heading_strings[heading], AirportBlockToString(temp->block));
|
|
245 |
}
|
|
246 |
else { printf("P:%2d NP:%2d", temp->position, temp->next_position);}
|
|
247 |
}
|
|
248 |
printf("\n");
|
|
249 |
}
|
|
250 |
}
|
|
251 |
|
|
252 |
|
|
253 |
static byte AirportBlockToString(uint32 block)
|
|
254 |
{
|
|
255 |
byte i = 0;
|
|
256 |
if (block & 0xffff0000) { block >>= 16; i += 16; }
|
|
257 |
if (block & 0x0000ff00) { block >>= 8; i += 8; }
|
|
258 |
if (block & 0x000000f0) { block >>= 4; i += 4; }
|
|
259 |
if (block & 0x0000000c) { block >>= 2; i += 2; }
|
|
260 |
if (block & 0x00000002) { i += 1; }
|
|
261 |
return i;
|
|
262 |
}*/
|
|
263 |
|
|
264 |
const AirportFTAClass* GetAirport(const byte airport_type)
|
|
265 |
{
|
|
266 |
AirportFTAClass *Airport = NULL;
|
|
267 |
//FIXME -- AircraftNextAirportPos_and_Order -> Needs something nicer, don't like this code
|
|
268 |
// needs constant change if more airports are added
|
|
269 |
switch (airport_type) {
|
|
270 |
case AT_SMALL: Airport = CountryAirport; break;
|
|
271 |
case AT_LARGE: Airport = CityAirport; break;
|
|
272 |
case AT_METROPOLITAN: Airport = MetropolitanAirport; break;
|
|
273 |
case AT_HELIPORT: Airport = Heliport; break;
|
|
274 |
case AT_OILRIG: Airport = Oilrig; break;
|
|
275 |
case AT_INTERNATIONAL: Airport = InternationalAirport; break;
|
|
276 |
default:
|
|
277 |
#ifdef DEBUG__
|
|
278 |
printf("Airport AircraftNextAirportPos_and_Order not yet implemented\n");
|
|
279 |
#endif
|
|
280 |
assert(airport_type <= AT_INTERNATIONAL);
|
|
281 |
}
|
|
282 |
return Airport;
|
|
283 |
}
|