rev |
line source |
nuclear@0
|
1 #include <stdlib.h>
|
nuclear@0
|
2 #include <ctype.h>
|
nuclear@0
|
3 #include <assert.h>
|
nuclear@0
|
4 #include "opengl.h"
|
nuclear@0
|
5
|
nuclear@0
|
6 #include "game.h"
|
nuclear@0
|
7 #include "input.h"
|
nuclear@0
|
8 #include "screen.h"
|
nuclear@0
|
9 #include "logger.h"
|
nuclear@0
|
10
|
nuclear@0
|
11 /* called by any other part of the game when a redisplay is needed
|
nuclear@0
|
12 * (mostly useful for tools which do not redisplay continuously)
|
nuclear@0
|
13 */
|
nuclear@0
|
14 void request_redisplay();
|
nuclear@0
|
15
|
nuclear@0
|
16 void swap_buffers();
|
nuclear@0
|
17
|
nuclear@0
|
18 static void display(void);
|
nuclear@0
|
19 static void reshape(int x, int y);
|
nuclear@0
|
20 static void keydown(unsigned char key, int x, int y);
|
nuclear@0
|
21 static void keyup(unsigned char key, int x, int y);
|
nuclear@0
|
22 static void skeydown(int key, int x, int y);
|
nuclear@0
|
23 static void skeyup(int key, int x, int y);
|
nuclear@0
|
24 static void mouse(int bn, int state, int x, int y);
|
nuclear@0
|
25 static void motion(int x, int y);
|
nuclear@0
|
26 static void passive_motion(int x, int y);
|
nuclear@0
|
27
|
nuclear@0
|
28 static long redisp_interval;
|
nuclear@0
|
29
|
nuclear@0
|
30 int main(int argc, char **argv)
|
nuclear@0
|
31 {
|
nuclear@0
|
32 glutInit(&argc, argv);
|
nuclear@0
|
33 glutInitWindowSize(800, 600);
|
nuclear@0
|
34 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE);
|
nuclear@0
|
35 glutCreateWindow("Xmass inferno");
|
nuclear@0
|
36
|
nuclear@0
|
37 glutDisplayFunc(display);
|
nuclear@0
|
38 glutReshapeFunc(reshape);
|
nuclear@0
|
39 glutKeyboardFunc(keydown);
|
nuclear@0
|
40 glutKeyboardUpFunc(keyup);
|
nuclear@0
|
41 glutSpecialFunc(skeydown);
|
nuclear@0
|
42 glutSpecialUpFunc(skeyup);
|
nuclear@0
|
43 glutMouseFunc(mouse);
|
nuclear@0
|
44 glutMotionFunc(motion);
|
nuclear@0
|
45 glutPassiveMotionFunc(passive_motion);
|
nuclear@0
|
46
|
nuclear@0
|
47 game_set_args(argc, argv);
|
nuclear@0
|
48 if(!game_init()) {
|
nuclear@0
|
49 return 1;
|
nuclear@0
|
50 }
|
nuclear@0
|
51 atexit(game_cleanup);
|
nuclear@0
|
52
|
nuclear@0
|
53 glutMainLoop();
|
nuclear@0
|
54 return 0;
|
nuclear@0
|
55 }
|
nuclear@0
|
56
|
nuclear@0
|
57 void request_redisplay()
|
nuclear@0
|
58 {
|
nuclear@0
|
59 glutPostRedisplay();
|
nuclear@0
|
60 }
|
nuclear@0
|
61
|
nuclear@0
|
62 void swap_buffers()
|
nuclear@0
|
63 {
|
nuclear@0
|
64 glUseProgram(0);
|
nuclear@0
|
65 glutSwapBuffers();
|
nuclear@0
|
66 }
|
nuclear@0
|
67
|
nuclear@0
|
68 static void display()
|
nuclear@0
|
69 {
|
nuclear@0
|
70 long ival = current_screen()->redisplay_interval();
|
nuclear@0
|
71 if(ival && !redisp_interval) {
|
nuclear@0
|
72 debug_log("switching to auto-redisplay (interval: %ld)\n", redisp_interval);
|
nuclear@0
|
73 glutIdleFunc(request_redisplay);
|
nuclear@0
|
74 }
|
nuclear@0
|
75 if(!ival && redisp_interval) {
|
nuclear@0
|
76 debug_log("switching to manual redisplay\n");
|
nuclear@0
|
77 glutIdleFunc(0);
|
nuclear@0
|
78 }
|
nuclear@0
|
79 redisp_interval = ival;
|
nuclear@0
|
80
|
nuclear@0
|
81 game_display();
|
nuclear@0
|
82 // TODO implement framerate limiter
|
nuclear@0
|
83 }
|
nuclear@0
|
84
|
nuclear@0
|
85
|
nuclear@0
|
86 static void reshape(int x, int y)
|
nuclear@0
|
87 {
|
nuclear@0
|
88 game_reshape(x, y);
|
nuclear@0
|
89 }
|
nuclear@0
|
90
|
nuclear@0
|
91 /* GLUT doesn't have any callbacks for modifier keys, so we fake it by calling
|
nuclear@0
|
92 * this function all over the place, to generate fake events whenever a modifier
|
nuclear@0
|
93 * key is detected to have changed state.
|
nuclear@0
|
94 * The limitation is that this will only detect modkey changes whenever a regular
|
nuclear@0
|
95 * key is pressed or released, or when a mouse button is pressed or released.
|
nuclear@0
|
96 */
|
nuclear@0
|
97 static void handle_modkeys()
|
nuclear@0
|
98 {
|
nuclear@0
|
99 static int modstate;
|
nuclear@0
|
100
|
nuclear@0
|
101 int mod = glutGetModifiers();
|
nuclear@0
|
102 if(mod != modstate) {
|
nuclear@0
|
103 int diff = mod ^ modstate;
|
nuclear@0
|
104
|
nuclear@0
|
105 if(diff & GLUT_ACTIVE_SHIFT) {
|
nuclear@0
|
106 bool pressed = mod & GLUT_ACTIVE_SHIFT;
|
nuclear@0
|
107 game_key(KEY_LSHIFT, pressed);
|
nuclear@0
|
108 }
|
nuclear@0
|
109 if(diff & GLUT_ACTIVE_CTRL) {
|
nuclear@0
|
110 bool pressed = mod & GLUT_ACTIVE_CTRL;
|
nuclear@0
|
111 game_key(KEY_LCTRL, pressed);
|
nuclear@0
|
112 }
|
nuclear@0
|
113 if(diff & GLUT_ACTIVE_ALT) {
|
nuclear@0
|
114 bool pressed = mod & GLUT_ACTIVE_ALT;
|
nuclear@0
|
115 game_key(KEY_LALT, pressed);
|
nuclear@0
|
116 }
|
nuclear@0
|
117 }
|
nuclear@0
|
118 modstate = mod;
|
nuclear@0
|
119 }
|
nuclear@0
|
120
|
nuclear@0
|
121 static int translate_special_key(int key)
|
nuclear@0
|
122 {
|
nuclear@0
|
123 if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
|
nuclear@0
|
124 return (key - GLUT_KEY_F1) + KEY_F1;
|
nuclear@0
|
125 }
|
nuclear@0
|
126 if(key >= GLUT_KEY_LEFT && key <= GLUT_KEY_PAGE_DOWN) {
|
nuclear@0
|
127 return (key - GLUT_KEY_LEFT) + KEY_LEFT;
|
nuclear@0
|
128 }
|
nuclear@0
|
129
|
nuclear@0
|
130 switch(key) {
|
nuclear@0
|
131 case GLUT_KEY_HOME:
|
nuclear@0
|
132 return KEY_HOME;
|
nuclear@0
|
133 case GLUT_KEY_END:
|
nuclear@0
|
134 return KEY_END;
|
nuclear@0
|
135 case GLUT_KEY_INSERT:
|
nuclear@0
|
136 return KEY_INSERT;
|
nuclear@0
|
137
|
nuclear@0
|
138 default:
|
nuclear@0
|
139 break;
|
nuclear@0
|
140 }
|
nuclear@0
|
141 return 0;
|
nuclear@0
|
142 }
|
nuclear@0
|
143
|
nuclear@0
|
144 static void keydown(unsigned char c, int x, int y)
|
nuclear@0
|
145 {
|
nuclear@0
|
146 int key = c;
|
nuclear@0
|
147 if(key == 127) {
|
nuclear@0
|
148 key = KEY_DELETE;
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 handle_modkeys();
|
nuclear@0
|
152 game_key(key, true);
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 static void keyup(unsigned char c, int x, int y)
|
nuclear@0
|
156 {
|
nuclear@0
|
157 int key = c;
|
nuclear@0
|
158 if(key == 127) {
|
nuclear@0
|
159 key = KEY_DELETE;
|
nuclear@0
|
160 }
|
nuclear@0
|
161
|
nuclear@0
|
162 handle_modkeys();
|
nuclear@0
|
163 game_key(key, false);
|
nuclear@0
|
164 }
|
nuclear@0
|
165
|
nuclear@0
|
166 static void skeydown(int key, int x, int y)
|
nuclear@0
|
167 {
|
nuclear@0
|
168 handle_modkeys();
|
nuclear@0
|
169
|
nuclear@0
|
170 if((key = translate_special_key(key)) > 0) {
|
nuclear@0
|
171 game_key(key, true);
|
nuclear@0
|
172 }
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 static void skeyup(int key, int x, int y)
|
nuclear@0
|
176 {
|
nuclear@0
|
177 handle_modkeys();
|
nuclear@0
|
178
|
nuclear@0
|
179 if((key = translate_special_key(key)) > 0) {
|
nuclear@0
|
180 game_key(key, false);
|
nuclear@0
|
181 }
|
nuclear@0
|
182 }
|
nuclear@0
|
183
|
nuclear@0
|
184 static void mouse(int bn, int state, int x, int y)
|
nuclear@0
|
185 {
|
nuclear@0
|
186 handle_modkeys();
|
nuclear@0
|
187
|
nuclear@0
|
188 int bnidx = bn - GLUT_LEFT_BUTTON;
|
nuclear@0
|
189 bool bnstate = state == GLUT_DOWN;
|
nuclear@0
|
190
|
nuclear@0
|
191 current_screen()->button(bnidx, bnstate, x, y);
|
nuclear@0
|
192 set_mouse_state(x, y, bnidx, bnstate); // this MUST be after the event dispatch
|
nuclear@0
|
193 }
|
nuclear@0
|
194
|
nuclear@0
|
195 static void motion(int x, int y)
|
nuclear@0
|
196 {
|
nuclear@0
|
197 set_mouse_state(x, y);
|
nuclear@0
|
198 current_screen()->motion(x, y, false);
|
nuclear@0
|
199 }
|
nuclear@0
|
200
|
nuclear@0
|
201 static void passive_motion(int x, int y)
|
nuclear@0
|
202 {
|
nuclear@0
|
203 set_mouse_state(x, y);
|
nuclear@0
|
204 current_screen()->motion(x, y, true);
|
nuclear@0
|
205 }
|