Merge from vendor branch GROFF:
[dragonfly.git] / games / piano / piano.c
1 /*
2  * piano.c - a piano emulator
3  *
4  * $FreeBSD: src/games/piano/piano.c,v 1.7 1999/12/12 03:22:37 billf Exp $
5  * $DragonFly: src/games/piano/piano.c,v 1.3 2005/05/31 00:22:38 swildner Exp $
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <curses.h>
11
12 #include <unistd.h>
13 #include <sys/file.h>
14
15 char *myname;
16 int verbose;
17 static const char *initcmd = "t160 o1 l16 ml";
18
19 static const char usage_msg[] =
20         "simple keyboard player V0.8086\n"
21         "usage: %s [-v][-i str]\n"
22         "\t-i str defaults 't160 o1 l16 ml'\n"
23         "function: play by console keyboard\n"
24         "\tESC to exit. Note keys are ...\n"
25         "\t1 2   4 5   7 8 9   - = \\\n"
26         "\t Q W E R T Y U I O P [ ]\n"
27         ;
28
29 struct kdef_t {
30         int ch;
31         const char *str;
32 };
33
34 static const char *kstr[256];
35
36 static struct kdef_t kdef[] = {
37         /* white key */
38         { '\t', "<g>" },
39         { 'q', "<a>" },
40         { 'w', "<b>" },
41         { 'e', "c" },
42         { 'r', "d" },
43         { 't', "e" },
44         { 'y', "f" },
45         { 'u', "g" },
46         { 'i', "a" },
47         { 'o', "b" },
48         { 'p', ">c<" },
49         { '[', ">d<" },
50         { ']', ">e<" },
51         { '\n', ">f<" },
52         { '\r', ">f<" },
53         /* black key */
54         { '`', "<f#>" },
55         { '1', "<g#>" },
56         { '2', "<a#>" },
57         /*{ '3', "<b#>" },*/
58         { '4', "c#" },
59         { '5', "d#" },
60         /*{ '6', "e#" },*/
61         { '7', "f#" },
62         { '8', "g#" },
63         { '9', "a#" },
64         /*{ '0', "b#" },*/
65         { '-', ">c#<" },
66         { '=', ">d#<" },
67         /*{ '\', ">e#<" },*/
68         { '\177', ">f#<" },
69         { '\0', NULL }
70 };
71
72 static int
73 init_kstr(void)
74 {
75         struct kdef_t *mv = kdef;
76         while (mv->str != NULL) {
77                 kstr[mv->ch] = mv->str;
78                 mv++;
79         }/* while */
80         return 0;
81 }/* init_kstr */
82
83 static int
84 fdputs(const char *s, int fd, int p_echo)
85 {
86         int err;
87         size_t len = strlen(s);
88         write(fd, s, len);
89         err = write(fd, "\n", 1);
90         if (p_echo) {
91                 fputs(s, stdout);
92         }
93         return err;
94 }/* fdputs */
95
96 static int
97 outspkr(const char *s)
98 {
99         int err = -1, fd = open("/dev/speaker", O_WRONLY);
100         if (fd >= 0) {
101                 fdputs(initcmd, fd, 0);
102                 err = fdputs(s, fd, verbose);
103                 close(fd);
104         }
105         return err;
106 }/* outspkr */
107
108 static int
109 nain(void)
110 {
111         int ch;
112         initscr();
113         noecho();
114         nonl();
115         raw();
116         init_kstr();
117         while ((ch = getch()) != '\033') {
118                 if (kstr[ch] != NULL) {
119                         outspkr(kstr[ch]);
120                 }
121                 else {
122                         if (verbose) {
123                                 switch (ch) {
124                                 case ' ':
125                                         fputs(" ", stdout);
126                                         break;
127                                 case '\b':
128                                         fputs("\b", stdout);
129                                         break;
130                                 }/* switch */
131                         }
132                 }
133         }/* while */
134         endwin();
135         return 0;
136 }/* nain */
137
138 int
139 main(int argc, char *argv[])
140 {
141         int ch, ex, show_usage = 0;
142         myname = argv[0];
143         while ((ch = getopt(argc, argv, "-vi:")) != -1) {
144                 switch (ch) {
145                 default:
146                 case 'V':
147                         show_usage++;
148                         break;
149                 case 'v':
150                         verbose++;
151                         break;
152                 case 'i':
153                         initcmd = optarg;
154                         break;
155                 }/* switch */
156         }/* while */
157         ex = 1;
158         if (show_usage) {
159                 fprintf(stderr, usage_msg, myname);
160         }
161         else {
162                 printf("Type ESC to exit.\n");
163                 ex = 0;
164                 nain();
165         }
166         return ex;
167 }/* main */