Merge branch 'gles'
[neverball] / ball / main.c
index 0c9c557..98a33d9 100644 (file)
@@ -42,18 +42,30 @@ const char ICON[] = "icon/neverball.png";
 
 /*---------------------------------------------------------------------------*/
 
-static void shot(void)
+static int shot_pending;
+
+static void shot_prep(void)
+{
+    shot_pending = 1;
+}
+
+static void shot_take(void)
 {
     static char filename[MAXSTR];
 
-    sprintf(filename, "Screenshots/screen%05d.png", config_screenshot());
-    image_snap(filename);
+    if (shot_pending)
+    {
+        sprintf(filename, "Screenshots/screen%05d.png", config_screenshot());
+        image_snap(filename);
+        shot_pending = 0;
+    }
 }
 
 /*---------------------------------------------------------------------------*/
 
 static void toggle_wire(void)
 {
+#if !ENABLE_OPENGLES
     static int wire = 0;
 
     if (wire)
@@ -70,15 +82,96 @@ static void toggle_wire(void)
         glDisable(GL_LIGHTING);
         wire = 1;
     }
+#endif
 }
 
 /*---------------------------------------------------------------------------*/
 
+static int handle_key_dn(SDL_Event *e)
+{
+    int d = 1;
+    int c;
+
+    c = e->key.keysym.sym;
+
+    if (config_tst_d(CONFIG_KEY_FORWARD, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), -1.0f);
+
+    else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), +1.0f);
+
+    else if (config_tst_d(CONFIG_KEY_LEFT, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), -1.0f);
+
+    else if (config_tst_d(CONFIG_KEY_RIGHT, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), +1.0f);
+
+    else switch (c)
+    {
+    case SDLK_F10:   shot_prep();               break;
+    case SDLK_F9:    config_tgl_d(CONFIG_FPS);  break;
+    case SDLK_F8:    config_tgl_d(CONFIG_NICE); break;
+
+    case SDLK_F7:
+        if (config_cheat())
+            toggle_wire();
+        break;
+    case SDLK_RETURN:
+        d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 1);
+        break;
+    case SDLK_ESCAPE:
+        d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 1);
+        break;
+
+    default:
+        if (SDL_EnableUNICODE(-1))
+            d = st_keybd(e->key.keysym.unicode, 1);
+        else
+            d = st_keybd(e->key.keysym.sym, 1);
+    }
+
+    return d;
+}
+
+static int handle_key_up(SDL_Event *e)
+{
+    int d = 1;
+    int c;
+
+    c = e->key.keysym.sym;
+
+    if (config_tst_d(CONFIG_KEY_FORWARD, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 0);
+
+    else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 0);
+
+    else if (config_tst_d(CONFIG_KEY_LEFT, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 0);
+
+    else if (config_tst_d(CONFIG_KEY_RIGHT, c))
+        st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 0);
+
+    else switch (c)
+    {
+    case SDLK_RETURN:
+        d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 0);
+        break;
+    case SDLK_ESCAPE:
+        d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 0);
+        break;
+
+    default:
+        d = st_keybd(e->key.keysym.sym, 0);
+    }
+
+    return d;
+}
+
 static int loop(void)
 {
     SDL_Event e;
     int d = 1;
-    int c;
 
     /* Process SDL events. */
 
@@ -106,76 +199,12 @@ static int loop(void)
             break;
 
         case SDL_KEYDOWN:
-
-            c = e.key.keysym.sym;
-
-            if (config_tst_d(CONFIG_KEY_FORWARD, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), -JOY_MAX);
-
-            else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), +JOY_MAX);
-
-            else if (config_tst_d(CONFIG_KEY_LEFT, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), -JOY_MAX);
-
-            else if (config_tst_d(CONFIG_KEY_RIGHT, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), +JOY_MAX);
-
-            else switch (c)
-            {
-            case SDLK_F10:   shot();                    break;
-            case SDLK_F9:    config_tgl_d(CONFIG_FPS);  break;
-            case SDLK_F8:    config_tgl_d(CONFIG_NICE); break;
-
-            case SDLK_F7:
-                if (config_cheat())
-                    toggle_wire();
-                break;
-
-            case SDLK_RETURN:
-                d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 1);
-                break;
-            case SDLK_ESCAPE:
-                d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 1);
-                break;
-
-            default:
-                if (SDL_EnableUNICODE(-1))
-                    d = st_keybd(e.key.keysym.unicode, 1);
-                else
-                    d = st_keybd(e.key.keysym.sym, 1);
-            }
-
+            d = handle_key_dn(&e);
             break;
 
         case SDL_KEYUP:
