]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/SoftwareDriver2_helper.h
83168c94bc5d297b7c84ffc881bfd210c4544cd1
[irrlicht.git] / source / Irrlicht / SoftwareDriver2_helper.h
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 /*\r
6         History:\r
7         - changed behavior for log2 textures ( replaced multiplies by shift )\r
8 */\r
9 \r
10 #ifndef __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__\r
11 #define __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__\r
12 \r
13 #include "SoftwareDriver2_compile_config.h"\r
14 #include "irrMath.h"\r
15 #include "irrMathFastCompat.h"\r
16 #include "CSoftwareTexture2.h"\r
17 #include "SMaterial.h"\r
18 \r
19 \r
20 namespace irr\r
21 {\r
22 \r
23 // supporting different packed pixel needs many defines...\r
24 \r
25 #if defined(SOFTWARE_DRIVER_2_32BIT)\r
26         typedef u32     tVideoSample;\r
27         typedef u32     tStencilSample;\r
28 \r
29         #define MASK_A  0xFF000000\r
30         #define MASK_R  0x00FF0000\r
31         #define MASK_G  0x0000FF00\r
32         #define MASK_B  0x000000FF\r
33 \r
34         #define SHIFT_A (unsigned)24\r
35         #define SHIFT_R (unsigned)16\r
36         #define SHIFT_G (unsigned)8\r
37         #define SHIFT_B (unsigned)0\r
38 \r
39         #define COLOR_MAX                                       0xFF\r
40         #define COLOR_MAX_LOG2                          8\r
41         #define COLOR_BRIGHT_WHITE                      0xFFFFFFFF\r
42 \r
43         #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY   (unsigned)2\r
44         #define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY      (unsigned)2\r
45 #else\r
46         typedef u16     tVideoSample;\r
47         typedef u8      tStencilSample;\r
48 \r
49         #define MASK_A  0x8000\r
50         #define MASK_R  0x7C00\r
51         #define MASK_G  0x03E0\r
52         #define MASK_B  0x001F\r
53 \r
54         #define SHIFT_A (unsigned)15\r
55         #define SHIFT_R (unsigned)10\r
56         #define SHIFT_G (unsigned)5\r
57         #define SHIFT_B (unsigned)0\r
58 \r
59         #define COLOR_MAX                                       0x1F\r
60         #define COLOR_MAX_LOG2                          5\r
61         #define COLOR_BRIGHT_WHITE                      0xFFFF\r
62         #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY   (unsigned)1\r
63         #define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY      (unsigned)1\r
64 \r
65 #endif\r
66 \r
67 \r
68 \r
69 \r
70 // ----------------------- Generic ----------------------------------\r
71 //! align_next - align to next upper 2^n\r
72 #define align_next(num,to) (((num) + (to-1)) & (~(to-1)))\r
73 \r
74 //! a more useful memset for pixel. dest must be aligned at least to 4 byte\r
75 // (standard memset only works with 8-bit values)\r
76 inline void memset32(void * dest, const u32 value, size_t bytesize)\r
77 {\r
78         u32 * d = (u32*) dest;\r
79 \r
80         size_t i;\r
81 \r
82         // loops unrolled to reduce the number of increments by factor ~8.\r
83         i = bytesize >> (2 + 3);\r
84         while (i)\r
85         {\r
86                 d[0] = value;\r
87                 d[1] = value;\r
88                 d[2] = value;\r
89                 d[3] = value;\r
90 \r
91                 d[4] = value;\r
92                 d[5] = value;\r
93                 d[6] = value;\r
94                 d[7] = value;\r
95 \r
96                 d += 8;\r
97                 i -= 1;\r
98         }\r
99 \r
100         i = (bytesize >> 2 ) & 7;\r
101         while (i)\r
102         {\r
103                 d[0] = value;\r
104                 d += 1;\r
105                 i -= 1;\r
106         }\r
107 }\r
108 \r
109 //! a more useful memset for pixel. dest must be aligned at least to 2 byte\r
110 // (standard memset only works with 8-bit values)\r
111 inline void memset16(void * dest, const u16 value, size_t bytesize)\r
112 {\r
113         u16 * d = (u16*) dest;\r
114 \r
115         size_t i;\r
116 \r
117         // loops unrolled to reduce the number of increments by factor ~8.\r
118         i = bytesize >> (1 + 3);\r
119         while (i)\r
120         {\r
121                 d[0] = value;\r
122                 d[1] = value;\r
123                 d[2] = value;\r
124                 d[3] = value;\r
125 \r
126                 d[4] = value;\r
127                 d[5] = value;\r
128                 d[6] = value;\r
129                 d[7] = value;\r
130 \r
131                 d += 8;\r
132                 --i;\r
133         }\r
134 \r
135         i = (bytesize >> 1 ) & 7;\r
136         while (i)\r
137         {\r
138                 d[0] = value;\r
139                 ++d;\r
140                 --i;\r
141         }\r
142 }\r
143 \r
144 //! memset interleaved\r
145 inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 height,const interlaced_control Interlaced)\r
146 {\r
147         if (Interlaced.bypass) return memset32(dest, value, pitch * height);\r
148 \r
149         u8* dst = (u8*)dest;\r
150         interlace_scanline_data line;\r
151         for (line.y = 0; line.y < height; line.y += SOFTWARE_DRIVER_2_STEP_Y)\r
152         {\r
153                 interlace_scanline_enabled memset32(dst, value, pitch);\r
154                 dst += pitch;\r
155         }\r
156 }\r
157 \r
158 // byte-align structures\r
159 #include "irrpack.h"\r
160 \r
161 //IEEE Standard for Floating - Point Arithmetic(IEEE 754)\r
162 typedef union {\r
163         float f;\r
164         unsigned int u;\r
165         struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields;\r
166         struct { unsigned int frac_exp:31; } abs;\r
167 } ieee754 PACK_STRUCT;\r
168 \r
169 // Default alignment\r
170 #include "irrunpack.h"\r
171 \r
172 // 0.5f as integer\r
173 #define ieee754_zero_dot_5      0x3f000000\r
174 #define ieee754_one                     0x3f800000\r
175 #define ieee754_two                     0x40000000\r
176 \r
177 #if 0\r
178 // integer log2 of a float ieee 754. [not used anymore]\r
179 static inline s32 s32_log2_f32( f32 f)\r
180 {\r
181         //u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127;\r
182         ieee754 _log2;\r
183         _log2.f = f;\r
184         return _log2.fields.exp ? _log2.fields.exp - 127 : 10000000; /*denormal very high number*/\r
185 }\r
186 #endif\r
187 \r
188 // integer log2 of an integer. returning 0 as denormal\r
189 static inline s32 s32_log2_s32(u32 in)\r
190 {\r
191         s32 ret = 0;\r
192         while (in > 1)\r
193         {\r
194                 in >>= 1;\r
195                 ret++;\r
196         }\r
197         return ret;\r
198         //return s32_log2_f32( (f32) x);\r
199         //ieee754 _log2;_log2.f = (f32) in; return _log2.fields.exp - 127;\r
200 }\r
201 \r
202 #if 0\r
203 static inline s32 s32_abs(s32 x)\r
204 {\r
205         s32 b = x >> 31;\r
206         return (x ^ b ) - b;\r
207 }\r
208 \r
209 \r
210 //! conditional set based on mask and arithmetic shift\r
211 REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )\r
212 {\r
213         return ( mask & ( a ^ b ) ) ^ b;\r
214 }\r
215 #endif\r
216 \r
217 // ------------------ Video---------------------------------------\r
218 /*!\r
219         Pixel = dest * ( 1 - alpha ) + source * alpha\r
220         alpha [0;256]\r
221 */\r
222 REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha )\r
223 {\r
224         u32 srcRB = c1 & 0x00FF00FF;\r
225         u32 srcXG = c1 & 0x0000FF00;\r
226 \r
227         u32 dstRB = c2 & 0x00FF00FF;\r
228         u32 dstXG = c2 & 0x0000FF00;\r
229 \r
230 \r
231         u32 rb = srcRB - dstRB;\r
232         u32 xg = srcXG - dstXG;\r
233 \r
234         rb *= alpha;\r
235         xg *= alpha;\r
236         rb >>= 8;\r
237         xg >>= 8;\r
238 \r
239         rb += dstRB;\r
240         xg += dstXG;\r
241 \r
242         rb &= 0x00FF00FF;\r
243         xg &= 0x0000FF00;\r
244 \r
245         return rb | xg;\r
246 }\r
247 \r
248 /*!\r
249         Pixel = dest * ( 1 - alpha ) + source * alpha\r
250         alpha [0;32]\r
251 */\r
252 inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha )\r
253 {\r
254         const u16 srcRB = c1 & 0x7C1F;\r
255         const u16 srcXG = c1 & 0x03E0;\r
256 \r
257         const u16 dstRB = c2 & 0x7C1F;\r
258         const u16 dstXG = c2 & 0x03E0;\r
259 \r
260         u32 rb = srcRB - dstRB;\r
261         u32 xg = srcXG - dstXG;\r
262 \r
263         rb *= alpha;\r
264         xg *= alpha;\r
265         rb >>= 5;\r
266         xg >>= 5;\r
267 \r
268         rb += dstRB;\r
269         xg += dstXG;\r
270 \r
271         rb &= 0x7C1F;\r
272         xg &= 0x03E0;\r
273 \r
274         return (u16)(rb | xg);\r
275 }\r
276 \r
277 /*\r
278         Pixel = c0 * (c1/31). c0 Alpha retain\r
279 */\r
280 inline u16 PixelMul16 ( const u16 c0, const u16 c1)\r
281 {\r
282         return (u16)((( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 ) |\r
283                         (( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 ) |\r
284                         (( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 ) |\r
285                         (c0 & 0x8000));\r
286 }\r
287 \r
288 /*\r
289         Pixel = c0 * (c1/31).\r
290 */\r
291 inline u16 PixelMul16_2 ( u16 c0, u16 c1)\r
292 {\r
293         return  (u16)(( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 |\r
294                         ( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 |\r
295                         ( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5  |\r
296                         ( c0 & c1 & 0x8000));\r
297 }\r
298 \r
299 /*\r
300         Pixel = c0 * (c1/255). c0 Alpha Retain\r
301 */\r
302 REALINLINE u32 PixelMul32 ( const u32 c0, const u32 c1)\r
303 {\r
304         return  (c0 & 0xFF000000) |\r
305                         (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) |\r
306                         (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) |\r
307                         (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8  ) & 0x000000FF);\r
308 }\r
309 \r
310 /*\r
311         Pixel = c0 * (c1/255).\r
312 */\r
313 REALINLINE u32 PixelMul32_2 ( const u32 c0, const u32 c1)\r
314 {\r
315         return  (( ( (c0 & 0xFF000000) >> 16 ) * ( (c1 & 0xFF000000) >> 16 ) ) & 0xFF000000 ) |\r
316                         (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) |\r
317                         (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) |\r
318                         (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8  ) & 0x000000FF);\r
319 }\r
320 \r
321 /*\r
322         Pixel = clamp ( c0 + c1, 0, 255 )\r
323 */\r
324 REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1)\r
325 {\r
326         u32 sum = ( c2 & 0x00FFFFFF )  + ( c1 & 0x00FFFFFF );\r
327         u32 low_bits = ( c2 ^ c1 ) & 0x00010101;\r
328         s32 carries  = ( sum - low_bits ) & 0x01010100;\r
329         u32 modulo = sum - carries;\r
330         u32 clamp = carries - ( carries >> 8 );\r
331         return modulo | clamp;\r
332 }\r
333 \r
334 #if 0\r
335 \r
336 // 1 - Bit Alpha Blending\r
337 inline u16 PixelBlend16 ( const u16 destination, const u16 source )\r
338 {\r
339         if((source & 0x8000) == 0x8000)\r
340                 return source; // The source is visible, so use it.\r
341         else\r
342                 return destination; // The source is transparent, so use the destination.\r
343 }\r
344 \r
345 // 1 - Bit Alpha Blending 16Bit SIMD\r
346 inline u32 PixelBlend16_simd ( const u32 destination, const u32 source )\r
347 {\r
348         switch(source & 0x80008000)\r
349         {\r
350                 case 0x80008000: // Both source pixels are visible\r
351                         return source;\r
352 \r
353                 case 0x80000000: // Only the first source pixel is visible\r
354                         return (source & 0xFFFF0000) | (destination & 0x0000FFFF);\r
355 \r
356                 case 0x00008000: // Only the second source pixel is visible.\r
357                         return (destination & 0xFFFF0000) | (source & 0x0000FFFF);\r
358 \r
359                 default: // Neither source pixel is visible.\r
360                         return destination;\r
361         }\r
362 }\r
363 #else\r
364 \r
365 // 1 - Bit Alpha Blending\r
366 inline u16 PixelBlend16 ( const u16 c2, const u16 c1 )\r
367 {\r
368         u16 mask = ((c1 & 0x8000) >> 15 ) + 0x7fff;\r
369         return (c2 & mask ) | ( c1 & ~mask );\r
370 }\r
371 \r
372 // 1 - Bit Alpha Blending 16Bit SIMD\r
373 inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 )\r
374 {\r
375         u32 mask = ((c1 & 0x80008000) >> 15 ) + 0x7fff7fff;\r
376         return (c2 & mask ) | ( c1 & ~mask );\r
377 }\r
378 \r
379 #endif\r
380 \r
381 /*!\r
382         Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha (OpenGL blending)\r
383 */\r
384 inline u32 PixelBlend32 ( const u32 c2, const u32 c1 )\r
385 {\r
386         // alpha test\r
387         u32 alpha = c1 & 0xFF000000;\r
388 \r
389         if ( 0 == alpha )\r
390                 return c2;\r
391         if ( 0xFF000000 == alpha )\r
392         {\r
393                 return c1;\r
394         }\r
395 \r
396         alpha >>= 24;\r
397 \r
398         // add highbit alpha, if ( alpha > 127 ) alpha += 1;\r
399         alpha += ( alpha >> 7);\r
400 \r
401         u32 srcRB = c1 & 0x00FF00FF;\r
402         u32 srcXG = c1 & 0x0000FF00;\r
403 \r
404         u32 dstRB = c2 & 0x00FF00FF;\r
405         u32 dstXG = c2 & 0x0000FF00;\r
406 \r
407 \r
408         u32 rb = srcRB - dstRB;\r
409         u32 xg = srcXG - dstXG;\r
410 \r
411         rb *= alpha;\r
412         xg *= alpha;\r
413         rb >>= 8;\r
414         xg >>= 8;\r
415 \r
416         rb += dstRB;\r
417         xg += dstXG;\r
418 \r
419         rb &= 0x00FF00FF;\r
420         xg &= 0x0000FF00;\r
421 \r
422         return (c1 & 0xFF000000) | rb | xg;\r
423 }\r
424 \r
425 \r
426 \r
427 // ------------------ Fix Point ----------------------------------\r
428 \r
429 #if defined(ENV64BIT)\r
430 typedef s32 tFixPoint;\r
431 typedef u32 tFixPointu;\r
432 #else\r
433 typedef s32 tFixPoint;\r
434 typedef u32 tFixPointu;\r
435 #endif\r
436 \r
437 // Fix Point 12 (overflow on s32)\r
438 #if 0\r
439         #define FIX_POINT_PRE                   12\r
440         #define FIX_POINT_FRACT_MASK    0xFFF\r
441         #define FIX_POINT_UNSIGNED_MASK 0x7FFFF000\r
442         #define FIX_POINT_ONE                   0x1000\r
443         #define FIX_POINT_ZERO_DOT_FIVE 0x0800\r
444         #define FIX_POINT_F32_MUL               4096.f\r
445 #endif\r
446 \r
447 // Fix Point 11 (overflow on s32)\r
448 #if 0\r
449         #define FIX_POINT_PRE                   11\r
450         #define FIX_POINT_FRACT_MASK    0x7FF\r
451         #define FIX_POINT_UNSIGNED_MASK 0xFFFFF800\r
452         #define FIX_POINT_ONE                   0x800\r
453         #define FIX_POINT_ZERO_DOT_FIVE 0x400\r
454         #define FIX_POINT_F32_MUL               2048.f\r
455 #endif\r
456 \r
457 // Fix Point 10\r
458 #if 1\r
459         #define FIX_POINT_PRE                   10\r
460         #define FIX_POINT_FRACT_MASK    0x000003FF\r
461         #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
462         #define FIX_POINT_ONE                   0x00000400\r
463         #define FIX_POINT_ZERO_DOT_FIVE 0x00000200\r
464         #define FIX_POINT_F32_MUL               1024.f\r
465 #endif\r
466 \r
467 // Fix Point 9\r
468 #if 0\r
469         #define FIX_POINT_PRE                   9\r
470         #define FIX_POINT_FRACT_MASK    0x1FF\r
471         #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
472         #define FIX_POINT_ONE                   0x200\r
473         #define FIX_POINT_ZERO_DOT_FIVE 0x100\r
474         #define FIX_POINT_F32_MUL               512.f\r
475 #endif\r
476 \r
477 // Fix Point 7\r
478 #if 0\r
479         #define FIX_POINT_PRE                   7\r
480         #define FIX_POINT_FRACT_MASK    0x7F\r
481         #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80\r
482         #define FIX_POINT_ONE                   0x80\r
483         #define FIX_POINT_ZERO_DOT_FIVE 0x40\r
484         #define FIX_POINT_F32_MUL               128.f\r
485 #endif\r
486 \r
487 #define FIXPOINT_COLOR_MAX              ( COLOR_MAX << FIX_POINT_PRE )\r
488 \r
489 #if   FIX_POINT_PRE == 10 && COLOR_MAX == 255\r
490         #define FIX_POINT_HALF_COLOR    0x1FE00\r
491         #define FIX_POINT_COLOR_ERROR   4\r
492 #elif FIX_POINT_PRE == 12 && COLOR_MAX == 255\r
493         #define FIX_POINT_HALF_COLOR    0x7F800\r
494         #define FIX_POINT_COLOR_ERROR   16\r
495 #elif FIX_POINT_PRE == 10 && COLOR_MAX == 31\r
496         #define FIX_POINT_HALF_COLOR    0x3E00\r
497         #define FIX_POINT_COLOR_ERROR   32\r
498 #else\r
499         #define FIX_POINT_HALF_COLOR    ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )\r
500         #define FIX_POINT_COLOR_ERROR   (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2))\r
501 #endif\r
502 \r
503 \r
504 /*\r
505         convert signed integer to fixpoint\r
506 */\r
507 inline tFixPoint s32_to_fixPoint (const s32 x)\r
508 {\r
509         return x << FIX_POINT_PRE;\r
510 }\r
511 \r
512 #if 0\r
513 inline tFixPointu u32_to_fixPoint (const u32 x)\r
514 {\r
515         return x << FIX_POINT_PRE;\r
516 }\r
517 #endif\r
518 \r
519 inline u32 fixPointu_to_u32 (const tFixPointu x)\r
520 {\r
521         return (u32)(x >> FIX_POINT_PRE);\r
522 }\r
523 \r
524 \r
525 // 1/x * FIX_POINT\r
526 #define fix_inverse32(x) (FIX_POINT_F32_MUL / (x))\r
527 #define fix_inverse32_color(x) ((FIX_POINT_F32_MUL*COLOR_MAX) / (x))\r
528 \r
529 \r
530 /*\r
531         convert float to fixpoint\r
532         fast convert (fistp on x86) HAS to be used..\r
533         hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different\r
534         others should use their favourite assembler..\r
535 */\r
536 #if 0\r
537 static inline int f_round2(f32 f)\r
538 {\r
539         f += (3<<22);\r
540         return IR(f) - 0x4b400000;\r
541 }\r
542 #endif\r
543 \r
544 /*\r
545         convert f32 to Fix Point.\r
546         multiply is needed anyway, so scale mulby\r
547 */\r
548 /*\r
549 REALINLINE tFixPoint tofix0 (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )\r
550 {\r
551         return (tFixPoint) (x * mulby);\r
552 }\r
553 */\r
554 #define tofix(x,y) (tFixPoint)(x * y)\r
555 \r
556 \r
557 /*\r
558         Fix Point , Fix Point Multiply\r
559 */\r
560 /*\r
561 REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)\r
562 {\r
563         return (x * y) >> (tFixPointu) FIX_POINT_PRE;\r
564 }\r
565 */\r
566 #define imulFixu(x,y) (((x) * (y)) >> (tFixPointu) FIX_POINT_PRE)\r
567 \r
568 \r
569 /*\r
570         Fix Point , Fix Point Multiply\r
571 */\r
572 REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)\r
573 {\r
574         return (x * y) >> FIX_POINT_PRE;\r
575 }\r
576 \r
577 #define imulFix_simple(x,y) ((x*y)>>FIX_POINT_PRE)\r
578 \r
579 #if 0\r
580 /*\r
581         Fix Point , Fix Point Multiply x * y * 2\r
582 */\r
583 REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)\r
584 {\r
585         return ( x * y) >> ( FIX_POINT_PRE -1 );\r
586 }\r
587 #endif\r
588 \r
589 /*\r
590         Multiply x * y * 1 FIXPOINT_COLOR_MAX\r
591 */\r
592 REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)\r
593 {\r
594 #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8\r
595         return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);\r
596 #else\r
597         return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);\r
598 #endif\r
599 }\r
600 \r
601 /*\r
602         Multiply x * y * 2\r
603 */\r
604 REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)\r
605 {\r
606         return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 );\r
607 }\r
608 \r
609 /*\r
610         Multiply x * y * 4 clamp\r
611 */\r
612 \r
613 REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)\r
614 {\r
615 #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8\r
616         tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);\r
617 #else\r
618         tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);\r
619 #endif\r
620         tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31;\r
621         return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask);\r
622 }\r
623 \r
624 \r
625 /*!\r
626         clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)\r
627 */\r
628 REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)\r
629 {\r
630         tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;\r
631         return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);\r
632 }\r
633 \r
634 \r
635 /*!\r
636         clamp FixPoint to 0 in FixPoint, max(a,0)\r
637 */\r
638 REALINLINE tFixPoint clampfix_mincolor ( const tFixPoint a)\r
639 {\r
640         return a - ( a & ( a >> 31 ) );\r
641 }\r
642 \r
643 REALINLINE tFixPoint saturateFix ( const tFixPoint a)\r
644 {\r
645         return clampfix_mincolor ( clampfix_maxcolor ( a ) );\r
646 }\r
647 \r
648 \r
649 #if 0\r
650 // rount fixpoint to int\r
651 inline s32 roundFix ( const tFixPoint x )\r
652 {\r
653         return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE);\r
654 }\r
655 #endif\r
656 \r
657 // x in [0;1[\r
658 #if 0\r
659 inline s32 f32_to_23Bits(const f32 x)\r
660 {\r
661         f32 y = x + 1.f;\r
662         return IR(y) & 0x7FFFFF;        // last 23 bits\r
663 }\r
664 #endif\r
665 \r
666 /*!\r
667         fixpoint in [0..Fixpoint_color] to VideoSample xrgb\r
668 */\r
669 REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
670 {\r
671         return  ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |\r
672                         ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
673                         ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |\r
674                         ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );\r
675 }\r
676 \r
677 \r
678 /*!\r
679         fixpoint to VideoSample argb\r
680         a in [0;1]\r
681         rgb in [0;255] colormax\r
682 */\r
683 REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
684 {\r
685         return  ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |\r
686                         ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
687                         ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |\r
688                         ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );\r
689 }\r
690 \r
691 /*!\r
692         return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
693 */\r
694 inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
695 {\r
696         (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );\r
697         (tFixPointu&) g =       (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
698         (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
699 }\r
700 \r
701 /*!\r
702         return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
703 */\r
704 inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
705 {\r
706         (tFixPointu&) a =       (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE );\r
707         (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );\r
708         (tFixPointu&) g =       (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
709         (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
710 }\r
711 \r
712 /*!\r
713         return fixpoint from VideoSample granularity 0..FIX_POINT_ONE\r
714 */\r
715 inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
716 {\r
717         (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
718         (tFixPointu&) g =       (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
719         (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
720 \r
721         //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
722         r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
723         g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
724         b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
725 }\r
726 \r
727 /*!\r
728         return fixpoint from VideoSample granularity 0..FIX_POINT_ONE\r
729 */\r
730 inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
731 {\r
732         (tFixPointu&) a =       (t00 & MASK_A) >> ( SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
733         (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
734         (tFixPointu&) g =       (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
735         (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
736 \r
737         //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
738         a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
739         r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
740         g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
741         b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
742 \r
743 }\r
744 \r
745 /*!\r
746         return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
747 */\r
748 inline void color_to_fix(tFixPoint c[4], const tVideoSample t00)\r
749 {\r
750         c[0] = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
751         c[1] = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
752         c[2] = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
753         c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
754 }\r
755 \r
756 /*!\r
757         return fixpoint from VideoSample granularity 0..FIX_POINT_ONE\r
758 */\r
759 inline void color_to_fix1(tFixPoint c[4], const tVideoSample t00)\r
760 {\r
761         c[0] = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
762         c[1] = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
763         c[2] = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
764         c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2);\r
765 \r
766         //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
767         c[0] += (c[0] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
768         c[1] += (c[1] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
769         c[2] += (c[2] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
770         c[3] += (c[3] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
771 \r
772 }\r
773 \r
774 \r
775 \r
776 //! ----- FP24 1.23 fix point z-buffer\r
777 \r
778 #if 1\r
779 typedef f32 fp24;\r
780 #else\r
781 struct fp24\r
782 {\r
783         u32 v;\r
784 \r
785         fp24() {}\r
786 \r
787         fp24 ( const f32 f )\r
788         {\r
789                 f32 y = f + 1.f;\r
790                 v = ((u32&)y) & 0x7FFFFF;       // last 23 bits\r
791         }\r
792 \r
793         void operator=(const f32 f )\r
794         {\r
795         f32 y = f + 1.f;\r
796                 v = ((u32&)y) & 0x7FFFFF;       // last 23 bits\r
797                 }\r
798 \r
799         void operator+=(const fp24 &other )\r
800         {\r
801                 v += other.v;\r
802         }\r
803 \r
804         operator f32 () const\r
805         {\r
806                 f32 r = FR ( v );\r
807                 return r + 1.f;\r
808         }\r
809 \r
810 };\r
811 #endif\r
812 \r
813 \r
814 // ------------------------ Internal Texture -----------------------------\r
815 \r
816 struct sInternalTexture\r
817 {\r
818         //power-of-two\r
819         void* data; //tVideoSample* Texture->lock(miplevel)\r
820         size_t textureXMask;\r
821         size_t textureYMask;\r
822 \r
823         size_t pitchlog2;\r
824 \r
825         video::CSoftwareTexture2 *Texture;\r
826         s32 lodFactor; // magnify/minify\r
827 };\r
828 \r
829 \r
830 \r
831 // get video sample plain\r
832 static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty )\r
833 {\r
834         size_t ofs;\r
835 \r
836         ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
837         ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );\r
838 \r
839         // texel\r
840         return *((tVideoSample*)( (u8*) t->data + ofs ));\r
841 }\r
842 \r
843 // get video sample to fix\r
844 inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
845                                                 const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
846                                                                 )\r
847 {\r
848         size_t ofs;\r
849 \r
850         ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
851         ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );\r
852 \r
853         // texel\r
854         tVideoSample t00;\r
855         t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
856 \r
857         r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
858         g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
859         b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
860 \r
861 }\r
862 \r
863 // get video sample to fixpoint colormax\r
864 inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
865         const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
866 )\r
867 {\r
868         size_t ofs;\r
869 \r
870         ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
871         ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
872 \r
873         // texel\r
874         tVideoSample t00;\r
875         t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
876 \r
877         a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
878         r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
879         g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
880         b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
881 \r
882 }\r
883 \r
884 #if 0\r
885 // get video sample to fixpoint\r
886 static REALINLINE void getTexel_fix ( tFixPoint &a,\r
887                         const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)\r
888 {\r
889         size_t ofs;\r
890 \r
891         ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
892         ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );\r
893 \r
894         // texel\r
895         tVideoSample t00;\r
896         t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
897 \r
898         a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
899 }\r
900 #endif\r
901 \r
902 /*\r
903         load a sample from internal texture at position tx,ty to fixpoint\r
904 */\r
905 #if defined(SOFTWARE_DRIVER_2_BILINEAR)\r
906 \r
907 #if 0\r
908 // texture2D in fixpoint color range bilinear\r
909 static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
910         const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
911 )\r
912 {\r
913 #if 0\r
914         if (t->lodFactor > 0)\r
915         {\r
916                 size_t ofs;\r
917 \r
918                 ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
919                 ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
920 \r
921                 // texel\r
922                 tVideoSample t00;\r
923                 t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
924 \r
925                 r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
926                 g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
927                 b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
928                 return;\r
929         }\r
930 #endif\r
931 \r
932         tFixPointu r00, g00, b00;\r
933         tFixPointu r01, g01, b01;\r
934         tFixPointu r10, g10, b10;\r
935         tFixPointu r11, g11, b11;\r
936 \r
937         size_t o0, o1, o2, o3;\r
938         tVideoSample t00;\r
939 \r
940         //wraps positive (ignoring negative)\r
941         o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
942         o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
943         o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
944         o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
945 \r
946         t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));\r
947         r00 = (t00 & MASK_R) >> SHIFT_R;\r
948         g00 = (t00 & MASK_G) >> SHIFT_G;\r
949         b00 = (t00 & MASK_B);\r
950 \r
951         t00 = *((tVideoSample*)((u8*)t->data + (o0 + o3)));\r
952         r10 = (t00 & MASK_R) >> SHIFT_R;\r
953         g10 = (t00 & MASK_G) >> SHIFT_G;\r
954         b10 = (t00 & MASK_B);\r
955 \r
956         t00 = *((tVideoSample*)((u8*)t->data + (o1 + o2)));\r
957         r01 = (t00 & MASK_R) >> SHIFT_R;\r
958         g01 = (t00 & MASK_G) >> SHIFT_G;\r
959         b01 = (t00 & MASK_B);\r
960 \r
961         t00 = *((tVideoSample*)((u8*)t->data + (o1 + o3)));\r
962         r11 = (t00 & MASK_R) >> SHIFT_R;\r
963         g11 = (t00 & MASK_G) >> SHIFT_G;\r
964         b11 = (t00 & MASK_B);\r
965 \r
966 \r
967         tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
968         tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
969 \r
970         //w00 w01 w10 w11\r
971         tFixPointu w[4];\r
972         w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
973         w[1] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
974         w[2] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
975         w[3] = imulFixu(fracx, fracy);\r
976 \r
977         r = (r00 * w[0]) +\r
978                 (r01 * w[1]) +\r
979                 (r10 * w[2]) +\r
980                 (r11 * w[3]);\r
981 \r
982         g = (g00 * w[0]) +\r
983                 (g01 * w[1]) +\r
984                 (g10 * w[2]) +\r
985                 (g11 * w[3]);\r
986 \r
987         b = (b00 * w[0]) +\r
988                 (b01 * w[1]) +\r
989                 (b10 * w[2]) +\r
990                 (b11 * w[3]);\r
991 \r
992 }\r
993 \r
994 #else\r
995 \r
996 // texture2D in fixpoint color range bilinear\r
997 static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
998         const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
999 )\r
1000 {\r
1001 #if 0\r
1002         if (tex->lodFactor > 1)\r
1003         {\r
1004                 //nearest neighbor\r
1005                 size_t ofs;\r
1006                 ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
1007                 ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1008 \r
1009                 tVideoSample t00;\r
1010                 t00 = *((tVideoSample*)((u8*)tex->data + ofs));\r
1011 \r
1012                 r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
1013                 g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
1014                 b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
1015                 return;\r
1016         }\r
1017 #endif\r
1018         //w00 w01 w10 w11\r
1019         tFixPointu w[4];\r
1020         {\r
1021                 tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
1022                 tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
1023                 w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
1024                 w[1] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
1025                 w[2] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
1026                 w[3] = imulFixu(fracx, fracy);\r
1027         }\r
1028 \r
1029         //wraps positive (ignoring negative)\r
1030         tVideoSample t[4];\r
1031         {\r
1032                 size_t o0, o1, o2, o3;\r
1033                 o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
1034                 o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
1035                 o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1036                 o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1037 \r
1038                 t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
1039                 t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
1040                 t[2] = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
1041                 t[3] = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
1042         }\r
1043 \r
1044         r = (((t[0] & MASK_R) >> SHIFT_R) * w[0]) +\r
1045                 (((t[1] & MASK_R) >> SHIFT_R) * w[1]) +\r
1046                 (((t[2] & MASK_R) >> SHIFT_R) * w[2]) +\r
1047                 (((t[3] & MASK_R) >> SHIFT_R) * w[3]);\r
1048 \r
1049         g = (((t[0] & MASK_G) >> SHIFT_G) * w[0]) +\r
1050                 (((t[1] & MASK_G) >> SHIFT_G) * w[1]) +\r
1051                 (((t[2] & MASK_G) >> SHIFT_G) * w[2]) +\r
1052                 (((t[3] & MASK_G) >> SHIFT_G) * w[3]);\r
1053 \r
1054         b = ((t[0] & MASK_B) * w[0]) +\r
1055                 ((t[1] & MASK_B) * w[1]) +\r
1056                 ((t[2] & MASK_B) * w[2]) +\r
1057                 ((t[3] & MASK_B) * w[3]);\r
1058 }\r
1059 \r
1060 #endif\r
1061 \r
1062 // get Sample bilinear\r
1063 static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
1064         const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
1065 )\r
1066 {\r
1067 \r
1068         tFixPointu a00, r00, g00, b00;\r
1069         tFixPointu a01, r01, g01, b01;\r
1070         tFixPointu a10, r10, g10, b10;\r
1071         tFixPointu a11, r11, g11, b11;\r
1072 \r
1073         size_t o0, o1, o2, o3;\r
1074         tVideoSample t00;\r
1075 \r
1076         o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
1077         o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
1078         o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1079         o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1080 \r
1081         t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
1082         a00 = (t00 & MASK_A) >> SHIFT_A;\r
1083         r00 = (t00 & MASK_R) >> SHIFT_R;\r
1084         g00 = (t00 & MASK_G) >> SHIFT_G;\r
1085         b00 = (t00 & MASK_B);\r
1086 \r
1087         t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
1088         a10 = (t00 & MASK_A) >> SHIFT_A;\r
1089         r10 = (t00 & MASK_R) >> SHIFT_R;\r
1090         g10 = (t00 & MASK_G) >> SHIFT_G;\r
1091         b10 = (t00 & MASK_B);\r
1092 \r
1093         t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
1094         a01 = (t00 & MASK_A) >> SHIFT_A;\r
1095         r01 = (t00 & MASK_R) >> SHIFT_R;\r
1096         g01 = (t00 & MASK_G) >> SHIFT_G;\r
1097         b01 = (t00 & MASK_B);\r
1098 \r
1099         t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
1100         a11 = (t00 & MASK_A) >> SHIFT_A;\r
1101         r11 = (t00 & MASK_R) >> SHIFT_R;\r
1102         g11 = (t00 & MASK_G) >> SHIFT_G;\r
1103         b11 = (t00 & MASK_B);\r
1104 \r
1105         const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;\r
1106         const tFixPointu txFractInv = FIX_POINT_ONE - txFract;\r
1107 \r
1108         const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;\r
1109         const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;\r
1110 \r
1111         const tFixPointu w00 = imulFixu(txFractInv, tyFractInv);\r
1112         const tFixPointu w10 = imulFixu(txFract, tyFractInv);\r
1113         const tFixPointu w01 = imulFixu(txFractInv, tyFract);\r
1114         const tFixPointu w11 = imulFixu(txFract, tyFract);\r
1115 \r
1116         a = (a00 * w00) +\r
1117                 (a01 * w01) +\r
1118                 (a10 * w10) +\r
1119                 (a11 * w11);\r
1120 \r
1121         fix_alpha_color_max(a);\r
1122 \r
1123         r = (r00 * w00) +\r
1124                 (r01 * w01) +\r
1125                 (r10 * w10) +\r
1126                 (r11 * w11);\r
1127 \r
1128         g = (g00 * w00) +\r
1129                 (g01 * w01) +\r
1130                 (g10 * w10) +\r
1131                 (g11 * w11);\r
1132 \r
1133         b = (b00 * w00) +\r
1134                 (b01 * w01) +\r
1135                 (b10 * w10) +\r
1136                 (b11 * w11);\r
1137 \r
1138 }\r
1139 \r
1140 #else // SOFTWARE_DRIVER_2_BILINEAR\r
1141 \r
1142 // get Sample linear == getSample_fixpoint\r
1143 \r
1144 static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
1145         const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
1146 )\r
1147 {\r
1148         size_t ofs;\r
1149         ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
1150         ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1151 \r
1152         // texel\r
1153         const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
1154 \r
1155         (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
1156         (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
1157         (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
1158 }\r
1159 \r
1160 static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
1161         const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
1162 )\r
1163 {\r
1164         size_t ofs;\r
1165         ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
1166         ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);\r
1167 \r
1168         // texel\r
1169         const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
1170 \r
1171         (tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
1172         fix_alpha_color_max(a);\r
1173         (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
1174         (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
1175         (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
1176 }\r
1177 \r
1178 \r
1179 #endif // SOFTWARE_DRIVER_2_BILINEAR\r
1180 \r
1181 \r
1182 // 2D Region closed [x0;x1]\r
1183 struct AbsRectangle\r
1184 {\r
1185         s32 x0;\r
1186         s32 y0;\r
1187         s32 x1;\r
1188         s32 y1;\r
1189 };\r
1190 \r
1191 //! 2D Intersection test\r
1192 inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRectangle& b)\r
1193 {\r
1194         dest.x0 = core::s32_max( a.x0, b.x0 );\r
1195         dest.y0 = core::s32_max( a.y0, b.y0 );\r
1196         dest.x1 = core::s32_min( a.x1, b.x1 );\r
1197         dest.y1 = core::s32_min( a.y1, b.y1 );\r
1198         return dest.x0 < dest.x1 && dest.y0 < dest.y1;\r
1199 }\r
1200 \r
1201 #if 0\r
1202 // some 1D defines\r
1203 struct sIntervall\r
1204 {\r
1205         s32 start;\r
1206         s32 end;\r
1207 };\r
1208 \r
1209 // returning intersection width\r
1210 inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b)\r
1211 {\r
1212         return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start );\r
1213 }\r
1214 \r
1215 #endif\r
1216 \r
1217 // strings\r
1218 static inline void tiny_strncpy(char* to, const char* from, const size_t count)\r
1219 {\r
1220         for (size_t r = 0; r < count && (*to = *from) != '\0'; ++from, ++to, ++r);\r
1221         *to = '\0';\r
1222 }\r
1223 \r
1224 #define tiny_strcpy(a, b) tiny_strncpy(a,b,sizeof(a)-1)\r
1225 \r
1226 \r
1227 // tiny_isequal = !strncmp(a,b,sizeof(a)-1)\r
1228 static inline int tiny_isequal(const char *s1, const char *s2, size_t n)\r
1229 {\r
1230         do {\r
1231                 if (*s1 != *s2++) return 0;\r
1232                 if (*s1++ == 0)\r
1233                         break;\r
1234         } while (--n != 0);\r
1235         return 1;\r
1236 }\r
1237 \r
1238 #define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0\r
1239 \r
1240 \r
1241 } // end namespace irr\r
1242 \r
1243 #endif\r
1244 \r