1 /* NetHack may be freely redistributed.  See license for details. */
2 
3 #include <vector>
4 #include <string>
5 
6 
7 #include <errno.h>
8 
9 #include "vulture_win.h"
10 #include "vulture_gra.h"
11 #include "vulture_gen.h"
12 #include "vulture_sdl.h"
13 #include "vulture_gfl.h"
14 #include "vulture_txt.h"
15 #include "vulture_init.h"
16 #include "vulture_nhplayerselection.h"
17 #include "vulture_main.h"
18 #include "vulture_sound.h"
19 #include "vulture_mou.h"
20 #include "vulture_tile.h"
21 #include "vulture_opt.h"
22 
23 #include "winclass/introwin.h"
24 
25 #include "date.h" /* this is in <variant>/include it's needed for VERSION_ID */
26 
27 static void vulture_show_intro(std::string introscript_name);
28 
29 
30 /*----------------------------
31 * function implementaions
32 *---------------------------- */
33 
34 
vulture_show_logo_screen(void)35 void vulture_show_logo_screen(void)
36 {
37 	SDL_Event event;
38 	SDL_Surface *logo;
39 
40 	vulture_play_event_sound("nhfe_music_main_title");
41 
42 	if (iflags.wc_splash_screen)
43 	{
44 		logo = vulture_load_graphic(V_FILENAME_LOGO);
45 		if (logo != NULL)
46 		{
47 			/* TODO Stretch this image fullscreen */
48 			vulture_put_img((vulture_screen->w - logo->w) / 2, (vulture_screen->h - logo->h) / 2, logo);
49 
50 			vulture_put_text_shadow( V_FONT_INTRO, VERSION_ID ,vulture_screen,
51 					(vulture_screen->w - vulture_text_length( V_FONT_INTRO, VERSION_ID )) / 2,
52 					(vulture_screen->h - logo->h) / 2 + logo->h - ( vulture_text_height( V_FONT_INTRO, VERSION_ID) ),
53 					V_COLOR_INTRO_TEXT, V_COLOR_BACKGROUND);
54 
55 			vulture_fade_in(0.5);
56 
57 			vulture_wait_input(&event, 0);
58 
59 			vulture_fade_out(0.2);
60 
61 			SDL_FreeSurface(logo);
62 		}
63 	}
64 
65 	vulture_refresh();
66 }
67 
68 
vulture_player_selection(void)69 void vulture_player_selection(void)
70 {
71 	SDL_Surface *logo;
72   std::string filename;
73 
74 	SDL_FillRect(vulture_screen, NULL, CLR32_BLACK);
75 	logo = vulture_load_graphic(V_FILENAME_CHARACTER_GENERATION);
76 	if (logo != NULL) {
77 		vulture_put_img((vulture_screen->w - logo->w) / 2, (vulture_screen->h - logo->h) / 2, logo);
78 		SDL_FreeSurface(logo);
79 	}
80 
81 	vulture_fade_in(0.2);
82 
83 	vulture_player_selection_internal();
84 
85 	/* Success! Show introduction. */
86 	vulture_fade_out(0.2);
87 
88 	filename = vulture_make_filename(V_CONFIG_DIRECTORY, "", V_FILENAME_INTRO_SCRIPT);
89 
90 	if (flags.legacy)
91 		vulture_show_intro(filename);
92 }
93 
94 
vulture_askname(void)95 void vulture_askname(void)
96 {
97 	int done;
98 	char inputbuffer[256];
99 
100 	done = vulture_get_input(-1, vulture_screen->h - 170,
101 						"What is your name?", inputbuffer);
102 	if (!done)
103 		/* Player pressed ESC during the name query, so quit the game */
104 		vulture_bail(NULL);
105 
106 	strncpy(plname, inputbuffer, 32);
107 
108 	/* do not fade out if user didn't enter anything, we will come back here */
109 	if (plname[0])
110 		vulture_fade_out(0.2);
111 }
112 
113 
vulture_show_intro(std::string introscript_name)114 static void vulture_show_intro(std::string introscript_name)
115 {
116 	FILE *f;
117 	char buffer[1024];
118 	unsigned int nr_scenes, lineno;
119   std::string line;
120   std::vector<std::string> imagenames;
121   std::vector< std::vector<std::string> > subtitles;
122 	introwin *iw;
123     int dummy;
124 
125 	/* read intro script */
126 	f = fopen(introscript_name.c_str(), "rb");
127 	if (f == NULL) {
128 		vulture_write_log(V_LOG_NOTE, NULL, 0, "intro script %s not found\n",
129 		                   introscript_name.c_str());
130 		return;
131 	}
132 
133 	lineno = nr_scenes = 0;
134 	while (fgets(buffer, 1024, f)) {
135 		lineno++;
136 
137 		if (buffer[0] == '%') {
138 			/* new scene */
139 			line = std::string(&buffer[1]);
140 			trim(line);
141 
142 			if (line.length() == 0)
143 				continue;
144 
145 			nr_scenes++;
146 
147 			if (line.substr(line.length() - 4, 4) != ".png")
148 				vulture_write_log(V_LOG_NOTE, NULL, 0, "scene image %s not png?", line.c_str());
149 
150 			/* trim off the file extension */
151 			line = line.substr(0, line.length() - 4);
152 
153 			imagenames.push_back(line);
154 			subtitles.resize(nr_scenes);
155 
156 		} else {
157 			/* text lines for current scene */
158 			if (nr_scenes == 0) {
159 				vulture_write_log(V_LOG_NOTE, NULL, 0, "subtitle without a preceding scene in line %d of intro script %s\n", lineno, introscript_name.c_str());
160 				continue;
161 			}
162 
163 			line = std::string(buffer);
164 			trim(line);
165 
166 			subtitles[nr_scenes - 1].push_back(line);
167 		}
168 	}
169 
170 	if (nr_scenes == 0) {
171 		vulture_write_log(V_LOG_NOTE, NULL, 0, "no scenes found in intro script %s\n",
172 		                   introscript_name.c_str());
173 		return;
174 	}
175 
176 	/* display intro */
177 	iw = new introwin(NULL, imagenames, subtitles);
178 	vulture_event_dispatcher(&dummy, V_RESPOND_INT, iw);
179 	delete iw;
180 }
181 
182 
vulture_init_colors()183 static void vulture_init_colors()
184 {
185 	/* set up the colors used in the game
186 	* the only good way to do this without needing graphics to have been loaded first
187 	* is to create a surface here which we then put into display format + alpha ourselves */
188 	SDL_Surface * pixel = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, 1, 1, 32,
189 								0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
190 	SDL_Surface * reformatted = SDL_DisplayFormatAlpha(pixel);
191 
192 	vulture_px_format = new SDL_PixelFormat;
193 	memcpy(vulture_px_format, reformatted->format, sizeof(SDL_PixelFormat));
194 
195 	SDL_FreeSurface(reformatted);
196 	SDL_FreeSurface(pixel);
197 
198 	CLR32_BLACK      = SDL_MapRGBA(vulture_px_format, 0,0,0, 0xff);
199 	CLR32_BLACK_A30  = SDL_MapRGBA(vulture_px_format, 0,0,0, 0x50);
200 	CLR32_BLACK_A50  = SDL_MapRGBA(vulture_px_format, 0,0,0, 0x80);
201 	CLR32_BLACK_A70  = SDL_MapRGBA(vulture_px_format, 0,0,0, 0xB0);
202 	CLR32_GREEN      = SDL_MapRGBA(vulture_px_format, 0x57, 0xff, 0x57, 0xff);
203 	CLR32_YELLOW     = SDL_MapRGBA(vulture_px_format, 0xff, 0xff, 0x57, 0xff);
204 	CLR32_ORANGE     = SDL_MapRGBA(vulture_px_format, 0xff, 0xc7, 0x3b, 0xff);
205 	CLR32_RED        = SDL_MapRGBA(vulture_px_format, 0xff, 0x23, 0x07, 0xff);
206 	CLR32_GRAY20     = SDL_MapRGBA(vulture_px_format, 0xb7, 0xab, 0xab, 0xff);
207 	CLR32_GRAY70     = SDL_MapRGBA(vulture_px_format, 0x53, 0x53, 0x53, 0xff);
208 	CLR32_GRAY77     = SDL_MapRGBA(vulture_px_format, 0x43, 0x3b, 0x3b, 0xff);
209 	CLR32_PURPLE44   = SDL_MapRGBA(vulture_px_format, 0x4f, 0x43, 0x6f, 0xff);
210 	CLR32_LIGHTPINK  = SDL_MapRGBA(vulture_px_format, 0xcf, 0xbb, 0xd3, 0xff);
211 	CLR32_LIGHTGREEN = SDL_MapRGBA(vulture_px_format, 0xaa, 0xff, 0xcc, 0xff);
212 	CLR32_BROWN      = SDL_MapRGBA(vulture_px_format, 0x9b, 0x6f, 0x57, 0xff);
213 	CLR32_WHITE      = SDL_MapRGBA(vulture_px_format, 0xff, 0xff, 0xff, 0xff);
214 	CLR32_BLESS_BLUE = SDL_MapRGBA(vulture_px_format, 0x96, 0xdc, 0xfe, 0x60);
215 	CLR32_CURSE_RED  = SDL_MapRGBA(vulture_px_format, 0x60, 0x00, 0x00, 0x50);
216 	CLR32_GOLD_SHADE = SDL_MapRGBA(vulture_px_format, 0xf0, 0xe0, 0x57, 0x40);
217 }
218 
219 
vulture_init_graphics(void)220 int vulture_init_graphics(void)
221 {
222 	int all_ok = TRUE;
223 	SDL_Surface *image;
224   std::string fullname;
225 	int font_loaded = 0;
226 
227 
228 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Initializing filenames\n");
229 	vulture_init_gamepath();
230 
231 
232 	/* Read options file */
233 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Reading Vulture's options\n");
234 	vulture_read_options();
235 
236 
237 	/* Enter graphics mode */
238 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Enter graphics mode\n");
239 	vulture_enter_graphics_mode();
240 
241 
242 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Initializing screen buffer\n");
243 
244 
245 	vulture_init_colors();
246 
247 	/* Load fonts */
248 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Initializing fonts\n");
249 
250 	/* try custom font first */
251 	if (iflags.wc_font_text) {
252 		if (access(iflags.wc_font_text, R_OK) == 0) {
253 			font_loaded = 1;
254 			font_loaded &= vulture_load_font(V_FONT_SMALL, iflags.wc_font_text, 0, 12);
255 			font_loaded &= vulture_load_font(V_FONT_LARGE, iflags.wc_font_text, 0, 14);
256 		}
257 		else
258 			printf("Could not access %s: %s\n", iflags.wc_font_text, strerror(errno));
259 	}
260 
261 	if (!font_loaded) {/* fallback to default font */
262 		font_loaded = 1;
263 		/* add the path to the filename */
264 		fullname = vulture_make_filename(V_FONTS_DIRECTORY, "", V_FILENAME_FONT);
265 
266 		font_loaded &= vulture_load_font(V_FONT_SMALL, fullname.c_str(), 0, 12);
267 		font_loaded &= vulture_load_font(V_FONT_LARGE, fullname.c_str(), 0, 14);
268 	}
269 
270 	all_ok &= font_loaded;
271 
272 	/* Load window style graphics */
273 	image = vulture_load_graphic(V_FILENAME_WINDOW_STYLE);
274 	if (image == NULL)
275 		all_ok = FALSE;
276 	else {
277 		vulture_winelem.corner_tl = vulture_get_img_src(1, 1, 23, 23, image);
278 		vulture_winelem.border_top = vulture_get_img_src(27, 1, 57, 23, image);
279 		vulture_winelem.corner_tr = vulture_get_img_src(61, 1, 84, 23, image);
280 		vulture_winelem.border_left = vulture_get_img_src(1, 27, 23, 54, image);
281 		vulture_winelem.center = vulture_get_img_src(141, 1, 238, 168, image);
282 		vulture_winelem.border_right = vulture_get_img_src(61, 27, 84, 54, image);
283 		vulture_winelem.corner_bl = vulture_get_img_src(1, 58, 23, 82, image);
284 		vulture_winelem.border_bottom = vulture_get_img_src(27, 58, 57, 82, image);
285 		vulture_winelem.corner_br = vulture_get_img_src(61, 58, 84, 82, image);
286 		vulture_winelem.checkbox_off = vulture_get_img_src(1, 107, 17, 123, image);
287 		vulture_winelem.checkbox_on = vulture_get_img_src(21, 107, 37, 123, image);
288 		vulture_winelem.checkbox_count = vulture_get_img_src(21, 127, 37, 143, image);
289 		vulture_winelem.radiobutton_off = vulture_get_img_src(41, 107, 57, 123, image);
290 		vulture_winelem.radiobutton_on = vulture_get_img_src(61, 107, 77, 123, image);
291 		vulture_winelem.scrollbar = vulture_get_img_src(81, 107, 97, 123, image);
292 		vulture_winelem.scrollbutton_down = vulture_get_img_src(101, 107, 117, 123, image);
293 		vulture_winelem.scrollbutton_up = vulture_get_img_src(121, 107, 137, 123, image);
294 		vulture_winelem.scroll_indicator = vulture_get_img_src(1, 127, 17, 154, image);
295 		vulture_winelem.direction_arrows = vulture_get_img_src(242, 1, 576, 134, image);
296 		vulture_winelem.invarrow_left = vulture_get_img_src(1, 158, 67, 174, image);
297 		vulture_winelem.invarrow_right = vulture_get_img_src(1, 178, 67, 194, image);
298 		vulture_winelem.closebutton = vulture_get_img_src(41, 127, 59, 145, image);
299 		SDL_FreeSurface(image);
300 	}
301 
302 	/* Initialize tile bitmaps */
303 	vulture_load_gametiles();
304 
305 
306 	/* make sure the cursor is not NULL when we try to draw for the first time */
307 	vulture_mouse_init();
308 
309 	vulture_write_log(V_LOG_DEBUG, __FILE__, __LINE__, "Vulture's window system ready.\n");
310 
311 	vulture_set_draw_region(0, 0, vulture_screen->w, vulture_screen->h);
312 	SDL_FillRect(vulture_screen, NULL, CLR32_BLACK);
313 
314 	return all_ok;
315 }
316 
317 
318 
vulture_destroy_graphics(void)319 void vulture_destroy_graphics(void)
320 {
321 	unsigned int i;
322 
323 	/* free tilearrays, related data */
324 	vulture_unload_gametiles();
325 
326 	/* clean up fonts */
327 	vulture_free_fonts();
328 
329 	/* unload mouse & tooltip backgrounds, tooltip text and tootltip surface */
330 	vulture_mouse_destroy();
331 
332 	vulture_eventstack_destroy();
333 
334 	/* free window elements */
335 	SDL_FreeSurface(vulture_winelem.corner_tl);
336 	SDL_FreeSurface(vulture_winelem.border_top);
337 	SDL_FreeSurface(vulture_winelem.corner_tr);
338 	SDL_FreeSurface(vulture_winelem.border_left);
339 	SDL_FreeSurface(vulture_winelem.center);
340 	SDL_FreeSurface(vulture_winelem.border_right);
341 	SDL_FreeSurface(vulture_winelem.corner_bl);
342 	SDL_FreeSurface(vulture_winelem.border_bottom);
343 	SDL_FreeSurface(vulture_winelem.corner_br);
344 	SDL_FreeSurface(vulture_winelem.checkbox_off);
345 	SDL_FreeSurface(vulture_winelem.checkbox_on);
346 	SDL_FreeSurface(vulture_winelem.checkbox_count);
347 	SDL_FreeSurface(vulture_winelem.radiobutton_off);
348 	SDL_FreeSurface(vulture_winelem.radiobutton_on);
349 	SDL_FreeSurface(vulture_winelem.scrollbar);
350 	SDL_FreeSurface(vulture_winelem.scrollbutton_down);
351 	SDL_FreeSurface(vulture_winelem.scrollbutton_up);
352 	SDL_FreeSurface(vulture_winelem.scroll_indicator);
353 	SDL_FreeSurface(vulture_winelem.direction_arrows);
354 	SDL_FreeSurface(vulture_winelem.invarrow_left);
355 	SDL_FreeSurface(vulture_winelem.invarrow_right);
356 	SDL_FreeSurface(vulture_winelem.closebutton);
357 
358 	/* free sound descriptions */
359 	for (i = 0; i < vulture_event_sounds.size(); i++)
360 		free (vulture_event_sounds[i].searchpattern);
361 
362 	/* misc small stuff */
363 	delete vulture_px_format;
364 }
365