implemented a laser pointer
[vrfileman] / src / main.cc
index 66e8e98..d236a3b 100644 (file)
@@ -8,36 +8,56 @@ static void process_event(SDL_Event *ev);
 static SDL_Window *win;
 static SDL_GLContext ctx;
 static bool redraw_pending = true;
+static bool fullscreen, mouse_grabbed;
 static bool quit;
 
-int main(int argc, char **argv)
-{
-       if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
-               fprintf(stderr, "failed to initialize SDL\n");
-               return 1;
-       }
+static int scale_factor = 1;
 
+static SDL_Window *create_window(int width, int height)
+{
+       SDL_Window *win;
        int x = SDL_WINDOWPOS_UNDEFINED;
        int y = SDL_WINDOWPOS_UNDEFINED;
        unsigned int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
-       win_width = 1280;
-       win_height = 800;
-       if(!(win = SDL_CreateWindow("vrfileman", x, y, win_width, win_height, flags))) {
-               fprintf(stderr, "failed to create window\n");
+       if(!(win = SDL_CreateWindow("vrfileman", x, y, width, height, flags))) {
+               return 0;
+       }
+       return win;
+}
+
+int main(int argc, char **argv)
+{
+       if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
+               fprintf(stderr, "failed to initialize SDL\n");
                return 1;
        }
 
-       SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-       SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
-       SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
-       SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
+       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
        SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
 
+       if(!(win = create_window(def_opt.width, def_opt.height))) {
+               // try again without the SRGB capability
+               SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 0);
+               if(!(win = create_window(def_opt.width, def_opt.height))) {
+                       fprintf(stderr, "failed to create window\n");
+                       return 1;
+               }
+               fprintf(stderr, "failed to create sRGB-capable window, defaulting to non-linear color space\n");
+               def_opt.srgb = false;
+       }
+
        if(!(ctx = SDL_GL_CreateContext(win))) {
                fprintf(stderr, "failed to create OpenGL context\n");
                return 1;
        }
        SDL_GL_GetDrawableSize(win, &win_width, &win_height);
+       win_aspect = (float)win_width / (float)win_height;
+
+       if(!app_init(argc, argv)) {
+               SDL_Quit();
+               return 1;
+       }
        app_reshape(win_width, win_height);
 
        while(!quit) {
@@ -51,6 +71,7 @@ int main(int argc, char **argv)
                }
 
                time_msec = app_get_msec();
+               time_sec = (double)time_msec / 1000.0;
                while(SDL_PollEvent(&ev)) {
                        process_event(&ev);
                        if(quit) goto break_evloop;
@@ -68,6 +89,51 @@ break_evloop:
        return 0;
 }
 
+void app_resize(int x, int y)
+{
+       SDL_SetWindowSize(win, x, y);
+}
+
+void app_fullscreen(bool fs)
+{
+       SDL_SetWindowFullscreen(win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+       fullscreen = fs;
+}
+
+void app_toggle_fullscreen()
+{
+       app_fullscreen(!fullscreen);
+}
+
+bool app_is_fullscreen()
+{
+       return fullscreen;
+}
+
+void app_grab_mouse(bool grab)
+{
+       /*SDL_SetWindowGrab(win, grab ? SDL_TRUE : SDL_FALSE);
+       SDL_ShowCursor(grab ? 1 : 0);
+       */
+       SDL_SetRelativeMouseMode(grab ? SDL_TRUE : SDL_FALSE);
+       mouse_grabbed = grab;
+}
+
+void app_toggle_grab_mouse()
+{
+       app_grab_mouse(!mouse_grabbed);
+}
+
+bool app_is_mouse_grabbed()
+{
+       return mouse_grabbed;
+}
+
+void app_quit()
+{
+       quit = true;
+}
+
 void app_redraw()
 {
        redraw_pending = true;
@@ -82,3 +148,40 @@ long app_get_msec()
 {
        return SDL_GetTicks();
 }
+
+static void process_event(SDL_Event *ev)
+{
+       switch(ev->type) {
+       case SDL_QUIT:
+               quit = true;
+               break;
+
+       case SDL_KEYDOWN:
+       case SDL_KEYUP:
+               app_keyboard(ev->key.keysym.sym, ev->key.state == SDL_PRESSED);
+               break;
+
+       case SDL_MOUSEBUTTONDOWN:
+       case SDL_MOUSEBUTTONUP:
+               app_mouse_button(ev->button.button - SDL_BUTTON_LEFT, ev->button.state == SDL_PRESSED,
+                               ev->button.x * scale_factor, ev->button.y * scale_factor);
+               break;
+
+       case SDL_MOUSEMOTION:
+               if(mouse_grabbed) {
+                       app_mouse_delta(ev->motion.xrel, ev->motion.yrel);
+               } else {
+                       app_mouse_motion(ev->motion.x * scale_factor, ev->motion.y * scale_factor);
+               }
+               break;
+
+       case SDL_WINDOWEVENT:
+               if(ev->window.event == SDL_WINDOWEVENT_RESIZED) {
+                       SDL_GL_GetDrawableSize(win, &win_width, &win_height);
+                       win_aspect = (float)win_width / (float)win_height;
+                       scale_factor = win_width / ev->window.data1;
+                       app_reshape(win_width, win_height);
+               }
+               break;
+       }
+}