]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2010-02-14 Samuel Thibault <samuel.thibault@ens-lyon.org>
authorSamuel Thibault <samuel.thibault@ens-lyon.org>
Sun, 14 Feb 2010 17:14:16 +0000 (18:14 +0100)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Sun, 14 Feb 2010 17:14:16 +0000 (18:14 +0100)
* commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails,
parse arguments as inline tempo and notes.  Move code for playing notes
to...
(play): ... new function.

ChangeLog
commands/i386/pc/play.c

index 950a26f3d95147071736ea27690190799963217e..60a1f5db37e16f78401abdbdde8c98191092358d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-02-14  Samuel Thibault  <samuel.thibault@ens-lyon.org>
+
+       * commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails,
+       parse arguments as inline tempo and notes.  Move code for playing notes
+       to...
+       (play): ... new function.
+
 2010-02-14  Samuel Thibault  <samuel.thibault@ens-lyon.org>
 
        * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use
index 84819b5519eef19e09f0d1b56ecf82b740a484a1..1bca3d763c2fa80c1bb5b44ca5f8351d34b40d3f 100644 (file)
@@ -143,66 +143,111 @@ beep_on (grub_uint16_t pitch)
   grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER);
 }
 
-static grub_err_t
-grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
-              int argc, char **args)
+/* Returns whether playing should continue.  */
+static int
+play (unsigned tempo, struct note *note)
 {
-  grub_file_t file;
-  struct note buf;
-  grub_uint32_t tempo;
   unsigned int to;
 
-  if (argc != 1)
-    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+  if (note->pitch == T_FINE || grub_checkkey () >= 0)
+    return 1;
 
-  file = grub_file_open (args[0]);
-  if (! file)
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+  grub_dprintf ("play", "pitch = %d, duration = %d\n", note->pitch,
+                note->duration);
 
-  if (grub_file_read (file, &tempo, sizeof(tempo)) != sizeof(tempo))
+  switch (note->pitch)
     {
-      grub_file_close (file);
-      return grub_error (GRUB_ERR_FILE_READ_ERROR,
-                         "file doesn't even contains a full tempo record");
+      case T_REST:
+        beep_off ();
+        break;
+
+      default:
+        beep_on (note->pitch);
+        break;
     }
 
-  tempo = grub_le_to_cpu32(tempo);
+  to = grub_get_rtc () + BASE_TEMPO * note->duration / tempo;
+  while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0))
+    ;
 
-  grub_dprintf ("play","tempo = %d\n", tempo);
+  return 0;
+}
+
+static grub_err_t
+grub_cmd_play (grub_command_t cmd __attribute__ ((unused)),
+              int argc, char **args)
+{
+  grub_file_t file;
 
-  while (grub_file_read (file, &buf,
-                         sizeof (struct note)) == sizeof (struct note))
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required");
+
+  file = grub_file_open (args[0]);
+  if (file)
     {
-      buf.pitch = grub_le_to_cpu16(buf.pitch);
-      buf.duration = grub_le_to_cpu16(buf.duration);
+      struct note buf;
+      grub_uint32_t tempo;
 
-      if (buf.pitch == T_FINE || grub_checkkey () >= 0)
-        break;
+      if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo))
+        {
+          grub_file_close (file);
+          return grub_error (GRUB_ERR_FILE_READ_ERROR,
+                             "file doesn't even contains a full tempo record");
+        }
 
-      grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch,
-                    buf.duration);
+      tempo = grub_le_to_cpu32 (tempo);
+      grub_dprintf ("play","tempo = %d\n", tempo);
 
-      switch (buf.pitch)
+      while (grub_file_read (file, &buf,
+                             sizeof (struct note)) == sizeof (struct note))
         {
-          case T_REST:
-            beep_off ();
-            break;
+          buf.pitch = grub_le_to_cpu16 (buf.pitch);
+          buf.duration = grub_le_to_cpu16 (buf.duration);
 
-          default:
-            beep_on (buf.pitch);
+          if (play (tempo, &buf))
             break;
         }
 
-      to = grub_get_rtc () + BASE_TEMPO * buf.duration / tempo;
-      while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0))
-        ;
+      grub_file_close (file);
+    }
+  else
+    {
+      char *end;
+      unsigned tempo;
+      struct note note;
+      int i;
+
+      tempo = grub_strtoul (args[0], &end, 0);
+
+      if (*end)
+        /* Was not a number either, assume it was supposed to be a file name.  */
+        return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
+
+      grub_dprintf ("play","tempo = %d\n", tempo);
 
+      for (i = 1; i + 1 < argc; i += 2)
+        {
+          note.pitch = grub_strtoul (args[i], &end, 0);
+          if (*end)
+            {
+              grub_error (GRUB_ERR_BAD_NUMBER, "bogus pitch number");
+              break;
+            }
+
+          note.duration = grub_strtoul (args[i + 1], &end, 0);
+          if (*end)
+            {
+              grub_error (GRUB_ERR_BAD_NUMBER, "bogus duration number");
+              break;
+            }
+
+          if (play (tempo, &note))
+            break;
+        }
     }
 
   beep_off ();
 
-  grub_file_close (file);
-
   while (grub_checkkey () > 0)
     grub_getkey ();