changeset 1194:0c0a5ff7b20b trunk

[svn] - add libjma (a hopefully portable snapshot of the ZSNES JMA implementation)
author nenolod
date Tue, 13 Jun 2006 20:37:25 -0700
parents 03414b9d2507
children b8e919aa6350
files ChangeLog Plugins/Input/console/Makefile.in Plugins/Input/console/libjma/7z.h Plugins/Input/console/libjma/7zlzma.cpp Plugins/Input/console/libjma/Makefile Plugins/Input/console/libjma/README Plugins/Input/console/libjma/aribitcd.h Plugins/Input/console/libjma/ariconst.h Plugins/Input/console/libjma/ariprice.h Plugins/Input/console/libjma/btreecd.h Plugins/Input/console/libjma/crc32.cpp Plugins/Input/console/libjma/crc32.h Plugins/Input/console/libjma/iiostrm.cpp Plugins/Input/console/libjma/iiostrm.h Plugins/Input/console/libjma/inbyte.cpp Plugins/Input/console/libjma/inbyte.h Plugins/Input/console/libjma/jma.cpp Plugins/Input/console/libjma/jma.h Plugins/Input/console/libjma/lencoder.h Plugins/Input/console/libjma/litcoder.h Plugins/Input/console/libjma/lzma.cpp Plugins/Input/console/libjma/lzma.h Plugins/Input/console/libjma/lzmadec.cpp Plugins/Input/console/libjma/lzmadec.h Plugins/Input/console/libjma/portable.h Plugins/Input/console/libjma/rcdefs.h Plugins/Input/console/libjma/rngcoder.h Plugins/Input/console/libjma/winout.cpp Plugins/Input/console/libjma/winout.h
diffstat 29 files changed, 2801 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jun 13 08:36:56 2006 -0700
+++ b/ChangeLog	Tue Jun 13 20:37:25 2006 -0700
@@ -1,3 +1,12 @@
+2006-06-13 15:36:56 +0000  Yoshiki Yazawa <yaz@cc.rim.or.jp>
+  revision [1296]
+  filesize must be cached, otherwise lookup loop will crash.
+  
+
+  Changes:        Modified:
+  +2 -1           trunk/audacious/util.c  
+
+
 2006-06-13 08:59:28 +0000  William Pitcock <nenolod@nenolod.net>
   revision [1294]
   - fix potential crashing on malformed ID3v2 tags
--- a/Plugins/Input/console/Makefile.in	Tue Jun 13 08:36:56 2006 -0700
+++ b/Plugins/Input/console/Makefile.in	Tue Jun 13 20:37:25 2006 -0700
@@ -3,6 +3,8 @@
 
 OBJECTIVE_LIBS = libconsole.so
 
+SUBDIRS = libjma
+
 LIBDIR = $(plugindir)/$(INPUT_PLUGIN_DIR)
 
 SOURCES = \
@@ -42,5 +44,5 @@
 
 OBJECTS = ${SOURCES:.cpp=.o}
 
-LIBADD += -lz $(GTK_LIBS) -lstdc++
+LIBADD += -lz $(GTK_LIBS) -lstdc++ ./libjma/libjma.a
 CXXFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/7z.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __7Z_H