-
-            c = e.key.keysym.sym;
-
-            if      (config_tst_d(CONFIG_KEY_FORWARD, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 1);
-
-            else if (config_tst_d(CONFIG_KEY_BACKWARD, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_Y), 1);
-
-            else if (config_tst_d(CONFIG_KEY_LEFT, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 1);
-
-            else if (config_tst_d(CONFIG_KEY_RIGHT, c))
-                st_stick(config_get_d(CONFIG_JOYSTICK_AXIS_X), 1);
-
-            else switch (c)
-            {
-            case SDLK_RETURN:
-                d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_A), 0);
-                break;
-            case SDLK_ESCAPE:
-                d = st_buttn(config_get_d(CONFIG_JOYSTICK_BUTTON_EXIT), 0);
-                break;
-
-            default:
-                d = st_keybd(e.key.keysym.sym, 0);
-            }
+            d = handle_key_up(&e);
+            break;
 
         case SDL_ACTIVEEVENT:
             if (e.active.state == SDL_APPINPUTFOCUS)
@@ -184,7 +213,7 @@ static int loop(void)
             break;
 
         case SDL_JOYAXISMOTION:
-            st_stick(e.jaxis.axis, e.jaxis.value);
+            st_stick(e.jaxis.axis, JOY_VALUE(e.jaxis.value));
             break;
 
         case SDL_JOYBUTTONDOWN:
@@ -229,13 +258,13 @@ static int loop(void)
 
                 /* Convert D-pad button events into joystick axis motion. */
 
-                if      (pad[0] && !pad[1]) st_stick(X, -JOY_MAX);
-                else if (pad[1] && !pad[0]) st_stick(X, +JOY_MAX);
-                else                        st_stick(X,        1);
+                if      (pad[0] && !pad[1]) st_stick(X, -1.0f);
+                else if (pad[1] && !pad[0]) st_stick(X, +1.0f);
+                else                        st_stick(X,  0.0f);
 
-                if      (pad[2] && !pad[3]) st_stick(Y, -JOY_MAX);
-                else if (pad[3] && !pad[2]) st_stick(Y, +JOY_MAX);
-                else                        st_stick(Y,        1);
+                if      (pad[2] && !pad[3]) st_stick(Y, -1.0f);
+                else if (pad[3] && !pad[2]) st_stick(Y, +1.0f);
+                else                        st_stick(Y,  0.0f);
             }
             else d = st_buttn(b, s);
         }
@@ -248,6 +277,7 @@ static int loop(void)
 
 static char *opt_data;
 static char *opt_replay;
+static char *opt_level;
 
 #define opt_usage \
     L_(                                                                   \
@@ -257,6 +287,7 @@ static char *opt_replay;
         "  -v, --version             show version.\n"                     \
         "  -d, --data <dir>          use 'dir' as game data directory.\n" \
         "  -r, --replay <file>       play the replay 'file'.\n"           \
+        "  -l, --level <file>        load the level 'file'\n"             \
     )
 
 #define opt_error(option) \
@@ -304,11 +335,40 @@ static void opt_parse(int argc, char **argv)
             continue;
         }
 
-        /* Assume a single unrecognized argument is a replay name. */
+        if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--level")  == 0)
+        {
+            if (i + 1 == argc)
+            {
+                opt_error(argv[i]);
+                exit(EXIT_FAILURE);
+            }
+            opt_level = argv[++i];
+            continue;
+        }
+
+        /* Perform magic on a single unrecognized argument. */
 
         if (argc == 2)
         {
-            opt_replay = argv[i];
+            size_t len = strlen(argv[i]);
+            int level = 0;
+
+            if (len > 4)
+            {
+                char *ext = argv[i] + len - 4;
+
+                if (strcmp(ext, ".map") == 0)
+                    strncpy(ext, ".sol", 4);
+
+                if (strcmp(ext, ".sol") == 0)
+                    level = 1;
+            }
+
+            if (level)
+                opt_level = argv[i];
+            else
+                opt_replay = argv[i];
+
             break;
         }
     }
@@ -430,7 +490,7 @@ int main(int argc, char *argv[])
 
     init_state(&st_null);
 
-    /* Initialize demo playback. */
+    /* Initialize demo playback or load the level. */
 
     if (opt_replay &&
         fs_add_path(dir_name(opt_replay)) &&
@@ -439,6 +499,32 @@ int main(int argc, char *argv[])
         demo_play_goto(1);
         goto_state(&st_demo_play);
     }
+    else if (opt_level)
+    {
+        const char *path = fs_resolve(opt_level);
+        int loaded = 0;
+
+        if (path)
+        {
+            /* HACK: must be around for the duration of the game. */
+            static struct level level;
+
+            if (level_load(path, &level))
+            {
+                progress_init(MODE_STANDALONE);
+
+                if (progress_play(&level))
+                {
+                    goto_state(&st_level);
+                    loaded = 1;
+                }
+            }
+        }
+        else fprintf(stderr, "%s: file is not in game path\n", opt_level);
+
+        if (!loaded)
+            goto_state(&st_title);
+    }
     else
         goto_state(&st_title);
 
@@ -459,6 +545,7 @@ int main(int argc, char *argv[])
             /* Render. */
 
             st_paint(0.001f * t0);
+            shot_take();
             video_swap();
 
             if (config_get_d(CONFIG_NICE))