aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h1042
1 files changed, 1042 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h
new file mode 100644
index 0000000..263548b
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/SoftwareDriver2_helper.h
@@ -0,0 +1,1042 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5/*
6 History:
7 - changed behavior for log2 textures ( replaced multiplies by shift )
8*/
9
10#ifndef __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__
11#define __S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED__
12
13#include "SoftwareDriver2_compile_config.h"
14#include "irrMath.h"
15#include "CSoftwareTexture2.h"
16#include "SMaterial.h"
17
18
19
20namespace irr
21{
22
23// supporting different packed pixel needs many defines...
24
25#ifdef SOFTWARE_DRIVER_2_32BIT
26 typedef u32 tVideoSample;
27
28 #define MASK_A 0xFF000000
29 #define MASK_R 0x00FF0000
30 #define MASK_G 0x0000FF00
31 #define MASK_B 0x000000FF
32
33 #define SHIFT_A 24
34 #define SHIFT_R 16
35 #define SHIFT_G 8
36 #define SHIFT_B 0
37
38 #define COLOR_MAX 0xFF
39 #define COLOR_MAX_LOG2 8
40 #define COLOR_BRIGHT_WHITE 0xFFFFFFFF
41
42 #define VIDEO_SAMPLE_GRANULARITY 2
43
44#else
45 typedef u16 tVideoSample;
46
47 #define MASK_A 0x8000
48 #define MASK_R 0x7C00
49 #define MASK_G 0x03E0
50 #define MASK_B 0x001F
51
52 #define SHIFT_A 15
53 #define SHIFT_R 10
54 #define SHIFT_G 5
55 #define SHIFT_B 0
56
57 #define COLOR_MAX 0x1F
58 #define COLOR_MAX_LOG2 5
59 #define COLOR_BRIGHT_WHITE 0xFFFF
60 #define VIDEO_SAMPLE_GRANULARITY 1
61
62#endif
63
64
65
66
67// ----------------------- Generic ----------------------------------
68
69//! a more useful memset for pixel
70// (standard memset only works with 8-bit values)
71inline void memset32(void * dest, const u32 value, u32 bytesize)
72{
73 u32 * d = (u32*) dest;
74
75 u32 i;
76
77 // loops unrolled to reduce the number of increments by factor ~8.
78 i = bytesize >> (2 + 3);
79 while (i)
80 {
81 d[0] = value;
82 d[1] = value;
83 d[2] = value;
84 d[3] = value;
85
86 d[4] = value;
87 d[5] = value;
88 d[6] = value;
89 d[7] = value;
90
91 d += 8;
92 i -= 1;
93 }
94
95 i = (bytesize >> 2 ) & 7;
96 while (i)
97 {
98 d[0] = value;
99 d += 1;
100 i -= 1;
101 }
102}
103
104//! a more useful memset for pixel
105// (standard memset only works with 8-bit values)
106inline void memset16(void * dest, const u16 value, u32 bytesize)
107{
108 u16 * d = (u16*) dest;
109
110 u32 i;
111
112 // loops unrolled to reduce the number of increments by factor ~8.
113 i = bytesize >> (1 + 3);
114 while (i)
115 {
116 d[0] = value;
117 d[1] = value;
118 d[2] = value;
119 d[3] = value;
120
121 d[4] = value;
122 d[5] = value;
123 d[6] = value;
124 d[7] = value;
125
126 d += 8;
127 --i;
128 }
129
130 i = (bytesize >> 1 ) & 7;
131 while (i)
132 {
133 d[0] = value;
134 ++d;
135 --i;
136 }
137}
138
139/*
140 use biased loop counter
141 --> 0 byte copy is forbidden
142*/
143REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize )
144{
145 u32 c = bytesize >> 2;
146
147 do
148 {
149 ((u32*) dest ) [ c-1 ] = ((u32*) source) [ c-1 ];
150 } while ( --c );
151
152}
153
154
155
156// integer log2 of a float ieee 754. TODO: non ieee floating point
157static inline s32 s32_log2_f32( f32 f)
158{
159 u32 x = IR ( f );
160 return ((x & 0x7F800000) >> 23) - 127;
161}
162
163static inline s32 s32_log2_s32(u32 x)
164{
165 return s32_log2_f32( (f32) x);
166}
167
168static inline s32 s32_abs(s32 x)
169{
170 s32 b = x >> 31;
171 return (x ^ b ) - b;
172}
173
174
175//! conditional set based on mask and arithmetic shift
176REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )
177{
178 return ( mask & ( a ^ b ) ) ^ b;
179}
180
181// ------------------ Video---------------------------------------
182/*!
183 Pixel = dest * ( 1 - alpha ) + source * alpha
184 alpha [0;256]
185*/
186REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )
187{
188 u32 srcRB = c1 & 0x00FF00FF;
189 u32 srcXG = c1 & 0x0000FF00;
190
191 u32 dstRB = c2 & 0x00FF00FF;
192 u32 dstXG = c2 & 0x0000FF00;
193
194
195 u32 rb = srcRB - dstRB;
196 u32 xg = srcXG - dstXG;
197
198 rb *= alpha;
199 xg *= alpha;
200 rb >>= 8;
201 xg >>= 8;
202
203 rb += dstRB;
204 xg += dstXG;
205
206 rb &= 0x00FF00FF;
207 xg &= 0x0000FF00;
208
209 return rb | xg;
210}
211
212/*!
213 Pixel = dest * ( 1 - alpha ) + source * alpha
214 alpha [0;32]
215*/
216inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u16 alpha )
217{
218 const u16 srcRB = c1 & 0x7C1F;
219 const u16 srcXG = c1 & 0x03E0;
220
221 const u16 dstRB = c2 & 0x7C1F;
222 const u16 dstXG = c2 & 0x03E0;
223
224 u32 rb = srcRB - dstRB;
225 u32 xg = srcXG - dstXG;
226
227 rb *= alpha;
228 xg *= alpha;
229 rb >>= 5;
230 xg >>= 5;
231
232 rb += dstRB;
233 xg += dstXG;
234
235 rb &= 0x7C1F;
236 xg &= 0x03E0;
237
238 return (u16)(rb | xg);
239}
240
241/*
242 Pixel = c0 * (c1/31). c0 Alpha retain
243*/
244inline u16 PixelMul16 ( const u16 c0, const u16 c1)
245{
246 return (u16)((( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 ) |
247 (( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 ) |
248 (( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 ) |
249 (c0 & 0x8000));
250}
251
252/*
253 Pixel = c0 * (c1/31).
254*/
255inline u16 PixelMul16_2 ( u16 c0, u16 c1)
256{
257 return (u16)(( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 |
258 ( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 |
259 ( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 |
260 ( c0 & c1 & 0x8000));
261}
262
263/*
264 Pixel = c0 * (c1/255). c0 Alpha Retain
265*/
266REALINLINE u32 PixelMul32 ( const u32 c0, const u32 c1)
267{
268 return (c0 & 0xFF000000) |
269 (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) |
270 (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) |
271 (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF);
272}
273
274/*
275 Pixel = c0 * (c1/255).
276*/
277REALINLINE u32 PixelMul32_2 ( const u32 c0, const u32 c1)
278{
279 return (( ( (c0 & 0xFF000000) >> 16 ) * ( (c1 & 0xFF000000) >> 16 ) ) & 0xFF000000 ) |
280 (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) |
281 (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) |
282 (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF);
283}
284
285/*
286 Pixel = clamp ( c0 + c1, 0, 255 )
287*/
288REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1)
289{
290 u32 sum = ( c2 & 0x00FFFFFF ) + ( c1 & 0x00FFFFFF );
291 u32 low_bits = ( c2 ^ c1 ) & 0x00010101;
292 s32 carries = ( sum - low_bits ) & 0x01010100;
293 u32 modulo = sum - carries;
294 u32 clamp = carries - ( carries >> 8 );
295 return modulo | clamp;
296}
297
298#if 0
299
300// 1 - Bit Alpha Blending
301inline u16 PixelBlend16 ( const u16 destination, const u16 source )
302{
303 if((source & 0x8000) == 0x8000)
304 return source; // The source is visible, so use it.
305 else
306 return destination; // The source is transparent, so use the destination.
307}
308
309// 1 - Bit Alpha Blending 16Bit SIMD
310inline u32 PixelBlend16_simd ( const u32 destination, const u32 source )
311{
312 switch(source & 0x80008000)
313 {
314 case 0x80008000: // Both source pixels are visible
315 return source;
316
317 case 0x80000000: // Only the first source pixel is visible
318 return (source & 0xFFFF0000) | (destination & 0x0000FFFF);
319
320 case 0x00008000: // Only the second source pixel is visible.
321 return (destination & 0xFFFF0000) | (source & 0x0000FFFF);
322
323 default: // Neither source pixel is visible.
324 return destination;
325 }
326}
327#else
328
329// 1 - Bit Alpha Blending
330inline u16 PixelBlend16 ( const u16 c2, const u16 c1 )
331{
332 u16 mask = ((c1 & 0x8000) >> 15 ) + 0x7fff;
333 return (c2 & mask ) | ( c1 & ~mask );
334}
335
336// 1 - Bit Alpha Blending 16Bit SIMD
337inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 )
338{
339 u32 mask = ((c1 & 0x80008000) >> 15 ) + 0x7fff7fff;
340 return (c2 & mask ) | ( c1 & ~mask );
341}
342
343#endif
344
345/*!
346 Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha
347*/
348inline u32 PixelBlend32 ( const u32 c2, const u32 c1 )
349{
350 // alpha test
351 u32 alpha = c1 & 0xFF000000;
352
353 if ( 0 == alpha )
354 return c2;
355
356 if ( 0xFF000000 == alpha )
357 {
358 return c1;
359 }
360
361 alpha >>= 24;
362
363 // add highbit alpha, if ( alpha > 127 ) alpha += 1;
364 alpha += ( alpha >> 7);
365
366 u32 srcRB = c1 & 0x00FF00FF;
367 u32 srcXG = c1 & 0x0000FF00;
368
369 u32 dstRB = c2 & 0x00FF00FF;
370 u32 dstXG = c2 & 0x0000FF00;
371
372
373 u32 rb = srcRB - dstRB;
374 u32 xg = srcXG - dstXG;
375
376 rb *= alpha;
377 xg *= alpha;
378 rb >>= 8;
379 xg >>= 8;
380
381 rb += dstRB;
382 xg += dstXG;
383
384 rb &= 0x00FF00FF;
385 xg &= 0x0000FF00;
386
387 return (c1 & 0xFF000000) | rb | xg;
388}
389
390
391
392// ------------------ Fix Point ----------------------------------
393
394typedef s32 tFixPoint;
395typedef u32 tFixPointu;
396
397// Fix Point 12
398#if 0
399 #define FIX_POINT_PRE 12
400 #define FIX_POINT_FRACT_MASK 0xFFF
401 #define FIX_POINT_SIGNED_MASK 0xFFFFF000
402 #define FIX_POINT_UNSIGNED_MASK 0x7FFFF000
403 #define FIX_POINT_ONE 0x1000
404 #define FIX_POINT_ZERO_DOT_FIVE 0x0800
405 #define FIX_POINT_F32_MUL 4096.f
406#endif
407
408// Fix Point 10
409#if 1
410 #define FIX_POINT_PRE 10
411 #define FIX_POINT_FRACT_MASK 0x3FF
412 #define FIX_POINT_SIGNED_MASK 0xFFFFFC00
413 #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00
414 #define FIX_POINT_ONE 0x400
415 #define FIX_POINT_ZERO_DOT_FIVE 0x200
416 #define FIX_POINT_F32_MUL 1024.f
417#endif
418
419// Fix Point 9
420#if 0
421 #define FIX_POINT_PRE 9
422 #define FIX_POINT_FRACT_MASK 0x1FF
423 #define FIX_POINT_SIGNED_MASK 0xFFFFFE00
424 #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00
425 #define FIX_POINT_ONE 0x200
426 #define FIX_POINT_ZERO_DOT_FIVE 0x100
427 #define FIX_POINT_F32_MUL 512.f
428#endif
429
430// Fix Point 7
431#if 0
432 #define FIX_POINT_PRE 7
433 #define FIX_POINT_FRACT_MASK 0x7F
434 #define FIX_POINT_SIGNED_MASK 0xFFFFFF80
435 #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80
436 #define FIX_POINT_ONE 0x80
437 #define FIX_POINT_ZERO_DOT_FIVE 0x40
438 #define FIX_POINT_F32_MUL 128.f
439#endif
440
441#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE )
442#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )
443
444
445/*
446 convert signed integer to fixpoint
447*/
448inline tFixPoint s32_to_fixPoint (const s32 x)
449{
450 return x << FIX_POINT_PRE;
451}
452
453inline tFixPointu u32_to_fixPoint (const u32 x)
454{
455 return x << FIX_POINT_PRE;
456}
457
458inline u32 fixPointu_to_u32 (const tFixPointu x)
459{
460 return x >> FIX_POINT_PRE;
461}
462
463
464// 1/x * FIX_POINT
465REALINLINE f32 fix_inverse32 ( const f32 x )
466{
467 return FIX_POINT_F32_MUL / x;
468}
469
470
471/*
472 convert float to fixpoint
473 fast convert (fistp on x86) HAS to be used..
474 hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different
475 others should use their favourite assembler..
476*/
477static inline int f_round2(f32 f)
478{
479 f += (3<<22);
480 return IR(f) - 0x4b400000;
481}
482
483/*
484 convert f32 to Fix Point.
485 multiply is needed anyway, so scale mulby
486*/
487REALINLINE tFixPoint tofix (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )
488{
489 return (tFixPoint) (x * mulby);
490}
491
492
493/*
494 Fix Point , Fix Point Multiply
495*/
496REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)
497{
498 return (x * y) >> (tFixPointu) FIX_POINT_PRE;
499}
500
501/*
502 Fix Point , Fix Point Multiply
503*/
504REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)
505{
506 return ( x * y) >> ( FIX_POINT_PRE );
507}
508
509/*
510 Fix Point , Fix Point Multiply x * y * 2
511*/
512REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
513{
514 return ( x * y) >> ( FIX_POINT_PRE -1 );
515}
516
517
518/*
519 Multiply x * y * 1
520*/
521REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)
522{
523 return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 4 );
524}
525
526/*
527 Multiply x * y * 2
528*/
529REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
530{
531 return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 );
532}
533
534/*
535 Multiply x * y * 4
536*/
537REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
538{
539#ifdef SOFTWARE_DRIVER_2_32BIT
540 return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 );
541#else
542 return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) );
543#endif
544}
545
546/*!
547 clamp FixPoint to maxcolor in FixPoint, min(a,31)
548*/
549REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)
550{
551 tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;
552 return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);
553}
554
555/*!
556 clamp FixPoint to 0 in FixPoint, max(a,0)
557*/
558REALINLINE tFixPoint clampfix_mincolor ( const tFixPoint a)
559{
560 return a - ( a & ( a >> 31 ) );
561}
562
563REALINLINE tFixPoint saturateFix ( const tFixPoint a)
564{
565 return clampfix_mincolor ( clampfix_maxcolor ( a ) );
566}
567
568
569// rount fixpoint to int
570inline s32 roundFix ( const tFixPoint x )
571{
572 return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE;
573}
574
575
576
577// x in [0;1[
578inline s32 f32_to_23Bits(const f32 x)
579{
580 f32 y = x + 1.f;
581 return IR(y) & 0x7FFFFF; // last 23 bits
582}
583
584/*!
585 return VideoSample from fixpoint
586*/
587REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b )
588{
589#ifdef __BIG_ENDIAN__
590 return FIXPOINT_COLOR_MAX |
591 ( r & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - 8) |
592 ( g & FIXPOINT_COLOR_MAX) << ( 16 - FIX_POINT_PRE ) |
593 ( b & FIXPOINT_COLOR_MAX) << ( 24 - FIX_POINT_PRE );
594#else
595 return ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |
596 ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
597 ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |
598 ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );
599#endif
600}
601
602
603/*!
604 return VideoSample from fixpoint
605*/
606REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )
607{
608#ifdef __BIG_ENDIAN__
609 return ( a & (FIX_POINT_FRACT_MASK - 1 )) >> ( FIX_POINT_PRE ) |
610 ( r & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - 8) |
611 ( g & FIXPOINT_COLOR_MAX) << ( 16 - FIX_POINT_PRE ) |
612 ( b & FIXPOINT_COLOR_MAX) << ( 24 - FIX_POINT_PRE );
613#else
614 return ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |
615 ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
616 ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |
617 ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );
618#endif
619
620}
621
622/*!
623 return fixpoint from VideoSample granularity COLOR_MAX
624*/
625inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
626{
627 (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );
628 (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
629 (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
630}
631
632/*!
633 return fixpoint from VideoSample granularity COLOR_MAX
634*/
635inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
636{
637 (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE );
638 (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );
639 (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
640 (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
641}
642
643/*!
644 return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
645*/
646inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
647{
648 (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );
649 (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
650 (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
651}
652
653/*!
654 return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
655*/
656inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
657{
658 (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE );
659 (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );
660 (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
661 (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
662}
663
664
665
666// ----- FP24 ---- floating point z-buffer
667
668#if 1
669typedef f32 fp24;
670#else
671struct fp24
672{
673 u32 v;
674
675 fp24() {}
676
677 fp24 ( const f32 f )
678 {
679 f32 y = f + 1.f;
680 v = ((u32&)y) & 0x7FFFFF; // last 23 bits
681 }
682
683 void operator=(const f32 f )
684 {
685 f32 y = f + 1.f;
686 v = ((u32&)y) & 0x7FFFFF; // last 23 bits
687 }
688
689 void operator+=(const fp24 &other )
690 {
691 v += other.v;
692 }
693
694 operator f32 () const
695 {
696 f32 r = FR ( v );
697 return r + 1.f;
698 }
699
700};
701#endif
702
703
704// ------------------------ Internal Texture -----------------------------
705
706struct sInternalTexture
707{
708 u32 textureXMask;
709 u32 textureYMask;
710
711 u32 pitchlog2;
712 void *data;
713
714 video::CSoftwareTexture2 *Texture;
715 s32 lodLevel;
716};
717
718
719
720// get video sample plain
721inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty )
722{
723 u32 ofs;
724
725 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
726 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
727
728 // texel
729 return *((tVideoSample*)( (u8*) t->data + ofs ));
730}
731
732// get video sample to fix
733inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
734 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
735 )
736{
737 u32 ofs;
738
739 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
740 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
741
742 // texel
743 tVideoSample t00;
744 t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
745
746 r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
747 g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
748 b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
749
750}
751
752// get video sample to fixpoint
753REALINLINE void getTexel_fix ( tFixPoint &a,
754 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
755 )
756{
757 u32 ofs;
758
759 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
760 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
761
762 // texel
763 tVideoSample t00;
764 t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
765
766 a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
767}
768
769
770inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
771 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty,
772 const u32 x, const u32 y
773 )
774{
775 static const tFixPointu dithermask[] =
776 {
777 0x00,0x80,0x20,0xa0,
778 0xc0,0x40,0xe0,0x60,
779 0x30,0xb0,0x10,0x90,
780 0xf0,0x70,0xd0,0x50
781 };
782
783 const u32 index = (y & 3 ) << 2 | (x & 3);
784
785 const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask;
786 const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask;
787
788 u32 ofs;
789 ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2;
790 ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
791
792 // texel
793 const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
794
795 (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
796 (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
797 (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
798
799}
800
801/*
802 load a sample from internal texture at position tx,ty to fixpoint
803*/
804#ifndef SOFTWARE_DRIVER_2_BILINEAR
805
806// get Sample linear == getSample_fixpoint
807
808inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
809 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
810 )
811{
812 u32 ofs;
813
814 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
815 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
816
817 // texel
818 const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
819
820 (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
821 (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
822 (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
823}
824
825inline void getSample_texture ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b,
826 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
827 )
828{
829 u32 ofs;
830
831 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
832 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
833
834 // texel
835 const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
836
837 (tFixPointu &)a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
838 (tFixPointu &)r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
839 (tFixPointu &)g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
840 (tFixPointu &)b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
841}
842
843
844#else
845
846
847// get sample linear
848REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b,
849 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
850 )
851{
852 u32 ofs;
853
854 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
855 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
856
857 // texel
858 tVideoSample t00;
859 t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
860
861 r = (t00 & MASK_R) >> SHIFT_R;
862 g = (t00 & MASK_G) >> SHIFT_G;
863 b = (t00 & MASK_B);
864}
865
866// get Sample bilinear
867REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
868 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
869 )
870{
871
872 tFixPointu r00,g00,b00;
873 tFixPointu r01,g01,b01;
874 tFixPointu r10,g10,b10;
875 tFixPointu r11,g11,b11;
876
877#if 0
878 getSample_linear ( r00, g00, b00, t, tx,ty );
879 getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty );
880 getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE );
881 getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );
882#else
883 u32 o0, o1,o2,o3;
884 tVideoSample t00;
885
886 o0 = ( ( (ty) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
887 o1 = ( ( (ty+FIX_POINT_ONE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
888 o2 = ( (tx) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
889 o3 = ( (tx+FIX_POINT_ONE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
890
891 t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o2 ) ));
892 r00 = (t00 & MASK_R) >> SHIFT_R; g00 = (t00 & MASK_G) >> SHIFT_G; b00 = (t00 & MASK_B);
893
894 t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o3 ) ));
895 r10 = (t00 & MASK_R) >> SHIFT_R; g10 = (t00 & MASK_G) >> SHIFT_G; b10 = (t00 & MASK_B);
896
897 t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o2 ) ));
898 r01 = (t00 & MASK_R) >> SHIFT_R; g01 = (t00 & MASK_G) >> SHIFT_G; b01 = (t00 & MASK_B);
899
900 t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o3 ) ));
901 r11 = (t00 & MASK_R) >> SHIFT_R; g11 = (t00 & MASK_G) >> SHIFT_G; b11 = (t00 & MASK_B);
902
903#endif
904
905 const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;
906 const tFixPointu txFractInv = FIX_POINT_ONE - txFract;
907
908 const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;
909 const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;
910
911 const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );
912 const tFixPointu w10 = imulFixu ( txFract , tyFractInv );
913 const tFixPointu w01 = imulFixu ( txFractInv, tyFract );
914 const tFixPointu w11 = imulFixu ( txFract , tyFract );
915
916 r = (r00 * w00 ) +
917 (r01 * w01 ) +
918 (r10 * w10 ) +
919 (r11 * w11 );
920
921 g = (g00 * w00 ) +
922 (g01 * w01 ) +
923 (g10 * w10 ) +
924 (g11 * w11 );
925
926 b = (b00 * w00 ) +
927 (b01 * w01 ) +
928 (b10 * w10 ) +
929 (b11 * w11 );
930
931}
932
933
934// get sample linear
935REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b,
936 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
937 )
938{
939 u32 ofs;
940
941 ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
942 ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
943
944 // texel
945 tVideoSample t00;
946 t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
947
948 a = (t00 & MASK_A) >> SHIFT_A;
949 r = (t00 & MASK_R) >> SHIFT_R;
950 g = (t00 & MASK_G) >> SHIFT_G;
951 b = (t00 & MASK_B);
952}
953
954// get Sample bilinear
955REALINLINE void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
956 const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
957 )
958{
959
960 tFixPointu a00, r00,g00,b00;
961 tFixPointu a01, r01,g01,b01;
962 tFixPointu a10, r10,g10,b10;
963 tFixPointu a11, r11,g11,b11;
964
965 getSample_linear ( a00, r00, g00, b00, t, tx,ty );
966 getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty );
967 getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE );
968 getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );
969
970 const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;
971 const tFixPointu txFractInv = FIX_POINT_ONE - txFract;
972
973 const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;
974 const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;
975
976 const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );
977 const tFixPointu w10 = imulFixu ( txFract , tyFractInv );
978 const tFixPointu w01 = imulFixu ( txFractInv, tyFract );
979 const tFixPointu w11 = imulFixu ( txFract , tyFract );
980
981 a = (a00 * w00 ) +
982 (a01 * w01 ) +
983 (a10 * w10 ) +
984 (a11 * w11 );
985
986 r = (r00 * w00 ) +
987 (r01 * w01 ) +
988 (r10 * w10 ) +
989 (r11 * w11 );
990
991 g = (g00 * w00 ) +
992 (g01 * w01 ) +
993 (g10 * w10 ) +
994 (g11 * w11 );
995
996 b = (b00 * w00 ) +
997 (b01 * w01 ) +
998 (b10 * w10 ) +
999 (b11 * w11 );
1000
1001}
1002
1003
1004#endif
1005
1006// some 2D Defines
1007struct AbsRectangle
1008{
1009 s32 x0;
1010 s32 y0;
1011 s32 x1;
1012 s32 y1;
1013};
1014
1015//! 2D Intersection test
1016inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRectangle& b)
1017{
1018 dest.x0 = core::s32_max( a.x0, b.x0 );
1019 dest.y0 = core::s32_max( a.y0, b.y0 );
1020 dest.x1 = core::s32_min( a.x1, b.x1 );
1021 dest.y1 = core::s32_min( a.y1, b.y1 );
1022 return dest.x0 < dest.x1 && dest.y0 < dest.y1;
1023}
1024
1025// some 1D defines
1026struct sIntervall
1027{
1028 s32 start;
1029 s32 end;
1030};
1031
1032// returning intersection width
1033inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b)
1034{
1035 return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start );
1036}
1037
1038
1039} // end namespace irr
1040
1041#endif
1042