1 /*
2  * OpenBOR - http://www.LavaLit.com
3  * -----------------------------------------------------------------------
4  * All rights reserved, see LICENSE in OpenBOR root for details.
5  *
6  * Copyright (c) 2004 - 2011 OpenBOR Team
7  */
8 
9 ///////////////////////////////////////////////////////////////////////////
10 //         This file defines some commmon methods used by the gamelib
11 ////////////////////////////////////////////////////////////////////////////
12 #include <assert.h>
13 #include "globals.h"
14 #include "types.h"
15 
16 static transpixelfunc pfp;
17 static unsigned int fillcolor;
18 static blend16fp pfp16;
19 static blend32fp pfp32;
20 static unsigned char* table;
21 static int transbg;
22 int trans_sw, trans_sh, trans_dw, trans_dh;
23 static void (*drawfp)(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy);
24 
25 static s_screen* handle_dest;
26 
27 static int y_dest;
28 static int x_dest;
29 static int span_dest;
30 
31 static unsigned char* ptr_dest;
32 static unsigned char* cur_dest;
33 
34 static gfx_entry* handle_src;
35 
36 static int y_src;
37 static int x_src;
38 static int span_src;
39 
40 static unsigned char* ptr_src;
41 static unsigned char* cur_src;
42 static unsigned char* cur_spr; // for sprite only
43 
44 static int spf, dpf; //pixelformat
45 
46 
47 /*transpixelfunc, 8bit*/
remapcolor(unsigned char * table,unsigned char color,unsigned char unused)48 static unsigned char remapcolor(unsigned char* table, unsigned char color, unsigned char unused)
49 {
50 	return table[color];
51 }
52 
blendcolor(unsigned char * table,unsigned char color1,unsigned char color2)53 static unsigned char blendcolor(unsigned char* table, unsigned char color1, unsigned char color2)
54 {
55 	if(!table) return color1;
56 	return table[color1<<8|color2];
57 }
58 
blendfillcolor(unsigned char * table,unsigned char unused,unsigned char color)59 static unsigned char blendfillcolor(unsigned char* table, unsigned char unused, unsigned char color)
60 {
61 	if(!table) return fillcolor;
62 	return table[fillcolor<<8|color];
63 }
64 
65 
66 /**
67 
68  draw a pixel from source gfx surface to destination screen
69  complex
70 
71 */
72 
draw_pixel_dummy(s_screen * dest,gfx_entry * src,int dx,int dy,int sx,int sy)73 inline void draw_pixel_dummy(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy)
74 {
75 	int pb = pixelbytes[(int)dest->pixelformat];
76 	unsigned char* pd = ((unsigned char*)(dest->data)) + (dx + dy*dest->width)*pb;
77 	memset(pd, 0, pb);
78 }
79 
draw_pixel_screen(s_screen * dest,gfx_entry * src,int dx,int dy,int sx,int sy)80 inline void draw_pixel_screen(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy)
81 {
82 	unsigned char *ptrd8, *ptrs8, ps8;
83 	unsigned short *ptrd16, *ptrs16, pd16, ps16;
84 	unsigned int *ptrd32, *ptrs32, pd32, ps32;
85 	switch(dest->pixelformat)
86 	{
87 		case PIXEL_8:
88 			ps8 = *(((unsigned char*)src->screen->data) + sx + sy * src->screen->width);
89 			if(transbg && !ps8) return;
90 			else if(fillcolor) ps8 = fillcolor;
91 			ptrd8 = ((unsigned char*)dest->data) + dx + dy * dest->width;
92 			*ptrd8 =pfp?pfp(table, ps8, *ptrd8):ps8;
93 			break;
94 		case PIXEL_16:
95 			ptrd16 = ((unsigned short*)dest->data) + dx + dy * dest->width;
96 			pd16 = *ptrd16;
97 			switch(src->screen->pixelformat)
98 			{
99 			case PIXEL_16:
100 				ptrs16 = ((unsigned short*)src->screen->data) + sx + sy * src->screen->width;
101 				ps16 = *ptrs16;
102 				if(transbg && !ps16) return;
103 				break;
104 			case PIXEL_x8:
105 				ptrs8 = ((unsigned char*)src->screen->data) + sx + sy * src->screen->width;
106 				if(transbg && !*ptrs8) return;
107 				ps16 = table?((unsigned short*)table)[*ptrs8]:((unsigned short*)src->screen->palette)[*ptrs8];
108 				break;
109 			default:
110 				return;
111 			}
112 			if(fillcolor) ps16 = fillcolor;
113 			if(!pfp16) *ptrd16 = ps16;
114 			else       *ptrd16 = pfp16(ps16, pd16);
115 			break;
116 		case PIXEL_32:
117 			ptrd32 = ((unsigned int*)dest->data) + dx + dy * dest->width;
118 			pd32 = *ptrd32;
119 			switch(src->screen->pixelformat)
120 			{
121 			case PIXEL_32:
122 				ptrs32 = ((unsigned int*)src->screen->data) + sx + sy * src->screen->width;
123 				ps32 = *ptrs32;
124 				if(transbg && !ps32) return;
125 				break;
126 			case PIXEL_x8:
127 				ptrs8 = ((unsigned char*)src->screen->data) + sx + sy * src->screen->width;
128 				if(transbg && !*ptrs8) return;
129 				ps32 = table?((unsigned int*)table)[*ptrs8]:((unsigned int*)src->screen->palette)[*ptrs8];
130 				break;
131 			default:
132 				return;
133 			}
134 			if(fillcolor) ps32 = fillcolor;
135 			if(!pfp32) *ptrd32 = ps32;
136 			else       *ptrd32 = pfp32(ps32, pd32);
137 			break;
138 
139 	}
140 }
141 
142 
draw_pixel_bitmap(s_screen * dest,gfx_entry * src,int dx,int dy,int sx,int sy)143 inline void draw_pixel_bitmap(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy)
144 {
145 	//stub
146 	// should be OK for now since s_screen and s_bitmap are identical to each other
147 	assert(sizeof(s_screen)!=sizeof(s_bitmap));
148 	draw_pixel_screen(dest, src, dx, dy, sx, sy);
149 }
150 
151 // get a pixel from specific sprite
152 // should be fairly slow due to the RLE compression
sprite_get_pixel(s_sprite * sprite,int x,int y)153 inline char sprite_get_pixel(s_sprite* sprite, int x, int y){
154 	int *linetab;
155 	register int lx = 0, count;
156 	unsigned char * data;
157 
158 	//should we check?
159 	//if(y<0 || y>=sprite->height || x<0 || x>=sprite->width)
160 	//	return 0;
161 
162 
163 	linetab = ((int*)sprite->data) + y;
164 
165 	data = ((unsigned char*)linetab) + (*linetab);
166 
167 	while(1) {
168 		count = *data++;
169 		if(count == 0xFF) return 0;
170 		if(lx+count>x) return 0; // transparent pixel
171 		lx += count;
172 		count = *data++;
173 		if(!count) continue;
174 		if(lx + count > x)
175 		{
176 			return data[x-lx]; // not transparent pixel
177 		}
178 		lx+=count;
179 		data+=count;
180 	}
181 
182 	return 0;
183 
184 }
185 
draw_pixel_sprite(s_screen * dest,gfx_entry * src,int dx,int dy,int sx,int sy)186 inline void draw_pixel_sprite(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy)
187 {
188 	unsigned char *ptrd8, ps8;
189 	unsigned short *ptrd16, pd16, ps16;
190 	unsigned int *ptrd32, pd32, ps32;
191 	switch(dest->pixelformat)
192 	{
193 		case PIXEL_8:
194 			if(!(ps8 = sprite_get_pixel(src->sprite, sx, sy)))
195 				return;
196 			ptrd8 = ((unsigned char*)dest->data) + dx + dy * dest->width;
197 			if(fillcolor) ps8 = fillcolor;
198 			*ptrd8 =pfp?pfp(table, ps8, *ptrd8):ps8;
199 			break;
200 		case PIXEL_16:
201 			if(!(ps8 = sprite_get_pixel(src->sprite, sx, sy)))
202 				return;
203 			ptrd16 = ((unsigned short*)dest->data) + dx + dy * dest->width;
204 			pd16 = *ptrd16;
205 			if(fillcolor) ps16 = fillcolor;
206 			else ps16 = table?((unsigned short*)table)[ps8]:((unsigned short*)src->sprite->palette)[ps8];
207 			if(!pfp16) *ptrd16 = ps16;
208 			else       *ptrd16 = pfp16(ps16, pd16);
209 			break;
210 		case PIXEL_32:
211 			if(!(ps8 = sprite_get_pixel(src->sprite, sx, sy)))
212 				return;
213 			ptrd32 = ((unsigned int*)dest->data) + dx + dy * dest->width;
214 			pd32 = *ptrd32;
215 			if(fillcolor) ps32 = fillcolor;
216 			else ps32 = table?((unsigned int*)table)[ps8]:((unsigned int*)src->sprite->palette)[ps8];
217 			if(!pfp32) *ptrd32 = ps32;
218 			else       *ptrd32 = pfp32(ps32, pd32);
219 			break;
220 	}
221 
222 }
223 
draw_pixel_gfx(s_screen * dest,gfx_entry * src,int dx,int dy,int sx,int sy)224 inline void draw_pixel_gfx(s_screen* dest, gfx_entry* src, int dx, int dy, int sx, int sy){
225 	//drawfp(dest, src, dx, dy, sx, sy);
226 	switch(src->screen->magic){
227 	case sprite_magic:
228 		draw_pixel_sprite(dest, src, dx, dy, sx, sy);
229 		break;
230 	case screen_magic:
231 		draw_pixel_screen(dest, src, dx, dy, sx, sy);
232 		break;
233 	case bitmap_magic:
234 		draw_pixel_bitmap(dest, src, dx, dy, sx, sy);
235 		break;
236 	default:
237 		draw_pixel_dummy(dest, src, dx, dy, sx, sy);//debug purpose
238 		break;
239 	}
240 }
241 
copy_pixel_block(int bytes)242 inline void copy_pixel_block(int bytes){
243 	memcpy(cur_dest, cur_src, bytes);
244 }
245 
write_pixel()246 inline void write_pixel(){
247 	unsigned char ps8;
248 	unsigned short ps16;
249 	unsigned ps32;
250 	if(!cur_src) return;
251 	switch(dpf)
252 	{
253 		case PIXEL_8:
254 			ps8 = *cur_src;
255 			if(transbg && !ps8) return;
256 			else if(fillcolor) ps8 = fillcolor;
257 			*cur_dest =pfp?pfp(table, ps8, *cur_dest):ps8;
258 			break;
259 		case PIXEL_16:
260 			switch(spf)
261 			{
262 			case PIXEL_16:
263 				ps16 = *(unsigned short*)cur_src;
264 				if(transbg && !ps16) return;
265 				break;
266 			case PIXEL_x8:
267 				if(!(ps8=*cur_src) && transbg) return;
268 				ps16 = ((unsigned short*)table)[ps8];
269 				break;
270 			default:
271 				return;
272 			}
273 			if(fillcolor) ps16 = fillcolor;
274 			if(!pfp16) *(unsigned short*)cur_dest = ps16;
275 			else       *(unsigned short*)cur_dest = pfp16(ps16, *(unsigned short*)cur_dest);
276 			break;
277 		case PIXEL_32:
278 			switch(spf)
279 			{
280 			case PIXEL_32:
281 				ps32 = *(unsigned*)cur_src;
282 				if(transbg && !ps32) return;
283 				break;
284 			case PIXEL_x8:
285 				if(!(ps8=*cur_src) && transbg) return;
286 				ps32 = ((unsigned*)table)[ps8];
287 				break;
288 			default:
289 				return;
290 			}
291 			if(fillcolor) ps32 = fillcolor;
292 			if(!pfp32) *(unsigned*)cur_dest = ps32;
293 			else       *(unsigned*)cur_dest = pfp32(ps32, *(unsigned*)cur_dest);
294 			break;
295 		default:
296 			break;
297 	}
298 
299 }
300 
dest_seek(int x,int y)301 inline void dest_seek(int x, int y){
302 	//x_dest = x; y_dest = y;
303 	cur_dest = ptr_dest + (y * trans_dw + x)*pixelbytes[dpf];
304 }
305 
dest_line_inc()306 inline void dest_line_inc(){
307 	//y_dest++;
308 	cur_dest += span_dest;
309 }
310 
dest_line_dec()311 inline void dest_line_dec(){
312 	//y_dest--;
313 	cur_dest -= span_dest;
314 }
315 
316 //should be within a line
dest_inc()317 inline void dest_inc(){
318 	//x_dest++;
319 	cur_dest  += pixelbytes[dpf];
320 }
321 
322 //should be within a line
dest_dec()323 inline void dest_dec(){
324 	//x_dest--;
325 	cur_dest -= pixelbytes[dpf];
326 }
327 
_sprite_seek(int x,int y)328 inline  void _sprite_seek(int x, int y){
329 	int* linetab;
330 	unsigned char* data = NULL;
331 	register int lx = 0, count;
332 
333 	linetab = ((int*)ptr_src) + y;
334 
335 	data = ((unsigned char*)linetab) + (*linetab);
336 
337 	while(1) {
338 		count = *data++;
339 		if(count == 0xFF) {
340 			cur_src = NULL;
341 			goto quit;
342 		}
343 		if(lx+count>x) { // transparent pixel
344 			cur_src = NULL;
345 			goto quit;
346 		}
347 		lx += count;
348 		count = *data++;
349 		if(!count) continue;
350 		if(lx + count > x){
351 			cur_src = data + x - lx;
352 			goto quit;
353 		}
354 		lx+=count;
355 		data+=count;
356 	}
357 
358 quit:
359 	cur_spr = data-1; // current block head
360 	return ;
361 
362 }
363 
src_seek(int x,int y)364 inline void src_seek(int x, int y){
365 	switch(handle_src->screen->magic){
366 	case sprite_magic:
367 		x_src = x; y_src = y;
368 		_sprite_seek(x,y);
369 		break;
370 	case screen_magic:
371 	case bitmap_magic:
372 		cur_src = ptr_src + (y * trans_sw + x)*pixelbytes[spf];
373 		break;
374 	default:
375 		break;
376 	}
377 }
378 
src_line_inc()379 inline void src_line_inc(){
380 	switch(handle_src->screen->magic){
381 	case sprite_magic:
382 		y_src++;
383 		_sprite_seek(x_src, y_src);
384 		break;
385 	case screen_magic:
386 	case bitmap_magic:
387 		cur_src += span_src;
388 		break;
389 	default:
390 		break;
391 	}
392 }
393 
src_line_dec()394 inline void src_line_dec(){
395 	switch(handle_src->screen->magic){
396 	case sprite_magic:
397 		y_src--;
398 		_sprite_seek(x_src, y_src);
399 		break;
400 	case screen_magic:
401 	case bitmap_magic:
402 		cur_src -= span_src;
403 		break;
404 	default:
405 		break;
406 	}
407 }
408 
409 //should be within a line
src_inc()410 inline void src_inc(){
411 	//int cnt;
412 	x_src++;
413 	switch(handle_src->screen->magic){
414 	case sprite_magic:
415 		//_sprite_seek(x,y);
416 		if(cur_src && cur_spr + *cur_spr > cur_src){
417 			cur_src++;
418 		}else _sprite_seek(x_src, y_src);
419 		break;
420 	case screen_magic:
421 	case bitmap_magic:
422 		cur_src += pixelbytes[spf];
423 		break;
424 	default:
425 		break;
426 	}
427 }
428 
429 //should be within a line
src_dec()430 inline void src_dec(){
431 	x_src--;
432 	switch(handle_src->screen->magic){
433 	case sprite_magic:
434 		//_sprite_seek(x,y);
435 		if(cur_src && cur_spr + 1 < cur_src){
436 			cur_src--;
437 		}else _sprite_seek(x_src, y_src);
438 		break;
439 	case screen_magic:
440 	case bitmap_magic:
441 		cur_src -= pixelbytes[spf];
442 		break;
443 	default:
444 		break;
445 	}
446 }
447 
init_gfx_global_draw_stuff(s_screen * dest,gfx_entry * src,s_drawmethod * drawmethod)448 void init_gfx_global_draw_stuff(s_screen* dest, gfx_entry* src, s_drawmethod* drawmethod){
449 
450 	spf = dpf = 0; //source pixel format
451 	drawfp = draw_pixel_dummy;
452 	pfp = NULL; fillcolor = 0; pfp16 = NULL;pfp32 = NULL; table = NULL; transbg = 0;
453 
454 	handle_dest = dest; handle_src = src;
455 	cur_dest = ptr_dest = (unsigned char*)dest->data;
456 	x_dest = y_dest = x_src = y_src = 0;
457 
458 	//nasty checkings due to those different pixel formats
459 	switch(src->screen->magic)
460 	{
461 	case screen_magic:
462 		//printf("gfx_screen\n");
463 		spf = src->screen->pixelformat;
464 		drawfp = draw_pixel_screen;
465 		trans_sw = src->screen->width;
466 		trans_sh = src->screen->height;
467 		cur_src = ptr_src = (unsigned char*)src->screen->data;
468 		table = drawmethod->table?drawmethod->table:src->screen->palette;
469 		break;
470 	case bitmap_magic:
471 		//printf("gfx_bitmap\n");
472 		spf = src->bitmap->pixelformat;
473 		drawfp = draw_pixel_bitmap;
474 		trans_sw = src->bitmap->width;
475 		trans_sh = src->bitmap->height;
476 		cur_src = ptr_src = (unsigned char*)src->bitmap->data;
477 		table = drawmethod->table?drawmethod->table:src->bitmap->palette;
478 		break;
479 	case sprite_magic:
480 		//printf("gfx_sprite\n");
481 		spf = src->sprite->pixelformat;
482 		drawfp = draw_pixel_sprite;
483 		trans_sw = src->sprite->width;
484 		trans_sh = src->sprite->height;
485 		if(trans_sw){
486 			ptr_src = (unsigned char*)src->sprite->data;
487 			cur_spr = ptr_src + (*(int*)ptr_src);
488 		}
489 		table = drawmethod->table?drawmethod->table:src->sprite->palette;
490 		break;
491 	default:
492 		//printf("gfx_unknown\n");
493 		return;
494 	}
495 
496 	trans_dw = dest->width;
497 	trans_dh = dest->height;
498 
499 	dpf = dest->pixelformat;
500 
501 	switch(dest->pixelformat)
502 	{
503 	case PIXEL_8:
504 		if(drawmethod->fillcolor) fillcolor = drawmethod->fillcolor&0xFF;
505 		else fillcolor = 0;
506 
507 		table = NULL;
508 
509 		if(drawmethod->table)
510 		{
511 			table = drawmethod->table;
512 			pfp = remapcolor;
513 		}
514 		else if(drawmethod->alpha>0)
515 		{
516 			table = blendtables[drawmethod->alpha-1];
517 			pfp = (fillcolor==TRANSPARENT_IDX?blendcolor:blendfillcolor);
518 		}
519 		else pfp = (fillcolor==TRANSPARENT_IDX?NULL:blendfillcolor);
520 		break;
521 	case PIXEL_16:
522 		fillcolor = drawmethod->fillcolor;
523 		if(drawmethod->alpha>0) pfp16 = blendfunctions16[drawmethod->alpha-1];
524 		else pfp16 = NULL;
525 		break;
526 	case PIXEL_32:
527 		fillcolor = drawmethod->fillcolor;
528 		if(drawmethod->alpha>0) pfp32 = blendfunctions32[drawmethod->alpha-1];
529 		else pfp32 = NULL;
530 		break;
531 	default:
532 		return;
533 	}
534 
535 	span_src = pixelbytes[spf]*trans_sw;
536 	span_dest = pixelbytes[dpf]*trans_dw;
537 	transbg = (drawmethod->transbg || src->screen->magic==sprite_magic); // check color key, we'll need this for screen and bitmap
538 
539 	if(!trans_sw) return;
540 	src_seek(0,0);
541 }
542 
543 
544 //sin cos tables
545 //sin cos tables
546 const float sin_table[] = //360
547 {
548 0, 0.01745240643728351, 0.03489949670250097, 0.05233595624294383, 0.0697564737441253, 0.08715574274765816, 0.10452846326765346, 0.12186934340514747, 0.13917310096006544, 0.15643446504023087, 0.17364817766693033, 0.1908089953765448, 0.20791169081775931, 0.224951054343865, 0.24192189559966773, 0.25881904510252074, 0.27563735581699916, 0.29237170472273677, 0.3090169943749474, 0.32556815445715664, 0.3420201433256687, 0.35836794954530027, 0.374606593415912, 0.3907311284892737, 0.40673664307580015, 0.42261826174069944, 0.4383711467890774, 0.45399049973954675, 0.4694715627858908, 0.48480962024633706, 0.49999999999999994, 0.5150380749100542, 0.5299192642332049, 0.5446390350150271, 0.5591929034707469, 0.573576436351046, 0.5877852522924731, 0.6018150231520483, 0.6156614753256582, 0.6293203910498374, 0.6427876096865392, 0.6560590289905072, 0.6691306063588582, 0.6819983600624985, 0.6946583704589972, 0.7071067811865475, 0.7193398003386511, 0.7313537016191705, 0.7431448254773941, 0.754709580222772, 0.766044443118978, 0.7771459614569708, 0.788010753606722, 0.7986355100472928, 0.8090169943749474, 0.8191520442889918, 0.8290375725550417, 0.8386705679454239, 0.848048096156426, 0.8571673007021122, 0.8660254037844386, 0.8746197071393957, 0.8829475928589269, 0.8910065241883678, 0.898794046299167, 0.9063077870366499, 0.9135454576426009, 0.9205048534524403, 0.9271838545667874, 0.9335804264972017, 0.9396926207859083, 0.9455185755993167, 0.9510565162951535, 0.9563047559630354, 0.9612616959383189, 0.9659258262890683, 0.9702957262759965, 0.9743700647852352, 0.9781476007338056, 0.981627183447664, 0.984807753012208, 0.9876883405951378, 0.9902680687415702, 0.992546151641322, 0.9945218953682733, 0.9961946980917455, 0.9975640502598242, 0.9986295347545738, 0.9993908270190958, 0.9998476951563913, 1, 0.9998476951563913, 0.9993908270190958, 0.9986295347545738, 0.9975640502598242, 0.9961946980917455, 0.9945218953682734, 0.9925461516413221, 0.9902680687415704, 0.9876883405951377, 0.984807753012208, 0.981627183447664, 0.9781476007338057, 0.9743700647852352, 0.9702957262759965, 0.9659258262890683, 0.9612616959383189, 0.9563047559630355, 0.9510565162951536, 0.9455185755993168, 0.9396926207859084, 0.9335804264972017, 0.9271838545667874, 0.9205048534524404, 0.913545457642601, 0.90630778703665, 0.8987940462991669, 0.8910065241883679, 0.8829475928589271, 0.8746197071393958, 0.8660254037844387, 0.8571673007021123, 0.8480480961564261, 0.8386705679454239, 0.8290375725550417, 0.819152044288992, 0.8090169943749474, 0.7986355100472927, 0.788010753606722, 0.777145961456971, 0.766044443118978, 0.7547095802227718, 0.7431448254773942, 0.7313537016191706, 0.7193398003386514, 0.7071067811865476, 0.6946583704589971, 0.6819983600624986, 0.6691306063588583, 0.6560590289905073, 0.6427876096865395, 0.6293203910498377, 0.6156614753256584, 0.6018150231520482, 0.5877852522924732, 0.5735764363510464, 0.5591929034707469, 0.544639035015027, 0.5299192642332049, 0.5150380749100544, 0.49999999999999994, 0.48480962024633717, 0.4694715627858911, 0.45399049973954686, 0.4383711467890773, 0.4226182617406995, 0.40673664307580043, 0.39073112848927416, 0.37460659341591223, 0.3583679495453002, 0.3420201433256689, 0.32556815445715703, 0.3090169943749475, 0.29237170472273704, 0.27563735581699966, 0.258819045102521, 0.24192189559966773, 0.22495105434386478, 0.20791169081775931, 0.19080899537654497, 0.17364817766693027, 0.15643446504023098, 0.13917310096006574, 0.12186934340514754, 0.10452846326765373, 0.08715574274765864, 0.06975647374412552, 0.05233595624294381, 0.0348994967025007, 0.01745240643728344, 1.2246063538223772e-16, -0.017452406437283192, -0.0348994967025009, -0.052335956242943564, -0.06975647374412483, -0.08715574274765794, -0.10452846326765305, -0.12186934340514774, -0.13917310096006552, -0.15643446504023073, -0.17364817766693047, -0.19080899537654472, -0.20791169081775906, -0.22495105434386497, -0.2419218955996675, -0.25881904510252035, -0.275637355816999, -0.2923717047227364, -0.30901699437494773, -0.32556815445715675, -0.34202014332566865, -0.35836794954530043, -0.374606593415912, -0.39073112848927355, -0.4067366430757998, -0.4226182617406993, -0.43837114678907707, -0.45399049973954625, -0.46947156278589086, -0.48480962024633694, -0.5000000000000001, -0.5150380749100542, -0.5299192642332048, -0.5446390350150271, -0.5591929034707467, -0.5735764363510458, -0.587785252292473, -0.601815023152048, -0.6156614753256578, -0.6293203910498376, -0.6427876096865392, -0.6560590289905074, -0.6691306063588582, -0.6819983600624984, -0.6946583704589974, -0.7071067811865475, -0.7193398003386509, -0.7313537016191701, -0.743144825477394, -0.7547095802227717, -0.7660444431189779, -0.7771459614569711, -0.7880107536067221, -0.7986355100472928, -0.8090169943749473, -0.8191520442889916, -0.8290375725550414, -0.838670567945424, -0.848048096156426, -0.8571673007021121, -0.8660254037844384, -0.874619707139396, -0.882947592858927, -0.8910065241883678, -0.8987940462991668, -0.9063077870366497, -0.913545457642601, -0.9205048534524403, -0.9271838545667873, -0.9335804264972016, -0.9396926207859082, -0.9455185755993168, -0.9510565162951535, -0.9563047559630353, -0.961261695938319, -0.9659258262890683, -0.9702957262759965, -0.9743700647852351, -0.9781476007338056, -0.9816271834476639, -0.984807753012208, -0.9876883405951377, -0.9902680687415704, -0.9925461516413221, -0.9945218953682734, -0.9961946980917455, -0.9975640502598242, -0.9986295347545738, -0.9993908270190956, -0.9998476951563913, -1, -0.9998476951563913, -0.9993908270190958, -0.9986295347545738, -0.9975640502598243, -0.9961946980917455, -0.9945218953682734, -0.992546151641322, -0.9902680687415704, -0.9876883405951378, -0.9848077530122081, -0.9816271834476641, -0.9781476007338058, -0.9743700647852352, -0.9702957262759966, -0.9659258262890682, -0.9612616959383188, -0.9563047559630354, -0.9510565162951536, -0.945518575599317, -0.9396926207859085, -0.9335804264972021, -0.9271838545667874, -0.9205048534524405, -0.9135454576426008, -0.9063077870366499, -0.898794046299167, -0.8910065241883679, -0.8829475928589271, -0.8746197071393961, -0.8660254037844386, -0.8571673007021123, -0.8480480961564262, -0.8386705679454243, -0.8290375725550421, -0.8191520442889918, -0.8090169943749476, -0.798635510047293, -0.7880107536067218, -0.7771459614569708, -0.7660444431189781, -0.7547095802227722, -0.7431448254773946, -0.731353701619171, -0.7193398003386517, -0.7071067811865477, -0.6946583704589976, -0.6819983600624982, -0.6691306063588581, -0.6560590289905074, -0.6427876096865396, -0.6293203910498378, -0.6156614753256588, -0.6018150231520483, -0.5877852522924734, -0.5735764363510465, -0.5591929034707473, -0.544639035015027, -0.5299192642332058, -0.5150380749100545, -0.5000000000000004, -0.4848096202463369, -0.4694715627858908, -0.45399049973954697, -0.438371146789077, -0.4226182617407, -0.40673664307580015, -0.3907311284892747, -0.37460659341591235, -0.35836794954530077, -0.3420201433256686, -0.32556815445715753, -0.3090169943749476, -0.29237170472273627, -0.2756373558169998, -0.2588190451025207, -0.24192189559966787, -0.22495105434386534, -0.20791169081775987, -0.19080899537654466, -0.17364817766693127, -0.1564344650402311, -0.13917310096006588, -0.12186934340514811, -0.10452846326765341, -0.08715574274765832, -0.06975647374412476, -0.05233595624294437, -0.034899496702500823, -0.01745240643728445
549 };
550 const float cos_table[] = //360
551 {
552 1, 0.9998476951563913, 0.9993908270190958, 0.9986295347545738, 0.9975640502598242, 0.9961946980917455, 0.9945218953682733, 0.992546151641322, 0.9902680687415704, 0.9876883405951378, 0.984807753012208, 0.981627183447664, 0.9781476007338057, 0.9743700647852352, 0.9702957262759965, 0.9659258262890683, 0.9612616959383189, 0.9563047559630354, 0.9510565162951535, 0.9455185755993168, 0.9396926207859084, 0.9335804264972017, 0.9271838545667874, 0.9205048534524404, 0.9135454576426009, 0.9063077870366499, 0.898794046299167, 0.8910065241883679, 0.882947592858927, 0.8746197071393957, 0.8660254037844387, 0.8571673007021123, 0.848048096156426, 0.838670567945424, 0.8290375725550416, 0.8191520442889918, 0.8090169943749474, 0.7986355100472928, 0.788010753606722, 0.7771459614569709, 0.766044443118978, 0.7547095802227721, 0.7431448254773942, 0.7313537016191706, 0.7193398003386512, 0.7071067811865476, 0.6946583704589974, 0.6819983600624985, 0.6691306063588582, 0.6560590289905073, 0.6427876096865394, 0.6293203910498375, 0.6156614753256583, 0.6018150231520484, 0.5877852522924731, 0.5735764363510462, 0.5591929034707468, 0.5446390350150272, 0.5299192642332049, 0.5150380749100544, 0.5000000000000001, 0.4848096202463371, 0.46947156278589086, 0.4539904997395468, 0.43837114678907746, 0.42261826174069944, 0.4067366430758002, 0.39073112848927394, 0.37460659341591196, 0.3583679495453004, 0.3420201433256688, 0.32556815445715675, 0.30901699437494745, 0.29237170472273677, 0.27563735581699916, 0.25881904510252074, 0.2419218955996679, 0.22495105434386492, 0.20791169081775945, 0.19080899537654491, 0.17364817766693041, 0.15643446504023092, 0.1391731009600657, 0.12186934340514749, 0.10452846326765346, 0.08715574274765814, 0.06975647374412545, 0.052335956242943966, 0.03489949670250108, 0.017452406437283376, 6.123031769111886e-17, -0.017452406437283477, -0.03489949670250073, -0.05233595624294362, -0.06975647374412533, -0.08715574274765823, -0.10452846326765333, -0.12186934340514736, -0.13917310096006535, -0.15643446504023103, -0.1736481776669303, -0.1908089953765448, -0.20791169081775912, -0.2249510543438648, -0.24192189559966778, -0.25881904510252085, -0.27563735581699905, -0.29237170472273666, -0.30901699437494734, -0.3255681544571564, -0.3420201433256687, -0.35836794954530027, -0.37460659341591207, -0.3907311284892736, -0.40673664307580004, -0.42261826174069933, -0.4383711467890775, -0.4539904997395467, -0.46947156278589053, -0.484809620246337, -0.4999999999999998, -0.5150380749100543, -0.5299192642332048, -0.5446390350150271, -0.5591929034707467, -0.5735764363510458, -0.587785252292473, -0.6018150231520484, -0.6156614753256583, -0.6293203910498373, -0.6427876096865394, -0.6560590289905075, -0.6691306063588582, -0.6819983600624984, -0.694658370458997, -0.7071067811865475, -0.7193398003386512, -0.7313537016191705, -0.743144825477394, -0.754709580222772, -0.7660444431189779, -0.7771459614569707, -0.7880107536067219, -0.7986355100472929, -0.8090169943749473, -0.8191520442889916, -0.8290375725550416, -0.8386705679454242, -0.848048096156426, -0.8571673007021122, -0.8660254037844387, -0.8746197071393957, -0.8829475928589268, -0.8910065241883678, -0.898794046299167, -0.9063077870366499, -0.9135454576426008, -0.9205048534524401, -0.9271838545667873, -0.9335804264972017, -0.9396926207859083, -0.9455185755993167, -0.9510565162951535, -0.9563047559630354, -0.9612616959383187, -0.9659258262890682, -0.9702957262759965, -0.9743700647852352, -0.9781476007338057, -0.981627183447664, -0.984807753012208, -0.9876883405951377, -0.9902680687415702, -0.992546151641322, -0.9945218953682733, -0.9961946980917455, -0.9975640502598242, -0.9986295347545738, -0.9993908270190958, -0.9998476951563913, -1, -0.9998476951563913, -0.9993908270190958, -0.9986295347545738, -0.9975640502598243, -0.9961946980917455, -0.9945218953682734, -0.992546151641322, -0.9902680687415702, -0.9876883405951378, -0.984807753012208, -0.981627183447664, -0.9781476007338057, -0.9743700647852352, -0.9702957262759965, -0.9659258262890684, -0.9612616959383189, -0.9563047559630355, -0.9510565162951535, -0.9455185755993167, -0.9396926207859084, -0.9335804264972017, -0.9271838545667874, -0.9205048534524404, -0.9135454576426011, -0.90630778703665, -0.8987940462991671, -0.8910065241883681, -0.8829475928589269, -0.8746197071393958, -0.8660254037844386, -0.8571673007021123, -0.8480480961564261, -0.838670567945424, -0.8290375725550418, -0.819152044288992, -0.8090169943749476, -0.798635510047293, -0.7880107536067222, -0.7771459614569708, -0.766044443118978, -0.7547095802227719, -0.7431448254773942, -0.7313537016191706, -0.7193398003386511, -0.7071067811865477, -0.6946583704589976, -0.6819983600624989, -0.6691306063588585, -0.6560590289905076, -0.6427876096865395, -0.6293203910498372, -0.6156614753256581, -0.6018150231520483, -0.5877852522924732, -0.5735764363510464, -0.5591929034707472, -0.544639035015027, -0.529919264233205, -0.5150380749100545, -0.5000000000000004, -0.48480962024633683, -0.46947156278589075, -0.4539904997395469, -0.43837114678907773, -0.42261826174069994, -0.4067366430758001, -0.3907311284892738, -0.3746065934159123, -0.3583679495453007, -0.3420201433256694, -0.32556815445715664, -0.30901699437494756, -0.2923717047227371, -0.2756373558169989, -0.25881904510252063, -0.24192189559966778, -0.22495105434386525, -0.2079116908177598, -0.19080899537654547, -0.17364817766693033, -0.15643446504023103, -0.13917310096006494, -0.12186934340514717, -0.10452846326765336, -0.08715574274765825, -0.06975647374412558, -0.052335956242944306, -0.03489949670250165, -0.017452406437283498, -1.836909530733566e-16, 0.01745240643728313, 0.03489949670250128, 0.052335956242943946, 0.06975647374412522, 0.08715574274765789, 0.10452846326765298, 0.12186934340514768, 0.13917310096006546, 0.15643446504023067, 0.17364817766692997, 0.19080899537654425, 0.20791169081775856, 0.22495105434386492, 0.24192189559966745, 0.25881904510252113, 0.2756373558169994, 0.2923717047227367, 0.30901699437494723, 0.3255681544571563, 0.34202014332566816, 0.35836794954529954, 0.37460659341591196, 0.3907311284892735, 0.40673664307580054, 0.4226182617406996, 0.4383711467890774, 0.45399049973954664, 0.4694715627858904, 0.4848096202463365, 0.5000000000000001, 0.5150380749100542, 0.5299192642332047, 0.5446390350150266, 0.5591929034707462, 0.573576436351046, 0.5877852522924729, 0.6018150231520479, 0.6156614753256585, 0.6293203910498375, 0.6427876096865392, 0.656059028990507, 0.6691306063588578, 0.681998360062498, 0.6946583704589966, 0.7071067811865473, 0.7193398003386509, 0.7313537016191707, 0.7431448254773942, 0.7547095802227719, 0.7660444431189778, 0.7771459614569706, 0.7880107536067216, 0.7986355100472928, 0.8090169943749473, 0.8191520442889916, 0.8290375725550414, 0.838670567945424, 0.8480480961564254, 0.8571673007021121, 0.8660254037844384, 0.8746197071393958, 0.8829475928589269, 0.8910065241883678, 0.8987940462991671, 0.9063077870366497, 0.913545457642601, 0.9205048534524399, 0.9271838545667873, 0.9335804264972015, 0.9396926207859084, 0.9455185755993165, 0.9510565162951535, 0.9563047559630357, 0.9612616959383187, 0.9659258262890683, 0.9702957262759965, 0.9743700647852351, 0.9781476007338056, 0.981627183447664, 0.9848077530122079, 0.9876883405951377, 0.9902680687415702, 0.992546151641322, 0.9945218953682733, 0.9961946980917455, 0.9975640502598243, 0.9986295347545738, 0.9993908270190958, 0.9998476951563913
553 };
554 
555 #define _max(a,b) (((a)>(b))?(a):(b))
556 #define _min(a,b) (((a)<(b))?(a):(b))
557 
558 
gfx_draw_rotate(s_screen * dest,gfx_entry * src,int x,int y,int centerx,int centery,s_drawmethod * drawmethod)559 void gfx_draw_rotate(s_screen* dest, gfx_entry* src, int x, int y, int centerx, int centery, s_drawmethod* drawmethod)
560 {
561 	float zoomx, zoomy, rzoomx, rzoomy, sina, cosa, ax, ay, bx, by, rx0, ry0, cx, cy, srcx0_f, srcx_f, srcy0_f, srcy_f, angle;
562 	int i, j, srcx, srcy;
563 	int xbound[4], ybound[4], xmin, xmax, ymin, ymax;
564 	float xboundf[4], yboundf[4];
565 	zoomx = drawmethod->scalex / 256.0;
566 	zoomy = drawmethod->scaley / 256.0;
567 	angle = drawmethod->rotate;
568     sina = sin_table[(int)angle];
569     cosa = cos_table[(int)angle];
570 
571 	init_gfx_global_draw_stuff(dest, src, drawmethod);
572 	if(!trans_sw) return;
573 
574 	centerx += drawmethod->centerx;
575 	centery += drawmethod->centery;
576 
577 	/////////////////begin clipping////////////////////////////
578 	xboundf[0] = drawmethod->flipx? (centerx-trans_sw)*zoomx : -centerx*zoomx;
579 	yboundf[0] = drawmethod->flipy? (centery-trans_sh)*zoomy : -centery*zoomy;
580 	xboundf[1] = xboundf[0] + trans_sw*zoomx;
581 	yboundf[1] = yboundf[0];
582 	xboundf[2] = xboundf[0];
583 	yboundf[2] = yboundf[0] + trans_sh*zoomy;
584 	xboundf[3] = xboundf[1];
585 	yboundf[3] = yboundf[2];
586 
587 	for(i=0; i<4; i++){
588 		xbound[i] =  (int)(x + xboundf[i]*cosa - yboundf[i]*sina);
589         ybound[i] =  (int)(y + xboundf[i]*sina + yboundf[i]*cosa);
590 	}
591 
592 	xmin = _max(_min(_min(xbound[0],xbound[1]), _min(xbound[2],xbound[3])), 0);
593 	xmax = _min(_max(_max(xbound[0],xbound[1]), _max(xbound[2],xbound[3])), trans_dw);
594 	ymin = _max(_min(_min(ybound[0],ybound[1]), _min(ybound[2],ybound[3])), 0);
595 	ymax = _min(_max(_max(ybound[0],ybound[1]), _max(ybound[2],ybound[3])), trans_dh);
596 	/////////////////end clipping////////////////////////////
597 
598 	// tricks to keep rotate not affected by flip
599 	if(drawmethod->flipx) {zoomx = -zoomx;}
600 	else  {angle = -angle;}
601 	if(drawmethod->flipy) {	zoomy = -zoomy; angle = -angle;}
602 
603 	angle = (((int)angle)%360+360)%360;
604 	//if(!zoomx || !zoomy) return; //should be checked already
605     rzoomx = 1.0 / zoomx;
606     rzoomy = 1.0 / zoomy;
607     sina = sin_table[(int)angle];
608     cosa = cos_table[(int)angle];
609     ax = rzoomx*cosa;
610     ay = rzoomx*sina;
611     bx = -rzoomy*sina;
612     by = rzoomy*cosa;
613     rx0 = centerx;
614     ry0 = centery;
615 	x -= rx0;
616 	y -= ry0;
617     cx = -(rx0+x)*rzoomx*cosa+(ry0+y)*rzoomy*sina+rx0;
618     cy = -(rx0+x)*rzoomx*sina-(ry0+y)*rzoomy*cosa+ry0;
619 	srcx0_f= cx+ymin*bx+xmin*ax, srcx_f;
620     srcy0_f= cy+ymin*by+xmin*ay, srcy_f;
621 
622     for (j=ymin; j<ymax; j++)
623     {
624         srcx_f = srcx0_f;
625         srcy_f = srcy0_f;
626         for (i=xmin;i<xmax;i++)
627         {
628             srcx=(int)(srcx_f);
629             srcy=(int)(srcy_f);
630 			if(srcx>=0 && srcx<trans_sw && srcy>=0 && srcy<trans_sh){
631 				draw_pixel_gfx(dest, src, i, j, srcx, srcy);
632 			}
633             srcx_f+=ax;
634             srcy_f+=ay;
635         }
636         srcx0_f+=bx;
637         srcy0_f+=by;
638     }
639 }
640 
641 // scalex scaley flipy ...
gfx_draw_scale(s_screen * dest,gfx_entry * src,int x,int y,int centerx,int centery,s_drawmethod * drawmethod)642 void gfx_draw_scale(s_screen *dest, gfx_entry* src, int x, int y, int centerx, int centery, s_drawmethod* drawmethod)
643 {
644 	float osx, sx, sy, dx, dy, w, h, cx, cy, stepdx, stepdy, beginy, endy, beginx, endx;
645 	int i, j;
646 	float zoomx = drawmethod->scalex / 256.0;
647 	float zoomy = drawmethod->scaley / 256.0;
648 	float shiftf = drawmethod->shiftx / 256.0;
649 
650 	//if(!zoomy || !zoomx) return; //should be checked already
651 
652 	//printf("==%d %d %d %d %d\n", drawmethod->scalex, drawmethod->scaley, drawmethod->flipx, drawmethod->flipy, drawmethod->shiftx);
653 
654 	init_gfx_global_draw_stuff(dest, src, drawmethod);
655 	if(!trans_sw) return;
656 
657 	centerx += drawmethod->centerx;
658 	centery += drawmethod->centery;
659 
660 	w = trans_sw * zoomx;
661 	h = trans_sh * zoomy;
662 	cx = centerx * zoomx;
663 	cy = centery * zoomy;
664 
665 	if(drawmethod->flipx) dx = cx - w + x;
666 	else dx = x - cx;
667 
668 	if(drawmethod->flipy){
669 		dy = cy - h + y;
670 		shiftf = - shiftf;
671 	}
672 	else dy = y - cy;
673 
674 	dx += (dy + h - y) * shiftf;
675 
676 	if(drawmethod->flipx) {
677 		stepdx = 1.0/zoomx;
678 		osx = 0.0;
679 	}else{
680 		stepdx = -1.0/zoomx;
681 		osx = trans_sw + stepdx;
682 	}
683 	if(drawmethod->flipy){
684 		stepdy = 1.0/zoomy;
685 		sy = 0.0;
686 	}else{
687 		stepdy = -1.0/zoomy;
688 		sy = trans_sh + stepdy;
689 	}
690 
691 	if(_max(dx+w, dx+w-shiftf*h)<=0) return;
692 	if(_min(dx, dx-shiftf*h)>=trans_dw) return;
693 	if(dy>=trans_dh) return;
694 	if(dy+h<=0) return;
695 
696 	if(dy+h>trans_dh) {
697 		endy = trans_dh;
698 		dx -= shiftf*(dy+h-endy);
699 		sy += stepdy*(dy+h-endy);
700 	} else endy = dy+h;
701 
702 	if(dy<0) beginy = 0;
703 	else beginy = dy;
704 
705 	//printf("=%d, %d, %lf, %lf, %lf, %lf, %lf, %lf\n ",x, y, w, h, osx, sy, dx, dy);
706 	// =64, 144, 44.000000, 36.500000, 43.000000, 0.000000, 38.000000, 143.000000
707 
708 	for(j=endy-1; j>=beginy; j--, sy+=stepdy, dx -= shiftf){
709 		if(dx>=trans_dw) continue;
710 		if(dx+w<=0) continue;
711 		sx = osx;
712 		beginx = dx;
713 		endx = dx+w;
714 		if(dx<0) beginx = 0;
715 		else beginx = dx;
716 		if(dx+w>trans_dw) {
717 			endx = trans_dw;
718 			sx += stepdx*(dx+w-trans_dw);
719 		} else endx = dx+w;
720 		dest_seek(endx-1, j);
721 		for(i=endx-1; i>=beginx; i--, sx+=stepdx){
722 			//draw_pixel_gfx(dest, src, i, j, (int)sx, (int)sy);
723 			src_seek((int)sx, (int)sy);
724 			write_pixel();
725 			dest_dec();
726 		}
727 	}
728 
729 }
730 
731 float _sinfactors[256] = {1.0f,1.0245412285229123f,1.049067674327418f,1.0735645635996673f,1.0980171403295606f,1.1224106751992162f,1.1467304744553617f,1.1709618887603012f,1.1950903220161282f,1.2191012401568697f,1.2429801799032638f,1.2667127574748984f,1.2902846772544622f,1.3136817403988914f,1.33688985339222f,1.3598950365349882f,1.3826834323650898f,1.4052413140049897f,1.427555093430282f,1.4496113296546064f,1.4713967368259977f,1.492898192229784f,1.5141027441932215f,1.5349976198870971f,1.5555702330196021f,1.5758081914178454f,1.5956993044924332f,1.6152315905806267f,1.6343932841636454f,1.6531728429537766f,1.6715589548470184f,1.6895405447370668f,1.7071067811865474f,1.724247082951467f,1.7409511253549592f,1.7572088465064843f,1.7730104533627368f,1.7883464276266063f,1.8032075314806448f,1.8175848131515837f,1.8314696123025453f,1.8448535652497071f,1.8577286100002721f,1.8700869911087112f,1.881921264348355f,1.8932243011955152f,1.9039892931234434f,1.9142097557035307f,1.9238795325112867f,1.9329927988347388f,1.9415440651830207f,1.9495281805930366f,1.956940335732209f,1.96377606579544f,1.970031253194544f,1.9757021300385284f,1.9807852804032304f,1.985277642388941f,1.9891765099647811f,1.99247953459871f,1.9951847266721967f,1.9972904566786902f,1.9987954562051724f,1.9996988186962041f,2.0f,1.9996988186962041f,1.9987954562051724f,1.9972904566786902f,1.995184726672197f,1.99247953459871f,1.9891765099647811f,1.985277642388941f,1.9807852804032304f,1.9757021300385284f,1.970031253194544f,1.96377606579544f,1.956940335732209f,1.9495281805930366f,1.9415440651830207f,1.9329927988347388f,1.9238795325112867f,1.9142097557035307f,1.9039892931234434f,1.8932243011955152f,1.881921264348355f,1.8700869911087114f,1.8577286100002721f,1.8448535652497071f,1.8314696123025453f,1.8175848131515837f,1.8032075314806448f,1.7883464276266063f,1.773010453362737f,1.7572088465064848f,1.740951125354959f,1.724247082951467f,1.7071067811865474f,1.689540544737067f,1.6715589548470184f,1.6531728429537766f,1.6343932841636454f,1.615231590580627f,1.5956993044924334f,1.5758081914178454f,1.5555702330196021f,1.5349976198870971f,1.5141027441932217f,1.4928981922297841f,1.471396736825998f,1.449611329654607f,1.427555093430282f,1.40524131400499f,1.3826834323650898f,1.3598950365349882f,1.3368898533922202f,1.3136817403988914f,1.2902846772544625f,1.2667127574748984f,1.242980179903264f,1.2191012401568701f,1.1950903220161286f,1.1709618887603012f,1.146730474455362f,1.1224106751992164f,1.0980171403295608f,1.0735645635996677f,1.0490676743274178f,1.0245412285229123f,1.0000000000000002f,0.9754587714770879f,0.9509323256725822f,0.9264354364003325f,0.9019828596704394f,0.8775893248007839f,0.8532695255446384f,0.8290381112396991f,0.8049096779838716f,0.7808987598431302f,0.7570198200967362f,0.7332872425251018f,0.709715322745538f,0.6863182596011088f,0.6631101466077799f,0.6401049634650119f,0.6173165676349104f,0.5947586859950102f,0.5724449065697181f,0.5503886703453933f,0.5286032631740023f,0.5071018077702161f,0.48589725580677845f,0.46500238011290307f,0.44442976698039804f,0.42419180858215466f,0.40430069550756675f,0.3847684094193733f,0.36560671583635473f,0.34682715704622346f,0.32844104515298156f,0.31045945526293317f,0.29289321881345254f,0.2757529170485332f,0.2590488746450411f,0.24279115349351576f,0.22698954663726334f,0.2116535723733941f,0.19679246851935494f,0.18241518684841618f,0.16853038769745476f,0.155146434750293f,0.142271389999728f,0.12991300889128865f,0.11807873565164506f,0.10677569880448478f,0.09601070687655688f,0.08579024429646953f,0.07612046748871348f,0.06700720116526104f,0.058455934816979194f,0.050471819406963325f,0.043059664267791176f,0.03622393420456016f,0.029968746805456026f,0.02429786996147154f,0.01921471959676968f,0.01472235761105889f,0.010823490035219096f,0.007520465401289922f,0.004815273327803071f,0.002709543321309793f,0.001204543794827595f,0.00030118130379575003f,0.0f,0.00030118130379575003f,0.001204543794827595f,0.002709543321309793f,0.004815273327803071f,0.007520465401289922f,0.010823490035219096f,0.014722357611058778f,0.01921471959676957f,0.02429786996147143f,0.029968746805456026f,0.03622393420456005f,0.043059664267791065f,0.050471819406963214f,0.05845593481697908f,0.06700720116526093f,0.07612046748871337f,0.08579024429646942f,0.09601070687655666f,0.10677569880448467f,0.11807873565164495f,0.12991300889128854f,0.14227138999972777f,0.15514643475029277f,0.16853038769745454f,0.18241518684841595f,0.19679246851935472f,0.21165357237339388f,0.22698954663726312f,0.24279115349351543f,0.2590488746450409f,0.275752917048533f,0.2928932188134523f,0.31045945526293283f,0.32844104515298133f,0.3468271570462229f,0.36560671583635407f,0.3847684094193726f,0.40430069550756675f,0.4241918085821548f,0.4444297669803978f,0.46500238011290273f,0.4858972558067781f,0.5071018077702157f,0.5286032631740021f,0.5503886703453931f,0.5724449065697175f,0.5947586859950096f,0.6173165676349096f,0.640104963465012f,0.66311014660778f,0.6863182596011085f,0.7097153227455375f,0.7332872425251014f,0.7570198200967358f,0.7808987598431298f,0.8049096779838712f,0.8290381112396983f,0.8532695255446376f,0.877589324800784f,0.9019828596704394f,0.9264354364003325f,0.9509323256725819f,0.9754587714770876f};
732 #define distortion(x, a) ((int)(_sinfactors[x]*a+0.5))
733 
gfx_draw_water(s_screen * dest,gfx_entry * src,int x,int y,int centerx,int centery,s_drawmethod * drawmethod)734 void gfx_draw_water(s_screen *dest, gfx_entry* src, int x, int y, int centerx, int centery, s_drawmethod* drawmethod){
735 	int sw, sh, dw, dh, ch, sy, t, u, sbeginx, sendx, bytestocopy, dbeginx, dendx, amplitude, time;
736 	float s, wavelength;
737 
738 	init_gfx_global_draw_stuff(dest, src, drawmethod);
739 	if(!trans_sw) return;
740 
741 	centerx += drawmethod->centerx;
742 	centery += drawmethod->centery;
743 
744 	sw = trans_sw;
745 	sh = trans_sh;
746 	dw = trans_dw;
747 	dh = trans_dh;
748 	ch = sh;
749 	x -= centerx;
750 	y -= centery;
751 
752 	amplitude = drawmethod->water.amplitude;
753 	time = drawmethod->water.wavetime;
754 
755 	s = time % 256;
756 
757 	// Clip x
758 	if(x + amplitude*2 + sw <= 0 || x - amplitude*2  >= dw) return;
759 	if(y + sh <=0 || y >= dh) return;
760 
761 	sy = 0;
762 	if(s<0) s+=256;
763 
764 	// Clip y
765 	if(y<0) {sy = -y; ch += y;}
766 	if(y+sh > dh) ch -= (y+sh) - dh;
767 
768 	if(y<0) y = 0;
769 
770 	u = (drawmethod->water.watermode==1)?distortion((int)s, amplitude):amplitude;
771 	wavelength = 256 / drawmethod->water.wavelength;
772 	s += sy*wavelength;
773 
774 	// Copy data
775 	do{
776 		s = s - (int)s + (int)s % 256;
777 		t = distortion((int)s, amplitude) - u;
778 
779 		dbeginx = x+t;
780 		dendx = x+t+sw;
781 
782 		if(dbeginx>=dw || dendx<=0) {dbeginx = dendx = sbeginx = sendx = 0;} //Nothing to draw
783 		//clip both
784 		else if(dbeginx<0 && dendx>dw){
785 			sbeginx = -dbeginx; sendx = sbeginx + dw;
786 			dbeginx = 0; dendx = dw;
787 		}
788 		//clip left
789 		else if(dbeginx<0) {
790 			sbeginx = -dbeginx; sendx = sw;
791 			dbeginx = 0;
792 		}
793 		// clip right
794 		else if(dendx>dw) {
795 			sbeginx = 0; sendx = dw - dbeginx;
796 			dendx = dw;
797 		}
798 		// clip none
799 		else{
800 			sbeginx = 0; sendx = sw;
801 		}
802 		if(pixelformat==PIXEL_8 && !transbg && src->screen->magic==screen_magic){
803 			dest_seek(dbeginx, y); src_seek(sbeginx, sy);
804 			copy_pixel_block(dendx-dbeginx);
805 		}else{
806 			bytestocopy = dendx-dbeginx;
807 			//TODO: optimize this if necessary
808 			for(t=0, dest_seek(dbeginx, y), src_seek(sbeginx, sy); t<bytestocopy; t++, dest_inc(), src_inc()){
809 				//draw_pixel_gfx(dest, src, dbeginx, y, sbeginx, sy);
810 				write_pixel();
811 			}
812 		}
813 
814 		s += wavelength;
815 		y++;
816 		sy++;
817 	}while(--ch);
818 }
819 
gfx_draw_plane(s_screen * dest,gfx_entry * src,int x,int y,int centerx,int centery,s_drawmethod * drawmethod)820 void gfx_draw_plane(s_screen *dest, gfx_entry* src, int x, int y, int centerx, int centery, s_drawmethod* drawmethod){
821 
822 	int i, j, dx, dy, sx, sy, width, height, copyh;
823 	float osxpos, sxpos, sypos, sxstep, systep, xpos, ypos, factor, size, cx, beginsize, endsize;
824 
825 	init_gfx_global_draw_stuff(dest, src, drawmethod);
826 	if(!trans_sw) return;
827 
828 	centerx += drawmethod->centerx;
829 	centery += drawmethod->centery;
830 
831 	x -= centerx;
832 	y -= centery;
833 
834 	xpos = x;
835 	ypos = y;
836 
837 	beginsize = drawmethod->water.beginsize;
838 	endsize = drawmethod->water.endsize;
839 
840 	if(beginsize<0 || endsize<0) return;
841 
842 	width = trans_sw;
843 	height = trans_sh;
844 
845 	// Check dimensions
846 	if(x >= trans_dw) return;
847 	if(y >= trans_dh) return;
848 	if(x<0){
849 		width += x;
850 		x = 0;
851 	}
852 	if(y<0){
853 		copyh = -y;
854 		height += y;
855 		y=0;
856 	}else copyh = 0;
857 	if(x+width > trans_dw){
858 		width = trans_dw - x;
859 	}
860 	if(y+height > trans_dh){
861 		height = trans_dh - y;
862 	}
863 	if(width<=0) return;
864 	if(height<=0) return;
865 
866 	copyh += height;
867 
868 	dy = ypos;
869 	dx = x;
870 
871 	cx = trans_dw / 2.0 - x;
872 
873 	osxpos = drawmethod->water.wavetime - xpos + trans_sw;
874 
875 	factor = (endsize - beginsize) / trans_sh;
876 	size = beginsize;
877 
878 	sypos = 0.0;
879 	for(i=0; i<copyh; i++, dy++, size+=factor, sypos+=systep)
880 	{
881 		sy = (int)sypos;
882 		sy %= trans_sh;
883 		if(sy<0) sy += trans_sh;
884 		sxstep = 1 / size;
885 		switch(drawmethod->water.perspective){
886 		case 1: // tile
887 			systep = sxstep;
888 			break;
889 		case 2: //stretch
890 			systep = sxstep*trans_sh/(float)trans_sw;
891 			break;
892 		default:
893 			systep = 1.0;
894 		}
895 		if(dy<0) continue;
896 		sxpos = osxpos - cx * sxstep;
897 
898 		//dest_seek(dx, dy);
899 		for(j=0; j<width; j++, sxpos += sxstep){
900 			sx = (int)sxpos;
901 			sx %= trans_sw;
902 			if(sx<0) sx += trans_sw;
903 			//src_seek(sx, sy);
904 			draw_pixel_gfx(dest, src, dx+j, dy, sx, sy);
905 			//write_pixel();
906 			//dest_inc();
907 		}
908 	}
909 
910 }
911 
912