1 /*
2  * OpenTyrian: A modern cross-platform port of Tyrian
3  * Copyright (C) 2007-2009  The OpenTyrian Development Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (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, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include "fonthand.h"
20 #include "network.h"
21 #include "nortsong.h"
22 #include "nortvars.h"
23 #include "opentyr.h"
24 #include "params.h"
25 #include "sprite.h"
26 #include "vga256d.h"
27 #include "video.h"
28 
29 const int font_ascii[256] =
30 {
31 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
32 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
33 	 -1,  26,  33,  60,  61,  62,  -1,  32,  64,  65,  63,  84,  29,  83,  28,  80, //  !"#$%&'()*+,-./
34 	 79,  70,  71,  72,  73,  74,  75,  76,  77,  78,  31,  30,  -1,  85,  -1,  27, // 0123456789:;<=>?
35 	 -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14, // @ABCDEFGHIJKLMNO
36 	 15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  68,  82,  69,  -1,  -1, // PQRSTUVWXYZ[\]^_
37 	 -1,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48, // `abcdefghijklmno
38 	 49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  66,  81,  67,  -1,  -1, // pqrstuvwxyz{|}~⌂
39 
40 	 86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101, // ÇüéâäàåçêëèïîìÄÅ
41 	102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, // ÉæÆôöòûùÿÖÜ¢£¥₧ƒ
42 	118, 119, 120, 121, 122, 123, 124, 125, 126,  -1,  -1,  -1,  -1,  -1,  -1,  -1, // áíóúñѪº¿
43 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
44 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
45 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
46 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
47 	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
48 };
49 
50 /* shape constants included in newshape.h */
51 
52 JE_integer defaultBrightness = -3;
53 JE_byte textGlowFont, textGlowBrightness = 6;
54 
55 JE_boolean levelWarningDisplay;
56 JE_byte levelWarningLines;
57 char levelWarningText[10][61]; /* [1..10] of string [60] */
58 JE_boolean warningRed;
59 
60 JE_byte warningSoundDelay;
61 JE_word armorShipDelay;
62 JE_byte warningCol;
63 JE_shortint warningColChange;
64 
JE_dString(SDL_Surface * screen,int x,int y,const char * s,unsigned int font)65 void JE_dString( SDL_Surface * screen, int x, int y, const char *s, unsigned int font )
66 {
67 	int bright = 0;
68 
69 	for (int i = 0; s[i] != '\0'; ++i)
70 	{
71 		int sprite_id = font_ascii[(unsigned char)s[i]];
72 
73 		switch (s[i])
74 		{
75 		case ' ':
76 			x += 6;
77 			break;
78 
79 		case '~':
80 			bright = (bright == 0) ? 2 : 0;
81 			break;
82 
83 		default:
84 			if (sprite_id != -1)
85 			{
86 				blit_sprite_dark(screen, x + 2, y + 2, font, sprite_id, false);
87 				blit_sprite_hv_unsafe(screen, x, y, font, sprite_id, 0xf, defaultBrightness + bright);
88 
89 				x += sprite(font, sprite_id)->width + 1;
90 			}
91 			break;
92 		}
93 	}
94 }
95 
JE_fontCenter(const char * s,unsigned int font)96 int JE_fontCenter( const char *s, unsigned int font )
97 {
98 	return 160 - (JE_textWidth(s, font) / 2);
99 }
100 
JE_textWidth(const char * s,unsigned int font)101 int JE_textWidth( const char *s, unsigned int font )
102 {
103 	int x = 0;
104 
105 	for (int i = 0; s[i] != '\0'; ++i)
106 	{
107 		int sprite_id = font_ascii[(unsigned char)s[i]];
108 
109 		if (s[i] == ' ')
110 			x += 6;
111 		else if (sprite_id != -1)
112 			x += sprite(font, sprite_id)->width + 1;
113 	}
114 
115 	return x;
116 }
117 
JE_textShade(SDL_Surface * screen,int x,int y,const char * s,unsigned int colorbank,int brightness,unsigned int shadetype)118 void JE_textShade( SDL_Surface * screen, int x, int y, const char *s, unsigned int colorbank, int brightness, unsigned int shadetype )
119 {
120 	switch (shadetype)
121 	{
122 		case PART_SHADE:
123 			JE_outText(screen, x+1, y+1, s, 0, -1);
124 			JE_outText(screen, x, y, s, colorbank, brightness);
125 			break;
126 		case FULL_SHADE:
127 			JE_outText(screen, x-1, y, s, 0, -1);
128 			JE_outText(screen, x+1, y, s, 0, -1);
129 			JE_outText(screen, x, y-1, s, 0, -1);
130 			JE_outText(screen, x, y+1, s, 0, -1);
131 			JE_outText(screen, x, y, s, colorbank, brightness);
132 			break;
133 		case DARKEN:
134 			JE_outTextAndDarken(screen, x+1, y+1, s, colorbank, brightness, TINY_FONT);
135 			break;
136 		case TRICK:
137 			JE_outTextModify(screen, x, y, s, colorbank, brightness, TINY_FONT);
138 			break;
139 	}
140 }
141 
JE_outText(SDL_Surface * screen,int x,int y,const char * s,unsigned int colorbank,int brightness)142 void JE_outText( SDL_Surface * screen, int x, int y, const char *s, unsigned int colorbank, int brightness )
143 {
144 	int bright = 0;
145 
146 	for (int i = 0; s[i] != '\0'; ++i)
147 	{
148 		int sprite_id = font_ascii[(unsigned char)s[i]];
149 
150 		switch (s[i])
151 		{
152 		case ' ':
153 			x += 6;
154 			break;
155 
156 		case '~':
157 			bright = (bright == 0) ? 4 : 0;
158 			break;
159 
160 		default:
161 			if (sprite_id != -1 && sprite_exists(TINY_FONT, sprite_id))
162 			{
163 				if (brightness >= 0)
164 					blit_sprite_hv_unsafe(screen, x, y, TINY_FONT, sprite_id, colorbank, brightness + bright);
165 				else
166 					blit_sprite_dark(screen, x, y, TINY_FONT, sprite_id, true);
167 
168 				x += sprite(TINY_FONT, sprite_id)->width + 1;
169 			}
170 			break;
171 		}
172 	}
173 }
174 
JE_outTextModify(SDL_Surface * screen,int x,int y,const char * s,unsigned int filter,unsigned int brightness,unsigned int font)175 void JE_outTextModify( SDL_Surface * screen, int x, int y, const char *s, unsigned int filter, unsigned int brightness, unsigned int font )
176 {
177 	for (int i = 0; s[i] != '\0'; ++i)
178 	{
179 		int sprite_id = font_ascii[(unsigned char)s[i]];
180 
181 		if (s[i] == ' ')
182 		{
183 			x += 6;
184 		}
185 		else if (sprite_id != -1)
186 		{
187 			blit_sprite_hv_blend(screen, x, y, font, sprite_id, filter, brightness);
188 
189 			x += sprite(font, sprite_id)->width + 1;
190 		}
191 	}
192 }
193 
JE_outTextAdjust(SDL_Surface * screen,int x,int y,const char * s,unsigned int filter,int brightness,unsigned int font,JE_boolean shadow)194 void JE_outTextAdjust( SDL_Surface * screen, int x, int y, const char *s, unsigned int filter, int brightness, unsigned int font, JE_boolean shadow )
195 {
196 	int bright = 0;
197 
198 	for (int i = 0; s[i] != '\0'; ++i)
199 	{
200 		int sprite_id = font_ascii[(unsigned char)s[i]];
201 
202 		switch (s[i])
203 		{
204 		case ' ':
205 			x += 6;
206 			break;
207 
208 		case '~':
209 			bright = (bright == 0) ? 4 : 0;
210 			break;
211 
212 		default:
213 			if (sprite_id != -1 && sprite_exists(TINY_FONT, sprite_id))
214 			{
215 				if (shadow)
216 					blit_sprite_dark(screen, x + 2, y + 2, font, sprite_id, false);
217 				blit_sprite_hv(screen, x, y, font, sprite_id, filter, brightness + bright);
218 
219 				x += sprite(font, sprite_id)->width + 1;
220 			}
221 			break;
222 		}
223 	}
224 }
225 
JE_outTextAndDarken(SDL_Surface * screen,int x,int y,const char * s,unsigned int colorbank,unsigned int brightness,unsigned int font)226 void JE_outTextAndDarken( SDL_Surface * screen, int x, int y, const char *s, unsigned int colorbank, unsigned int brightness, unsigned int font )
227 {
228 	int bright = 0;
229 
230 	for (int i = 0; s[i] != '\0'; ++i)
231 	{
232 		int sprite_id = font_ascii[(unsigned char)s[i]];
233 
234 		switch (s[i])
235 		{
236 		case ' ':
237 			x += 6;
238 			break;
239 
240 		case '~':
241 			bright = (bright == 0) ? 4 : 0;
242 			break;
243 
244 		default:
245 			if (sprite_id != -1 && sprite_exists(TINY_FONT, sprite_id))
246 			{
247 				blit_sprite_dark(screen, x + 1, y + 1, font, sprite_id, false);
248 				blit_sprite_hv_unsafe(screen, x, y, font, sprite_id, colorbank, brightness + bright);
249 
250 				x += sprite(font, sprite_id)->width + 1;
251 			}
252 			break;
253 		}
254 	}
255 }
256 
JE_updateWarning(SDL_Surface * screen)257 void JE_updateWarning( SDL_Surface * screen )
258 {
259 	if (delaycount2() == 0)
260 	{ /*Update Color Bars*/
261 
262 		warningCol += warningColChange;
263 		if (warningCol > 14 * 16 + 10 || warningCol < 14 * 16 + 4)
264 		{
265 			warningColChange = -warningColChange;
266 		}
267 		fill_rectangle_xy(screen, 0, 0, 319, 5, warningCol);
268 		fill_rectangle_xy(screen, 0, 194, 319, 199, warningCol);
269 		JE_showVGA();
270 
271 		setjasondelay2(6);
272 
273 		if (warningSoundDelay > 0)
274 		{
275 			warningSoundDelay--;
276 		}
277 		else
278 		{
279 			warningSoundDelay = 14;
280 			JE_playSampleNum(17);
281 		}
282 	}
283 }
284 
JE_outTextGlow(SDL_Surface * screen,int x,int y,const char * s)285 void JE_outTextGlow( SDL_Surface * screen, int x, int y, const char *s )
286 {
287 	JE_integer z;
288 	JE_byte c = 15;
289 
290 	if (warningRed)
291 	{
292 		c = 7;
293 	}
294 
295 	JE_outTextAdjust(screen, x - 1, y,     s, 0, -12, textGlowFont, false);
296 	JE_outTextAdjust(screen, x,     y - 1, s, 0, -12, textGlowFont, false);
297 	JE_outTextAdjust(screen, x + 1, y,     s, 0, -12, textGlowFont, false);
298 	JE_outTextAdjust(screen, x,     y + 1, s, 0, -12, textGlowFont, false);
299 	if (frameCountMax > 0)
300 		for (z = 1; z <= 12; z++)
301 		{
302 			setjasondelay(frameCountMax);
303 			JE_outTextAdjust(screen, x, y, s, c, z - 10, textGlowFont, false);
304 			if (JE_anyButton())
305 			{
306 				frameCountMax = 0;
307 			}
308 
309 			NETWORK_KEEP_ALIVE();
310 
311 			JE_showVGA();
312 
313 			wait_delay();
314 		}
315 	for (z = (frameCountMax == 0) ? 6 : 12; z >= textGlowBrightness; z--)
316 	{
317 		setjasondelay(frameCountMax);
318 		JE_outTextAdjust(screen, x, y, s, c, z - 10, textGlowFont, false);
319 		if (JE_anyButton())
320 		{
321 			frameCountMax = 0;
322 		}
323 
324 		NETWORK_KEEP_ALIVE();
325 
326 		JE_showVGA();
327 
328 		wait_delay();
329 	}
330 	textGlowBrightness = 6;
331 }
332 
333