1 /*
2 * XPilotNG/SDL, an SDL/OpenGL XPilot client. Copyright (C) 2003-2004 by
3 *
4 * Juha Lindstr�m <juhal@users.sourceforge.net>
5 * Erik Andersson <deity_at_home.se>
6 * Darel Cullen <darelcullen@users.sourceforge.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include "xpclient_sdl.h"
24
25 #include "text.h"
26 #include "console.h"
27 #include "sdlkeys.h"
28 #include "glwidgets.h"
29 #include "sdlpaint.h"
30 #include "sdlinit.h"
31 #include "scrap.h"
32
33 /* These are only needed for the polygon tessellation */
34 /* I'd like to move them to Paint_init/cleanup but because it */
35 /* is called before the map is ready I need separate functions */
36 /* for now.. */
37 extern int Gui_init(void);
38 extern void Gui_cleanup(void);
39
40 int draw_depth;
41
42 /* This holds video information assigned at initialise */
43 const SDL_VideoInfo *videoInfo;
44
45 /* Flags to pass to SDL_SetVideoMode */
46 int videoFlags;
47 SDL_Surface *MainSDLSurface = NULL;
48
49 font_data gamefont;
50 font_data mapfont;
51 int gameFontSize;
52 int mapFontSize;
53 char *gamefontname;
54
55 /* ugly kps hack */
file_exists(const char * path)56 static bool file_exists(const char *path)
57 {
58 FILE *fp;
59
60 if (!path) {
61 return false;
62 } else {
63 fp = fopen(path ? path : "", "r");
64 if (fp) {
65 fclose(fp);
66 return true;
67 }
68 return false;
69 }
70 }
71
Init_playing_windows(void)72 int Init_playing_windows(void)
73 {
74 /*
75 sdl_init_colors();
76 Init_spark_colors();
77 */
78 if ( !AppendGLWidgetList(&MainWidget,Init_MainWidget(&gamefont)) ) {
79 error("widget initialization failed");
80 return -1;
81 }
82 if (Console_init()) {
83 error("console initialization failed");
84 return -1;
85 }
86 if (Gui_init()) {
87 error("gui initialization failed");
88 return -1;
89 }
90
91 return 0;
92 }
93
find_size(int * w,int * h)94 static bool find_size(int *w, int *h)
95 {
96 SDL_Rect **modes, *m;
97 int i, d, best_i, best_d;
98
99 modes = SDL_ListModes(NULL, videoFlags);
100 if (modes == NULL) return false;
101 if (modes == (SDL_Rect**)-1) return true;
102
103 best_i = 0;
104 best_d = INT_MAX;
105 for (i = 0; modes[i]; i++) {
106 m = modes[i];
107 d = (m->w - *w)*(m->w - *w) + (m->h - *h)*(m->h - *h);
108 if (d < best_d) {
109 best_d = d;
110 best_i = i;
111 }
112 }
113 *w = modes[best_i]->w;
114 *h = modes[best_i]->h;
115 return true;
116 }
117
Init_window(void)118 int Init_window(void)
119 {
120 int value;
121 char defaultfontname[] = CONF_FONTDIR "FreeSansBoldOblique.ttf";
122 bool gf_exists = true,df_exists = true,gf_init = false, mf_init = false;
123
124 if (TTF_Init()) {
125 error("SDL_ttf initialization failed: %s", SDL_GetError());
126 return -1;
127 }
128 warn("SDL_ttf initialized.\n");
129
130 Conf_print();
131
132 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
133 error("failed to initialize SDL: %s", SDL_GetError());
134 return -1;
135 }
136
137 atexit(SDL_Quit);
138
139 /* Fetch the video info */
140 videoInfo = SDL_GetVideoInfo( );
141
142 num_spark_colors=8;
143
144 /* the flags to pass to SDL_SetVideoMode */
145 videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
146 videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
147 videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
148 #ifndef _WINDOWS
149 videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
150 #else
151 videoFlags |= SDL_FULLSCREEN;
152 #endif
153
154 /** This checks to see if surfaces can be stored in memory */
155 if ( videoInfo->hw_available )
156 videoFlags |= SDL_HWSURFACE;
157 else
158 videoFlags |= SDL_SWSURFACE;
159
160 /* This checks if hardware blits can be done */
161 if ( videoInfo->blit_hw )
162 videoFlags |= SDL_HWACCEL;
163
164 draw_depth = videoInfo->vfmt->BitsPerPixel;
165
166 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
167
168 if (videoFlags & SDL_FULLSCREEN)
169 if (!find_size((int*)&draw_width, (int*)&draw_height))
170 videoFlags ^= SDL_FULLSCREEN;
171
172 if ((MainSDLSurface = SDL_SetVideoMode(draw_width,
173 draw_height,
174 draw_depth,
175 videoFlags )) == NULL) {
176 error("Could not find a valid GLX visual for your display");
177 return -1;
178 }
179
180 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
181 printf("RGB bpp %d/", value);
182 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE,&value);
183 printf("%d/", value);
184 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value);
185 printf("%d ", value);
186 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value);
187 printf("Bit Depth is %d\n",value);
188
189 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
190 glViewport(0, 0, draw_width, draw_height);
191 glMatrixMode(GL_PROJECTION);
192 gluOrtho2D(0, draw_width, 0, draw_height);
193 glMatrixMode(GL_MODELVIEW);
194 glEnable(GL_BLEND);
195 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
196
197 /* Set title for window */
198 SDL_WM_SetCaption(TITLE, NULL);
199
200 /* this prevents a freetype crash if you pass non existant fonts */
201 if (!file_exists(gamefontname)) {
202 error("cannot find your game font '%s'.\n" \
203 "Please check that it exists!",gamefontname);
204 xpprintf("Reverting to defaultfont '%s'\n",defaultfontname);
205 gf_exists = false;
206 }
207 if (!file_exists(defaultfontname)) {
208 error("cannot find the default font! '%s'" ,defaultfontname);
209 df_exists = false;
210 }
211
212 if (!gf_exists && !df_exists) {
213 error("Failed to find any font files!\n" \
214 "Probably you forgot to run 'make install',use '-TTFont <font.ttf>' argument" \
215 " until you do");
216 return -1;
217 }
218
219 if (gf_exists) {
220 if (fontinit(&gamefont,gamefontname,gameFontSize)) {
221 error("Font initialization failed with %s", gamefontname);
222 } else gf_init = true;
223 }
224 if (!gf_init && df_exists) {
225 if (fontinit(&gamefont,defaultfontname,gameFontSize)) {
226 error("Default font initialization failed with %s", defaultfontname);
227 } else gf_init = true;
228 }
229
230 if (!gf_init) {
231 error("Failed to initialize any game font! (quitting)");
232 return -1;
233 }
234
235 if (gf_exists) {
236 if (fontinit(&mapfont,gamefontname,mapFontSize)) {
237 error("Font initialization failed with %s", gamefontname);
238 } else mf_init = true;
239 }
240 if (!mf_init && df_exists) {
241 if (fontinit(&mapfont,defaultfontname,mapFontSize)) {
242 error("Default font initialization failed with %s", defaultfontname);
243 } else mf_init = true;
244 }
245
246 if (!mf_init) {
247 error("Failed to initialize any map font! (quitting)");
248 return -1;
249 }
250
251 /* Set up the clipboard */
252 if ( init_scrap() < 0 ) {
253 error("Couldn't init clipboard: %s\n");
254 }
255
256 return 0;
257 }
258
259 /* function to reset our viewport after a window resize */
Resize_Window(int width,int height)260 int Resize_Window( int width, int height )
261 {
262 SDL_Rect b = {0,0,0,0};
263
264 if (videoFlags & SDL_FULLSCREEN)
265 if (!find_size(&width, &height))
266 return -1;
267
268 b.w = draw_width = width;
269 b.h = draw_height = height;
270
271 SetBounds_GLWidget(MainWidget,&b);
272
273 if (!SDL_SetVideoMode( width,
274 height,
275 draw_depth,
276 videoFlags ))
277 return -1;
278
279
280 /* change to the projection matrix and set our viewing volume. */
281 glMatrixMode( GL_PROJECTION );
282
283 glLoadIdentity( );
284
285 gluOrtho2D(0, draw_width, 0, draw_height);
286
287 /* Make sure we're chaning the model view and not the projection */
288 glMatrixMode( GL_MODELVIEW );
289
290 /* Reset The View */
291 glLoadIdentity( );
292
293 /* Setup our viewport. */
294 glViewport( 0, 0, ( GLint )draw_width, ( GLint )draw_height );
295 return 0;
296 }
297
298
Platform_specific_cleanup(void)299 void Platform_specific_cleanup(void)
300 {
301 Close_Widget(&MainWidget);
302 Gui_cleanup();
303 Console_cleanup();
304 fontclean(&gamefont);
305 fontclean(&mapfont);
306 TTF_Quit();
307 SDL_Quit();
308 }
309
Set_geometry(xp_option_t * opt,const char * s)310 static bool Set_geometry(xp_option_t *opt, const char *s)
311 {
312 int w = 0, h = 0;
313
314 if (s[0] == '=') {
315 sscanf(s, "%*c%d%*c%d", &w, &h);
316 } else {
317 sscanf(s, "%d%*c%d", &w, &h);
318 }
319 if (w == 0 || h == 0) return false;
320 if (MainSDLSurface != NULL) {
321 Resize_Window(w, h);
322 } else {
323 draw_width = w;
324 draw_height = h;
325 }
326 return true;
327 }
328
Get_geometry(xp_option_t * opt)329 static const char* Get_geometry(xp_option_t *opt)
330 {
331 static char buf[20]; /* should be enough */
332 snprintf(buf, 20, "%dx%d", draw_width, draw_height);
333 return buf;
334 }
335
Set_fontName(xp_option_t * opt,const char * value)336 static bool Set_fontName(xp_option_t *opt, const char *value)
337 {
338 UNUSED_PARAM(opt);
339 XFREE(gamefontname);
340 gamefontname = xp_safe_strdup(value);
341
342 return true;
343 }
344
Get_fontName(xp_option_t * opt)345 static const char *Get_fontName(xp_option_t *opt)
346 {
347 UNUSED_PARAM(opt);
348 return gamefontname;
349 }
350
351 static xp_option_t sdlinit_options[] = {
352 XP_STRING_OPTION(
353 "geometry",
354 "1280x1024",
355 NULL,
356 0,
357 Set_geometry, NULL, Get_geometry,
358 XP_OPTFLAG_DEFAULT,
359 "Set the initial window geometry.\n"),
360
361 XP_INT_OPTION(
362 "gameFontSize",
363 16, 12, 32,
364 &gameFontSize,
365 NULL,
366 XP_OPTFLAG_DEFAULT,
367 "Height of font used for game strings.\n"),
368
369 XP_INT_OPTION(
370 "mapFontSize",
371 16, 12, 64,
372 &mapFontSize,
373 NULL,
374 XP_OPTFLAG_DEFAULT,
375 "Height of font used for strings painted on the map.\n"),
376
377 XP_STRING_OPTION(
378 "TTFont",
379 CONF_FONTDIR "FreeSansBoldOblique.ttf",
380 NULL, 0,
381 Set_fontName, NULL, Get_fontName,
382 XP_OPTFLAG_DEFAULT,
383 "Set the font to use.\n")
384 };
385
Store_sdlinit_options(void)386 void Store_sdlinit_options(void)
387 {
388 STORE_OPTIONS(sdlinit_options);
389 }
390