From e791c52a3a6fe424b08164fdb29cca8a96d9ccba Mon Sep 17 00:00:00 2001
From: halleyscometsw <halleyscometsw@51a99a44-fe44-0410-b1ba-c3e57ba2b86b>
Date: Sat, 20 Dec 2008 22:57:54 +0000
Subject: [PATCH] rwar support (and changed version 3 rwsd support to use it)
 cleaned up references to vjdsp

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@529 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
---
 readme.txt                |   1 +
 src/Makefile              |   1 -
 src/meta/Makefile.unix.am |   1 -
 src/meta/rwsd.c           | 118 ++++++++++++++++++++++++++------------
 src/vgmstream.c           |   3 +
 src/vgmstream.h           |   1 +
 unix/data.c               |   1 +
 7 files changed, 88 insertions(+), 38 deletions(-)

diff --git a/readme.txt b/readme.txt
index ed49f642..482e344e 100644
--- a/readme.txt
+++ b/readme.txt
@@ -186,6 +186,7 @@ multi:
 - .genh (lots)
 - .nwa (16 bit PCM, NWA DPCM)
 - .psw (PSX ADPCM, GC DSP ADPCM)
+- .rwar (GC DSP ADPCM, 8/16 bit PCM)
 - .rwsd (GC DSP ADPCM, 8/16 bit PCM)
 - .rsd (PSX ADPCM, 16 bit PCM, GC DSP ADPCM, Xbox IMA ADPCM)
 - .sad (GC DSP ADPCM, NDS IMA ADPCM)
diff --git a/src/Makefile b/src/Makefile
index 15778394..571c6e6f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -123,7 +123,6 @@ META_OBJS=meta/adx_header.o \
     meta/sdt.o \
     meta/aix.o \
     meta/ngc_tydsp.o \
-    meta/ngc_vjdsp.o \
     meta/xbox_wvs.o \
     meta/xbox_ims.o \
     meta/xbox_stma.o \
diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am
index c4fc96f0..c170b024 100644
--- a/src/meta/Makefile.unix.am
+++ b/src/meta/Makefile.unix.am
@@ -88,7 +88,6 @@ libmeta_la_SOURCES += sdt.c
 libmeta_la_SOURCES += aix.c
 libmeta_la_SOURCES += ngc_tydsp.c
 libmeta_la_SOURCES += xbox_wvs.c
-libmeta_la_SOURCES += ngc_vjdsp.c
 libmeta_la_SOURCES += xbox_stma.c
 libmeta_la_SOURCES += xbox_ims.c
 libmeta_la_SOURCES += de2.c
diff --git a/src/meta/rwsd.c b/src/meta/rwsd.c
index db66292b..62b9c38f 100644
--- a/src/meta/rwsd.c
+++ b/src/meta/rwsd.c
@@ -2,6 +2,31 @@
 #include "../coding/coding.h"
 #include "../util.h"
 
+static off_t read_rwar(off_t offset, int *version, STREAMFILE *streamFile)
+{
+    off_t wave_offset;
+    if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574152) /* "RWAR" */
+        goto fail;
+
+    switch (read_32bitBE(offset+4,streamFile))
+    {
+        case 0xFEFF0100:
+            if ((uint32_t)read_32bitBE(offset+0x60,streamFile)!=0x52574156) /* "RWAV" */
+                goto fail;
+
+            wave_offset = offset+0x78;
+            *version = 0;
+
+            break;
+        default:
+            goto fail;
+    }
+
+    return wave_offset;
+fail:
+    return -1;
+}
+
 /* RWSD is quite similar to BRSTM, but can contain several streams.
  * Still, some games use it for single streams. We only support the
  * single stream form here */
@@ -16,6 +41,7 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
     int codec_number;
     int channel_count;
     int loop_flag;
+    int rwar = 0;
     int version = -1;
 
     off_t start_offset;
@@ -23,45 +49,56 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
 
     /* check extension, case insensitive */
     streamFile->get_name(streamFile,filename,sizeof(filename));
-    if (strcasecmp("rwsd",filename_extension(filename))) goto fail;
+    if (strcasecmp("rwsd",filename_extension(filename)))
+    {
+        if (strcasecmp("rwar",filename_extension(filename)))
+            goto fail;
+        else
+            rwar = 1;
+    }
 
     /* check header */
