xref: /haiku/src/add-ons/screen_savers/nebula/Draw.c (revision 56430ad8002b8fd1ac69b590e9cc130de6d9e852)
1 /*
2  * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Copyright 2015, Augustin Cavalier <waddlesplash>. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  *
6  * Effect from corTeX / Optimum.
7  */
8 
9 #include <SupportDefs.h>
10 
11 #include "Draw.h"
12 
13 
14 // Hand-translated from x86 assembly.
15 /* memshset (char *dst, int center_shade,int fixed_shade, int length_2) */
16 /* dst is the *center* of the dst segment */
17 /* center shade is the initial color (at center) (!! 8:8 also) */
18 /* fixed_shade is the fixed point increment (8:8) */
19 /* length_2 is the 1/2 length to set (to the left, and to the right) */
20 
21 /* a memaddshadedset function (or something like that ) */
22 void memshset(char* dstParam, int center_shade, int fixed_shade, int half_length)
23 {
24 	unsigned char* dst;
25 	unsigned char* source;
26 	int offset;
27 
28 	if (half_length == 0)
29 		return;
30 
31 	dst = (unsigned char*)dstParam;
32 	source = dst;
33 	dst -= half_length; // Left segment
34 	source += half_length; // Right segment
35 	source++; // Don't overlap at middle
36 
37 	offset = half_length;
38 	offset = -offset;
39 	offset--; // For in-advance incl in loop
40 
41 	do {
42 		int tmp;
43 		center_shade += fixed_shade; // Increment color.
44 		center_shade &= 0xFFFF; // Mask so we can do overflow tests.
45 		offset++;
46 
47 		tmp = dst[half_length] + (center_shade >> 8); // Increment left pixel.
48 		// Did it overflow?
49 		if (tmp & 0xFF00)
50 			dst[half_length] = 255;
51 		else
52 			dst[half_length] = tmp;
53 
54 		tmp = source[offset] + (center_shade >> 8); // Increment right pixel.
55 		if (tmp & 0xFF00)
56 			source[offset] = 255;
57 		else
58 			source[offset] = tmp;
59 	} while (--half_length != 0);
60 }
61 
62 
63 /* do the "motion blur" (actually the pixel fading) */
64 void mblur(char* srcParam, int nbpixels)
65 {
66 	unsigned int clear1UpperBit = 0x7f7f7f7f;
67 	unsigned int clear3UpperBits = 0x1f1f1f1f;
68 	unsigned long* src = (unsigned long*)srcParam;
69 
70 	if ((nbpixels >>= 2) == 0)
71 		return;
72 
73 	do {
74 		long eax, ebx;
75 		eax = *src;
76 		src++;
77 
78 		ebx = eax;
79 		eax >>= 1;
80 
81 		ebx >>= 3;
82 		eax &= clear1UpperBit;
83 
84 		ebx &= clear3UpperBits;
85 
86 		eax += ebx;
87 		src[-1] = eax;
88 	} while (--nbpixels != 0);
89 }
90