comparison ext/guichan-0.8.1/src/hge/hgegraphics.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/hge/hgegraphics.hpp"
49
50 #include "guichan/cliprectangle.hpp"
51 #include "guichan/exception.hpp"
52 #include "guichan/rectangle.hpp"
53 #include "guichan/hge/hgeimage.hpp"
54
55 namespace gcn
56 {
57 HGE *HGEGraphics::mHGE = NULL;
58
59 HGEGraphics::HGEGraphics()
60 :mClipNull(false)
61 {
62 mHGE = hgeCreate(HGE_VERSION);
63
64 mHardwareColor = 0;
65 }
66
67 HGEGraphics::~HGEGraphics()
68 {
69 mHGE->Release();
70 }
71
72 void HGEGraphics::_beginDraw()
73 {
74 pushClipArea(Rectangle(0,
75 0,
76 mHGE->System_GetState(HGE_SCREENWIDTH),
77 mHGE->System_GetState(HGE_SCREENHEIGHT)));
78 }
79
80 void HGEGraphics::_endDraw()
81 {
82 // pop the clip area pushed in _beginDraw
83 popClipArea();
84 }
85
86 bool HGEGraphics::pushClipArea(Rectangle area)
87 {
88 bool result = Graphics::pushClipArea(area);
89
90 const ClipRectangle top = mClipStack.top();
91
92 // HGE won't let you set clip areas
93 // that have zero width or height
94 // so we have to check for that.
95 if (top.width == 0 || top.height == 0)
96 {
97 mClipNull = true;
98 }
99 else
100 {
101 mClipNull = false;
102 mHGE->Gfx_SetTransform(top.xOffset,
103 top.yOffset);
104 mHGE->Gfx_SetClipping(top.x,
105 top.y,
106 top.width,
107 top.height);
108 }
109 return result;
110 }
111
112 void HGEGraphics::popClipArea()
113 {
114 Graphics::popClipArea();
115
116 if (mClipStack.empty())
117 {
118 mHGE->Gfx_SetClipping();
119
120 return;
121 }
122 else
123 {
124 const ClipRectangle top = mClipStack.top();
125
126 // HGE won't let you set clip areas
127 //that have zero width or height
128 // so we have to check for that.
129 if (top.width == 0 || top.height == 0)
130 {
131 mClipNull = true;
132 }
133 else
134 {
135 mClipNull = false;
136 mHGE->Gfx_SetTransform(top.xOffset,
137 top.yOffset);
138 mHGE->Gfx_SetClipping(top.x,
139 top.y,
140 top.width,
141 top.height);
142 }
143 }
144 }
145
146 void HGEGraphics::drawImage(const Image *image,
147 int srcX,
148 int srcY,
149 int dstX,
150 int dstY,
151 int width,
152 int height)
153 {
154 if (mClipNull)
155 {
156 return;
157 }
158
159 const HGEImage *hgeImage = static_cast<const HGEImage*>(image);
160
161 if (hgeImage == NULL)
162 {
163 throw GCN_EXCEPTION("Trying to draw an image of unknown format, must be an HGEImage.");
164 }
165
166 ClipRectangle const top = mClipStack.top();
167
168 dstX += top.xOffset;
169 dstY += top.yOffset;
170
171 hgeImage->getSprite()->SetTextureRect(srcX, srcY, width, height);
172 hgeImage->getSprite()->Render(dstX, dstY);
173 }
174
175 void HGEGraphics::drawImage(const Image *image, int dstX, int dstY)
176 {
177 if (mClipNull)
178 {
179 return;
180 }
181
182 drawImage(image, 0, 0, dstX, dstY, image->getWidth(), image->getHeight());
183 }
184
185 void HGEGraphics::drawPoint(int x, int y)
186 {
187 if (mClipNull)
188 {
189 return;
190 }
191
192 ClipRectangle const top = mClipStack.top();
193
194 x += top.xOffset;
195 y += top.yOffset;
196
197 mHGE->Gfx_RenderLine(x, y, x + 1, y, mHardwareColor);
198 }
199
200 void HGEGraphics::drawLine(int x1, int y1, int x2, int y2)
201 {
202 if (mClipNull)
203 {
204 return;
205 }
206
207 // As HGE omits the last pixel we need to adjust the coordinates
208 // before drawing the line. If it's a vertical or horizontal line
209 // all we have to do is add the omitted pixel.
210 if (y1 == y2 || x1 == x2)
211 {
212 x2++;
213 y2++;
214 }
215 // If it's not a vertical or horizontal line it gets a little bit
216 // trickier.
217 else
218 {
219 // If y2 is greater than y1 then we know y2 will be omitted as
220 // it will be a part of the last pixel coordinate.
221 if (y2 > y1)
222 {
223 y2++;
224 }
225 // Else will y1 be omitted.
226 else
227 {
228 y1++;
229 }
230 // The same thing applies for the x coordinates. If x2 is greater
231 // than x1 then we know x2 will be omitted as it will be a part of
232 // the last pixel coordinate.
233 if (x2 > x1)
234 {
235 x2++;
236 }
237 // Else will x1 be omitted.
238 else
239 {
240 x1++;
241 }
242 }
243
244 ClipRectangle const top = mClipStack.top();
245
246 x1 += top.xOffset;
247 y1 += top.yOffset;
248 x2 += top.xOffset;
249 y2 += top.yOffset;
250
251 mHGE->Gfx_RenderLine(x1, y1, x2, y2, mHardwareColor);
252 }
253
254 void HGEGraphics::drawRectangle(const Rectangle &rectangle)
255 {
256 if (mClipNull)
257 {
258 return;
259 }
260
261 int x1 = rectangle.x;
262 int y1 = rectangle.y;
263 int x2 = rectangle.x + rectangle.width;
264 int y2 = rectangle.y + rectangle.height;
265
266 ClipRectangle const top = mClipStack.top();
267
268 x1 += top.xOffset;
269 y1 += top.yOffset;
270 x2 += top.xOffset;
271 y2 += top.yOffset;
272
273 mHGE->Gfx_RenderLine(x1, y1 + 1, x2, y1, mHardwareColor);
274 mHGE->Gfx_RenderLine(x2, y1 + 1, x2, y2 - 1, mHardwareColor);
275 mHGE->Gfx_RenderLine(x2, y2, x1 + 1, y2, mHardwareColor);
276 mHGE->Gfx_RenderLine(x1 + 1, y2, x1 + 1, y1 + 1, mHardwareColor);
277 }
278
279 void HGEGraphics::fillRectangle(const Rectangle &rectangle)
280 {
281 if (mClipNull)
282 {
283 return;
284 }
285
286 // We need to compensate for the fact that HGE doesn't
287 // seem to include the the coordinate pixels when rendering
288 // a quad.
289 int x1 = rectangle.x;
290 int y1 = rectangle.y;
291 int x2 = rectangle.x + rectangle.width;
292 int y2 = rectangle.y + rectangle.height;
293
294 ClipRectangle const top = mClipStack.top();
295
296 x1 += top.xOffset;
297 y1 += top.yOffset;
298 x2 += top.xOffset;
299 y2 += top.yOffset;
300
301 hgeQuad quad;
302
303 quad.tex = NULL;
304
305 quad.v[0].x = x1;
306 quad.v[0].y = y1;
307 quad.v[0].col = mHardwareColor;
308
309 quad.v[1].x = x2;
310 quad.v[1].y = y1;
311 quad.v[1].col = mHardwareColor;
312
313 quad.v[2].x = x2;
314 quad.v[2].y = y2;
315 quad.v[2].col = mHardwareColor;
316
317 quad.v[3].x = x1;
318 quad.v[3].y = y2;
319 quad.v[3].col = mHardwareColor;
320
321 int i;
322 for (i = 0; i < 4; ++i)
323 {
324 quad.v[i].z = 0.5f;
325 }
326
327 quad.blend = BLEND_DEFAULT;
328
329 mHGE->Gfx_RenderQuad(&quad);
330 }
331
332 void HGEGraphics::setColor(const Color &color)
333 {
334 mColor = color;
335
336 mHardwareColor = ARGB(color.a, color.r, color.g, color.b);
337 }
338
339 const Color& HGEGraphics::getColor() const
340 {
341 return mColor;
342 }
343 }