From: Samuel Thibault Date: Sun, 14 Feb 2010 17:14:16 +0000 (+0100) Subject: 2010-02-14 Samuel Thibault X-Git-Tag: 1.98~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=37c8483b9756d3ea161d0f7a123c4bd57e1cddaf;p=thirdparty%2Fgrub.git 2010-02-14 Samuel Thibault * 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. --- diff --git a/ChangeLog b/ChangeLog index 950a26f3d..60a1f5db3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-14 Samuel Thibault + + * 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 * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 84819b551..1bca3d763 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -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, ¬e)) + break; + } } beep_off (); - grub_file_close (file); - while (grub_checkkey () > 0) grub_getkey ();