+#define __7Z_H
+
+#include "iiostrm.h"
+
+bool decompress_lzma_7z(ISequentialInStream& in, unsigned in_size, ISequentialOutStream& out, unsigned out_size) throw ();
+bool decompress_lzma_7z(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size) throw ();
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/7zlzma.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,50 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "7z.h"
+
+#include "lzmadec.h"
+
+bool decompress_lzma_7z(ISequentialInStream& in, unsigned in_size, ISequentialOutStream& out, unsigned out_size) throw ()
+{
+  try
+  {
+    NCompress::NLZMA::CDecoder cc;
+
+    UINT64 in_size_l = in_size;
+    UINT64 out_size_l = out_size;
+
+    if (cc.ReadCoderProperties(&in) != S_OK)                 { return(false); }
+    if (cc.Code(&in, &out, &in_size_l, &out_size_l) != S_OK) { return(false); }
+    if (out.size_get() != out_size || out.overflow_get())    { return(false); }
+
+    return(true);
+  }
+  catch (...)
+  {
+    return(false);
+  }
+}
+
+bool decompress_lzma_7z(const unsigned char* in_data, unsigned int in_size, unsigned char* out_data, unsigned int out_size) throw ()
+{
+  ISequentialInStream_Array in(reinterpret_cast<const char*>(in_data), in_size);
+  ISequentialOutStream_Array out(reinterpret_cast<char*>(out_data), out_size);
+
+  return(decompress_lzma_7z(in, in_size, out, out_size));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/Makefile	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,19 @@
+include ../../../../mk/rules.mk
+include ../../../../mk/objective.mk
+
+OBJECTIVE_LIBS_NOINST = libjma.a
+
+SOURCES = \
+	7zlzma.cpp		\
+	crc32.cpp		\
+	iiostrm.cpp		\
+	inbyte.cpp		\
+	jma.cpp			\
+	lzma.cpp		\
+	lzmadec.cpp		\
+	winout.cpp
+
+OBJECTS = ${SOURCES:.cpp=.o}
+
+LIBADD += -lstdc++
+CXXFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/README	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,6 @@
+This is a snapshot of the JMA code taken from ZSNES. However, do not
+blame them if it does not work -- instead file a bug against the
+libjma component in our Mantis, at:
+
+   http://bugs.audacious-media-player.org
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/aribitcd.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,73 @@
+#ifndef __COMPRESSION_BITCODER_H
+#define __COMPRESSION_BITCODER_H
+
+#include "rngcoder.h"
+
+namespace NCompression {
+namespace NArithmetic {
+
+const int kNumBitModelTotalBits  = 11;
+const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+/////////////////////////////
+// CBitModel
+
+template <int aNumMoveBits>
+class CBitModel
+{
+public:
+  UINT32 m_Probability;
+  void UpdateModel(UINT32 aSymbol)
+  {
+    /*
+    m_Probability -= (m_Probability + ((aSymbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
+    m_Probability += (1 - aSymbol) << (kNumBitModelTotalBits - aNumMoveBits);
+    */
+    if (aSymbol == 0)
+      m_Probability += (kBitModelTotal - m_Probability) >> aNumMoveBits;
+    else
+      m_Probability -= (m_Probability) >> aNumMoveBits;
+  }
+public:
+  void Init() { m_Probability = kBitModelTotal / 2; }
+};
+
+template <int aNumMoveBits>
+class CBitDecoder: public CBitModel<aNumMoveBits>
+{
+public:
+  UINT32 Decode(CRangeDecoder *aRangeDecoder)
+  {
+    UINT32 aNewBound = (aRangeDecoder->m_Range >> kNumBitModelTotalBits) * CBitModel<aNumMoveBits>::m_Probability;
+    if (aRangeDecoder->m_Code < aNewBound)
+    {
+      aRangeDecoder->m_Range = aNewBound;
+      CBitModel<aNumMoveBits>::m_Probability += (kBitModelTotal - CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
+      if (aRangeDecoder->m_Range < kTopValue)
+      {
+        aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
+        aRangeDecoder->m_Range <<= 8;
+      }
+      return 0;
+    }
+    else
+    {
+      aRangeDecoder->m_Range -= aNewBound;
+      aRangeDecoder->m_Code -= aNewBound;
+      CBitModel<aNumMoveBits>::m_Probability -= (CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
+      if (aRangeDecoder->m_Range < kTopValue)
+      {
+        aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
+        aRangeDecoder->m_Range <<= 8;
+      }
+      return 1;
+    }
+  }
+};
+
+}}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/ariconst.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __ARICONST_H
+#define __ARICONST_H
+
+#include "aribitcd.h"
+
+
+typedef NCompression::NArithmetic::CRangeDecoder CMyRangeDecoder;
+template <int aNumMoveBits> class CMyBitDecoder:
+    public NCompression::NArithmetic::CBitDecoder<aNumMoveBits> {};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/ariprice.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,12 @@
+#ifndef __COMPRESSION_ARIPRICE_H
+#define __COMPRESSION_ARIPRICE_H
+
+namespace NCompression {
+namespace NArithmetic {
+
+const UINT32 kNumBitPriceShiftBits = 6;
+const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/btreecd.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,126 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __BITTREECODER_H
+#define __BITTREECODER_H
+
+#include "aribitcd.h"
+#include "rcdefs.h"
+
+
+//////////////////////////
+// CBitTreeDecoder
+
+template <int aNumMoveBits, UINT32 m_NumBitLevels>
+class CBitTreeDecoder
+{
+  CMyBitDecoder<aNumMoveBits> m_Models[1 << m_NumBitLevels];
+public:
+  void Init()
+  {
+    for(UINT32 i = 1; i < (1 << m_NumBitLevels); i++)
+      m_Models[i].Init();
+  }
+  UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
+  {
+    UINT32 aModelIndex = 1;
+    RC_INIT_VAR
+    for(UINT32 aBitIndex = m_NumBitLevels; aBitIndex > 0; aBitIndex--)
+    {
+      // aModelIndex = (aModelIndex << 1) + m_Models[aModelIndex].Decode(aRangeDecoder);
+      RC_GETBIT(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex)
+    }
+    RC_FLUSH_VAR
+    return aModelIndex - (1 << m_NumBitLevels);
+  };
+};
+
+////////////////////////////////
+// CReverseBitTreeDecoder
+
+template <int aNumMoveBits>
+class CReverseBitTreeDecoder2
+{
+  CMyBitDecoder<aNumMoveBits> *m_Models;
+  UINT32 m_NumBitLevels;
+public:
+  CReverseBitTreeDecoder2(): m_Models(0) { }
+  ~CReverseBitTreeDecoder2() { delete []m_Models; }
+  bool Create(UINT32 aNumBitLevels)
+  {
+    m_NumBitLevels = aNumBitLevels;
+    m_Models = new CMyBitDecoder<aNumMoveBits>[1 << aNumBitLevels];
+    return (m_Models != 0);
+  }
+  void Init()
+  {
+    UINT32 aNumModels = 1 << m_NumBitLevels;
+    for(UINT32 i = 1; i < aNumModels; i++)
+      m_Models[i].Init();
+  }
+  UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
+  {
+    UINT32 aModelIndex = 1;
+    UINT32 aSymbol = 0;
+    RC_INIT_VAR
+    for(UINT32 aBitIndex = 0; aBitIndex < m_NumBitLevels; aBitIndex++)
+    {
+      // UINT32 aBit = m_Models[aModelIndex].Decode(aRangeDecoder);
+      // aModelIndex <<= 1;
+      // aModelIndex += aBit;
+      // aSymbol |= (aBit << aBitIndex);
+      RC_GETBIT2(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex, ; , aSymbol |= (1 << aBitIndex))
+    }
+    RC_FLUSH_VAR
+    return aSymbol;
+  };
+};
+////////////////////////////
+// CReverseBitTreeDecoder2
+
+template <int aNumMoveBits, UINT32 m_NumBitLevels>
+class CReverseBitTreeDecoder
+{
+  CMyBitDecoder<aNumMoveBits> m_Models[1 << m_NumBitLevels];
+public:
+  void Init()
+  {
+    for(UINT32 i = 1; i < (1 << m_NumBitLevels); i++)
+      m_Models[i].Init();
+  }
+  UINT32 Decode(CMyRangeDecoder *aRangeDecoder)
+  {
+    UINT32 aModelIndex = 1;
+    UINT32 aSymbol = 0;
+    RC_INIT_VAR
+    for(UINT32 aBitIndex = 0; aBitIndex < m_NumBitLevels; aBitIndex++)
+    {
+      // UINT32 aBit = m_Models[aModelIndex].Decode(aRangeDecoder);
+      // aModelIndex <<= 1;
+      // aModelIndex += aBit;
+      // aSymbol |= (aBit << aBitIndex);
+      RC_GETBIT2(aNumMoveBits, m_Models[aModelIndex].m_Probability, aModelIndex, ; , aSymbol |= (1 << aBitIndex))
+    }
+    RC_FLUSH_VAR
+    return aSymbol;
+  }
+};
+
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/crc32.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 2004-2006 NSRT Team ( http://nsrt.edgeemu.com )
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+
+namespace CRC32lib
+{
+  //Don't ask questions, this is the PKZip CRC32 table
+  const unsigned int crc32Table[256] = {
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
+
+
+  //CRC32 for char arrays
+  unsigned int CRC32(const unsigned char *array, size_t size, register unsigned int crc32)
+  {
+    const unsigned char *end_p = array+size;
+    for (register const unsigned char *p = array; p < end_p; p++)
+    {
+      crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ *p) & 0xFF];
+    }
+
+    return(~crc32);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/crc32.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,26 @@
+/*
+Copyright (C) 2004-2006 NSRT Team ( http://nsrt.edgeemu.com )
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CRC32_H
+#define CRC32_H
+
+namespace CRC32lib
+{
+  unsigned int CRC32(const unsigned char *, size_t, register unsigned int crc32 = 0xFFFFFFFF);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/iiostrm.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,132 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "portable.h"
+#include "iiostrm.h"
+#include "crc32.h"
+
+HRESULT ISequentialInStream_Array::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  if (aSize > size)
+  {
+    aSize = size;
+  }
+
+  *aProcessedSize = aSize;
+  memcpy(aData, data, aSize);
+  size -= aSize;
+  data += aSize;
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStream_Array::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  if (aSize > size)
+  {
+    overflow = true;
+    aSize = size;
+  }
+
+  *aProcessedSize = aSize;
+  memcpy(data, aData, aSize);
+  size -= aSize;
+  data += aSize;
+  total += aSize;
+  return(S_OK);
+}
+
+HRESULT ISequentialInStream_String::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  if (aSize > data.size())
+  {
+    aSize = data.size();
+  }
+
+  *aProcessedSize = aSize;
+  memcpy(aData, data.c_str(), aSize);
+  data.erase(0, aSize);
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStream_String::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  *aProcessedSize = aSize;
+  data.append((const char *)aData, aSize);
+  total += aSize;
+  return(S_OK);
+}
+
+HRESULT ISequentialInStream_Istream::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  data.read((char *)aData, aSize);
+  *aProcessedSize = data.gcount();
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStream_Ostream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  *aProcessedSize = aSize;
+  data.write((char *)aData, aSize);
+  total += aSize;
+  return(S_OK);
+}
+
+
+
+HRESULT ISequentialInStreamCRC32_Array::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialInStream_Array::Read(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStreamCRC32_Array::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialOutStream_Array::Write(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
+
+HRESULT ISequentialInStreamCRC32_String::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialInStream_String::Read(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStreamCRC32_String::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialOutStream_String::Write(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
+
+HRESULT ISequentialInStreamCRC32_Istream::Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialInStream_Istream::Read(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
+
+HRESULT ISequentialOutStreamCRC32_Ostream::Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize)
+{
+  ISequentialOutStream_Ostream::Write(aData, aSize, aProcessedSize);
+  crc32 = CRC32lib::CRC32((const unsigned char *)aData, *aProcessedSize, ~crc32);
+  return(S_OK);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/iiostrm.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,210 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __IINOUTSTREAMS_H
+#define __IINOUTSTREAMS_H
+
+#include <string>
+#include <fstream>
+
+#include "portable.h"
+
+
+class ISequentialInStream
+{
+public:
+  virtual HRESULT Read(void *, UINT32, UINT32 *) = 0;
+
+  virtual ~ISequentialInStream() {}
+};
+
+
+class ISequentialInStream_Array : public ISequentialInStream
+{
+  const char *data;
+  unsigned int size;
+public:
+  ISequentialInStream_Array(const char *Adata, unsigned Asize) : data(Adata), size(Asize) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStream_Array() {}
+};
+
+class ISequentialInStream_String : public ISequentialInStream
+{
+  std::string& data;
+public:
+  ISequentialInStream_String(std::string& Adata) : data(Adata) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStream_String() {}
+};
+
+class ISequentialInStream_Istream : public ISequentialInStream
+{
+  std::istream& data;
+public:
+  ISequentialInStream_Istream(std::istream& Adata) : data(Adata) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStream_Istream() {}
+};
+
+
+
+class ISequentialOutStream
+{
+public:
+  virtual bool overflow_get() const = 0;
+  virtual unsigned int size_get() const = 0;
+
+  virtual HRESULT Write(const void *, UINT32, UINT32 *) = 0;
+
+  virtual ~ISequentialOutStream() {}
+};
+
+
+class ISequentialOutStream_Array : public ISequentialOutStream
+{
+  char *data;
+  unsigned int size;
+  bool overflow;
+  unsigned int total;
+public:
+  ISequentialOutStream_Array(char *Adata, unsigned Asize) : data(Adata), size(Asize), overflow(false), total(0) { }
+
+  bool overflow_get() const { return(overflow); }
+  unsigned int size_get() const { return(total); }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStream_Array() {}
+};
+
+class ISequentialOutStream_String : public ISequentialOutStream
+{
+  std::string& data;
+  unsigned int total;
+public:
+  ISequentialOutStream_String(std::string& Adata) : data(Adata), total(0) { }
+
+  bool overflow_get() const { return(false); }
+  unsigned int size_get() const { return(total); }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStream_String() {}
+};
+
+
+class ISequentialOutStream_Ostream : public ISequentialOutStream
+{
+  std::ostream& data;
+  unsigned int total;
+public:
+  ISequentialOutStream_Ostream(std::ostream& Adata) : data(Adata), total(0) { }
+
+  bool overflow_get() const { return(false); }
+  unsigned int size_get() const { return(total); }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStream_Ostream() {}
+};
+
+
+
+class ISequentialStreamCRC32
+{
+protected:
+  unsigned int crc32;
+public:
+  ISequentialStreamCRC32() : crc32(0) {}
+  unsigned int crc32_get() const { return(crc32); }
+
+  virtual ~ISequentialStreamCRC32() {}
+};
+
+
+class ISequentialInStreamCRC32_Array : public ISequentialInStream_Array, public ISequentialStreamCRC32
+{
+public:
+  ISequentialInStreamCRC32_Array(const char *Adata, unsigned Asize) : ISequentialInStream_Array(Adata, Asize) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStreamCRC32_Array() {}
+};
+
+class ISequentialInStreamCRC32_String : public ISequentialInStream_String, public ISequentialStreamCRC32
+{
+public:
+  ISequentialInStreamCRC32_String(std::string& Adata) : ISequentialInStream_String(Adata) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStreamCRC32_String() {}
+};
+
+class ISequentialInStreamCRC32_Istream : public ISequentialInStream_Istream, public ISequentialStreamCRC32
+{
+public:
+  ISequentialInStreamCRC32_Istream(std::istream& Adata) : ISequentialInStream_Istream(Adata) { }
+
+  HRESULT Read(void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialInStreamCRC32_Istream() {}
+};
+
+
+class ISequentialOutStreamCRC32_Array : public ISequentialOutStream_Array, public ISequentialStreamCRC32
+{
+public:
+  ISequentialOutStreamCRC32_Array(char *Adata, unsigned Asize) : ISequentialOutStream_Array(Adata, Asize) { }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStreamCRC32_Array() {}
+};
+
+class ISequentialOutStreamCRC32_String : public ISequentialOutStream_String, public ISequentialStreamCRC32
+{
+public:
+  ISequentialOutStreamCRC32_String(std::string& Adata) : ISequentialOutStream_String(Adata) { }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStreamCRC32_String() {}
+};
+
+
+class ISequentialOutStreamCRC32_Ostream : public ISequentialOutStream_Ostream, public ISequentialStreamCRC32
+{
+public:
+  ISequentialOutStreamCRC32_Ostream(std::ostream& Adata) : ISequentialOutStream_Ostream(Adata) { }
+
+  HRESULT Write(const void *aData, UINT32 aSize, UINT32 *aProcessedSize);
+
+  virtual ~ISequentialOutStreamCRC32_Ostream() {}
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/inbyte.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "inbyte.h"
+
+namespace NStream{
+
+CInByte::CInByte(UINT32 aBufferSize):
+  m_BufferBase(0),
+  m_BufferSize(aBufferSize)
+{
+  m_BufferBase = new BYTE[m_BufferSize];
+}
+
+CInByte::~CInByte()
+{
+  delete []m_BufferBase;
+}
+
+void CInByte::Init(ISequentialInStream *aStream)
+{
+  m_Stream = aStream;
+  m_ProcessedSize = 0;
+  m_Buffer = m_BufferBase;
+  m_BufferLimit = m_Buffer;
+  m_StreamWasExhausted = false;
+}
+
+bool CInByte::ReadBlock()
+{
+  if (m_StreamWasExhausted)
+    return false;
+  m_ProcessedSize += (m_Buffer - m_BufferBase);
+  UINT32 aNumProcessedBytes;
+  HRESULT aResult = m_Stream->Read(m_BufferBase, m_BufferSize, &aNumProcessedBytes);
+  if (aResult != S_OK)
+    throw aResult;
+  m_Buffer = m_BufferBase;
+  m_BufferLimit = m_Buffer + aNumProcessedBytes;
+  m_StreamWasExhausted = (aNumProcessedBytes == 0);
+  return (!m_StreamWasExhausted);
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/inbyte.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,76 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __STREAM_INBYTE_H
+#define __STREAM_INBYTE_H
+
+#include "iiostrm.h"
+
+namespace NStream {
+
+class CInByte
+{
+  UINT64 m_ProcessedSize;
+  BYTE *m_BufferBase;
+  UINT32 m_BufferSize;
+  BYTE *m_Buffer;
+  BYTE *m_BufferLimit;
+  ISequentialInStream* m_Stream;
+  bool m_StreamWasExhausted;
+
+  bool ReadBlock();
+
+public:
+  CInByte(UINT32 aBufferSize = 0x100000);
+  ~CInByte();
+
+  void Init(ISequentialInStream *aStream);
+
+  bool ReadByte(BYTE &aByte)
+    {
+      if(m_Buffer >= m_BufferLimit)
+        if(!ReadBlock())
+          return false;
+      aByte = *m_Buffer++;
+      return true;
+    }
+  BYTE ReadByte()
+    {
+      if(m_Buffer >= m_BufferLimit)
+        if(!ReadBlock())
+          return 0x0;
+      return *m_Buffer++;
+    }
+  void ReadBytes(void *aData, UINT32 aSize, UINT32 &aProcessedSize)
+    {
+      for(aProcessedSize = 0; aProcessedSize < aSize; aProcessedSize++)
+        if (!ReadByte(((BYTE *)aData)[aProcessedSize]))
+          return;
+    }
+  bool ReadBytes(void *aData, UINT32 aSize)
+    {
+      UINT32 aProcessedSize;
+      ReadBytes(aData, aSize, aProcessedSize);
+      return (aProcessedSize == aSize);
+    }
+  UINT64 GetProcessedSize() const { return m_ProcessedSize + (m_Buffer - m_BufferBase); }
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/jma.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,550 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <sstream>
+#include "jma.h"
+using namespace std;
+
+#include "portable.h"
+#include "7z.h"
+#include "crc32.h"
+
+namespace JMA
+{
+  const char jma_magic[] = { 'J', 'M', 'A', 0, 'N' };
+  const unsigned int jma_header_length = 5;
+  const unsigned char jma_version = 1;
+  const unsigned int jma_version_length = 1;
+  const unsigned int jma_total_header_length = jma_header_length + jma_version_length + UINT_SIZE;
+
+  //Convert DOS/zip/JMA integer time to to time_t
+  time_t uint_to_time(unsigned short date, unsigned short time)
+  {
+    tm formatted_time;
+
+    formatted_time.tm_mday = date & 0x1F;
+    formatted_time.tm_mon  = ((date >> 5) & 0xF) - 1;
+    formatted_time.tm_year = ((date >> 9) & 0x7f) + 80;
+    formatted_time.tm_sec  = (time & 0x1F) * 2;
+    formatted_time.tm_min  = (time >> 5) & 0x3F;
+    formatted_time.tm_hour = (time >> 11) & 0x1F;
+
+    return(mktime(&formatted_time));
+  }
+
+
+  //Retreive the file block, what else?
+  void jma_open::retrieve_file_block() throw(jma_errors)
+  {
+    unsigned char uint_buffer[UINT_SIZE];
+    unsigned char ushort_buffer[USHORT_SIZE];
+
+    //File block size is the last UINT in the file
+    stream.seekg(-UINT_SIZE,ios::end);
+    stream.read((char *)uint_buffer, UINT_SIZE);
+    size_t file_block_size = charp_to_uint(uint_buffer);
+
+    //Currently at the end of the file, so that's the file size
+    size_t jma_file_size = stream.tellg();
+
+    //The file block can't be larger than the JMA file without it's header.
+    //This if can probably be improved
+    if (file_block_size >= jma_file_size-jma_total_header_length)
+    {
+      throw(JMA_BAD_FILE);
+    }
+
+    //Seek to before file block so we can read the file block
+    stream.seekg(-((int)file_block_size+UINT_SIZE),ios::end);
+
+    //This is needed if the file block is compressed
+    stringstream decompressed_file_block;
+    //Pointer to where to read file block from (file or decompressed buffer)
+    istream *file_block_stream;
+
+    //Setup file info buffer and byte to read with
+    jma_file_info file_info;
+    char byte;
+
+    stream.get(byte);
+    if (!byte) //If file block is compressed
+    {
+      //Compressed size isn't counting the byte we just read or the UINT for compressed size
+      size_t compressed_size = file_block_size - (1+UINT_SIZE);
+
+      //Read decompressed size / true file block size
+      stream.read((char *)uint_buffer, UINT_SIZE);
+      file_block_size = charp_to_uint(uint_buffer);
+
+      //Setup access methods for decompression
+      ISequentialInStream_Istream compressed_data(stream);
+      ISequentialOutStream_Ostream decompressed_data(decompressed_file_block);
+
+      //Decompress the data
+      if (!decompress_lzma_7z(compressed_data, compressed_size, decompressed_data, file_block_size))
+      {
+        throw(JMA_DECOMPRESS_FAILED);
+      }
+
+      //Go to beginning, setup pointer to buffer
+      decompressed_file_block.seekg(0, ios::beg);
+      file_block_stream = &decompressed_file_block;
+    }
+    else
+    {
+      stream.putback(byte); //Putback byte, byte is part of filename, not compressed indicator
+      file_block_stream = &stream;
+    }
+
+
+    //Minimum file name length is 2 bytes, a char and a null
+    //Minimum comment length is 1 byte, a null
+    //There are currently 2 UINTs and 2 USHORTs per file
+    while (file_block_size >= 2+1+UINT_SIZE*2+USHORT_SIZE*2) //This does allow for a gap, but that's okay
+    {
+      //First stored in the file block is the file name null terminated
+      file_info.name = "";
+
+      file_block_stream->get(byte);
+      while (byte)
+      {
+        file_info.name += byte;
+        file_block_stream->get(byte);
+      }
+
+      //There must be a file name or the file is bad
+      if (!file_info.name.length())
+      {
+        throw(JMA_BAD_FILE);
+      }
+
+      //Same trick as above for the comment
+      file_info.comment = "";
+
+      file_block_stream->get(byte);
+      while (byte)
+      {
+        file_info.comment += byte;
+        file_block_stream->get(byte);
+      }
+
+      //Next is a UINT representing the file's size
+      file_block_stream->read((char *)uint_buffer, UINT_SIZE);
+      file_info.size = charp_to_uint(uint_buffer);
+
+      //Followed by CRC32
+      file_block_stream->read((char *)uint_buffer, UINT_SIZE);
+      file_info.crc32 = charp_to_uint(uint_buffer);
+
+      //Special USHORT representation of file's date
+      file_block_stream->read((char *)ushort_buffer, USHORT_SIZE);
+      file_info.date = charp_to_ushort(ushort_buffer);
+
+      //Special USHORT representation of file's time
+      file_block_stream->read((char *)ushort_buffer, USHORT_SIZE);
+      file_info.time = charp_to_ushort(ushort_buffer);
+
+      file_info.buffer = 0; //Pointing to null till we decompress files
+
+      files.push_back(file_info); //Put file info into our structure
+
+      //Subtract size of the file info we just read
+      file_block_size -= file_info.name.length()+file_info.comment.length()+2+UINT_SIZE*2+USHORT_SIZE*2;
+    }
+  }
+
+  //Constructor for opening JMA files for reading
+  jma_open::jma_open(const char *compressed_file_name) throw (jma_errors)
+  {
+    decompressed_buffer = 0;
+    compressed_buffer = 0;
+
+    stream.open(compressed_file_name, ios::in | ios::binary);
+    if (!stream.is_open())
+    {
+      throw(JMA_NO_OPEN);
+    }
+
+    //Header is "JMA\0N"
+    unsigned char header[jma_header_length];
+    stream.read((char *)header, jma_header_length);
+    if (memcmp(jma_magic, header, jma_header_length))
+    {
+      throw(JMA_BAD_FILE);
+    }
+
+    //Not the cleanest code but logical
+    stream.read((char *)header, 5);
+    if (*header <= jma_version)
+    {
+      chunk_size = charp_to_uint(header+1); //Chunk size is a UINT that follows version #
+      retrieve_file_block();
+    }
+    else
+    {
+      throw(JMA_UNSUPPORTED_VERSION);
+    }
+  }
+
+  //Destructor only has to close the stream if neccesary
+  jma_open::~jma_open()
+  {
+    if (stream.is_open())
+    {
+      stream.close();
+    }
+  }
+
+  //Return a vector containing useful info about the files in the JMA
+  vector<jma_public_file_info> jma_open::get_files_info()
+  {
+    vector<jma_public_file_info> file_info_vector;
+    jma_public_file_info file_info;
+
+    for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
+    {
+      file_info.name = i->name;
+      file_info.comment = i->comment;
+      file_info.size = i->size;
+      file_info.datetime = uint_to_time(i->date, i->time);
+      file_info.crc32 = i->crc32;
+      file_info_vector.push_back(file_info);
+    }
+
+    return(file_info_vector);
+  }
+
+  //Skip forward a given number of chunks
+  void jma_open::chunk_seek(unsigned int chunk_num) throw(jma_errors)
+  {
+    //Check the stream is open
+    if (!stream.is_open())
+    {
+      throw(JMA_NO_OPEN);
+    }
+
+    //Clear possible errors so the seek will work
+    stream.clear();
+
+    //Move forward over header
+    stream.seekg(jma_total_header_length, ios::beg);
+
+    unsigned char int4_buffer[UINT_SIZE];
+
+    while (chunk_num--)
+    {
+      //Read in size of chunk
+      stream.read((char *)int4_buffer, UINT_SIZE);
+
+      //Skip chunk plus it's CRC32
+      stream.seekg(charp_to_uint(int4_buffer)+UINT_SIZE, ios::cur);
+    }
+  }
+
+  //Return a vector of pointers to each file in the JMA, the buffer to hold all the files
+  //must be initilized outside.
+  vector<unsigned char *> jma_open::get_all_files(unsigned char *buffer) throw(jma_errors)
+  {
+    //If there's no stream we can't read from it, so exit
+    if (!stream.is_open())
+    {
+      throw(JMA_NO_OPEN);
+    }
+
+    //Seek to the first chunk
+    chunk_seek(0);
+
+    //Set the buffer that decompressed data goes to
+    decompressed_buffer = buffer;
+
+    //If the JMA is not solid
+    if (chunk_size)
+    {
+      unsigned char int4_buffer[UINT_SIZE];
+      size_t size = get_total_size(files);
+
+      //For each chunk in the file...
+      for (size_t remaining_size = size; remaining_size; remaining_size -= chunk_size)
+      {
+        //Read the compressed size
+        stream.read((char *)int4_buffer, UINT_SIZE);
+        size_t compressed_size = charp_to_uint(int4_buffer);
+
+        //Allocate memory of the correct size to hold the compressed data in the JMA
+        //Throw error on failure as that is unrecoverable from
+        try
+        {
+          compressed_buffer = new unsigned char[compressed_size];
+        }
+        catch (bad_alloc xa)
+        {
+          throw(JMA_NO_MEM_ALLOC);
+        }
+
+        //Read all the compressed data in
+        stream.read((char *)compressed_buffer, compressed_size);
+
+        //Read the expected CRC of compressed data from the file
+        stream.read((char *)int4_buffer, UINT_SIZE);
+
+        //If it doesn't match, throw error and cleanup memory
+        if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer))
+        {
+          delete[] compressed_buffer;
+          throw(JMA_BAD_FILE);
+        }
+
+        //Decompress the data, cleanup memory on failure
+        if (!decompress_lzma_7z(compressed_buffer, compressed_size,
+                                decompressed_buffer+size-remaining_size,
+                                (remaining_size > chunk_size) ? chunk_size : remaining_size))
+        {
+          delete[] compressed_buffer;
+          throw(JMA_DECOMPRESS_FAILED);
+        }
+        delete[] compressed_buffer;
+
+        if (remaining_size <= chunk_size) //If we just decompressed the remainder
+        {
+          break;
+        }
+      }
+    }
+    else //Solidly compressed JMA
+    {
+      unsigned char int4_buffer[UINT_SIZE];
+
+      //Read the size of the compressed data
+      stream.read((char *)int4_buffer, UINT_SIZE);
+      size_t compressed_size = charp_to_uint(int4_buffer);
+
+      //Get decompressed size
+      size_t size = get_total_size(files);
+
+      //Setup access methods for decompression
+      ISequentialInStream_Istream compressed_data(stream);
+      ISequentialOutStream_Array decompressed_data(reinterpret_cast<char*>(decompressed_buffer), size);
+
+      //Decompress the data
+      if (!decompress_lzma_7z(compressed_data, compressed_size, decompressed_data, size))
+      {
+        throw(JMA_DECOMPRESS_FAILED);
+      }
+
+      /*
+      //Allocate memory of the right size to hold the compressed data in the JMA
+      try
+      {
+        compressed_buffer = new unsigned char[compressed_size];
+      }
+      catch (bad_alloc xa)
+      {
+        throw(JMA_NO_MEM_ALLOC);
+      }
+
+      //Copy the compressed data into memory
+      stream.read((char *)compressed_buffer, compressed_size);
+      size_t size = get_total_size(files);
+
+      //Read the CRC of the compressed data
+      stream.read((char *)int4_buffer, UINT_SIZE);
+
+      //If it doesn't match, complain
+      if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer))
+      {
+        delete[] compressed_buffer;
+        throw(JMA_BAD_FILE);
+      }
+
+      //Decompress the data
+      if (!decompress_lzma_7z(compressed_buffer, compressed_size, decompressed_buffer, size))
+      {
+        delete[] compressed_buffer;
+        throw(JMA_DECOMPRESS_FAILED);
+      }
+      delete[] compressed_buffer;
+      */
+    }
+
+    vector<unsigned char *> file_pointers;
+    size_t size = 0;
+
+    //For each file, add it's pointer to the vector, size is pointer offset in the buffer
+    for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
+    {
+      i->buffer = decompressed_buffer+size;
+      file_pointers.push_back(decompressed_buffer+size);
+      size += i->size;
+    }
+
+    //Return the vector of pointers
+    return(file_pointers);
+  }
+
+  //Extracts the file with a given name found in the archive to the given buffer
+  void jma_open::extract_file(string& name, unsigned char *buffer) throw(jma_errors)
+  {
+    if (!stream.is_open())
+    {
+      throw(JMA_NO_OPEN);
+    }
+
+    size_t size_to_skip = 0;
+    size_t our_file_size = 0;
+
+    //Search through the vector of file information
+    for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++)
+    {
+      if (i->name == name)
+      {
+        //Set the variable so we can tell we found it
+        our_file_size = i->size;
+        break;
+      }
+
+      //Keep a running total of size
+      size_to_skip += i->size;
+    }
+
+    if (!our_file_size) //File with the specified name was not found in the archive
+    {
+      throw(JMA_FILE_NOT_FOUND);
+    }
+
+    //If the JMA only contains one file, we can skip a lot of overhead
+    if (files.size() == 1)
+    {
+      get_all_files(buffer);
+      return;
+    }
+
+    if (chunk_size) //we are using non-solid archive..
+    {
+      unsigned int chunks_to_skip = size_to_skip / chunk_size;
+
+      //skip over requisite number of chunks
+      chunk_seek(chunks_to_skip);
+
+      //Allocate memory for compressed and decompressed data
+      unsigned char *comp_buffer = 0, *decomp_buffer = 0;
+      try
+      {
+        //Compressed data size is <= non compressed size
+        unsigned char *combined_buffer = new unsigned char[chunk_size*2];
+        comp_buffer = combined_buffer;
+        decomp_buffer = combined_buffer+chunk_size;
+      }
+      catch (bad_alloc xa)
+      {
+        throw(JMA_NO_MEM_ALLOC);
+      }
+
+      size_t first_chunk_offset = size_to_skip % chunk_size;
+      unsigned char int4_buffer[UINT_SIZE];
+      for (size_t i = 0; i < our_file_size;)
+      {
+        //Get size
+        stream.read((char *)int4_buffer, UINT_SIZE);
+        size_t compressed_size = charp_to_uint(int4_buffer);
+
+        //Read all the compressed data in
+        stream.read((char *)comp_buffer, compressed_size);
+
+        //Read the CRC of the compressed data
+        stream.read((char *)int4_buffer, UINT_SIZE);
+
+        //If it doesn't match, complain
+        if (CRC32lib::CRC32(comp_buffer, compressed_size) != charp_to_uint(int4_buffer))
+        {
+          delete[] comp_buffer;
+          throw(JMA_BAD_FILE);
+        }
+
+        //Decompress chunk
+        if (!decompress_lzma_7z(comp_buffer, compressed_size, decomp_buffer, chunk_size))
+        {
+          delete[] comp_buffer;
+          throw(JMA_DECOMPRESS_FAILED);
+        }
+
+        size_t copy_amount = our_file_size-i > chunk_size-first_chunk_offset ? chunk_size-first_chunk_offset : our_file_size-i;
+
+        memcpy(buffer+i, decomp_buffer+first_chunk_offset, copy_amount);
+        first_chunk_offset = 0; //Set to zero since this is only for the first iteration
+        i += copy_amount;
+      }
+      delete[] comp_buffer;
+    }
+    else //Solid JMA
+    {
+      unsigned char *decomp_buffer = 0;
+      try
+      {
+        decomp_buffer = new unsigned char[get_total_size(files)];
+      }
+      catch (bad_alloc xa)
+      {
+        throw(JMA_NO_MEM_ALLOC);
+      }
+
+      get_all_files(decomp_buffer);
+
+      memcpy(buffer, decomp_buffer+size_to_skip, our_file_size);
+
+      delete[] decomp_buffer;
+    }
+  }
+
+  bool jma_open::is_solid()
+  {
+    return(chunk_size ? false : true);
+  }
+
+  const char *jma_error_text(jma_errors error)
+  {
+    switch (error)
+    {
+      case JMA_NO_CREATE:
+        return("JMA could not be created");
+
+      case JMA_NO_MEM_ALLOC:
+        return("Memory for JMA could be allocated");
+
+      case JMA_NO_OPEN:
+        return("JMA could not be opened");
+
+      case JMA_BAD_FILE:
+        return("Invalid/Corrupt JMA");
+
+      case JMA_UNSUPPORTED_VERSION:
+        return("JMA version not supported");
+
+      case JMA_COMPRESS_FAILED:
+        return("JMA compression failed");
+
+      case JMA_DECOMPRESS_FAILED:
+        return("JMA decompression failed");
+
+      case JMA_FILE_NOT_FOUND:
+        return("File not found in JMA");
+    }
+    return("Unknown error");
+  }
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/jma.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,88 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef JMA_H
+#define JMA_H
+
+#include <string>
+#include <fstream>
+#include <vector>
+#include <time.h>
+
+namespace JMA
+{
+  enum jma_errors { JMA_NO_CREATE, JMA_NO_MEM_ALLOC, JMA_NO_OPEN, JMA_BAD_FILE,
+                    JMA_UNSUPPORTED_VERSION, JMA_COMPRESS_FAILED, JMA_DECOMPRESS_FAILED,
+                    JMA_FILE_NOT_FOUND };
+
+  struct jma_file_info_base
+  {
+    std::string name;
+    std::string comment;
+    size_t size;
+    unsigned int crc32;
+  };
+
+  struct jma_public_file_info : jma_file_info_base
+  {
+    time_t datetime;
+  };
+
+  struct jma_file_info : jma_file_info_base
+  {
+    unsigned short date;
+    unsigned short time;
+    const unsigned char *buffer;
+  };
+
+  template<class jma_file_type>
+  inline size_t get_total_size(std::vector<jma_file_type>& files)
+  {
+    size_t size = 0;
+    for (typename std::vector<jma_file_type>::iterator i = files.begin(); i != files.end(); i++)
+    {
+      size += i->size; //We do have a problem if this wraps around
+    }
+
+    return(size);
+  }
+
+  class jma_open
+  {
+    public:
+    jma_open(const char *) throw(jma_errors);
+    ~jma_open();
+
+    std::vector<jma_public_file_info> get_files_info();
+    std::vector<unsigned char *> get_all_files(unsigned char *) throw(jma_errors);
+    void extract_file(std::string& name, unsigned char *) throw(jma_errors);
+    bool is_solid();
+
+    private:
+    std::ifstream stream;
+    std::vector<jma_file_info> files;
+    size_t chunk_size;
+    unsigned char *decompressed_buffer;
+    unsigned char *compressed_buffer;
+
+    void chunk_seek(unsigned int) throw(jma_errors);
+    void retrieve_file_block() throw(jma_errors);
+  };
+
+  const char *jma_error_text(jma_errors);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/lencoder.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,93 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __LENCODER_H
+#define __LENCODER_H
+
+#include "btreecd.h"
+
+namespace NLength {
+
+const UINT32 kNumPosStatesBitsMax = 4;
+const int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+
+const int kNumMoveBits = 5;
+
+const int kNumLenBits = 3;
+const int kNumLowSymbols = 1 << kNumLenBits;
+const int kNumMidBits = 3;
+const int kNumMidSymbols = 1 << kNumMidBits;
+
+const int kNumHighBits = 8;
+
+const int kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+const int kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CDecoder
+{
+  CMyBitDecoder<kNumMoveBits> m_Choice;
+  CBitTreeDecoder<kNumMoveBits, kNumLenBits>  m_LowCoder[kNumPosStatesMax];
+  CMyBitDecoder<kNumMoveBits> m_Choice2;
+  CBitTreeDecoder<kNumMoveBits, kNumMidBits>  m_MidCoder[kNumPosStatesMax];
+  CBitTreeDecoder<kNumMoveBits, kNumHighBits> m_HighCoder;
+  UINT32 m_NumPosStates;
+public:
+  void Create(UINT32 aNumPosStates)
+    { m_NumPosStates = aNumPosStates; }
+  void Init()
+  {
+    m_Choice.Init();
+    for (UINT32 aPosState = 0; aPosState < m_NumPosStates; aPosState++)
+    {
+      m_LowCoder[aPosState].Init();
+      m_MidCoder[aPosState].Init();
+    }
+    m_Choice2.Init();
+    m_HighCoder.Init();
+  }
+  UINT32 Decode(CMyRangeDecoder *aRangeDecoder, UINT32 aPosState)
+  {
+    if(m_Choice.Decode(aRangeDecoder) == 0)
+      return m_LowCoder[aPosState].Decode(aRangeDecoder);
+    else
+    {
+      UINT32 aSymbol = kNumLowSymbols;
+      if(m_Choice2.Decode(aRangeDecoder) == 0)
+        aSymbol += m_MidCoder[aPosState].Decode(aRangeDecoder);
+      else
+      {
+        aSymbol += kNumMidSymbols;
+        aSymbol += m_HighCoder.Decode(aRangeDecoder);
+      }
+      return aSymbol;
+    }
+  }
+
+};
+
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/litcoder.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,122 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __LITERALCODER_H
+#define __LITERALCODER_H
+
+#include "aribitcd.h"
+#include "rcdefs.h"
+
+namespace NLiteral {
+
+const int kNumMoveBits = 5;
+
+class CDecoder2
+{
+  CMyBitDecoder<kNumMoveBits> m_Decoders[3][1 << 8];
+public:
+  void Init()
+  {
+    for (int i = 0; i < 3; i++)
+      for (int j = 1; j < (1 << 8); j++)
+        m_Decoders[i][j].Init();
+  }
+
+  BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder)
+  {
+    UINT32 aSymbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      // aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder);
+      RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol)
+    }
+    while (aSymbol < 0x100);
+    RC_FLUSH_VAR
+    return aSymbol;
+  }
+
+  BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, BYTE aMatchByte)
+  {
+    UINT32 aSymbol = 1;
+    RC_INIT_VAR
+    do
+    {
+      UINT32 aMatchBit = (aMatchByte >> 7) & 1;
+      aMatchByte <<= 1;
+      // UINT32 aBit = m_Decoders[1 + aMatchBit][aSymbol].Decode(aRangeDecoder);
+      // aSymbol = (aSymbol << 1) | aBit;
+      UINT32 aBit;
+      RC_GETBIT2(kNumMoveBits, m_Decoders[1 + aMatchBit][aSymbol].m_Probability, aSymbol,
+          aBit = 0, aBit = 1)
+      if (aMatchBit != aBit)
+      {
+        while (aSymbol < 0x100)
+        {
+          // aSymbol = (aSymbol << 1) | m_Decoders[0][aSymbol].Decode(aRangeDecoder);
+          RC_GETBIT(kNumMoveBits, m_Decoders[0][aSymbol].m_Probability, aSymbol)
+        }
+        break;
+      }
+    }
+    while (aSymbol < 0x100);
+    RC_FLUSH_VAR
+    return aSymbol;
+  }
+};
+
+class CDecoder
+{
+  CDecoder2 *m_Coders;
+  UINT32 m_NumPrevBits;
+  UINT32 m_NumPosBits;
+  UINT32 m_PosMask;
+public:
+  CDecoder(): m_Coders(0) {}
+  ~CDecoder()  { Free(); }
+  void Free()
+  {
+    delete []m_Coders;
+    m_Coders = 0;
+  }
+  void Create(UINT32 aNumPosBits, UINT32 aNumPrevBits)
+  {
+    Free();
+    m_NumPosBits = aNumPosBits;
+    m_PosMask = (1 << aNumPosBits) - 1;
+    m_NumPrevBits = aNumPrevBits;
+    UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits);
+    m_Coders = new CDecoder2[aNumStates];
+  }
+  void Init()
+  {
+    UINT32 aNumStates = 1 << (m_NumPrevBits + m_NumPosBits);
+    for (UINT32 i = 0; i < aNumStates; i++)
+      m_Coders[i].Init();
+  }
+  UINT32 GetState(UINT32 aPos, BYTE aPrevByte) const
+    { return ((aPos & m_PosMask) << m_NumPrevBits) + (aPrevByte >> (8 - m_NumPrevBits)); }
+  BYTE DecodeNormal(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte)
+    { return m_Coders[GetState(aPos, aPrevByte)].DecodeNormal(aRangeDecoder); }
+  BYTE DecodeWithMatchByte(CMyRangeDecoder *aRangeDecoder, UINT32 aPos, BYTE aPrevByte, BYTE aMatchByte)
+    { return m_Coders[GetState(aPos, aPrevByte)].DecodeWithMatchByte(aRangeDecoder, aMatchByte); }
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/lzma.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "lzma.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+UINT32 kDistStart[kDistTableSizeMax];
+
+static class CConstInit
+{
+public:
+  CConstInit()
+  {
+    UINT32 aStartValue = 0;
+    int i;
+    for (i = 0; i < kDistTableSizeMax; i++)
+    {
+      kDistStart[i] = aStartValue;
+      aStartValue += (1 << kDistDirectBits[i]);
+    }
+  }
+} g_ConstInit;
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/lzma.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,124 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "lencoder.h"
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UINT32 kNumRepDistances = 4;
+
+const BYTE kNumStates = 12;
+
+const BYTE kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
+const BYTE kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const BYTE kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const BYTE kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+  BYTE m_Index;
+  void Init()
+    { m_Index = 0; }
+  void UpdateChar()
+    { m_Index = kLiteralNextStates[m_Index]; }
+  void UpdateMatch()
+    { m_Index = kMatchNextStates[m_Index]; }
+  void UpdateRep()
+    { m_Index = kRepNextStates[m_Index]; }
+  void UpdateShortRep()
+    { m_Index = kShortRepNextStates[m_Index]; }
+};
+
+class CBaseCoder
+{
+protected:
+  CState m_State;
+  BYTE m_PreviousByte;
+  bool m_PeviousIsMatch;
+  UINT32 m_RepDistances[kNumRepDistances];
+  void Init()
+  {
+    m_State.Init();
+    m_PreviousByte = 0;
+    m_PeviousIsMatch = false;
+    for(UINT32 i = 0 ; i < kNumRepDistances; i++)
+      m_RepDistances[i] = 0;
+  }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMax = 28;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+extern UINT32 kDistStart[kDistTableSizeMax];
+const BYTE kDistDirectBits[kDistTableSizeMax] =
+{
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
+  10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
+  20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26
+};
+
+const UINT32 kNumLenToPosStates = 4;
+inline UINT32 GetLenToPosState(UINT32 aLen)
+{
+  aLen -= 2;
+  if (aLen < kNumLenToPosStates)
+    return aLen;
+  return kNumLenToPosStates - 1;
+}
+
+const int kMatchMinLen = 2;
+
+const int kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const int kAlignTableSize = 1 << kNumAlignBits;
+const UINT32 kAlignMask = (kAlignTableSize - 1);
+
+const int kStartPosModelIndex = 4;
+const int kEndPosModelIndex = 14;
+const int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+
+const int kMainChoiceLiteralIndex = 0;
+const int kMainChoiceMatchIndex = 1;
+
+const int kMatchChoiceDistanceIndex= 0;
+const int kMatchChoiceRepetitionIndex = 1;
+
+const int kNumMoveBitsForMainChoice = 5;
+const int kNumMoveBitsForPosCoders = 5;
+
+const int kNumMoveBitsForAlignCoders = 5;
+
+const int kNumMoveBitsForPosSlotCoder = 5;
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/lzmadec.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,298 @@
+/*
+Copyright (C) 2005-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "portable.h"
+#include "lzmadec.h"
+
+#define RETURN_E_OUTOFMEMORY_IF_FALSE(x) { if (!(x)) return E_OUTOFMEMORY; }
+
+namespace NCompress {
+namespace NLZMA {
+
+HRESULT CDecoder::SetDictionarySize(UINT32 aDictionarySize)
+{
+  if (aDictionarySize > (1 << kDicLogSizeMax))
+    return E_INVALIDARG;
+
+  UINT32 aWindowReservSize = MyMax(aDictionarySize, UINT32(1 << 21));
+
+  if (m_DictionarySize != aDictionarySize)
+  {
+    m_OutWindowStream.Create(aDictionarySize, kMatchMaxLen, aWindowReservSize);
+    m_DictionarySize = aDictionarySize;
+  }
+  return S_OK;
+}
+
+HRESULT CDecoder::SetLiteralProperties(
+    UINT32 aLiteralPosStateBits, UINT32 aLiteralContextBits)
+{
+  if (aLiteralPosStateBits > 8)
+    return E_INVALIDARG;
+  if (aLiteralContextBits > 8)
+    return E_INVALIDARG;
+  m_LiteralDecoder.Create(aLiteralPosStateBits, aLiteralContextBits);
+  return S_OK;
+}
+
+HRESULT CDecoder::SetPosBitsProperties(UINT32 aNumPosStateBits)
+{
+  if (aNumPosStateBits > NLength::kNumPosStatesBitsMax)
+    return E_INVALIDARG;
+  UINT32 aNumPosStates = 1 << aNumPosStateBits;
+  m_LenDecoder.Create(aNumPosStates);
+  m_RepMatchLenDecoder.Create(aNumPosStates);
+  m_PosStateMask = aNumPosStates - 1;
+  return S_OK;
+}
+
+CDecoder::CDecoder():
+  m_DictionarySize((UINT32)-1)
+{
+  Create();
+}
+
+HRESULT CDecoder::Create()
+{
+  for(int i = 0; i < kNumPosModels; i++)
+  {
+    RETURN_E_OUTOFMEMORY_IF_FALSE(
+        m_PosDecoders[i].Create(kDistDirectBits[kStartPosModelIndex + i]));
+  }
+  return S_OK;
+}
+
+
+HRESULT CDecoder::Init(ISequentialInStream *anInStream,
+    ISequentialOutStream *anOutStream)
+{
+  m_RangeDecoder.Init(anInStream);
+
+  m_OutWindowStream.Init(anOutStream);
+
+  int i;
+  for(i = 0; i < kNumStates; i++)
+  {
+    for (UINT32 j = 0; j <= m_PosStateMask; j++)
+    {
+      m_MainChoiceDecoders[i][j].Init();
+      m_MatchRepShortChoiceDecoders[i][j].Init();
+    }
+    m_MatchChoiceDecoders[i].Init();
+    m_MatchRepChoiceDecoders[i].Init();
+    m_MatchRep1ChoiceDecoders[i].Init();
+    m_MatchRep2ChoiceDecoders[i].Init();
+  }
+
+  m_LiteralDecoder.Init();
+
+  // m_RepMatchLenDecoder.Init();
+
+  for (i = 0; (UINT32) i < kNumLenToPosStates; i++)
+    m_PosSlotDecoder[i].Init();
+
+  for(i = 0; i < kNumPosModels; i++)
+    m_PosDecoders[i].Init();
+
+  m_LenDecoder.Init();
+  m_RepMatchLenDecoder.Init();
+
+  m_PosAlignDecoder.Init();
+  return S_OK;
+
+}
+
+HRESULT CDecoder::CodeReal(ISequentialInStream *anInStream,
+    ISequentialOutStream *anOutStream,
+    const UINT64 *anInSize, const UINT64 *anOutSize)
+{
+  if (anOutSize == NULL)
+    return E_INVALIDARG;
+
+  Init(anInStream, anOutStream);
+
+  CState aState;
+  aState.Init();
+  bool aPeviousIsMatch = false;
+  BYTE aPreviousByte = 0;
+  UINT32 aRepDistances[kNumRepDistances];
+  for(UINT32 i = 0 ; i < kNumRepDistances; i++)
+    aRepDistances[i] = 0;
+
+  UINT64 aNowPos64 = 0;
+  UINT64 aSize = *anOutSize;
+  while(aNowPos64 < aSize)
+  {
+    UINT64 aNext = MyMin(aNowPos64 + (1 << 18), aSize);
+    while(aNowPos64 < aNext)
+    {
+      UINT32 aPosState = UINT32(aNowPos64) & m_PosStateMask;
+      if (m_MainChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == (UINT32) kMainChoiceLiteralIndex)
+      {
+        // aCounts[0]++;
+        aState.UpdateChar();
+        if(aPeviousIsMatch)
+        {
+          BYTE aMatchByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1);
+          aPreviousByte = m_LiteralDecoder.DecodeWithMatchByte(&m_RangeDecoder,
+              UINT32(aNowPos64), aPreviousByte, aMatchByte);
+          aPeviousIsMatch = false;
+        }
+        else
+          aPreviousByte = m_LiteralDecoder.DecodeNormal(&m_RangeDecoder,
+              UINT32(aNowPos64), aPreviousByte);
+        m_OutWindowStream.PutOneByte(aPreviousByte);
+        aNowPos64++;
+      }
+      else
+      {
+        aPeviousIsMatch = true;
+        UINT32 aDistance, aLen;
+        if(m_MatchChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) ==
+            (UINT32) kMatchChoiceRepetitionIndex)
+        {
+          if(m_MatchRepChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
+          {
+            if(m_MatchRepShortChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == 0)
+            {
+              aState.UpdateShortRep();
+              aPreviousByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1);
+              m_OutWindowStream.PutOneByte(aPreviousByte);
+              aNowPos64++;
+              // aCounts[3 + 4]++;
+              continue;
+            }
+            // aCounts[3 + 0]++;
+            aDistance = aRepDistances[0];
+          }
+          else
+          {
+            if(m_MatchRep1ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
+            {
+              aDistance = aRepDistances[1];
+              aRepDistances[1] = aRepDistances[0];
+              // aCounts[3 + 1]++;
+            }
+            else
+            {
+              if (m_MatchRep2ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0)
+              {
+                // aCounts[3 + 2]++;
+                aDistance = aRepDistances[2];
+              }
+              else
+              {
+                // aCounts[3 + 3]++;
+                aDistance = aRepDistances[3];
+                aRepDistances[3] = aRepDistances[2];
+              }
+              aRepDistances[2] = aRepDistances[1];
+              aRepDistances[1] = aRepDistances[0];
+            }
+            aRepDistances[0] = aDistance;
+          }
+          aLen = m_RepMatchLenDecoder.Decode(&m_RangeDecoder, aPosState) + kMatchMinLen;
+          // aCounts[aLen]++;
+          aState.UpdateRep();
+        }
+        else
+        {
+          aLen = kMatchMinLen + m_LenDecoder.Decode(&m_RangeDecoder, aPosState);
+          aState.UpdateMatch();
+          UINT32 aPosSlot = m_PosSlotDecoder[GetLenToPosState(aLen)].Decode(&m_RangeDecoder);
+          // aCounts[aPosSlot]++;
+          if (aPosSlot >= (UINT32) kStartPosModelIndex)
+          {
+            aDistance = kDistStart[aPosSlot];
+            if (aPosSlot < (UINT32) kEndPosModelIndex)
+              aDistance += m_PosDecoders[aPosSlot - kStartPosModelIndex].Decode(&m_RangeDecoder);
+            else
+            {
+              aDistance += (m_RangeDecoder.DecodeDirectBits(kDistDirectBits[aPosSlot] -
+                  kNumAlignBits) << kNumAlignBits);
+              aDistance += m_PosAlignDecoder.Decode(&m_RangeDecoder);
+            }
+          }
+          else
+            aDistance = aPosSlot;
+
+
+          aRepDistances[3] = aRepDistances[2];
+          aRepDistances[2] = aRepDistances[1];
+          aRepDistances[1] = aRepDistances[0];
+
+          aRepDistances[0] = aDistance;
+          // UpdateStat(aLen, aPosSlot);
+        }
+        if (aDistance >= aNowPos64)
+          throw E_INVALIDDATA;
+        m_OutWindowStream.CopyBackBlock(aDistance, aLen);
+        aNowPos64 += aLen;
+        aPreviousByte = m_OutWindowStream.GetOneByte(0 - 1);
+      }
+    }
+  }
+  return Flush();
+}
+
+HRESULT CDecoder::Code(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize)
+{
+  try {
+     return CodeReal(anInStream, anOutStream, anInSize, anOutSize);
+  } catch (HRESULT& e) {
+     return e;
+  } catch (...) {
+     return E_FAIL;
+  }
+}
+
+HRESULT CDecoder::ReadCoderProperties(ISequentialInStream *anInStream)
+{
+  UINT32 aNumPosStateBits;
+  UINT32 aLiteralPosStateBits;
+  UINT32 aLiteralContextBits;
+  UINT32 aDictionarySize;
+
+   UINT32 aProcessesedSize;
+
+  BYTE aByte;
+  RETURN_IF_NOT_S_OK(anInStream->Read(&aByte, sizeof(aByte), &aProcessesedSize));
+  if (aProcessesedSize != sizeof(aByte))
+    return E_INVALIDARG;
+
+  aLiteralContextBits = aByte % 9;
+  BYTE aRemainder = aByte / 9;
+  aLiteralPosStateBits = aRemainder % 5;
+  aNumPosStateBits = aRemainder / 5;
+
+  UINT8 uint_buffer[UINT_SIZE];
+  RETURN_IF_NOT_S_OK(anInStream->Read(uint_buffer, sizeof(aDictionarySize), &aProcessesedSize));
+  aDictionarySize = charp_to_uint(uint_buffer);
+
+  if (aProcessesedSize != sizeof(aDictionarySize))
+    return E_INVALIDARG;
+
+  RETURN_IF_NOT_S_OK(SetDictionarySize(aDictionarySize));
+  RETURN_IF_NOT_S_OK(SetLiteralProperties(aLiteralPosStateBits, aLiteralContextBits));
+  RETURN_IF_NOT_S_OK(SetPosBitsProperties(aNumPosStateBits));
+
+  return S_OK;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/lzmadec.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,82 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __LZARITHMETIC_DECODER_H
+#define __LZARITHMETIC_DECODER_H
+
+#include "winout.h"
+#include "lzma.h"
+#include "lencoder.h"
+#include "litcoder.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef CMyBitDecoder<kNumMoveBitsForMainChoice> CMyBitDecoder2;
+
+class CDecoder
+{
+  NStream::NWindow::COut m_OutWindowStream;
+  CMyRangeDecoder m_RangeDecoder;
+
+  CMyBitDecoder2 m_MainChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
+  CMyBitDecoder2 m_MatchChoiceDecoders[kNumStates];
+  CMyBitDecoder2 m_MatchRepChoiceDecoders[kNumStates];
+  CMyBitDecoder2 m_MatchRep1ChoiceDecoders[kNumStates];
+  CMyBitDecoder2 m_MatchRep2ChoiceDecoders[kNumStates];
+  CMyBitDecoder2 m_MatchRepShortChoiceDecoders[kNumStates][NLength::kNumPosStatesMax];
+
+  CBitTreeDecoder<kNumMoveBitsForPosSlotCoder, kNumPosSlotBits> m_PosSlotDecoder[kNumLenToPosStates];
+
+  CReverseBitTreeDecoder2<kNumMoveBitsForPosCoders> m_PosDecoders[kNumPosModels];
+  CReverseBitTreeDecoder<kNumMoveBitsForAlignCoders, kNumAlignBits> m_PosAlignDecoder;
+  // CBitTreeDecoder2<kNumMoveBitsForPosCoders> m_PosDecoders[kNumPosModels];
+  // CBitTreeDecoder<kNumMoveBitsForAlignCoders, kNumAlignBits> m_PosAlignDecoder;
+
+  NLength::CDecoder m_LenDecoder;
+  NLength::CDecoder m_RepMatchLenDecoder;
+
+  NLiteral::CDecoder m_LiteralDecoder;
+
+  UINT32 m_DictionarySize;
+
+  UINT32 m_PosStateMask;
+
+  HRESULT Create();
+
+  HRESULT Init(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream);
+
+  HRESULT Flush() {  return m_OutWindowStream.Flush(); }
+
+  HRESULT CodeReal(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize);
+
+public:
+
+  CDecoder();
+
+  HRESULT Code(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *anInSize, const UINT64 *anOutSize);
+  HRESULT ReadCoderProperties(ISequentialInStream *anInStream);
+
+  HRESULT SetDictionarySize(UINT32 aDictionarySize);
+  HRESULT SetLiteralProperties(UINT32 aLiteralPosStateBits, UINT32 aLiteralContextBits);
+  HRESULT SetPosBitsProperties(UINT32 aNumPosStateBits);
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/portable.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,83 @@
+/*
+Copyright (C) 2004-2006 NSRT Team ( http://nsrt.edgeemu.com )
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __PORTABLE_H
+#define __PORTABLE_H
+
+#include <string.h>
+
+typedef signed char INT8;
+typedef unsigned char UINT8;
+typedef short INT16;
+typedef unsigned short UINT16;
+typedef long INT32;
+typedef unsigned long UINT32;
+typedef long long INT64;
+typedef unsigned long long UINT64;
+
+typedef UINT8 BYTE;
+typedef UINT16 WORD;
+typedef UINT32 DWORD;
+
+typedef unsigned UINT_PTR;
+
+typedef int BOOL;
+#define FALSE 0
+#define TRUE 1
+
+#define HRESULT int
+#define S_OK 0
+#define E_INVALIDARG -1
+#define E_OUTOFMEMORY -2
+#define E_FAIL -3
+#define E_INTERNAL_ERROR -4
+#define E_INVALIDDATA -5
+
+template <class T> inline T MyMin(T a, T b) {
+	return a < b ? a : b;
+}
+
+template <class T> inline T MyMax(T a, T b) {
+	return a > b ? a : b;
+}
+
+#define RETURN_IF_NOT_S_OK(x) { HRESULT __aResult_ = (x); if(__aResult_ != S_OK) return __aResult_; }
+
+
+#define UINT_SIZE (4)
+#define USHORT_SIZE (2)
+
+//Convert an array of 4 bytes back into an integer
+inline unsigned int charp_to_uint(const unsigned char buffer[UINT_SIZE])
+{
+  unsigned int num = (unsigned int)buffer[3];
+  num |= ((unsigned int)buffer[2]) << 8;
+  num |= ((unsigned int)buffer[1]) << 16;
+  num |= ((unsigned int)buffer[0]) << 24;
+  return(num);
+}
+
+//Convert an array of 2 bytes back into a short integer
+inline unsigned short charp_to_ushort(const unsigned char buffer[USHORT_SIZE])
+{
+  unsigned short num = (unsigned short)buffer[1];
+  num |= ((unsigned short)buffer[0]) << 8;
+  return(num);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/rcdefs.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __RCDEFS_H
+#define __RCDEFS_H
+
+#include "aribitcd.h"
+#include "ariconst.h"
+
+#define RC_INIT_VAR                            \
+  UINT32 aRange = aRangeDecoder->m_Range;      \
+  UINT32 aCode = aRangeDecoder->m_Code;
+
+#define RC_FLUSH_VAR                          \
+  aRangeDecoder->m_Range = aRange;            \
+  aRangeDecoder->m_Code = aCode;
+
+#define RC_NORMALIZE                                    \
+    if (aRange < NCompression::NArithmetic::kTopValue)               \
+    {                                                              \
+      aCode = (aCode << 8) | aRangeDecoder->m_Stream.ReadByte();   \
+      aRange <<= 8; }
+
+#define RC_GETBIT2(aNumMoveBits, aProb, aModelIndex, Action0, Action1)                        \
+    {UINT32 aNewBound = (aRange >> NCompression::NArithmetic::kNumBitModelTotalBits) * aProb; \
+    if (aCode < aNewBound)                               \
+    {                                                             \
+      Action0;                                                    \
+      aRange = aNewBound;                                         \
+      aProb += (NCompression::NArithmetic::kBitModelTotal - aProb) >> aNumMoveBits;          \
+      aModelIndex <<= 1;                                          \
+    }                                                             \
+    else                                                          \
+    {                                                             \
+      Action1;                                                    \
+      aRange -= aNewBound;                                        \
+      aCode -= aNewBound;                                          \
+      aProb -= (aProb) >> aNumMoveBits;                           \
+      aModelIndex = (aModelIndex << 1) + 1;                       \
+    }}                                                             \
+    RC_NORMALIZE
+
+#define RC_GETBIT(aNumMoveBits, aProb, aModelIndex) RC_GETBIT2(aNumMoveBits, aProb, aModelIndex, ; , ;)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/rngcoder.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,143 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __COMPRESSION_RANGECODER_H
+#define __COMPRESSION_RANGECODER_H
+
+#include "inbyte.h"
+
+namespace NCompression {
+namespace NArithmetic {
+
+const UINT32 kNumTopBits = 24;
+const UINT32 kTopValue = (1 << kNumTopBits);
+
+class CRangeDecoder
+{
+public:
+  NStream::CInByte m_Stream;
+  UINT32 m_Range;
+  UINT32 m_Code;
+  UINT32 m_Word;
+  void Normalize()
+  {
+    while (m_Range < kTopValue)
+    {
+      m_Code = (m_Code << 8) | m_Stream.ReadByte();
+      m_Range <<= 8;
+    }
+  }
+
+  void Init(ISequentialInStream *aStream)
+  {
+    m_Stream.Init(aStream);
+    m_Code = 0;
+    m_Range = UINT32(-1);
+    for(int i = 0; i < 5; i++)
+      m_Code = (m_Code << 8) | m_Stream.ReadByte();
+  }
+
+  UINT32 GetThreshold(UINT32 aTotal)
+  {
+    return (m_Code) / ( m_Range /= aTotal);
+  }
+
+  void Decode(UINT32 aStart, UINT32 aSize, UINT32 aTotal)
+  {
+    m_Code -= aStart * m_Range;
+    m_Range *= aSize;
+    Normalize();
+  }
+
+  /*
+  UINT32 DecodeDirectBitsDiv(UINT32 aNumTotalBits)
+  {
+    m_Range >>= aNumTotalBits;
+    UINT32 aThreshold = m_Code / m_Range;
+    m_Code -= aThreshold * m_Range;
+
+    Normalize();
+    return aThreshold;
+  }
+
+  UINT32 DecodeDirectBitsDiv2(UINT32 aNumTotalBits)
+  {
+    if (aNumTotalBits <= kNumBottomBits)
+      return DecodeDirectBitsDiv(aNumTotalBits);
+    UINT32 aResult = DecodeDirectBitsDiv(aNumTotalBits - kNumBottomBits) << kNumBottomBits;
+    return (aResult | DecodeDirectBitsDiv(kNumBottomBits));
+  }
+  */
+
+  UINT32 DecodeDirectBits(UINT32 aNumTotalBits)
+  {
+    UINT32 aRange = m_Range;
+    UINT32 aCode = m_Code;
+    UINT32 aResult = 0;
+    for (UINT32 i = aNumTotalBits; i > 0; i--)
+    {
+      aRange >>= 1;
+      /*
+      aResult <<= 1;
+      if (aCode >= aRange)
+      {
+        aCode -= aRange;
+        aResult |= 1;
+      }
+      */
+      UINT32 t = (aCode - aRange) >> 31;
+      aCode -= aRange & (t - 1);
+      // aRange = aRangeTmp + ((aRange & 1) & (1 - t));
+      aResult = (aResult << 1) | (1 - t);
+
+      if (aRange < kTopValue)
+      {
+        aCode = (aCode << 8) | m_Stream.ReadByte();
+        aRange <<= 8;
+      }
+    }
+    m_Range = aRange;
+    m_Code = aCode;
+    return aResult;
+  }
+
+  UINT32 DecodeBit(UINT32 aSize0, UINT32 aNumTotalBits)
+  {
+    UINT32 aNewBound = (m_Range >> aNumTotalBits) * aSize0;
+    UINT32 aSymbol;
+    if (m_Code < aNewBound)
+    {
+      aSymbol = 0;
+      m_Range = aNewBound;
+    }
+    else
+    {
+      aSymbol = 1;
+      m_Code -= aNewBound;
+      m_Range -= aNewBound;
+    }
+    Normalize();
+    return aSymbol;
+  }
+
+  UINT64 GetProcessedSize() {return m_Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/winout.cpp	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "winout.h"
+
+namespace NStream {
+namespace NWindow {
+
+void COut::Create(UINT32 aKeepSizeBefore, UINT32 aKeepSizeAfter, UINT32 aKeepSizeReserv)
+{
+  m_Pos = 0;
+  m_PosLimit = aKeepSizeReserv + aKeepSizeBefore;
+  m_KeepSizeBefore = aKeepSizeBefore;
+  m_KeepSizeAfter = aKeepSizeAfter;
+  m_KeepSizeReserv = aKeepSizeReserv;
+  m_StreamPos = 0;
+  m_MoveFrom = m_KeepSizeReserv;
+  m_WindowSize = aKeepSizeBefore;
+  UINT32 aBlockSize = m_KeepSizeBefore + m_KeepSizeAfter + m_KeepSizeReserv;
+  delete []m_Buffer;
+  m_Buffer = new BYTE[aBlockSize];
+}
+
+COut::~COut()
+{
+  delete []m_Buffer;
+}
+
+void COut::SetWindowSize(UINT32 aWindowSize)
+{
+  m_WindowSize = aWindowSize;
+  m_MoveFrom = m_KeepSizeReserv + m_KeepSizeBefore - aWindowSize;
+}
+
+void COut::Init(ISequentialOutStream *aStream, bool aSolid)
+{
+  m_Stream = aStream;
+
+  if(aSolid)
+    m_StreamPos = m_Pos;
+  else
+  {
+    m_Pos = 0;
+    m_PosLimit = m_KeepSizeReserv + m_KeepSizeBefore;
+    m_StreamPos = 0;
+  }
+}
+
+HRESULT COut::Flush()
+{
+  UINT32 aSize = m_Pos - m_StreamPos;
+  if(aSize == 0)
+    return S_OK;
+  UINT32 aProcessedSize;
+  HRESULT aResult = m_Stream->Write(m_Buffer + m_StreamPos, aSize, &aProcessedSize);
+  if (aResult != S_OK)
+    return aResult;
+  if (aSize != aProcessedSize)
+    return E_FAIL;
+  m_StreamPos = m_Pos;
+  return S_OK;
+}
+
+void COut::MoveBlockBackward()
+{
+  HRESULT aResult = Flush();
+  if (aResult != S_OK)
+    throw aResult;
+  memmove(m_Buffer, m_Buffer + m_MoveFrom, m_WindowSize + m_KeepSizeAfter);
+  m_Pos -= m_MoveFrom;
+  m_StreamPos -= m_MoveFrom;
+}
+
+}}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/console/libjma/winout.h	Tue Jun 13 20:37:25 2006 -0700
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
+Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License version 2.1 as published by the Free Software Foundation.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __STREAM_WINDOWOUT_H
+#define __STREAM_WINDOWOUT_H
+
+#include "iiostrm.h"
+
+namespace NStream {
+namespace NWindow {
+
+// m_KeepSizeBefore: how mach BYTEs must be in buffer before m_Pos;
+// m_KeepSizeAfter: how mach BYTEs must be in buffer after m_Pos;
+// m_KeepSizeReserv: how mach BYTEs must be in buffer for Moving Reserv;
+//                    must be >= aKeepSizeAfter; // test it
+
+class COut
+{
+  BYTE  *m_Buffer;
+  UINT32 m_Pos;
+  UINT32 m_PosLimit;
+  UINT32 m_KeepSizeBefore;
+  UINT32 m_KeepSizeAfter;
+  UINT32 m_KeepSizeReserv;
+  UINT32 m_StreamPos;
+
+  UINT32 m_WindowSize;
+  UINT32 m_MoveFrom;
+
+  ISequentialOutStream *m_Stream;
+
+  virtual void MoveBlockBackward();
+public:
+  COut(): m_Buffer(0), m_Stream(0) {}
+  virtual ~COut();
+  void Create(UINT32 aKeepSizeBefore,
+      UINT32 aKeepSizeAfter, UINT32 aKeepSizeReserv = (1<<17));
+  void SetWindowSize(UINT32 aWindowSize);
+
+  void Init(ISequentialOutStream *aStream, bool aSolid = false);
+  HRESULT Flush();
+
+  UINT32 GetCurPos() const { return m_Pos; }
+  const BYTE *GetPointerToCurrentPos() const { return m_Buffer + m_Pos;};
+
+  void CopyBackBlock(UINT32 aDistance, UINT32 aLen)
+  {
+    if (m_Pos >= m_PosLimit)
+      MoveBlockBackward();
+    BYTE *p = m_Buffer + m_Pos;
+    aDistance++;
+    for(UINT32 i = 0; i < aLen; i++)
+      p[i] = p[i - aDistance];
+    m_Pos += aLen;
+  }
+
+  void PutOneByte(BYTE aByte)
+  {
+    if (m_Pos >= m_PosLimit)
+      MoveBlockBackward();
+    m_Buffer[m_Pos++] = aByte;
+  }
+
+  BYTE GetOneByte(UINT32 anIndex) const
+  {
+    return m_Buffer[m_Pos + anIndex];
+  }
+
+  BYTE *GetBuffer() const { return m_Buffer; }
+};
+
+}}
+
+#endif