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