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