1 /***************************************************************************
2                           effects.c -  Special graphics effects for XRally
3                              -------------------
4     begin                : Sat Jan 1 2000
5     copyright            : (C) 2000 by Perdig
6     email                : perdig@linuxbr.com.br
7 
8     $Id: effects.c,v 1.1 2000/11/25 14:48:53 perdig Exp $
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19 #include "global.h"
20 #include "graphics.h"
21 #include "effects.h"
22 
23 static int _lookup_blend_cache(blend_cache_t *, unsigned long *pixel);
24 static void _add_blend_cache(blend_cache_t *, unsigned long old_pix, unsigned long new_pix);
25 
init_blend_cache(blend_cache_t * _cache)26 void init_blend_cache(blend_cache_t *_cache) {
27 	XColor temp;
28 	// Lookup the color pixel value (is always good)
29 	alloc_color(&_cache->color);
30 	// Init the first node (uses the value of pixel 0)
31 	_cache->node = (node_t *)malloc(sizeof(node_t) * 1);
32 	_cache->node->old_pix = 0;
33 	temp.pixel = 0;
34 	query_color(&temp);
35 	temp.red = temp.red*(100-_cache->factor)/100 + _cache->color.red*_cache->factor/100;
36   temp.blue = temp.blue*(100-_cache->factor)/100+ _cache->color.blue*_cache->factor/100;
37 	temp.green = temp.green*(100-_cache->factor)/100 + _cache->color.green*_cache->factor/100;
38 	alloc_color(&temp);
39 	_cache->node->new_pix = temp.pixel;
40 	_cache->node->next = NULL;
41 }
42 
free_blend_cache(blend_cache_t * _cache)43 void free_blend_cache(blend_cache_t *_cache) {
44 	node_t *anode, *bnode;
45 	if (!_cache->node) {
46 		hdbg("This cache wasn't initialized!");
47 		return;
48 	}
49 	anode = _cache->node;
50 	while (anode->next) {
51 		bnode = anode->next;
52 		free(anode);
53 		anode = bnode;
54 	}
55 	free(anode);
56 	_cache->node = NULL;
57 }
58 
_lookup_blend_cache(blend_cache_t * _cache,unsigned long * _pixel)59 static int _lookup_blend_cache(blend_cache_t *_cache, unsigned long *_pixel) {
60 	node_t *node;
61 	node = _cache->node;
62 	if (!node) {
63 		hdbg("This cache wasn't initialized!");
64 		return -1;
65 	}
66 	while (node->next != NULL) {
67 		if (node->old_pix == *_pixel) {
68 			*_pixel = node->new_pix;
69 			return 0;
70 		}
71 		else
72 			node = node->next;
73 	}
74 	return 1;
75 }
76 
_add_blend_cache(blend_cache_t * _cache,unsigned long old_pix,unsigned long new_pix)77 static void _add_blend_cache(blend_cache_t *_cache, unsigned long old_pix, unsigned long new_pix) {
78 	node_t *node;
79 	node_t *t_node;
80 	node = _cache->node;
81 	if (!node) {
82 		hdbg("This cache wasn't initialized!");
83 		return;
84 	}
85 	while (node->next != NULL)
86 		node = node->next;
87 	t_node = (node_t *)malloc(sizeof(node_t));
88 	t_node->old_pix = old_pix;
89 	t_node->new_pix = new_pix;
90 	t_node->next = NULL;
91 	node->next = t_node;
92 }
93 
blend_image(Pixmap pix,int x,int y,int w,int h,blend_cache_t * cache)94 XImage *blend_image(Pixmap pix, int x, int y, int w, int h, blend_cache_t *cache) {
95 	XImage *window;
96 	XColor color;
97 	node_t *node = cache->node;
98 	unsigned long old_pix;
99 	if (!node) {
100 		hdbg("This cache wasn't initialized!");
101 		return NULL;
102 	}
103 	ldbg("Starting to blend...");
104 	window = get_image(pix, x, y, w, h);
105 	//XInitImage(window);
106 	for (y = 0; y < window->height; y++) {
107 		for (x = 0; x < window->width; x++) {
108   		color.pixel = get_pixel(window, x, y);
109 			if (_lookup_blend_cache(cache, &color.pixel) != 0) {
110 				old_pix = color.pixel;
111 				query_color(&color);
112 				// Blend is the amount of the blend color, not the old color
113 				color.red = color.red*(100-cache->factor)/100 + cache->color.red*cache->factor/100;
114 				color.blue = color.blue*(100-cache->factor)/100+ cache->color.blue*cache->factor/100;
115 				color.green = color.green*(100-cache->factor)/100 + cache->color.green*cache->factor/100;
116 				alloc_color(&color);
117 				_add_blend_cache(cache, old_pix, color.pixel);
118 			}
119 			put_pixel(window, x, y, color.pixel);
120 		}
121 	}
122 	return window;
123 }
124 
125