Subversion Repositories Kolibri OS

Rev

Rev 801 | Rev 1843 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
576 serge 1
//
2
//   This file is part of the AC97 mp3 player.
650 serge 3
//   (C) copyright Serge 2006-2007 infinity_sound@mail.ru
4
//   (C) copyright Quantum 2007    ufmod@users.sf.net
576 serge 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
#include "../kolibri.h"
17
#include "string.h"
18
#include "ac97wav.h"
19
#include "../mpg/mpg123.h"
20
#include "../sound.h"
646 serge 21
#include "../ufmod-codec.h"                   /* uFMOD integration */
22
void exit();                                  /* uFMOD integration */
576 serge 23
 
1842 clevermous 24
#define DOCKABLE_WINDOW
576 serge 25
#define MP3_ERROR_OUT_OF_BUFFER  5
26
int m_last_error;
27
 
28
void _stdcall thread_proc(void *param);
1842 clevermous 29
int _stdcall create_thread(void *proc, void *param, int stack_size);
576 serge 30
 
1842 clevermous 31
#ifdef DOCKABLE_WINDOW
32
void GetThreadInfo (char *info, int slot); //Asper+
33
#endif
34
 
576 serge 35
void touch(char *buf, int size);
36
int mp3FindSync(byte* buf, int size, int* sync);
646 serge 37
int stream_read_raw(struct reader *rd,unsigned char *buf, int size);
576 serge 38
 
646 serge 39
int __cdecl _stricmp (const char * dst, const char * src);
40
char *__cdecl strrchr (const char * string,int ch);
1842 clevermous 41
int _strncmp(char *src, char *dst, DWORD n); //Asper+
42
int _strncpy (char *dst, char *src, int n); //Asper+
43
void uint2str(unsigned int value, char *string); //Asper+
646 serge 44
 
576 serge 45
struct reader rd;
46
struct frame fr;
47
 
48
DWORD hDrv;
49
DWORD hSound;
50
SNDBUF hBuff;
51
 
52
CTRL_INFO info;
53
 
54
FILEINFO   fileinfo;
1842 clevermous 55
const char filename[256];
646 serge 56
const char *fileext;
1842 clevermous 57
char full_filename[4096];
576 serge 58
 
59
int m_vol;
60
int l_vol=-700;     //-7db
61
int r_vol=-700;
62
int pan =0;
63
 
64
DWORD status;
65
DWORD first_sync;
1842 clevermous 66
DWORD PLStatus=0; //Asper+
576 serge 67
 
1842 clevermous 68
#ifdef DOCKABLE_WINDOW
69
byte thread_info[1024]; //Asper+
70
#endif
71
 
72
int tid, pl_tid;
73
const DWORD main_wh=92, pl_ww=300, pl_wh=382; //Asper+
74
DWORD pl_wx=100, pl_wy=101+92;  //Asper+
75
//DWORD main_wc=0x404040, main_bc=0x808080;  //Asper+ ac97snd Classic style
76
//DWORD main_wc=0x002040, main_bc=0x008080, main_ic=0x002040, selected_ic=0x1010F0;  //Asper+
77
DWORD main_wc=0x101030, main_bc=0x008080, main_ic=0x000000, selected_ic=0x1010F0;  //Asper+
78
 
576 serge 79
unsigned char *testbuff;
80
unsigned char *outbuf;
81
unsigned char *inpbuf;
82
unsigned char *outPtr;
83
 
84
int inpsize;
85
int outsize;
86
int outremain;
87
int totalout;
88
int done;
646 serge 89
 
576 serge 90
char header[] = "AC97 MP3 player";
1842 clevermous 91
char header_PL[] = "PLAYLIST";
646 serge 92
char buttons_xm[]  = " Play    Stop                    Vol-    Vol+"; /* uFMOD integration */
93
char buttons_wav[] = " Play    Stop     <<      >>     Vol-    Vol+"; /* uFMOD integration */
1842 clevermous 94
char button_PL[] = "PL"; //Asper+
646 serge 95
char *buttons_text = buttons_wav;                                     /* uFMOD integration */
576 serge 96
 
646 serge 97
void play_xm();                                                       /* uFMOD integration */
576 serge 98
void (*snd_play)();
99
 
1842 clevermous 100
 
101
//Asper_____________________Play List code start_____________________________
102
#define PLI_BUTTON_HEIGHT    13
103
#define PL_MAX_SHOWN_ITEMS   (pl_wh-PLI_BUTTON_HEIGHT-40)/PLI_BUTTON_HEIGHT
104
#define MAX_TEXT_WIDTH       46
105
 
106
int currSelected, currActive, currFirstShowed;
107
unsigned char *pl_buff;
108
char pl_path[4096];
109
int pl_items_number;
110
 
111
int ShowPLContent(char *filebuffer);
112
int GetFileNameFromPL(const char *fbuff, int index, char *name);
113
void Win2Dos (char *st, int len);
114
 
115
void HidePLWindow()
116
{
117
   BeginDraw();
118
   ResizeReplaceWindow(pl_wx,pl_wy,0,0);
119
   EndDraw();
120
}
121
 
