xlib_playground

Xlib playground for experiments.
Log | Files | Refs

ex7.c (18454B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <time.h>
      4 #include <unistd.h>
      5 #include <string.h>
      6 #include <math.h>
      7 
      8 #include "x.h"
      9 
     10 /* macros */
     11 #define INIT_WIDTH (800)
     12 #define INIT_HEIGHT (600)
     13 #define FPS (60)
     14 #define SUB_TICK (4)
     15 #define NUM_RECT (200)
     16 #define GRAVITY (1000)
     17 #define max(a, b) ((a) > (b) ? (a) : (b))
     18 #define min(a, b) ((a) < (b) ? (a) : (b))
     19 #define WORLD_WIDTH (80)
     20 #define WORLD_HEIGHT (60)
     21 #define BLOCK_SIZE (10)
     22 
     23 // #define COUNT_FPS
     24 
     25 enum keys {
     26 	KEY_D,
     27 	KEY_S,
     28 	KEY_A,
     29 	KEY_W,
     30 	KEY_Q,
     31 	KEY_SPACE,
     32 	NUM_KEY, //number of keys in this enum
     33 };
     34 enum key_state {
     35 	KEY_UP,
     36 	KEY_DOWN,
     37 };
     38 enum next_menu {
     39 	START_MENU,
     40 	GAME_PLAY,
     41 	GAME_OVER,
     42 	QUIT,
     43 };
     44 
     45 struct rect {
     46 	float ppx, ppy; // previous position
     47 	float px, py;   // top left corner
     48 	float vx, vy;
     49 	float ax, ay;
     50 	int w, h;
     51 	int m;
     52 };
     53 
     54 struct circle {
     55 	float ppx, ppy;
     56 	float px, py;
     57 	float vx, vy;
     58 	float ax, ay;
     59 	int r;
     60 	int m;
     61 };
     62 
     63 char world_map[WORLD_WIDTH * WORLD_HEIGHT + 1] =
     64 "................................................................................"
     65 "................................................................................"
     66 "................................................................................"
     67 "................................................................................"
     68 "................................................................................"
     69 "........b......................................................................."
     70 "................................................................................"
     71 "................................................................................"
     72 "....b..........................................................................."
     73 "................................................................................"
     74 "................b..............................................................."
     75 "..........................................................b..........b.........."
     76 "................................................................................"
     77 ".......................b........................................................"
     78 "...........................................b...................................."
     79 "...........................................b...................................."
     80 "................................................................................"
     81 "..................b............................................................."
     82 "................................................................................"
     83 "...........................................b...................................."
     84 "................................................................................"
     85 "................................................................................"
     86 "...........................b...................................................."
     87 "................................................................................"
     88 "................................................................................"
     89 "................................................................................"
     90 "................................................................................"
     91 "................................................................................"
     92 "................................................................................"
     93 "....................................bbbbbbbbbb.................................."
     94 "................................................................................"
     95 "................................................................................"
     96 "................................................................................"
     97 "................................................................................"
     98 "................................................................................"
     99 "................................................................................"
    100 "..............................................bbbbbbbbbb........................"
    101 "................................................................................"
    102 "................................................................................"
    103 "................................................................................"
    104 "................................................................................"
    105 "....................................bbbbbbbbbb.................................."
    106 "................................................................................"
    107 "................................................................................"
    108 "................................................................................"
    109 "................................................................................"
    110 "..........................bbbbbbbbbb............................................"
    111 "................................................................................"
    112 "................................................................................"
    113 "................................................................................"
    114 "................................................................................"
    115 "................bbbbbbbbbb......................................................"
    116 "................................................................................"
    117 "................................................................................"
    118 "...p............................................................................"
    119 "bbbbbbbbbbbbbbbbbbbbbbbbb.......bbbbbbbbbbbbbbbbbbbbbbbb...bbbbbbbbbbbbbbbbbbbbb"
    120 "........................b.......b......................b...b...................."
    121 "........................b.......b......................b...b...................."
    122 "........................b.......b......................b...b...................."
    123 "........................b.......b......................b...b....................";
    124 
    125 /* variables */
    126 struct rect   block[NUM_RECT];
    127 struct rect   player;
    128 int           player_is_falling;
    129 int           next_menu = START_MENU;
    130 extern int    win_width, win_height;
    131 
    132 
    133 /* function prototypes */
    134 void cleanup(void);
    135 void start_menu(void);
    136 void game_play(void);
    137 void receive_events(int[]);
    138 void handle_inputs(int[]);
    139 void rect_next_tick(struct rect *, long);
    140 int  rect_test_collision(struct rect *, struct rect *);
    141 void rect_handle_collision_mf(struct rect *, struct rect *);
    142 void rect_handle_collision(struct rect *, struct rect *);
    143 void rect_handle_collision_elastic(struct rect *, struct rect *);
    144 void circle_next_tick(struct circle *, long);
    145 int  circle_test_collision(struct circle *, struct circle *);
    146 void update_falling_status(struct rect *, long);
    147 void game_over(void);
    148 
    149 void
    150 start_menu(void)
    151 {
    152 	char *menu_char_q = "press q to quit.";
    153 	char *menu_char_s = "press <space> to start.";
    154 
    155 	x_clear_area();
    156 	x_draw_string(0x00FFFF,
    157 				  win_width/2 - 10 * strlen(menu_char_q)/2,
    158 				  win_height/2,
    159 				  menu_char_q, strlen(menu_char_q));
    160 	x_draw_string(0x00FFFF,
    161 				  win_width/2 - 10 * strlen(menu_char_s)/2,
    162 				  win_height/2 + 20,
    163 				  menu_char_s, strlen(menu_char_s));
    164 
    165 	while (next_menu == START_MENU) {
    166 		char c;
    167 		int  event = x_next_event(&c);
    168 
    169 		switch (event) {
    170 		case XEXPOSE:
    171 			x_draw_string(0x00FFFF,
    172 						  win_width/2 - 10 * strlen(menu_char_q)/2,
    173 						  win_height/2,
    174 						  menu_char_q, strlen(menu_char_q));
    175 			x_draw_string(0x00FFFF,
    176 						  win_width/2 - 10 * strlen(menu_char_s)/2,
    177 						  win_height/2 + 20,
    178 						  menu_char_s, strlen(menu_char_s));
    179 
    180 			break;
    181 		case XWINDEL:
    182 			next_menu = QUIT;
    183 			break;
    184 		case XKEYPRESS:
    185 			switch (c) {
    186 			case 'q':
    187 				next_menu = QUIT;
    188 				break;
    189 			case ' ':
    190 				next_menu = GAME_PLAY;
    191 				break;
    192 			default:
    193 				break;
    194 			}
    195 			break;
    196 		default:
    197 			break;
    198 		}
    199 	}
    200 }
    201 
    202 void
    203 receive_events(int key_state[])
    204 {
    205 	while (x_pending() > 0) {
    206 		char c;
    207 		int event = x_next_event(&c);
    208 
    209 		switch (event) {
    210 		case XWINDEL:
    211 			next_menu = QUIT;
    212 			break;
    213 		case XKEYPRESS:
    214 			switch (c) {
    215 			case 'q':
    216 				key_state[KEY_Q] = KEY_DOWN;
    217 				break;
    218 			case 'd':
    219 				key_state[KEY_D] = KEY_DOWN;
    220 				break;
    221 			case 'a':
    222 				key_state[KEY_A] = KEY_DOWN;
    223 				break;
    224 			case 'w':
    225 				key_state[KEY_W] = KEY_DOWN;
    226 				break;
    227 			case 's':
    228 				key_state[KEY_S] = KEY_DOWN;
    229 				break;
    230 			case ' ':
    231 				key_state[KEY_SPACE] = KEY_DOWN;
    232 				break;
    233 			default:
    234 				break;
    235 			}
    236 			break;
    237 		case XKEYRELEASE:
    238 			switch (c) {
    239 			case 'q':
    240 				key_state[KEY_Q] = KEY_UP;
    241 				break;
    242 			case 'd':
    243 				key_state[KEY_D] = KEY_UP;
    244 				break;
    245 			case 'a':
    246 				key_state[KEY_A] = KEY_UP;
    247 				break;
    248 			case 'w':
    249 				key_state[KEY_W] = KEY_UP;
    250 				break;
    251 			case 's':
    252 				key_state[KEY_S] = KEY_UP;
    253 				break;
    254 			case ' ':
    255 				key_state[KEY_SPACE] = KEY_UP;
    256 				break;
    257 			default:
    258 				break;
    259 			}
    260 			break;
    261 		}
    262 	}
    263 }
    264 
    265 void
    266 handle_inputs(int key_state[])
    267 {
    268 	if (key_state[KEY_Q] == KEY_DOWN){
    269 		next_menu = GAME_OVER;
    270 		return;
    271 	}
    272 	if (key_state[KEY_D] == KEY_DOWN) {
    273 		if (player.vx > 0) {
    274 			player.ax = 500;
    275 		} else {
    276 			player.ax = 1000;
    277 		}
    278 	} else if (key_state[KEY_A] == KEY_DOWN) {
    279 		if (player.vx > 0) {
    280 			player.ax = -1000;
    281 		} else {
    282 			player.ax = -500;
    283 		}
    284 	} else {
    285 		if (player_is_falling)
    286 			player.ax = -player.vx;
    287 		else
    288 			player.ax = -3 * player.vx;
    289 	}
    290 
    291 	if (player.vx < -200) player.vx = -200;
    292 	if (player.vx > 200) player.vx = 200;
    293 	/*
    294 	if (key_state[KEY_S] == KEY_DOWN)
    295 		player.vy += 300;
    296 	if (key_state[KEY_W] == KEY_DOWN)
    297 		player.vy += -300;
    298 	*/
    299 	if (!player_is_falling && key_state[KEY_SPACE] == KEY_DOWN)
    300 		player.vy = -450;
    301 }
    302 
    303 void
    304 rect_next_tick(struct rect *s, long ndt) // nano second
    305 {
    306 	s->ppx = s->px;
    307 	s->ppy = s->py;
    308 	s->vx += s->ax * ndt / 1000 / 1000 / 1000;
    309 	s->vy += s->ay * ndt / 1000 / 1000 / 1000;
    310 	s->px += s->vx * ndt / 1000 / 1000 / 1000;
    311 	s->py += s->vy * ndt / 1000 / 1000 / 1000;
    312 
    313 	// bind within the window
    314 	if (s->px < 0) {
    315 		s->px = 0;
    316 		//s->vx *= -1;
    317 	}
    318 	if (win_width < s->px + s->w) {
    319 		s->px = win_width - s->w;
    320 		//s->vx *= -1;
    321 	}
    322 	/*
    323 	if (s->py < 0) {
    324 		s->py = 0;
    325 		s->vy *= -1;
    326 	}
    327 	if (win_height < s->py + s->h) {
    328 		s->py = win_height - s->h;
    329 		s->vy *= -1;
    330 	}
    331 	*/
    332 	// game over when fall out of the screen
    333 	if (s->py > win_height)
    334 		next_menu = GAME_OVER;
    335 }
    336 
    337 void
    338 circle_next_tick(struct circle *c, long ndt)
    339 {
    340 	c->ppx = c->px;
    341 	c->ppy = c->py;
    342 	c->vx += c->ax * ndt / 1000 / 1000 / 1000;
    343 	c->vy += c->ay * ndt / 1000 / 1000 / 1000;
    344 	c->px += c->vx * ndt / 1000 / 1000 / 1000;
    345 	c->py += c->vy * ndt / 1000 / 1000 / 1000;
    346 
    347 	// bind within the window
    348 	if (c->px - c->r < 0) {
    349 		c->px = c->r;
    350 		c->vx *= -1;
    351 	}
    352 	if (win_width < c->px + c->r) {
    353 		c->px = win_width - c->r;
    354 		c->vx *= -1;
    355 	}
    356 	if (c->py - c->r < 0) {
    357 		c->py = c->r;
    358 		c->vy *= -1;
    359 	}
    360 	if (win_height < c->py + c->r) {
    361 		c->py = win_height - c->r;
    362 		c->vy *= -1;
    363 	}
    364 }
    365 
    366 int
    367 rect_test_collision(struct rect *s1, struct rect *s2)
    368 {
    369 	return s1->px < s2->px + s2->w && s2->px < s1->px + s1->w &&
    370 	       s2->py < s1->py + s1->h && s1->py < s2->py + s2->h;
    371 }
    372 
    373 int
    374 circle_test_collision(struct circle *c1, struct circle *c2)
    375 {
    376 	return (c1->px - c2->px) * (c1->px - c2->px) +
    377 	       (c1->py - c2->py) * (c1->py - c2->py) <
    378 		   (c1->r + c2->r) * (c1->r + c2->r);
    379 }
    380 
    381 /*
    382  * Handle collision of a moving rect against fixed rect
    383  */
    384 void
    385 rect_handle_collision_mf(struct rect *sm, struct rect *sf)
    386 {
    387 	if (!rect_test_collision(sm, sf))
    388 		return;
    389 	if (sm->ppx + sm->w <= sf->ppx && sf->px < sm->px + sm->w) {
    390 		// collisioin from left to right
    391 		sm->px = sf->px - sm->w;
    392 		sm->vx = 0;
    393 	}
    394 	if (sf->ppx + sf->w <= sm->ppx && sm->px < sf->px + sf->w) {
    395 		// collision from right to left
    396 		sm->px = sf->px + sf->w;
    397 		sm->vx = 0;
    398 	}
    399 
    400 	if (sm->ppy + sm->h <= sf->ppy && sf->py < sm->py + sm->h) {
    401 		// collision from up to down
    402 		sm->py = sf->py - sm->h;
    403 		sm->vy = 0;
    404 	}
    405 	if (sf->ppy + sf->h <= sm->ppy && sm->py < sf->py + sf->h) {
    406 		// collision from dohn to up
    407 		sm->py = sf->py + sf->h;
    408 		sm->vy = 0;
    409 	}
    410 
    411 }
    412 
    413 /*
    414  * Handle collision of a moving rect against another moving rect
    415  */
    416 void
    417 rect_handle_collision_mm(struct rect *s1, struct rect *s2)
    418 {
    419 	if (!rect_test_collision(s1, s2))
    420 		return;
    421 
    422 	float lapx = min(s1->px + s1->w, s2->px + s2->w) - max(s1->px, s2->px);
    423 	float lapy = min(s1->py + s1->h, s2->py + s2->h) - max(s1->py, s2->py);
    424 
    425 	if (lapx < lapy) {
    426 		if (s1->px + s1->w < s2->px + s2->w / 2) {
    427 			s1->px -= lapx / 2;
    428 			s2->px += lapx / 2;
    429 		} else {
    430 			s1->px += lapx / 2;
    431 			s2->px -= lapx / 2;
    432 		}
    433 	} else {
    434 		if (s1->py + s1->h < s2->py + s2->h / 2) {
    435 			s1->py -= lapy / 2;
    436 			s2->py += lapy / 2;
    437 		} else {
    438 			s1->py += lapy / 2;
    439 			s2->py -= lapy / 2;
    440 		}
    441 	}
    442 }
    443 
    444 void
    445 circle_handle_collision_mm(struct circle *c1, struct circle *c2)
    446 {
    447 	if (!circle_test_collision(c1, c2))
    448 		return;
    449 
    450 	float col_px = c2->px - c1->px;
    451 	float col_py = c2->py - c1->py;
    452 	float col_pr = sqrtf(col_px * col_px + col_py * col_py);
    453 	col_px /= col_pr;
    454 	col_py /= col_pr;
    455 
    456 	c1->px = c1->px - col_px  / 2;
    457 	c1->py = c1->py - col_py  / 2;
    458 	c2->px = c2->px + col_px  / 2;
    459 	c2->py = c2->py + col_py  / 2;
    460 }
    461 
    462 void
    463 rect_handle_collision_elastic(struct rect *s1, struct rect *s2)
    464 {
    465 	if(!rect_test_collision(s1, s2))
    466 		return;
    467 
    468 	rect_handle_collision_mm(s1, s2);
    469 
    470 	float v1, v2;
    471 	float m1 = s1->m;
    472 	float m2 = s2->m;
    473 
    474 	float lapx = min(s1->px + s1->w, s2->px + s2->w) - max(s1->px, s2->px);
    475 	float lapy = min(s1->py + s1->h, s2->py + s2->h) - max(s1->py, s2->py);
    476 
    477 	if (lapx < lapy) {
    478 		v1 = s1->vx;
    479 		v2 = s2->vx;
    480 		s1->vx = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
    481 		s2->vx = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
    482 	} else {
    483 		v1 = s1->vy;
    484 		v2 = s2->vy;
    485 		s1->vy = 2*m2/(m1+m2)*v2 + (m1-m2)/(m1+m2)*v1;
    486 		s2->vy = 2*m1/(m1+m2)*v1 + (m2-m1)/(m1+m2)*v2;
    487 	}
    488 }
    489 
    490 void
    491 circle_handle_collision_elastic(struct circle *c1, struct circle *c2)
    492 {
    493 	if(!circle_test_collision(c1, c2))
    494 		return;
    495 
    496 	circle_handle_collision_mm(c1, c2);
    497 
    498 	float col_px = c2->px - c1->px;
    499 	float col_py = c2->py - c1->py;
    500 	float col_pr = sqrtf(col_px * col_px + col_py * col_py);
    501 	col_px /= col_pr;
    502 	col_py /= col_pr;
    503 	float nor_px = col_py;
    504 	float nor_py = -col_px;
    505 
    506 	float m1 = c1->m;
    507 	float m2 = c2->m;
    508 
    509 	float col_1v = c1->vx * col_px + c1->vy * col_py;
    510 	float col_2v = c2->vx * col_px + c2->vy * col_py;
    511 
    512 	float col_1vxn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_px;
    513 	float col_1vyn = (2*m2/(m1+m2)*col_2v + (m1-m2)/(m1+m2)*col_1v) * col_py;
    514 	float col_2vxn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_px;
    515 	float col_2vyn = (2*m1/(m1+m2)*col_1v + (m2-m1)/(m1+m2)*col_2v) * col_py;
    516 
    517 	float nor_1vx = nor_px * (c1->vx * nor_px + c1->vy * nor_py);
    518 	float nor_1vy = nor_py * (c1->vx * nor_px + c1->vy * nor_py);
    519 	float nor_2vx = nor_px * (c2->vx * nor_px + c2->vy * nor_py);
    520 	float nor_2vy = nor_py * (c2->vx * nor_px + c2->vy * nor_py);
    521 
    522 	c1->vx = col_1vxn + nor_1vx;
    523 	c1->vy = col_1vyn + nor_1vy;
    524 	c2->vx = col_2vxn + nor_2vx;
    525 	c2->vy = col_2vyn + nor_2vy;
    526 }
    527 
    528 void
    529 update_falling_status(struct rect *player, long ndt)
    530 {
    531 	int collision = 0;
    532 	struct rect r = {0};
    533 	r.ppx = player->ppx;
    534 	r.ppy = player->ppy;
    535 	r.px = player->px;
    536 	r.py = player->py;
    537 	r.vx = 0;
    538 	r.vy = 0;
    539 	r.ax = 0;
    540 	r.ay = GRAVITY;
    541 	r.w = player->w;
    542 	r.h = player->h;
    543 	r.m = player->m;
    544 
    545 	rect_next_tick(&r, ndt);
    546 	for (int i = 0; i < NUM_RECT; i++)
    547 		if (rect_test_collision(&r, &block[i]))
    548 			collision = 1;
    549 
    550 	if (collision == 1)
    551 		player_is_falling = 0;
    552 	else
    553 		player_is_falling = 1;
    554 }
    555 
    556 void
    557 game_play(void)
    558 {
    559 	int  key_state[NUM_KEY];
    560 	long t0, t1, dt;
    561 #ifdef COUNT_FPS
    562 	int fps_count = 0;
    563 #endif
    564 	struct timespec ts;
    565 
    566 	int bi = 0;
    567 	for (int i = 0; i < WORLD_WIDTH * WORLD_HEIGHT; i++) {
    568 		if (world_map[i] == 'b') {
    569 			block[bi].ppx = block[bi].px = i % WORLD_WIDTH * BLOCK_SIZE;
    570 			block[bi].ppy = block[bi].py = i / WORLD_WIDTH * BLOCK_SIZE;
    571 			block[bi].ax = 0;
    572 			block[bi].ay = 0;
    573 			block[bi].vx = 0;
    574 			block[bi].vy = 0;
    575 			block[bi].w = block[bi].h = BLOCK_SIZE;
    576 			block[bi].m = block[bi].w * block[bi].h;
    577 			bi++;
    578 		} else if (world_map[i] == 'p') {
    579 			player.ppx = player.px =  i % WORLD_WIDTH * BLOCK_SIZE;
    580 			player.ppy = player.py = i / WORLD_WIDTH * BLOCK_SIZE;
    581 			player.vx = 0;
    582 			player.vy = 0;
    583 			player.ax = 0;
    584 			player.ay = GRAVITY;
    585 			player.w = player.h = BLOCK_SIZE;
    586 			player.m = player.w * player.h;
    587 		}
    588 	}
    589 
    590 	while (next_menu == GAME_PLAY){
    591 		clock_gettime(CLOCK_MONOTONIC, &ts);
    592 		t0 = ts.tv_nsec;
    593 		receive_events(key_state);
    594 		handle_inputs(key_state);
    595 
    596 
    597 		clock_gettime(CLOCK_MONOTONIC, &ts);
    598 		t0 = ts.tv_nsec;
    599 
    600 		int collision[NUM_RECT] = {0};
    601 		for (int k = 0; k < SUB_TICK; k++) {
    602 			update_falling_status(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK);
    603 			if (player_is_falling)
    604 				player.ay = GRAVITY;
    605 			else
    606 				player.ay = 0;
    607 			rect_next_tick(&player, 1000 * 1000 * 1000 / FPS / SUB_TICK);
    608 			for (int i = 0; i < NUM_RECT; i++)
    609 				rect_next_tick(&block[i], 1000 * 1000 * 1000 / FPS / SUB_TICK);
    610 
    611 			for (int i = 0; i < NUM_RECT; i++){
    612 				rect_handle_collision_mf(&player, &block[i]);
    613 				if (rect_test_collision(&player, &block[i]))
    614 					collision[i] = 1;
    615 			}
    616 		}
    617 
    618 		// fix fps
    619 		// TODO: This method create some strange stripe when
    620 		// rendered in 60fps on a 60fps monitor.
    621 		dt = 0;
    622 		while (dt < 1.0 * 1000 * 1000 * 1000 / FPS){
    623 			clock_gettime(CLOCK_MONOTONIC, &ts);
    624 			t1 = ts.tv_nsec;
    625 			dt = t1 > t0 ? t1 - t0 : t1 - t0 + 1000 * 1000 * 1000;
    626 		}
    627 #ifdef COUNT_FPS
    628 		// count fps.
    629 		fps_count++;
    630 		if (t1 < t0){
    631 			printf("fps: %u\n", fps_count);
    632 			fps_count = 0;
    633 		}
    634 #endif
    635 
    636 		x_clear_area();
    637 		for (int i = 0; i < NUM_RECT; i++) {
    638 			x_draw_rectangle(0x00FF00,
    639 						   block[i].px, block[i].py,    // position
    640 						   block[i].w, block[i].h);
    641 		}
    642 		x_draw_rectangle(0x009FFF,
    643 					   player.px, player.py,    // position
    644 					   player.w, player.h);
    645 		char status_string[128];
    646 		snprintf(status_string, 128, "falling: %d", player_is_falling);
    647 		x_draw_string(0x00FFFF,
    648 		            0, 20,
    649 		            status_string,
    650 					strlen(status_string));
    651 	}
    652 }
    653 
    654 void
    655 game_over(void)
    656 {
    657 	char *menu_char = "GAME OVER";
    658 
    659 	x_clear_area();
    660 	x_draw_string(0x00FFFF,
    661 				win_width/2 - 10 * strlen(menu_char)/2, win_height/2,
    662 				menu_char, strlen(menu_char));
    663 	x_flush();
    664 
    665 	sleep(1);
    666 	next_menu = START_MENU;
    667 }
    668 
    669 int
    670 main(void)
    671 {
    672 	win_width = 800;
    673 	win_height = 600;
    674 	x_setup_window(0, 0, win_width, win_height, 0x000000, "UNKO");
    675 	while (next_menu != QUIT){
    676 		switch (next_menu){
    677 		case START_MENU:
    678 			start_menu();
    679 			break;
    680 		case GAME_PLAY:
    681 			game_play();
    682 			break;
    683 		case GAME_OVER:
    684 			game_over();
    685 			break;
    686 		default:
    687 			break;
    688 		}
    689 	}
    690 
    691 	x_clean_up();
    692 	return 0;
    693 }