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