1 /*
2 * Kuklomenos
3 * Copyright (C) 2008-2009 Martin Bays <mbays@sdf.lonestar.org>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/.
17 */
18
19 #include <algorithm>
20 #include <SDL/SDL.h>
21 #include <SDL_gfxPrimitivesDirty.h>
22
23 #include "coords.h"
24 #include "gfx.h"
25 #include "geom.h"
26 #include "settings.h"
27
View(CartCoord icentre,float izoom,float iangle)28 View::View(CartCoord icentre, float izoom, float iangle) :
29 centre(icentre), zoom(izoom), angle(iangle) {}
30
coord(const CartCoord & c) const31 ScreenCoord View::coord(const CartCoord &c) const
32 {
33 RelCartCoord d( (c-centre).rotated(angle) );
34 return ScreenCoord(
35 screenGeom.centre.x+(int)(d.dx*zoom),
36 screenGeom.centre.y-(int)(d.dy*zoom));
37 }
38
inView(const CartCoord & c,float in) const39 bool View::inView(const CartCoord &c, float in) const
40 {
41 RelCartCoord d = c-centre;
42 return ( (zoom*zoom)*(d.dx*d.dx+d.dy*d.dy) <= (screenGeom.rad-in)*(screenGeom.rad-in) );
43 }
44
draw(SDL_Surface * surface,const View & view,View * boundView,bool noAA)45 int Line::draw(SDL_Surface* surface, const View& view, View* boundView, bool noAA)
46 {
47 ScreenCoord s = view.coord(start);
48 ScreenCoord e = view.coord(end);
49 const bool useAA = ( (settings.useAA==AA_YES && !noAA) ||
50 settings.useAA==AA_FORCE );
51
52 Uint32 drawColour = colour;
53
54 if (!boundView || (boundView->inView(start) && boundView->inView(end)))
55 return ( useAA ? aalineColor : lineColor )
56 (surface, s.x, s.y, e.x, e.y, drawColour);
57 else
58 return 0;
59 }
60
draw(SDL_Surface * surface,const View & view,View * boundView,bool noAA)61 int Circle::draw(SDL_Surface* surface, const View& view, View* boundView, bool noAA)
62 {
63 bool useAA = ( (settings.useAA==AA_YES && !noAA) ||
64 settings.useAA==AA_FORCE );
65 ScreenCoord c = view.coord(centre);
66 float screenRad = r*view.zoom;
67
68 if (screenRad > 2*screenGeom.rad)
69 // our AA circle algorithm doesn't handle huge circles well
70 useAA = false;
71
72 if (!boundView || boundView->inView(centre, r*boundView->zoom))
73 return (filled ? filledCircleColor :
74 useAA ? aacircleColor : circleColor)
75 (surface, c.x, c.y, int(screenRad), colour);
76 else
77 return 0;
78 }
79
draw(SDL_Surface * surface,const View & view,View * boundView,bool noAA)80 int Polygon::draw(SDL_Surface* surface, const View& view, View* boundView, bool noAA)
81 {
82 const bool useAA = ( (settings.useAA==AA_YES && !noAA) ||
83 settings.useAA==AA_FORCE );
84
85 for (int i=0; i<n; i++)
86 {
87 if (boundView && !boundView->inView(points[i]))
88 return 0;
89 }
90
91 Sint16 *sx = new Sint16[n];
92 Sint16 *sy = new Sint16[n];
93 int ret;
94
95 for (int i=0; i<n; i++)
96 {
97 ScreenCoord s = view.coord(points[i]);
98 sx[i] = s.x;
99 sy[i] = s.y;
100 }
101
102 ret = ( filled ? filledPolygonColor :
103 useAA ? aapolygonColor : polygonColor )(
104 surface, sx, sy, n, colour);
105
106 delete[] sx;
107 delete[] sy;
108 return ret;
109 }
110
draw(SDL_Surface * surface,const View & view,View * boundView,bool noAA)111 int Pixel::draw(SDL_Surface* surface, const View& view, View* boundView, bool noAA)
112 {
113 if (boundView && !boundView->inView(point))
114 return 0;
115 else
116 {
117 ScreenCoord c = view.coord(point);
118 return pixelColor(surface, c.x, c.y, colour);
119 }
120 }
121