1 /*
2 	Dirty rectangle markers
3 
4 	(C) 2006 ARAnyM developer team
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with this program; if not, write to the Free Software
18 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #include "SDL_compat.h"
22 #include <string.h>
23 
24 #include "dirty_rects.h"
25 
26 /*--- Constructor/destructor ---*/
27 
DirtyRects(int width,int height)28 DirtyRects::DirtyRects(int width, int height)
29 {
30 	dirtyMarker=NULL;
31 	resizeDirty(width,height);
32 }
33 
~DirtyRects(void)34 DirtyRects::~DirtyRects(void)
35 {
36 	if (dirtyMarker) {
37 		delete [] dirtyMarker;
38 	}
39 }
40 
41 /*--- Public functions ---*/
42 
resizeDirty(int width,int height)43 void DirtyRects::resizeDirty(int width, int height)
44 {
45 	if (dirtyMarker) {
46 		delete [] dirtyMarker;
47 	}
48 
49 	areaW = width;
50 	areaH = height;
51 
52 	dirtyW = width>>4;
53 	if (width & 15) {
54 		dirtyW++;
55 	}
56 	dirtyH = height>>4;
57 	if (height & 15) {
58 		dirtyH++;
59 	}
60 	dirtyMarker = new Uint8[dirtyW * dirtyH];
61 
62 	/* Will refresh everything */
63 	memset(dirtyMarker, 1, dirtyW * dirtyH);
64 	minDirtX = 0;
65 	minDirtY = 0;
66 	maxDirtX = areaW-1;
67 	maxDirtY = areaH-1;
68 }
69 
getDirtyRects(void)70 Uint8 *DirtyRects::getDirtyRects(void)
71 {
72 	return dirtyMarker;
73 }
74 
setDirtyRect(int x,int y,int w,int h)75 void DirtyRects::setDirtyRect(int x, int y, int w, int h)
76 {
77 	// adjust minDirt and maxDirt points
78 	if (x < minDirtX)
79 		minDirtX = x & 0xfffffff0;  // rounded down to multiple of 16
80 	if (y < minDirtY)
81 		minDirtY = y & 0xfffffff0;  // rounded down to multiple of 16
82 	if (x+w-1 > maxDirtX)
83 		maxDirtX = x+w-1;
84 	if (y+h-1 > maxDirtY)
85 		maxDirtY = y+h-1;
86 
87 	// mark affected area in our marker map as dirty
88 	int x2 = x+w;
89 	if (x2 & 15) {
90 		x2 = (x2|15)+1;
91 	}
92 	x2>>=4;
93 	int y2 = y+h;
94 	if (y2 & 15) {
95 		y2 = (y2|15)+1;
96 	}
97 	y2>>=4;
98 	int x1 = x>>4, y1 = y>>4;
99 
100 	for (y=y1;y<y2;y++) {
101 		for(x=x1;x<x2;x++) {
102 			if ((x>=0) && (x<dirtyW) && (y>=0) && (y<dirtyH)) {
103 				dirtyMarker[y*dirtyW+x]=1;
104 			}
105 		}
106 	}
107 }
108 
setDirtyLine(int x1,int y1,int x2,int y2)109 void DirtyRects::setDirtyLine(int x1, int y1, int x2, int y2)
110 {
111 	int min_x,min_y, max_x, max_y;
112 	if (x1<=x2) {
113 		min_x=x1;
114 		max_x=x2;
115 	}
116 	else {
117 		min_x=x2;
118 		max_x=x1;
119 	}
120 	if (y1<=y2) {
121 		min_y=y1;
122 		max_y=y2;
123 	}
124 	else {
125 		min_y=y2;
126 		max_y=y1;
127 	}
128 	setDirtyRect(min_x,min_y,max_x-min_x+1,max_y-min_y+1);
129 }
130 
131 
clearDirtyRects(void)132 void DirtyRects::clearDirtyRects(void)
133 {
134 	// clear marker map
135 	memset(dirtyMarker, 0, dirtyW * dirtyH);
136 
137 	// reset dirt points
138 	minDirtX = areaW;
139 	minDirtY = areaH;
140 	maxDirtX = 0;
141 	maxDirtY = 0;
142 }
143 
hasDirtyRect(void)144 bool DirtyRects::hasDirtyRect(void)
145 {
146 	return minDirtX<=maxDirtX;
147 }
148 
149 
getDirtyWidth(void)150 int DirtyRects::getDirtyWidth(void)
151 {
152 	return dirtyW;
153 }
154 
getDirtyHeight(void)155 int DirtyRects::getDirtyHeight(void)
156 {
157 	return dirtyH;
158 }
159 
getMinDirtX(void)160 int DirtyRects::getMinDirtX(void)
161 {
162 	return minDirtX;
163 }
164 
getMinDirtY(void)165 int DirtyRects::getMinDirtY(void)
166 {
167 	return minDirtY;
168 }
169 
getMaxDirtX(void)170 int DirtyRects::getMaxDirtX(void)
171 {
172 	return maxDirtX;
173 }
174 
getMaxDirtY(void)175 int DirtyRects::getMaxDirtY(void)
176 {
177 	return maxDirtY;
178 }
179