comparison ext/guichan-0.8.2/src/hge/hgegraphics.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
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 }