converted OggVorbisStream to use assman
[laserbrain_demo] / src / main.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <GL/glew.h>
5 #include <SDL2/SDL.h>
6 #include "app.h"
7
8 static bool init(int argc, char **argv);
9 static void process_event(SDL_Event *ev);
10 static void proc_modkeys();
11 static int translate_keysym(SDL_Keycode sym);
12
13 static SDL_Window *win;
14 static SDL_GLContext ctx;
15 static bool fullscreen, mouse_grabbed;
16 static bool quit;
17
18 static unsigned int start_time;
19 static unsigned int modkeys;
20
21 SDL_GameController *gamepad;
22
23 static int scale_factor = 1;
24
25 int main(int argc, char **argv)
26 {
27         if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
28                 fprintf(stderr, "failed to initialize SDL\n");
29                 return 1;
30         }
31
32         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
33         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
34         SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
35 #ifndef NDEBUG
36         SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
37 #endif
38
39         int defpos = SDL_WINDOWPOS_UNDEFINED;
40         unsigned int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
41
42         if(!(win = SDL_CreateWindow("demo", defpos, defpos, 1024, 768, sdlflags))) {
43                 // try again without sRGB capability
44                 SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0);
45                 if(!(win = SDL_CreateWindow("demo", defpos, defpos, 1024, 768, sdlflags))) {
46                         fprintf(stderr, "failed to create window\n");
47                         SDL_Quit();
48                         return 1;
49                 }
50                 fprintf(stderr, "failed to get an sRGB framebuffer.\n");
51         }
52         int val;
53         SDL_GL_GetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, &val);
54         printf("SDL says we %s an sRGB framebuffer\n", val ? "got" : "didn't get");
55         fb_srgb = val;
56
57         if(!(ctx = SDL_GL_CreateContext(win))) {
58                 fprintf(stderr, "failed to create OpenGL context\n");
59                 SDL_Quit();
60                 return 1;
61         }
62         SDL_GL_GetDrawableSize(win, &win_width, &win_height);
63         win_aspect = (float)win_width / (float)win_height;
64
65         printf("detected %d joysticks\n", SDL_NumJoysticks());
66         for(int i=0; i<SDL_NumJoysticks(); i++) {
67                 if(SDL_IsGameController(i)) {
68                         if(!(gamepad = SDL_GameControllerOpen(i))) {
69                                 fprintf(stderr, "failed to open game controller %i: %s\n", i, SDL_GetError());
70                                 continue;
71                         }
72                         printf("Using gamepad: %s\n", SDL_GameControllerNameForIndex(i));
73                 }
74         }
75
76         if(!init(argc, argv)) {
77                 SDL_Quit();
78                 return 1;
79         }
80         app_reshape(win_width, win_height);
81
82         SDL_RaiseWindow(win);
83
84         while(!quit) {
85                 SDL_Event ev;
86
87                 time_msec = SDL_GetTicks() - start_time;
88                 while(SDL_PollEvent(&ev)) {
89                         process_event(&ev);
90                         if(quit) goto break_evloop;
91                 }
92
93                 app_display();
94         }
95 break_evloop:
96
97         app_cleanup();
98         SDL_Quit();
99         return 0;
100 }
101
102 void app_swap_buffers()
103 {
104         SDL_GL_SwapWindow(win);
105 }
106
107 void app_quit()
108 {
109         quit = true;
110 }
111
112 unsigned int app_get_modifiers()
113 {
114         return modkeys;
115 }
116
117 void app_resize(int x, int y)
118 {
119         SDL_SetWindowSize(win, x, y);
120 }
121
122 void app_fullscreen(bool fs)
123 {
124         SDL_SetWindowFullscreen(win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
125         fullscreen = fs;
126 }
127
128 void app_toggle_fullscreen()
129 {
130         app_fullscreen(!fullscreen);
131 }
132
133 bool app_is_fullscreen()
134 {
135         return fullscreen;
136 }
137
138 void app_grab_mouse(bool grab)
139 {
140         if(grab) {
141                 SDL_WarpMouseInWindow(win, win_width / 2, win_height / 2);
142         }
143         //SDL_SetWindowGrab(win, grab ? SDL_TRUE : SDL_FALSE);
144         //SDL_ShowCursor(grab ? 1 : 0);
145         SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE);
146         mouse_grabbed = grab;
147 }
148
149 void app_toggle_grab_mouse()
150 {
151         app_grab_mouse(!mouse_grabbed);
152 }
153
154 bool app_is_mouse_grabbed()
155 {
156         return mouse_grabbed;
157 }
158
159
160 static bool init(int argc, char **argv)
161 {
162         if(!app_init(argc, argv)) {
163                 return false;
164         }
165
166         start_time = SDL_GetTicks();
167         return true;
168 }
169
170 static void process_event(SDL_Event *ev)
171 {
172         int key;
173
174         switch(ev->type) {
175         case SDL_QUIT:
176                 quit = true;
177                 break;
178
179         case SDL_KEYDOWN:
180         case SDL_KEYUP:
181                 proc_modkeys();
182                 if((key = translate_keysym(ev->key.keysym.sym)) != -1) {
183                         app_keyboard(key, ev->key.state == SDL_PRESSED);
184                 }
185                 break;
186
187         case SDL_MOUSEBUTTONDOWN:
188         case SDL_MOUSEBUTTONUP:
189                 proc_modkeys();
190                 app_mouse_button(ev->button.button - SDL_BUTTON_LEFT, ev->button.state == SDL_PRESSED,
191                                 ev->button.x * scale_factor, ev->button.y * scale_factor);
192                 break;
193
194         case SDL_MOUSEMOTION:
195                 if(mouse_grabbed) {
196                         app_mouse_delta(ev->motion.xrel, ev->motion.yrel);
197                 } else {
198                         app_mouse_motion(ev->motion.x * scale_factor, ev->motion.y * scale_factor);
199                 }
200                 break;
201
202         case SDL_MOUSEWHEEL:
203                 app_mouse_wheel(ev->wheel.y);
204                 break;
205
206         case SDL_WINDOWEVENT:
207                 if(ev->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
208                         SDL_GL_GetDrawableSize(win, &win_width, &win_height);
209                         win_aspect = (float)win_width / (float)win_height;
210                         scale_factor = win_width / ev->window.data1;
211                         app_reshape(win_width, win_height);
212                 }
213                 break;
214
215         case SDL_CONTROLLERAXISMOTION:
216                 app_gamepad_axis(ev->caxis.axis, ev->caxis.value / 32768.0f);
217                 break;
218
219         case SDL_CONTROLLERBUTTONDOWN:
220         case SDL_CONTROLLERBUTTONUP:
221                 app_gamepad_button(ev->cbutton.button, ev->type == SDL_CONTROLLERBUTTONDOWN);
222                 break;
223         }
224 }
225
226 static void proc_modkeys()
227 {
228         modkeys = 0;
229         SDL_Keymod sdlmod = SDL_GetModState();
230         if(sdlmod & KMOD_SHIFT) {
231                 modkeys |= MOD_SHIFT;
232         }
233         if(sdlmod & KMOD_ALT) {
234                 modkeys |= MOD_ALT;
235         }
236         if(sdlmod & KMOD_CTRL) {
237                 modkeys |= MOD_CTRL;
238         }
239 }
240
241 static int translate_keysym(SDL_Keycode sym)
242 {
243         switch(sym) {
244         case SDLK_RETURN:
245                 return '\n';
246         case SDLK_DELETE:
247                 return KEY_DEL;
248         case SDLK_LEFT:
249                 return KEY_LEFT;
250         case SDLK_RIGHT:
251                 return KEY_RIGHT;
252         case SDLK_UP:
253                 return KEY_UP;
254         case SDLK_DOWN:
255                 return KEY_DOWN;
256         case SDLK_PAGEUP:
257                 return KEY_PGUP;
258         case SDLK_PAGEDOWN:
259                 return KEY_PGDOWN;
260         case SDLK_HOME:
261                 return KEY_HOME;
262         case SDLK_END:
263                 return KEY_END;
264         default:
265                 break;
266         }
267
268         if(sym < 127) {
269                 return sym;
270         }
271         if(sym >= SDLK_F1 && sym <= SDLK_F12) {
272                 return KEY_F1 + sym - SDLK_F1;
273         }
274         return -1;
275 }