1 /*=============================================================================
2 Blobby Volley 2
3 Copyright (C) 2006 Jonathan Sieber (jonathan_sieber@yahoo.de)
4 Copyright (C) 2006 Daniel Knobe (daniel-knobe@web.de)
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 2 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 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 =============================================================================*/
20 
21 /* header include */
22 #include "RenderManager.h"
23 
24 /* includes */
25 #include "FileRead.h"
26 
27 /* implementation */
28 RenderManager* RenderManager::mSingleton = 0;
29 
RenderManager()30 RenderManager::RenderManager() : mDrawGame(false)
31 {
32 	//assert(!mSingleton);
33 	if (mSingleton)
34 	{
35 		mSingleton->deinit();
36 		delete mSingleton;
37 	}
38 
39 	mSingleton = this;
40 	mMouseMarkerPosition = -100.0;
41 	mNeedRedraw = true;
42 }
43 
highlightSurface(SDL_Surface * surface,int luminance)44 SDL_Surface* RenderManager::highlightSurface(SDL_Surface* surface, int luminance)
45 {
46 	SDL_Surface *newSurface = createEmptySurface(surface->w, surface->h);
47 	SDL_SetColorKey(surface, SDL_FALSE, 0);
48 	SDL_BlitSurface(surface, 0, newSurface, 0);
49 	SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(newSurface->format, 0, 0, 0));
50 
51 	Uint8 alpha;
52 	SDL_GetSurfaceAlphaMod(surface, &alpha);
53 	SDL_SetSurfaceAlphaMod(newSurface, alpha);
54 	SDL_SetColorKey(newSurface, SDL_TRUE, SDL_MapRGB(newSurface->format, 0, 0, 0));
55 
56 	SDL_LockSurface(newSurface);
57 	for (int y = 0; y < surface->h; ++y)
58 	{
59 		for (int x = 0; x < surface->w; ++x)
60 		{
61 			// this seems overly complicated:
62 			// aren't we just calculating newSurface->pixels + (y * newSurface->w + x)
63 			SDL_Color* pixel = &( ((SDL_Color*)newSurface->pixels)[y * newSurface->w + x] );
64 			Uint32 colorKey;
65 			SDL_GetColorKey(surface, &colorKey);
66 			// we index newSurface->pixels once as Uint32[] and once as SDL_Color[], so these must have the same size
67 			static_assert( sizeof(Uint32) == sizeof(SDL_Color), "Uint32 must have the same size as SDL_Color" );
68 
69 			if (colorKey != ((Uint32*)newSurface->pixels)[y * newSurface->w +x])
70 			{
71 				pixel->r = pixel->r + luminance > 255 ? 255 : pixel->r + luminance;
72 				pixel->g = pixel->g + luminance > 255 ? 255 : pixel->g + luminance;
73 				pixel->b = pixel->b + luminance > 255 ? 255 : pixel->b + luminance;
74 			}
75 		}
76 	}
77 	SDL_UnlockSurface(newSurface);
78 	// no DisplayFormatAlpha, because of problems with
79 	// OpenGL RenderManager
80 	return newSurface;
81 }
82 
loadSurface(std::string filename)83 SDL_Surface* RenderManager::loadSurface(std::string filename)
84 {
85 	FileRead file(filename);
86 	int fileLength = file.length();
87 
88 	// just read the whole file
89 	boost::shared_array<char> fileContent = file.readRawBytes(fileLength);
90 
91 	SDL_RWops* rwops = SDL_RWFromMem(fileContent.get(), fileLength);
92 	SDL_Surface* newSurface = SDL_LoadBMP_RW(rwops , 1);
93 
94 	if (!newSurface)
95 		BOOST_THROW_EXCEPTION ( FileLoadException(filename) );
96 
97 	return newSurface;
98 }
99 
100 
createEmptySurface(unsigned int width,unsigned int height)101 SDL_Surface* RenderManager::createEmptySurface(unsigned int width, unsigned int height)
102 {
103 	SDL_Surface* newSurface = SDL_CreateRGBSurface(0, width, height, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000);
104 
105 	return newSurface;
106 }
107 
getNextFontIndex(std::string::const_iterator & iter)108 int RenderManager::getNextFontIndex(std::string::const_iterator& iter)
109 {
110 	int index = 47;
111 	wchar_t testChar = *iter;
112 	++iter;
113 	if (testChar >= '0' && testChar <= '9')
114 		index = testChar - '0';
115 	else if (testChar >= 'a' && testChar <= 'z')
116 		index = testChar - 'a' + 10;
117 	else if (testChar >= 'A' && testChar <= 'Z')
118 		index = testChar - 'A' + 10;
119 	else if (testChar == '.')
120 		index = 36;
121 	else if (testChar == '!')
122 		index = 37;
123 	else if (testChar == '(')
124 		index = 38;
125 	else if (testChar == ')')
126 		index = 39;
127 	else if (testChar == '\'')
128 		index = 44;
129 	else if (testChar == ':')
130 		index = 45;
131 	else if (testChar == ';')
132 		index = 46;
133 	else if (testChar == '?')
134 		index = 47;
135 	else if (testChar == ',')
136 		index = 48;
137 	else if (testChar == '/')
138 		index = 49;
139 	else if (testChar == '_')
140 		index = 50;
141 	else if (testChar == ' ')
142 		index = 51;
143 	else if (testChar == '-')
144 		index = 52;
145 	else if (testChar == '%')
146 		index = 53;
147 	else if (testChar == '+')
148 		index = 54;
149 	else if (testChar == std::string("ß")[0]) // UTF-8 escape
150 	{
151 		testChar = *iter;
152 		++iter;
153 		if (testChar == std::string("ß")[1])
154 			return 40;
155 		else if (testChar == std::string("ä")[1])
156 			return 41;
157 		else if (testChar == std::string("ö")[1])
158 			return 42;
159 		else if (testChar == std::string("ü")[1])
160 			return 43;
161 		else if (testChar == std::string("Ä")[1])
162 			return 41;
163 		else if (testChar == std::string("Ö")[1])
164 			return 42;
165 		else if (testChar == std::string("Ü")[1])
166 			return 43;
167 	}
168 
169 	return index;
170 }
171 
setMouseMarker(float position)172 void RenderManager::setMouseMarker(float position)
173 {
174 	mMouseMarkerPosition = position;
175 }
176 
blobRect(const Vector2 & position)177 SDL_Rect RenderManager::blobRect(const Vector2& position)
178 {
179 	SDL_Rect rect = {
180 		(short)(lround(position.x) - 37),
181 		(short)(lround(position.y) - 44),
182 		75,
183 		89
184 	};
185 
186 	return rect;
187 }
188 
ballRect(const Vector2 & position)189 SDL_Rect RenderManager::ballRect(const Vector2& position)
190 {
191 	SDL_Rect rect = {
192 		(short)(lround(position.x) - 32),
193 		(short)(lround(position.y) - 32),
194 		64,
195 		64
196 	};
197 	return rect;
198 }
199 
ballShadowPosition(const Vector2 & position)200 Vector2 RenderManager::ballShadowPosition(const Vector2& position)
201 {
202 	return Vector2(
203 		position.x + (500.0 - position.y) / 4 + 16.0,
204 		500.0 - (500.0 - position.y) / 16.0 - 10.0
205 	);
206 }
207 
ballShadowRect(const Vector2 & position)208 SDL_Rect RenderManager::ballShadowRect(const Vector2& position)
209 {
210 	SDL_Rect rect = {
211 		short(lround(position.x) - 64),
212 		short(lround(position.y) - 16),
213 		69,
214 		17
215 	};
216 
217 	return rect;
218 }
219 
blobShadowPosition(const Vector2 & position)220 Vector2 RenderManager::blobShadowPosition(const Vector2& position)
221 {
222 	return Vector2(
223 		position.x + (500.0 - position.y) / 4 + 16.0,
224 		500.0 - (500.0 - position.y) / 16.0 - 10.0
225 	);
226 }
227 
blobShadowRect(const Vector2 & position)228 SDL_Rect RenderManager::blobShadowRect(const Vector2& position)
229 {
230 	SDL_Rect rect = {
231 		short(lround(position.x) - 64),
232 		short(lround(position.y) - 16),
233 		128,
234 		32
235 	};
236 	return rect;
237 }
238 
redraw()239 void RenderManager::redraw()
240 {
241 	mNeedRedraw = true;
242 }
243 
drawGame(bool draw)244 void RenderManager::drawGame(bool draw)
245 {
246 	mDrawGame = draw;
247 }
248 
setTitle(const std::string & title)249 void RenderManager::setTitle(const std::string& title)
250 {
251 	SDL_SetWindowTitle(mWindow, title.c_str());
252 }
253 
getWindow()254 SDL_Window* RenderManager::getWindow()
255 {
256 	return mWindow;
257 }
258 
getOscillationColor() const259 Color RenderManager::getOscillationColor() const
260 {
261 	float time = float(SDL_GetTicks()) / 1000.0;
262 
263 	return Color(
264 					int((std::sin(time*1.5) + 1.0) * 128),
265 					int((std::sin(time*2.5) + 1.0) * 128),
266 					int((std::sin(time*3.5) + 1.0) * 128)
267 				);
268 }
269