move blit to core, allow filtering while blitting
[pcsx_rearmed.git] / plugins / dfsound / xa.c
index bdea89a..1c5425e 100644 (file)
@@ -22,8 +22,6 @@
 // will be included from spu.c
 #ifdef _IN_SPU
 
-#define XA_HACK
-
 ////////////////////////////////////////////////////////////////////////
 // XA GLOBALS
 ////////////////////////////////////////////////////////////////////////
@@ -61,42 +59,44 @@ static int gauss_window[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 INLINE void MixXA(void)
 {
  int ns;
- uint32_t l;
-
- for(ns=0;ns<NSSIZE*2 && XAPlay!=XAFeed;)
-  {
-   XALastVal=*XAPlay++;
-   if(XAPlay==XAEnd) XAPlay=XAStart;
-#ifdef XA_HACK
-   SSumLR[ns++]+=(((short)(XALastVal&0xffff))       * iLeftXAVol)/32768;
-   SSumLR[ns++]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32768;
-#else
-   SSumLR[ns++]+=(((short)(XALastVal&0xffff))       * iLeftXAVol)/32767;
-   SSumLR[ns++]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
-#endif
-  }
+ short l, r;
+ uint32_t v;
+ int cursor = decode_pos;
 
- if(XAPlay==XAFeed && XARepeat)
-  {
+ if(XAPlay != XAFeed || XARepeat > 0)
+ {
+  if(XAPlay == XAFeed)
    XARepeat--;
-   for(;ns<NSSIZE*2;)
-    {
-#ifdef XA_HACK
-     SSumLR[ns++]+=(((short)(XALastVal&0xffff))       * iLeftXAVol)/32768;
-     SSumLR[ns++]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32768;
-#else
-     SSumLR[ns++]+=(((short)(XALastVal&0xffff))       * iLeftXAVol)/32767;
-     SSumLR[ns++]+=(((short)((XALastVal>>16)&0xffff)) * iRightXAVol)/32767;
-#endif
-    }
-  }
+
+  v = XALastVal;
+  for(ns=0;ns<NSSIZE*2;)
+   {
+    if(XAPlay != XAFeed) v=*XAPlay++;
+    if(XAPlay == XAEnd) XAPlay=XAStart;
+
+    l = ((int)(short)v * iLeftXAVol) >> 15;
+    r = ((int)(short)(v >> 16) * iLeftXAVol) >> 15;
+    SSumLR[ns++] += l;
+    SSumLR[ns++] += r;
+    spuMem[cursor] = l;
+    spuMem[cursor + 0x400/2] = r;
+    cursor = (cursor + 1) & 0x1ff;
+   }
+  XALastVal = v;
+ }
 
  for(ns=0;ns<NSSIZE*2 && CDDAPlay!=CDDAFeed && (CDDAPlay!=CDDAEnd-1||CDDAFeed!=CDDAStart);)
   {
-   l=*CDDAPlay++;
+   v=*CDDAPlay++;
    if(CDDAPlay==CDDAEnd) CDDAPlay=CDDAStart;
-   SSumLR[ns++]+=(((short)(l&0xffff))       * iLeftXAVol)/32767;
-   SSumLR[ns++]+=(((short)((l>>16)&0xffff)) * iRightXAVol)/32767;
+
+   l = ((int)(short)v * iLeftXAVol) >> 15;
+   r = ((int)(short)(v >> 16) * iLeftXAVol) >> 15;
+   SSumLR[ns++] += l;
+   SSumLR[ns++] += r;
+   spuMem[cursor] = l;
+   spuMem[cursor + 0x400/2] = r;
+   cursor = (cursor + 1) & 0x1ff;
   }
 }
 
@@ -104,7 +104,7 @@ INLINE void MixXA(void)
 // small linux time helper... only used for watchdog
 ////////////////////////////////////////////////////////////////////////
 
-unsigned long timeGetTime_spu()
+static unsigned long timeGetTime_spu()
 {
  struct timeval tv;
  gettimeofday(&tv, 0);                                 // well, maybe there are better ways
@@ -222,13 +222,11 @@ INLINE void FeedXA(xa_decode_t *xap)
        s=(short)LOWORD(l);
        l1=s;
        l1=(l1*iPlace)/iSize;
-       if(l1<-32767) l1=-32767;
-       if(l1> 32767) l1=32767;
+       ssat32_to_16(l1);
        s=(short)HIWORD(l);
        l2=s;
        l2=(l2*iPlace)/iSize;
-       if(l2<-32767) l2=-32767;
-       if(l2> 32767) l2=32767;
+       ssat32_to_16(l2);
        l=(l1&0xffff)|(l2<<16);
 
        *XAFeed++=l;
@@ -328,8 +326,7 @@ INLINE void FeedXA(xa_decode_t *xap)
         }
 
        l1=(l1*iPlace)/iSize;
-       if(l1<-32767) l1=-32767;
-       if(l1> 32767) l1=32767;
+       ssat32_to_16(l1);
        l=(l1&0xffff)|(l1<<16);
        *XAFeed++=l;
 
@@ -392,21 +389,29 @@ INLINE void FeedXA(xa_decode_t *xap)
 // FEED CDDA
 ////////////////////////////////////////////////////////////////////////
 
-INLINE void FeedCDDA(unsigned char *pcm, int nBytes)
+INLINE int FeedCDDA(unsigned char *pcm, int nBytes)
 {
+ int space;
+ space=(CDDAPlay-CDDAFeed-1)*4 & (CDDA_BUFFER_SIZE - 1);
+ if(space<nBytes)
+  return 0x7761; // rearmed_wait
+
  while(nBytes>0)
   {
    if(CDDAFeed==CDDAEnd) CDDAFeed=CDDAStart;
-   while(CDDAFeed==CDDAPlay-1||
-         (CDDAFeed==CDDAEnd-1&&CDDAPlay==CDDAStart))
-   {
-    if (!iUseTimer) usleep(1000);
-    else return;
-   }
-   *CDDAFeed++=(*pcm | (*(pcm+1)<<8) | (*(pcm+2)<<16) | (*(pcm+3)<<24));
-   nBytes-=4;
-   pcm+=4;
+   space=(CDDAPlay-CDDAFeed-1)*4 & (CDDA_BUFFER_SIZE - 1);
+   if(CDDAFeed+space/4>CDDAEnd)
+    space=(CDDAEnd-CDDAFeed)*4;
+   if(space>nBytes)
+    space=nBytes;
+
+   memcpy(CDDAFeed,pcm,space);
+   CDDAFeed+=space/4;
+   nBytes-=space;
+   pcm+=space;
   }
+
+ return 0x676f; // rearmed_go
 }
 
 #endif