fullscreen and mouse grab
[deeprace] / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include "miniglut.h"
5 #include "game.h"
6
7 static void idle(void);
8 static void reshape(int x, int y);
9 static void keydown(unsigned char key, int x, int y);
10 static void keyup(unsigned char key, int x, int y);
11 static void skeydown(int key, int x, int y);
12 static void skeyup(int key, int x, int y);
13 static void mouse(int bn, int st, int x, int y);
14 static void motion(int x, int y);
15 static int translate_skey(int key);
16
17 static int warping;
18
19 int main(int argc, char **argv)
20 {
21         glutInit(&argc, argv);
22         glutInitWindowSize(640, 480);
23         glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
24         glutCreateWindow("deeprace");
25
26         glutDisplayFunc(game_display);
27         glutIdleFunc(idle);
28         glutReshapeFunc(reshape);
29         glutKeyboardFunc(keydown);
30         glutKeyboardUpFunc(keyup);
31         glutSpecialFunc(skeydown);
32         glutSpecialUpFunc(skeyup);
33         glutMouseFunc(mouse);
34         glutMotionFunc(motion);
35         glutPassiveMotionFunc(motion);
36
37         if(game_init() == -1) {
38                 return 1;
39         }
40         atexit(game_shutdown);
41         glutMainLoop();
42         return 0;
43 }
44
45 void game_swap_buffers(void)
46 {
47         glutSwapBuffers();
48         assert(glGetError() == GL_NO_ERROR);
49 }
50
51 void game_quit(void)
52 {
53         exit(0);
54 }
55
56 void game_fullscreen(int fs)
57 {
58         static int prev_w, prev_h;
59         static int prev_grab;
60
61         if(fs == -1) {
62                 fs = !fullscr;
63         }
64
65         if(fs == fullscr) return;
66
67         if(fs) {
68                 prev_w = glutGet(GLUT_WINDOW_WIDTH);
69                 prev_h = glutGet(GLUT_WINDOW_HEIGHT);
70                 prev_grab = mouse_grabbed;
71                 game_grabmouse(1);
72                 glutFullScreen();
73         } else {
74                 glutReshapeWindow(prev_w, prev_h);
75                 if(!prev_grab) {
76                         game_grabmouse(0);
77                 }
78         }
79         fullscr = fs;
80 }
81
82 void game_grabmouse(int grab)
83 {
84         static int prev_x, prev_y;
85
86         if(grab == -1) {
87                 grab = !mouse_grabbed;
88         }
89
90         if(grab == mouse_grabbed) return;
91
92         if(grab) {
93                 warping = 1;
94                 prev_x = mouse_x;
95                 prev_y = mouse_y;
96                 glutWarpPointer(win_width / 2, win_height / 2);
97                 glutSetCursor(GLUT_CURSOR_NONE);
98         } else {
99                 warping = 1;
100                 glutWarpPointer(prev_x, prev_y);
101                 glutSetCursor(GLUT_CURSOR_INHERIT);
102         }
103         mouse_grabbed = grab;
104 }
105
106
107 static void idle(void)
108 {
109         glutPostRedisplay();
110 }
111
112 static void reshape(int x, int y)
113 {
114         if(fullscr) {
115                 warping = 1;
116                 glutWarpPointer(x / 2, y / 2);
117         }
118         game_reshape(x, y);
119 }
120
121 static void keydown(unsigned char key, int x, int y)
122 {
123         modkeys = glutGetModifiers();
124         game_keyboard(key, 1);
125 }
126
127 static void keyup(unsigned char key, int x, int y)
128 {
129         game_keyboard(key, 0);
130 }
131
132 static void skeydown(int key, int x, int y)
133 {
134         int k;
135         modkeys = glutGetModifiers();
136         if((k = translate_skey(key)) >= 0) {
137                 game_keyboard(k, 1);
138         }
139 }
140
141 static void skeyup(int key, int x, int y)
142 {
143         int k = translate_skey(key);
144         if(k >= 0) {
145                 game_keyboard(k, 0);
146         }
147 }
148
149 static void mouse(int bn, int st, int x, int y)
150 {
151         modkeys = glutGetModifiers();
152         game_mouse(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y);
153 }
154
155 static void motion(int x, int y)
156 {
157         if(mouse_grabbed) {
158                 if(!warping) {
159                         game_motion(x, y);
160                         warping = 1;
161                         glutWarpPointer(win_width / 2, win_height / 2);
162                 } else {
163                         warping = 0;
164                 }
165         } else {
166                 game_motion(x, y);
167         }
168 }
169
170 static int translate_skey(int key)
171 {
172         switch(key) {
173         case GLUT_KEY_LEFT:
174                 return GKEY_LEFT;
175         case GLUT_KEY_UP:
176                 return GKEY_UP;
177         case GLUT_KEY_RIGHT:
178                 return GKEY_RIGHT;
179         case GLUT_KEY_DOWN:
180                 return GKEY_DOWN;
181         case GLUT_KEY_PAGE_UP:
182                 return GKEY_PGUP;
183         case GLUT_KEY_PAGE_DOWN:
184                 return GKEY_PGDOWN;
185         case GLUT_KEY_HOME:
186                 return GKEY_HOME;
187         case GLUT_KEY_END:
188                 return GKEY_END;
189         case GLUT_KEY_INSERT:
190                 return GKEY_INS;
191         default:
192                 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
193                         return key - GLUT_KEY_F1 + GKEY_F1;
194                 }
195         }
196
197         return -1;
198 }