distance function generation from level data, first pass
[raydungeon] / src / game.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <GL/gl.h>
4 #include <GL/glu.h>
5 #include "game.h"
6 #include "options.h"
7
8 int mouse_x, mouse_y, mouse_state[3];
9 int mouse_grabbed;
10 unsigned int modkeys;
11 int win_width, win_height;
12 float win_aspect;
13 int fullscr;
14
15 long time_msec;
16
17 struct game_screen *cur_scr;
18 char *start_scr_name;
19
20 /* available screens */
21 extern struct game_screen scr_menu, scr_game, scr_map, scr_lvled;
22 #define MAX_SCREENS     4
23 static struct game_screen *screens[MAX_SCREENS];
24 static int num_screens;
25
26
27 int game_init(int argc, char **argv)
28 {
29         int i;
30         char *env;
31
32         load_options(GAME_CFG_FILE);
33         if(parse_options(argc, argv) == -1) {
34                 return -1;
35         }
36         game_resize(opt.xres, opt.yres);
37         game_vsync(opt.vsync);
38         if(opt.fullscreen) {
39                 game_fullscreen(1);
40         }
41
42         /* initialize screens */
43         screens[num_screens++] = &scr_menu;
44         screens[num_screens++] = &scr_game;
45         screens[num_screens++] = &scr_map;
46         screens[num_screens++] = &scr_lvled;
47
48         if((env = getenv("START_SCREEN"))) {
49                 start_scr_name = env;
50         }
51
52         for(i=0; i<num_screens; i++) {
53                 if(screens[i]->init() == -1) {
54                         return -1;
55                 }
56         }
57
58         glClearColor(0.1, 0.1, 0.1, 1);
59
60         for(i=0; i<num_screens; i++) {
61                 if(screens[i]->name && start_scr_name && strcmp(screens[i]->name, start_scr_name) == 0) {
62                         game_chscr(screens[i]);
63                         break;
64                 }
65         }
66         if(!cur_scr) {
67                 game_chscr(&scr_game);  /* TODO: scr_menu */
68         }
69         return 0;
70 }
71
72 void game_shutdown(void)
73 {
74         int i;
75
76         save_options(GAME_CFG_FILE);
77
78         for(i=0; i<num_screens; i++) {
79                 if(screens[i]->destroy) {
80                         screens[i]->destroy();
81                 }
82         }
83 }
84
85 void game_display(void)
86 {
87         time_msec = game_getmsec();
88
89         if(cur_scr) {
90                 cur_scr->display();
91         }
92
93         game_swap_buffers();
94 }
95
96 void game_reshape(int x, int y)
97 {
98         win_width = x;
99         win_height = y;
100         win_aspect = (float)x / (float)y;
101         glViewport(0, 0, x, y);
102
103         if(cur_scr && cur_scr->reshape) {
104                 cur_scr->reshape(x, y);
105         }
106 }
107
108 void game_keyboard(int key, int press)
109 {
110         if(press) {
111                 switch(key) {
112                 case 27:
113                         game_quit();
114                         break;
115
116                 case '\n':
117                 case '\r':
118                         if(modkeys & GKEY_MOD_ALT) {
119                 case GKEY_F11:
120                                 game_fullscreen(-1);
121                                 return;
122                         }
123                         break;
124                 }
125         }
126
127         if(cur_scr && cur_scr->keyboard) {
128                 cur_scr->keyboard(key, press);
129         }
130 }
131
132 void game_mouse(int bn, int st, int x, int y)
133 {
134         mouse_x = x;
135         mouse_y = y;
136         if(bn < 3) {
137                 mouse_state[bn] = st;
138         }
139
140         if(cur_scr && cur_scr->mouse) {
141                 cur_scr->mouse(bn, st, x, y);
142         }
143 }
144
145 void game_motion(int x, int y)
146 {
147         if(cur_scr && cur_scr->motion) {
148                 cur_scr->motion(x, y);
149         }
150         mouse_x = x;
151         mouse_y = y;
152 }
153
154 void game_chscr(struct game_screen *scr)
155 {
156         struct game_screen *prev = cur_scr;
157
158         if(!scr) return;
159
160         if(scr->start && scr->start() == -1) {
161                 return;
162         }
163         if(scr->reshape) {
164                 scr->reshape(win_width, win_height);
165         }
166
167         if(prev && prev->stop) {
168                 prev->stop();
169         }
170         cur_scr = scr;
171 }