renamed source files back to .c
[cave9.git] / src / main.c
blobadb38e46e31508dd76bee139ead7a428bddbbe0e
1 /*
2 This file is part of cave9.
4 cave9 is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 cave9 is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with cave9. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdlib.h>
19 #include <time.h>
20 #include <string.h>
21 #include "vec.h"
22 #include "display.h"
23 #include "game.h"
25 typedef struct Input_struct
27 bool pressed[SDLK_LAST];
28 enum {WELCOME, PLAY, PAUSE, GAMEOVER, QUIT} state;
29 } Input;
31 void game_init(Display* display, Cave* cave, Ship* digger, Ship* player)
33 ship_init(player, SHIP_RADIUS);
34 ship_init(digger, MAX_CAVE_RADIUS);
35 cave_init(cave,digger);
36 display_message(display, cave, player, "");
39 void control(Display* display, Cave* cave, Ship* digger, Ship* player, Input* input)
41 SDL_Event event;
43 while(SDL_PollEvent(&event)) {
44 switch(event.type) {
45 case SDL_KEYDOWN:
46 switch(event.key.keysym.sym) {
47 case SDLK_ESCAPE:
48 case SDLK_q:
49 input->state = Input::QUIT;
50 break;
51 case SDLK_f:
52 if(input->state == Input::PLAY) {
53 input->state = Input::PAUSE;
54 display_message(display, cave, player, "paused");
56 SDL_WM_ToggleFullScreen(display->screen);
57 break;
58 case SDLK_p:
59 case SDLK_PAUSE:
60 case SDLK_SPACE:
61 if(input->state == Input::WELCOME
62 || input->state == Input::PAUSE
63 || input->state == Input::GAMEOVER) {
64 if(input->state == Input::GAMEOVER)
65 game_init(display, cave, digger, player);
66 else
67 display_message(display, cave, player, "");
68 input->state = Input::PLAY;
70 else if(input->state == Input::PLAY) {
71 input->state = Input::PAUSE;
72 display_message(display, cave, player, "paused");
74 break;
75 case SDLK_RETURN:
76 if(SDL_GetModState() & KMOD_ALT)
77 SDL_WM_ToggleFullScreen(display->screen);
78 break;
79 default:
80 break;
82 case SDL_KEYUP:
83 input->pressed[event.key.keysym.sym] = (event.type == SDL_KEYDOWN);
84 break;
85 case SDL_QUIT:
86 input->state = Input::QUIT;
87 break;
88 case SDL_VIDEORESIZE:
90 int aa;
91 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &aa );
92 viewport(display, event.resize.w, event.resize.h, 0,
93 display->screen->flags & SDL_FULLSCREEN, aa);
95 break;
96 case SDL_VIDEOEXPOSE:
97 display_frame(display, cave, player);
98 break;
99 default:
100 break;
105 void player_control(Ship* player, Input* input)
107 player->lefton =
108 input->pressed[SDLK_LEFT] ||
109 input->pressed[SDLK_LSHIFT] ||
110 input->pressed[SDLK_LCTRL];
111 player->righton =
112 input->pressed[SDLK_RIGHT] ||
113 input->pressed[SDLK_RSHIFT] ||
114 input->pressed[SDLK_RCTRL];
117 void args_init(Args* args, int argc, char* argv[])
119 args->width = 640;
120 args->height = 480;
121 args->bpp = 0;
122 args->fullscreen = 0;
123 args->highres = 0;
124 args->antialiasing = 0;
125 args->monoliths = 0;
126 args->start = 0;
127 args->cockpit = 0;
128 int help_called = 0;
130 struct {
131 bool has_arg;
132 int* val;
133 char* short_name;
134 char* long_name;
135 } options[] = {
136 { 0, &help_called, "-h", "--help" },
137 { 1, &args->width, "-W", "--width" },
138 { 1, &args->height, "-H", "--height" },
139 { 1, &args->bpp, "-B", "--bpp" },
140 { 0, &args->fullscreen, "-F", "--fullscreen" },
141 { 0, &args->highres, "-R", "--highres" },
142 { 1, &args->antialiasing, "-A", "--antialiasing" },
143 { 0, &args->monoliths, "-M", "--monoliths" },
144 { 1, &args->start, "-S", "--start" },
145 { 0, &args->cockpit, "-C", "--cockpit" },
146 { 0, NULL, NULL, NULL }
149 for(int i = 1; i < argc; ++i) {
150 for(int opt = 0; ; ++opt) {
151 if(options[opt].val == NULL) {
152 fprintf(stderr, "invalid argument %s\n", argv[i]);
153 help_called = 1;
154 break;
156 if(!strcmp(argv[i], options[opt].short_name) || !strcmp(argv[i], options[opt].long_name)) {
157 int value = 1;
158 if(options[opt].has_arg) {
159 if(++i == argc) {
160 fprintf(stderr, "argument required for %s\n", argv[i-1]);
161 exit(1);
163 value = atoi(argv[i]);
165 *(options[opt].val) = value;
166 break;
171 if(help_called) {
172 printf("command-line options:\n");
173 for(int opt = 0; options[opt].val; ++opt) {
174 printf("%s or %s", options[opt].short_name, options[opt].long_name);
175 if(options[opt].has_arg)
176 printf(" <num>");
177 printf("\n");
179 exit(1);
183 int main(int argc, char* argv[])
185 Args args;
186 Display display;
187 Input input;
188 memset( input.pressed, 0, sizeof(input.pressed) );
190 srand(time(NULL));
192 Cave cave;
193 Ship digger;
194 Ship player;
196 args_init(&args, argc, argv);
197 display_init(&display, &args);
199 player.start = digger.start = (float)args.start;
200 game_init(&display, &cave, &digger, &player);
201 input.state = Input::WELCOME;
202 display_message(&display, &cave, &player, "welcome! left+right for control. [press space]");
204 float dt = 0;
205 while(input.state != Input::QUIT) {
206 int t0 = SDL_GetTicks();
208 control(&display, &cave, &digger, &player, &input);
210 switch(input.state) {
211 case Input::PLAY:
212 player_control(&player, &input);
213 ship_move(&player, dt);
214 digger_control(&digger);
215 ship_move(&digger, dt);
216 if(collision(&cave, &player) <= 0) {
217 display_message(&display, &cave, &player, "gameover. [press space]");
218 input.state = Input::GAMEOVER;
220 cave_gen(&cave, &digger);
222 display_frame(&display, &cave, &player);
223 break;
224 case Input::WELCOME:
225 case Input::PAUSE:
226 case Input::GAMEOVER:
227 case Input::QUIT:
228 break;
231 int t1 = SDL_GetTicks();
232 SDL_Delay( MAX( 1, 1000/FPS-(t1-t0) ) );
234 dt = (SDL_GetTicks()-t0)/1000.;
235 //dt = 1./FPS;
238 display_net_finish(&display);
239 display_message(&display, &cave, &player, "bye.");
241 return 0;
244 // vim600:fdm=syntax:fdn=1: