Applied my "bidirectional dt scaling" patch. Accordingly, the game can
[neverball] / putt / st_all.c
index 891f0df..67dced9 100644 (file)
@@ -1,4 +1,4 @@
-/*   
+/*
  * Copyright (C) 2003 Robert Kooima
  *
  * NEVERPUTT is  free software; you can redistribute  it and/or modify
@@ -62,7 +62,7 @@ static int score_card(const char  *title,
         if ((jd = gui_hstack(id)))
         {
             if ((kd = gui_varray(jd)))
-            { 
+            {
                 if (p1) gui_label(kd, _("O"),         0, GUI_NE, 0, 0);
                 if (p1) gui_label(kd, hole_out(0), 0, 0,           gui_wht, gui_wht);
                 if (p1) gui_label(kd, hole_out(1), 0, GUI_SE * l1, gui_red, gui_wht);
@@ -170,7 +170,7 @@ static int title_enter(void)
 
     if ((id = gui_vstack(0)))
     {
-        gui_label(id, _("Neverputt"), GUI_LRG, GUI_ALL, 0, 0);
+        gui_label(id, "Neverputt", GUI_LRG, GUI_ALL, 0, 0);
         gui_space(id);
 
         if ((jd = gui_harray(id)))
@@ -265,24 +265,26 @@ static int course_enter(void)
 
         if ((jd = gui_hstack(id)))
         {
-           shot_id = gui_image(jd, course_shot(0), w / 3, h / 3);
+            shot_id = gui_image(jd, course_shot(0), w / 3, h / 3);
             gui_filler(jd);
-           if ((kd = gui_varray(jd)))
-           {
+            if ((kd = gui_varray(jd)))
+            {
                 for(i = 0; i < n; i += m)
-               {
-                   if ((ld = gui_harray(kd)))
-                   {
-                       for (j = (m-1); j >= 0; j--)
-                       {
-                           if (i+j < n)
-                               gui_active(gui_image(ld, course_shot(i+j), w / 3 / m, h / 3 / m), i+j, 0);
-                           else
-                               gui_space(ld);
-                       }
-                   }
-               }
-           }
+                {
+                    if ((ld = gui_harray(kd)))
+                    {
+                        for (j = (m - 1); j >= 0; j--)
+                        {
+                            if (i + j < n)
+                                gui_active(gui_image(ld, course_shot(i + j),
+                                                     w / 3 / m, h / 3 / m),
+                                           i + j, 0);
+                            else
+                                gui_space(ld);
+                        }
+                    }
+                }
+            }
         }
 
         gui_space(id);
@@ -327,11 +329,11 @@ static void course_point(int id, int x, int y, int dx, int dy)
     if ((jd = gui_point(id, x, y)))
     {
         int i = gui_token(jd);
-       if (course_exists(i))
-       {
-           gui_set_image(shot_id, course_shot(i));
+        if (course_exists(i))
+        {
+            gui_set_image(shot_id, course_shot(i));
             gui_set_multi(desc_id, _(course_desc(i)));
-       }
+        }
         gui_pulse(jd, 1.2f);
     }
 }
@@ -457,6 +459,117 @@ static int party_keybd(int c, int d)
 
 /*---------------------------------------------------------------------------*/
 
+static int paused = 0;
+
+static struct state *st_continue;
+static struct state *st_quit;
+
+#define PAUSE_CONTINUE 1
+#define PAUSE_QUIT     2
+
+int goto_pause(struct state *s, int e)
+{
+    if (e && (SDL_GetModState() & (KMOD_SHIFT | KMOD_CTRL | KMOD_ALT | KMOD_META)))
+        return goto_state(s);
+    st_continue = curr_state();
+    st_quit = s;
+    paused = 1;
+    return goto_state(&st_pause);
+}
+
+static int pause_action(int i)
+{
+    audio_play(AUD_MENU, 1.0f);
+
+    switch(i)
+    {
+    case PAUSE_CONTINUE:
+        return goto_state(st_continue ? st_continue : &st_title);
+
+    case PAUSE_QUIT:
+        return goto_state(st_quit);
+    }
+    return 1;
+}
+
+static int pause_enter(void)
+{
+    int id, jd, td;
+
+    audio_music_fade_out(0.2f);
+
+    if ((id = gui_vstack(0)))
+    {
+        td = gui_label(id, _("Paused"), GUI_LRG, GUI_ALL, 0, 0);
+        gui_space(id);
+
+        if ((jd = gui_harray(id)))
+        {
+            gui_state(jd, _("Quit"), GUI_SML, PAUSE_QUIT, 0);
+            gui_start(jd, _("Continue"), GUI_SML, PAUSE_CONTINUE, 1);
+        }
+
+        gui_pulse(td, 1.2f);
+        gui_layout(id, 0, 0);
+    }
+
+    hud_init();
+    return id;
+}
+
+static void pause_leave(int id)
+{
+    gui_delete(id);
+    hud_free();
+    audio_music_fade_in(0.5f);
+}
+
+static void pause_paint(int id, float st)
+{
+    game_draw(0);
+    gui_paint(id);
+    hud_paint();
+}
+
+static void pause_timer(int id, float dt)
+{
+    gui_timer(id, dt);
+    audio_timer(dt);
+}
+
+static void pause_point(int id, int x, int y, int dx, int dy)
+{
+    gui_pulse(gui_point(id, x, y), 1.2f);
+}
+
+static int pause_click(int b, int d)
+{
+    return (d && b < 0) ? pause_action(gui_token(gui_click())) : 1;
+}
+
+static int pause_keybd(int c, int d)
+{
+    if (d && (c == SDLK_ESCAPE || config_tst_d(CONFIG_KEY_PAUSE, c)))
+        return pause_action(PAUSE_CONTINUE);
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int shared_keybd(int c, int d)
+{
+    if (d)
+    {
+        if (c == SDLK_ESCAPE)
+            return goto_pause(&st_over, 1);
+        if (config_tst_d(CONFIG_KEY_PAUSE, c))
+            return goto_pause(&st_over, 0);
+    }
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
 static int num = 0;
 
 static int next_enter(void)
@@ -498,6 +611,9 @@ static int next_enter(void)
     hud_init();
     game_set_fly(1.f);
 
+    if (paused)
+        paused = 0;
+
     return id;
 }
 
@@ -537,7 +653,9 @@ static int next_keybd(int c, int d)
         if (c == SDLK_F12)
             return goto_state(&st_poser);
         if (c == SDLK_ESCAPE)
-            return goto_state(&st_over);
+            return goto_pause(&st_over, 1);
+        if (config_tst_d(CONFIG_KEY_PAUSE, c))
+            return goto_pause(&st_over, 0);
         if (c == SDLK_RETURN)
         {
             hole_goto(num, -1);
@@ -572,7 +690,11 @@ static int poser_keybd(int c, int d)
 
 static int flyby_enter(void)
 {
-    hud_init();
+    if (paused)
+        paused = 0;
+    else
+        hud_init();
+
     return 0;
 }
 
@@ -610,11 +732,6 @@ static int flyby_click(int b, int d)
     return 1;
 }
 
-static int flyby_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int stroke_enter(void)
@@ -622,7 +739,11 @@ static int stroke_enter(void)
     hud_init();
     game_clr_mag();
     config_set_d(CONFIG_CAMERA, 2);
-    config_set_grab();
+    config_set_grab(!paused);
+
+    if (paused)
+        paused = 0;
+
     return 0;
 }
 
@@ -659,17 +780,17 @@ static int stroke_click(int b, int d)
     return (d && b < 0) ? goto_state(&st_roll) : 1;
 }
 
-static int stroke_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int roll_enter(void)
 {
     hud_init();
-    game_putt();
+
+    if (paused)
+        paused = 0;
+    else
+        game_putt();
+
     return 0;
 }
 