122
void ShowPLWindow()
123
{
124
   unsigned int i;
125
 
126
   BeginDraw();
127
   DrawWindow(pl_wx,pl_wy,pl_ww,pl_wh,main_ic,4,0,0,0);
128
 
129
   for (i=0; i
130
	   make_button(7,24+i*(PLI_BUTTON_HEIGHT+1),285,PLI_BUTTON_HEIGHT, (0x10+i)|BT_NORMAL|BT_NOFRAME, main_ic);
131
 
132
   write_text(8,8,FONT0, header_PL, sizeof(header_PL)-1);
133
   ShowPLContent(pl_buff);
134
   EndDraw();
135
}
136
 
137
int LoadTrack(int i)
138
{
139
	if (GetFileNameFromPL(pl_buff, i, filename))
140
	{
141
		strcpy (full_filename, pl_path);
142
		strcat (full_filename, filename);
143
		return 1;
144
	}
145
	return 0;
146
}
147
 
148
void _stdcall pl_thread_proc(void *param)
149
{  int evnt;
150
   int key, button;
151
   DWORD tmp_x, tmp_y, i; //Asper+
152
   char ipc_buff[16]="";
153
 
154
   set_event_mask(0x47); //Asper + IPC event
155
   ipc_init(ipc_buff, 16);
156
 
157
  _asm
158
  {
159
    mov eax, 66
160
    mov ebx, 1
161
    mov ecx, 1
162
    int 0x40
163
  };
164
 
165
  ShowPLWindow();
166
 
167
  while(1)
168
  {
169
	if (PLStatus&0xF0)
170
    {
171
		switch(PLStatus)
172
		{
173
			case 0x11:
174
				HidePLWindow();
175
			break;
176
			case 0x12:
177
				ResizeReplaceWindow(pl_wx,pl_wy,pl_ww,pl_wh);
178
			break;
179
		}
180
		PLStatus&=0x0F;
181
	}
182
	switch (status)
183
	{
184
		case ST_TRACK:
185
			break;
186
		case ST_EXIT:
187
			PLStatus=0x00;
188
			exit();
189
	}
190
 
191
#ifdef DOCKABLE_WINDOW
192
	tmp_x = (DWORD)thread_info[35]*0x100+(DWORD)thread_info[34];
193
	tmp_y = (DWORD)thread_info[38]+main_wh+1;
194
	if (pl_wx!= tmp_x || pl_wy!=tmp_y)
195
	{
196
		pl_wx=tmp_x;
197
		pl_wy=tmp_y;
198
		ResizeReplaceWindow(pl_wx,pl_wy,-1,-1);
199
	}
200
#endif
201
 
202
    evnt = wait_for_event(20);
203
 
204
    switch(evnt)
205
    {
206
      case EV_REDRAW:
207
			  ShowPLWindow();
208
        break;
209
 
210
      case EV_KEY:
211
        if(!get_key(&key))
212
        {
213
 
214
          switch(key)
215
          {  case 0xE0:
216
             case 0xE1:
217
               break;
218
             default:
219
               switch (key)
220
               {
221
                 case 0x01:  //Esc
222
					 PLStatus=0x00;
223
					 exit();
224
					 break;
225
 
226
				 case 0x1C:  //Enter
227
					 currActive=currFirstShowed+currSelected-1;
228
					 status = ST_TRACK;
229
					 break;
230
                 case 0x47:  //Home
231
					 if(l_vol < 0)
232
					 { l_vol+=100;
233
					   r_vol+=100;
234
					   SetVolume(hBuff,l_vol,r_vol);
235
					 };
236
				   break;
237
                 case 0x48:  //Up
238
					 if (currSelected==0)
239
					 {
240
						 if (currFirstShowed>0)
241
							 currFirstShowed--;
242
						 ShowPLContent(pl_buff);
243
						 break;
244
					 }
245
					 currSelected--;
246
					 ShowPLContent(pl_buff);
247
					 break;
248
                 case 0x50:  //Down
249
					 if (currSelected+currFirstShowed > pl_items_number-2) break;
250
					 if (currSelected==PL_MAX_SHOWN_ITEMS-1)
251
					 {
252
						 //if (currFirstShowed
253
							 currFirstShowed++;
254
						 ShowPLContent(pl_buff);
255
						 break;
256
					 }
257
					 //if (currSelected
258
					 currSelected++;
259
					 ShowPLContent(pl_buff);
260
					 break;
261
                 case 0x4F:  //End
262
					 if(l_vol > -10000)
263
					 { l_vol-=100;
264
					   r_vol-=100;
265
					   SetVolume(hBuff,l_vol,r_vol);
266
					 };
267
					 break;
268
                 case 0x53:
269
					 if(pan > -10000)
270
					 { pan -=100;
271
					   SetPan(hBuff,pan);
272
					 };
273
					 break;
274
                 case 0x51:
275
					 if(pan < 10000)
276
					 { pan +=100;
277
					   SetPan(hBuff,pan);
278
					 };
279
					 break;
280
			   }
281
		  };
282
		};
283
		break;
284
 
285
      case EV_BUTTON:
286
		  button=get_button_id();
287
		  if (button==1)
288
		  {
289
			  PLStatus=0x00;
290
			  exit();
291
		  }
292
		  for (i=0;i
293
		  {
294
			  if (button==0x10+i)
295
			  {
296
				  currActive=currFirstShowed+i-1;
297
				  status = ST_TRACK;
298
				  break;
299
			  }
300
		  }
301
		  break;
302
	  case EV_IPC:
303
  		  *ipc_buff='\0';
304
		  ShowPLContent(pl_buff);
305
		  break;
306
 
307
	}
308
  }
309
}
310
 
311
void Win2Dos (char *st, int len)
312
{
313
	int i;
314
	unsigned char ch;
315
 
316
	for (i=0; i
317
	{
318
		ch = st[i];
319
		if (ch>=192)
320
		{
321
			if (ch>=240) ch-=16;
322
			else ch-=64;
323
		}
324
		else
325
		{
326
			if (ch==168) ch = 240;
327
			if (ch==184) ch = 241;
328
			if (ch==185) ch = 252;
329
			if ((ch==147) || (ch==148) || (ch==171) || (ch==187)) ch = 34;
330
			if ((ch==150) || (ch==151)) ch = 45;
331
		}
332
		st[i]=ch;
333
	}
334
}
335
 
336
int GetFileNameFromPL(const char *plbuff, int index, char *name)
337
{
338
	int count=0,i=0,j=0;
339
	char ch;
340
 
341
	do{
342
		ch=plbuff[i];
343
		if (ch!='#' && i && plbuff[i-1]=='\n')
344
			count++;
345
		if (count-1==index)
346
		{
347
			if (j>MAX_TEXT_WIDTH || ch=='\n')
348
			{
349
				name[j-1]='\0';
350
				break;
351
			}
352
			if (ch=='\\') ch='/';
353
			name[j++]=ch;
354
		}
355
		else if (count-1>index) break;
356
		i++;
357
	}while (ch);
358
	if (!ch) return 0;
359
	return j;
360
}
361
 
362
int CountFileNamesInPL(const char *plbuff)
363
{
364
	int count=0,i=0;
365
	char ch;
366
 
367
	do{
368
		ch=plbuff[i];
369
		if (ch!='#' && i && plbuff[i-1]=='\n')
370
			count++;
371
		i++;
372
	}while (ch);
373
	if (count) count--;
374
	return count;
375
}
376
 
377
int ShowPLContent(char *filebuffer)
378
{
379
	char st[MAX_TEXT_WIDTH+10]="", tmp[MAX_TEXT_WIDTH+1]="";
380
	unsigned int len=8,i;
381
	DWORD text_color;
382
 
383
	draw_bar(7,24,285,PLI_BUTTON_HEIGHT*(PL_MAX_SHOWN_ITEMS+2), main_ic);
384
	draw_bar(7,24+currSelected*(PLI_BUTTON_HEIGHT+1),285,PLI_BUTTON_HEIGHT, selected_ic);
385
	for (i=0; i
386
	{
387
		text_color = (currFirstShowed+i==currActive?0xFFFFFF|FONT0:0x00FF20|FONT0);
388
		if (!GetFileNameFromPL(filebuffer, i+currFirstShowed, tmp)) break;
389
		uint2str(currFirstShowed+i+1, st);
390
		strcat(st, ". ");
391
		strcat(st, tmp);
392
		len = strlen(st);
393
		if (len > MAX_TEXT_WIDTH)
394
			len = MAX_TEXT_WIDTH;
395
		write_text(11,i*(PLI_BUTTON_HEIGHT+1)+27,text_color, st, len);
396
	}
397
	return 1;
398
}
399
//Asper_____________________Play List code end_____________________________
400
 
401
void update_dinamic_content() //Asper +
402
{
403
	int len;                                                          /* uFMOD integration */
404
	draw_bar(7,41,286,11,main_wc);
405
 
406
	draw_bar(7,55,286,11,main_wc);
407
	len = strlen(filename);                                                /* uFMOD integration */
408
	if(len > 47) len = 47;                                              /* uFMOD integration */
409
	write_text(11,57,0x00FF20|FONT0, filename, len);                        /* uFMOD integration */
410
}
411
 
576 serge 412
void draw_window()
413
{
414
   BeginDraw();
415
 
1842 clevermous 416
   DrawWindow(100,100,299,main_wh,main_wc,4,0,0,0); //Asper+
576 serge 417
 
1842 clevermous 418
   make_button(7,24,45,13, 0x10|BT_NORMAL,main_bc);
419
   make_button(56,24,45,13, 0x11|BT_NORMAL,main_bc);
420
   make_button(104,24,45,13, 0x12|BT_NORMAL,main_bc);
421
   make_button(152,24,45,13, 0x13|BT_NORMAL,main_bc);
422
   make_button(200,24,45,13, 0x14|BT_NORMAL,main_bc);
423
   make_button(248,24,45,13, 0x15|BT_NORMAL,main_bc);
576 serge 424
 
1842 clevermous 425
   make_button(268,70,25,13, 0x16|BT_NORMAL,main_bc); //Asper+ PL button
576 serge 426
 
1842 clevermous 427
   make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,main_wc);
576 serge 428
 
1842 clevermous 429
   update_dinamic_content();
646 serge 430
   write_text(8,8,FONT0, header, sizeof(header)-1);                     /* uFMOD integration */
1842 clevermous 431
   write_text(12,28,main_wc|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */
646 serge 432
   write_text(11,27,0xA0FFA0|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */
576 serge 433
 
1842 clevermous 434
   write_text(276,74,main_wc|FONT0,button_PL,sizeof(button_PL)-1); //Asper+ PL button text
435
   write_text(275,73,0xA0FFA0|FONT0,button_PL,sizeof(button_PL)-1); //Asper+
576 serge 436
   EndDraw();
437
};
438
 
439
void draw_progress_bar()
440
{  DWORD x;
646 serge 441
   x = (DWORD)(287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size); /* uFMOD integration */
576 serge 442
   if(x==0) return;
443
   draw_bar(7,41,x,11,0xA0A0A0);
1842 clevermous 444
   draw_bar(x+7,41,287-x,11,main_wc);
576 serge 445
};
446
 
1842 clevermous 447
void debug_out_str(const char* str)
576 serge 448
{
449
  while (*str != 0)
450
  {
451
    debug_out(*str);
452
    str++;
453
  }
454
}
455
 
1842 clevermous 456
int LoadPL(char *fname)
577 serge 457
{
1842 clevermous 458
	DWORD fmt;
459
	DWORD r_bytes;
460
	int retval;
461
	int i;
462
//		char st[100]="";
463
 
464
	char *pch;
465
 
466
	r_bytes=0;
467
	pch=strrchr(fname, '/');
468
	if (pch)
469
		i=pch-fname+1;
470
	else
471
		i=strlen(fname);
472
 
473
	_strncpy (pl_path, fname, i);
474
	pl_path[i]='\0';
475
 
476
	if (!pl_buff)
477
		pl_buff = UserAlloc(0x40000);
478
	retval=read_file (fname,pl_buff,0,0x40000,&r_bytes);
479
 
480
	if ( retval && (r_bytes==0))
481
		return 0;
482
 
483
	Win2Dos(pl_buff, r_bytes);
484
	pl_items_number=CountFileNamesInPL(pl_buff);
485
/*
486
	debug_out_str("\n\rPlay List files number = ");
487
	itoa(pl_items_number, st, 10);
488
	debug_out_str(st);
489
*/
490
	fmt = test_m3u(pl_buff);
491
 
492
	if(!fmt)
493
	{
494
		debug_out_str("\n\rInvalid M3U file");
495
		return 0;
496
	}
497
	debug_out_str("\n\rValid M3U file");
498
	currSelected=currFirstShowed=0;
499
	currActive=-1;
500
	return 1;
501
}
502
 
503
int LoadFile(char *fname)
504
{
577 serge 505
   DWORD fmt;
506
   DWORD r_bytes;
507
   int retval;
508
   int err;
646 serge 509
   unsigned char *ttl, *cur;               /* uFMOD integration */
1842 clevermous 510
 
577 serge 511
   debug_out_str("\n\rPlay file ");
512
   debug_out_str(fname);
513
   debug_out_str("\n\r");
1842 clevermous 514
 
577 serge 515
   if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND)
1842 clevermous 516
   {  debug_out_str("\n\rfile not found\n\r");
577 serge 517
      return 0;
518
   }
1842 clevermous 519
 
520
   r_bytes=0;
521
   strcpy(filename, strrchr(fname,'/')+1);
522
   if( !(fileext = strrchr(filename,'.')))
523
	   return 0;
524
 
525
   if(!_stricmp(fileext,".m3u"))
526
   {
527
	   LoadPL(fname);
528
	   status=ST_TRACK;
529
	   return 1;
577 serge 530
   }
1842 clevermous 531
 
532
   if (!testbuff)
533
	   testbuff = UserAlloc(4096);
534
 
577 serge 535
   retval=read_file (fname,testbuff,0,2048,&r_bytes);
1842 clevermous 536
   if ( retval && (r_bytes==0))
537
	   return 0;
538
 
539
   if (!inpbuf)
540
   {
541
	   inpbuf = UserAlloc(0x10000);
542
	   touch(inpbuf, 0x10000);
543
   }
577 serge 544
   create_reader(&rd, inpbuf, 0x10000);
545
   init_reader(&rd,fname);
1842 clevermous 546
 
646 serge 547
   if(!_stricmp(fileext,".mp3"))
1842 clevermous 548
   {
646 serge 549
			fmt = test_mp3(testbuff);
550
			if(!fmt)
551
			{
1842 clevermous 552
			  debug_out_str("\n\rInvalid MP3 file");
646 serge 553
			  return 0;
554
			};
1842 clevermous 555
			snd_play = &play_mp3;
556
			outremain = 0x40000;
557
			if (!outbuf)
558
			{
559
				outbuf = UserAlloc(outremain);
560
				touch(outbuf, outremain);
561
			}
562
			make_decode_tables(32767);
563
			init_layer2();
564
			init_layer3(32);
646 serge 565
			fr.single = -1;
1842 clevermous 566
			goto play;
577 serge 567
   };
646 serge 568
 
569
   if(!_stricmp(fileext,".xm"))
570
   {
571
	   if(uFMOD_LoadSong(fname))
572
	   {
573
	      buttons_text = buttons_xm;               /* uFMOD integration */
574
	      fmt = PCM_2_16_48;                       /* uFMOD integration */
575
	      snd_play = &play_xm;                     /* uFMOD integration */
576
	      ttl = uFMOD_GetTitle();                  /* uFMOD integration */
577
	      cur = ttl;                               /* uFMOD integration */
578
	      err = 0;                                 /* uFMOD integration */
579
	      while(*cur && *cur++ != ' ') err++;      /* uFMOD integration */
580
	      if(err){                                 /* uFMOD integration */
581
	 	      cur = fname;                             /* uFMOD integration */
582
			     while(*cur) cur++;                       /* uFMOD integration */
583
			     *cur++ = ' ';                            /* uFMOD integration */
584
			     *cur++ = '|';                            /* uFMOD integration */
585
			     *cur++ = ' ';                            /* uFMOD integration */
586
			     while(*ttl) *cur++ = *ttl++;             /* uFMOD integration */
587
		    }
588
		    goto play;
589
		 }
590
		 debug_out_str("\n\rInvalid XM file");
591
     return 0;
592
	 };
593
 
594
	 if(!_stricmp(fileext, ".wav"))
595
	 {
1842 clevermous 596
       fmt = test_wav((WAVEHEADER*)testbuff);
646 serge 597
	   if(fmt)
598
		 {
599
		   snd_play = &play_wave;
600
		   set_reader(&rd, 44);
601
		   outbuf = UserAlloc(32*1024);
602
		   touch(outbuf, 32768);
1842 clevermous 603
		   goto play;
646 serge 604
		 }
605
     debug_out_str("\n\rInvalid WAV file");
606
     return 0;
607
	 };
577 serge 608
 
1842 clevermous 609
   debug_out_str("\n\rUnsupported file");
646 serge 610
   return 0;
611
 
612
play:
613
 
577 serge 614
   status = ST_PLAY;
1842 clevermous 615
   SetFormat(hBuff, fmt);
616
   SetVolume(hBuff,l_vol,r_vol);
617
   GetVolume(hBuff,&l_vol,&r_vol);
618
 
619
   return 1;
620
}
621
 
622
int main(int argc, char *argv[])
623
{
624
   int err, ver;
625
   int i;
626
   char ipc_msg[2]="\0\0";
627
 
628
   strcpy (full_filename, argv[1]);
629
   pl_items_number=0;
630
 
631
   InitHeap(1024*1024);
577 serge 632
 
1842 clevermous 633
   if(err = InitSound(&ver))
634
   {
635
     debug_out_str("Sound service not installed\n\r");
636
     return 0;
637
   }
638
 
639
   if( (SOUND_VERSION>(ver&0xFFFF)) ||
640
       (SOUND_VERSION<(ver >> 16)))
641
   {
642
     debug_out_str("Sound service version mismatch\n\r");
643
     return 0;
644
   }
645
 
646
   if (err = CreateBuffer(PCM_2_16_48, 0, &hBuff))
577 serge 647
   {
648
     debug_out_str("create buffer return error\n\r");
1842 clevermous 649
     return 0;
577 serge 650
   }
1842 clevermous 651
 
652
   if (!LoadFile(full_filename))
653
	   return 0;
654
   tid=create_thread(thread_proc, 0, 4096);
577 serge 655
 
656
   while(1)
657
   {  delay(10);
658
      switch(status)
1842 clevermous 659
      {  case ST_TRACK:
660
			StopBuffer(hBuff);
661
			if (LoadTrack(++currActive))
662
			{
663
				if (LoadFile(full_filename))
664
					status = ST_PLAY;
665
			}
666
			else status = ST_STOP;
577 serge 667
 
1842 clevermous 668
			//Update ac97snd and PL windows
669
			i=currActive-currFirstShowed;
670
			if (i>PL_MAX_SHOWN_ITEMS-1)
671
				currFirstShowed = currActive - PL_MAX_SHOWN_ITEMS/2;
672
			ipc_send_msg(tid, ipc_msg);
673
			ipc_send_msg(pl_tid, ipc_msg);
674
			continue;
675
 
676
	  case ST_PLAY:
677
		  snd_play();
678
		  continue;
577 serge 679
 
1842 clevermous 680
	  case ST_STOP:
681
		  StopBuffer(hBuff);
682
		  status = ST_DONE;
683
		  continue;
684
 
685
	  case ST_EXIT:
686
		  uFMOD_StopSong();          /* uFMOD integration */
687
		  StopBuffer(hBuff);
688
		  DestroyBuffer(hBuff);
689
		  return 0;
690
	  };
577 serge 691
   };
692
   return 0;
693
};
694
 
576 serge 695
void touch(char *buf, int size)
696
{ int i;
697
   char a;
646 serge 698
    for ( i = 0;i < size; i+=4096)     //alloc all pages
576 serge 699
      a = buf[i];
700
};
701
 
1842 clevermous 702
DWORD test_m3u(char *buf) //Asper+
703
{
704
	char  *sign="#EXTM3U";
705
	return _strncmp(buf, sign, 7);
706
}
707
 
576 serge 708
DWORD test_mp3(char *buf)
709
{  unsigned long hdr;
710
    WAVEHEADER whdr;
711
 
712
    while (1)
713
    {  if(rd.filepos > 102400)
714
          return 0;
715
        if(!rd.head_read(&rd,&hdr))
577 serge 716
                        return 0;
576 serge 717
        if(!decode_header(&fr,hdr))
646 serge 718
        {
719
         if((hdr & 0xffffff00) == 0x49443300)
720
 	      {
721
 		    int id3length = 0;
722
		    id3length = parse_new_id3(&rd, hdr);
723
		    continue;
724
	      };
725
          rd.strpos-=3;
726
          rd.stream-=3;
727
          rd.strremain+=3;
728
          continue;
576 serge 729
        };
730
        break;
646 serge 731
    };
576 serge 732
 
733
    first_sync = rd.filepos-rd.strremain-4;
734
 
735
    whdr.riff_id = 0x46464952;
736
    whdr.riff_format = 0x45564157;
737
    whdr.wFormatTag = 0x01;
738
    whdr.nSamplesPerSec = freqs[fr.sampling_frequency];
646 serge 739
    whdr.nChannels = 2;
576 serge 740
    whdr.wBitsPerSample = 16;
741
 
742
    return test_wav(&whdr);
743
};
744
 
745
 
746
void play_mp3()
747
{  char *outPtr;
748
    int totalout;
749
    int outcount;
750
 
577 serge 751
 //   memset(&fr,0,sizeof(fr));
752
    fr.down_sample_sblimit = 32;
576 serge 753
    fr.single = -1;
754
    reset_mpg();
755
 
756
    outPtr = outbuf;
757
    totalout=0;
758
    done = 0;
759
    outremain=0x40000;
760
 
761
    memset(outbuf,0,0x40000);
762
    set_reader(&rd, 0);    //;first_sync);
763
 
764
    while(1)
765
    { if(status!=ST_PLAY)
766
             break;
767
 
577 serge 768
     for(;;)
769
     {   outcount = 0;
576 serge 770
          if( !read_frame(&rd, &fr))
771
          {  done = 1;
772
              break;
773
          };
774
          fr.do_layer(&fr, outPtr,&outcount);
775
          outPtr+= outcount;
776
          totalout+=outcount;
777
          outremain-=outcount;
778
          if(outremain < outcount*2)
779
            break;
577 serge 780
    };
576 serge 781
 
577 serge 782
    if(done)
783
    { if(totalout < 4096)
784
      {  memset(outPtr,0,4096-totalout);
785
                totalout = 4096;
576 serge 786
      };
577 serge 787
    }
788
    else
789
      if(totalout < 8192)
790
        continue;
576 serge 791
 
577 serge 792
    outPtr = outbuf;
793
    while (totalout >= 4096)
794
    {
795
 
796
      WaveOut(hBuff,outPtr,4096);
797
      if(status!=ST_PLAY)
1842 clevermous 798
      { if ((status != ST_EXIT) && (status != ST_STOP))
799
         status = ST_TRACK;
577 serge 800
        return;
801
      };
802
      totalout-=4096;
803
      outPtr+=4096;
804
      outremain+=4096;
805
    };
806
    if(done)
807
      break;
808
 
809
    memmove(outbuf,outPtr, totalout);
810
    outPtr = outbuf+totalout;
811
   }
812
 
1842 clevermous 813
    if ((status != ST_EXIT) && (status != ST_STOP))
814
      status =  ST_TRACK;
576 serge 815
};
816
 
817
void play_wave()
646 serge 818
{  int count;
576 serge 819
 
820
   set_reader(&rd,44);
821
   while(1)
822
   {
823
      if(status!=ST_PLAY)
824
        break;
825
 
646 serge 826
      if( count=stream_read_raw(&rd,outbuf,32768))
827
      {
828
        WaveOut(hBuff,outbuf,count);
829
        continue;
830
      }
831
      done = 1;
832
      break;
576 serge 833
   };
834
 
1842 clevermous 835
   if ((status != ST_EXIT) && (status != ST_STOP))
836
     status =  ST_TRACK;
576 serge 837
};
838
 
646 serge 839
void play_xm(){                             /* uFMOD integration */
840
	while(status == ST_PLAY){                 /* uFMOD integration */
841
		uFMOD_WaveOut(hBuff);                   /* uFMOD integration */
842
		delay(8);                               /* uFMOD integration */
843
	}                                         /* uFMOD integration */
1842 clevermous 844
	if ((status != ST_EXIT) && (status != ST_STOP)) status = ST_TRACK;   /* uFMOD integration */
646 serge 845
}                                           /* uFMOD integration */
846
 
576 serge 847
void snd_stop()
848
{
849
  StopBuffer(hBuff);
850
};
851
 
577 serge 852
void _stdcall thread_proc(void *param)
853
{  int evnt;
854
   int pos;
855
   int key;
856
   DWORD offset;
1842 clevermous 857
   char ipc_buff[16];
799 serge 858
 
1842 clevermous 859
   set_event_mask(0x47); //Asper + IPC event
860
   ipc_init(ipc_buff, 16);
861
 
577 serge 862
  _asm
576 serge 863
  {
577 serge 864
    mov eax, 66
865
    mov ebx, 1
866
    mov ecx, 1
867
    int 0x40
576 serge 868
  };
577 serge 869
 
870
  draw_window();
576 serge 871
 
577 serge 872
  while(1)
1842 clevermous 873
  {
874
	 if(status==ST_PLAY)
577 serge 875
     {  draw_progress_bar();
1842 clevermous 876
        evnt = wait_for_event(80);
577 serge 877
     }
878
     else
1842 clevermous 879
		 evnt = wait_for_event_infinite();
576 serge 880
 
1842 clevermous 881
#ifdef DOCKABLE_WINDOW
882
     GetThreadInfo(thread_info, -1);
883
#endif
884
 
577 serge 885
    switch(evnt)
886
    {
887
      case EV_REDRAW:
1842 clevermous 888
		  draw_window();
889
		  break;
576 serge 890
 
577 serge 891
      case EV_KEY:
892
        if(!get_key(&key))
893
        {
894
 
895
          switch(key)
896
          {  case 0xE0:
897
             case 0xE1:
898
               break;
899
             default:
900
               switch (key)
901
               {
902
                 case 0x01:  //Esc
903
                   status = ST_EXIT;
904
                   exit();
1842 clevermous 905
                   break;
577 serge 906
 
907
                 case 0x47:  //Home
908
                   if(l_vol < 0)
909
                   { l_vol+=100;
910
                     r_vol+=100;
911
                     SetVolume(hBuff,l_vol,r_vol);
912
                   };
913
                   break;
914
                 case 0x4F:  //End
915
                   if(l_vol > -10000)
916
                   { l_vol-=100;
917
                     r_vol-=100;
918
                     SetVolume(hBuff,l_vol,r_vol);
919
                   };
920
                   break;
921
                 case 0x53:
922
                   if(pan > -10000)
923
                   { pan -=100;
924
                     SetPan(hBuff,pan);
925
                   };
926
                   break;
927
                 case 0x51:
928
                   if(pan < 10000)
929
                   { pan +=100;
930
                     SetPan(hBuff,pan);
931
                   };
932
                   break;
933
               }
934
          };
935
        };
936
        break;
576 serge 937
 
577 serge 938
      case EV_BUTTON:
939
        switch(get_button_id())
940
        {  case 1:
941
             status = ST_EXIT;
942
             exit();
943
             break;
944
 
945
           case 0x10:
946
             status = ST_PLAY;
576 serge 947
             continue;
948
 
577 serge 949
           case 0x11:
950
             status = ST_STOP;
951
             break;
1842 clevermous 952
           case 0x12:
953
			   currActive-=2;
954
			   status = ST_TRACK;
955
			   break;
956
           case 0x13:
957
			   status = ST_TRACK;
958
			   break;
577 serge 959
           case 0x14:
960
            if(l_vol > -10000)
961
            {
962
              l_vol-=100;
963
              r_vol-=100;
964
              SetVolume(hBuff,l_vol,r_vol);
965
            };
966
            break;
576 serge 967
 
577 serge 968
           case 0x15:
969
            if(l_vol < 0)
970
            { l_vol+=100;
971
              r_vol+=100;
972
              SetVolume(hBuff,l_vol,r_vol);
973
            };
974
            break;
576 serge 975
 
1842 clevermous 976
           case 0x16: //Asper+ PL button action
977
			   switch (PLStatus)
978
			   {    case 0x00: //PL not started.
979
						pl_tid=create_thread(pl_thread_proc, 0, 4096);
980
						PLStatus=0x12;
981
				    break;
982
					case 0x01: //PL started, but hidden.
983
						PLStatus=0x12;
984
				    break;
985
					case 0x02: //PL started and showed.
986
						PLStatus=0x11;
987
					break;
988
			   }
989
            break;
990
 
577 serge 991
           case 0x30:
992
            if(status==ST_DONE)
993
              break;
994
            pos = (GetMousePos(REL_WINDOW)>>16)-7;
995
            offset = ((fileinfo.size-44)/286*pos+44)&0xFFFFFFFC;
996
            set_reader(&rd, offset);
997
            draw_progress_bar();
998
            break;
999
        };
1842 clevermous 1000
		break;
1001
 
1002
	  case EV_IPC:
1003
		  *ipc_buff='\0';
1004
		  update_dinamic_content();
1005
		  break;
1006
 
577 serge 1007
    };
1008
  };
576 serge 1009
};
1010
 
1011
void delay (int val)
1012
{
1013
  _asm
799 serge 1014
 {
1015
      mov   eax,5
576 serge 1016
      mov   ebx, [val]
1017
      int   0x40
1018
  };
1019
}
1020
 
1021
int wait_for_event(int time)
1022
{ int retval;
1023
  _asm
799 serge 1024
 {
1025
     mov  eax,23
576 serge 1026
     mov  ebx,[time]
1027
     int  0x40
1028
     mov [retval], eax
1029
 };
1030
 return retval;
1031
};
1032
 
1033
int wait_for_event_infinite()
1034
{ int retval;
1035
  _asm
799 serge 1036
  {
1037
      mov  eax,10
576 serge 1038
      int  0x40
1039
      mov [retval], eax
1040
  };
1041
  return retval;
1042
};
1043
 
1044
void BeginDraw()
1045
{_asm
799 serge 1046
 {
1047
    mov   eax,12
576 serge 1048
    mov   ebx, 1
1049
    int   0x40
1050
  };
1051
};
1052
 
1053
void EndDraw()
1054
{ _asm
799 serge 1055
 {
1056
    mov   eax,12
576 serge 1057
    mov   ebx, 2
1058
    int   0x40
1059
  };
1060
};
1061
 
1842 clevermous 1062
//Asper+_______start KolibriOS sys functions___________________
1063
void ResizeReplaceWindow (DWORD x, DWORD y, DWORD w, DWORD h) //Asper+
1064
{
1065
  _asm
1066
 {
1067
      mov   eax, 67
1068
      mov   ebx, [x]
1069
      mov   ecx, [y]
1070
      mov   edx, [w]
1071
      mov   esi, [h]
1072
      int   0x40
1073
  };
1074
}
1075
 
1076
#ifdef DOCKABLE_WINDOW
1077
void GetThreadInfo (char *info, int slot) //Asper+
1078
{
1079
	_asm
1080
	{
1081
		mov   eax, 9
1082
		mov   ebx, [info]
1083
		mov   ecx, [slot]
1084
		int   0x40
1085
	}
1086
}
1087
#endif
1088
 
1089
void set_event_mask(int mask)
1090
{
1091
	_asm
1092
	{
1093
		mov  eax, 40
1094
		mov  ebx, [mask]
1095
		int  0x40
1096
	}
1097
}
1098
 
1099
void ipc_init(char *buf, int bufsize)
1100
{
1101
	_asm
1102
	{
1103
		mov  eax, 60
1104
		mov  ebx, 1
1105
		mov  ecx, [buf]
1106
		mov  edx, [bufsize]
1107
		int  0x40
1108
	}
1109
}
1110
 
1111
int ipc_send_msg(int PID, char *msg)
1112
{
1113
	int len = strlen(msg);
1114
	int retval;
1115
	_asm
1116
	{
1117
		mov  eax, 60
1118
		mov  ebx, 2
1119
		mov  ecx, [PID]
1120
		mov  edx, [msg]
1121
		mov  esi, [len]
1122
		int  0x40
1123
		mov [retval], eax
1124
	}
1125
}
1126
//Asper+_______end KolibriOS sys functions___________________
1127
 
1128
//Asper+_______start strings routines___________________
1129
int _strncmp(char *src, char *dst, DWORD n)
1130
{
1131
	_asm{
1132
		mov		esi, src
1133
		mov		edi, dst
1134
		mov		ecx, n
1135
	}
1136
 l1:
1137
	_asm{
1138
		cmpsb
1139
		jne 	err
1140
		loop 	l1
1141
	}
1142
	return 1;
1143
 err:
1144
	return 0;
1145
}
1146
 
1147
int _strncpy (char *dst, char *src, int n)
1148
{
1149
	int  i;
1150
	for (i=0; i
1151
	{
1152
		dst[i]=src[i];
1153
		if (src[i]=='\0') break;
1154
	}
1155
	return 0;
1156
}
1157
 
1158
void uint2str(unsigned int value, char *string)
1159
{
1160
  char tmp[33];
1161
  int i, j;
1162
  unsigned v;
1163
 
1164
  v = (unsigned)value;
1165
  j = 0;
1166
  do{
1167
    i = v % 10;
1168
    v = v / 10;
1169
    if (i < 10)
1170
      tmp[j] = i+'0';
1171
    else
1172
      tmp[j] = i + 'a' - 10;
1173
	j++;
1174
  }while (v);
1175
 
1176
  for (i=0; i
1177
    string[i] = tmp[j-i-1];
1178
  string[i] = '\0';
1179
}
1180
 
1181
//Asper+_______end strings routines___________________
1182
 
1183
 
576 serge 1184
///*********
646 serge 1185
void *memmove ( void * dst, void * src, unsigned int count)  /* uFMOD integration */
576 serge 1186
{ void *ret;
1187
  ret = dst;
1188
 
1189
  if (dst <= src || (char *)dst >= ((char *)src + count))
1190
  {
1191
      while (count--)
1192
      { *(char *)dst = *(char *)src;
1193
          dst = (char *)dst + 1;
1194
          src = (char *)src + 1;
1195
      }
1196
   }
1197
   else
1198
    {
1199
        dst = (char *)dst + count - 1;
1200
        src = (char *)src + count - 1;
1201
         while (count--)
1202
          {  *(char *)dst = *(char *)src;
1203
              dst = (char *)dst - 1;
1204
              src = (char *)src - 1;
1205
          }
1206
    }
1207
    return ret;
1208
};
1209
//**********/
1210
 
1211
void * __cdecl mem_cpy(void * dst,const void * src,size_t count)
1212
{    void * ret = dst;
1213
      while (count--)
1214
      {  *(char *)dst = *(char *)src;
1215
          dst = (char *)dst + 1;
1216
          src = (char *)src + 1;
1217
      };
1218
      return(ret);
1219
}
1220
 
646 serge 1221
char * __cdecl strrchr (const char * string,int ch)
1222
{
1223
        char *start = (char *)string;
1224
 
1225
        while (*string++)                       /* find end of string */
1226
                ;
1227
                                                /* search towards front */
1228
        while (--string != start && *string != (char)ch)
1229
                ;
1230
 
1231
        if (*string == (char)ch)                /* char found ? */
1232
                return( (char *)string );
1233
 
1234
        return(NULL);
1235
}
1236
 
1237
int __cdecl _stricmp (const char * dst, const char * src)
1238
{
1239
    int f, l;
1240
 
1241
    do
1242
    {
1243
        if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') )
1244
            f -= 'A' - 'a';
1245
        if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') )
1246
            l -= 'A' - 'a';
1247
    }
1248
    while ( f && (f == l) );
1249
 
1250
    return(f - l);
1251
}
1252
 
1253