1 /*
2 
3 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4 	and the "Aleph One" developers.
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 3 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	This license is contained in the file "COPYING",
17 	which is included with this source code; it is available online at
18 	http://www.gnu.org/licenses/gpl.html
19 
20 */
21 
22 /*
23  *  Crosshairs_SDL.cpp - Crosshairs display, SDL implementation
24  */
25 
26 #include "cseries.h"
27 #include "Crosshairs.h"
28 #include "screen_drawing.h"
29 #include "world.h" // for struct world_point2d :(
30 
31 
32 /*
33  *  Crosshairs status
34  */
35 
36 extern bool use_lua_hud_crosshairs;
37 
38 static bool _Crosshairs_IsActive = false;
39 
Crosshairs_IsActive(void)40 bool Crosshairs_IsActive(void)
41 {
42 	return _Crosshairs_IsActive;
43 }
44 
Crosshairs_SetActive(bool NewState)45 bool Crosshairs_SetActive(bool NewState)
46 {
47 	return _Crosshairs_IsActive = NewState;
48 }
49 
50 
51 /*
52  *  Draw crosshairs in center of surface
53  */
54 
Crosshairs_Render(SDL_Surface * s)55 bool Crosshairs_Render(SDL_Surface *s)
56 {
57 	if (!_Crosshairs_IsActive)
58 		return false;
59 	if (use_lua_hud_crosshairs)
60 		return false;
61 
62 	// Get the crosshair data
63 	CrosshairData &Crosshairs = GetCrosshairData();
64 
65 	// Get color
66 	uint32 pixel = SDL_MapRGB(s->format, Crosshairs.Color.red >> 8, Crosshairs.Color.green >> 8, Crosshairs.Color.blue >> 8);
67 
68 	// Get coordinates
69 	int xcen = s->w / 2 - 1, ycen = s->h / 2 - 1;
70 
71 	if (Crosshairs.Shape == CHShape_RealCrosshairs)
72 	{
73 
74 		// Left
75 		SDL_Rect r = {xcen - Crosshairs.FromCenter - Crosshairs.Length, ycen - Crosshairs.Thickness / 2, Crosshairs.Length, Crosshairs.Thickness};
76 		SDL_FillRect(s, &r, pixel);
77 
78 		// Right
79 		r.x = xcen + Crosshairs.FromCenter;
80 		SDL_FillRect(s, &r, pixel);
81 
82 		// Top
83 		r.x = xcen - Crosshairs.Thickness / 2;
84 		r.y = ycen - Crosshairs.FromCenter - Crosshairs.Length;
85 		r.w = Crosshairs.Thickness;
86 		r.h = Crosshairs.Length;
87 		SDL_FillRect(s, &r, pixel);
88 
89 		// Bottom
90 		r.y = ycen + Crosshairs.FromCenter;
91 		SDL_FillRect(s, &r, pixel);
92 	}
93 	else if (Crosshairs.Shape == CHShape_Circle)
94 	{
95 
96 		// This will really be an octagon, for OpenGL-rendering convenience
97 
98 		// Precalculate the line endpoints, for convenience
99 
100 		short octa_points[2][6];
101 		short len;
102 
103 		len = Crosshairs.Length;
104 		octa_points[0][0] = xcen - len;
105 		octa_points[0][5] = xcen + len;
106 		octa_points[1][0] = ycen - len;
107 		octa_points[1][5] = ycen + len;
108 
109 		len = len / 2;
110 		octa_points[0][1] = xcen - len;
111 		octa_points[0][4] = xcen + len;
112 		octa_points[1][1] = ycen - len;
113 		octa_points[1][4] = ycen + len;
114 
115 		len = std::min(len, Crosshairs.FromCenter);
116 		octa_points[0][2] = xcen - len;
117 		octa_points[0][3] = xcen + len;
118 		octa_points[1][2] = ycen - len;
119 		octa_points[1][3] = ycen + len;
120 
121 		// We need to do 12 line segments, so we do them in 2*2*3 fashion
122 		for (int ix = 0; ix < 2; ix++)
123 		{
124 			int ixi = (ix > 0) ? 5 : 0;
125 			int ixid = (ix > 0) ? -1 : 1;
126 			for (int iy = 0; iy < 2; iy++)
127 			{
128 				int iyi = (iy > 0) ? 5 : 0;
129 				int iyid = (iy > 0) ? -1 : 1;
130 
131 				world_point2d p1;
132 				world_point2d p2;
133 
134 				// Vertical
135 				p1.x = octa_points[0][ixi];
136 				p1.y = octa_points[1][iyi + 2 * iyid];
137 				p2.x = octa_points[0][ixi];
138 				p2.y = octa_points[1][iyi+iyid];
139 
140 				draw_line(s, &p1, &p2, pixel, Crosshairs.Thickness);
141 
142 				// Diagonal
143 				p1 = p2;
144 				p2.x = octa_points[0][ixi+ixid];
145 				p2.y = octa_points[1][iyi];
146 				draw_line(s, &p1, &p2, pixel, Crosshairs.Thickness);
147 
148 				// Horizontal
149 				p1 = p2;
150 				p2.x = octa_points[0][ixi + 2*ixid];
151 				p2.y = octa_points[1][iyi];
152 				draw_line(s, &p1, &p2, pixel, Crosshairs.Thickness);
153 			}
154 		}
155 	}
156 
157 	return true;
158 }
159