implemented a laser pointer
[vrfileman] / src / main.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <SDL2/SDL.h>
4 #include "app.h"
5
6 static void process_event(SDL_Event *ev);
7
8 static SDL_Window *win;
9 static SDL_GLContext ctx;
10 static bool redraw_pending = true;
11 static bool fullscreen, mouse_grabbed;
12 static bool quit;
13
14 static int scale_factor = 1;
15
16 static SDL_Window *create_window(int width, int height)
17 {
18         SDL_Window *win;
19         int x = SDL_WINDOWPOS_UNDEFINED;
20         int y = SDL_WINDOWPOS_UNDEFINED;
21         unsigned int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
22         if(!(win = SDL_CreateWindow("vrfileman", x, y, width, height, flags))) {
23                 return 0;
24         }
25         return win;
26 }
27
28 int main(int argc, char **argv)
29 {
30         if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
31                 fprintf(stderr, "failed to initialize SDL\n");
32                 return 1;
33         }
34
35         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
36         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
37         SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
38
39         if(!(win = create_window(def_opt.width, def_opt.height))) {
40                 // try again without the SRGB capability
41                 SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0);
42                 if(!(win = create_window(def_opt.width, def_opt.height))) {
43                         fprintf(stderr, "failed to create window\n");
44                         return 1;
45                 }
46                 fprintf(stderr, "failed to create sRGB-capable window, defaulting to non-linear color space\n");
47                 def_opt.srgb = false;
48         }
49
50         if(!(ctx = SDL_GL_CreateContext(win))) {
51                 fprintf(stderr, "failed to create OpenGL context\n");
52                 return 1;
53         }
54         SDL_GL_GetDrawableSize(win, &win_width, &win_height);
55         win_aspect = (float)win_width / (float)win_height;
56
57         if(!app_init(argc, argv)) {
58                 SDL_Quit();
59                 return 1;
60         }
61         app_reshape(win_width, win_height);
62
63         while(!quit) {
64                 SDL_Event ev;
65
66                 if(!redraw_pending) {
67                         if(!SDL_WaitEvent(0)) {
68                                 fprintf(stderr, "error while waiting for events\n");
69                                 break;
70                         }
71                 }
72
73                 time_msec = app_get_msec();
74                 time_sec = (double)time_msec / 1000.0;
75                 while(SDL_PollEvent(&ev)) {
76                         process_event(&ev);
77                         if(quit) goto break_evloop;
78                 }
79
80                 if(redraw_pending) {
81                         redraw_pending = false;
82                         app_draw();
83                 }
84         }
85 break_evloop:
86
87         app_cleanup();
88         SDL_Quit();
89         return 0;
90 }
91
92 void app_resize(int x, int y)
93 {
94         SDL_SetWindowSize(win, x, y);
95 }
96
97 void app_fullscreen(bool fs)
98 {
99         SDL_SetWindowFullscreen(win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
100         fullscreen = fs;
101 }
102
103 void app_toggle_fullscreen()
104 {
105         app_fullscreen(!fullscreen);
106 }
107
108 bool app_is_fullscreen()
109 {
110         return fullscreen;
111 }
112
113 void app_grab_mouse(bool grab)
114 {
115         /*SDL_SetWindowGrab(win, grab ? SDL_TRUE : SDL_FALSE);
116         SDL_ShowCursor(grab ? 1 : 0);
117         */
118         SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE);
119         mouse_grabbed = grab;
120 }
121
122 void app_toggle_grab_mouse()
123 {
124         app_grab_mouse(!mouse_grabbed);
125 }
126
127 bool app_is_mouse_grabbed()
128 {
129         return mouse_grabbed;
130 }
131
132 void app_quit()
133 {
134         quit = true;
135 }
136
137 void app_redraw()
138 {
139         redraw_pending = true;
140 }
141
142 void app_swap_buffers()
143 {
144         SDL_GL_SwapWindow(win);
145 }
146
147 long app_get_msec()
148 {
149         return SDL_GetTicks();
150 }
151
152 static void process_event(SDL_Event *ev)
153 {
154         switch(ev->type) {
155         case SDL_QUIT:
156                 quit = true;
157                 break;
158
159         case SDL_KEYDOWN:
160         case SDL_KEYUP:
161                 app_keyboard(ev->key.keysym.sym, ev->key.state == SDL_PRESSED);
162                 break;
163
164         case SDL_MOUSEBUTTONDOWN:
165         case SDL_MOUSEBUTTONUP:
166                 app_mouse_button(ev->button.button - SDL_BUTTON_LEFT, ev->button.state == SDL_PRESSED,
167                                 ev->button.x * scale_factor, ev->button.y * scale_factor);
168                 break;
169
170         case SDL_MOUSEMOTION:
171                 if(mouse_grabbed) {
172                         app_mouse_delta(ev->motion.xrel, ev->motion.yrel);
173                 } else {
174                         app_mouse_motion(ev->motion.x * scale_factor, ev->motion.y * scale_factor);
175                 }
176                 break;
177
178         case SDL_WINDOWEVENT:
179                 if(ev->window.event == SDL_WINDOWEVENT_RESIZED) {
180                         SDL_GL_GetDrawableSize(win, &win_width, &win_height);
181                         win_aspect = (float)win_width / (float)win_height;
182                         scale_factor = win_width / ev->window.data1;
183                         app_reshape(win_width, win_height);
184                 }
185                 break;
186         }
187 }