1 /* OpenCP Module Player
2  * copyright (c) '94-'10 Stian Skjelstad <stian@nixia.no>
3  *
4  * AYPlay interface routines
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * revision history: (please note changes here)
21  *  -sss051202   Stian Skjelstad <stian@nixia.no>
22  *    -first release
23  */
24 
25 
26 #include "config.h"
27 #include <stdio.h>
28 #include <string.h>
29 #include <time.h>
30 #include "types.h"
31 #include "ayplay.h"
32 #include "boot/plinkman.h"
33 #include "cpiface/cpiface.h"
34 #include "dev/deviplay.h"
35 #include "dev/player.h"
36 #include "filesel/filesystem.h"
37 #include "filesel/mdb.h"
38 #include "filesel/pfilesel.h"
39 #include "stuff/compat.h"
40 #include "stuff/err.h"
41 #include "stuff/poutput.h"
42 #include "stuff/sets.h"
43 #include "stuff/timer.h"
44 
45 #define _MAX_FNAME 8
46 #define _MAX_EXT 4
47 
48 static time_t starttime;
49 static time_t pausetime;
50 static char currentmodname[_MAX_FNAME+1];
51 static char currentmodext[_MAX_EXT+1];
52 static char *modname;
53 static char *composer;
54 static int16_t vol;
55 static int16_t bal;
56 static int16_t pan;
57 static int srnd;
58 static int16_t amp;
59 static int16_t speed;
60 static int16_t reverb;
61 static int16_t chorus;
62 static char finespeed=8;
63 
64 static time_t pausefadestart;
65 static uint8_t pausefaderelspeed;
66 static int8_t pausefadedirect;
67 
startpausefade(void)68 static void startpausefade(void)
69 {
70 	if (plPause)
71 		starttime=starttime+dos_clock()-pausetime;
72 
73 	if (pausefadedirect)
74 	{
75 		if (pausefadedirect<0)
76 			plPause=1;
77 		pausefadestart=2*dos_clock()-DOS_CLK_TCK-pausefadestart;
78 	} else
79 		pausefadestart=dos_clock();
80 
81 	if (plPause)
82 	{
83 		plChanChanged=1;
84 		ayPause(plPause=0);
85 		pausefadedirect=1;
86 	} else
87 		pausefadedirect=-1;
88 }
89 
dopausefade(void)90 static void dopausefade(void)
91 {
92 	int16_t i;
93 	if (pausefadedirect>0)
94 	{
95 		i=((int32_t)dos_clock()-pausefadestart)*64/DOS_CLK_TCK;
96 		if (i<0)
97 			i=0;
98 		if (i>=64)
99 		{
100 			i=64;
101 			pausefadedirect=0;
102 		}
103 	} else {
104 		i=64-((int32_t)dos_clock()-pausefadestart)*64/DOS_CLK_TCK;
105 		if (i>=64)
106 			i=64;
107 		if (i<=0)
108 		{
109 			i=0;
110 			pausefadedirect=0;
111 			pausetime=dos_clock();
112 			ayPause(plPause=1);
113 			plChanChanged=1;
114 			aySetSpeed(speed);
115 			return;
116 		}
117 	}
118 	pausefaderelspeed=i;
119 	aySetSpeed(speed*i/64);
120 }
121 
normalize(void)122 static void normalize(void)
123 {
124 	mcpNormalize(0);
125 	speed=set.speed;
126 	pan=set.pan;
127 	bal=set.bal;
128 	vol=set.vol;
129 	amp=set.amp;
130 	srnd=set.srnd;
131 	reverb=set.reverb;
132 	chorus=set.chorus;
133 /*	aySetAmplify(1024*amp);*/
134 	aySetVolume(vol, bal, pan, srnd);
135 	aySetSpeed(speed);
136 /*
137 	wpSetMasterReverbChorus(reverb, chorus);
138 */
139 }
140 
ayCloseFile()141 static void ayCloseFile()
142 {
143 	ayClosePlayer();
144 }
145 
ayLooped(void)146 static int ayLooped(void)
147 {
148 	if (pausefadedirect)
149 		dopausefade();
150 	aySetLoop(fsLoopMods);
151 	ayIdle();
152 	if (plrIdle)
153 		plrIdle();
154 	return !fsLoopMods&&ayIsLooped();
155 }
156 
ayDrawGStrings(uint16_t (* buf)[CONSOLE_MAX_X])157 static void ayDrawGStrings(uint16_t (*buf)[CONSOLE_MAX_X])
158 {
159 	long tim;
160 	struct ayinfo globinfo;
161 
162 	ayGetInfo(&globinfo);
163 
164 	if (plPause)
165 		tim=(pausetime-starttime)/DOS_CLK_TCK;
166 	else
167 		tim=(dos_clock()-starttime)/DOS_CLK_TCK;
168 
169 	if (plScrWidth<128)
170 	{
171 		memset(buf[0]+80, 0, (plScrWidth-80)*sizeof(uint16_t));
172 		memset(buf[1]+80, 0, (plScrWidth-80)*sizeof(uint16_t));
173 		memset(buf[2]+80, 0, (plScrWidth-80)*sizeof(uint16_t));
174 
175 		writestring(buf[0], 0, 0x09, " vol: \372\372\372\372\372\372\372\372 ", 15);
176 		writestring(buf[0], 15, 0x09, " srnd: \372  pan: l\372\372\372m\372\372\372r  bal: l\372\372\372m\372\372\372r ", 41);
177 		writestring(buf[0], 56, 0x09, " spd: ---% \x1D ptch: ---% ", 24);
178 		writestring(buf[0], 6, 0x0F, "\376\376\376\376\376\376\376\376", (vol+4)>>3);
179 		writestring(buf[0], 22, 0x0F, srnd?"x":"o", 1);
180 		if (((pan+70)>>4)==4)
181 			writestring(buf[0], 34, 0x0F, "m", 1);
182 		else {
183 			writestring(buf[0], 30+((pan+70)>>4), 0x0F, "r", 1);
184 			writestring(buf[0], 38-((pan+70)>>4), 0x0F, "l", 1);
185 		}
186 		writestring(buf[0], 46+((bal+70)>>4), 0x0F, "I", 1);
187 		_writenum(buf[0], 62, 0x0F, speed*100/256, 10, 3);
188 		_writenum(buf[0], 75, 0x0F, speed*100/256, 10, 3);
189 
190 
191 		writestring(buf[1],  0, 0x09," song .. of ..                                 cpu: ...% amp: ...% filter: ...  ",80);
192 		writenum(buf[1],  6, 0x0F, globinfo.track, 16, 2, 0);
193 		writenum(buf[1], 12, 0x0F, globinfo.numtracks, 16, 2, 0);
194 		_writenum(buf[1], 52, 0x0F, tmGetCpuUsage(), 10, 3);
195 		_writenum(buf[1], 62, 0x0F, amp*100/64, 10, 3);
196 /*
197 		writestring(buf[1], 75, 0x0F, sidpGetFilter()?"on":"off", 3);
198 */
199 		writestring(buf[1], 75, 0x0F, "off", 3);
200 
201 		writestring(buf[2],  0, 0x09, " file \372\372\372\372\372\372\372\372.\372\372\372: .............................................  time: ..:.. ", 80);
202 		writestring(buf[2],  6, 0x0F, currentmodname, _MAX_FNAME);
203 		writestring(buf[2], 14, 0x0F, currentmodext, _MAX_EXT);
204 		writestring(buf[2], 20, 0x0F, globinfo.trackname, 45);
205 		if (plPause)
206 			writestring(buf[2], 58, 0x0C, "paused", 6);
207 		writenum(buf[2], 73, 0x0F, (tim/60)%60, 10, 2, 1);
208 		writestring(buf[2], 75, 0x0F, ":", 1);
209 		writenum(buf[2], 76, 0x0F, tim%60, 10, 2, 0);
210 
211 	} else {
212 		memset(buf[0]+128, 0, (plScrWidth-128)*sizeof(uint16_t));
213 		memset(buf[1]+128, 0, (plScrWidth-128)*sizeof(uint16_t));
214 		memset(buf[2]+128, 0, (plScrWidth-128)*sizeof(uint16_t));
215 
216 		writestring(buf[0], 0, 0x09, "    volume: \372\372\372\372\372\372\372\372\372\372\372\372\372\372\372\372  ", 30);
217 		writestring(buf[0], 30, 0x09, " surround: \372   panning: l\372\372\372\372\372\372\372m\372\372\372\372\372\372\372r   balance: l\372\372\372\372\372\372\372m\372\372\372\372\372\372\372r  ", 72);
218 		writestring(buf[0], 102, 0x09,  " speed: ---% \x1D pitch: ---%    ", 30);
219 		writestring(buf[0], 12, 0x0F, "\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376\376", (vol+2)>>2);
220 		writestring(buf[0], 41, 0x0F, srnd?"x":"o", 1);
221 		if (((pan+68)>>3)==8)
222 			writestring(buf[0], 62, 0x0F, "m", 1);
223 		else {
224 			writestring(buf[0], 54+((pan+68)>>3), 0x0F, "r", 1);
225 			writestring(buf[0], 70-((pan+68)>>3), 0x0F, "l", 1);
226 		}
227 		writestring(buf[0], 83+((bal+68)>>3), 0x0F, "I", 1);
228 		_writenum(buf[0], 110, 0x0F, speed*100/256, 10, 3);
229 		_writenum(buf[0], 124, 0x0F, speed*100/256, 10, 3);
230 
231 		writestring(buf[1],  0, 0x09,"    song .. of ..                                   cpu: ...%",132);
232 		writenum(buf[1],  9, 0x0F, globinfo.track, 16, 2, 0);
233 		writenum(buf[1], 15, 0x0F, globinfo.numtracks, 16, 2, 0);
234 
235 		_writenum(buf[1], 57, 0x0F, tmGetCpuUsage(), 10, 3);
236 		writestring(buf[1], 60, 0x0F, "%", 1);
237 
238 		writestring(buf[1], 61, 0x00, "", 128-61);
239 		writestring(buf[1], 92, 0x09, "   amplification: ...%  filter: ...     ", 40);
240 		_writenum(buf[1], 110, 0x0F, amp*100/64, 10, 3);
241 		writestring(buf[1], 124, 0x0F, "off", 3); /* <80 also misses this */
242 
243 		writestring(buf[2],  0, 0x09, "    file \372\372\372\372\372\372\372\372.\372\372\372: ........................................  composer: ........................................  time: ..:..   ", 132);
244 		writestring(buf[2],  9, 0x0F, currentmodname, _MAX_FNAME);
245 		writestring(buf[2], 17, 0x0F, currentmodext, _MAX_EXT);
246 		writestring(buf[2], 23, 0x0F, globinfo.trackname, 40);
247 		writestring(buf[2], 75, 0x0F, composer, 40);
248 		if (plPause)
249 			writestring(buf[2], 100, 0x0C, "playback paused", 15);
250 		writenum(buf[2], 123, 0x0F, (tim/60)%60, 10, 2, 1);
251 		writestring(buf[2], 125, 0x0F, ":", 1);
252 		writenum(buf[2], 126, 0x0F, tim%60, 10, 2, 0);
253 	}
254 
255 }
256 
ayProcessKey(uint16_t key)257 static int ayProcessKey(uint16_t key)
258 {
259 	int csg;
260 	struct ayinfo globinfo;
261 	ayGetInfo(&globinfo);
262 
263 	switch (key)
264 	{
265 		case KEY_ALT_K:
266 			cpiKeyHelp('p', "Start/stop pause with fade");
267 			cpiKeyHelp('P', "Start/stop pause with fade");
268 			cpiKeyHelp(KEY_CTRL_P, "Start/stop pause");
269 			cpiKeyHelp('<', "Jump to previous track");
270 			cpiKeyHelp(KEY_CTRL_LEFT, "Jump to previous track");
271 			cpiKeyHelp('>', "Jump to next track");
272 			cpiKeyHelp(KEY_CTRL_RIGHT, "Jump to next track");
273 			cpiKeyHelp('-', "Decrease volume (small)");
274 			cpiKeyHelp('+', "Increase volume (small)");
275 			cpiKeyHelp('/', "Move balance left (small)");
276 			cpiKeyHelp('*', "Move balance right (small)");
277 			cpiKeyHelp(',', "Move panning against normal (small)");
278 			cpiKeyHelp('.', "Move panning against reverse (small)");
279 			cpiKeyHelp(KEY_F(2), "Decrease volume");
280 			cpiKeyHelp(KEY_F(3), "Increase volume");
281 			cpiKeyHelp(KEY_F(4), "Toggle surround on/off");
282 			cpiKeyHelp(KEY_F(5), "Move panning against normal");
283 			cpiKeyHelp(KEY_F(6), "Move panning against reverse");
284 			cpiKeyHelp(KEY_F(7), "Move balance left");
285 			cpiKeyHelp(KEY_F(8), "Move balance right");
286 			cpiKeyHelp(KEY_F(9), "Decrease pitch speed");
287 			cpiKeyHelp(KEY_F(11), "Decrease pitch speed");
288 			cpiKeyHelp(KEY_F(10), "Increase pitch speed");
289 			cpiKeyHelp(KEY_F(12), "Increase pitch speed");
290 			if (plrProcessKey)
291 				plrProcessKey(key);
292 			return 0;
293 		case 'p': case 'P':
294 			startpausefade();
295 			break;
296 		case KEY_CTRL_P:
297 			pausefadedirect=0;
298 			if (plPause)
299 				starttime=starttime+dos_clock()-pausetime;
300 			else
301 				pausetime=dos_clock();
302 			plPause=!plPause;
303 			ayPause(plPause);
304 			break;
305 		case '<':
306 		case KEY_CTRL_LEFT: /* curses.h can't do these */
307 		/* case 0x7300: //ctrl-left */
308 			csg=globinfo.track-1;
309 			if (csg)
310 			{
311 				ayStartSong(csg);
312 				starttime=dos_clock();
313 			}
314 			break;
315 		case '>':
316 		case KEY_CTRL_RIGHT: /* curses.h can't do these */
317 		/* case 0x7400: //ctrl-right*/
318 			csg=globinfo.track+1;
319 			if (csg<=globinfo.numtracks)
320 			{
321 				ayStartSong(csg);
322 				starttime=dos_clock();
323 			}
324 			break;
325 		case '-':
326 			if (vol>=2)
327 				vol-=2;
328 			aySetVolume(vol, bal, pan, srnd);
329 			break;
330 		case '+':
331 			if (vol<=62)
332 				vol+=2;
333 			aySetVolume(vol, bal, pan, srnd);
334 			break;
335 		case '/':
336 			if ((bal-=4)<-64)
337 				bal=-64;
338 			aySetVolume(vol, bal, pan, srnd);
339 			break;
340 		case '*':
341 			if ((bal+=4)>64)
342 				bal=64;
343 			aySetVolume(vol, bal, pan, srnd);
344 			break;
345 		case ',':
346 			if ((pan-=4)<-64)
347 				pan=-64;
348 			aySetVolume(vol, bal, pan, srnd);
349 			break;
350 		case '.':
351 			if ((pan+=4)>64)
352 				pan=64;
353 			aySetVolume(vol, bal, pan, srnd);
354 			break;
355 		case KEY_F(2):
356 			if ((vol-=8)<0)
357 				vol=0;
358 			aySetVolume(vol, bal, pan, srnd);
359 			break;
360 		case KEY_F(3):
361 			if ((vol+=8)>64)
362 				vol=64;
363 			aySetVolume(vol, bal, pan, srnd);
364 			break;
365 		case KEY_F(4):
366 			aySetVolume(vol, bal, pan, srnd=srnd?0:2);
367 			break;
368 		case KEY_F(5):
369 			if ((pan-=16)<-64)
370 				pan=-64;
371 			aySetVolume(vol, bal, pan, srnd);
372 			break;
373 		case KEY_F(6):
374 			if ((pan+=16)>64)
375 				pan=64;
376 			aySetVolume(vol, bal, pan, srnd);
377 			break;
378 		case KEY_F(7):
379 			if ((bal-=16)<-64)
380 				bal=-64;
381 			aySetVolume(vol, bal, pan, srnd);
382 			break;
383 		case KEY_F(8):
384 			if ((bal+=16)>64)
385 				bal=64;
386 			aySetVolume(vol, bal, pan, srnd);
387 			break;
388 		case KEY_F(9):
389 		case KEY_F(11):
390 			if ((speed-=finespeed)<16)
391 				speed=16;
392 			aySetSpeed(speed);
393 			break;
394 		case KEY_F(10):
395 		case KEY_F(12):
396 			if ((speed+=finespeed)>2048)
397 				speed=2048;
398 			aySetSpeed(speed);
399 			break;
400 
401 		default:
402 			if (plrProcessKey)
403 			{
404 				int ret=plrProcessKey(key);
405 				if (ret==2)
406 					cpiResetScreen();
407 				if (ret)
408 					return 1;
409 			}
410 			return 0;
411 	}
412 	return 1;
413 
414 }
415 
ayOpenFile(struct moduleinfostruct * info,struct ocpfilehandle_t * file)416 static int ayOpenFile(struct moduleinfostruct *info, struct ocpfilehandle_t *file)
417 {
418 /*
419 	struct ayinfo ay;
420 */
421 	if (!file)
422 		return -1;
423 
424 	strncpy(currentmodname, info->name, _MAX_FNAME);
425 	strncpy(currentmodext, info->name + _MAX_FNAME, _MAX_EXT);
426 
427 	modname=info->modname;
428 	composer=info->composer;
429 
430 	fprintf(stderr, "Loading %s%s...\n", currentmodname, currentmodext);
431 
432 	plIsEnd=ayLooped;
433 	plProcessKey=ayProcessKey;
434 	plDrawGStrings=ayDrawGStrings;
435 	plSetMute=aySetMute;
436 	plGetMasterSample=plrGetMasterSample;
437 	plGetRealMasterVolume=plrGetRealMasterVolume;
438 
439 	plNLChan=6;
440 	ayChanSetup();
441 
442 	if (!ayOpenPlayer(file))
443 	{
444 #ifdef INITCLOSE_DEBUG
445 		fprintf(stderr, "ayOpenPlayer FAILED\n");
446 #endif
447 		return -1;
448 	}
449 
450 	starttime=dos_clock();
451 	plPause=0;
452 	normalize();
453 	pausefadedirect=0;
454 
455 
456 /*
457 	ayGetInfo(&ay);
458 	aylen=inf.len;
459 	ayrate=inf.rate;
460 */
461 
462 	return errOk;
463 }
464 
465 struct cpifaceplayerstruct ayPlayer = {ayOpenFile, ayCloseFile};
466 struct linkinfostruct dllextinfo = {.name = "playay", .desc = "OpenCP aylet Player (c) 2005-09 Russell Marks, Ian Collier & Stian Skjelstad", .ver = DLLVERSION, .size = 0};
467