rev |
line source |
nuclear@20
|
1 /* SimplyGL window system module for SDL */
|
nuclear@20
|
2 /* link-with: `sdl-config --libs` */
|
nuclear@20
|
3
|
nuclear@20
|
4 #include "config.h"
|
nuclear@20
|
5
|
nuclear@20
|
6 #ifdef USE_WSYS_MODULE_SDL
|
nuclear@20
|
7
|
nuclear@20
|
8 #include <SDL/SDL.h>
|
nuclear@20
|
9 #include "sgl.h"
|
nuclear@20
|
10 #include "wsys.h"
|
nuclear@20
|
11
|
nuclear@20
|
12
|
nuclear@20
|
13
|
nuclear@20
|
14 static int init(void);
|
nuclear@20
|
15 static void shutdown(void);
|
nuclear@20
|
16
|
nuclear@20
|
17 /* video mode switching */
|
nuclear@20
|
18 static int set_vidmode(int xsz, int ysz);
|
nuclear@20
|
19 static int get_vidmode(int *xsz, int *ysz);
|
nuclear@20
|
20
|
nuclear@20
|
21 /* create/destroy windows */
|
nuclear@20
|
22 static int create_window(int xsz, int ysz, unsigned int flags);
|
nuclear@20
|
23 static void close_window(int wid);
|
nuclear@20
|
24
|
nuclear@20
|
25 /* window management */
|
nuclear@20
|
26 static int set_active(int wid);
|
nuclear@20
|
27 static int set_title(const char *str);
|
nuclear@20
|
28 static void redisplay(void);
|
nuclear@20
|
29 static void swap_buffers(void);
|
nuclear@20
|
30
|
nuclear@20
|
31 static int get_modifiers(void);
|
nuclear@20
|
32
|
nuclear@20
|
33 /* event handling and friends */
|
nuclear@20
|
34 static void set_event(int idx, int enable);
|
nuclear@20
|
35 static int process_events(void);
|
nuclear@20
|
36 static int handle_event(SDL_Event *ev);
|
nuclear@20
|
37
|
nuclear@20
|
38
|
nuclear@20
|
39 static struct wsys_module ws = {
|
nuclear@20
|
40 "sdl", 6,
|
nuclear@20
|
41 init,
|
nuclear@20
|
42 shutdown,
|
nuclear@20
|
43 set_vidmode,
|
nuclear@20
|
44 get_vidmode,
|
nuclear@20
|
45 create_window,
|
nuclear@20
|
46 close_window,
|
nuclear@20
|
47 set_active,
|
nuclear@20
|
48 set_title,
|
nuclear@20
|
49 redisplay,
|
nuclear@20
|
50 swap_buffers,
|
nuclear@20
|
51 get_modifiers,
|
nuclear@20
|
52 set_event,
|
nuclear@20
|
53 process_events,
|
nuclear@20
|
54 0
|
nuclear@20
|
55 };
|
nuclear@20
|
56
|
nuclear@20
|
57 static int must_redisplay = 1;
|
nuclear@20
|
58 static int win_width, win_height;
|
nuclear@20
|
59 static unsigned int sdl_flags;
|
nuclear@20
|
60
|
nuclear@20
|
61
|
nuclear@20
|
62 void sgl_register_sdl(void)
|
nuclear@20
|
63 {
|
nuclear@20
|
64 sgl_register_module(&ws);
|
nuclear@20
|
65 }
|
nuclear@20
|
66
|
nuclear@20
|
67
|
nuclear@20
|
68 static int init(void)
|
nuclear@20
|
69 {
|
nuclear@20
|
70 return SDL_Init(SDL_INIT_VIDEO);
|
nuclear@20
|
71 }
|
nuclear@20
|
72
|
nuclear@20
|
73 static void shutdown(void)
|
nuclear@20
|
74 {
|
nuclear@20
|
75 SDL_Quit();
|
nuclear@20
|
76 }
|
nuclear@20
|
77
|
nuclear@20
|
78 /* video mode switching */
|
nuclear@20
|
79 static int set_vidmode(int xsz, int ysz)
|
nuclear@20
|
80 {
|
nuclear@20
|
81 return 0; /* TODO */
|
nuclear@20
|
82 }
|
nuclear@20
|
83
|
nuclear@20
|
84 static int get_vidmode(int *xsz, int *ysz)
|
nuclear@20
|
85 {
|
nuclear@20
|
86 return 0; /* TODO */
|
nuclear@20
|
87 }
|
nuclear@20
|
88
|
nuclear@20
|
89 /* create/destroy windows */
|
nuclear@20
|
90 static int create_window(int xsz, int ysz, unsigned int flags)
|
nuclear@20
|
91 {
|
nuclear@20
|
92 void (*func)();
|
nuclear@20
|
93
|
nuclear@20
|
94 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
nuclear@20
|
95 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
nuclear@20
|
96 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
nuclear@20
|
97
|
nuclear@20
|
98 if(flags & SGL_DOUBLE) {
|
nuclear@20
|
99 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
nuclear@20
|
100 }
|
nuclear@20
|
101 if(flags & SGL_DEPTH) {
|
nuclear@20
|
102 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
nuclear@20
|
103 }
|
nuclear@20
|
104 if(flags & SGL_STENCIL) {
|
nuclear@20
|
105 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
nuclear@20
|
106 }
|
nuclear@20
|
107 if(flags & SGL_STEREO) {
|
nuclear@20
|
108 SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
|
nuclear@20
|
109 }
|
nuclear@20
|
110 if(flags & SGL_MULTISAMPLE) {
|
nuclear@20
|
111 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
nuclear@20
|
112 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
nuclear@20
|
113 }
|
nuclear@20
|
114
|
nuclear@20
|
115 sdl_flags = SDL_OPENGL | SDL_RESIZABLE;
|
nuclear@20
|
116
|
nuclear@20
|
117 if(!SDL_SetVideoMode(xsz, ysz, 32, sdl_flags)) {
|
nuclear@20
|
118 return -1;
|
nuclear@20
|
119 }
|
nuclear@20
|
120 win_width = xsz;
|
nuclear@20
|
121 win_height = ysz;
|
nuclear@20
|
122 set_title("OpenGL/SDL");
|
nuclear@20
|
123
|
nuclear@20
|
124 if((func = sgl_get_callback(SGL_CREATE))) {
|
nuclear@20
|
125 func(0);
|
nuclear@20
|
126 }
|
nuclear@20
|
127 if((func = sgl_get_callback(SGL_RESHAPE))) {
|
nuclear@20
|
128 func(xsz, ysz);
|
nuclear@20
|
129 }
|
nuclear@20
|
130
|
nuclear@20
|
131 return 0;
|
nuclear@20
|
132 }
|
nuclear@20
|
133
|
nuclear@20
|
134 static void close_window(int wid)
|
nuclear@20
|
135 {
|
nuclear@20
|
136 SDL_Quit();
|
nuclear@20
|
137 }
|
nuclear@20
|
138
|
nuclear@20
|
139 /* window management */
|
nuclear@20
|
140 static int set_active(int wid)
|
nuclear@20
|
141 {
|
nuclear@20
|
142 return 0; /* only one window is supported in SDL */
|
nuclear@20
|
143 }
|
nuclear@20
|
144
|
nuclear@20
|
145 static int set_title(const char *str)
|
nuclear@20
|
146 {
|
nuclear@20
|
147 SDL_WM_SetCaption(str, str);
|
nuclear@20
|
148 return 0;
|
nuclear@20
|
149 }
|
nuclear@20
|
150
|
nuclear@20
|
151 static void redisplay(void)
|
nuclear@20
|
152 {
|
nuclear@20
|
153 must_redisplay = 1;
|
nuclear@20
|
154 }
|
nuclear@20
|
155
|
nuclear@20
|
156 static void swap_buffers(void)
|
nuclear@20
|
157 {
|
nuclear@20
|
158 SDL_GL_SwapBuffers();
|
nuclear@20
|
159 }
|
nuclear@20
|
160
|
nuclear@20
|
161 static int get_modifiers(void)
|
nuclear@20
|
162 {
|
nuclear@20
|
163 int mod = 0;
|
nuclear@20
|
164 SDLMod sdlmod = SDL_GetModState();
|
nuclear@20
|
165
|
nuclear@20
|
166 if(sdlmod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
|
nuclear@20
|
167 mod |= SGL_MOD_SHIFT;
|
nuclear@20
|
168 }
|
nuclear@20
|
169 if(sdlmod & (KMOD_LCTRL | KMOD_RCTRL)) {
|
nuclear@20
|
170 mod |= SGL_MOD_CONTROL;
|
nuclear@20
|
171 }
|
nuclear@20
|
172 if(sdlmod & (KMOD_LALT | KMOD_RALT)) {
|
nuclear@20
|
173 mod |= SGL_MOD_ALT;
|
nuclear@20
|
174 }
|
nuclear@20
|
175 return mod;
|
nuclear@20
|
176 }
|
nuclear@20
|
177
|
nuclear@20
|
178 /* event handling and friends */
|
nuclear@20
|
179 static void set_event(int idx, int enable)
|
nuclear@20
|
180 {
|
nuclear@20
|
181 /* no need to do anything for SDL */
|
nuclear@20
|
182 }
|
nuclear@20
|
183
|
nuclear@20
|
184 static int process_events(void)
|
nuclear@20
|
185 {
|
nuclear@20
|
186 int got_event;
|
nuclear@20
|
187 SDL_Event ev;
|
nuclear@20
|
188 sgl_idle_callback_t idle = sgl_get_callback(SGL_IDLE);
|
nuclear@20
|
189 sgl_display_callback_t disp = sgl_get_callback(SGL_DISPLAY);
|
nuclear@20
|
190
|
nuclear@20
|
191 if(must_redisplay && disp) {
|
nuclear@20
|
192 disp();
|
nuclear@20
|
193 must_redisplay = 0;
|
nuclear@20
|
194 }
|
nuclear@20
|
195
|
nuclear@20
|
196 if(idle) {
|
nuclear@20
|
197 got_event = SDL_PollEvent(&ev);
|
nuclear@20
|
198 } else {
|
nuclear@20
|
199 if(!SDL_WaitEvent(&ev)) {
|
nuclear@20
|
200 return -1;
|
nuclear@20
|
201 }
|
nuclear@20
|
202 got_event = 1;
|
nuclear@20
|
203 }
|
nuclear@20
|
204
|
nuclear@20
|
205 if(got_event) {
|
nuclear@20
|
206 do {
|
nuclear@20
|
207 if(handle_event(&ev) == -1) {
|
nuclear@20
|
208 return -1;
|
nuclear@20
|
209 }
|
nuclear@20
|
210 } while(SDL_PollEvent(&ev));
|
nuclear@20
|
211 }
|
nuclear@20
|
212
|
nuclear@20
|
213 if(idle) {
|
nuclear@20
|
214 idle();
|
nuclear@20
|
215 }
|
nuclear@20
|
216
|
nuclear@20
|
217 return 0;
|
nuclear@20
|
218 }
|
nuclear@20
|
219
|
nuclear@20
|
220 static int handle_event(SDL_Event *ev)
|
nuclear@20
|
221 {
|
nuclear@20
|
222 void (*func)();
|
nuclear@20
|
223
|
nuclear@20
|
224 switch(ev->type) {
|
nuclear@20
|
225 case SDL_VIDEORESIZE:
|
nuclear@20
|
226 /* XXX this'll fuck up big time on windows, will lose the gl state! */
|
nuclear@20
|
227 SDL_SetVideoMode(ev->resize.w, ev->resize.h, 32, sdl_flags);
|
nuclear@20
|
228
|
nuclear@20
|
229 if((func = sgl_get_callback(SGL_RESHAPE)) &&
|
nuclear@20
|
230 (ev->resize.w != win_width || ev->resize.h != win_height)) {
|
nuclear@20
|
231 win_width = ev->resize.w;
|
nuclear@20
|
232 win_height = ev->resize.h;
|
nuclear@20
|
233
|
nuclear@20
|
234 func(win_width, win_height);
|
nuclear@20
|
235 }
|
nuclear@20
|
236 break;
|
nuclear@20
|
237
|
nuclear@20
|
238 case SDL_VIDEOEXPOSE:
|
nuclear@20
|
239 must_redisplay = 1;
|
nuclear@20
|
240 break;
|
nuclear@20
|
241
|
nuclear@20
|
242 case SDL_KEYDOWN:
|
nuclear@20
|
243 case SDL_KEYUP:
|
nuclear@20
|
244 if((func = sgl_get_callback(SGL_KEYBOARD))) {
|
nuclear@20
|
245 func(ev->key.keysym.sym, ev->key.state == SDL_PRESSED);
|
nuclear@20
|
246 }
|
nuclear@20
|
247 break;
|
nuclear@20
|
248
|
nuclear@20
|
249 case SDL_MOUSEBUTTONDOWN:
|
nuclear@20
|
250 case SDL_MOUSEBUTTONUP:
|
nuclear@20
|
251 if((func = sgl_get_callback(SGL_MOUSE))) {
|
nuclear@20
|
252 func(ev->button.which - 1, ev->button.state == SDL_PRESSED, ev->button.x, ev->button.y);
|
nuclear@20
|
253 }
|
nuclear@20
|
254 break;
|
nuclear@20
|
255
|
nuclear@20
|
256 case SDL_MOUSEMOTION:
|
nuclear@20
|
257 if(ev->motion.state) {
|
nuclear@20
|
258 func = sgl_get_callback(SGL_MOTION);
|
nuclear@20
|
259 } else {
|
nuclear@20
|
260 func = sgl_get_callback(SGL_PASSIVE);
|
nuclear@20
|
261 }
|
nuclear@20
|
262
|
nuclear@20
|
263 if(func) {
|
nuclear@20
|
264 func(ev->motion.x, ev->motion.y);
|
nuclear@20
|
265 }
|
nuclear@20
|
266 break;
|
nuclear@20
|
267
|
nuclear@20
|
268 case SDL_QUIT:
|
nuclear@20
|
269 return -1;
|
nuclear@20
|
270 }
|
nuclear@20
|
271
|
nuclear@20
|
272 return 0;
|
nuclear@20
|
273 }
|
nuclear@20
|
274
|
nuclear@20
|
275 #else
|
nuclear@20
|
276 int sgl_wsys_sdl_silence_the_fucking_empty_file_warnings;
|
nuclear@20
|
277 #endif /* USE_WSYS_MODULE_SDL */
|