Cube  Diff

Differences From Artifact [2b192347af]:

To Artifact [49154c0e62]:


60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74







-
+







			int stepb = fast_f2nat(b / (float)steps);
			g /= lightscale;
			stepg /= lightscale;
			b /= lightscale;
			stepb /= lightscale;
			loopi(steps)
			{
				sqr *s = S(x >> PRECBITS, y >> PRECBITS);
				struct sqr *s = S(x >> PRECBITS, y >> PRECBITS);
				int tl = (l >> PRECBITS) + s->r;
				s->r = tl > 255 ? 255 : tl;
				tl = (g >> PRECBITS) + s->g;
				s->g = tl > 255 ? 255 : tl;
				tl = (b >> PRECBITS) + s->b;
				s->b = tl > 255 ? 255 : tl;
				if (SOLID(s))
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+















-
+







			y += stepy * dimness;

			if (OUTBORD(x >> PRECBITS, y >> PRECBITS))
				return;

			loopi(steps)
			{
				sqr *s = S(x >> PRECBITS, y >> PRECBITS);
				struct sqr *s = S(x >> PRECBITS, y >> PRECBITS);
				int tl = (l >> PRECBITS) + s->r;
				s->r = s->g = s->b = tl > 255 ? 255 : tl;
				if (SOLID(s))
					return;
				x += stepx;
				y += stepy;
				l -= stepl;
				stepl -= 25;
			}
		}
	} else // the old (white) light code, here for the few people with old
	       // video cards that don't support overbright
	{
		loopi(steps)
		{
			sqr *s = S(x >> PRECBITS, y >> PRECBITS);
			struct sqr *s = S(x >> PRECBITS, y >> PRECBITS);
			int light = l >> PRECBITS;
			if (light > s->r)
				s->r = s->g = s->b = (uchar)light;
			if (SOLID(s))
				return;
			x += stepx;
			y += stepy;
143
144
145
146
147
148
149

150
151

152
153
154

155
156

157
158
159
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185


186
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219


220
221
222
223
224
225
226
227
228
229
230
231
232


233
234
235

236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252


253
254
255


256
257

258
259
260
261
262
263
264
265

266
267

268
269
270
271
272
143
144
145
146
147
148
149
150
151

152

153

154
155

156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183


184
185
186
187
188
189
190
191
192
193
194
195
196

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217


218
219
220
221
222
223
224
225
226
227
228
229
230


231
232
233
234

235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250


251
252
253


254
255
256

257
258
259
260
261
262
263
264

265
266

267
268
269
270
271
272







+

-
+
-

-
+

-
+











-
+







-
+







-
-
+
+











-
+




















-
-
+
+











-
-
+
+


-
+










-
+




-
-
+
+

-
-
+
+

-
+







-
+

-
+





		lightray((float)sx, sy2, l);
		lightray((float)ex, sy2, l);
	}

	rndtime();
}

// median filter, smooths out random noise in light and makes it more mipable
void
postlightarea(block &a) // median filter, smooths out random noise in light and
postlightarea(const struct block *a)
                        // makes it more mipable
{
	loop(x, a.xs) loop(y, a.ys) // assumes area not on edge of world
	loop(x, a->xs) loop(y, a->ys) // assumes area not on edge of world
	{
		sqr *s = S(x + a.x, y + a.y);
		struct sqr *s = S(x + a->x, y + a->y);
#define median(m)                                                            \
	s->m =                                                               \
	    (s->m * 2 + SW(s, 1, 0)->m * 2 + SW(s, 0, 1)->m * 2 +            \
	        SW(s, -1, 0)->m * 2 + SW(s, 0, -1)->m * 2 + SW(s, 1, 1)->m + \
	        SW(s, 1, -1)->m + SW(s, -1, 1)->m + SW(s, -1, -1)->m) /      \
	    14; // median is 4/2/1 instead
		median(r);
		median(g);
		median(b);
	}

	remip(&a, 0);
	remip(a, 0);
}

void
calclight()
{
	loop(x, ssize) loop(y, ssize)
	{
		sqr *s = S(x, y);
		struct sqr *s = S(x, y);
		s->r = s->g = s->b = 10;
	}

	for (Entity *e in ents)
		if (e.type == LIGHT)
			calclightsource(e);

	block b = { 1, 1, ssize - 2, ssize - 2 };
	postlightarea(b);
	struct block b = { 1, 1, ssize - 2, ssize - 2 };
	postlightarea(&b);
	setvar(@"fullbright", 0);
}

VARP(dynlight, 0, 16, 32);

static OFMutableData *dlights;

void
cleardlights()
{
	while (dlights.count > 0) {
		block *backup = *(block **)[dlights lastItem];
		struct block *backup = *(struct block **)[dlights lastItem];
		[dlights removeLastItem];
		blockpaste(backup);
		OFFreeMemory(backup);
	}
}

void
dodynlight(const OFVector3D *vold, const OFVector3D *v, int reach, int strength,
    DynamicEntity *owner)
{
	if (!reach)
		reach = dynlight;
	if (owner.monsterstate)
		reach = reach / 2;
	if (!reach)
		return;
	if (v->x < 0 || v->y < 0 || v->x > ssize || v->y > ssize)
		return;

	int creach = reach + 16; // dependant on lightray random offsets!
	block b = { (int)v->x - creach, (int)v->y - creach, creach * 2 + 1,
		creach * 2 + 1 };
	struct block b = { (int)v->x - creach, (int)v->y - creach,
		creach * 2 + 1, creach * 2 + 1 };

	if (b.x < 1)
		b.x = 1;
	if (b.y < 1)
		b.y = 1;
	if (b.xs + b.x > ssize - 2)
		b.xs = ssize - 2 - b.x;
	if (b.ys + b.y > ssize - 2)
		b.ys = ssize - 2 - b.y;

	if (dlights == nil)
		dlights =
		    [[OFMutableData alloc] initWithItemSize:sizeof(block *)];
		dlights = [[OFMutableData alloc]
		    initWithItemSize:sizeof(struct block *)];

	// backup area before rendering in dynlight
	block *copy = blockcopy(&b);
	struct block *copy = blockcopy(&b);
	[dlights addItem:&copy];

	PersistentEntity *l = [Entity entity];
	l.x = v->x;
	l.y = v->y;
	l.z = v->z;
	l.attr1 = reach;
	l.type = LIGHT;
	l.attr2 = strength;
	calclightsource(l);
	postlightarea(b);
	postlightarea(&b);
}

// utility functions also used by editing code

block *
blockcopy(const block *s)
struct block *
blockcopy(const struct block *s)
{
	block *b = (block *)OFAllocZeroedMemory(
	    1, sizeof(block) + s->xs * s->ys * sizeof(sqr));
	struct block *b = OFAllocZeroedMemory(
	    1, sizeof(struct block) + s->xs * s->ys * sizeof(struct sqr));
	*b = *s;
	sqr *q = (sqr *)(b + 1);
	struct sqr *q = (struct sqr *)(b + 1);
	for (int x = s->x; x < s->xs + s->x; x++)
		for (int y = s->y; y < s->ys + s->y; y++)
			*q++ = *S(x, y);
	return b;
}

void
blockpaste(const block *b)
blockpaste(const struct block *b)
{
	sqr *q = (sqr *)(b + 1);
	struct sqr *q = (struct sqr *)(b + 1);
	for (int x = b->x; x < b->xs + b->x; x++)
		for (int y = b->y; y < b->ys + b->y; y++)
			*S(x, y) = *q++;
	remipmore(b, 0);
}