comparison ext/guichan-0.8.1/src/allegro/allegrographics.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/allegro/allegrographics.hpp"
49 #include "guichan/allegro/allegroimage.hpp"
50 #include "guichan/rectangle.hpp"
51 #include "guichan/exception.hpp"
52 #include "guichan/cliprectangle.hpp"
53 #include "guichan/color.hpp"
54
55 namespace gcn
56 {
57 AllegroGraphics::AllegroGraphics()
58 {
59 mTarget = NULL;
60 mClipNull = false;
61 }
62
63 AllegroGraphics::AllegroGraphics(BITMAP *target)
64 {
65 mTarget = target;
66 }
67
68 AllegroGraphics::~AllegroGraphics()
69 {
70 }
71
72 void AllegroGraphics::setTarget(BITMAP *target)
73 {
74 mTarget = target;
75 }
76
77 BITMAP *AllegroGraphics::getTarget()
78 {
79 return mTarget;
80 }
81
82 void AllegroGraphics::_beginDraw()
83 {
84 if (mTarget == NULL)
85 {
86 throw GCN_EXCEPTION("Target BITMAP is null, set it with setTarget first.");
87 }
88
89 // push a clip area the size of the target bitmap
90 pushClipArea(Rectangle(0, 0, mTarget->w, mTarget->h));
91 }
92
93 void AllegroGraphics::_endDraw()
94 {
95 // pop the clip area pushed in _beginDraw
96 popClipArea();
97 }
98
99 bool AllegroGraphics::pushClipArea(Rectangle area)
100 {
101 bool result = Graphics::pushClipArea(area);
102
103 const ClipRectangle& cr = mClipStack.top();
104
105 // Allegro won't let you set clip areas
106 // that have zero width or height
107 // so we have to check for that.
108 if (cr.width == 0 || cr.height == 0)
109 {
110 mClipNull = true;
111 }
112 else
113 {
114 mClipNull = false;
115 #if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0
116 set_clip(mTarget,
117 cr.x,
118 cr.y,
119 cr.x + cr.width - 1,
120 cr.y + cr.height - 1);
121 #else
122 set_clip_rect(mTarget,
123 cr.x,
124 cr.y,
125 cr.x + cr.width - 1,
126 cr.y + cr.height - 1);
127 #endif
128 }
129
130 return result;
131 }
132
133 void AllegroGraphics::popClipArea()
134 {
135 Graphics::popClipArea();
136
137 if (mClipStack.empty())
138 {
139 return;
140 }
141
142 const ClipRectangle& cr = mClipStack.top();
143
144 // Allegro won't let you set clip areas
145 //that have zero width or height
146 // so we have to check for that.
147 if (cr.width == 0 || cr.height == 0)
148 {
149 mClipNull = true;
150 }
151 else
152 {
153 mClipNull = false;
154 #if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0
155 set_clip(mTarget,
156 cr.x,
157 cr.y,
158 cr.x + cr.width - 1,
159 cr.y + cr.height - 1);
160 #else
161 set_clip_rect(mTarget,
162 cr.x,
163 cr.y,
164 cr.x + cr.width - 1,
165 cr.y + cr.height - 1);
166 #endif
167 }
168 }
169
170 void AllegroGraphics::drawImage(const Image* image,
171 int srcX,
172 int srcY,
173 int dstX,
174 int dstY,
175 int width,
176 int height)
177 {
178 if (mClipNull)
179 {
180 return;
181 }
182
183 if (mClipStack.empty())
184 {
185 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion "
186 "outside of _beginDraw() and _endDraw()?");
187 }
188
189 const int xOffset = mClipStack.top().xOffset;
190 const int yOffset = mClipStack.top().yOffset;
191
192 const AllegroImage* srcImage = dynamic_cast<const AllegroImage*>(image);
193
194 if (srcImage == NULL)
195 {
196 throw GCN_EXCEPTION("Trying to draw an image of unknown format, must be an AllegroImage.");
197 }
198
199 masked_blit(srcImage->getBitmap(),
200 mTarget,
201 srcX,
202 srcY,
203 dstX + xOffset,
204 dstY + yOffset,
205 width,
206 height);
207 }
208
209 void AllegroGraphics::drawPoint(int x, int y)
210 {
211 if (mClipNull)
212 {
213 return;
214 }
215
216 if (mClipStack.empty())
217 {
218 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion "
219 "outside of _beginDraw() and _endDraw()?");
220 }
221
222 const int xOffset = mClipStack.top().xOffset;
223 const int yOffset = mClipStack.top().yOffset;
224
225 putpixel(mTarget,
226 x + xOffset,
227 y + yOffset,
228 mAllegroColor);
229 }
230
231 void AllegroGraphics::drawLine(int x1, int y1, int x2, int y2)
232 {
233 if (mClipNull)
234 {
235 return;
236 }
237
238 if (mClipStack.empty())
239 {
240 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion "
241 "outside of _beginDraw() and _endDraw()?");
242 }
243
244 const int xOffset = mClipStack.top().xOffset;
245 const int yOffset = mClipStack.top().yOffset;
246
247 line(mTarget,
248 x1 + xOffset,
249 y1 + yOffset,
250 x2 + xOffset,
251 y2 + yOffset,
252 mAllegroColor);
253 }
254
255 void AllegroGraphics::drawRectangle(const Rectangle& rectangle)
256 {
257 if (mClipNull)
258 {
259 return;
260 }
261
262 if (mClipStack.empty())
263 {
264 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion "
265 "outside of _beginDraw() and _endDraw()?");
266 }
267
268 const int xOffset = mClipStack.top().xOffset;
269 const int yOffset = mClipStack.top().yOffset;
270
271 rect(mTarget,
272 rectangle.x + xOffset,
273 rectangle.y + yOffset,
274 rectangle.x + rectangle.width - 1 + xOffset,
275 rectangle.y + rectangle.height - 1 + yOffset,
276 mAllegroColor);
277 }
278
279 void AllegroGraphics::fillRectangle(const Rectangle& rectangle)
280 {
281 if (mClipNull)
282 {
283 return;
284 }
285
286 if (mClipStack.empty())
287 {
288 throw GCN_EXCEPTION("Clip stack is empty, perhaps you called a draw funtion "
289 "outside of _beginDraw() and _endDraw()?");
290 }
291
292 const int xOffset = mClipStack.top().xOffset;
293 const int yOffset = mClipStack.top().yOffset;
294
295 rectfill(mTarget,
296 rectangle.x + xOffset,
297 rectangle.y + yOffset,
298 rectangle.x + rectangle.width - 1 + xOffset,
299 rectangle.y + rectangle.height - 1 + yOffset,
300 mAllegroColor);
301 }
302
303 void AllegroGraphics::setColor(const Color& color)
304 {
305 mColor = color;
306 mAllegroColor = makecol(color.r, color.g, color.b);
307
308 if (color.a != 255)
309 {
310 set_trans_blender(255, 255, 255, color.a);
311 drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
312 }
313 else
314 {
315 solid_mode();
316 }
317 }
318
319 const Color& AllegroGraphics::getColor() const
320 {
321 return mColor;
322 }
323
324 int AllegroGraphics::getAllegroColor() const
325 {
326 return mAllegroColor;
327 }
328
329 void AllegroGraphics::drawBitmap(BITMAP* bitmap, int dstX, int dstY)
330 {
331 const int xOffset = mClipStack.top().xOffset;
332 const int yOffset = mClipStack.top().yOffset;
333
334 masked_blit(bitmap,
335 mTarget,
336 0,
337 0,
338 dstX + xOffset,
339 dstY + yOffset,
340 bitmap->w,
341 bitmap->h);
342 }
343 }