@@ -697,21 +818,20 @@ static void roll_timer(int id, float dt)
     audio_timer(dt);
 }
 
-static int roll_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int goal_enter(void)
 {
     int id;
-    
+
     if ((id = gui_label(0, _("It's In!"), GUI_MED, GUI_ALL, gui_grn, gui_grn)))
         gui_layout(id, 0, 0);
 
-    hole_goal();
+    if (paused)
+        paused = 0;
+    else
+        hole_goal();
+
     hud_init();
 
     return id;
@@ -754,17 +874,17 @@ static int goal_click(int b, int d)
     return 1;
 }
 
-static int goal_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int stop_enter(void)
 {
-    hole_stop();
+    if (paused)
+        paused = 0;
+    else
+        hole_stop();
+
     hud_init();
+
     return 0;
 }
 
@@ -808,21 +928,23 @@ static int stop_click(int b, int d)
     return 1;
 }
 
-static int stop_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int fall_enter(void)
 {
     int id;
-    
+
     if ((id = gui_label(0, _("1 Stroke Penalty"), GUI_MED, GUI_ALL, gui_blk, gui_red)))
         gui_layout(id, 0, 0);
 
-    hole_fall();
+    if (paused)
+        paused = 0;
+    else
+    {
+        hole_fall();
+        game_draw(0); /*TODO: is this call ok? */
+    }
+
     hud_init();
 
     return id;
@@ -865,16 +987,15 @@ static int fall_click(int b, int d)
     return 1;
 }
 
-static int fall_keybd(int c, int d)
-{
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_over) : 1;
-}
-
 /*---------------------------------------------------------------------------*/
 
 static int score_enter(void)
 {
     audio_music_fade_out(2.f);
+
+    if (paused)
+        paused = 0;
+
     return score_card(_("Scores"), gui_yel, gui_red);
 }
 
@@ -909,7 +1030,14 @@ static int score_click(int b, int d)
 
 static int score_keybd(int c, int d)
 {
-    return (d && c == SDLK_ESCAPE) ? goto_state(&st_title) : 1;
+    if (d)
+    {
+        if (c == SDLK_ESCAPE)
+            return goto_pause(&st_title, 1);
+        if (config_tst_d(CONFIG_KEY_PAUSE, c))
+            return goto_pause(&st_title, 0);
+    }
+    return 1;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -1022,7 +1150,7 @@ struct state st_flyby = {
     NULL,
     NULL,
     flyby_click,
-    flyby_keybd,
+    shared_keybd,
     NULL,
     1, 0
 };
@@ -1035,7 +1163,7 @@ struct state st_stroke = {
     stroke_point,
     NULL,
     stroke_click,
-    stroke_keybd,
+    shared_keybd,
     NULL,
     0, 0
 };
@@ -1048,7 +1176,7 @@ struct state st_roll = {
     NULL,
     NULL,
     NULL,
-    roll_keybd,
+    shared_keybd,
     NULL,
     0, 0
 };
@@ -1061,7 +1189,7 @@ struct state st_goal = {
     NULL,
     NULL,
     goal_click,
-    goal_keybd,
+    shared_keybd,
     NULL,
     0, 0
 };
@@ -1074,7 +1202,7 @@ struct state st_stop = {
     NULL,
     NULL,
     stop_click,
-    stop_keybd,
+    shared_keybd,
     NULL,
     0, 0
 };
@@ -1087,7 +1215,7 @@ struct state st_fall = {
     NULL,
     NULL,
     fall_click,
-    fall_keybd,
+    shared_keybd,
     NULL,
     0, 0
 };
@@ -1117,3 +1245,16 @@ struct state st_over = {
     NULL,
     1, 0
 };
+
+struct state st_pause = {
+    pause_enter,
+    pause_leave,
+    pause_paint,
+    pause_timer,
+    pause_point,
+    NULL,
+    pause_click,
+    pause_keybd,
+    NULL,
+    1, 0
+};