1 //----------------------------------------------------------------------------
2 //  EDGE SDL Video Code
3 //----------------------------------------------------------------------------
4 //
5 //  Copyright (c) 1999-2009  The EDGE Team.
6 //
7 //  This program is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU General Public License
9 //  as published by the Free Software Foundation; either version 2
10 //  of the License, or (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //----------------------------------------------------------------------------
18 
19 #include "i_defs.h"
20 #include "i_sdlinc.h"
21 #include "i_defs_gl.h"
22 
23 #include <signal.h>
24 
25 #include "m_argv.h"
26 #include "m_misc.h"
27 #include "r_modes.h"
28 
29 
30 SDL_Surface *my_vis;
31 
32 int graphics_shutdown = 0;
33 
34 cvar_c in_grab;
35 
36 static bool grab_state;
37 
38 static int display_W, display_H;
39 
40 
41 // Possible Screen Modes
42 static struct { int w, h; } possible_modes[] =
43 {
44 	{  320, 200, },
45 	{  320, 240, },
46 	{  400, 300, },
47 	{  512, 384, },
48 	{  640, 400, },
49 	{  640, 480, },
50 	{  800, 600, },
51 	{ 1024, 768, },
52 	{ 1280,1024, },
53 	{ 1600,1200, },
54 
55 	{  -1,  -1, }
56 };
57 
58 
I_GrabCursor(bool enable)59 void I_GrabCursor(bool enable)
60 {
61 	if (! my_vis || graphics_shutdown)
62 		return;
63 
64 	grab_state = enable;
65 
66 	if (grab_state && in_grab.d)
67 	{
68 		SDL_ShowCursor(0);
69 		SDL_WM_GrabInput(SDL_GRAB_ON);
70 	}
71 	else
72 	{
73 		SDL_ShowCursor(1);
74 		SDL_WM_GrabInput(SDL_GRAB_OFF);
75 	}
76 }
77 
78 
I_StartupGraphics(void)79 void I_StartupGraphics(void)
80 {
81 	if (M_CheckParm("-directx"))
82 		force_directx = true;
83 
84 	if (M_CheckParm("-gdi") || M_CheckParm("-nodirectx"))
85 		force_directx = false;
86 
87 	const char *driver = M_GetParm("-videodriver");
88 
89 	if (! driver)
90 		driver = SDL_getenv("SDL_VIDEODRIVER");
91 
92 	if (! driver)
93 	{
94 		driver = "default";
95 
96 #ifdef WIN32
97 		if (force_directx)
98 			driver = "directx";
99 #endif
100 	}
101 
102 	if (stricmp(driver, "default") != 0)
103 	{
104 		char buffer[200];
105 		snprintf(buffer, sizeof(buffer), "SDL_VIDEODRIVER=%s", driver);
106 		SDL_putenv(buffer);
107 	}
108 
109 	I_Printf("SDL_Video_Driver: %s\n", driver);
110 
111 
112 	if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0)
113 		I_Error("Couldn't init SDL VIDEO!\n%s\n", SDL_GetError());
114 
115 	if (M_CheckParm("-nograb"))
116 		in_grab = 0;
117 
118 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE,     5);
119 	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,   5);
120 	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,    5);
121 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
122 	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,   16);
123 	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
124 
125 
126     // -DS- 2005/06/27 Detect SDL Resolutions
127 	const SDL_VideoInfo *info = SDL_GetVideoInfo();
128 
129 	display_W = info->current_w;
130 	display_H = info->current_h;
131 
132 	I_Printf("Desktop resolution: %dx%d\n", display_W, display_H);
133 
134 	SDL_Rect **modes = SDL_ListModes(info->vfmt,
135 					  SDL_OPENGL | SDL_DOUBLEBUF | SDL_FULLSCREEN);
136 
137 	if (modes && modes != (SDL_Rect **)-1)
138 	{
139 		for (; *modes; modes++)
140 		{
141 			scrmode_c test_mode;
142 
143 			test_mode.width  = (*modes)->w;
144 			test_mode.height = (*modes)->h;
145 			test_mode.depth  = info->vfmt->BitsPerPixel;  // HMMMM ???
146 			test_mode.full   = true;
147 
148 			if ((test_mode.width & 15) != 0)
149 				continue;
150 
151 			if (test_mode.depth == 15 || test_mode.depth == 16 ||
152 			    test_mode.depth == 24 || test_mode.depth == 32)
153 			{
154 				R_AddResolution(&test_mode);
155 			}
156 		}
157 	}
158 
159 	// -ACB- 2000/03/16 Test for possible windowed resolutions
160 	for (int full = 0; full <= 1; full++)
161 	{
162 		for (int depth = 16; depth <= 32; depth = depth+16)
163 		{
164 			for (int i = 0; possible_modes[i].w != -1; i++)
165 			{
166 				scrmode_c mode;
167 
168 				mode.width  = possible_modes[i].w;
169 				mode.height = possible_modes[i].h;
170 				mode.depth  = depth;
171 				mode.full   = full;
172 
173 				int got_depth = SDL_VideoModeOK(mode.width, mode.height,
174 						mode.depth, SDL_OPENGL | SDL_DOUBLEBUF |
175 						(mode.full ? SDL_FULLSCREEN : 0));
176 
177 				if (R_DepthIsEquivalent(got_depth, mode.depth))
178 				{
179 					R_AddResolution(&mode);
180 				}
181 			}
182 		}
183 	}
184 
185 	I_Printf("I_StartupGraphics: initialisation OK\n");
186 }
187 
188 
I_SetScreenSize(scrmode_c * mode)189 bool I_SetScreenSize(scrmode_c *mode)
190 {
191 	I_GrabCursor(false);
192 
193 	I_Printf("I_SetScreenSize: trying %dx%d %dbpp (%s)\n",
194 			 mode->width, mode->height, mode->depth,
195 			 mode->full ? "fullscreen" : "windowed");
196 
197 	my_vis = SDL_SetVideoMode(mode->width, mode->height, mode->depth,
198 					SDL_OPENGL | SDL_DOUBLEBUF |
199 					(mode->full ? SDL_FULLSCREEN : 0));
200 
201 	if (my_vis == NULL)
202 	{
203 		I_Printf("I_SetScreenSize: (mode not possible)\n");
204 		return false;
205 	}
206 
207 	if (my_vis->format->BytesPerPixel <= 1)
208 	{
209 		I_Printf("I_SetScreenSize: 8-bit mode set (not suitable)\n");
210 		return false;
211 	}
212 
213 	I_Printf("I_SetScreenSize: mode now %dx%d %dbpp flags:0x%x\n",
214 			 my_vis->w, my_vis->h,
215 			 my_vis->format->BitsPerPixel, my_vis->flags);
216 
217 	// -AJA- turn off cursor -- BIG performance increase.
218 	//       Plus, the combination of no-cursor + grab gives
219 	//       continuous relative mouse motion.
220 	I_GrabCursor(true);
221 
222 #ifdef DEVELOPERS
223 	// override SDL signal handlers (the so-called "parachute").
224 	signal(SIGFPE,SIG_DFL);
225 	signal(SIGSEGV,SIG_DFL);
226 #endif
227 
228 	glClearColor(0, 0, 0, 0);
229 	glClear(GL_COLOR_BUFFER_BIT);
230 
231 	SDL_GL_SwapBuffers();
232 
233 	return true;
234 }
235 
236 
I_StartFrame(void)237 void I_StartFrame(void)
238 {
239 	glClearColor(0, 0, 0, 0);
240 	glClear(GL_COLOR_BUFFER_BIT);
241 }
242 
243 
I_FinishFrame(void)244 void I_FinishFrame(void)
245 {
246 	SDL_GL_SwapBuffers();
247 
248 	if (in_grab.CheckModified())
249 		I_GrabCursor(grab_state);
250 }
251 
252 
I_PutTitle(const char * title)253 void I_PutTitle(const char *title)
254 {
255 	SDL_WM_SetCaption(title, title);
256 }
257 
I_SetGamma(float gamma)258 void I_SetGamma(float gamma)
259 {
260 	if (SDL_SetGamma(gamma, gamma, gamma) < 0)
261 		I_Printf("Failed to change gamma.\n");
262 }
263 
264 
I_ShutdownGraphics(void)265 void I_ShutdownGraphics(void)
266 {
267 	if (graphics_shutdown)
268 		return;
269 
270 	graphics_shutdown = 1;
271 
272 	if (SDL_WasInit(SDL_INIT_EVERYTHING))
273 	{
274         // reset gamma to default
275         I_SetGamma(1.0f);
276 
277 		SDL_Quit ();
278 	}
279 }
280 
281 
I_GetDesktopSize(int * width,int * height)282 void I_GetDesktopSize(int *width, int *height)
283 {
284 	*width  = display_W;
285 	*height = display_H;
286 }
287 
288 //--- editor settings ---
289 // vi:ts=4:sw=4:noexpandtab
290