1 /* zzm.c -- zzm file routines
2 * $Id: zzm.c,v 1.2 2005/05/28 03:17:46 bitman Exp $
3 * Copyright (C) 2000 Ryan Phillips <bitman@scn.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place Suite 330; Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24
25 #include "zzm.h"
26 #include "kevedit/kevedit.h"
27 #include "editbox.h"
28 #include "structures/svector.h"
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <ctype.h>
34
35
zzmpullsong(stringvector * zzmv,int songnum)36 stringvector zzmpullsong(stringvector * zzmv, int songnum)
37 {
38 stringvector songlines; /* List of zzm format music */
39 stringnode * curline; /* Current node */
40
41 initstringvector(&songlines);
42
43 if (songnum < 1)
44 return songlines;
45
46 for (curline = zzmv->first; curline != NULL; curline = curline->next) {
47 if (curline->s != NULL &&
48 str_equ(curline->s, "; $SONG ", STREQU_UNCASE | STREQU_FRONT)) {
49 int cursongnum = 0;
50 sscanf(curline->s + 8, "%d", &cursongnum);
51 if (cursongnum == songnum)
52 for (curline = curline->next; curline != NULL && curline->s[0] != ';'; curline = curline->next)
53 pushstring(&songlines, strcpy((char *) malloc(strlen(curline->s)+2), curline->s));
54 }
55 }
56
57 return songlines;
58 }
59
zzmpicksong(stringvector * zzmv,displaymethod * d)60 int zzmpicksong(stringvector * zzmv, displaymethod * d)
61 {
62 stringvector songtitles; /* List of song names in zzmv */
63 stringvector rawtitles; /* vector sharing strings with zzmv */
64 stringnode * curline; /* Current node */
65 char *newstr; /* New strings for songtitles */
66 int i = 0, k = 0;
67
68 if (zzmv == NULL || zzmv->first == NULL)
69 return -1;
70
71 initstringvector(&songtitles);
72 initstringvector(&rawtitles);
73
74
75 pushstring(&songtitles, strcpy((char *) malloc(42), "@here"));
76 /* put header info at top of songtitles */
77 for (curline = zzmv->first; curline != NULL; curline = curline->next) {
78 if (curline->s != NULL &&
79 str_equ(curline->s, "; $TITLE ", STREQU_UNCASE | STREQU_FRONT)) {
80 newstr = (char *) malloc(43);
81 strcpy(newstr, "$");
82 strncat(newstr, curline->s + 9, 41);
83 for (i = 0; i < strlen(newstr); i++)
84 if (newstr[i] == '~')
85 newstr[i] = ' ';
86
87 pushstring(&songtitles, newstr);
88 pushstring(&songtitles, strcpy((char *) malloc(2), ""));
89 }
90 }
91
92 /* find all the song titles and put them songnames */
93 for (curline = zzmv->first; curline != NULL; curline = curline->next) {
94 if (curline->s != NULL &&
95 str_equ(curline->s, "; $SONG TITLE ", STREQU_UNCASE | STREQU_FRONT)) {
96
97 /* put the song number and title in rawtitles */
98 pushstring(&rawtitles, curline->s + 14);
99 }
100 }
101
102 if (rawtitles.first == NULL)
103 return -1;
104
105 /* Sort rawtitles */
106 /* Use insertion sort because the titles are most likely in order anyway. */
107 if (rawtitles.first != NULL && rawtitles.first->next != NULL) {
108 char *curstr = NULL;
109 stringnode *nodepos = NULL;
110 int valcur, valprev;
111
112 for (rawtitles.cur = rawtitles.first->next; rawtitles.cur != NULL; rawtitles.cur = rawtitles.cur->next) {
113 curstr = rawtitles.cur->s;
114 sscanf(rawtitles.cur->s, "%d", &valcur);
115
116 /* Find place to insert curstr */
117 nodepos = rawtitles.cur;
118 while (nodepos != rawtitles.first && (sscanf(nodepos->prev->s, "%d", &valprev), valprev) > valcur) {
119 nodepos->s = nodepos->prev->s;
120 nodepos = nodepos->prev;
121 }
122 nodepos->s = curstr;
123 }
124 }
125
126 /* Copy titles into songtitles for browsing */
127
128 for (rawtitles.cur = rawtitles.first; rawtitles.cur != NULL; rawtitles.cur = rawtitles.cur->next) {
129 /* the title from rawtitles.cur can now be pushed onto songtitles */
130 newstr = (char *) malloc(strlen(rawtitles.cur->s) + 3);
131 strcpy(newstr, "!");
132 strcat(newstr, rawtitles.cur->s);
133 if (strstr(newstr, " ") != NULL)
134 *strstr(newstr, " ") = ';';
135
136 /* remove ~s from older files */
137 for (k = 0; k < strlen(newstr); k++)
138 if (newstr[k] == '~') newstr[k] = ' ';
139
140 /* Cut the string off if wider than dialog */
141 if (strlen(newstr) > 42)
142 newstr[42] = 0;
143
144 pushstring(&songtitles, newstr);
145 }
146
147 /* songtitles now contains all the info we need to offer a dialog */
148 songtitles.cur = songtitles.first;
149 do {
150 if (editbox("Pick a ZZM Song", &songtitles, 0, 1, d) == 27) {
151 deletestringvector(&songtitles);
152 return -1;
153 }
154 } while (songtitles.cur->s[0] != '!');
155
156 /* determine the number chosen */
157 sscanf(songtitles.cur->s, "%*c%d", &i);
158
159 deletestringvector(&songtitles);
160
161 return i;
162 }
163
zzmripsong(stringvector * zoc,int maxseparation)164 stringvector zzmripsong(stringvector * zoc, int maxseparation)
165 {
166 stringvector songlines;
167 stringnode * curline = zoc->cur;
168 int separation = 0;
169
170 initstringvector(&songlines);
171
172 while (curline != NULL && separation <= maxseparation) {
173 char* tune = strstr(curline->s, "#");
174 if (tune != NULL && str_equ(tune, "#play ", STREQU_UNCASE | STREQU_RFRONT)) {
175 separation = 0; /* Reset separation counter */
176 tune += 6; /* Advance to notes! */
177
178 /* Push the remainder of the line into songlines */
179 pushstring(&songlines, str_dup(tune));
180 } else {
181 separation++;
182 }
183
184 curline = curline->next;
185 }
186
187 return songlines;
188 }
189