1 #include <stdlib.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <SDL_video.h>
6 #include "loading_win.h"
7 #include "draw_scene.h"
8 #include "elwindows.h"
9 #include "errors.h"
10 #include "font.h"
11 #include "gl_init.h"
12 #include "interface.h"
13 #include "multiplayer.h"
14 #include "textures.h"
15 #include "widgets.h"
16 
17 #define PROGRESSBAR_ID       1
18 
19 const float load_bar_colors[12] = {
20 /*
21 	// exp bar colors
22 	//red    green   blue
23 	0.100f, 0.800f, 0.100f, // topleft
24 	0.100f, 0.800f, 0.100f, // topright
25 	0.100f, 0.400f, 0.100f, // bottomright
26 	0.100f, 0.400f, 0.100f  // bottomleft
27 */
28 	// Roja's colors
29 	//red    green   blue
30 	0.086f, 0.659f, 0.988f, // topleft
31 	0.086f, 0.659f, 0.988f, // topright
32 	0.294f, 0.173f, 0.690f, // bottomright
33 	0.294f, 0.173f, 0.690f  // bottomleft
34 };
35 
36 int loading_win = -1;
37 static Uint32 loading_win_progress_bar = -1;
38 static float total_progress = 0;
39 static GLuint loading_texture = 0;
40 static float frac_x, frac_y;
41 static Uint32 loading_texture_handle;
42 static Uint32 use_snapshot = 0;
43 static unsigned char text_buffer[255] = {0};
44 static char version_str[250] = {0};
45 static int progressbar_len = 0;
46 static int progressbar_height = 0;
47 
display_loading_win_handler(window_info * win)48 static int display_loading_win_handler(window_info *win)
49 {
50 	if (use_snapshot == 0)
51 	{
52 		bind_texture(loading_texture_handle);
53 
54 		glEnable(GL_TEXTURE_2D);
55 
56 		glBegin(GL_QUADS);
57 		glTexCoord2f(0.0f, 0.0f);
58 		glVertex3i(0, 0, 0);
59 
60 		glTexCoord2f(0.0f, frac_y);
61 		glVertex3i(0, win->len_y, 0);
62 
63 	 	glTexCoord2f(frac_x, frac_y);
64 		glVertex3i(win->len_x, win->len_y, 0);
65 
66 		glTexCoord2f(frac_x, 0.0f);
67 		glVertex3i(win->len_x, 0, 0);
68 		glEnd();
69 	}
70 	else
71 	{
72 		bind_texture_id(loading_texture);
73 
74 		glEnable(GL_TEXTURE_2D);
75 
76 		glBegin(GL_QUADS);
77 		glTexCoord2f (0.0f, frac_y);
78 		glVertex3i(0, 0, 0);
79 
80 		glTexCoord2f(0.0f, 0.0f);
81 		glVertex3i(0, win->len_y, 0);
82 
83 		glTexCoord2f(frac_x, 0.0f);
84 		glVertex3i(win->len_x, win->len_y, 0);
85 
86 	 	glTexCoord2f(frac_x, frac_y);
87 		glVertex3i(win->len_x, 0, 0);
88 		glEnd();
89 	}
90 
91 	// Since the background doesn't use the texture cache, invalidate
92 	// the last texture, so that the font will be loaded
93 	last_texture = -1;
94 	glColor3f (1.0, 1.0, 1.0);
95 	draw_string_zoomed_centered(win->len_x / 2, (win->len_y * 2) / 3 - win->default_font_len_y - 2,
96 		(const unsigned char*)version_str, 1, win->current_scale);
97 	draw_string_small_zoomed_centered(win->len_x / 2, (win->len_y * 2) / 3 + progressbar_height + 2,
98 		text_buffer, 1, win->current_scale);
99 
100 	glDisable(GL_TEXTURE_2D);
101 #ifdef OPENGL_TRACE
102 	CHECK_GL_ERRORS();
103 #endif //OPENGL_TRACE
104 	return 1;
105 }
106 
take_snapshot(int width,int height)107 static void take_snapshot (int width, int height)
108 {
109 	int bg_width = 1024;
110 	int bg_height = 512;
111 
112 #ifdef OPENGL_TRACE
113 	CHECK_GL_ERRORS();
114 #endif //OPENGL_TRACE
115 
116 	glGenTextures (1, &loading_texture);
117 	glBindTexture (GL_TEXTURE_2D, loading_texture);
118 
119 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
120 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
121 
122 	// texture sizes need to be powers of 2
123 	while (bg_width < width)
124 		bg_width *= 2;
125 	while (bg_height < height)
126 		bg_height *= 2;
127 
128 #ifdef OPENGL_TRACE
129 	CHECK_GL_ERRORS();
130 #endif //OPENGL_TRACE
131 	// Copy the current screen to the texture
132 	glReadBuffer(GL_BACK);
133 #ifdef OPENGL_TRACE
134 	CHECK_GL_ERRORS();
135 #endif //OPENGL_TRACE
136 	if (glGetError() != GL_NO_ERROR)
137 	{
138 		LOG_ERROR("%s: %d glReadBuffer(GL_BACK) problem.\n", __FUNCTION__, __LINE__);
139 		glReadBuffer(GL_FRONT);
140 	}
141 
142 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bg_width, bg_height, 0, GL_RGBA, GL_BYTE, NULL);
143 	if (glIsTexture(loading_texture) == GL_FALSE)
144 		LOG_ERROR("%s: %d texture problem.\n", __FUNCTION__, __LINE__);
145 	else
146 		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bg_width, bg_height);
147 
148 	frac_x = ((float) width) / bg_width;
149 	frac_y = ((float) height) / bg_height;
150 
151 	use_snapshot = 1;
152 
153 #ifdef OPENGL_TRACE
154 	CHECK_GL_ERRORS();
155 #endif //OPENGL_TRACE
156 }
157 
create_loading_win(int width,int height,int snapshot)158 int create_loading_win (int width, int height, int snapshot)
159 {
160 	version_str[0] = '\0';
161 	if (snapshot)
162 	{
163 		take_snapshot (width, height);
164 	}
165 
166 	if (loading_win == -1)// Make sure we only have one loading window
167 	{
168 		window_info * win = NULL;
169 		loading_win = create_window("Loading window", -1, -1, 0, 0, width, height, ELW_USE_UISCALE|ELW_TITLE_NONE|ELW_SHOW);
170 		set_window_handler(loading_win, ELW_HANDLER_DISPLAY, &display_loading_win_handler);
171 		if (loading_win >= 0 && loading_win < windows_list.num_windows)
172 			win = &windows_list.window[loading_win];
173 		else
174 			return -1;
175 		progressbar_len = (int)(0.5 + win->current_scale * 300);
176 		progressbar_height = (int)(0.5 + win->current_scale * 20);
177 		loading_win_progress_bar = progressbar_add_extended(loading_win, PROGRESSBAR_ID, NULL, (width - progressbar_len)/2, (height*2)/3,
178 				progressbar_len, progressbar_height, 0, 1.0f, 0.0f, load_bar_colors);
179 		widget_set_color(loading_win, loading_win_progress_bar, 0.0f, 0.0f, 0.0f);
180 		if (!snapshot)
181 		{
182 			loading_texture_handle = load_texture_cached("./textures/login_back", tt_image);
183 			frac_x = frac_y = 1.0f;
184 			use_snapshot = 0;
185 
186 			get_version_string (version_str, sizeof (version_str));
187 		}
188 	}
189 
190 	return loading_win;
191 }
192 
update_loading_win(char * text,float progress_increase)193 void update_loading_win (char *text, float progress_increase)
194 {
195 	if(loading_win != -1) {
196 		total_progress += progress_increase;
197 		LOG_DEBUG("%s (%.0f%%)", text, total_progress);
198 		if (total_progress > 100.1f)
199 		{
200 			LOG_ERROR("Loading window progress > 100%%! (%g)", total_progress);
201 			total_progress = 100.0f;
202 		}
203 
204 		progressbar_set_progress(loading_win, loading_win_progress_bar, total_progress);
205 
206 		if (text != NULL && strlen(text) <= 255)
207 		{
208 			if (loading_win >= 0 && loading_win < windows_list.num_windows)
209 			{
210 				put_small_text_in_box_zoomed((unsigned char*)text, strlen(text),
211 					window_width, text_buffer, windows_list.window[loading_win].current_scale);
212 			}
213 		}
214 		// The loading window is supposed to display stuff while
215 		// loading maps when the draw_scene loop is held up. Hence
216 		// we have to call our own drawing code. Instead of making
217 		// sure that the proper root window is hidden, we call
218 		// display_window directly.
219 		glLoadIdentity ();
220 		Enter2DMode ();
221 		display_window (loading_win);
222 		Leave2DMode ();
223 		SDL_GL_SwapWindow(el_gl_window);
224 	}
225 }
226 
destroy_loading_win(void)227 int destroy_loading_win(void)
228 {
229 	if (use_snapshot != 0)
230 	{
231 		glDeleteTextures (1, &loading_texture);
232 	}
233 	destroy_window(loading_win);
234 	loading_win = -1;
235 	loading_texture = -1;
236 	loading_win_progress_bar = -1;
237 	total_progress = 0.0f;
238 
239 	return 0;
240 }
241