-    if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344) /* "RWSD" */
-        goto fail;
-
-    switch (read_32bitBE(4,streamFile))
+    if (rwar)
     {
-        case 0xFEFF0102:
-            /* ideally we would look through the chunk list for a WAVE chunk,
-             * but it's always in the same order */
-            /* get WAVE offset, check */
-            wave_offset = read_32bitBE(0x18,streamFile);
-            if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */
-                goto fail;
-            /* get WAVE size, check */
-            wave_length = read_32bitBE(0x1c,streamFile);
-            if (read_32bitBE(wave_offset+4,streamFile)!=wave_length)
-                goto fail;
+        wave_offset = read_rwar(0,&version,streamFile);
+        if (wave_offset < 0) goto fail;
+    }
+    else
+    {
+        if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344) /* "RWSD" */
+            goto fail;
 
-            /* check wave count */
-            if (read_32bitBE(wave_offset+8,streamFile) != 1)
-                goto fail; /* only support 1 */
-
-            version = 2;
-
-            break;
-        case 0xFEFF0103:
-            {
-                if ((uint32_t)read_32bitBE(0x140,streamFile)!=0x52574156) /* "RWAV" */
+        switch (read_32bitBE(4,streamFile))
+        {
+            case 0xFEFF0102:
+                /* ideally we would look through the chunk list for a WAVE chunk,
+                 * but it's always in the same order */
+                /* get WAVE offset, check */
+                wave_offset = read_32bitBE(0x18,streamFile);
+                if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */
+                    goto fail;
+                /* get WAVE size, check */
+                wave_length = read_32bitBE(0x1c,streamFile);
+                if (read_32bitBE(wave_offset+4,streamFile)!=wave_length)
                     goto fail;
 
-                wave_offset = 0x158;
+                /* check wave count */
+                if (read_32bitBE(wave_offset+8,streamFile) != 1)
+                    goto fail; /* only support 1 */
+
+                version = 2;
+
+                break;
+            case 0xFEFF0103:
+                wave_offset = read_rwar(0xe0,&version,streamFile);
+                if (wave_offset < 0) goto fail;
+
+                rwar = 1;
+                break;
+            default:
+                goto fail;
+        }
 
-                version = 3;
-            }
-            break;
-        default:
-            goto fail;
     }
 
     /* get type details */
@@ -100,7 +137,10 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
     vgmstream->coding_type = coding_type;
     vgmstream->layout_type = layout_none;
 
-    vgmstream->meta_type = meta_RWSD;
+    if (rwar)
+        vgmstream->meta_type = meta_RWAR;
+    else
+        vgmstream->meta_type = meta_RWSD;
 
     if (vgmstream->coding_type == coding_NGC_DSP) {
         off_t coef_offset;
@@ -115,10 +155,16 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
         }
     }
 
-    if (version == 2)
-        start_offset = read_32bitBE(8,streamFile);
+    if (rwar)
+    {
+        if (version == 0)
+            start_offset = wave_offset + 0xF0;
+    }
     else
-        start_offset = 0x248;
+    {
+        if (version == 2)
+            start_offset = read_32bitBE(8,streamFile);
+    }
     stream_size = read_32bitBE(wave_offset+0x50,streamFile);
 
     /* open the file for reading by each channel */
diff --git a/src/vgmstream.c b/src/vgmstream.c
index 53ac3728..1157b136 100644
--- a/src/vgmstream.c
+++ b/src/vgmstream.c
@@ -1476,6 +1476,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
         case meta_RWSD:
             snprintf(temp,TEMPSIZE,"Nintendo RWSD header (single stream)");
             break;
+        case meta_RWAR:
+            snprintf(temp,TEMPSIZE,"Nintendo RWAR header (single stream)");
+            break;
         case meta_PSX_XA:
             snprintf(temp,TEMPSIZE,"RIFF/CDXA header");
             break;
diff --git a/src/vgmstream.h b/src/vgmstream.h
index 7389b8fb..5355aba3 100644
--- a/src/vgmstream.h
+++ b/src/vgmstream.h
@@ -169,6 +169,7 @@ typedef enum {
     meta_AFC,               /* AFC */
     meta_AST,               /* AST */
     meta_RWSD,              /* single-stream RWSD */
+    meta_RWAR,              /* single-stream RWAR */
     meta_RSTM_SPM,          /* RSTM with 44->22khz hack */
 	meta_THP,
 
diff --git a/unix/data.c b/unix/data.c
index c0b751f4..6b1c4b20 100644
--- a/unix/data.c
+++ b/unix/data.c
@@ -155,6 +155,7 @@ gchar *vgmstream_exts [] = {
   "smp",
   "emff",
   "thp",
+  "rwar",
   /* terminator */
   NULL
 };