1 /* ---------------------------------------------------------------------- *
2 * transport.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * ---------------------------------------------------------------------- */
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include "common.h"
10 #include "lctypes.h"
11 #include "lin-city.h"
12 #include "transport.h"
13 #include "power.h"
14 #include "stats.h" /* for transport_cost */
15
16 /* ---------------------------------------------------------------------
17 For track, road and rail:
18
19 int_1 contains the amount of food
20 int_2 contains the amount of jobs
21 int_3 contains the amount of coal
22 int_4 contains the amount of goods
23 int_5 contains the amount of ore
24 int_6 contains the amount of steel
25 int_7 contains the amount of waste
26 --------------------------------------------------------------------- */
27
28 void
general_transport(Map_Point_Info * minfo,int * pol,int max_waste,int * waste_count)29 general_transport (Map_Point_Info *minfo, int *pol,
30 int max_waste, int *waste_count)
31 {
32 int tot, av, *base, xm1, xp1, ym1, yp1;
33
34 /* 30. Oct 1996:
35 * we'll use a loop with pointers here instead of doin' each
36 * operation by hand. this reduces code complexity and should
37 * lead to a higher cache hit ratio - theoretically
38 * (ThMO)
39 *
40 * 12. Dec 1996:
41 * as this is a heavy used routine, another speedup improvement is
42 * needed. we'll now use 1 pointer, which will be incremented and
43 * 1 .. 4 constant indices, which replaces the old pointer-pure
44 * version.
45 * advantages: elimination of unnecessary pointer increments.
46 * Note: this *only* works, if the related addresses use one and the
47 * same address space - which is naturally for 2-dimensional
48 * arrays.
49 * (ThMO)
50 */
51
52 base = &minfo->int_1;
53 switch (minfo->flags & 0x0F)
54 {
55 case 0:
56 return;
57
58 case 1: /* inlined t_av_l() -- (ThMO) */
59 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
60 do {
61 tot = *base + base[xm1];
62 av = tot / 2;
63 base[xm1] = av;
64 *base++ = av + tot % 2;
65 } while (base <= &minfo->int_7);
66 break;
67
68 case 2: /* inlined t_av_u() -- (ThMO) */
69 ym1 = &minfo[-1].int_1 - base;
70 do {
71 tot = *base + base[ym1];
72 av = tot / 2;
73 base[ym1] = av;
74 *base++ = av + tot % 2;
75 } while (base <= &minfo->int_7);
76 break;
77
78 case 3: /* inlined t_av_lu() -- (ThMO) */
79 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
80 ym1 = &minfo[-1].int_1 - base;
81 do {
82 tot = *base + base[xm1] + base[ym1];
83 av = tot / 3;
84 base[xm1] = base[ym1] = av;
85 *base++ = av + tot % 3;
86 } while (base <= &minfo->int_7);
87 break;
88
89 case 4: /* inlined t_av_r() -- (ThMO) */
90 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
91 do {
92 tot = *base + base[xp1];
93 av = tot / 2;
94 base[xp1] = av;
95 *base++ = av + tot % 2;
96 } while (base <= &minfo->int_7);
97 break;
98
99 case 5: /* inlined t_av_lr() -- (ThMO) */
100 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
101 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
102 do {
103 tot = *base + base[xm1] + base[xp1];
104 av = tot / 3;
105 base[xm1] = base[xp1] = av;
106 *base++ = av + tot % 3;
107 } while (base <= &minfo->int_7);
108 break;
109
110 case 6: /* inline t_av_ur() -- (ThMO) */
111 ym1 = &minfo[-1].int_1 - base;
112 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
113 do {
114 tot = *base + base[ym1] + base[xp1];
115 av = tot / 3;
116 base[ym1] = base[xp1] = av;
117 *base++ = av + tot % 3;
118 } while (base <= &minfo->int_7);
119 break;
120
121 case 7: /* inlined t_av_lur() -- (ThMO) */
122 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
123 ym1 = &minfo[-1].int_1 - base;
124 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
125 do {
126 tot = *base + base[xm1] + base[ym1] + base[xp1];
127 av = tot / 4;
128 base[xm1] = base[ym1] = base[xp1] = av;
129 *base++ = av + tot % 4;
130 } while (base <= &minfo->int_7);
131 break;
132
133 case 8: /* inlined t_av_d() -- (ThMO) */
134 yp1 = &minfo[1].int_1 - base;
135 do {
136 tot = *base + base[yp1];
137 av = tot / 2;
138 base[yp1] = av;
139 *base++ = av + tot % 2;
140 } while (base <= &minfo->int_7);
141 break;
142
143 case 9: /* inlined t_av_ld() -- (ThMO) */
144 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
145 yp1 = &minfo[1].int_1 - base;
146 do {
147 tot = *base + base[xm1] + base[yp1];
148 av = tot / 3;
149 base[xm1] = base[yp1] = av;
150 *base++ = av + tot % 3;
151 } while (base <= &minfo->int_7);
152 break;
153
154 case 10: /* inlined t_av_ud() -- (ThMO) */
155 ym1 = &minfo[-1].int_1 - base;
156 yp1 = &minfo[1].int_1 - base;
157 do {
158 tot = *base + base[ym1] + base[yp1];
159 av = tot / 3;
160 base[ym1] = base[yp1] = av;
161 *base++ = av + tot % 3;
162 } while (base <= &minfo->int_7);
163 break;
164
165 case 11: /* inlined t_av_lud() -- (ThMO) */
166 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
167 ym1 = &minfo[-1].int_1 - base;
168 yp1 = &minfo[1].int_1 - base;
169 do {
170 tot = *base + base[xm1] + base[ym1] + base[yp1];
171 av = tot / 4;
172 base[xm1] = base[ym1] = base[yp1] = av;
173 *base++ = av + tot % 4;
174 } while (base <= &minfo->int_7);
175 break;
176
177 case 12: /* inlined t_av_rd() -- (ThMO) */
178 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
179 yp1 = &minfo[1].int_1 - base;
180 do {
181 tot = *base + base[xp1] + base[yp1];
182 av = tot / 3;
183 base[xp1] = base[yp1] = av;
184 *base++ = av + tot % 3;
185 } while (base <= &minfo->int_7);
186 break;
187
188 case 13: /* inlined t_av_lrd() -- (ThMO) */
189 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
190 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
191 yp1 = &minfo[1].int_1 - base;
192 do {
193 tot = *base + base[xm1] + base[xp1] + base[yp1];
194 av = tot / 4;
195 base[xm1] = base[xp1] = base[yp1] = av;
196 *base++ = av + tot % 4;
197 } while (base <= &minfo->int_7);
198 break;
199
200 case 14: /* inlined t_av_urd() -- (ThMO) */
201 ym1 = &minfo[-1].int_1 - base;
202 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
203 yp1 = &minfo[1].int_1 - base;
204 do {
205 tot = *base + base[ym1] + base[xp1] + base[yp1];
206 av = tot / 4;
207 base[ym1] = base[xp1] = base[yp1] = av;
208 *base++ = av + tot % 4;
209 } while (base <= &minfo->int_7);
210 break;
211
212 case 15: /* inlined t_av_lurd() -- (ThMO) */
213 xm1 = &minfo[-WORLD_SIDE_LEN].int_1 - base;
214 ym1 = &minfo[-1].int_1 - base;
215 xp1 = &minfo[WORLD_SIDE_LEN].int_1 - base;
216 yp1 = &minfo[1].int_1 - base;
217 do {
218 tot = *base + base[xm1] + base[ym1] + base[xp1] + base[yp1];
219 av = tot / 5;
220 base[xm1] = base[ym1] = base[xp1] = base[yp1] = av;
221 *base++ = av + tot % 5;
222 } while (base <= &minfo->int_7);
223 break;
224 }
225 if (*--base >= max_waste) {
226 *base -= WASTE_BURN_ON_TRANSPORT;
227 ++*pol;
228 if (*waste_count > TRANSPORT_BURN_WASTE_COUNT) {
229 *waste_count = 0;
230 } else {
231 ++ * waste_count;
232 }
233 }
234 }
235
236