foo
[raydungeon] / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include "opengl.h"
5 #include "miniglut.h"
6 #include "game.h"
7
8 static void idle(void);
9 static void reshape(int x, int y);
10 static void keydown(unsigned char key, int x, int y);
11 static void keyup(unsigned char key, int x, int y);
12 static void skeydown(int key, int x, int y);
13 static void skeyup(int key, int x, int y);
14 static void mouse(int bn, int st, int x, int y);
15 static void motion(int x, int y);
16 static int translate_skey(int key);
17
18 static int warping;
19
20 #if defined(__unix__) || defined(unix)
21 #include <GL/glx.h>
22 static Display *xdpy;
23 static Window xwin;
24
25 static void (*glx_swap_interval_ext)();
26 static void (*glx_swap_interval_sgi)();
27 #endif
28 #ifdef _WIN32
29 #include <windows.h>
30 static PROC wgl_swap_interval_ext;
31 #endif
32
33
34
35 int main(int argc, char **argv)
36 {
37         glutInit(&argc, argv);
38         glutInitWindowSize(1280, 800);
39         glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
40         glutCreateWindow("raydungeon");
41
42         glutDisplayFunc(game_display);
43         glutIdleFunc(idle);
44         glutReshapeFunc(reshape);
45         glutKeyboardFunc(keydown);
46         glutKeyboardUpFunc(keyup);
47         glutSpecialFunc(skeydown);
48         glutSpecialUpFunc(skeyup);
49         glutMouseFunc(mouse);
50         glutMotionFunc(motion);
51         glutPassiveMotionFunc(motion);
52
53         if(init_opengl() == -1) {
54                 return 1;
55         }
56
57 #if defined(__unix__) || defined(unix)
58         xdpy = glXGetCurrentDisplay();
59         xwin = glXGetCurrentDrawable();
60
61         if(!(glx_swap_interval_ext = glXGetProcAddress((unsigned char*)"glXSwapIntervalEXT"))) {
62                 glx_swap_interval_sgi = glXGetProcAddress((unsigned char*)"glXSwapIntervalSGI");
63         }
64 #endif
65 #ifdef _WIN32
66         wgl_swap_interval_ext = wglGetProcAddress("wglSwapIntervalEXT");
67 #endif
68
69         game_reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
70
71         if(game_init(argc, argv) == -1) {
72                 return 1;
73         }
74         atexit(game_shutdown);
75         glutMainLoop();
76         return 0;
77 }
78
79 long game_getmsec(void)
80 {
81         return glutGet(GLUT_ELAPSED_TIME);
82 }
83
84 void game_swap_buffers(void)
85 {
86         glutSwapBuffers();
87         assert(glGetError() == GL_NO_ERROR);
88 }
89
90 void game_quit(void)
91 {
92         exit(0);
93 }
94
95 void game_resize(int x, int y)
96 {
97         if(x == win_width && y == win_height) return;
98
99         glutReshapeWindow(x, y);
100 }
101
102 void game_fullscreen(int fs)
103 {
104         static int prev_w, prev_h;
105         static int prev_grab;
106
107         if(fs == -1) {
108                 fs = !fullscr;
109         }
110
111         if(fs == fullscr) return;
112
113         if(fs) {
114                 prev_w = glutGet(GLUT_WINDOW_WIDTH);
115                 prev_h = glutGet(GLUT_WINDOW_HEIGHT);
116                 prev_grab = mouse_grabbed;
117                 game_grabmouse(1);
118                 glutFullScreen();
119         } else {
120                 glutReshapeWindow(prev_w, prev_h);
121                 if(!prev_grab) {
122                         game_grabmouse(0);
123                 }
124         }
125         fullscr = fs;
126 }
127
128 void game_grabmouse(int grab)
129 {
130         static int prev_x, prev_y;
131
132         if(grab == -1) {
133                 grab = !mouse_grabbed;
134         }
135
136         if(grab == mouse_grabbed) return;
137
138         if(grab) {
139                 warping = 1;
140                 prev_x = mouse_x;
141                 prev_y = mouse_y;
142                 glutWarpPointer(win_width / 2, win_height / 2);
143                 glutSetCursor(GLUT_CURSOR_NONE);
144         } else {
145                 warping = 1;
146                 glutWarpPointer(prev_x, prev_y);
147                 glutSetCursor(GLUT_CURSOR_INHERIT);
148         }
149         mouse_grabbed = grab;
150 }
151
152 #if defined(__unix__) || defined(unix)
153 void game_vsync(int vsync)
154 {
155         vsync = vsync ? 1 : 0;
156         if(glx_swap_interval_ext) {
157                 glx_swap_interval_ext(xdpy, xwin, vsync);
158         } else if(glx_swap_interval_sgi) {
159                 glx_swap_interval_sgi(vsync);
160         }
161 }
162 #endif
163 #ifdef WIN32
164 void game_vsync(int vsync)
165 {
166         if(wgl_swap_interval_ext) {
167                 wgl_swap_interval_ext(vsync ? 1 : 0);
168         }
169 }
170 #endif
171
172
173
174 static void idle(void)
175 {
176         glutPostRedisplay();
177 }
178
179 static void reshape(int x, int y)
180 {
181         if(fullscr) {
182                 warping = 1;
183                 glutWarpPointer(x / 2, y / 2);
184         }
185         game_reshape(x, y);
186 }
187
188 static void keydown(unsigned char key, int x, int y)
189 {
190         modkeys = glutGetModifiers();
191         game_keyboard(key, 1);
192 }
193
194 static void keyup(unsigned char key, int x, int y)
195 {
196         game_keyboard(key, 0);
197 }
198
199 static void skeydown(int key, int x, int y)
200 {
201         int k;
202         modkeys = glutGetModifiers();
203         if((k = translate_skey(key)) >= 0) {
204                 game_keyboard(k, 1);
205         }
206 }
207
208 static void skeyup(int key, int x, int y)
209 {
210         int k = translate_skey(key);
211         if(k >= 0) {
212                 game_keyboard(k, 0);
213         }
214 }
215
216 static void mouse(int bn, int st, int x, int y)
217 {
218         modkeys = glutGetModifiers();
219         game_mouse(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y);
220 }
221
222 static void motion(int x, int y)
223 {
224         if(mouse_grabbed) {
225                 if(!warping) {
226                         game_motion(x, y);
227                         warping = 1;
228                         glutWarpPointer(win_width / 2, win_height / 2);
229                 } else {
230                         warping = 0;
231                         mouse_x = x;
232                         mouse_y = y;
233                 }
234         } else {
235                 game_motion(x, y);
236         }
237 }
238
239 static int translate_skey(int key)
240 {
241         switch(key) {
242         case GLUT_KEY_LEFT:
243                 return GKEY_LEFT;
244         case GLUT_KEY_UP:
245                 return GKEY_UP;
246         case GLUT_KEY_RIGHT:
247                 return GKEY_RIGHT;
248         case GLUT_KEY_DOWN:
249                 return GKEY_DOWN;
250         case GLUT_KEY_PAGE_UP:
251                 return GKEY_PGUP;
252         case GLUT_KEY_PAGE_DOWN:
253                 return GKEY_PGDOWN;
254         case GLUT_KEY_HOME:
255                 return GKEY_HOME;
256         case GLUT_KEY_END:
257                 return GKEY_END;
258         case GLUT_KEY_INSERT:
259                 return GKEY_INS;
260         default:
261                 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
262                         return key - GLUT_KEY_F1 + GKEY_F1;
263                 }
264         }
265
266         return -1;
267 }