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