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