Mercurial > fife-parpg
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 } |