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