diff --git a/programs/media/ac97snd/ac97snd/ac97snd.vcproj b/programs/media/ac97snd/ac97snd/ac97snd.vcproj
index c3f6d72d15..6d00e578a8 100644
--- a/programs/media/ac97snd/ac97snd/ac97snd.vcproj
+++ b/programs/media/ac97snd/ac97snd/ac97snd.vcproj
@@ -125,6 +125,8 @@
/>
> Vol- Vol+"; /* uFMOD integration */
+char button_PL[] = "PL"; //Asper+
char *buttons_text = buttons_wav; /* uFMOD integration */
void play_xm(); /* uFMOD integration */
void (*snd_play)();
-void draw_window()
+
+//Asper_____________________Play List code start_____________________________
+#define PLI_BUTTON_HEIGHT 13
+#define PL_MAX_SHOWN_ITEMS (pl_wh-PLI_BUTTON_HEIGHT-40)/PLI_BUTTON_HEIGHT
+#define MAX_TEXT_WIDTH 46
+
+int currSelected, currActive, currFirstShowed;
+unsigned char *pl_buff;
+char pl_path[4096];
+int pl_items_number;
+
+int ShowPLContent(char *filebuffer);
+int GetFileNameFromPL(const char *fbuff, int index, char *name);
+void Win2Dos (char *st, int len);
+
+void HidePLWindow()
+{
+ BeginDraw();
+ ResizeReplaceWindow(pl_wx,pl_wy,0,0);
+ EndDraw();
+}
+
+void ShowPLWindow()
+{
+ unsigned int i;
+
+ BeginDraw();
+ DrawWindow(pl_wx,pl_wy,pl_ww,pl_wh,main_ic,4,0,0,0);
+
+ for (i=0; i0)
+ currFirstShowed--;
+ ShowPLContent(pl_buff);
+ break;
+ }
+ currSelected--;
+ ShowPLContent(pl_buff);
+ break;
+ case 0x50: //Down
+ if (currSelected+currFirstShowed > pl_items_number-2) break;
+ if (currSelected==PL_MAX_SHOWN_ITEMS-1)
+ {
+ //if (currFirstShowed -10000)
+ { l_vol-=100;
+ r_vol-=100;
+ SetVolume(hBuff,l_vol,r_vol);
+ };
+ break;
+ case 0x53:
+ if(pan > -10000)
+ { pan -=100;
+ SetPan(hBuff,pan);
+ };
+ break;
+ case 0x51:
+ if(pan < 10000)
+ { pan +=100;
+ SetPan(hBuff,pan);
+ };
+ break;
+ }
+ };
+ };
+ break;
+
+ case EV_BUTTON:
+ button=get_button_id();
+ if (button==1)
+ {
+ PLStatus=0x00;
+ exit();
+ }
+ for (i=0;i=192)
+ {
+ if (ch>=240) ch-=16;
+ else ch-=64;
+ }
+ else
+ {
+ if (ch==168) ch = 240;
+ if (ch==184) ch = 241;
+ if (ch==185) ch = 252;
+ if ((ch==147) || (ch==148) || (ch==171) || (ch==187)) ch = 34;
+ if ((ch==150) || (ch==151)) ch = 45;
+ }
+ st[i]=ch;
+ }
+}
+
+int GetFileNameFromPL(const char *plbuff, int index, char *name)
+{
+ int count=0,i=0,j=0;
+ char ch;
+
+ do{
+ ch=plbuff[i];
+ if (ch!='#' && i && plbuff[i-1]=='\n')
+ count++;
+ if (count-1==index)
+ {
+ if (j>MAX_TEXT_WIDTH || ch=='\n')
+ {
+ name[j-1]='\0';
+ break;
+ }
+ if (ch=='\\') ch='/';
+ name[j++]=ch;
+ }
+ else if (count-1>index) break;
+ i++;
+ }while (ch);
+ if (!ch) return 0;
+ return j;
+}
+
+int CountFileNamesInPL(const char *plbuff)
+{
+ int count=0,i=0;
+ char ch;
+
+ do{
+ ch=plbuff[i];
+ if (ch!='#' && i && plbuff[i-1]=='\n')
+ count++;
+ i++;
+ }while (ch);
+ if (count) count--;
+ return count;
+}
+
+int ShowPLContent(char *filebuffer)
+{
+ char st[MAX_TEXT_WIDTH+10]="", tmp[MAX_TEXT_WIDTH+1]="";
+ unsigned int len=8,i;
+ DWORD text_color;
+
+ draw_bar(7,24,285,PLI_BUTTON_HEIGHT*(PL_MAX_SHOWN_ITEMS+2), main_ic);
+ draw_bar(7,24+currSelected*(PLI_BUTTON_HEIGHT+1),285,PLI_BUTTON_HEIGHT, selected_ic);
+ for (i=0; i MAX_TEXT_WIDTH)
+ len = MAX_TEXT_WIDTH;
+ write_text(11,i*(PLI_BUTTON_HEIGHT+1)+27,text_color, st, len);
+ }
+ return 1;
+}
+//Asper_____________________Play List code end_____________________________
+
+void update_dinamic_content() //Asper +
{
int len; /* uFMOD integration */
+ draw_bar(7,41,286,11,main_wc);
+
+ draw_bar(7,55,286,11,main_wc);
+ len = strlen(filename); /* uFMOD integration */
+ if(len > 47) len = 47; /* uFMOD integration */
+ write_text(11,57,0x00FF20|FONT0, filename, len); /* uFMOD integration */
+}
+
+void draw_window()
+{
BeginDraw();
- DrawWindow(100,100,299,72,0x404040,3,0,0,0);
+ DrawWindow(100,100,299,main_wh,main_wc,4,0,0,0); //Asper+
- make_button(7,24,45,13, 0x10|BT_NORMAL,0x808080);
- make_button(56,24,45,13, 0x11|BT_NORMAL,0x808080);
- make_button(104,24,45,13, 0x12|BT_NORMAL,0x808080);
- make_button(152,24,45,13, 0x13|BT_NORMAL,0x808080);
- make_button(200,24,45,13, 0x14|BT_NORMAL,0x808080);
- make_button(248,24,45,13, 0x15|BT_NORMAL,0x808080);
+ make_button(7,24,45,13, 0x10|BT_NORMAL,main_bc);
+ make_button(56,24,45,13, 0x11|BT_NORMAL,main_bc);
+ make_button(104,24,45,13, 0x12|BT_NORMAL,main_bc);
+ make_button(152,24,45,13, 0x13|BT_NORMAL,main_bc);
+ make_button(200,24,45,13, 0x14|BT_NORMAL,main_bc);
+ make_button(248,24,45,13, 0x15|BT_NORMAL,main_bc);
- make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,0x404040);
- draw_bar(7,41,286,11,0x404040);
+ make_button(268,70,25,13, 0x16|BT_NORMAL,main_bc); //Asper+ PL button
- draw_bar(7,55,286,11,0x404040);
- len = strlen(filename); /* uFMOD integration */
- if(len > 47) len = 47; /* uFMOD integration */
- write_text(11,57,0x00FF20|FONT0, filename, len); /* uFMOD integration */
+ make_button(7,41,286,11, 0x30|BT_HIDE|BT_NOFRAME,main_wc);
+ update_dinamic_content();
write_text(8,8,FONT0, header, sizeof(header)-1); /* uFMOD integration */
- write_text(12,28,0x404040|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */
+ write_text(12,28,main_wc|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */
write_text(11,27,0xA0FFA0|FONT0,buttons_text,sizeof(buttons_wav)-1); /* uFMOD integration */
+ write_text(276,74,main_wc|FONT0,button_PL,sizeof(button_PL)-1); //Asper+ PL button text
+ write_text(275,73,0xA0FFA0|FONT0,button_PL,sizeof(button_PL)-1); //Asper+
EndDraw();
};
@@ -111,10 +441,10 @@ void draw_progress_bar()
x = (DWORD)(287.0f * (float)(rd.filepos-rd.strremain)/(float)fileinfo.size); /* uFMOD integration */
if(x==0) return;
draw_bar(7,41,x,11,0xA0A0A0);
- draw_bar(x+7,41,287-x,11,0x404040);
+ draw_bar(x+7,41,287-x,11,main_wc);
};
-void debug_out_str(char* str)
+void debug_out_str(const char* str)
{
while (*str != 0)
{
@@ -123,74 +453,117 @@ void debug_out_str(char* str)
}
}
-int main(int argc, char *argv[]) //int argc, char *argv[])
+int LoadPL(char *fname)
+{
+ DWORD fmt;
+ DWORD r_bytes;
+ int retval;
+ int i;
+// char st[100]="";
+
+ char *pch;
+
+ r_bytes=0;
+ pch=strrchr(fname, '/');
+ if (pch)
+ i=pch-fname+1;
+ else
+ i=strlen(fname);
+
+ _strncpy (pl_path, fname, i);
+ pl_path[i]='\0';
+
+ if (!pl_buff)
+ pl_buff = UserAlloc(0x40000);
+ retval=read_file (fname,pl_buff,0,0x40000,&r_bytes);
+
+ if ( retval && (r_bytes==0))
+ return 0;
+
+ Win2Dos(pl_buff, r_bytes);
+ pl_items_number=CountFileNamesInPL(pl_buff);
+/*
+ debug_out_str("\n\rPlay List files number = ");
+ itoa(pl_items_number, st, 10);
+ debug_out_str(st);
+*/
+ fmt = test_m3u(pl_buff);
+
+ if(!fmt)
+ {
+ debug_out_str("\n\rInvalid M3U file");
+ return 0;
+ }
+ debug_out_str("\n\rValid M3U file");
+ currSelected=currFirstShowed=0;
+ currActive=-1;
+ return 1;
+}
+
+int LoadFile(char *fname)
{
DWORD fmt;
DWORD r_bytes;
int retval;
int err;
- int ver;
unsigned char *ttl, *cur; /* uFMOD integration */
-
- fname = argv[1];
+
debug_out_str("\n\rPlay file ");
debug_out_str(fname);
debug_out_str("\n\r");
-
- InitHeap(1024*1024);
+
if(get_fileinfo(fname, &fileinfo)==FILE_NOT_FOUND)
- { debug_out_str("\n\rfile not found\n\r");
+ { debug_out_str("\n\rfile not found\n\r");
return 0;
- };
-
- if(err = InitSound(&ver))
- {
- debug_out_str("Sound service not installed\n\r");
- return 0;
}
-
- if( (SOUND_VERSION>(ver&0xFFFF)) ||
- (SOUND_VERSION<(ver >> 16)))
- {
- debug_out_str("Sound service version mismatch\n\r");
- return 0;
- }
-
- testbuff = UserAlloc(4096);
-
- get_fileinfo(fname, &fileinfo);
+
r_bytes=0;
+ strcpy(filename, strrchr(fname,'/')+1);
+ if( !(fileext = strrchr(filename,'.')))
+ return 0;
+
+ if(!_stricmp(fileext,".m3u"))
+ {
+ LoadPL(fname);
+ status=ST_TRACK;
+ return 1;
+ }
+
+ if (!testbuff)
+ testbuff = UserAlloc(4096);
+
retval=read_file (fname,testbuff,0,2048,&r_bytes);
- if ( retval && (r_bytes==0))
- return 0;
-
- inpbuf = UserAlloc(0x10000);
- touch(inpbuf, 0x10000);
-
+ if ( retval && (r_bytes==0))
+ return 0;
+
+ if (!inpbuf)
+ {
+ inpbuf = UserAlloc(0x10000);
+ touch(inpbuf, 0x10000);
+ }
create_reader(&rd, inpbuf, 0x10000);
init_reader(&rd,fname);
-
- filename = strrchr(fname,'/')+1;
- if( !(fileext = strrchr(filename,'.')))
- return 0;
-
+
if(!_stricmp(fileext,".mp3"))
- {
+ {
fmt = test_mp3(testbuff);
if(!fmt)
{
- debug_out_str("\n\rInvalid MP3 file");
+ debug_out_str("\n\rInvalid MP3 file");
return 0;
};
- snd_play = &play_mp3;
- outremain = 0x40000;
- outbuf = UserAlloc(outremain);
- touch(outbuf, outremain);
- make_decode_tables(32767);
- init_layer2();
- init_layer3(32);
+ snd_play = &play_mp3;
+ outremain = 0x40000;
+ if (!outbuf)
+ {
+ outbuf = UserAlloc(outremain);
+ touch(outbuf, outremain);
+ }
+ make_decode_tables(32767);
+ init_layer2();
+ init_layer3(32);
fr.single = -1;
- goto play;
+ goto play;
};
if(!_stricmp(fileext,".xm"))
@@ -220,55 +593,101 @@ int main(int argc, char *argv[]) //int argc, char *argv[])
if(!_stricmp(fileext, ".wav"))
{
- fmt = test_wav((WAVEHEADER*)testbuff);
+ fmt = test_wav((WAVEHEADER*)testbuff);
if(fmt)
{
snd_play = &play_wave;
set_reader(&rd, 44);
outbuf = UserAlloc(32*1024);
touch(outbuf, 32768);
- goto play;
+ goto play;
}
debug_out_str("\n\rInvalid WAV file");
return 0;
};
- debug_out_str("\n\rUsupported file");
+ debug_out_str("\n\rUnsupported file");
return 0;
play:
status = ST_PLAY;
+ SetFormat(hBuff, fmt);
+ SetVolume(hBuff,l_vol,r_vol);
+ GetVolume(hBuff,&l_vol,&r_vol);
+
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int err, ver;
+ int i;
+ char ipc_msg[2]="\0\0";
+
+ strcpy (full_filename, argv[1]);
+ pl_items_number=0;
+
+ InitHeap(1024*1024);
- if (err = CreateBuffer(fmt,0, &hBuff))
+ if(err = InitSound(&ver))
+ {
+ debug_out_str("Sound service not installed\n\r");
+ return 0;
+ }
+
+ if( (SOUND_VERSION>(ver&0xFFFF)) ||
+ (SOUND_VERSION<(ver >> 16)))
+ {
+ debug_out_str("Sound service version mismatch\n\r");
+ return 0;
+ }
+
+ if (err = CreateBuffer(PCM_2_16_48, 0, &hBuff))
{
debug_out_str("create buffer return error\n\r");
- ; return 0;
+ return 0;
}
-
- SetVolume(hBuff,l_vol,r_vol);
- GetVolume(hBuff,&l_vol,&r_vol);
-
- create_thread(thread_proc, 0, 4096);
+
+ if (!LoadFile(full_filename))
+ return 0;
+ tid=create_thread(thread_proc, 0, 4096);
while(1)
{ delay(10);
switch(status)
- { case ST_PLAY:
- snd_play();
- continue;
+ { case ST_TRACK:
+ StopBuffer(hBuff);
+ if (LoadTrack(++currActive))
+ {
+ if (LoadFile(full_filename))
+ status = ST_PLAY;
+ }
+ else status = ST_STOP;
- case ST_STOP:
- StopBuffer(hBuff);
- status = ST_DONE;
- continue;
+ //Update ac97snd and PL windows
+ i=currActive-currFirstShowed;
+ if (i>PL_MAX_SHOWN_ITEMS-1)
+ currFirstShowed = currActive - PL_MAX_SHOWN_ITEMS/2;
+ ipc_send_msg(tid, ipc_msg);
+ ipc_send_msg(pl_tid, ipc_msg);
+ continue;
+
+ case ST_PLAY:
+ snd_play();
+ continue;
- case ST_EXIT:
- uFMOD_StopSong(); /* uFMOD integration */
- StopBuffer(hBuff);
- DestroyBuffer(hBuff);
- return 0;
- };
+ case ST_STOP:
+ StopBuffer(hBuff);
+ status = ST_DONE;
+ continue;
+
+ case ST_EXIT:
+ uFMOD_StopSong(); /* uFMOD integration */
+ StopBuffer(hBuff);
+ DestroyBuffer(hBuff);
+ return 0;
+ };
};
return 0;
};
@@ -280,6 +699,12 @@ void touch(char *buf, int size)
a = buf[i];
};
+DWORD test_m3u(char *buf) //Asper+
+{
+ char *sign="#EXTM3U";
+ return _strncmp(buf, sign, 7);
+}
+
DWORD test_mp3(char *buf)
{ unsigned long hdr;
WAVEHEADER whdr;
@@ -370,8 +795,8 @@ void play_mp3()
WaveOut(hBuff,outPtr,4096);
if(status!=ST_PLAY)
- { if(status != ST_EXIT)
- status = ST_STOP;
+ { if ((status != ST_EXIT) && (status != ST_STOP))
+ status = ST_TRACK;
return;
};
totalout-=4096;
@@ -385,8 +810,8 @@ void play_mp3()
outPtr = outbuf+totalout;
}
- if(status != ST_EXIT)
- status = ST_STOP;
+ if ((status != ST_EXIT) && (status != ST_STOP))
+ status = ST_TRACK;
};
void play_wave()
@@ -407,8 +832,8 @@ void play_wave()
break;
};
- if(status != ST_EXIT)
- status = ST_STOP;
+ if ((status != ST_EXIT) && (status != ST_STOP))
+ status = ST_TRACK;
};
void play_xm(){ /* uFMOD integration */
@@ -416,7 +841,7 @@ void play_xm(){ /* uFMOD integration */
uFMOD_WaveOut(hBuff); /* uFMOD integration */
delay(8); /* uFMOD integration */
} /* uFMOD integration */
- if(status != ST_EXIT) status = ST_STOP; /* uFMOD integration */
+ if ((status != ST_EXIT) && (status != ST_STOP)) status = ST_TRACK; /* uFMOD integration */
} /* uFMOD integration */
void snd_stop()
@@ -429,6 +854,10 @@ void _stdcall thread_proc(void *param)
int pos;
int key;
DWORD offset;
+ char ipc_buff[16];
+
+ set_event_mask(0x47); //Asper + IPC event
+ ipc_init(ipc_buff, 16);
_asm
{
@@ -441,18 +870,23 @@ void _stdcall thread_proc(void *param)
draw_window();
while(1)
- { if(status==ST_PLAY)
+ {
+ if(status==ST_PLAY)
{ draw_progress_bar();
- evnt = wait_for_event(80);
+ evnt = wait_for_event(80);
}
else
- evnt = wait_for_event_infinite();
+ evnt = wait_for_event_infinite();
+
+#ifdef DOCKABLE_WINDOW
+ GetThreadInfo(thread_info, -1);
+#endif
switch(evnt)
{
case EV_REDRAW:
- draw_window();
- break;
+ draw_window();
+ break;
case EV_KEY:
if(!get_key(&key))
@@ -468,7 +902,7 @@ void _stdcall thread_proc(void *param)
case 0x01: //Esc
status = ST_EXIT;
exit();
- break;
+ break;
case 0x47: //Home
if(l_vol < 0)
@@ -515,8 +949,13 @@ void _stdcall thread_proc(void *param)
case 0x11:
status = ST_STOP;
break;
-// case 0x12:
-// case 0x13:
+ case 0x12:
+ currActive-=2;
+ status = ST_TRACK;
+ break;
+ case 0x13:
+ status = ST_TRACK;
+ break;
case 0x14:
if(l_vol > -10000)
{
@@ -534,6 +973,21 @@ void _stdcall thread_proc(void *param)
};
break;
+ case 0x16: //Asper+ PL button action
+ switch (PLStatus)
+ { case 0x00: //PL not started.
+ pl_tid=create_thread(pl_thread_proc, 0, 4096);
+ PLStatus=0x12;
+ break;
+ case 0x01: //PL started, but hidden.
+ PLStatus=0x12;
+ break;
+ case 0x02: //PL started and showed.
+ PLStatus=0x11;
+ break;
+ }
+ break;
+
case 0x30:
if(status==ST_DONE)
break;
@@ -543,6 +997,13 @@ void _stdcall thread_proc(void *param)
draw_progress_bar();
break;
};
+ break;
+
+ case EV_IPC:
+ *ipc_buff='\0';
+ update_dinamic_content();
+ break;
+
};
};
};
@@ -598,6 +1059,128 @@ void EndDraw()
};
};
+//Asper+_______start KolibriOS sys functions___________________
+void ResizeReplaceWindow (DWORD x, DWORD y, DWORD w, DWORD h) //Asper+
+{
+ _asm
+ {
+ mov eax, 67
+ mov ebx, [x]
+ mov ecx, [y]
+ mov edx, [w]
+ mov esi, [h]
+ int 0x40
+ };
+}
+
+#ifdef DOCKABLE_WINDOW
+void GetThreadInfo (char *info, int slot) //Asper+
+{
+ _asm
+ {
+ mov eax, 9
+ mov ebx, [info]
+ mov ecx, [slot]
+ int 0x40
+ }
+}
+#endif
+
+void set_event_mask(int mask)
+{
+ _asm
+ {
+ mov eax, 40
+ mov ebx, [mask]
+ int 0x40
+ }
+}
+
+void ipc_init(char *buf, int bufsize)
+{
+ _asm
+ {
+ mov eax, 60
+ mov ebx, 1
+ mov ecx, [buf]
+ mov edx, [bufsize]
+ int 0x40
+ }
+}
+
+int ipc_send_msg(int PID, char *msg)
+{
+ int len = strlen(msg);
+ int retval;
+ _asm
+ {
+ mov eax, 60
+ mov ebx, 2
+ mov ecx, [PID]
+ mov edx, [msg]
+ mov esi, [len]
+ int 0x40
+ mov [retval], eax
+ }
+}
+//Asper+_______end KolibriOS sys functions___________________
+
+//Asper+_______start strings routines___________________
+int _strncmp(char *src, char *dst, DWORD n)
+{
+ _asm{
+ mov esi, src
+ mov edi, dst
+ mov ecx, n
+ }
+ l1:
+ _asm{
+ cmpsb
+ jne err
+ loop l1
+ }
+ return 1;
+ err:
+ return 0;
+}
+
+int _strncpy (char *dst, char *src, int n)
+{
+ int i;
+ for (i=0; i