1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2
3 /*
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 // See doc/devel/planettopo for details.
20
21 #include "libs/gfxlib.h"
22 #include "libs/mathlib.h"
23 #include "planets.h"
24
25 void
DeltaTopography(COUNT num_iterations,SBYTE * DepthArray,RECT * pRect,SIZE depth_delta)26 DeltaTopography (COUNT num_iterations, SBYTE *DepthArray, RECT *pRect,
27 SIZE depth_delta)
28 {
29 SIZE width, height, delta_y;
30 struct
31 {
32 COORD x_top, x_bot;
33 SIZE x_incr, delta_x, error_term;
34 } LineDDA0, LineDDA1;
35
36 width = pRect->extent.width;
37 height = pRect->extent.height;
38 delta_y = (height - 1) << 1;
39 do
40 {
41 SIZE d;
42 COUNT h, w1, w2;
43 DWORD rand_val;
44 SBYTE *lpDst;
45
46 if ((RandomContext_Random (SysGenRNG) & 1) == 0)
47 depth_delta = -depth_delta;
48
49 rand_val = RandomContext_Random (SysGenRNG);
50 w1 = LOWORD (rand_val);
51 w2 = HIWORD (rand_val);
52
53 LineDDA0.x_top = LOBYTE (w1) % width;
54 LineDDA0.x_bot = HIBYTE (w1) % width;
55 LineDDA0.delta_x = (LineDDA0.x_bot - LineDDA0.x_top) << 1;
56 if (LineDDA0.delta_x >= 0)
57 LineDDA0.x_incr = 1;
58 else
59 {
60 LineDDA0.x_incr = -1;
61 LineDDA0.delta_x = -LineDDA0.delta_x;
62 }
63 if (LineDDA0.delta_x > delta_y)
64 LineDDA0.error_term = -(LineDDA0.delta_x >> 1);
65 else
66 LineDDA0.error_term = -(delta_y >> 1);
67
68 LineDDA1.x_top = (LOBYTE (w2) % (width - 1)) + LineDDA0.x_top + 1;
69 LineDDA1.x_bot = (HIBYTE (w2) % (width - 1)) + LineDDA0.x_bot + 1;
70 LineDDA1.delta_x = (LineDDA1.x_bot - LineDDA1.x_top) << 1;
71 if (LineDDA1.delta_x >= 0)
72 LineDDA1.x_incr = 1;
73 else
74 {
75 LineDDA1.x_incr = -1;
76 LineDDA1.delta_x = -LineDDA1.delta_x;
77 }
78 if (LineDDA1.delta_x > delta_y)
79 LineDDA1.error_term = -(LineDDA1.delta_x >> 1);
80 else
81 LineDDA1.error_term = -(delta_y >> 1);
82
83 lpDst = &DepthArray[LineDDA0.x_top];
84 h = height;
85 do
86 {
87 COUNT w;
88
89 w1 = LineDDA1.x_top - LineDDA0.x_top;
90 w2 = width - w1;
91
92 if ((int)(LineDDA0.x_top + w1) > (int)width)
93 w = width - LineDDA0.x_top;
94 else
95 {
96 w = w1;
97 LineDDA0.x_top += w1;
98 }
99 w1 -= w;
100 while (w--)
101 {
102 d = *lpDst + depth_delta;
103 if (d >= -128 && d <= 127)
104 *lpDst = (SBYTE)d;
105 ++lpDst;
106 }
107 if (w1 == 0)
108 {
109 if (LineDDA0.x_top == width)
110 {
111 LineDDA0.x_top = 0;
112 lpDst -= width;
113 }
114 }
115 else
116 {
117 LineDDA0.x_top = w1;
118 lpDst -= width;
119 do
120 {
121 d = *lpDst + depth_delta;
122 if (d >= -128 && d <= 127)
123 *lpDst = (SBYTE)d;
124 ++lpDst;
125 } while (--w1);
126 }
127
128 if ((int)(LineDDA0.x_top + w2) > (int)width)
129 w = width - LineDDA0.x_top;
130 else
131 {
132 w = w2;
133 LineDDA0.x_top += w2;
134 }
135 w2 -= w;
136 while (w--)
137 {
138 d = *lpDst - depth_delta;
139 if (d >= -128 && d <= 127)
140 *lpDst = (SBYTE)d;
141 ++lpDst;
142 }
143 if (w2 == 0)
144 {
145 if (LineDDA0.x_top == width)
146 {
147 LineDDA0.x_top = 0;
148 lpDst -= width;
149 }
150 }
151 else
152 {
153 LineDDA0.x_top = w2;
154 lpDst -= width;
155 do
156 {
157 d = *lpDst - depth_delta;
158 if (d >= -128 && d <= 127)
159 *lpDst = (SBYTE)d;
160 ++lpDst;
161 } while (--w2);
162 }
163
164 lpDst += pRect->extent.width;
165
166 if (delta_y >= LineDDA0.delta_x)
167 {
168 if ((LineDDA0.error_term += LineDDA0.delta_x) >= 0)
169 {
170 lpDst += LineDDA0.x_incr;
171 LineDDA0.x_top += LineDDA0.x_incr;
172 LineDDA0.error_term -= delta_y;
173 }
174 }
175 else
176 {
177 do
178 {
179 lpDst += LineDDA0.x_incr;
180 LineDDA0.x_top += LineDDA0.x_incr;
181 } while ((LineDDA0.error_term += delta_y) < 0);
182 LineDDA0.error_term -= LineDDA0.delta_x;
183 }
184
185 if (delta_y >= LineDDA1.delta_x)
186 {
187 if ((LineDDA1.error_term += LineDDA1.delta_x) >= 0)
188 {
189 LineDDA1.x_top += LineDDA1.x_incr;
190 LineDDA1.error_term -= delta_y;
191 }
192 }
193 else
194 {
195 do
196 {
197 LineDDA1.x_top += LineDDA1.x_incr;
198 } while ((LineDDA1.error_term += delta_y) < 0);
199 LineDDA1.error_term -= LineDDA1.delta_x;
200 }
201 } while (--h);
202 } while (--num_iterations);
203 }
204
205
206
207