1 /* $Id: text.c,v 1.5 2006/09/15 13:34:06 toad32767 Exp $ */
2 /**
3  ** 2005, 2006 by Marco Trillo
4  ** This file is part of UModPlayer, and is released by
5  ** its autors to the Public Domain.
6  ** In case it's not legally possible, its autors grant
7  ** anyone the right to use, redistribute and modify
8  ** this software for any purpose, without any conditions,
9  ** unless such conditions are required by law.
10  **
11  ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS
12  ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE
13  ** USE OR MISUSE OF THIS SOFTWARE.
14  **/
15 
16 /*
17  * =====================
18  *  TEXT-RELATED STUFF
19  * =====================
20  */
21 
22 #include <messages.h>
23 #include <umodplayer.h>
24 #include <file_parse.h>
25 
26 EXPORT char *
strcopyof(char * str)27 strcopyof(char *str)
28 {
29 	char *ptr;
30 	size_t len;
31 
32 	len = (size_t) strlen(str) + 1;
33 	ptr = malloc(len);
34 	if (ptr == NULL)
35 		return NULL;
36 	memcpy(ptr, str, len);	/* includes NUL */
37 
38 	return ptr;
39 }
40 
41 EXPORT char *
ReadStringFromFile(FILE * fp)42 ReadStringFromFile(FILE * fp)
43 {
44 	char ret[128];
45 	char *ptr = (char *) ret;
46 	int c, i = 0;
47 
48 	c = getc(fp);
49 	while (c != EOF && c != '\n' && (i++) < 127) {
50 		*ptr++ = (char) c;
51 		c = getc(fp);
52 	}
53 	*ptr = '\0';
54 
55 	return strcopyof(ret);
56 }
57 
58 EXPORT char *
ReadString()59 ReadString()
60 {
61 	return ReadStringFromFile(stdin);
62 }
63 
64 
65 EXPORT void
TrimString(char * string)66 TrimString(char *string)
67 {
68 	/* Remove final blank spaces on strings */
69 	int l;
70 	l = strlen(string) - 1;
71 	for (;;) {
72 		if (l < 0)
73 			break;
74 		if (string[l] == ' ' || string[l] == '\t')
75 			string[l] = '\0';
76 		else
77 			break;
78 		l--;
79 	}
80 	return;
81 }
82 
83 EXPORT int
CalcLen(char ** array,int size)84 CalcLen(char **array, int size)
85 {
86 	int i, a, L = 0;
87 	for (i = 0; i < size; ++i) {
88 		a = strlen(array[i]);
89 		if (a > L) {
90 			L = a;
91 		}
92 	}
93 
94 	return L;
95 }
96 
97 /* sound options ordered by table position */
98 LOCAL int sndopts[4] = {MODPLUG_ENABLE_NOISE_REDUCTION, MODPLUG_ENABLE_REVERB,
99                          MODPLUG_ENABLE_MEGABASS, MODPLUG_ENABLE_SURROUND};
100 
101 EXPORT void
MyTextCallback(int id,int row,int col,char * buf)102 MyTextCallback(int id, int row, int col, char *buf)
103 {
104 	if (id == 0) {
105 		if (col == 0)
106 			strcpy(buf, rr[row]);
107 		else {
108 			if (row == 0)
109 				sprintf(buf, "%.3f kHz", ((double) sets.samplerate) / 1000.0);
110 			else if (row == 1) {
111 				switch (sets.resampling) {
112 				case 0:
113 					strcpy(buf, "No Interpolation");
114 					break;
115 				case 1:
116 					strcpy(buf, "Linear");
117 					break;
118 				case 2:
119 					strcpy(buf, "Spline");
120 					break;
121 				case 3:
122 					strcpy(buf, "Fir Filter");
123 					break;
124 				}
125 			} else if (row == 6) {
126 				if (sets.channels == 1)
127 					strcpy(buf, "Mono");
128 				else if (sets.channels == 2)
129 					strcpy(buf, "Stereo");
130 				else
131 					strcpy(buf, "Invalid");
132 			} else if (row == 7) {
133 				sprintf(buf, "%u", sets.vol);
134 			} else {
135 				/*
136 				 * sndopts[] is ordered in the same
137 				 * order as the option apparitions
138 				 * in the table.
139 				 */
140 				if (sets.flags & sndopts[row - 2])
141 					strcpy(buf, "YES");
142 				else
143 					strcpy(buf, "NO");
144 			}
145 		}
146 		return;
147 	} else if (id == 1) {
148 		if (col == 1)
149 			strcpy(buf, rr[row]);
150 		else {
151 			switch (row) {
152 			case 0:
153 				strcpy(buf, "Length:");
154 				break;
155 			case 1:
156 				strcpy(buf, "Format:");
157 				break;
158 			case 2:
159 				strcpy(buf, "Instruments:");
160 				break;
161 			case 3:
162 				strcpy(buf, "Samples:");
163 				break;
164 			case 4:
165 				strcpy(buf, "Channels:");
166 				break;
167 			case 5:
168 				strcpy(buf, "Patterns:");
169 				break;
170 			}
171 		}
172 		return;
173 	} else if (id == 2) {
174 		if (col == 0) {
175 			switch (row) {
176 			case 0:
177 				strcpy(buf, "Reverb Depth");
178 				break;
179 			case 1:
180 				strcpy(buf, "Reverb Delay");
181 				break;
182 			case 2:
183 				strcpy(buf, "Bass Amount");
184 				break;
185 			case 3:
186 				strcpy(buf, "Bass Range");
187 				break;
188 			case 4:
189 				strcpy(buf, "Surround Depth");
190 				break;
191 			case 5:
192 				strcpy(buf, "Surround Delay");
193 				break;
194 			case 6:
195 				strcpy(buf, "Endianness");
196 				break;
197 			case 7:
198 				strcpy(buf, "Appareance");
199 				break;
200 			case 8:
201 				strcpy(buf, "Verbosity");
202 				break;
203 			}
204 		} else
205 			strcpy(buf, rr[row]);
206 		return;
207 	} else if (id == 3) {
208 		strcpy(buf, rr[row]);
209 		return;
210 	}
211 	return;
212 }
213 
214 EXPORT int
TotalLines(const char * text,int length,int maxchars)215 TotalLines(const char *text, int length, int maxchars)
216 {
217 	int i, lines = 0, j = 0;
218 	for (i = 0; i < length; ++i) {
219 		++j;
220 		if (text[i] == '\r' || text[i] == '\n' || j == maxchars) {
221 			++lines;
222 			j = 0;
223 		}
224 	}
225 	return lines;
226 }
227 
228 EXPORT void
PaginateText(const char * text,int length)229 PaginateText(const char *text, int length)
230 {
231 	unsigned int i, j, k, line, tlines;
232 	unsigned short klines, kcolumns;
233 
234 	/* FIXME: getting lines & columns from system instead of using the
235 	 * default (80x24) */
236 	klines = 24;
237 	kcolumns = 80;
238 
239 	klines--;
240 	tlines = TotalLines(text, length, kcolumns);
241 	j = 0;
242 	k = 0;
243 	line = 0;
244 	for (i = 0; i < length; ++i) {
245 		if (j == klines) {
246 			notice(MESSAGE_PAGINATING, ((line * 100) / tlines));
247 			fflush(stdout);
248 			(void) getchar();
249 			j = 0;
250 		}
251 		if (text[i] != '\r' && text[i] != '\n')
252 			putchar(text[i]);
253 		/* Process newlines */
254 		if (text[i] == '\n' || text[i] == '\r' || k == kcolumns) {
255 			putchar('\n');
256 			++j;
257 			++line;
258 			k = 0;
259 		}
260 		++k;
261 	}
262 	return;
263 }
264 
265 EXPORT void
DisplaySongComments()266 DisplaySongComments()
267 {
268 	char *comments;
269 
270 	comments = ModPlug_GetMessage(file.mod);
271 	if (comments) {
272 		PaginateText(comments, strlen(comments));
273 		putchar('\n');
274 	} else {
275 		puts(MESSAGE_NO_MESSAGE);
276 	}
277 	return;
278 }
279 
280 EXPORT void
SaveSongComments(char * fname)281 SaveSongComments(char *fname)
282 {
283 	FILE *fp;
284 	int i, length;
285 	char *comments;
286 
287 	comments = ModPlug_GetMessage(file.mod);
288 	notice("Exporting song text message to '%s'\n", fname);
289 	if (comments) {
290 		fp = fopen(fname, "w+");
291 		if (fp == NULL) {
292 			puts(MESSAGE_OPEN_ERROR);
293 			free(fname);
294 			return;
295 		}
296 		length = strlen(comments);
297 		for (i = 0; i < length; ++i) {
298 			if (comments[i] == '\r') {
299 				putc('\n', fp);
300 			} else {
301 				putc((int) comments[i], fp);
302 			}
303 		}
304 		fclose(fp);
305 		notice("%d bytes written\n", i);
306 	} else {
307 		puts(MESSAGE_NO_MESSAGE);
308 	}
309 	return;
310 }
311 
312 EXPORT void
DisplayInstruments(int saveToFile)313 DisplayInstruments(int saveToFile)
314 {
315 	unsigned int instrus, i, bytes_in, length = 0;
316 	char *nbuf;
317 
318 	instrus = ModPlug_NumInstruments(file.mod);
319 	if (instrus < 1) {
320 		puts(MESSAGE_NO_INSTRUMENTS);
321 		return;
322 	}
323 	nbuf = (char *) malloc(47);
324 	if (nbuf == NULL)
325 		return;
326 	for (i = 1; i <= instrus; ++i) {
327 		sprintf(nbuf + length, "%3d. ", i);
328 		bytes_in = ModPlug_InstrumentName(file.mod, i, nbuf + length + 6);
329 		length += bytes_in + 6;
330 		if (bytes_in > 40) {
331 			free(nbuf);
332 			return;
333 		}
334 		nbuf[length] = '\n';
335 		++length;
336 		nbuf = (char *) realloc(nbuf, length + 47);
337 		if (nbuf == NULL)
338 			return;
339 	}
340 	nbuf = (char *) realloc(nbuf, length);
341 	if (nbuf == NULL)
342 		return;
343 
344 	if (saveToFile == 0)
345 		PaginateText(nbuf, length);
346 	else {
347 		notice("Exporting instrument names...\n");
348 		if (write(saveToFile, nbuf, length) < length)
349 			error("write(2) failed!\n");
350 		else
351 			notice("%u bytes written OK...\n", length);
352 	}
353 
354 	free(nbuf);
355 
356 	return;
357 }
358 
359 EXPORT void
DisplaySamples(int saveToFile)360 DisplaySamples(int saveToFile)
361 {
362 	unsigned int ssamples, i, bytes_in, length = 0;
363 	char *nbuf;
364 
365 	ssamples = ModPlug_NumSamples(file.mod);
366 	if (ssamples < 1) {
367 		puts(MESSAGE_NO_SAMPLES);
368 		return;
369 	}
370 	nbuf = (char *) malloc(47);
371 	if (nbuf == NULL)
372 		return;
373 	for (i = 1; i <= ssamples; ++i) {
374 		sprintf(nbuf + length, "%3d. ", i);
375 		bytes_in = ModPlug_SampleName(file.mod, i, nbuf + length + 6);
376 		length += bytes_in + 6;
377 		if (bytes_in > 40) {
378 			free(nbuf);
379 			return;
380 		}
381 		nbuf[length] = '\n';
382 		++length;
383 		nbuf = (char *) realloc(nbuf, length + 47);
384 		if (nbuf == NULL)
385 			return;
386 	}
387 	nbuf = (char *) realloc(nbuf, length);
388 	if (nbuf == NULL)
389 		return;
390 
391 	if (saveToFile == 0)
392 		PaginateText(nbuf, length);
393 	else {
394 		notice("Exporting sample names...\n");
395 		if (write(saveToFile, nbuf, length) < length)
396 			error("write(2) failed\n");
397 		else
398 			notice("%u bytes written OK...\n", length);
399 	}
400 
401 	free(nbuf);
402 
403 	return;
404 }
405 
406 EXPORT void
GetRangeValues(char * string,int * x,int * y)407 GetRangeValues(char *string, int *x, int *y)
408 {
409 	unsigned int len, i;
410 	char *p1 = NULL;
411 	char *p2 = NULL;
412 
413 	*x = 0;
414 	*y = 0;
415 	len = (unsigned int) strlen(string);
416 	if (!len) {
417 		return;
418 	}
419 	len--;
420 	p1 = string;
421 	for (i = len; i > 0; --i) {
422 		if (string[i] == '-') {
423 			p2 = &string[i + 1];
424 		}
425 	}
426 	if (p1)
427 		*x = atoi(p1);
428 	if (p2)
429 		*y = atoi(p2);
430 	return;
431 }
432