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