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