Index: proj/include/proj_func.h
===================================================================
--- proj/include/proj_func.h	(revision 250)
+++ proj/include/proj_func.h	(revision 251)
@@ -56,6 +56,16 @@
  */
 double get_mouse_angle(gunner_t *p);
 
+typedef struct menu menu_t;
+
+menu_t* (menu_ctor)(const font_t *fnt);
+
+int (menu_update_state)(menu_t *menu, int click);
+
+void (menu_draw)(menu_t *menu);
+
+void (menu_dtor)(menu_t *p);
+
 typedef struct timer {
     int time;
     text_t *text;
@@ -66,6 +76,8 @@
 
 void (timer_update)(text_timer_t *p);
 
+void (timer_reset)(text_timer_t *p);
+
 void (timer_dtor)(text_timer_t *p);
 
 #endif /* end of include guard: PROJ_FUNC_H_INCLUDED */
Index: proj/include/proj_macros.h
===================================================================
--- proj/include/proj_macros.h	(revision 250)
+++ proj/include/proj_macros.h	(revision 251)
@@ -30,6 +30,12 @@
 #define SHOOTER_SPEED   5   /** @brief Shooter speed */
 #define BULLET_SPEED    8   /** @brief Bullet speet */
 
+// Game States
+#define MENU            0
+#define GAME            1
+#define TEST            2
+#define EXIT            3
+
 // Extra Keys
 #define ESC_MAKE_CODE   0x01    /** @brief ESC Make Code */
 #define ESC_BREAK_CODE  0x81    /** @brief ESC Break Code */
@@ -43,4 +49,9 @@
 #define DEFAULT_SCALE   0.5                  /** @brief Default zoom */
 #define MAX_SCALE       10.0                 /** @brief Maximum zoom */
 
+// Colors
+#define TEXT_COLOR              0x888888
+#define HIGHLIGHT_COLOR         0xA0A0A0
+#define DELIMITER_COLOR         0x404040
+
 #endif /* end of include guard: PROJ_MACROS_H_INCLUDED */
Index: proj/include/rectangle.h
===================================================================
--- proj/include/rectangle.h	(revision 250)
+++ proj/include/rectangle.h	(revision 251)
@@ -17,6 +17,7 @@
 int16_t  (rectangle_get_y)(const rectangle_t *p);
 uint16_t (rectangle_get_w)(const rectangle_t *p);
 uint16_t (rectangle_get_h)(const rectangle_t *p);
+int      (rectangle_collide_point)(const rectangle_t *p, int x, int y);
 
 void (rectangle_draw)(const rectangle_t *p);
 
Index: proj/src/proj.c
===================================================================
--- proj/src/proj.c	(revision 250)
+++ proj/src/proj.c	(revision 251)
@@ -7,6 +7,8 @@
 #include "proj_func.h"
 
 #include "kbc.h"
+#include "kbc_macros.h"
+#include "i8254.h"
 #include "timer.h"
 #include "keyboard.h"
 #include "mouse.h"
@@ -173,6 +175,8 @@
 
         text_timer_t *in_game_timer = timer_ctor(consolas);
 
+        menu_t *main_menu = menu_ctor(consolas);
+
         list_t *shooter_list = list_ctor();
 
         gunner_t *shooter1 = gunner_ctor(bsp_shooter, bsp_pistol); if(shooter1 == NULL) printf("Failed to get shooter1\n");
@@ -201,9 +205,9 @@
         /// loop stuff
         int ipc_status;
         message msg;
-        int good = 1;
+        int game_state = MENU, click = 0;
 
-        while (good) {
+        while (game_state != EXIT) {
             /* Get a request message. */
             if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
                 printf("driver_receive failed with %d", r);
@@ -215,52 +219,99 @@
                         for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) {
                             if (msg.m_notify.interrupts & n) {
                                 interrupt_handler(i);
-                                if ((scancode[0]) == ESC_BREAK_CODE) good = 0;
-                                if (i == 0) {
-                                    if (no_interrupts % 60 == 0) timer_update(in_game_timer);
-                                    //if (no_interrupts % refresh_count_value == 0) {
-                                            update_movement(map1, shooter1, keys, shooter_list);
+                                switch (i) {
+                                case TIMER0_IRQ:
+                                    switch (game_state) {
+                                    case MENU:
+                                        if (no_interrupts % 2 == 0){
+                                            graph_clear_screen();
+                                            game_state = menu_update_state(main_menu, click);
+                                            menu_draw(main_menu);
 
-                                            update_game_state(map1, shooter_list, bullet_list);
+                                            click = 0;
 
-                                            //update_scale();
                                             sprite_set_pos(sp_crosshair, *mouse_x, *mouse_y);
-                                            angle = get_mouse_angle(shooter1);
-                                            gunner_set_angle(shooter1, angle - M_PI_2);
-                                            graph_clear_screen();
+                                            sprite_draw(sp_crosshair);
+                                            graph_draw();
+                                        }
+                                        break;
+                                    case GAME:
+                                        if (no_interrupts % 60 == 0) timer_update(in_game_timer);
+                                        update_movement(map1, shooter1, keys, shooter_list);
 
-                                            ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
-                                                           gunner_get_y(shooter1)-ent_get_YLength()/2.0);
+                                        update_game_state(map1, shooter_list, bullet_list);
 
-                                            map_draw   (map1);
-                                            gunner_draw_list(shooter_list);
-                                            bullet_draw_list(bullet_list);
+                                        //update_scale();
+                                        angle = get_mouse_angle(shooter1);
+                                        gunner_set_angle(shooter1, angle - M_PI_2);
 
-                                            text_draw(in_game_timer->text);
-                                            sprite_draw(sp_crosshair);
-                                            graph_draw();
-                                        //}
+                                        ent_set_origin(gunner_get_x(shooter1)-ent_get_XLength()/2.0,
+                                                       gunner_get_y(shooter1)-ent_get_YLength()/2.0);
+
+                                        graph_clear_screen();
+                                        map_draw   (map1);
+                                        gunner_draw_list(shooter_list);
+                                        bullet_draw_list(bullet_list);
+
+                                        text_draw(in_game_timer->text);
+
+                                        sprite_set_pos(sp_crosshair, *mouse_x, *mouse_y);
+                                        sprite_draw(sp_crosshair);
+                                        graph_draw();
+                                        break;
                                     }
-                                    else if (i == 12) {
-                                        if (counter_mouse_ih >= 3) {
-                                            mouse_parse_packet(packet_mouse_ih, &pp);
-                                            update_mouse(&pp);
-
-                                            if (last_lb ^ keys->lb_pressed && keys->lb_pressed) {
-                                                shoot_bullet(shooter1, bullet_list, bsp_bullet);
+                                    break;
+                                case KBC_IRQ:
+                                    switch (game_state) {
+                                    case MENU:
+                                        if ((scancode[0]) == ESC_BREAK_CODE) game_state = EXIT;
+                                        break;
+                                    case GAME:
+                                        if ((scancode[0]) == ESC_BREAK_CODE) {
+                                            game_state = MENU;
+                                            // reset game
+                                            while(list_size(bullet_list) > 0){
+                                                bullet_t *p = (bullet_t*)list_erase(bullet_list, list_begin(bullet_list));
+                                                bullet_dtor(p);
                                             }
-                                            last_lb = keys->lb_pressed;
-                                            counter_mouse_ih = 0;
-
+                                            list_node_t *it = list_begin(shooter_list);
+                                            while (it != list_end(shooter_list)) {
+                                                gunner_t *p = *(gunner_t**)list_node_val(it);
+                                                get_random_spawn(map1, p);
+                                                gunner_set_curr_health(p, gunner_get_health(p));
+                                                it = list_node_next(it);
+                                            }
+                                            timer_reset(in_game_timer);
                                         }
+                                        break;
                                     }
+                                    break;
+                                case MOUSE_IRQ:
+                                    if (counter_mouse_ih >= 3) {
+                                        mouse_parse_packet(packet_mouse_ih, &pp);
+                                        update_mouse(&pp);
+                                        switch (game_state) {
+                                        case MENU:
+                                            if (!click) click = last_lb ^ keys->lb_pressed && keys->lb_pressed;
+                                            break;
+                                        case GAME:
+                                            if (last_lb ^ keys->lb_pressed && keys->lb_pressed)
+                                                shoot_bullet(shooter1, bullet_list, bsp_bullet);
+                                            break;
+                                        }
+                                        last_lb = keys->lb_pressed;
+                                        counter_mouse_ih = 0;
+
+                                    }
+                                    break;
                                 }
                             }
+                        }
 
-                            break;
-                        default:
-                            break; /* no other notifications expected: do nothing */
-                    }
+                        break;
+                    default:
+                        break; /* no other notifications expected: do nothing */
+                }
             } else { /* received standart message, not a notification */
                 /* no standart message expected: do nothing */
             }
Index: proj/src/proj_func.c
===================================================================
--- proj/src/proj_func.c	(revision 250)
+++ proj/src/proj_func.c	(revision 251)
@@ -10,6 +10,8 @@
 #include "utils.h"
 #include "ent.h"
 #include "fast_math.h"
+#include "rectangle.h"
+#include "font.h"
 
 #include "kbc_macros.h"
 
@@ -189,6 +191,143 @@
     return atan2(gunner_get_y_screen(p) - mouse_y, mouse_x - gunner_get_x_screen(p));
 }
 
+struct menu {
+    rectangle_t *r0, *r1, *r2;
+    text_t      *t0, *t1, *t2;
+    rectangle_t *frame;
+};
+
+menu_t* (menu_ctor)(const font_t *fnt){
+    if(fnt == NULL) return NULL;
+    menu_t *ret = (menu_t*)malloc(sizeof(menu_t));
+    if (ret == NULL) return NULL;
+    ret->r0 = rectangle_ctor(0, 0, 400, 100);
+    ret->r1 = rectangle_ctor(0, 0, 400, 100);
+    ret->r2 = rectangle_ctor(0, 0, 400, 100);
+    ret->t0 = text_ctor(fnt, "PLAY");
+    ret->t1 = text_ctor(fnt, "TEST");
+    ret->t2 = text_ctor(fnt, "EXIT");
+    ret->frame = rectangle_ctor(0, 0, 800, 500);
+    if (ret->r0 == NULL || ret->r1 == NULL || ret->r2 == NULL ||
+        ret->t0 == NULL || ret->t1 == NULL || ret->t2 == NULL ||
+        ret->frame == NULL) return NULL;
+    // VISUAL
+    rectangle_set_fill_color(ret->r0, BLACK);
+    rectangle_set_outline_width(ret->r0, 2);
+    rectangle_set_outline_color(ret->r0, WHITE);
+    rectangle_set_fill_color(ret->r1, BLACK);
+    rectangle_set_outline_width(ret->r1, 2);
+    rectangle_set_outline_color(ret->r1, WHITE);
+    rectangle_set_fill_color(ret->r2, BLACK);
+    rectangle_set_outline_width(ret->r2, 2);
+    rectangle_set_outline_color(ret->r2, WHITE);
+    text_set_valign(ret->t0, text_valign_center);
+    text_set_halign(ret->t0, text_halign_center);
+    text_set_color(ret->t0, TEXT_COLOR);
+    text_set_valign(ret->t1, text_valign_center);
+    text_set_halign(ret->t1, text_halign_center);
+    text_set_color(ret->t1, TEXT_COLOR);
+    text_set_valign(ret->t2, text_valign_center);
+    text_set_halign(ret->t2, text_halign_center);
+    text_set_color(ret->t2, TEXT_COLOR);
+    rectangle_set_fill_color(ret->frame, BLACK);
+    rectangle_set_outline_width(ret->frame, 6);
+    rectangle_set_outline_color(ret->frame, WHITE);
+    // POSITIONS
+    rectangle_set_pos(ret->r0,
+                      graph_get_XRes()/2    - rectangle_get_w(ret->r0)/2,
+                      graph_get_YRes()*0.35 - rectangle_get_h(ret->r0)/2);
+
+
+    rectangle_set_pos(ret->r1,
+                    graph_get_XRes()/2    - rectangle_get_w(ret->r1)/2,
+                    graph_get_YRes()*0.5 - rectangle_get_h(ret->r1)/2);
+
+
+    rectangle_set_pos(ret->r2,
+                  graph_get_XRes()/2    - rectangle_get_w(ret->r2)/2,
+                  graph_get_YRes()*0.65 - rectangle_get_h(ret->r2)/2);
+
+    text_set_pos(ret->t0, rectangle_get_x(ret->r0)+rectangle_get_w(ret->r0)/2,
+                          rectangle_get_y(ret->r0)+rectangle_get_h(ret->r0)/2);
+
+    text_set_pos(ret->t1, rectangle_get_x(ret->r1)+rectangle_get_w(ret->r1)/2,
+                          rectangle_get_y(ret->r1)+rectangle_get_h(ret->r1)/2);
+
+    text_set_pos(ret->t2, rectangle_get_x(ret->r2)+rectangle_get_w(ret->r2)/2,
+                          rectangle_get_y(ret->r2)+rectangle_get_h(ret->r2)/2);
+
+    rectangle_set_pos(ret->frame,
+                  graph_get_XRes()/2    - rectangle_get_w(ret->frame)/2,
+                  graph_get_YRes()*0.5 - rectangle_get_h(ret->frame)/2);
+    return ret;
+}
+
+static int highlighted = -1;
+
+int (menu_update_state)(menu_t *menu, int click) {
+
+    if (rectangle_collide_point(menu->r0, mouse_x, mouse_y)) {
+        highlighted = GAME;
+        if (click) return GAME;
+    } else if (rectangle_collide_point(menu->r1, mouse_x, mouse_y)) {
+        highlighted = TEST;
+        if (click) return TEST;
+    } else if (rectangle_collide_point(menu->r2, mouse_x, mouse_y)) {
+        highlighted = EXIT;
+        if (click) return EXIT;
+    } else {
+        highlighted = -1;
+    }
+    return MENU;
+}
+
+void (menu_draw)(menu_t *menu) {
+    rectangle_draw(menu->frame);
+    switch (highlighted) {
+    case GAME:
+        rectangle_set_fill_color(menu->r0, HIGHLIGHT_COLOR);
+        rectangle_draw(menu->r0);
+        rectangle_draw(menu->r1);
+        rectangle_draw(menu->r2);
+        rectangle_set_fill_color(menu->r0, BLACK);
+        break;
+    case TEST:
+        rectangle_set_fill_color(menu->r1, HIGHLIGHT_COLOR);
+        rectangle_draw(menu->r0);
+        rectangle_draw(menu->r1);
+        rectangle_draw(menu->r2);
+        rectangle_set_fill_color(menu->r1, BLACK);
+        break;
+    case EXIT:
+        rectangle_set_fill_color(menu->r2, HIGHLIGHT_COLOR);
+        rectangle_draw(menu->r0);
+        rectangle_draw(menu->r1);
+        rectangle_draw(menu->r2);
+        rectangle_set_fill_color(menu->r2, BLACK);
+        break;
+    default:
+        rectangle_draw(menu->r0);
+        rectangle_draw(menu->r1);
+        rectangle_draw(menu->r2);
+        break;
+    }
+    text_draw(menu->t0);
+    text_draw(menu->t1);
+    text_draw(menu->t2);
+}
+
+void (menu_dtor)(menu_t *p){
+    rectangle_dtor(p->r0);
+    rectangle_dtor(p->r1);
+    rectangle_dtor(p->r2);
+    rectangle_dtor(p->frame);
+    text_dtor(p->t0);
+    text_dtor(p->t1);
+    text_dtor(p->t2);
+    free(p);
+}
+
 text_timer_t* (timer_ctor)(const font_t *fnt){
     if(fnt == NULL) return NULL;
     text_timer_t *ret = malloc(sizeof(timer_t));
@@ -196,7 +335,7 @@
     ret->time = 0;
     ret->text = text_ctor(fnt, "000s");
     ret->array = text_get_string(ret->text);
-    text_set_color(ret->text, 0x888888);
+    text_set_color(ret->text, TEXT_COLOR);
     return ret;
 }
 
@@ -208,6 +347,13 @@
     p->array[0] = (p->time/100) % 10 + '0';
 }
 
+void (timer_reset)(text_timer_t *p){
+    p->time = 0;
+    p->array[2] = '0';
+    p->array[1] = '0';
+    p->array[0] = '0';
+}
+
 void (timer_dtor)(text_timer_t *p){
     if (p == NULL) return;
     text_dtor(p->text);
Index: proj/src/rectangle.c
===================================================================
--- proj/src/rectangle.c	(revision 250)
+++ proj/src/rectangle.c	(revision 251)
@@ -41,6 +41,11 @@
 uint16_t (rectangle_get_w)(const rectangle_t *p){ return p->w; }
 uint16_t (rectangle_get_h)(const rectangle_t *p){ return p->h; }
 
+int (rectangle_collide_point)(const rectangle_t *p, int x, int y) {
+    int16_t x0 = p->x, y0 = p->y;
+    return (x >= x0 && x <= x0 + p->w) && (y >= y0 && y <= y0 + p->h);
+}
+
 static void (rectangle_draw_hline)(int16_t x, int16_t y, int16_t l, uint32_t color){
     if(l < 0){ rectangle_draw_hline(x+l, y, -l, color); return; }
     for(int16_t x_ = max(0,x); x_ < min(x+l,graph_get_XRes()); ++x_){
