1 /*
2 LOW_LEVEL_TEXTURES.C
3 
4 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
5 	and the "Aleph One" developers.
6 
7 	This program is free software; you can redistribute it and/or modify
8 	it under the terms of the GNU General Public License as published by
9 	the Free Software Foundation; either version 3 of the License, or
10 	(at your option) any later version.
11 
12 	This program is distributed in the hope that it will be useful,
13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 	GNU General Public License for more details.
16 
17 	This license is contained in the file "COPYING",
18 	which is included with this source code; it is available online at
19 	http://www.gnu.org/licenses/gpl.html
20 
21 Friday, August 19, 1994 2:05:54 PM
22 
23 Monday, February 27, 1995 11:40:47 PM  (Jason')
24 	rob suggests that the PPC might not write-allocate cache lines so we might be faster if we
25 	read from a location we�re about to write to.  he also suggested a rowbytes of 704 instead
26 	of 640 off-screen for better cache performance.
27 
28 Jan 30, 2000 (Loren Petrich):
29 	Added some typecasts
30 	Removed some "static" declarations that conflict with "extern"
31 */
32 
33 #include "cseries.h"
34 #include "preferences.h"
35 #include "textures.h"
36 #include "scottish_textures.h"
37 
38 /* ---------- global state */
39 
texture_random_seed()40 inline uint16 & texture_random_seed()
41 {
42 	static uint16 seed = 6906;
43 	return seed;
44 }
45 
46 /* ---------- texture horizontal polygon */
47 
48 #define HORIZONTAL_WIDTH_SHIFT 7 /* 128 (8 for 256) */
49 #define HORIZONTAL_HEIGHT_SHIFT 7 /* 128 */
50 #define HORIZONTAL_FREE_BITS (32-TRIG_SHIFT-WORLD_FRACTIONAL_BITS)
51 #define HORIZONTAL_WIDTH_DOWNSHIFT (32-HORIZONTAL_WIDTH_SHIFT)
52 #define HORIZONTAL_HEIGHT_DOWNSHIFT (32-HORIZONTAL_HEIGHT_SHIFT)
53 
54 struct _horizontal_polygon_line_header
55 {
56 	int32 y_downshift;
57 };
58 
59 struct _horizontal_polygon_line_data
60 {
61 	uint32 source_x, source_y;
62 	uint32 source_dx, source_dy;
63 
64 	void *shading_table;
65 };
66 
67 /* ---------- texture vertical polygon */
68 
69 #define VERTICAL_TEXTURE_WIDTH 128
70 #define VERTICAL_TEXTURE_WIDTH_BITS 7
71 #define VERTICAL_TEXTURE_WIDTH_FRACTIONAL_BITS (FIXED_FRACTIONAL_BITS-VERTICAL_TEXTURE_WIDTH_BITS)
72 #define VERTICAL_TEXTURE_ONE (1<<VERTICAL_TEXTURE_WIDTH_FRACTIONAL_BITS)
73 #define VERTICAL_TEXTURE_FREE_BITS FIXED_FRACTIONAL_BITS
74 #define VERTICAL_TEXTURE_DOWNSHIFT (32-VERTICAL_TEXTURE_WIDTH_BITS)
75 
76 struct _vertical_polygon_data
77 {
78 	int16 downshift;
79 	int16 x0;
80 	int16 width;
81 
82 	int16 pad;
83 };
84 
85 struct _vertical_polygon_line_data
86 {
87 	void *shading_table;
88 	pixel8 *texture;
89 	int32 texture_y, texture_dy;
90 };
91 
92 /* ---------- code */
93 
94 // Find the next lower power of 2, and return the exponent
NextLowerExponent(int n)95 inline int NextLowerExponent(int n)
96 {
97 	int xp = 0;
98 	while(n > 1) {n >>= 1; xp++;}
99 	return xp;
100 }
101 
102 template <typename T>
average(T fg,T bg)103 inline T average(T fg, T bg)
104 {
105 	return fg;
106 }
107 
108 template <>
average(pixel32 fg,pixel32 bg)109 inline pixel32 average(pixel32 fg, pixel32 bg)
110 {
111 	// badly assume that the pixel format is ARGB
112 	return ( ((((fg) ^ (bg)) & 0xfffefefeL) >> 1) + ((fg) & (bg)) );
113 }
114 
115 template <>
average(pixel16 fg,pixel16 bg)116 inline pixel16 average(pixel16 fg, pixel16 bg)
117 {
118 	// badly assume that the pixel format is 565
119 	return ( ((((fg) ^ (bg)) & 0xf7deU) >> 1) + ((fg) & (bg)) );
120 }
121 
122 template <typename T>
alpha_blend(T fg,T bg,pixel8 alpha,pixel32 rmask,pixel32 bmask,pixel32 gmask)123 inline T alpha_blend(T fg, T bg, pixel8 alpha, pixel32 rmask, pixel32 bmask, pixel32 gmask)
124 {
125 	return (
126 		(rmask & ((bg & rmask) + ((int)(1LL*((int)(fg & rmask) - (int)(bg & rmask)) * alpha) >> 8))) |
127 		(gmask & ((bg & gmask) + ((int)(1LL*((int)(fg & gmask) - (int)(bg & gmask)) * alpha) >> 8))) |
128 		(bmask & ((bg & bmask) + ((int)(1LL*((int)(fg & bmask) - (int)(bg & bmask)) * alpha) >> 8)))
129 		);
130 }
131 
132 template <typename T, int sw_alpha_blend, bool check_transparency>
write_pixel(T * dst,pixel8 pixel,T * shading_table,uint8 * opacity_table,pixel32 rmask,pixel32 gmask,pixel32 bmask)133 void inline write_pixel(T *dst, pixel8 pixel, T *shading_table, uint8 *opacity_table, pixel32 rmask, pixel32 gmask, pixel32 bmask)
134 {
135 	if (!check_transparency || pixel != 0)
136 	{
137 		if (sw_alpha_blend == _sw_alpha_off)
138 		{
139 			*dst = shading_table[pixel];
140 		}
141 		else if (sw_alpha_blend == _sw_alpha_fast)
142 		{
143 			*dst = average(shading_table[pixel], *dst);
144 		}
145 		else if (sw_alpha_blend == _sw_alpha_nice)
146 		{
147 			*dst = alpha_blend(shading_table[pixel], *dst, opacity_table[pixel], rmask, gmask, bmask);
148 		}
149 	}
150 }
151 
152 template <typename T, int sw_alpha_blend>
153 void texture_horizontal_polygon_lines
154 (
155 	struct bitmap_definition *texture,
156 	struct bitmap_definition *screen,
157 	struct view_data *view,
158 	struct _horizontal_polygon_line_data *data,
159 	short y0,
160 	short *x0_table,
161 	short *x1_table,
162 	short line_count,
163 	uint8 *opacity_table = 0
164 )
165 {
166 	(void) (view);
167 
168 	pixel32 rmask = 0;
169 	pixel32 gmask = 0;
170 	pixel32 bmask = 0;
171 
172 	if (sw_alpha_blend == _sw_alpha_nice)
173 	{
174 		extern SDL_Surface *world_pixels;
175 		SDL_PixelFormat *fmt = world_pixels->format;
176 
177 		rmask = fmt->Rmask;
178 		gmask = fmt->Gmask;
179 		bmask = fmt->Bmask;
180 	}
181 
182 	while ((line_count-= 1)>=0)
183 	{
184 		short x0= *x0_table++, x1= *x1_table++;
185 
186 		T *shading_table= (T *)data->shading_table;
187 		T *write= (T *) screen->row_addresses[y0] + x0;
188 		pixel8 *base_address= texture->row_addresses[0];
189 		uint32 source_x= data->source_x;
190 		uint32 source_y= data->source_y;
191 		uint32 source_dx= data->source_dx;
192 		uint32 source_dy= data->source_dy;
193 		short count= x1-x0;
194 
195 		while ((count-= 1)>=0)
196 		{
197 			write_pixel<T, sw_alpha_blend, false>(write++, base_address[((source_y>>(HORIZONTAL_HEIGHT_DOWNSHIFT-7))&(0x7f<<7))+(source_x>>HORIZONTAL_WIDTH_DOWNSHIFT)], shading_table, opacity_table, rmask, gmask, bmask);
198 
199 			source_x+= source_dx, source_y+= source_dy;
200 		}
201 
202 		data+= 1;
203 		y0+= 1;
204 	}
205 }
206 
207 #define LANDSCAPE_WIDTH_BITS 9
208 #define LANDSCAPE_TEXTURE_WIDTH_DOWNSHIFT (32-LANDSCAPE_WIDTH_BITS)
209 template <typename T>
landscape_horizontal_polygon_lines(struct bitmap_definition * texture,struct bitmap_definition * screen,struct view_data * view,struct _horizontal_polygon_line_data * data,short y0,short * x0_table,short * x1_table,short line_count)210 void landscape_horizontal_polygon_lines(
211 	struct bitmap_definition *texture,
212 	struct bitmap_definition *screen,
213 	struct view_data *view,
214 	struct _horizontal_polygon_line_data *data,
215 	short y0,
216 	short *x0_table,
217 	short *x1_table,
218 	short line_count)
219 {
220 	short landscape_texture_width_downshift= 32 - NextLowerExponent(texture->height);
221 
222 	(void) (view);
223 
224 	while ((line_count-= 1)>=0)
225 	{
226 		short x0= *x0_table++, x1= *x1_table++;
227 
228 		T *shading_table= (T *)data->shading_table;
229 		T *write= (T *)screen->row_addresses[y0] + x0;
230 		pixel8 *read= texture->row_addresses[data->source_y];
231 		uint32 source_x= data->source_x;
232 		uint32 source_dx= data->source_dx;
233 		short count= x1-x0;
234 
235 		while ((count-= 1)>=0)
236 		{
237 			*write++= shading_table[read[source_x>>landscape_texture_width_downshift]];
238 			source_x+= source_dx;
239 		}
240 
241 		data+= 1;
242 		y0+= 1;
243 	}
244 }
245 
246 template <typename T, bool check_transparent>
copy_check_transparent(T * dst,pixel8 read,T * shading_table)247 void inline copy_check_transparent(T *dst, pixel8 read, T *shading_table)
248 {
249 	if (!check_transparent || read != 0)
250 	{
251 		*dst = shading_table[read];
252 	}
253 }
254 
255 
256 template <typename T, int sw_alpha_blend, bool check_transparent>
257 void texture_vertical_polygon_lines(
258 	struct bitmap_definition *screen,
259 	struct view_data *view,
260 	struct _vertical_polygon_data *data,
261 	short *y0_table,
262 	short *y1_table,
263 	uint8 *opacity_table = 0)
264 {
265 	struct _vertical_polygon_line_data *line= (struct _vertical_polygon_line_data *) (data+1);
266 	int bytes_per_row= screen->bytes_per_row;
267 	int downshift= data->downshift;
268 	int line_count= data->width;
269 	bool aborted= false;
270 	int x= data->x0;
271 	int count;
272 
273 	(void) (view);
274 
275 	pixel32 rmask = 0;
276 	pixel32 gmask = 0;
277 	pixel32 bmask = 0;
278 
279 	if (sw_alpha_blend == _sw_alpha_nice) {
280 		extern SDL_Surface *world_pixels;
281 		SDL_PixelFormat *fmt = world_pixels->format;
282 
283 		rmask = fmt->Rmask;
284 		gmask = fmt->Gmask;
285 		bmask = fmt->Bmask;
286 	}
287 
288 	while (line_count>0)
289 	{
290 		if (line_count<4 || (x&3) || aborted)
291 		{
292 			int y0= *y0_table++, y1= *y1_table++;
293 			uint32 texture_y= line->texture_y;
294 			uint32 texture_dy= line->texture_dy;
295 			T *write, *shading_table;
296 			pixel8 *read;
297 
298 			shading_table= (T *)line->shading_table;
299 			read= line->texture;
300 			write= (T *)screen->row_addresses[y0] + x;
301 
302 			for (count= y1-y0; count>0; --count)
303 			{
304 				write_pixel<T, sw_alpha_blend, check_transparent>(write, read[texture_y>>downshift], shading_table, opacity_table, rmask, gmask, bmask);
305 
306 				write = (T *)((byte *)write + bytes_per_row);
307 				texture_y+= texture_dy;
308 			}
309 
310 			x+= 1;
311 			line+= 1;
312 			line_count-= 1;
313 
314 			aborted= false;
315 		}
316 		else
317 		{
318 			uint32 texture_y0= line[0].texture_y, texture_dy0= line[0].texture_dy;
319 			pixel8 *read0= line[0].texture;
320 			T *shading_table0= (T *)line[0].shading_table;
321 
322 			uint32 texture_y1= line[1].texture_y, texture_dy1= line[1].texture_dy;
323 			pixel8 *read1= line[1].texture;
324 			T *shading_table1= (T *)line[1].shading_table;
325 
326 			uint32 texture_y2= line[2].texture_y, texture_dy2= line[2].texture_dy;
327 			pixel8 *read2= line[2].texture;
328 			T *shading_table2= (T *)line[2].shading_table;
329 
330 			uint32 texture_y3= line[3].texture_y, texture_dy3= line[3].texture_dy;
331 			pixel8 *read3= line[3].texture;
332 			T *shading_table3= (T *)line[3].shading_table;
333 
334 			T *write;
335 
336 			int ymax;
337 
338 			/* sync */
339 			{
340 				int y0= y0_table[0], y1= y0_table[1], y2= y0_table[2], y3= y0_table[3];
341 				T *temp_write;
342 
343 				ymax= MAX(y0, y1), ymax= MAX(ymax, y2), ymax= MAX(ymax, y3);
344 				write= (T *)screen->row_addresses[ymax] + x;
345 
346 				{
347 					int ymin= MIN(y1_table[0], y1_table[1]);
348 
349 					ymin= MIN(ymin, y1_table[2]);
350 					ymin= MIN(ymin, y1_table[3]);
351 
352 					if (ymin<=ymax)
353 					{
354 						aborted= true;
355 						continue;
356 					}
357 				}
358 
359 				for (count= ymax-y0, temp_write= (T *)screen->row_addresses[y0] + x; count>0; --count)
360 				{
361 					copy_check_transparent<T, check_transparent>(temp_write, read0[texture_y0>>downshift], shading_table0);
362 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
363 					texture_y0+= texture_dy0;
364 				}
365 
366 				for (count= ymax-y1, temp_write= (T *)screen->row_addresses[y1] + x; count>0; --count)
367 				{
368 					copy_check_transparent<T, check_transparent>(temp_write + 1, read1[texture_y1>>downshift], shading_table1);
369 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
370 					texture_y1+= texture_dy1;
371 				}
372 
373 				for (count= ymax-y2, temp_write= (T *)screen->row_addresses[y2] + x; count>0; --count)
374 				{
375 					copy_check_transparent<T, check_transparent>(temp_write + 2, read2[texture_y2>>downshift], shading_table2);
376 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
377 					texture_y2+= texture_dy2;
378 				}
379 
380 				for (count= ymax-y3, temp_write= (T *)screen->row_addresses[y3] + x; count>0; --count)
381 				{
382 					copy_check_transparent<T, check_transparent>(temp_write + 3, read3[texture_y3>>downshift], shading_table3);
383 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
384 					texture_y3+= texture_dy3;
385 				}
386 			}
387 
388 			/* parallel map (x4) */
389 			{
390 				int dy0= y1_table[0] - ymax;
391 				int dy1= y1_table[1] - ymax;
392 				int dy2= y1_table[2] - ymax;
393 				int dy3= y1_table[3] - ymax;
394 
395 				count= MIN(dy0, dy1), count= MIN(count, dy2), count= MIN(count, dy3);
396 				ymax+= count;
397 
398 				for (; count>0; --count)
399 				{
400 					write_pixel<T, sw_alpha_blend, check_transparent>(write, read0[texture_y0>>downshift], shading_table0, opacity_table, rmask, gmask, bmask);
401 					texture_y0+= texture_dy0;
402 
403 					write_pixel<T, sw_alpha_blend, check_transparent>(write+1, read1[texture_y1>>downshift], shading_table1, opacity_table, rmask, gmask, bmask);
404 					texture_y1+= texture_dy1;
405 
406 					write_pixel<T, sw_alpha_blend, check_transparent>(write+2, read2[texture_y2>>downshift], shading_table2, opacity_table, rmask, gmask, bmask);
407 					texture_y2+= texture_dy2;
408 
409 					write_pixel<T, sw_alpha_blend, check_transparent>(write+3, read3[texture_y3>>downshift], shading_table3, opacity_table, rmask, gmask, bmask);
410 					texture_y3+= texture_dy3;
411 
412 					write = (T *)((byte *)write + bytes_per_row);
413 				}
414 			}
415 
416 			/* desync */
417 			{
418 				T *temp_write;
419 
420 				for (count= y1_table[0] - ymax, temp_write= write; count>0; --count)
421 				{
422 					copy_check_transparent<T, check_transparent>(temp_write, read0[texture_y0>>downshift], shading_table0);
423 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
424 					texture_y0+= texture_dy0;
425 				}
426 
427 				for (count= y1_table[1] - ymax, temp_write= write; count>0; --count)
428 				{
429 					copy_check_transparent<T, check_transparent>(temp_write + 1, read1[texture_y1>>downshift], shading_table1);
430 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
431 					texture_y1+= texture_dy1;
432 				}
433 
434 				for (count= y1_table[2] - ymax, temp_write= write; count>0; --count)
435 				{
436 					copy_check_transparent<T, check_transparent>(temp_write + 2, read2[texture_y2>>downshift], shading_table2);
437 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
438 					texture_y2+= texture_dy2;
439 				}
440 
441 				for (count= y1_table[3] - ymax, temp_write= write; count>0; --count)
442 				{
443 					copy_check_transparent<T, check_transparent>(temp_write + 3, read3[texture_y3>>downshift], shading_table3);
444 					temp_write = (T *)((byte *)temp_write + bytes_per_row);
445 					texture_y3+= texture_dy3;
446 				}
447 			}
448 
449 			y0_table+= 4, y1_table+= 4;
450 			line_count-= 4;
451 			line+= 4;
452 			x+= 4;
453 		}
454 	}
455 }
456 
457 template <typename T>
tint_tables_pointer(_vertical_polygon_line_data * line,short tint_table_index)458 inline void *tint_tables_pointer(_vertical_polygon_line_data *line, short tint_table_index)
459 {
460 	return 0;
461 }
462 
463 template <>
464 inline void *tint_tables_pointer<pixel8>(_vertical_polygon_line_data *line, short tint_table_index)
465 {
466 	return (void *) ((pixel8 *) line->shading_table + tint_table_index * sizeof(struct tint_table8));
467 }
468 
469 template <>
470 inline void *tint_tables_pointer<pixel16>(_vertical_polygon_line_data *line, short tint_table_index)
471 {
472 	return (void *) ((struct tint_table16 *) line->shading_table + (tint_table_index<<1));
473 }
474 
475 template <>
476 inline void *tint_tables_pointer<pixel32>(_vertical_polygon_line_data *line, short tint_table_index)
477 {
478 	return (void *) ((struct tint_table32 *) line->shading_table + (tint_table_index<<3));
479 }
480 
481 template <typename T>
get_pixel_tint(T,void *,SDL_PixelFormat *)482 inline T get_pixel_tint(T, void *, SDL_PixelFormat *)
483 {
484 	return 0;
485 }
486 
487 template <>
get_pixel_tint(pixel8 pixel,void * tint_tables,SDL_PixelFormat *)488 inline pixel8 get_pixel_tint(pixel8 pixel, void *tint_tables, SDL_PixelFormat *)
489 {
490 	return ((pixel8 *) tint_tables)[pixel];
491 }
492 
493 template<>
get_pixel_tint(pixel16 pixel,void * tint_tables_pv,SDL_PixelFormat * fmt)494 inline pixel16 get_pixel_tint(pixel16 pixel, void *tint_tables_pv, SDL_PixelFormat *fmt)
495 {
496 	tint_table16 *tint_tables = (tint_table16 *) tint_tables_pv;
497 	uint8 r = (((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss);
498 	uint8 g = (((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss);
499 	uint8 b = (((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss);
500 
501 	return tint_tables->red[r >> 3] | tint_tables->green[g >> 3] | tint_tables->blue[b >> 3];
502 }
503 
504 template <>
get_pixel_tint(pixel32 pixel,void * tint_tables_pv,SDL_PixelFormat * fmt)505 inline pixel32 get_pixel_tint(pixel32 pixel, void *tint_tables_pv, SDL_PixelFormat *fmt)
506 {
507 	tint_table32 *tint_tables = (tint_table32 *) tint_tables_pv;
508 	uint8 r = (((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss);
509 	uint8 g = (((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss);
510 	uint8 b = (((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss);
511 
512 	return tint_tables->red[r] | tint_tables->green[g] | tint_tables->blue[b];
513 }
514 
515 template <typename T>
tint_vertical_polygon_lines(struct bitmap_definition * screen,struct view_data * view,struct _vertical_polygon_data * data,short * y0_table,short * y1_table,uint16 transfer_data)516 void tint_vertical_polygon_lines(
517 	struct bitmap_definition *screen,
518 	struct view_data *view,
519 	struct _vertical_polygon_data *data,
520 	short *y0_table,
521 	short *y1_table,
522 	uint16 transfer_data)
523 {
524 	short tint_table_index= transfer_data&0xff;
525 	struct _vertical_polygon_line_data *line= (struct _vertical_polygon_line_data *) (data+1);
526 	short bytes_per_row= screen->bytes_per_row;
527 	int line_count= data->width;
528 	int x= data->x0;
529 
530 	void *tint_tables = tint_tables_pointer<T>(line, tint_table_index);
531 
532 	(void) (view);
533 
534 	extern SDL_Surface *world_pixels;
535 
536 	fc_assert(tint_table_index>=0 && tint_table_index<number_of_shading_tables);
537 
538 	while ((line_count-= 1)>=0)
539 	{
540 		short y0= *y0_table++, y1= *y1_table++;
541 		T *write= (T *) screen->row_addresses[y0] + x;
542 		pixel8 *read= line->texture;
543 		_fixed texture_y= line->texture_y, texture_dy= line->texture_dy;
544 		short count= y1-y0;
545 
546 		while ((count-=1)>=0)
547 		{
548 			if (read[FIXED_INTEGERAL_PART(texture_y)])
549 			{
550 				*write = get_pixel_tint<T>(*write, tint_tables, world_pixels->format);
551 
552 			}
553 
554 			write = (T *)((byte *)write + bytes_per_row);
555 			texture_y+= texture_dy;
556 		}
557 
558 		line+= 1;
559 		x+= 1;
560 	}
561 }
562 
563 
564 template <typename T>
randomize_vertical_polygon_lines_write(uint16 seed)565 inline T randomize_vertical_polygon_lines_write(uint16 seed)
566 {
567 	return static_cast<T>(seed);
568 }
569 
570 template <>
571 inline pixel32 randomize_vertical_polygon_lines_write<pixel32>(uint16 seed)
572 {
573 	return (pixel32)seed^(((pixel32)seed)<<8);
574 }
575 
576 template <typename T, bool check_transparent>
randomize_vertical_polygon_lines(struct bitmap_definition * screen,struct view_data * view,struct _vertical_polygon_data * data,short * y0_table,short * y1_table,uint16 transfer_data)577 void randomize_vertical_polygon_lines(
578 	struct bitmap_definition *screen,
579 	struct view_data *view,
580 	struct _vertical_polygon_data *data,
581 	short *y0_table,
582 	short *y1_table,
583 	uint16 transfer_data)
584 {
585 	struct _vertical_polygon_line_data *line= (struct _vertical_polygon_line_data *) (data+1);
586 	short bytes_per_row= screen->bytes_per_row;
587 	int line_count= data->width;
588 	int x= data->x0;
589 	uint16 seed= texture_random_seed();
590 	uint16 drop_less_than= transfer_data;
591 
592 	(void) (view);
593 
594 	while ((line_count-= 1)>=0)
595 	{
596 		short y0= *y0_table++, y1= *y1_table++;
597 		T *write= (T *) screen->row_addresses[y0] + x;
598 		pixel8 *read= line->texture;
599 		_fixed texture_y= line->texture_y, texture_dy= line->texture_dy;
600 		short count= y1-y0;
601 
602 		while ((count-=1)>=0)
603 		{
604 			if (!check_transparent || read[texture_y>>(data->downshift)])
605 			{
606 				if (seed >= drop_less_than) *write = randomize_vertical_polygon_lines_write<T>(seed);
607 				if (seed&1) seed= (seed>>1)^0xb400; else seed= seed>>1;
608 			}
609 
610 			write = (T *)((byte *)write + bytes_per_row);
611 			texture_y+= texture_dy;
612 		}
613 
614 		line+= 1;
615 		x+= 1;
616 	}
617 
618 	texture_random_seed() = seed;
619 }
620